Reference documentation for deal.II version GIT 49863513f1 2023-10-02 19:40:02+00:00
\(\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\}}\)
parameter_handler.h
Go to the documentation of this file.
1 // ---------------------------------------------------------------------
2 //
3 // Copyright (C) 1998 - 2023 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 
16 #ifndef dealii_parameter_handler_h
17 #define dealii_parameter_handler_h
18 
19 
20 #include <deal.II/base/config.h>
21 
23 #include <deal.II/base/patterns.h>
25 
26 #include <boost/archive/basic_archive.hpp>
27 #include <boost/property_tree/ptree_fwd.hpp>
28 #include <boost/property_tree/ptree_serialization.hpp>
29 #include <boost/serialization/split_member.hpp>
30 
31 #include <map>
32 #include <memory>
33 #include <string>
34 #include <vector>
35 
37 
38 // forward declarations for interfaces and friendship
39 #ifndef DOXYGEN
40 class LogStream;
42 #endif
43 
856 {
857 public:
874  {
879  DefaultStyle = 0x0000,
880 
885  Short = 0x0001,
886 
891 
896  PRM = 0x0010,
897 
905 
909  LaTeX = 0x0020,
910 
916  Description = 0x0040,
917 
925  XML = 0x0080,
926 
932  JSON = 0x0100,
933 
939 
947 
953 
959 
965  };
966 
967 
968 
973 
979  virtual ~ParameterHandler() override = default;
980 
985 
990  operator=(const ParameterHandler &) = delete;
991 
1026  virtual void
1027  parse_input(std::istream &input,
1028  const std::string &filename = "input file",
1029  const std::string &last_line = "",
1030  const bool skip_undefined = false);
1031 
1053  virtual void
1054  parse_input(const std::string &filename,
1055  const std::string &last_line = "",
1056  const bool skip_undefined = false,
1057  const bool assert_mandatory_entries_are_found = false);
1058 
1067  virtual void
1068  parse_input_from_string(const std::string &s,
1069  const std::string &last_line = "",
1070  const bool skip_undefined = false);
1071 
1079  virtual void
1080  parse_input_from_xml(std::istream &input, const bool skip_undefined = false);
1081 
1089  virtual void
1090  parse_input_from_json(std::istream &input, const bool skip_undefined = false);
1091 
1095  void
1096  clear();
1097 
1098 
1124  void
1125  declare_entry(const std::string &entry,
1126  const std::string &default_value,
1127  const Patterns::PatternBase &pattern = Patterns::Anything(),
1128  const std::string &documentation = "",
1129  const bool has_to_be_set = false);
1130 
1178  void
1179  add_action(const std::string &entry,
1180  const std::function<void(const std::string &value)> &action,
1181  const bool execute_action = true);
1182 
1198  template <typename ParameterType>
1199  void
1200  add_parameter(const std::string &entry,
1201  ParameterType &parameter,
1202  const std::string &documentation = "",
1203  const Patterns::PatternBase &pattern =
1205  const bool has_to_be_set = false);
1206 
1250  void
1251  declare_alias(const std::string &existing_entry_name,
1252  const std::string &alias_name,
1253  const bool alias_is_deprecated = false);
1254 
1258  void
1259  enter_subsection(const std::string &subsection);
1260 
1264  void
1265  leave_subsection();
1266 
1272  bool
1273  subsection_path_exists(const std::vector<std::string> &sub_path) const;
1274 
1280  std::string
1281  get(const std::string &entry_string) const;
1282 
1293  std::string
1294  get(const std::vector<std::string> &entry_subsection_path,
1295  const std::string &entry_string) const;
1296 
1302  long int
1303  get_integer(const std::string &entry_string) const;
1304 
1313  long int
1314  get_integer(const std::vector<std::string> &entry_subsection_path,
1315  const std::string &entry_string) const;
1316 
1320  double
1321  get_double(const std::string &entry_name) const;
1322 
1329  double
1330  get_double(const std::vector<std::string> &entry_subsection_path,
1331  const std::string &entry_string) const;
1337  bool
1338  get_bool(const std::string &entry_name) const;
1339 
1348  bool
1349  get_bool(const std::vector<std::string> &entry_subsection_path,
1350  const std::string &entry_string) const;
1351 
1361  void
1362  set(const std::string &entry_name, const std::string &new_value);
1363 
1374  void
1375  set(const std::string &entry_name, const char *new_value);
1376 
1386  void
1387  set(const std::string &entry_name, const long int new_value);
1388 
1402  void
1403  set(const std::string &entry_name, const double new_value);
1404 
1414  void
1415  set(const std::string &entry_name, const bool new_value);
1416 
1489  std::ostream &
1490  print_parameters(std::ostream &out, const OutputStyle style) const;
1491 
1492 
1493 
1514  void
1515  print_parameters(const std::string &filename,
1516  const OutputStyle style = DefaultStyle) const;
1517 
1532  void
1533  log_parameters(LogStream &out, const OutputStyle style = DefaultStyle);
1534 
1553  void
1555  const OutputStyle style = DefaultStyle);
1556 
1561  std::size_t
1562  memory_consumption() const;
1563 
1569  template <class Archive>
1570  void
1571  save(Archive &ar, const unsigned int version) const;
1572 
1578  template <class Archive>
1579  void
1580  load(Archive &ar, const unsigned int version);
1581 
1582 #ifdef DOXYGEN
1588  template <class Archive>
1589  void
1590  serialize(Archive &archive, const unsigned int version);
1591 #else
1592  // This macro defines the serialize() method that is compatible with
1593  // the templated save() and load() method that have been implemented.
1594  BOOST_SERIALIZATION_SPLIT_MEMBER()
1595 #endif
1596 
1600  bool
1601  operator==(const ParameterHandler &prm2) const;
1602 
1611  std::set<std::string>
1613 
1619  void
1621 
1631  std::string,
1632  << "The following entry already exists: " << arg1 << '.');
1637  std::string,
1638  std::string,
1639  << "The string <" << arg1
1640  << "> does not match the given pattern <" << arg2 << ">.");
1646  "You can't leave a subsection if you are already at the top level "
1647  "of the subsection hierarchy.");
1652  std::string,
1653  << "You can't ask for entry <" << arg1
1654  << "> you have not yet declared.");
1655 
1663  std::string,
1664  std::string,
1665  << "There are unequal numbers of 'subsection' and 'end' "
1666  "statements in the parameter file <"
1667  << arg1 << ">." << (arg2.size() > 0 ? "\n" + arg2 : ""));
1668 
1674  int,
1675  std::string,
1676  std::string,
1677  << "Line <" << arg1 << "> of file <" << arg2
1678  << ">: You are trying to enter a subsection '" << arg3
1679  << "', but the ParameterHandler object does "
1680  << "not know of any such subsection.");
1681 
1688  int,
1689  std::string,
1690  std::string,
1691  << "Line <" << arg1 << "> of file <" << arg2 << ">: " << arg3);
1692 
1699  int,
1700  std::string,
1701  std::string,
1702  std::string,
1703  std::string,
1704  << "Line <" << arg1 << "> of file <" << arg2
1705  << ">:\n"
1706  " The entry value \n"
1707  << " " << arg3 << '\n'
1708  << " for the entry named\n"
1709  << " " << arg4 << '\n'
1710  << " does not match the given pattern:\n"
1711  << " " << arg5);
1712 
1719  "The provided file could not be parsed as a "
1720  "ParameterHandler description.");
1721 
1730  int,
1731  std::string,
1732  std::string,
1733  << "Line <" << arg1 << "> of file <" << arg2
1734  << ">: This line "
1735  "contains an 'include' or 'INCLUDE' statement, but the given "
1736  "file to include <"
1737  << arg3 << "> cannot be opened.");
1738 
1741 private:
1746  static const char path_separator = '.';
1747 
1751  std::vector<std::string> subsection_path;
1752 
1761  std::unique_ptr<boost::property_tree::ptree> entries;
1762 
1771  std::map<std::string, std::pair<bool, bool>> entries_set_status;
1772 
1778  std::vector<std::unique_ptr<const Patterns::PatternBase>> patterns;
1779 
1786  std::vector<std::function<void(const std::string &)>> actions;
1787 
1796  std::string
1797  get_current_path() const;
1798 
1803  std::string
1804  get_current_full_path(const std::string &name) const;
1805 
1810  std::string
1811  get_current_full_path(const std::vector<std::string> &sub_path,
1812  const std::string &name) const;
1813 
1832  void
1833  scan_line(std::string line,
1834  const std::string &input_filename,
1835  const unsigned int current_line_n,
1836  const bool skip_undefined);
1837 
1849  void
1851  const boost::property_tree::ptree &tree,
1852  const std::vector<std::string> &target_subsection_path,
1853  const ParameterHandler::OutputStyle style,
1854  const unsigned int indent_level,
1855  std::ostream &out) const;
1856 
1858 };
1859 
1870 {
1871  return static_cast<ParameterHandler::OutputStyle>(
1872  static_cast<unsigned int>(f1) | static_cast<unsigned int>(f2));
1873 }
1874 
2091 {
2092 public:
2098  {
2099  public:
2104  virtual ~UserClass() = default;
2105 
2110  virtual void
2111  create_new(const unsigned int run_no) = 0;
2112 
2116  virtual void
2118  };
2119 
2124 
2129  virtual ~MultipleParameterLoop() override = default;
2130 
2152  virtual void
2153  parse_input(std::istream &input,
2154  const std::string &filename = "input file",
2155  const std::string &last_line = "",
2156  const bool skip_undefined = false) override;
2157 
2166 
2170  void
2171  loop(UserClass &uc);
2172 
2177  std::size_t
2178  memory_consumption() const;
2179 
2180 private:
2184  class Entry
2185  {
2186  public:
2193  {
2201  array
2202  };
2203 
2208  : type(array)
2209  {}
2210 
2216  Entry(const std::vector<std::string> &Path,
2217  const std::string &Name,
2218  const std::string &Value);
2219 
2223  void
2225 
2229  std::vector<std::string> subsection_path;
2230 
2234  std::string entry_name;
2235 
2239  std::string entry_value;
2240 
2245  std::vector<std::string> different_values;
2246 
2251 
2256  std::size_t
2257  memory_consumption() const;
2258  };
2259 
2263  std::vector<Entry> multiple_choices;
2264 
2269  unsigned int n_branches;
2270 
2274  void
2275  init_branches();
2276 
2283  void
2285 
2289  void
2290  fill_entry_values(const unsigned int run_no);
2291 };
2292 
2293 
2294 // ---------------------- inline and template functions --------------------
2295 template <class Archive>
2296 inline void
2297 ParameterHandler::save(Archive &ar, const unsigned int) const
2298 {
2299  // Forward to serialization
2300  // function in the base class.
2301  ar &static_cast<const Subscriptor &>(*this);
2302 
2303  ar &*entries.get();
2304 
2305  std::vector<std::string> descriptions;
2306 
2307  descriptions.reserve(patterns.size());
2308  for (const auto &pattern : patterns)
2309  descriptions.push_back(pattern->description());
2310 
2311  ar &descriptions;
2312 }
2313 
2314 
2315 template <class Archive>
2316 inline void
2317 ParameterHandler::load(Archive &ar, const unsigned int)
2318 {
2319  // Forward to serialization
2320  // function in the base class.
2321  ar &static_cast<Subscriptor &>(*this);
2322 
2323  ar &*entries.get();
2324 
2325  std::vector<std::string> descriptions;
2326  ar &descriptions;
2327 
2328  patterns.clear();
2329  for (const auto &description : descriptions)
2330  patterns.push_back(Patterns::pattern_factory(description));
2331 }
2332 
2333 
2334 template <typename ParameterType>
2335 void
2336 ParameterHandler::add_parameter(const std::string &entry,
2337  ParameterType &parameter,
2338  const std::string &documentation,
2339  const Patterns::PatternBase &pattern,
2340  const bool has_to_be_set)
2341 {
2342  static_assert(std::is_const_v<ParameterType> == false,
2343  "You tried to add a parameter using a type "
2344  "that is const. Use a non-const type.");
2345 
2346  declare_entry(entry,
2348  pattern),
2349  pattern,
2350  documentation,
2351  has_to_be_set);
2352 
2353  std::string path = get_current_full_path(entry);
2354  const unsigned int pattern_index =
2355  entries->get<unsigned int>(path + path_separator + "pattern");
2356 
2357  auto action = [&, pattern_index](const std::string &val) {
2359  val, *patterns[pattern_index]);
2360  };
2361  add_action(entry, action, false);
2362 }
2363 
2365 
2366 #endif
std::vector< std::string > subsection_path
std::vector< std::string > different_values
std::size_t memory_consumption() const
virtual void create_new(const unsigned int run_no)=0
virtual void run(ParameterHandler &prm)=0
virtual void parse_input(std::istream &input, const std::string &filename="input file", const std::string &last_line="", const bool skip_undefined=false)
void fill_entry_values(const unsigned int run_no)
std::size_t memory_consumption() const
virtual ~MultipleParameterLoop() override=default
void loop(UserClass &uc)
std::vector< Entry > multiple_choices
static const char path_separator
std::size_t memory_consumption() const
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)
void load(Archive &ar, const unsigned int version)
virtual void parse_input(std::istream &input, const std::string &filename="input file", const std::string &last_line="", const bool skip_undefined=false)
virtual void parse_input_from_xml(std::istream &input, const bool skip_undefined=false)
std::string get_current_path() const
ParameterHandler(const ParameterHandler &)=delete
std::vector< std::unique_ptr< const Patterns::PatternBase > > patterns
std::ostream & print_parameters(std::ostream &out, const OutputStyle style) const
void recursively_print_parameters(const boost::property_tree::ptree &tree, const std::vector< std::string > &target_subsection_path, const ParameterHandler::OutputStyle style, const unsigned int indent_level, std::ostream &out) const
void add_action(const std::string &entry, const std::function< void(const std::string &value)> &action, const bool execute_action=true)
void save(Archive &ar, const unsigned int version) const
long int get_integer(const std::string &entry_string) const
bool get_bool(const std::string &entry_name) const
void declare_entry(const std::string &entry, const std::string &default_value, const Patterns::PatternBase &pattern=Patterns::Anything(), const std::string &documentation="", const bool has_to_be_set=false)
virtual void parse_input_from_string(const std::string &s, const std::string &last_line="", const bool skip_undefined=false)
std::string get(const std::string &entry_string) const
std::set< std::string > get_entries_wrongly_not_set() const
void set(const std::string &entry_name, const std::string &new_value)
void log_parameters(LogStream &out, const OutputStyle style=DefaultStyle)
void serialize(Archive &archive, const unsigned int version)
std::map< std::string, std::pair< bool, bool > > entries_set_status
std::string get_current_full_path(const std::string &name) const
std::vector< std::function< void(const std::string &)> > actions
void log_parameters_section(LogStream &out, const OutputStyle style=DefaultStyle)
std::unique_ptr< boost::property_tree::ptree > entries
bool subsection_path_exists(const std::vector< std::string > &sub_path) const
virtual ~ParameterHandler() override=default
void scan_line(std::string line, const std::string &input_filename, const unsigned int current_line_n, const bool skip_undefined)
double get_double(const std::string &entry_name) const
void declare_alias(const std::string &existing_entry_name, const std::string &alias_name, const bool alias_is_deprecated=false)
bool operator==(const ParameterHandler &prm2) const
std::vector< std::string > subsection_path
void enter_subsection(const std::string &subsection)
void assert_that_entries_have_been_set() const
virtual void parse_input_from_json(std::istream &input, const bool skip_undefined=false)
ParameterHandler & operator=(const ParameterHandler &)=delete
#define DEAL_II_NAMESPACE_OPEN
Definition: config.h:477
#define DEAL_II_NAMESPACE_CLOSE
Definition: config.h:478
IteratorRange< FilteredIterator< BaseIterator > > operator|(IteratorRange< BaseIterator > i, const Predicate &p)
static ::ExceptionBase & ExcUnbalancedSubsections(std::string arg1, std::string arg2)
static ::ExceptionBase & ExcEntryUndeclared(std::string arg1)
static ::ExceptionBase & ExcInvalidXMLParameterFile()
static ::ExceptionBase & ExcEntryAlreadyExists(std::string arg1)
static ::ExceptionBase & ExcValueDoesNotMatchPattern(std::string arg1, std::string arg2)
#define DeclException2(Exception2, type1, type2, outsequence)
Definition: exceptions.h:535
static ::ExceptionBase & ExcAlreadyAtTopLevel()
static ::ExceptionBase & ExcCannotParseLine(int arg1, std::string arg2, std::string arg3)
#define DeclExceptionMsg(Exception, defaulttext)
Definition: exceptions.h:490
static ::ExceptionBase & ExcCannotOpenIncludeStatementFile(int arg1, std::string arg2, std::string arg3)
#define DeclException3(Exception3, type1, type2, type3, outsequence)
Definition: exceptions.h:558
#define DeclException1(Exception1, type1, outsequence)
Definition: exceptions.h:512
static ::ExceptionBase & ExcInvalidEntryForPattern(int arg1, std::string arg2, std::string arg3, std::string arg4, std::string arg5)
static ::ExceptionBase & ExcNoSubsection(int arg1, std::string arg2, std::string arg3)
#define DeclException5( Exception5, type1, type2, type3, type4, type5, outsequence)
Definition: exceptions.h:607
std::unique_ptr< PatternBase > pattern_factory(const std::string &description)
Definition: patterns.cc:138
static T to_value(const std::string &s, const Patterns::PatternBase &p= *Convert< T >::to_pattern())=delete