Reference documentation for deal.II version 9.5.0
\(\newcommand{\dealvcentcolon}{\mathrel{\mathop{:}}}\) \(\newcommand{\dealcoloneq}{\dealvcentcolon\mathrel{\mkern-1.2mu}=}\) \(\newcommand{\jump}[1]{\left[\!\left[ #1 \right]\!\right]}\) \(\newcommand{\average}[1]{\left\{\!\left\{ #1 \right\}\!\right\}}\)
Loading...
Searching...
No Matches
parsed_convergence_table.cc
Go to the documentation of this file.
1// ---------------------------------------------------------------------
2//
3// Copyright (C) 2019 - 2022 by the deal.II authors
4//
5// This file is part of the deal.II library.
6//
7// The deal.II library is free software; you can use it, redistribute
8// it, and/or modify it under the terms of the GNU Lesser General
9// Public License as published by the Free Software Foundation; either
10// version 2.1 of the License, or (at your option) any later version.
11// The full text of the license can be found in the file LICENSE.md at
12// the top level directory of deal.II.
13//
14// ---------------------------------------------------------------------
15
20
22
23namespace
24{
25 std::vector<std::string>
26 get_unique_component_names(const std::vector<std::string> &component_names)
27 {
28 auto elements = component_names;
29 auto last = std::unique(elements.begin(), elements.end());
30 elements.resize(last - elements.begin());
31 return elements;
32 }
33
34
35
36 std::vector<ComponentMask>
37 get_unique_component_masks(const std::vector<std::string> &component_names)
38 {
39 const auto unique_component_names =
40 get_unique_component_names(component_names);
41
42 std::vector<ComponentMask> masks;
43
44 std::vector<std::vector<bool>> bools(
45 unique_component_names.size(),
46 std::vector<bool>(component_names.size(), false));
47
48 unsigned int j = 0;
49 for (unsigned int i = 0; i < component_names.size(); ++i)
50 {
51 if (unique_component_names[j] != component_names[i])
52 masks.emplace_back(bools[j++]);
53 bools[j][i] = true;
54 }
55 masks.emplace_back(bools[j++]);
56 AssertDimension(j, unique_component_names.size());
57 return masks;
58 }
59} // namespace
60
61
62
64 const std::vector<std::string> & solution_names,
65 const std::vector<std::set<VectorTools::NormType>> &list_of_error_norms)
66 : ParsedConvergenceTable(solution_names,
67 list_of_error_norms,
68 2.0,
69 {"cells", "dofs"},
70 "dofs",
71 "reduction_rate_log2",
72 "",
73 3,
74 true)
75{}
76
77
78
80 const std::vector<std::string> & component_names,
81 const std::vector<std::set<VectorTools::NormType>> &list_of_error_norms,
82 const double exponent,
83 const std::set<std::string> & extra_columns,
84 const std::string & rate_key,
85 const std::string & rate_mode,
86 const std::string & error_file_name,
87 const unsigned int precision,
88 const bool compute_error)
89 : component_names(component_names)
90 , unique_component_names(get_unique_component_names(component_names))
91 , unique_component_masks(get_unique_component_masks(component_names))
92 , norms_per_unique_component(list_of_error_norms)
93 , exponent(exponent)
94 , extra_columns(extra_columns)
95 , rate_key(rate_key)
96 , rate_mode(rate_mode)
97 , precision(precision)
98 , error_file_name(error_file_name)
99 , compute_error(compute_error)
100{
103}
104
105
106
107void
109{
110 prm.add_parameter("Enable computation of the errors",
112 "When set to false, no computations are performed.");
113
114 prm.add_parameter("Error precision",
115 precision,
116 "Number of digits to use when printing the error.",
118
119 prm.add_parameter("Error file name",
121 "Set this to a filename with extension .txt, .gpl, .org, "
122 "or .tex to enable writing the convergence table to a "
123 "file.");
124
125 prm.add_parameter(
126 "List of error norms to compute",
128 "Each component is separated by a semicolon "
129 "and each norm by a comma. See the documentation of VectorTools::NormType "
130 "for a list of implemented norms. If you want to skip a component, leave "
131 "its entry empty.");
132
133
134 prm.add_parameter("Exponent for p-norms",
135 exponent,
136 "The exponent to use when computing p-norms.",
138
139 prm.add_parameter("Extra columns",
141 "Extra columns to add to the table. Available options "
142 "are dofs and cells.",
143 Patterns::List(Patterns::Selection("dofs|cells")));
144
145 prm.add_parameter("Rate key",
146 rate_key,
147 "Key to use when computing convergence rates. If "
148 "this is set to a column that is not present, or to the "
149 "empty string, then no error rates are computed.");
150
151 prm.add_parameter("Rate mode",
152 rate_mode,
153 "What type of error rate to compute. Available options are "
154 "reduction_rate_log2, reduction_rate, and none.",
156 "reduction_rate|reduction_rate_log2|none"));
157}
158
159
160
161void
163{
164 if (compute_error)
165 {
166 // Add convergence rates if the rate_key is not empty
167 if (rate_key != "")
168 {
169 bool has_key = false;
170 for (const auto &col : extra_columns)
171 {
172 if (rate_key == col)
173 has_key = true;
174
175 if (col != "")
177 }
178
179 for (const auto &extra_col : extra_column_functions)
180 if (extra_col.second.second == false)
181 {
182 if (rate_key == extra_col.first)
183 has_key = true;
185 extra_col.first);
186 }
187
188 if (has_key)
189 {
190 if (rate_mode == "reduction_rate_log2")
193 else if (rate_mode == "reduction_rate")
196 else
197 {
198 Assert(rate_mode != "none", ExcInternalError());
199 }
200 }
201 else
202 {
203 AssertThrow(rate_key != "",
205 "You specified the key <" + rate_key +
206 "> to compute convergence rates, but that key does "
207 "not exist in the current table."));
208 }
209 }
210 }
211}
212
213
214
215void
217{
218 if (compute_error)
219 {
221 table.write_text(out);
222 output_table();
223 }
224}
225
226
227
228void
230{
231 if (compute_error && error_file_name != "")
232 {
234
235 const std::string error_file_format =
236 error_file_name.substr(error_file_name.find_last_of('.') + 1);
237
238 std::ofstream table_file(error_file_name);
239
240 if (error_file_format == "tex")
241 table.write_tex(table_file);
242 else if (error_file_format == "txt")
243 table.write_text(table_file);
244 else if (error_file_format == "gpl")
245 table.write_text(table_file,
247 else if (error_file_format == "org")
249 else
250 {
251 AssertThrow(false,
253 std::string("Unrecognized file format: ") +
254 error_file_format));
255 }
256 table_file.close();
257 }
258}
259
260
261
262void
264 const std::string & column_name,
265 const std::function<double()> &custom_function,
266 const bool compute_rate)
267{
268 extra_column_functions[column_name] = {custom_function, compute_rate};
269}
270
void evaluate_all_convergence_rates(const std::string &reference_column_key, const RateMode rate_mode)
void omit_column_from_convergence_rate_evaluation(const std::string &key)
void add_parameter(const std::string &entry, ParameterType &parameter, const std::string &documentation="", const Patterns::PatternBase &pattern= *Patterns::Tools::Convert< ParameterType >::to_pattern(), const bool has_to_be_set=false)
The ParsedConvergenceTable class.
void add_extra_column(const std::string &column_name, const std::function< double()> &custom_function, const bool compute_rate=true)
void add_parameters(ParameterHandler &prm)
std::set< std::string > extra_columns
ParsedConvergenceTable(const std::vector< std::string > &component_names={"u"}, const std::vector< std::set< VectorTools::NormType > > &list_of_error_norms={ {VectorTools::H1_norm, VectorTools::L2_norm, VectorTools::Linfty_norm}})
const std::vector< std::string > unique_component_names
std::vector< std::set< VectorTools::NormType > > norms_per_unique_component
std::map< std::string, std::pair< std::function< double()>, bool > > extra_column_functions
void write_text(std::ostream &out, const TextOutputFormat format=table_with_headers) const
@ table_with_separate_column_description
void write_tex(std::ostream &file, const bool with_header=true) const
#define DEAL_II_NAMESPACE_OPEN
Definition config.h:472
#define DEAL_II_NAMESPACE_CLOSE
Definition config.h:473
#define Assert(cond, exc)
#define AssertDimension(dim1, dim2)
static ::ExceptionBase & ExcInternalError()
static ::ExceptionBase & ExcMessage(std::string arg1)
#define AssertThrow(cond, exc)