Reference documentation for deal.II version Git 7026f387cc 2019-10-15 14:19:01 -0400
\(\newcommand{\dealcoloneq}{\mathrel{\vcenter{:}}=}\)
parameter_handler.h
1 // ---------------------------------------------------------------------
2 //
3 // Copyright (C) 1998 - 2019 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 
22 #include <deal.II/base/exceptions.h>
23 #include <deal.II/base/patterns.h>
24 #include <deal.II/base/subscriptor.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 
36 DEAL_II_NAMESPACE_OPEN
37 
38 // forward declarations for interfaces and friendship
39 #ifndef DOXYGEN
40 class LogStream;
42 #endif
43 
847 {
848 public:
854  {
859  Text = 1,
860 
864  LaTeX = 2,
869 
876  XML = 4,
877 
882  JSON = 5,
883 
888  ShortText = 193
889  };
890 
891 
892 
897 
903  virtual ~ParameterHandler() override = default;
904 
908  ParameterHandler(const ParameterHandler &) = delete;
909 
914  operator=(const ParameterHandler &) = delete;
915 
950  virtual void
951  parse_input(std::istream & input,
952  const std::string &filename = "input file",
953  const std::string &last_line = "",
954  const bool skip_undefined = false);
955 
999  virtual void
1000  parse_input(const std::string &filename,
1001  const std::string &last_line = "",
1002  const bool skip_undefined = false);
1003 
1012  virtual void
1013  parse_input_from_string(const std::string &s,
1014  const std::string &last_line = "",
1015  const bool skip_undefined = false);
1016 
1024  virtual void
1025  parse_input_from_xml(std::istream &input);
1026 
1034  virtual void
1035  parse_input_from_json(std::istream &input);
1036 
1040  void
1041  clear();
1042 
1043 
1063  void
1064  declare_entry(const std::string & entry,
1065  const std::string & default_value,
1066  const Patterns::PatternBase &pattern = Patterns::Anything(),
1067  const std::string & documentation = "");
1068 
1112  void
1113  add_action(const std::string & entry,
1114  const std::function<void(const std::string &value)> &action);
1115 
1125  template <class ParameterType>
1126  void
1127  add_parameter(const std::string & entry,
1128  ParameterType & parameter,
1129  const std::string & documentation = "",
1130  const Patterns::PatternBase &pattern =
1132 
1176  void
1177  declare_alias(const std::string &existing_entry_name,
1178  const std::string &alias_name,
1179  const bool alias_is_deprecated = false);
1180 
1184  void
1185  enter_subsection(const std::string &subsection);
1186 
1190  void
1191  leave_subsection();
1192 
1198  std::string
1199  get(const std::string &entry_string) const;
1200 
1211  std::string
1212  get(const std::vector<std::string> &entry_subsection_path,
1213  const std::string & entry_string) const;
1214 
1220  long int
1221  get_integer(const std::string &entry_string) const;
1222 
1231  long int
1232  get_integer(const std::vector<std::string> &entry_subsection_path,
1233  const std::string & entry_string) const;
1234 
1238  double
1239  get_double(const std::string &entry_name) const;
1240 
1247  double
1248  get_double(const std::vector<std::string> &entry_subsection_path,
1249  const std::string & entry_string) const;
1255  bool
1256  get_bool(const std::string &entry_name) const;
1257 
1266  bool
1267  get_bool(const std::vector<std::string> &entry_subsection_path,
1268  const std::string & entry_string) const;
1269 
1279  void
1280  set(const std::string &entry_name, const std::string &new_value);
1281 
1292  void
1293  set(const std::string &entry_name, const char *new_value);
1294 
1304  void
1305  set(const std::string &entry_name, const long int new_value);
1306 
1320  void
1321  set(const std::string &entry_name, const double new_value);
1322 
1332  void
1333  set(const std::string &entry_name, const bool new_value);
1334 
1335 
1395  std::ostream &
1396  print_parameters(std::ostream &out, const OutputStyle style) const;
1397 
1415  DEAL_II_DEPRECATED
1416  void
1417  print_parameters_section(std::ostream & out,
1418  const OutputStyle style,
1419  const unsigned int indent_level,
1420  const bool include_top_level_elements = false);
1421 
1427  void
1428  log_parameters(LogStream &out);
1429 
1439  void
1441 
1446  std::size_t
1447  memory_consumption() const;
1448 
1453  template <class Archive>
1454  void
1455  save(Archive &ar, const unsigned int version) const;
1456 
1461  template <class Archive>
1462  void
1463  load(Archive &ar, const unsigned int version);
1464 
1465  BOOST_SERIALIZATION_SPLIT_MEMBER()
1466 
1467 
1470  bool
1471  operator==(const ParameterHandler &prm2) const;
1472 
1482  std::string,
1483  << "The following entry already exists: " << arg1 << ".");
1488  std::string,
1489  std::string,
1490  << "The string <" << arg1
1491  << "> does not match the given pattern <" << arg2 << ">.");
1497  "You can't leave a subsection if you are already at the top level "
1498  "of the subsection hierarchy.");
1503  std::string,
1504  << "You can't ask for entry <" << arg1
1505  << "> you have not yet declared.");
1506 
1514  std::string,
1515  std::string,
1516  << "There are unequal numbers of 'subsection' and 'end' "
1517  "statements in the parameter file <"
1518  << arg1 << ">." << (arg2.size() > 0 ? "\n" + arg2 : ""));
1519 
1525  int,
1526  std::string,
1527  std::string,
1528  << "Line <" << arg1 << "> of file <" << arg2
1529  << ": There is "
1530  "no such subsection to be entered: "
1531  << arg3);
1532 
1539  int,
1540  std::string,
1541  std::string,
1542  << "Line <" << arg1 << "> of file <" << arg2 << ">: " << arg3);
1543 
1550  int,
1551  std::string,
1552  std::string,
1553  std::string,
1554  std::string,
1555  << "Line <" << arg1 << "> of file <" << arg2
1556  << ">:\n"
1557  " The entry value \n"
1558  << " " << arg3 << '\n'
1559  << " for the entry named\n"
1560  << " " << arg4 << '\n'
1561  << " does not match the given pattern:\n"
1562  << " " << arg5);
1563 
1570  "The provided file could not be parsed as a "
1571  "ParameterHandler description.");
1572 
1579  std::string,
1580  std::string,
1581  std::string,
1582  << " The entry value \n"
1583  << " " << arg1 << '\n'
1584  << " for the entry named\n"
1585  << " " << arg2 << '\n'
1586  << " does not match the given pattern:\n"
1587  << " " << arg3);
1588 
1597  int,
1598  std::string,
1599  std::string,
1600  << "Line <" << arg1 << "> of file <" << arg2
1601  << ">: This line "
1602  "contains an 'include' or 'INCLUDE' statement, but the given "
1603  "file to include <"
1604  << arg3 << "> cannot be opened.");
1605 
1607 private:
1612  static const char path_separator = '.';
1613 
1617  std::vector<std::string> subsection_path;
1618 
1627  std::unique_ptr<boost::property_tree::ptree> entries;
1628 
1634  std::vector<std::unique_ptr<const Patterns::PatternBase>> patterns;
1635 
1642  std::vector<std::function<void(const std::string &)>> actions;
1643 
1650  static std::string
1651  collate_path_string(const std::vector<std::string> &subsection_path);
1652 
1661  std::string
1662  get_current_path() const;
1663 
1668  std::string
1669  get_current_full_path(const std::string &name) const;
1670 
1675  std::string
1676  get_current_full_path(const std::vector<std::string> &sub_path,
1677  const std::string & name) const;
1678 
1697  void
1698  scan_line(std::string line,
1699  const std::string &input_filename,
1700  const unsigned int current_line_n,
1701  const bool skip_undefined);
1702 
1714  void
1716  const std::vector<std::string> &target_subsection_path,
1717  const OutputStyle style,
1718  const unsigned int indent_level,
1719  std::ostream & out) const;
1720 
1721  friend class MultipleParameterLoop;
1722 };
1723 
1724 
1725 
1942 class MultipleParameterLoop : public ParameterHandler
1943 {
1944 public:
1950  {
1951  public:
1956  virtual ~UserClass() = default;
1957 
1962  virtual void
1963  create_new(const unsigned int run_no) = 0;
1964 
1968  virtual void
1969  run(ParameterHandler &prm) = 0;
1970  };
1971 
1975  MultipleParameterLoop();
1976 
1981  virtual ~MultipleParameterLoop() override = default;
1982 
2004  virtual void
2005  parse_input(std::istream & input,
2006  const std::string &filename = "input file",
2007  const std::string &last_line = "",
2008  const bool skip_undefined = false) override;
2009 
2018 
2022  void
2023  loop(UserClass &uc);
2024 
2029  std::size_t
2030  memory_consumption() const;
2031 
2032 private:
2036  class Entry
2037  {
2038  public:
2045  {
2053  array
2054  };
2055 
2060  : type(array)
2061  {}
2062 
2068  Entry(const std::vector<std::string> &Path,
2069  const std::string & Name,
2070  const std::string & Value);
2071 
2075  void
2076  split_different_values();
2077 
2081  std::vector<std::string> subsection_path;
2082 
2086  std::string entry_name;
2087 
2091  std::string entry_value;
2092 
2097  std::vector<std::string> different_values;
2098 
2103 
2108  std::size_t
2109  memory_consumption() const;
2110  };
2111 
2115  std::vector<Entry> multiple_choices;
2116 
2121  unsigned int n_branches;
2122 
2126  void
2127  init_branches();
2128 
2135  void
2136  init_branches_current_section();
2137 
2141  void
2142  fill_entry_values(const unsigned int run_no);
2143 };
2144 
2145 
2146 // ---------------------- inline and template functions --------------------
2147 template <class Archive>
2148 inline void
2149 ParameterHandler::save(Archive &ar, const unsigned int) const
2150 {
2151  // Forward to serialization
2152  // function in the base class.
2153  ar &static_cast<const Subscriptor &>(*this);
2154 
2155  ar &*entries.get();
2156 
2157  std::vector<std::string> descriptions;
2158 
2159  for (const auto &pattern : patterns)
2160  descriptions.push_back(pattern->description());
2161 
2162  ar &descriptions;
2163 }
2164 
2165 
2166 template <class Archive>
2167 inline void
2168 ParameterHandler::load(Archive &ar, const unsigned int)
2169 {
2170  // Forward to serialization
2171  // function in the base class.
2172  ar &static_cast<Subscriptor &>(*this);
2173 
2174  ar &*entries.get();
2175 
2176  std::vector<std::string> descriptions;
2177  ar & descriptions;
2178 
2179  patterns.clear();
2180  for (const auto &description : descriptions)
2181  patterns.push_back(Patterns::pattern_factory(description));
2182 }
2183 
2184 
2185 template <class ParameterType>
2186 void
2187 ParameterHandler::add_parameter(const std::string & entry,
2188  ParameterType & parameter,
2189  const std::string & documentation,
2190  const Patterns::PatternBase &pattern)
2191 {
2192  static_assert(std::is_const<ParameterType>::value == false,
2193  "You tried to add a parameter using a type "
2194  "that is const. Use a non-const type.");
2195 
2196  declare_entry(entry,
2198  parameter, pattern.clone()),
2199  pattern,
2200  documentation);
2201 
2202  std::string path = get_current_full_path(entry);
2203  const unsigned int pattern_index =
2204  entries->get<unsigned int>(path + path_separator + "pattern");
2205 
2206  auto action = [&, pattern_index](const std::string &val) {
2208  val, patterns[pattern_index]->clone());
2209  };
2210  add_action(entry, action);
2211 }
2212 
2213 DEAL_II_NAMESPACE_CLOSE
2214 
2215 #endif
std::vector< Entry > multiple_choices
long int get_integer(const std::string &entry_string) const
void loop(ITERATOR begin, typename identity< ITERATOR >::type end, DOFINFO &dinfo, INFOBOX &info, const std::function< void(DOFINFO &, typename INFOBOX::CellInfo &)> &cell_worker, const std::function< void(DOFINFO &, typename INFOBOX::CellInfo &)> &boundary_worker, const std::function< void(DOFINFO &, DOFINFO &, typename INFOBOX::CellInfo &, typename INFOBOX::CellInfo &)> &face_worker, ASSEMBLER &assembler, const LoopControl &lctrl=LoopControl())
Definition: loop.h:446
static const char path_separator
#define DeclException2(Exception2, type1, type2, outsequence)
Definition: exceptions.h:541
void declare_entry(const std::string &entry, const std::string &default_value, const Patterns::PatternBase &pattern=Patterns::Anything(), const std::string &documentation="")
static ::ExceptionBase & ExcEntryAlreadyExists(std::string arg1)
static std::string collate_path_string(const std::vector< std::string > &subsection_path)
static ::ExceptionBase & ExcInvalidEntryForPatternXML(std::string arg1, std::string arg2, std::string arg3)
static ::ExceptionBase & ExcCannotOpenIncludeStatementFile(int arg1, std::string arg2, std::string arg3)
std::string get_current_path() const
static ::ExceptionBase & ExcEntryUndeclared(std::string arg1)
static T to_value(const std::string &s, const std::unique_ptr< Patterns::PatternBase > &p=Convert< T >::to_pattern())=delete
static ::ExceptionBase & ExcUnbalancedSubsections(std::string arg1, std::string arg2)
std::ostream & print_parameters(std::ostream &out, const OutputStyle style) const
void log_parameters(LogStream &out)
virtual void parse_input_from_string(const std::string &s, const std::string &last_line="", const bool skip_undefined=false)
virtual std::unique_ptr< PatternBase > clone() const =0
virtual void parse_input_from_json(std::istream &input)
void log_parameters_section(LogStream &out)
STL namespace.
std::vector< std::string > subsection_path
#define DeclException5( Exception5, type1, type2, type3, type4, type5, outsequence)
Definition: exceptions.h:613
void scan_line(std::string line, const std::string &input_filename, const unsigned int current_line_n, const bool skip_undefined)
static ::ExceptionBase & ExcValueDoesNotMatchPattern(std::string arg1, std::string arg2)
void load(Archive &ar, const unsigned int version)
std::vector< std::string > subsection_path
void add_parameter(const std::string &entry, ParameterType &parameter, const std::string &documentation="", const Patterns::PatternBase &pattern= *Patterns::Tools::Convert< ParameterType >::to_pattern())
void enter_subsection(const std::string &subsection)
virtual void parse_input_from_xml(std::istream &input)
static ::ExceptionBase & ExcInvalidXMLParameterFile()
static ::ExceptionBase & ExcCannotParseLine(int arg1, std::string arg2, std::string arg3)
double get_double(const std::string &entry_name) const
#define DeclException1(Exception1, type1, outsequence)
Definition: exceptions.h:518
std::string get_current_full_path(const std::string &name) const
#define DeclExceptionMsg(Exception, defaulttext)
Definition: exceptions.h:496
std::unique_ptr< boost::property_tree::ptree > entries
virtual void parse_input(std::istream &input, const std::string &filename="input file", const std::string &last_line="", const bool skip_undefined=false)
std::unique_ptr< PatternBase > pattern_factory(const std::string &description)
Definition: patterns.cc:136
bool get_bool(const std::string &entry_name) const
static ::ExceptionBase & ExcAlreadyAtTopLevel()
std::vector< std::unique_ptr< const Patterns::PatternBase > > patterns
void add_action(const std::string &entry, const std::function< void(const std::string &value)> &action)
void print_parameters_section(std::ostream &out, const OutputStyle style, const unsigned int indent_level, const bool include_top_level_elements=false)
void save(Archive &ar, const unsigned int version) const
void recursively_print_parameters(const std::vector< std::string > &target_subsection_path, const OutputStyle style, const unsigned int indent_level, std::ostream &out) const
std::vector< std::string > different_values
#define DeclException3(Exception3, type1, type2, type3, outsequence)
Definition: exceptions.h:564
std::size_t memory_consumption() const
static ::ExceptionBase & ExcInvalidEntryForPattern(int arg1, std::string arg2, std::string arg3, std::string arg4, std::string arg5)
std::vector< std::function< void(const std::string &)> > actions
virtual ~ParameterHandler() override=default
static ::ExceptionBase & ExcNoSubsection(int arg1, std::string arg2, std::string arg3)
void declare_alias(const std::string &existing_entry_name, const std::string &alias_name, const bool alias_is_deprecated=false)
ParameterHandler & operator=(const ParameterHandler &)=delete