deal2lkit: A ToolKit library for Deal.II
error_handler.cc
Go to the documentation of this file.
1 //-----------------------------------------------------------
2 //
3 // Copyright (C) 2015 by the deal2lkit authors
4 //
5 // This file is part of the deal2lkit library.
6 //
7 // The deal2lkit 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 at
12 // the top level of the deal2lkit distribution.
13 //
14 //-----------------------------------------------------------
15 
17 
18 #include <deal.II/base/logstream.h>
20 #include <deal.II/base/utilities.h>
22 
24 
28 #include <deal.II/fe/mapping_q.h>
29 #include <deal.II/fe/fe.h>
30 #include <cstdio>
31 #include <iostream>
32 #include <fstream>
33 #include <vector>
34 #include <string>
35 
36 
37 D2K_NAMESPACE_OPEN
38 
39 template <int ntables>
40 ErrorHandler<ntables>::ErrorHandler ( const std::string name,
41  const std::string solution_names,
42  const std::string list_of_error_norms
43  ) :
44  ParameterAcceptor(name),
45  solution_names(solution_names),
46  list_of_error_norms(list_of_error_norms)
47 {
48  initialized = false;
49 }
50 
51 template <int ntables>
53 {
54  std::string dummy_names;
55  if (ntables > 1)
56  {
57  for (unsigned int i=0; i<ntables-1; ++i)
58  {
59  dummy_names = dummy_names + "error"+Utilities::int_to_string(i)+", ";
60  }
61  dummy_names = dummy_names + "error"+Utilities::int_to_string(ntables);
62  }
63  else
64  dummy_names = dummy_names + "error";
65  prm.declare_entry ("Write error files", "false", Patterns::Bool());
66  prm.declare_entry ("Output error tables", "true", Patterns::Bool());
67  prm.declare_entry ("Error file format", "tex", Patterns::Selection("tex|txt|gpl|org"));
68  prm.declare_entry ("Compute error", "true", Patterns::Bool());
69  prm.declare_entry ("Table names", dummy_names, Patterns::List(Patterns::Anything(), ntables, ntables),
70  "Comma separated list of table names. ");
71  prm.declare_entry ("Error precision", "3", Patterns::Integer());
72  prm.declare_entry ("Solution names", solution_names, Patterns::Anything(),
73  "Comma separated list of names for the components. This "
74  "will be used both for error tables in text format and to "
75  "output the solution to a file. Note that in the case "
76  "of a vector function the error name which is used to "
77  "compute the norm (supposing the type of the other "
78  "components is 'Add') is the first one.");
79  prm.declare_entry ("Solution names for latex", solution_names, Patterns::Anything(),
80  "Comma separated version of the same thing as above for "
81  "the latex version of the table.");
82 
83  // prm.declare_entry ("Ib output format", "msh", Patterns::Selection("raw|msh"));
84  // prm.declare_entry ("Ib input file prefix", "ellipse", Patterns::Anything());
85  for (unsigned int i=0; i<ntables; ++i)
86  {
87  char tmp[10];
88  sprintf(tmp, "Table %d", i);
89  prm.enter_subsection(tmp);
90 
91  prm.declare_entry("List of error norms to compute", list_of_error_norms,
92  Patterns::Anything(), "Each component is separated by a semicolon, "
93  "and each norm by a comma. Implemented norms are Linfty, L2, "
94  "H1, AddUp, which means that the norm is added to the previous "
95  "component, and Custom.");
96  prm.declare_entry("Add convergence rates", "true", Patterns::Bool(),
97  "Evaluate convergence rates and add a column to the table for each "
98  "computed norm. ");
99  prm.declare_entry("Latex table caption", "error", Patterns::Anything(),
100  "The caption that will go under the table if we write the file in "
101  "tex format. The default value for this object is the same name "
102  "as the table name.");
103  prm.declare_entry("Extra terms", "cells,dofs",
105  "The extra columns to add to the table.");
106  prm.declare_entry("Rate key", "",
107  Patterns::Selection("dofs|cells|dt|"),
108  "The key to use to compute the convergence rates.");
109  prm.leave_subsection();
110  }
111 }
112 
113 template <int ntables>
115 {
116  write_error = prm.get_bool ("Write error files");
117  output_error = prm.get_bool ("Output error tables");
118 
119  error_file_format = prm.get ("Error file format");
120  compute_error = prm.get_bool ("Compute error");
121  std::string all_names = prm.get ("Table names");
122  precision = prm.get_integer ("Error precision");
123  headers = Utilities::split_string_list(prm.get ("Solution names"));
124  latex_headers = Utilities::split_string_list(prm.get ("Solution names for latex"));
125 
126  if (all_names != "")
127  {
128  names = Utilities::split_string_list(all_names);
129  Assert(names.size() <= ntables,
130  ExcMessage("You tried to construct more tables than you have compiled for."));
131  types.resize(names.size(), std::vector<NormFlags> (headers.size()));
132  add_rates.resize(names.size());
133  tables.resize(names.size());
134  latex_captions.resize(names.size());
135  std::map<std::string, bool> extra;
136  extra["dof"] = false;
137  extra["cells"] = false;
138  extra["dt"] = false;
139 
140  extras.resize(names.size(), extra);
141  rate_keys.resize(names.size(), "");
142 
143  for (unsigned int i=0; i<names.size(); ++i)
144  {
145  char tmp[10];
146  sprintf(tmp, "Table %d", i);
147  prm.enter_subsection(tmp);
148 
149  all_names = prm.get("List of error norms to compute");
150  add_rates[i] = prm.get_bool("Add convergence rates");
151  rate_keys[i] = prm.get("Rate key");
152  latex_captions[i] = prm.get("Latex table caption");
153  std::vector<std::string> all_extras =
154  Utilities::split_string_list(prm.get("Extra terms"));
155 
156  for (unsigned int x=0; x< all_extras.size(); ++x)
157  extras[i][all_extras[x]] = true;
158 
159  prm.leave_subsection();
160 
161  std::vector<std::string> all_comps = Utilities::split_string_list(all_names, ';');
162  // Check that the input string has all the needed fields
163  AssertThrow(all_comps.size() == headers.size(),
164  ExcDimensionMismatch(all_comps.size() , headers.size()));
165 
166  for (unsigned int j=0; j<all_comps.size(); ++j)
167  {
168  std::vector<std::string> all_types =
169  Utilities::split_string_list(all_comps[j]);
170  // If we named it the same, defaults to AddUp
171  if (j>0 && headers[j] == headers[j-1])
172  {
173  types[i][j] |= AddUp;
174  continue;
175  }
176  for (unsigned int k=0; k<all_types.size(); ++k)
177  {
178  if (all_types[k] == "Linfty")
179  {
180  types[i][j] |= Linfty;
181  }
182  else if (all_types[k] == "L2")
183  {
184  types[i][j] |= L2;
185  }
186  else if (all_types[k] == "W1infty")
187  {
188  types[i][j] |= W1infty;
189  }
190  else if (all_types[k] == "H1")
191  {
192  types[i][j] |= H1;
193  }
194  else if (all_types[k] == "AddUp")
195  {
196  types[i][j] |= AddUp;
197  }
198  else if (all_types[k] == "Custom")
199  {
200  types[i][j] |= Custom;
201  }
202  else
203  {
204  AssertThrow(false, ExcMessage("Didn't recognize a norm type."));
205  }
206  }
207  }
208  }
209  }
210  initialized = true;
211 }
212 
213 template <int ntables>
214 void ErrorHandler<ntables>::output_table (std::ostream &out, const unsigned int table_no)
215 {
216  if (compute_error)
217  {
219  AssertThrow(table_no < names.size(), ExcIndexRange(table_no, 0, names.size()));
220 
221  // Add convergence rates
222  if (add_rates[table_no])
223  {
224  if (extras[table_no]["dofs"])
225  tables[table_no].omit_column_from_convergence_rate_evaluation("dofs");
226  if (extras[table_no]["cells"])
227  tables[table_no].omit_column_from_convergence_rate_evaluation("cells");
228  if (extras[table_no]["dt"])
229  tables[table_no].omit_column_from_convergence_rate_evaluation("dt");
230  if (rate_keys[table_no] == "")
231  tables[table_no].evaluate_all_convergence_rates(ConvergenceTable::reduction_rate_log2);
232  else
233  tables[table_no].evaluate_all_convergence_rates(rate_keys[table_no], ConvergenceTable::reduction_rate_log2);
234  }
235 
236  if (output_error) tables[table_no].write_text(out);
237 
238  if (write_error)
239  {
240  std::string filename = names[table_no] +
241  "." + error_file_format;
242 
243  std::ofstream table_file(filename.c_str());
244 
245  if (error_file_format == "tex")
246  tables[table_no].write_tex(table_file);
247  else if (error_file_format == "txt")
248  tables[table_no].write_text(table_file);
249  else if (error_file_format == "gpl")
250  tables[table_no].write_text(table_file,
252  else if (error_file_format == "org")
253  tables[table_no].write_text(table_file,
255  table_file.close();
256  }
257  }
258 }
259 
260 template <int ntables>
261 void ErrorHandler<ntables>::output_table (ConditionalOStream &pcout, const unsigned int table_no)
262 {
263  if ( pcout.is_active() ) output_table (pcout.get_stream(), table_no);
264 }
265 
266 D2K_NAMESPACE_CLOSE
267 
268 
269 template class deal2lkit::ErrorHandler<1>;
270 template class deal2lkit::ErrorHandler<2>;
271 template class deal2lkit::ErrorHandler<3>;
272 template class deal2lkit::ErrorHandler<4>;
table_with_separate_column_description
A parameter acceptor base class.
static ParameterHandler prm
Static parameter.
bool compute_error
Compute the error.
std::vector< ConvergenceTable > tables
Error results.
ErrorHandler(const std::string name="", const std::string solution_names="u", const std::string list_of_error_norms="Linfty, L2, H1")
The constructor takes an optional name, specifying the parameter entry.
static::ExceptionBase & ExcNotInitialized()
#define AssertThrow(cond, exc)
static::ExceptionBase & ExcIndexRange(int arg1, int arg2, int arg3)
std::string get(const std::string &entry_string) const
std::ostream & get_stream() const
void enter_subsection(const std::string &subsection)
static::ExceptionBase & ExcMessage(std::string arg1)
const std::string list_of_error_norms
List of error norms to compute.
unsigned int precision
The precision with which the table is written.
virtual void declare_parameters(ParameterHandler &prm)
Initialize the given values for the paramter file.
std::string error_file_format
The error file format.
#define Assert(cond, exc)
static::ExceptionBase & ExcDimensionMismatch(std::size_t arg1, std::size_t arg2)
bool output_error
Output the error file also on screen.
std::vector< std::string > latex_headers
Headers for latex tables.
std::vector< std::string > headers
Headers for tables and output.
void output_table(std::ostream &out=std::cout, const unsigned int table_no=0)
By default output first table.
bool initialized
The parameters have been read.
std::string int_to_string(const unsigned int value, const unsigned int digits=numbers::invalid_unsigned_int)
void leave_subsection()
bool get_bool(const std::string &entry_name) const
virtual void parse_parameters(ParameterHandler &prm)
Parse the given parameter handler.
std::vector< std::map< std::string, bool > > extras
The extra column to add to the tables.
std::vector< std::string > rate_keys
Wether or not to calculate the rates according to the given keys.
std::vector< std::string > names
Names of the tables.
std::vector< std::string > split_string_list(const std::string &s, const char delimiter=',')
void declare_entry(const std::string &entry, const std::string &default_value, const Patterns::PatternBase &pattern=Patterns::Anything(), const std::string &documentation=std::string())
std::vector< std::string > latex_captions
Captions for latex.
std::vector< bool > add_rates
Add convergence rates.
bool is_active() const
bool write_error
Write the error files.
const std::string solution_names
Value of solution names.
long int get_integer(const std::string &entry_string) const