From: Luca Heltai Date: Tue, 30 Apr 2019 14:37:34 +0000 (+0200) Subject: Updated code to use VectorTools::NormType X-Git-Tag: v9.1.0-rc1~143^2~6 X-Git-Url: https://gitweb.dealii.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=3921b0f2c29cb9faa854165ad5822936d4861c91;p=dealii.git Updated code to use VectorTools::NormType --- diff --git a/include/deal.II/base/parsed_convergence_table.h b/include/deal.II/base/parsed_convergence_table.h index 2ec1f233c1..a0c12ec1d6 100644 --- a/include/deal.II/base/parsed_convergence_table.h +++ b/include/deal.II/base/parsed_convergence_table.h @@ -22,7 +22,6 @@ #include #include #include -#include #include #include @@ -64,19 +63,24 @@ DEAL_II_NAMESPACE_OPEN * @endcode * * The above code constructs a ParsedConvergenceTable that works for - * scalar problems, and will produce an error table with `H1`, `L2`, and - * `Linfty` norms of the error. + * scalar problems, and will produce an error table with `H1_norm`, `L2_norm`, + * and `Linfty_norm` norms of the error. * * Whenever a call to the methods error_from_exact() or difference() is made, - * the instance of this class inspects its parameters, and computes all norms + * the instance of this class inspects its parameters, computes all norms * specified by the parameter given at construction time, possibly modified - * via a parameter file. + * via a parameter file, computes all extra column entries specified using the + * method add_extra_column(), and writes one row of the convergence table. + * + * Once you have finished with the computations, a call to output_table() will + * generate a formatted convergence table on the provided stream, and to the + * file (if any) specified in the parameter file. * * With a small modification, the same code can be used to estimate the errors * of mixed or multi-physics problems, e.g.: * @code - * using namespace ParsedConvergenceTableFlags; - * ParsedConvergenceTable table({"u,u,p"},{{H1, L2}, {L2}}); + * using namespace VectorTools; + * ParsedConvergenceTable table({"u,u,p"},{{H1_norm, L2_norm}, {L2_norm}}); * * ParameterHandler prm; * table.add_parameters(prm); @@ -96,16 +100,20 @@ DEAL_II_NAMESPACE_OPEN * components) and `L2` error in the pressure field. * * By calling the method add_parameters() passing a ParameterHandler object, - * the following options will be defined in the given ParameterHandler object, + * the following options will be defined in the given ParameterHandler object + * (in the current level of the ParameterHandler object, i.e., whatever level + * you have entered with the ParamterHandler::enter_subsection() method), * and can be modified at run time through a parameter file: * @code * set Enable computation of the errors = true * set Enable output to streams = true * set Error file name = * set Error precision = 3 + * set Exponent for p-norms = 2 * set Extra columns = dofs, cells - * set List of error norms to compute = Linfty, L2, H1 + * set List of error norms to compute = Linfty_norm, L2_norm, H1_norm * set Rate key = dofs + * set Rate mode = reduction_rate_log2 * @endcode * * When using this class, please cite @@ -141,13 +149,14 @@ public: * * For example, the following constructor * @code - * using namespace ParsedConvergenceTableFlags; - * ParsedConvergenceTable table({"u", "v", "v"}, {{Linfty}, {L2, H1}}); + * using namespace VectorTools; + * ParsedConvergenceTable table({"u", "v", "v"}, + * {{Linfty_norm}, {L2_norm, H1_norm}}); * @endcode * - * Will produce (if the parameter file is left untouched) the following table: + * Would produce (if the parameter file is left untouched) a table similar to * @code - * cells dofs u_Linfty v_L2 v_H1 + * cells dofs u_Linfty_norm v_L2_norm v_H1_norm * 4 9 1.183e-01 - 5.156e-02 - 2.615e-01 - * 16 25 3.291e-02 2.50 1.333e-02 2.65 1.272e-01 1.41 * 64 81 8.449e-03 2.31 3.360e-03 2.34 6.313e-02 1.19 @@ -155,7 +164,7 @@ public: * 1024 1089 5.325e-04 2.09 2.106e-04 2.09 1.574e-02 1.05 * @endcode * - * Se the documentation of NormType for a list of + * Se the documentation of VectorTools::NormType for a list of * available norms you can compute using this class, and see the other * constructor for a documentation of all the parameters you can change. * @@ -164,11 +173,9 @@ public: * unique component name */ ParsedConvergenceTable( - const std::vector &component_names = {"u"}, - const std::vector> - &list_of_error_norms = {{ParsedConvergenceTableFlags::H1, - ParsedConvergenceTableFlags::L2, - ParsedConvergenceTableFlags::Linfty}}); + const std::vector & component_names = {"u"}, + const std::vector> &list_of_error_norms = { + {VectorTools::H1_norm, VectorTools::L2_norm, VectorTools::Linfty_norm}}); /** * Full constructor for ParsedConvergenceTable. @@ -177,19 +184,27 @@ public: * names are interpreted as components of a vector valued field; * @param list_of_error_norms Specify what error norms to compute for each * unique component name; - * @param extra_columns Extra columns to add; + * @param exponent The exponent to use in p-norms; + * @param extra_columns Extra columns to add. These may be "cells" or "dofs"; * @param rate_key Specify the extra column by which we will compute the - * error rates; + * error rates. This key can either be one of "cells" or "dofs", or, if you + * add extra columns to the table via the method add_extra_column(), it may + * be one of the extra columns you added; + * @param rate_mode Specify the rate mode to use when computing error rates. + * This maybe either "reduction_rate", "reduction_rate_log2", or "none". See + * the documentation of ConvergenceTable::RateMode for an explanation of how + * each of this mode behaves; * @param error_file_name Name of error output file (with extension txt, * gpl, tex, or org). If different from the empty string, than * output_table() also writes in this file in the format deduced from its * extension; * @param precision How many digits to use when writing the error; - * @param compute_error If set to `false`, then no error computation is - * performed, and no output is produced; - * @param output_error If set to `false`, then the call to output_table() - * will produce only an output file (if @p error_file_name is not empty), - * but no output will be written on the given stream. + * @param compute_error Control wether the filling of the table is enabled + * or not. This flag may be used to disable at run time any error computation; + * @param output_error Control the behaviour of the output_table() method. Set + * this to true if you want output_table() to write the table to its input + * argument. This flag may be used to disable at run time any explicit output + * to stream. * * The parameters you specify with this constructor can be written to a * ParameterHandler object by calling the add_parameters() method. Once you @@ -214,10 +229,12 @@ public: * # Number of digits to use when printing the error. * set Error precision = 3 * - * # Extra columns to add to the table. Available options are dofs, cells, and - * # dt. + * # Extra columns to add to the table. Available options are dofs and cells * set Extra columns = dofs, cells * + * # The exponent to use when computing p-norms. + * set Exponent for p-norms = 2 + * * # Each component is separated by a semicolon, and each norm by a comma. * # Implemented norms are Linfty, L2, W1infty, H1, and custom. If you want to * # skip a component, use none. @@ -226,18 +243,23 @@ public: * # Key to use when computing convergence rates. If this is set to a * # column that is not present, or to none, then no error rates are computed. * set Rate key = dofs + * + * # What type of error rate to compute. Available options are + * # reduction_rate_log2, reduction_rate, and none. + * set Rate mode = reduction_rate_log2 * @endcode */ ParsedConvergenceTable( - const std::vector &component_names, - const std::vector> - &list_of_error_norms, - const std::set &extra_columns, - const ParsedConvergenceTableFlags::ExtraColumns & rate_key, - const std::string & error_file_name, - const unsigned int & precision, - const bool & compute_error, - const bool & output_error); + const std::vector & component_names, + const std::vector> &list_of_error_norms, + const double & exponent, + const std::set & extra_columns, + const std::string & rate_key, + const std::string & rate_mode, + const std::string & error_file_name, + const unsigned int & precision, + const bool & compute_error, + const bool & output_error); /** * Attach all the parameters in this class to entries of the parameter @@ -251,111 +273,100 @@ public: * Add a row to the error table, containing the error between @p solution and * the @p exact function, in the norm(s) specified in the parameter file. * - * If you specify a @p weight expression during this call, then this is used - * to compute weighted errors. If the weight is different from "1.0", then - * you have to make sure that muparser is installed and enabled, otherwise an - * exception will be thrown. + * If you specify a @p weight function during this call, then this is used + * to compute weighted errors. The weight function can be either a scalar + * function (which will be used for all components), or a vector function. + * When it is a vector function, an assertion is triggered if the number of + * components does not coincide with the number of components of the + * underlying finite element space. */ template void - error_from_exact(const DoFHandlerType & vspace, - const VectorType & solution, - const Function &exact, - double dt = 0., - const std::string &weight = "1.0"); + error_from_exact( + const DoFHandlerType & vspace, + const VectorType & solution, + const Function &exact, + const Function *weight = nullptr); /** * Same as above, with a different mapping. */ template void - error_from_exact(const Mapping & mapping, - const DoFHandlerType & vspace, - const VectorType & solution, - const Function &exact, - double dt = 0., - const std::string &weight = "1.0"); - + error_from_exact( + const Mapping + & mapping, + const DoFHandlerType & vspace, + const VectorType & solution, + const Function &exact, + const Function *weight = nullptr); /** - * Call the given custom function to compute a custom error for any component - * for which you specify the ParsedConvergenceTableFlags::custom norm. This function - * may be called several times to add different columns with different names, - * provided you use an appropriate function every time, and - * that you also update @p column_name every time. + * Add an additional column (with name @p name) to the table, by invoking + * the function @p custom_function, when calling error_from_exact() or + * difference(). * - * Should you wish to do so, then make sure the parameter - * @p add_table_extras is set to `false` for each call, except one, so - * that you only add extra column information once. + * You can call this method as many times as you want. If @p column_name was + * already used in a previous call, then calling this method with the same + * name will overwrite whatever function you had previously specified. If + * you use a lambda function for this call, make sure that the variables used + * internally in the lambda function remain valid until the call to + * error_from_exact() or difference(). * - * An example usage of this class with a custom error function is the - * following: + * This method may be used, for example, to compute the error w.r.t. to + * time step increments in time, for example: * @code - * using namespace ParsedConvergenceTableFlags; - * ParsedConvergenceTable table({"u"}, {{"custom"}}); + * using namespace VectorTools; + * ParsedConvergenceTable table({"u"}, {{L2_norm}}); + * + * double dt = .5; + * auto dt_function = [&]() { + * return dt; + * }; + * + * table.add_extra_column("dt", dt_function, true); * * for (unsigned int i = 0; i < n_cycles; ++i) * { - * // ... refine and distribute dofs - * auto cycle_function = [&](const unsigned int component) { - * return i; - * }; - * table.custom_error(cycle_function, dof_handler, "cycle", true); + * // ... compute solution at the current dt + * + * table.error_from_exact(dof_handler, solution, exact_solution); + * dt /= 2.0; * } * table.output_table(std::cout); * @endcode * - * Will produce (if the parameter file is left untouched) the following table: - * @code - * cells dofs cycle - * 4 9 0 - * 16 25 1 - * 64 81 2 - * 256 289 3 - * 1024 1089 4 - * @endcode + * will produce a table similar to * - * Should you wish to add another column, then the above code should be - * replaced by: * @code - * using namespace ParsedConvergenceTableFlags; - * ParsedConvergenceTable table({"u"}, {"custom"}); - * - * for (unsigned int i = 0; i < n_cycles; ++i) - * { - * // ... refine and distribute dofs - * auto cycle_function = [&](const unsigned int) { - * return i; - * }; - * auto cycle_square_function = [&](const unsigned int) { - * return i*i; - * }; - * table.custom_error(cycle_function, dof_handler, "cycle", false); - * table.custom_error(cycle_square_function, dof_handler, - * "cycle_square", true); - * } - * table.output_table(std::cout); + * dt u_L2_norm + * 5.000e-1 5.156e-02 - + * 2.500e-2 1.333e-02 2.65 + * 1.250e-2 3.360e-03 2.34 + * 6.250e-3 8.418e-04 2.18 * @endcode * - * This will produce the table: + * provided that you use the following parameter file (only non default + * entries are shown here): + * * @code - * cells dofs cycle cycle_square - * 4 9 0 0 - * 16 25 1 1 - * 64 81 2 4 - * 256 289 3 9 - * 1024 1089 4 16 + * set Extra columns = + * set List of error norms to compute = L2_norm + * set Rate key = dt * @endcode + * + * + * @param name Name of the column to add. + * @param custom_function Function that will be called to fill the given + * entry. You need to make sure that the scope of this function is valid + * up to the + * @param exclude_from_rates If set to true, then no error rates will be + * computed for this column. */ - template void - custom_error(const std::function - & custom_error_function, - const DoFHandlerType &dh, - const std::string & column_name = "custom", - const bool add_table_extras = false, - const double dt = 0.); + add_extra_column(const std::string & column_name, + const std::function &custom_function, + const bool & exclude_from_rates = false); /** * Difference between two solutions in the same vector space. @@ -365,7 +376,7 @@ public: difference(const DoFHandlerType &, const VectorType &, const VectorType &, - double dt = 0.); + const Function *weight = nullptr); /** * Same as above, with a non default mapping. @@ -377,7 +388,7 @@ public: const DoFHandlerType &, const VectorType &, const VectorType &, - double dt = 0.); + const Function *weight = nullptr); /** * Write the error table to the @p out stream, and (possibly) to the file @@ -402,26 +413,41 @@ private: */ const std::vector unique_component_masks; + /** + * Additional methods to call when adding rows to the table. + */ + std::map, bool>> + extra_column_functions; + /** * Type of error to compute per components. */ - std::vector> - norms_per_unique_component; + std::vector> norms_per_unique_component; + + /** + * Exponent to use in the p-norm types. + */ + double exponent; /** * The actual table */ ConvergenceTable table; - + /** * Extra columns to add to the table. */ - std::set extra_columns; + std::set extra_columns; + + /** + * The name of column with respect to which we compute convergence rates. + */ + std::string rate_key; /** - * Whether or not to calculate the rates according to the given keys. + * Reduction rate mode. See ConvergenceTable::RateMode for a documentation. */ - ParsedConvergenceTableFlags::ExtraColumns rate_key; + std::string rate_mode; /** * The precision used to output the table. @@ -453,10 +479,11 @@ private: // ============================================================ template void -ParsedConvergenceTable::difference(const DoFHandlerType &dh, - const VectorType & solution1, - const VectorType & solution2, - double dt) +ParsedConvergenceTable::difference( + const DoFHandlerType & dh, + const VectorType & solution1, + const VectorType & solution2, + const Function *weight) { AssertThrow(solution1.size() == solution2.size(), ExcDimensionMismatch(solution1.size(), solution2.size())); @@ -466,7 +493,7 @@ ParsedConvergenceTable::difference(const DoFHandlerType &dh, solution, ConstantFunction( 0, component_names.size()), - dt); + weight); } @@ -475,11 +502,11 @@ template void ParsedConvergenceTable::difference( const Mapping - & mapping, - const DoFHandlerType &dh, - const VectorType & solution1, - const VectorType & solution2, - double dt) + & mapping, + const DoFHandlerType & dh, + const VectorType & solution1, + const VectorType & solution2, + const Function *weight) { AssertThrow(solution1.size() == solution2.size(), ExcDimensionMismatch(solution1.size(), solution2.size())); @@ -490,7 +517,7 @@ ParsedConvergenceTable::difference( solution, ConstantFunction( 0, component_names.size()), - dt); + weight); } @@ -501,15 +528,13 @@ ParsedConvergenceTable::error_from_exact( const DoFHandlerType & dh, const VectorType & solution, const Function &exact, - double dt, - const std::string & weight) + const Function *weight) { error_from_exact(StaticMappingQ1::mapping, dh, solution, exact, - dt, weight); } @@ -523,80 +548,80 @@ ParsedConvergenceTable::error_from_exact( const DoFHandlerType & dh, const VectorType & solution, const Function &exact, - double dt, - const std::string & weight) + const Function *weight) { - const int dim = DoFHandlerType::dimension; - const int spacedim = DoFHandlerType::space_dimension; + const int dim = DoFHandlerType::dimension; + const int spacedim = DoFHandlerType::space_dimension; + const auto n_components = component_names.size(); + if (compute_error) { - AssertDimension(exact.n_components, component_names.size()); + AssertDimension(exact.n_components, n_components); + AssertDimension(dh.get_fe().n_components(), n_components); const unsigned int n_active_cells = dh.get_triangulation().n_global_active_cells(); const unsigned int n_dofs = dh.n_dofs(); for (const auto &col : extra_columns) - if (col == ParsedConvergenceTableFlags::cells) + if (col == "cells") { table.add_value("cells", n_active_cells); table.set_tex_caption("cells", "\\# cells"); table.set_tex_format("cells", "r"); } - else if (col == ParsedConvergenceTableFlags::dofs) + else if (col == "dofs") { table.add_value("dofs", n_dofs); table.set_tex_caption("dofs", "\\# dofs"); table.set_tex_format("dofs", "r"); } - else if (col == ParsedConvergenceTableFlags::dt) - { - table.add_value("dt", dt); - table.set_tex_caption("dt", "\\Delta t"); - table.set_tex_format("dt", "r"); - } + // A vector of zero std::functions with n_components components + const std::vector &)>> + zero_components(n_components, + [](const Point &) { return 0.0; }); - std::map - norm_to_index; - norm_to_index[ParsedConvergenceTableFlags::L2] = 0; - norm_to_index[ParsedConvergenceTableFlags::H1] = 1; - norm_to_index[ParsedConvergenceTableFlags::Linfty] = 2; - norm_to_index[ParsedConvergenceTableFlags::W1infty] = 3; - norm_to_index[ParsedConvergenceTableFlags::custom] = 4; + // The default weight function, with n_components components + std::vector &)>> + weight_components(n_components, + [](const Point &) { return 1.0; }); - const auto n_components = component_names.size(); - for (unsigned int i = 0; i < unique_component_names.size(); ++i) + if (weight != nullptr) { - std::vector error(5, 0.0); - const auto & norms = norms_per_unique_component[i]; - const auto & mask = unique_component_masks[i]; - -# ifndef DEAL_II_WITH_MUPARSER - Assert(weight == "1.0", - ExcMessage("If you want to use a weight which is " - "different from 1.0, you have to " - "install deal.II with muparser enabled.")); - ComponentSelectFunction select_component( - {mask.first_selected_component(), - mask.first_selected_component() + mask.n_selected_components()}, - n_components); -# else - std::string comp_sel; - { - // Select all required components - std::vector expr(n_components, "0"); + if (weight->n_components == 1) + { + for (auto &f : weight_components) + f = [&](const Point &p) { return weight->value(p); }; + } + else + { + AssertDimension(weight->n_components, n_components); + for (unsigned int i = 0; i < n_components; ++i) + weight_components[i] = [&](const Point &p) { + return weight->value(p, i); + }; + } + } - for (unsigned int i = 0; i < n_components; ++i) - if (mask[i] == true) - expr[i] = weight; + for (unsigned int i = 0; i < norms_per_unique_component.size(); ++i) + { + std::map errors; - comp_sel = expr[0]; - for (unsigned int i = 1; i < expr.size(); ++i) - comp_sel += "; " + expr[i]; - } - FunctionParser select_component(comp_sel); -# endif + const auto &norms = norms_per_unique_component[i]; + const auto &mask = unique_component_masks[i]; + + // Simple case first + if (norms.empty()) + continue; + + auto components_expr = zero_components; + for (unsigned int i = 0; i < n_components; ++i) + if (mask[i] == true) + components_expr[i] = weight_components[i]; + + FunctionFromFunctionObjects select_component( + components_expr); Vector difference_per_cell( dh.get_triangulation().n_global_active_cells()); @@ -605,164 +630,46 @@ ParsedConvergenceTable::error_from_exact( for (const auto &norm : norms) { - if (norm == ParsedConvergenceTableFlags::L2) - { - VectorTools::integrate_difference(mapping, - dh, - solution, - exact, - difference_per_cell, - q_gauss, - VectorTools::L2_norm, - &select_component); - } - - error[norm_to_index[ParsedConvergenceTableFlags::L2]] = - VectorTools::compute_global_error(dh.get_triangulation(), - difference_per_cell, - VectorTools::L2_norm); - difference_per_cell = 0; - - if (norm == ParsedConvergenceTableFlags::H1) - { - VectorTools::integrate_difference(mapping, - dh, - solution, - exact, - difference_per_cell, - q_gauss, - VectorTools::H1_norm, - &select_component); - } - error[norm_to_index[ParsedConvergenceTableFlags::H1]] = - VectorTools::compute_global_error(dh.get_triangulation(), - difference_per_cell, - VectorTools::H1_norm); - difference_per_cell = 0; - - if (norm == ParsedConvergenceTableFlags::W1infty) - { - VectorTools::integrate_difference(mapping, - dh, - solution, - exact, - difference_per_cell, - q_gauss, - VectorTools::W1infty_norm, - &select_component); - } - - error[norm_to_index[ParsedConvergenceTableFlags::W1infty]] = - VectorTools::compute_global_error( - dh.get_triangulation(), - difference_per_cell, - VectorTools::W1infty_seminorm); - difference_per_cell = 0; - - if (norm == ParsedConvergenceTableFlags::Linfty) - { - VectorTools::integrate_difference(mapping, - dh, - solution, - exact, - difference_per_cell, - q_gauss, - VectorTools::Linfty_norm, - &select_component); - } - - error[norm_to_index[ParsedConvergenceTableFlags::Linfty]] = - VectorTools::compute_global_error(dh.get_triangulation(), - difference_per_cell, - VectorTools::Linfty_norm); difference_per_cell = 0; - - // Now add what we just computed. - if (norm != ParsedConvergenceTableFlags::none) - { - std::string name = unique_component_names[i] + "_" + - Patterns::Tools::to_string(norm); - std::string latex_name = - "$\\| " + unique_component_names[i] + " - " + - unique_component_names[i] + "_h \\|_{" + - Patterns::Tools::to_string(norm) + "}$"; - - table.add_value(name, error[norm_to_index[norm]]); - table.set_precision(name, precision); - table.set_scientific(name, true); - table.set_tex_caption(name, latex_name); - } + VectorTools::integrate_difference(mapping, + dh, + solution, + exact, + difference_per_cell, + q_gauss, + norm, + &select_component, + exponent); + + errors[norm] = VectorTools::compute_global_error( + dh.get_triangulation(), difference_per_cell, norm, exponent); + + std::string name = unique_component_names[i] + "_" + + Patterns::Tools::to_string(norm); + std::string latex_name = "$\\| " + unique_component_names[i] + + " - " + unique_component_names[i] + + "_h \\|_{" + + Patterns::Tools::to_string(norm) + "}$"; + + table.add_value(name, errors[norm]); + table.set_precision(name, precision); + table.set_scientific(name, true); + table.set_tex_caption(name, latex_name); } } - } -} - -template -void -ParsedConvergenceTable::custom_error( - const std::function - & custom_error_function, - const DoFHandlerType &dh, - const std::string & column_name, - const bool add_table_extras, - const double dt) -{ - if (compute_error) - { - const unsigned int n_components = norms_per_unique_component.size(); - const unsigned int n_active_cells = - dh.get_triangulation().n_global_active_cells(); - const unsigned int n_dofs = dh.n_dofs(); - if (add_table_extras) - { - for (const auto &col : extra_columns) - { - if (col == ParsedConvergenceTableFlags::cells) - { - table.add_value("cells", n_active_cells); - table.set_tex_caption("cells", "\\# cells"); - table.set_tex_format("cells", "r"); - } - if (col == ParsedConvergenceTableFlags::dofs) - { - table.add_value("dofs", n_dofs); - table.set_tex_caption("dofs", "\\# dofs"); - table.set_tex_format("dofs", "r"); - } - if (col == ParsedConvergenceTableFlags::dt) - { - table.add_value("dt", dt); - table.set_tex_caption("dt", "\\Delta t"); - table.set_tex_format("dt", "r"); - } - } - } - - for (unsigned int j = 0; j < n_components; ++j) + for (const auto &extra_col : extra_column_functions) { - const auto &norms = norms_per_unique_component[j]; + const double custom_error = extra_col.second.first(); - for (const auto &norm : norms) - if (norm == ParsedConvergenceTableFlags::custom) - { - const double custom_error = custom_error_function(j); - - std::string name = - unique_component_names[j] + "_" + column_name; - std::string latex_name = "$\\| " + unique_component_names[j] + - " - " + unique_component_names[j] + - "_h \\|_{\\text{" + column_name + - "} $"; - - table.add_value(name, custom_error); - table.set_precision(name, precision); - table.set_scientific(name, true); - table.set_tex_caption(name, latex_name); - } + std::string name = extra_col.first; + table.add_value(name, custom_error); + table.set_precision(name, precision); + table.set_scientific(name, true); } } } + #endif DEAL_II_NAMESPACE_CLOSE diff --git a/include/deal.II/base/parsed_convergence_table_flags.h b/include/deal.II/base/parsed_convergence_table_flags.h deleted file mode 100644 index 8efd96705e..0000000000 --- a/include/deal.II/base/parsed_convergence_table_flags.h +++ /dev/null @@ -1,232 +0,0 @@ -// --------------------------------------------------------------------- -// -// Copyright (C) 2019 by the deal.II authors -// -// This file is part of the deal.II library. -// -// The deal.II library is free software; you can use it, redistribute -// it, and/or modify it under the terms of the GNU Lesser General -// Public License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// The full text of the license can be found in the file LICENSE.md at -// the top level directory of deal.II. -// -// ------------------------------------------------------------------- - -#ifndef dealii_base_parsed_convergence_table_flags_h -#define dealii_base_parsed_convergence_table_flags_h - -#include - -#include - -DEAL_II_NAMESPACE_OPEN - -namespace ParsedConvergenceTableFlags -{ - /** - * Implemented Error norms. - */ - enum NormType - { - none = 0x00, - Linfty = 0x01, - L2 = 0x02, - W1infty = 0x04, - H1 = 0x08, - custom = 0x10, - }; - - /** - * The ExtraColumns enum. - */ - enum ExtraColumns - { - no_columns = 0x0, - dofs = 0x1, - cells = 0x2, - dt = 0x4 - }; -} // namespace ParsedConvergenceTableFlags - -namespace Patterns -{ - namespace Tools - { - template <> - struct Convert - { - /** - * Return the Correct pattern for NormType. - */ - static std::unique_ptr - to_pattern() - { - return std_cxx14::make_unique( - "none|Linfty|L2|W1infty|H1|custom"); - } - - - - /** - * Convert a NormType to a string. - */ - static std::string - to_string(const ParsedConvergenceTableFlags::NormType & s, - const std::unique_ptr &p = - Convert::to_pattern()) - { - (void)p; - if (s == ParsedConvergenceTableFlags::Linfty) - return "Linfty"; - else if (s == ParsedConvergenceTableFlags::L2) - return "L2"; - else if (s == ParsedConvergenceTableFlags::W1infty) - return "W1infty"; - else if (s == ParsedConvergenceTableFlags::H1) - return "H1"; - else if (s == ParsedConvergenceTableFlags::custom) - return "custom"; - else if (s == ParsedConvergenceTableFlags::none) - return "none"; - else - { - AssertThrow(false, ExcMessage("Didn't recognize a norm type.")); - return ""; - } - } - - - - /** - * Convert a string to a NormType. - */ - static ParsedConvergenceTableFlags::NormType - to_value(const std::string & norm_string, - const std::unique_ptr &p = - Convert::to_pattern()) - { - (void)p; - ParsedConvergenceTableFlags::NormType norm = - ParsedConvergenceTableFlags::none; - - if (norm_string == "Linfty") - { - norm = ParsedConvergenceTableFlags::Linfty; - } - else if (norm_string == "L2") - { - norm = ParsedConvergenceTableFlags::L2; - } - else if (norm_string == "W1infty") - { - norm = ParsedConvergenceTableFlags::W1infty; - } - else if (norm_string == "H1") - { - norm = ParsedConvergenceTableFlags::H1; - } - else if (norm_string == "custom") - { - norm = ParsedConvergenceTableFlags::custom; - } - else if (norm_string == "none") - { - norm = ParsedConvergenceTableFlags::none; - } - else - { - AssertThrow(false, ExcMessage("The norm type <" + norm_string + "> is not recognized.")); - } - - return norm; - } - }; - - - - template <> - struct Convert - { - /** - * Return the Correct pattern for ExtraColumns. - */ - static std::unique_ptr - to_pattern() - { - return std_cxx14::make_unique("none|cells|dofs|dt"); - } - - - - /** - * Convert an ExtraColumn object to a string. - */ - static std::string - to_string( - const ParsedConvergenceTableFlags::ExtraColumns &s, - const std::unique_ptr & p = - Convert::to_pattern()) - { - (void)p; - if (s == ParsedConvergenceTableFlags::cells) - return "cells"; - else if (s == ParsedConvergenceTableFlags::dofs) - return "dofs"; - else if (s == ParsedConvergenceTableFlags::dt) - return "dt"; - else if (s == ParsedConvergenceTableFlags::no_columns) - return "none"; - else - { - AssertThrow(false, ExcMessage("Didn't recognize a column type.")); - return ""; - } - } - - - - /** - * Convert a string to an ExtraColumn object. - */ - static ParsedConvergenceTableFlags::ExtraColumns - to_value( - const std::string & column_string, - const std::unique_ptr &p = - Convert::to_pattern()) - { - (void)p; - ParsedConvergenceTableFlags::ExtraColumns column = - ParsedConvergenceTableFlags::no_columns; - - if (column_string == "cells") - { - column = ParsedConvergenceTableFlags::cells; - } - else if (column_string == "dofs") - { - column = ParsedConvergenceTableFlags::dofs; - } - else if (column_string == "dt") - { - column = ParsedConvergenceTableFlags::dt; - } - else if (column_string == "none") - { - column = ParsedConvergenceTableFlags::no_columns; - } - else - { - AssertThrow(false, - ExcMessage("The column type <" + column_string + "> is not recognized.")); - } - - return column; - } - }; - } // namespace Tools -} // namespace Patterns - -DEAL_II_NAMESPACE_CLOSE - -#endif diff --git a/include/deal.II/numerics/vector_tools.h b/include/deal.II/numerics/vector_tools.h index 37b43f49ed..139ca99ce0 100644 --- a/include/deal.II/numerics/vector_tools.h +++ b/include/deal.II/numerics/vector_tools.h @@ -21,6 +21,7 @@ #include #include +#include #include #include @@ -3308,6 +3309,119 @@ namespace VectorTools } // namespace VectorTools +// Make sure we can use NormType with Patterns. +namespace Patterns +{ + namespace Tools + { + template <> + struct Convert + { + /** + * Return the Correct pattern for NormType. + */ + static std::unique_ptr + to_pattern() + { + return std_cxx14::make_unique( + "mean|L1_norm|L2_norm|Lp_norm|" + "Linfty_norm|H1_seminorm|Hdiv_seminorm|" + "H1_norm|W1p_seminorm|W1p_norm|" + "W1infty_seminorm|W1infty_norm"); + } + + + + /** + * Convert a NormType to a string. + */ + static std::string + to_string(const VectorTools::NormType & s, + const std::unique_ptr &p = + Convert::to_pattern()) + { + std::string str; + if (s == VectorTools::mean) + str = "mean"; + else if (s == VectorTools::L1_norm) + str = "L1_norm"; + else if (s == VectorTools::L2_norm) + str = "L2_norm"; + else if (s == VectorTools::Lp_norm) + str = "Lp_norm"; + else if (s == VectorTools::Linfty_norm) + str = "Linfty_norm"; + else if (s == VectorTools::H1_seminorm) + str = "H1_seminorm"; + else if (s == VectorTools::Hdiv_seminorm) + str = "Hdiv_seminorm"; + else if (s == VectorTools::H1_norm) + str = "H1_norm"; + else if (s == VectorTools::W1p_seminorm) + str = "W1p_seminorm"; + else if (s == VectorTools::W1infty_seminorm) + str = "W1infty_seminorm"; + else if (s == VectorTools::W1infty_norm) + str = "W1infty_norm"; + else if (s == VectorTools::W1p_norm) + str = "W1p_norm"; + else + { + AssertThrow(false, ExcMessage("Didn't recognize a norm type.")); + } + AssertThrow(p->match(str), ExcInternalError()); + return str; + } + + + /** + * Convert a string to a NormType. + */ + static VectorTools::NormType + to_value(const std::string & str, + const std::unique_ptr &p = + Convert::to_pattern()) + { + VectorTools::NormType norm = VectorTools::mean; + AssertThrow(p->match(str), + ExcMessage( + "String " + str + + " cannot be converted to VectorTools::NormType")); + + if (str == "mean") + norm = VectorTools::mean; + else if (str == "L1_norm") + norm = VectorTools::L1_norm; + else if (str == "L2_norm") + norm = VectorTools::L2_norm; + else if (str == "Lp_norm") + norm = VectorTools::Lp_norm; + else if (str == "Linfty_norm") + norm = VectorTools::Linfty_norm; + else if (str == "H1_seminorm") + norm = VectorTools::H1_seminorm; + else if (str == "Hdiv_seminorm") + norm = VectorTools::Hdiv_seminorm; + else if (str == "H1_norm") + norm = VectorTools::H1_norm; + else if (str == "W1p_seminorm") + norm = VectorTools::W1p_seminorm; + else if (str == "W1infty_seminorm") + norm = VectorTools::W1infty_seminorm; + else if (str == "W1infty_norm") + norm = VectorTools::W1infty_norm; + else if (str == "W1p_norm") + norm = VectorTools::W1p_norm; + else + { + AssertThrow(false, ExcMessage("Didn't recognize a norm type.")); + } + return norm; + } + }; + } // namespace Tools +} // namespace Patterns + DEAL_II_NAMESPACE_CLOSE #endif diff --git a/source/base/parsed_convergence_table.cc b/source/base/parsed_convergence_table.cc index d955bb0b64..ef324daefe 100644 --- a/source/base/parsed_convergence_table.cc +++ b/source/base/parsed_convergence_table.cc @@ -60,14 +60,14 @@ namespace ParsedConvergenceTable::ParsedConvergenceTable( - const std::vector &solution_names, - const std::vector> - &list_of_error_norms) + const std::vector & solution_names, + const std::vector> &list_of_error_norms) : ParsedConvergenceTable(solution_names, list_of_error_norms, - {ParsedConvergenceTableFlags::cells, - ParsedConvergenceTableFlags::dofs}, - ParsedConvergenceTableFlags::dofs, + 2.0, + {"cells", "dofs"}, + "dofs", + "reduction_rate_log2", "", 3, true, @@ -77,27 +77,31 @@ ParsedConvergenceTable::ParsedConvergenceTable( ParsedConvergenceTable::ParsedConvergenceTable( - const std::vector &component_names, - const std::vector> - &list_of_error_norms, - const std::set &extra_columns, - const ParsedConvergenceTableFlags::ExtraColumns & rate_key, - const std::string & error_file_name, - const unsigned int & precision, - const bool & compute_error, - const bool & output_error) + const std::vector & component_names, + const std::vector> &list_of_error_norms, + const double & exponent, + const std::set & extra_columns, + const std::string & rate_key, + const std::string & rate_mode, + const std::string & error_file_name, + const unsigned int & precision, + const bool & compute_error, + const bool & output_error) : component_names(component_names) , unique_component_names(get_unique_component_names(component_names)) , unique_component_masks(get_unique_component_masks(component_names)) , norms_per_unique_component(list_of_error_norms) + , exponent(exponent) , extra_columns(extra_columns) , rate_key(rate_key) + , rate_mode(rate_mode) , precision(precision) , error_file_name(error_file_name) , compute_error(compute_error) , output_error(output_error) { - AssertDimension(unique_component_names.size(), list_of_error_norms.size()); + AssertDimension(norms_per_unique_component.size(), + unique_component_names.size()); } @@ -132,16 +136,30 @@ ParsedConvergenceTable::add_parameters(ParameterHandler &prm) "and each norm by a comma. Implemented norms are Linfty, L2, " "W1infty, H1, and custom. If you want to skip a component, use none."); + + prm.add_parameter("Exponent for p-norms", + exponent, + "The exponent to use when computing p-norms.", + Patterns::Double(1)); + prm.add_parameter("Extra columns", extra_columns, "Extra columns to add to the table. Available options " - "are dofs, cells, and dt."); + "are dofs and cells.", + Patterns::List(Patterns::Selection("dofs|cells"))); prm.add_parameter("Rate key", rate_key, "Key to use when computing convergence rates. If " - "this is set to a column that is not present, or to none, " - "then no error rates are computed."); + "this is set to a column that is not present, or to the " + "empty string, then no error rates are computed."); + + prm.add_parameter("Rate mode", + rate_mode, + "What type of error rate to compute. Available options are " + "reduction_rate_log2, reduction_rate, and none.", + Patterns::Selection( + "reduction_rate|reduction_rate_log2|none")); } @@ -152,7 +170,7 @@ ParsedConvergenceTable::output_table(std::ostream &out) if (compute_error) { // Add convergence rates if the rate_key is not empty - if (rate_key != ParsedConvergenceTableFlags::no_columns) + if (rate_key != "") { bool has_key = false; for (const auto &col : extra_columns) @@ -160,14 +178,43 @@ ParsedConvergenceTable::output_table(std::ostream &out) if (rate_key == col) has_key = true; - if (col != ParsedConvergenceTableFlags::no_columns) + if (col != "") table.omit_column_from_convergence_rate_evaluation( Patterns::Tools::to_string(col)); } + + for (const auto &extra_col : extra_column_functions) + if (extra_col.second.second) + { + if (rate_key == extra_col.first) + has_key = true; + table.omit_column_from_convergence_rate_evaluation( + extra_col.first); + } + if (has_key) - table.evaluate_all_convergence_rates( - Patterns::Tools::to_string(rate_key), - ConvergenceTable::reduction_rate_log2); + { + if (rate_mode == "reduction_rate_log2") + table.evaluate_all_convergence_rates( + Patterns::Tools::to_string(rate_key), + ConvergenceTable::reduction_rate_log2); + else if (rate_mode == "reduction_rate") + table.evaluate_all_convergence_rates( + Patterns::Tools::to_string(rate_key), + ConvergenceTable::reduction_rate); + else + { + Assert(rate_mode != "none", ExcInternalError()); + } + } + else + { + AssertThrow(rate_key != "", + ExcMessage( + "You specified the key <" + rate_key + + "> to compute convergence rates, but that key does " + "not exist in the current table.")); + } } if (output_error) @@ -200,4 +247,16 @@ ParsedConvergenceTable::output_table(std::ostream &out) } } } + + + +void +ParsedConvergenceTable::add_extra_column( + const std::string & column_name, + const std::function &custom_function, + const bool & exclude_from_rates) +{ + extra_column_functions[column_name] = {custom_function, exclude_from_rates}; +} + DEAL_II_NAMESPACE_CLOSE diff --git a/tests/base/parsed_convergence_table_01.cc b/tests/base/parsed_convergence_table_01.cc index 0057e2c6f8..8a79e6dd2a 100644 --- a/tests/base/parsed_convergence_table_01.cc +++ b/tests/base/parsed_convergence_table_01.cc @@ -47,13 +47,15 @@ main() FE_Q<2> fe(1); DoFHandler<2> dh(tria); + Functions::CosineFunction<2> exact(1); + for (unsigned int i = 0; i < 5; ++i) { tria.refine_global(1); dh.distribute_dofs(fe); Vector sol(dh.n_dofs()); - VectorTools::interpolate(dh, Functions::CosineFunction<2>(1), sol); - table.error_from_exact(dh, sol, Functions::CosineFunction<2>(1)); + VectorTools::interpolate(dh, exact, sol); + table.error_from_exact(dh, sol, exact); } table.output_table(deallog.get_file_stream()); } diff --git a/tests/base/parsed_convergence_table_01.output b/tests/base/parsed_convergence_table_01.output index dda330200a..5e431ad0e4 100644 --- a/tests/base/parsed_convergence_table_01.output +++ b/tests/base/parsed_convergence_table_01.output @@ -1,7 +1,7 @@ -dofs cells u_Linfty u_L2 u_H1 -9 4 1.183e-01 - 5.156e-02 - 2.615e-01 - -25 16 3.291e-02 2.50 1.333e-02 2.65 1.272e-01 1.41 -81 64 8.449e-03 2.31 3.360e-03 2.34 6.313e-02 1.19 -289 256 2.126e-03 2.17 8.418e-04 2.18 3.150e-02 1.09 -1089 1024 5.325e-04 2.09 2.106e-04 2.09 1.574e-02 1.05 +cells dofs u_L2_norm u_Linfty_norm u_H1_norm +4 9 5.156e-02 - 1.183e-01 - 2.615e-01 - +16 25 1.333e-02 2.65 3.291e-02 2.50 1.272e-01 1.41 +64 81 3.360e-03 2.34 8.449e-03 2.31 6.313e-02 1.19 +256 289 8.418e-04 2.18 2.126e-03 2.17 3.150e-02 1.09 +1024 1089 2.106e-04 2.09 5.325e-04 2.09 1.574e-02 1.05 diff --git a/tests/base/parsed_convergence_table_02.output b/tests/base/parsed_convergence_table_02.output index 561d926930..6a5bfce2b9 100644 --- a/tests/base/parsed_convergence_table_02.output +++ b/tests/base/parsed_convergence_table_02.output @@ -3,6 +3,8 @@ DEAL:parameters::Enable computation of the errors: true DEAL:parameters::Enable output to streams: true DEAL:parameters::Error file name: DEAL:parameters::Error precision: 3 -DEAL:parameters::Extra columns: dofs, cells -DEAL:parameters::List of error norms to compute: Linfty, L2, H1 +DEAL:parameters::Exponent for p-norms: 2 +DEAL:parameters::Extra columns: cells, dofs +DEAL:parameters::List of error norms to compute: L2_norm, Linfty_norm, H1_norm DEAL:parameters::Rate key: dofs +DEAL:parameters::Rate mode: reduction_rate_log2 diff --git a/tests/base/parsed_convergence_table_03.cc b/tests/base/parsed_convergence_table_03.cc index 20b22cb24c..cc712f9ef3 100644 --- a/tests/base/parsed_convergence_table_03.cc +++ b/tests/base/parsed_convergence_table_03.cc @@ -39,8 +39,8 @@ main() initlog(); ParsedConvergenceTable table({"u", "v"}, - {{ParsedConvergenceTableFlags::L2}, - {ParsedConvergenceTableFlags::H1}}); + {{VectorTools::L2_norm}, + {VectorTools::H1_norm}}); ParameterHandler prm; table.add_parameters(prm); @@ -48,16 +48,17 @@ main() Triangulation<2> tria; GridGenerator::hyper_cube(tria); - FESystem<2> fe(FE_Q<2>(1), 2); - DoFHandler<2> dh(tria); + FESystem<2> fe(FE_Q<2>(1), 2); + DoFHandler<2> dh(tria); + Functions::CosineFunction<2> exact(2); for (unsigned int i = 0; i < 5; ++i) { tria.refine_global(1); dh.distribute_dofs(fe); Vector sol(dh.n_dofs()); - VectorTools::interpolate(dh, Functions::CosineFunction<2>(2), sol); - table.error_from_exact(dh, sol, Functions::CosineFunction<2>(2)); + VectorTools::interpolate(dh, exact, sol); + table.error_from_exact(dh, sol, exact); } table.output_table(deallog.get_file_stream()); } diff --git a/tests/base/parsed_convergence_table_03.output b/tests/base/parsed_convergence_table_03.output index 62170103fc..711d333342 100644 --- a/tests/base/parsed_convergence_table_03.output +++ b/tests/base/parsed_convergence_table_03.output @@ -1,7 +1,7 @@ -dofs cells u_L2 v_H1 -18 4 5.156e-02 - 2.615e-01 - -50 16 1.333e-02 2.65 1.272e-01 1.41 -162 64 3.360e-03 2.34 6.313e-02 1.19 -578 256 8.418e-04 2.18 3.150e-02 1.09 -2178 1024 2.106e-04 2.09 1.574e-02 1.05 +cells dofs u_L2_norm v_H1_norm +4 18 5.156e-02 - 2.615e-01 - +16 50 1.333e-02 2.65 1.272e-01 1.41 +64 162 3.360e-03 2.34 6.313e-02 1.19 +256 578 8.418e-04 2.18 3.150e-02 1.09 +1024 2178 2.106e-04 2.09 1.574e-02 1.05 diff --git a/tests/base/parsed_convergence_table_04.cc b/tests/base/parsed_convergence_table_04.cc index 3e00ece7bc..fa7132da1d 100644 --- a/tests/base/parsed_convergence_table_04.cc +++ b/tests/base/parsed_convergence_table_04.cc @@ -38,7 +38,7 @@ main() { initlog(); - ParsedConvergenceTable table({"u", "u"}, {{ParsedConvergenceTableFlags::L2}}); + ParsedConvergenceTable table({"u", "u"}, {{VectorTools::L2_norm}}); ParameterHandler prm; table.add_parameters(prm); @@ -46,16 +46,17 @@ main() Triangulation<2> tria; GridGenerator::hyper_cube(tria); - FESystem<2> fe(FE_Q<2>(1), 2); - DoFHandler<2> dh(tria); + FESystem<2> fe(FE_Q<2>(1), 2); + DoFHandler<2> dh(tria); + Functions::CosineFunction<2> exact(2); for (unsigned int i = 0; i < 5; ++i) { tria.refine_global(1); dh.distribute_dofs(fe); Vector sol(dh.n_dofs()); - VectorTools::interpolate(dh, Functions::CosineFunction<2>(2), sol); - table.error_from_exact(dh, sol, Functions::CosineFunction<2>(2)); + VectorTools::interpolate(dh, exact, sol); + table.error_from_exact(dh, sol, exact); } table.output_table(deallog.get_file_stream()); } diff --git a/tests/base/parsed_convergence_table_04.output b/tests/base/parsed_convergence_table_04.output index 1d09679cb4..d741b3bcde 100644 --- a/tests/base/parsed_convergence_table_04.output +++ b/tests/base/parsed_convergence_table_04.output @@ -1,7 +1,7 @@ -dofs cells u_L2 -18 4 7.291e-02 - -50 16 1.885e-02 2.65 -162 64 4.752e-03 2.34 -578 256 1.190e-03 2.18 -2178 1024 2.978e-04 2.09 +cells dofs u_L2_norm +4 18 7.291e-02 - +16 50 1.885e-02 2.65 +64 162 4.752e-03 2.34 +256 578 1.190e-03 2.18 +1024 2178 2.978e-04 2.09 diff --git a/tests/base/parsed_convergence_table_05.cc b/tests/base/parsed_convergence_table_05.cc index 8cfb65071a..e2970a3d70 100644 --- a/tests/base/parsed_convergence_table_05.cc +++ b/tests/base/parsed_convergence_table_05.cc @@ -39,8 +39,8 @@ main() initlog(); ParsedConvergenceTable table({"u", "u", "p"}, - {{ParsedConvergenceTableFlags::H1}, - {ParsedConvergenceTableFlags::L2}}); + {{VectorTools::H1_norm}, + {VectorTools::L2_norm}}); ParameterHandler prm; table.add_parameters(prm); @@ -51,13 +51,15 @@ main() FESystem<2> fe(FE_Q<2>(1), 3); DoFHandler<2> dh(tria); + Functions::CosineFunction<2> exact(3); + for (unsigned int i = 0; i < 5; ++i) { tria.refine_global(1); dh.distribute_dofs(fe); Vector sol(dh.n_dofs()); - VectorTools::interpolate(dh, Functions::CosineFunction<2>(3), sol); - table.error_from_exact(dh, sol, Functions::CosineFunction<2>(3)); + VectorTools::interpolate(dh, exact, sol); + table.error_from_exact(dh, sol, exact); } table.output_table(deallog.get_file_stream()); } diff --git a/tests/base/parsed_convergence_table_05.output b/tests/base/parsed_convergence_table_05.output index 1cc8dca7fc..c78d698078 100644 --- a/tests/base/parsed_convergence_table_05.output +++ b/tests/base/parsed_convergence_table_05.output @@ -1,7 +1,7 @@ -dofs cells u_H1 p_L2 -27 4 3.699e-01 - 5.156e-02 - -75 16 1.799e-01 1.41 1.333e-02 2.65 -243 64 8.927e-02 1.19 3.360e-03 2.34 -867 256 4.455e-02 1.09 8.418e-04 2.18 -3267 1024 2.226e-02 1.05 2.106e-04 2.09 +cells dofs u_H1_norm p_L2_norm +4 27 3.699e-01 - 5.156e-02 - +16 75 1.799e-01 1.41 1.333e-02 2.65 +64 243 8.927e-02 1.19 3.360e-03 2.34 +256 867 4.455e-02 1.09 8.418e-04 2.18 +1024 3267 2.226e-02 1.05 2.106e-04 2.09 diff --git a/tests/base/parsed_convergence_table_06.cc b/tests/base/parsed_convergence_table_06.cc index 0bf129ea0d..0f26c7966c 100644 --- a/tests/base/parsed_convergence_table_06.cc +++ b/tests/base/parsed_convergence_table_06.cc @@ -36,11 +36,9 @@ int main() { - initlog(); + initlog(1); - ParsedConvergenceTable table({"u", "u", "p"}, - {{ParsedConvergenceTableFlags::H1}, - {ParsedConvergenceTableFlags::none}}); + ParsedConvergenceTable table({"u", "u", "p"}, {{VectorTools::H1_norm}, {}}); ParameterHandler prm; table.add_parameters(prm); @@ -51,13 +49,15 @@ main() FESystem<2> fe(FE_Q<2>(1), 3); DoFHandler<2> dh(tria); + Functions::CosineFunction<2> exact(3); + for (unsigned int i = 0; i < 5; ++i) { tria.refine_global(1); dh.distribute_dofs(fe); Vector sol(dh.n_dofs()); - VectorTools::interpolate(dh, Functions::CosineFunction<2>(3), sol); - table.error_from_exact(dh, sol, Functions::CosineFunction<2>(3)); + VectorTools::interpolate(dh, exact, sol); + table.error_from_exact(dh, sol, exact); } table.output_table(deallog.get_file_stream()); } diff --git a/tests/base/parsed_convergence_table_06.output b/tests/base/parsed_convergence_table_06.output index 07e887e86c..5d4cec934c 100644 --- a/tests/base/parsed_convergence_table_06.output +++ b/tests/base/parsed_convergence_table_06.output @@ -1,7 +1,7 @@ -dofs cells u_H1 -27 4 3.699e-01 - -75 16 1.799e-01 1.41 -243 64 8.927e-02 1.19 -867 256 4.455e-02 1.09 -3267 1024 2.226e-02 1.05 +cells dofs u_H1_norm +4 27 3.699e-01 - +16 75 1.799e-01 1.41 +64 243 8.927e-02 1.19 +256 867 4.455e-02 1.09 +1024 3267 2.226e-02 1.05 diff --git a/tests/base/parsed_convergence_table_07.cc b/tests/base/parsed_convergence_table_07.cc index 81a216edf0..a8194fc145 100644 --- a/tests/base/parsed_convergence_table_07.cc +++ b/tests/base/parsed_convergence_table_07.cc @@ -38,7 +38,7 @@ main() { initlog(); - ParsedConvergenceTable table({"u"}, {{ParsedConvergenceTableFlags::custom}}); + ParsedConvergenceTable table({"u"}, {{}}); ParameterHandler prm; table.add_parameters(prm); @@ -49,12 +49,16 @@ main() FESystem<2> fe(FE_Q<2>(1), 1); DoFHandler<2> dh(tria); + Functions::CosineFunction<2> exact(1); + for (unsigned int i = 0; i < 5; ++i) { tria.refine_global(1); dh.distribute_dofs(fe); - auto cycle = [&](const unsigned int) { return (i + 1) * 1.0; }; - table.custom_error(cycle, dh, "cycle", true); + Vector sol(dh.n_dofs()); + auto cycle = [&]() { return (i + 1) * 1.0; }; + table.add_extra_column("cycle", cycle); + table.error_from_exact(dh, sol, exact); } table.output_table(deallog.get_file_stream()); } diff --git a/tests/base/parsed_convergence_table_07.output b/tests/base/parsed_convergence_table_07.output index fe2d44fefa..5648c34f96 100644 --- a/tests/base/parsed_convergence_table_07.output +++ b/tests/base/parsed_convergence_table_07.output @@ -1,7 +1,7 @@ -dofs cells u_cycle -9 4 1.000e+00 - -25 16 2.000e+00 -1.36 -81 64 3.000e+00 -0.69 -289 256 4.000e+00 -0.45 -1089 1024 5.000e+00 -0.34 +cells dofs cycle +4 9 1.000e+00 - +16 25 2.000e+00 -1.36 +64 81 3.000e+00 -0.69 +256 289 4.000e+00 -0.45 +1024 1089 5.000e+00 -0.34 diff --git a/tests/base/parsed_convergence_table_08.cc b/tests/base/parsed_convergence_table_08.cc index cbe4ee3562..2d0be867b6 100644 --- a/tests/base/parsed_convergence_table_08.cc +++ b/tests/base/parsed_convergence_table_08.cc @@ -38,12 +38,12 @@ main() { initlog(); - ParsedConvergenceTable table({"u"}, {{ParsedConvergenceTableFlags::custom}}); + ParsedConvergenceTable table({"u"}, {{}}); ParameterHandler prm; table.add_parameters(prm); - std::string input = "set Extra columns = none\n"; + std::string input = "set Extra columns = \n"; prm.parse_input_from_string(input); @@ -53,12 +53,17 @@ main() FESystem<2> fe(FE_Q<2>(1), 1); DoFHandler<2> dh(tria); + Functions::CosineFunction<2> exact(1); + for (unsigned int i = 0; i < 5; ++i) { tria.refine_global(1); dh.distribute_dofs(fe); - auto cycle = [&](const unsigned int) { return (i + 1) * 1.0; }; - table.custom_error(cycle, dh, "cycle", true); + Vector sol(dh.n_dofs()); + + auto cycle = [&]() { return (i + 1) * 1.0; }; + table.add_extra_column("cycle", cycle); + table.error_from_exact(dh, sol, exact); } table.output_table(deallog.get_file_stream()); } diff --git a/tests/base/parsed_convergence_table_08.output b/tests/base/parsed_convergence_table_08.output index 1a27569374..c59dd3911d 100644 --- a/tests/base/parsed_convergence_table_08.output +++ b/tests/base/parsed_convergence_table_08.output @@ -1,5 +1,5 @@ - u_cycle + cycle 1.000e+00 2.000e+00 3.000e+00 diff --git a/tests/base/parsed_convergence_table_09.cc b/tests/base/parsed_convergence_table_09.cc index 05a07c6245..db0c0aad23 100644 --- a/tests/base/parsed_convergence_table_09.cc +++ b/tests/base/parsed_convergence_table_09.cc @@ -38,12 +38,12 @@ main() { initlog(); - ParsedConvergenceTable table({"u"}, {{ParsedConvergenceTableFlags::custom}}); + ParsedConvergenceTable table({"u"}, {{}}); ParameterHandler prm; table.add_parameters(prm); - std::string input = "set Extra columns = dt\n" + std::string input = "set Extra columns = \n" "set Rate key = dt\n"; prm.parse_input_from_string(input); @@ -54,12 +54,20 @@ main() FESystem<2> fe(FE_Q<2>(1), 1); DoFHandler<2> dh(tria); + Functions::CosineFunction<2> exact(1); + for (unsigned int i = 0; i < 5; ++i) { tria.refine_global(1); dh.distribute_dofs(fe); - auto cycle = [&](const unsigned int) { return (i + 1) * 1.0; }; - table.custom_error(cycle, dh, "cycle", true, 1.0 / (i * i + 1)); + Vector sol(dh.n_dofs()); + + auto cycle = [&]() { return (i + 1) * 1.0; }; + auto dt = [&]() { return 1.0 / (i * i + 1); }; + + table.add_extra_column("cycle", cycle); + table.add_extra_column("dt", dt); + table.error_from_exact(dh, sol, exact); } table.output_table(deallog.get_file_stream()); } diff --git a/tests/base/parsed_convergence_table_09.output b/tests/base/parsed_convergence_table_09.output index 9b5f696c0d..31787d7683 100644 --- a/tests/base/parsed_convergence_table_09.output +++ b/tests/base/parsed_convergence_table_09.output @@ -1,7 +1,7 @@ - dt u_cycle -1.0000 1.000e+00 - -0.5000 2.000e+00 2.00 -0.2000 3.000e+00 0.89 -0.1000 4.000e+00 0.83 -0.0588 5.000e+00 0.84 + cycle dt +1.000e+00 1.000e+00 +2.000e+00 5.000e-01 +3.000e+00 2.000e-01 +4.000e+00 1.000e-01 +5.000e+00 5.882e-02 diff --git a/tests/base/parsed_convergence_table_10.cc b/tests/base/parsed_convergence_table_10.cc index af3c9a43ee..cb3c5ca838 100644 --- a/tests/base/parsed_convergence_table_10.cc +++ b/tests/base/parsed_convergence_table_10.cc @@ -38,13 +38,13 @@ main() { initlog(); - ParsedConvergenceTable table({"u"}, {{ParsedConvergenceTableFlags::custom}}); + ParsedConvergenceTable table({"u"}, {{}}); ParameterHandler prm; table.add_parameters(prm); - std::string input = "set Extra columns = dt, dofs, cells\n" - "set Rate key = cells\n" + std::string input = "set Extra columns = dofs, cells\n" + "set Rate key = dt\n" "set Enable output to streams = false\n"; prm.parse_input_from_string(input); @@ -55,14 +55,20 @@ main() FESystem<2> fe(FE_Q<2>(1), 1); DoFHandler<2> dh(tria); + Functions::CosineFunction<2> exact(1); + for (unsigned int i = 0; i < 5; ++i) { tria.refine_global(1); dh.distribute_dofs(fe); - auto cycle = [&](const unsigned int) { - return 1.0 / ((i + 1) * (i + 1)); - }; - table.custom_error(cycle, dh, "cycle", true, i + 1); + Vector sol(dh.n_dofs()); + + auto cycle = [&]() { return (i + 1) * 1.0; }; + auto dt = [&]() { return i + 1.0; }; + + table.add_extra_column("cycle", cycle); + table.add_extra_column("dt", dt, true); + table.error_from_exact(dh, sol, exact); } input = "set Error file name = error.txt\n"; diff --git a/tests/base/parsed_convergence_table_10.output b/tests/base/parsed_convergence_table_10.output index f1d7508a0e..d33f4d1576 100644 --- a/tests/base/parsed_convergence_table_10.output +++ b/tests/base/parsed_convergence_table_10.output @@ -1,17 +1,17 @@ -dofs cells dt u_cycle - 9 4 1.0000 1.000e+00 - - 25 16 2.0000 2.500e-01 2.00 - 81 64 3.0000 1.111e-01 1.17 - 289 256 4.0000 6.250e-02 0.83 -1089 1024 5.0000 4.000e-02 0.64 +cells dofs cycle dt + 4 9 1.000e+00 - 1.000e+00 + 16 25 2.000e+00 -2.00 2.000e+00 + 64 81 3.000e+00 -2.00 3.000e+00 + 256 289 4.000e+00 -2.00 4.000e+00 + 1024 1089 5.000e+00 -2.00 5.000e+00 -| dofs | cells | dt | u_cycle | u_cycle...red.rate.log2 | -| 9 | 4 | 1.0000 | 1.000e+00 | - | -| 25 | 16 | 2.0000 | 2.500e-01 | 2.00 | -| 81 | 64 | 3.0000 | 1.111e-01 | 1.17 | -| 289 | 256 | 4.0000 | 6.250e-02 | 0.83 | -| 1089 | 1024 | 5.0000 | 4.000e-02 | 0.64 | +| cells | dofs | cycle | cycle...red.rate.log2 | dt | +| 4 | 9 | 1.000e+00 | - | 1.000e+00 | +| 16 | 25 | 2.000e+00 | -2.00 | 2.000e+00 | +| 64 | 81 | 3.000e+00 | -2.00 | 3.000e+00 | +| 256 | 289 | 4.000e+00 | -2.00 | 4.000e+00 | +| 1024 | 1089 | 5.000e+00 | -2.00 | 5.000e+00 | \documentclass[10pt]{report} \usepackage{float} @@ -20,14 +20,14 @@ dofs cells dt u_cycle \begin{document} \begin{table}[H] \begin{center} -\begin{tabular}{|r|r|r|c|c|} \hline -\# dofs & \# cells & \Delta t & -\multicolumn{2}{|c|}{$\| u - u_h \|_{\text{cycle} $}\\ \hline -9 & 4 & 1.0000 & 1.000e+00 & -\\ \hline -25 & 16 & 2.0000 & 2.500e-01 & 2.00\\ \hline -81 & 64 & 3.0000 & 1.111e-01 & 1.17\\ \hline -289 & 256 & 4.0000 & 6.250e-02 & 0.83\\ \hline -1089 & 1024 & 5.0000 & 4.000e-02 & 0.64\\ \hline +\begin{tabular}{|r|r|c|c|c|} \hline +\# cells & \# dofs & +\multicolumn{2}{|c|}{cycle} & dt\\ \hline +4 & 9 & 1.000e+00 & - & 1.000e+00\\ \hline +16 & 25 & 2.000e+00 & -2.00 & 2.000e+00\\ \hline +64 & 81 & 3.000e+00 & -2.00 & 3.000e+00\\ \hline +256 & 289 & 4.000e+00 & -2.00 & 4.000e+00\\ \hline +1024 & 1089 & 5.000e+00 & -2.00 & 5.000e+00\\ \hline \end{tabular} \end{center} \end{table}