Reference documentation for deal.II version 9.1.0-pre
parameter_handler.h
1 // ---------------------------------------------------------------------
2 //
3 // Copyright (C) 1998 - 2018 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 class LogStream;
41 
818 {
819 private:
823  ParameterHandler(const ParameterHandler &) = delete;
824 
829  operator=(const ParameterHandler &) = delete;
830 
831 public:
837  {
842  Text = 1,
843 
847  LaTeX = 2,
852 
859  XML = 4,
860 
865  JSON = 5,
866 
871  ShortText = 193
872  };
873 
874 
875 
880 
886  virtual ~ParameterHandler() override = default;
887 
916  virtual void
917  parse_input(std::istream & input,
918  const std::string &filename = "input file",
919  const std::string &last_line = "");
920 
964  virtual void
965  parse_input(const std::string &filename, const std::string &last_line = "");
966 
975  virtual void
976  parse_input_from_string(const char *s, const std::string &last_line = "");
977 
985  virtual void
986  parse_input_from_xml(std::istream &input);
987 
995  virtual void
996  parse_input_from_json(std::istream &input);
997 
1001  void
1002  clear();
1003 
1004 
1024  void
1025  declare_entry(const std::string & entry,
1026  const std::string & default_value,
1027  const Patterns::PatternBase &pattern = Patterns::Anything(),
1028  const std::string & documentation = std::string());
1029 
1073  void
1074  add_action(const std::string & entry,
1075  const std::function<void(const std::string &value)> &action);
1076 
1086  template <class ParameterType>
1087  void
1088  add_parameter(const std::string & entry,
1089  ParameterType & parameter,
1090  const std::string & documentation = std::string(),
1091  const Patterns::PatternBase &pattern =
1093 
1137  void
1138  declare_alias(const std::string &existing_entry_name,
1139  const std::string &alias_name,
1140  const bool alias_is_deprecated = false);
1141 
1145  void
1146  enter_subsection(const std::string &subsection);
1147 
1151  void
1152  leave_subsection();
1153 
1159  std::string
1160  get(const std::string &entry_string) const;
1161 
1167  long int
1168  get_integer(const std::string &entry_string) const;
1169 
1173  double
1174  get_double(const std::string &entry_name) const;
1175 
1181  bool
1182  get_bool(const std::string &entry_name) const;
1183 
1193  void
1194  set(const std::string &entry_name, const std::string &new_value);
1195 
1206  void
1207  set(const std::string &entry_name, const char *new_value);
1208 
1218  void
1219  set(const std::string &entry_name, const long int &new_value);
1220 
1234  void
1235  set(const std::string &entry_name, const double &new_value);
1236 
1246  void
1247  set(const std::string &entry_name, const bool &new_value);
1248 
1249 
1309  std::ostream &
1310  print_parameters(std::ostream &out, const OutputStyle style) const;
1311 
1329  DEAL_II_DEPRECATED
1330  void
1331  print_parameters_section(std::ostream & out,
1332  const OutputStyle style,
1333  const unsigned int indent_level,
1334  const bool include_top_level_elements = false);
1335 
1341  void
1342  log_parameters(LogStream &out);
1343 
1353  void
1355 
1360  std::size_t
1361  memory_consumption() const;
1362 
1367  template <class Archive>
1368  void
1369  save(Archive &ar, const unsigned int version) const;
1370 
1375  template <class Archive>
1376  void
1377  load(Archive &ar, const unsigned int version);
1378 
1379  BOOST_SERIALIZATION_SPLIT_MEMBER()
1380 
1381 
1384  bool
1385  operator==(const ParameterHandler &prm2) const;
1386 
1396  std::string,
1397  << "The following entry already exists: " << arg1 << ".");
1402  std::string,
1403  std::string,
1404  << "The string <" << arg1
1405  << "> does not match the given pattern <" << arg2 << ">.");
1411  "You can't leave a subsection if you are already at the top level "
1412  "of the subsection hierarchy.");
1417  std::string,
1418  << "You can't ask for entry <" << arg1
1419  << "> you have not yet declared.");
1420 
1428  std::string,
1429  std::string,
1430  << "There are unequal numbers of 'subsection' and 'end' "
1431  "statements in the parameter file <"
1432  << arg1 << ">." << (arg2.size() > 0 ? "\n" + arg2 : ""));
1433 
1439  int,
1440  std::string,
1441  std::string,
1442  << "Line <" << arg1 << "> of file <" << arg2
1443  << ": There is "
1444  "no such subsection to be entered: "
1445  << arg3);
1446 
1453  int,
1454  std::string,
1455  std::string,
1456  << "Line <" << arg1 << "> of file <" << arg2 << ">: " << arg3);
1457 
1464  int,
1465  std::string,
1466  std::string,
1467  std::string,
1468  std::string,
1469  << "Line <" << arg1 << "> of file <" << arg2
1470  << ">:\n"
1471  " The entry value \n"
1472  << " " << arg3 << '\n'
1473  << " for the entry named\n"
1474  << " " << arg4 << '\n'
1475  << " does not match the given pattern:\n"
1476  << " " << arg5);
1477 
1484  "The provided file could not be parsed as a "
1485  "ParameterHandler description.");
1486 
1493  std::string,
1494  std::string,
1495  std::string,
1496  << " The entry value \n"
1497  << " " << arg1 << '\n'
1498  << " for the entry named\n"
1499  << " " << arg2 << '\n'
1500  << " does not match the given pattern:\n"
1501  << " " << arg3);
1502 
1511  int,
1512  std::string,
1513  std::string,
1514  << "Line <" << arg1 << "> of file <" << arg2
1515  << ">: This line "
1516  "contains an 'include' or 'INCLUDE' statement, but the given "
1517  "file to include <"
1518  << arg3 << "> cannot be opened.");
1519 
1521 private:
1526  static const char path_separator = '.';
1527 
1531  std::vector<std::string> subsection_path;
1532 
1541  std::unique_ptr<boost::property_tree::ptree> entries;
1542 
1548  std::vector<std::unique_ptr<const Patterns::PatternBase>> patterns;
1549 
1556  std::vector<std::function<void(const std::string &)>> actions;
1557 
1564  static std::string
1565  collate_path_string(const std::vector<std::string> &subsection_path);
1566 
1575  std::string
1576  get_current_path() const;
1577 
1582  std::string
1583  get_current_full_path(const std::string &name) const;
1584 
1597  void
1598  scan_line(std::string line,
1599  const std::string &input_filename,
1600  const unsigned int current_line_n);
1601 
1613  void
1615  const std::vector<std::string> &target_subsection_path,
1616  const OutputStyle style,
1617  const unsigned int indent_level,
1618  std::ostream & out) const;
1619 
1620  friend class MultipleParameterLoop;
1621 };
1622 
1623 
1624 
1841 class MultipleParameterLoop : public ParameterHandler
1842 {
1843 public:
1849  {
1850  public:
1855  virtual ~UserClass() = default;
1856 
1861  virtual void
1862  create_new(const unsigned int run_no) = 0;
1863 
1867  virtual void
1868  run(ParameterHandler &prm) = 0;
1869  };
1870 
1874  MultipleParameterLoop();
1875 
1880  virtual ~MultipleParameterLoop() override = default;
1881 
1897  virtual void
1898  parse_input(std::istream & input,
1899  const std::string &filename = "input file",
1900  const std::string &last_line = "") override;
1901 
1910 
1914  void
1915  loop(UserClass &uc);
1916 
1921  std::size_t
1922  memory_consumption() const;
1923 
1924 private:
1928  class Entry
1929  {
1930  public:
1937  {
1945  array
1946  };
1947 
1952  : type(array)
1953  {}
1954 
1960  Entry(const std::vector<std::string> &Path,
1961  const std::string & Name,
1962  const std::string & Value);
1963 
1967  void
1968  split_different_values();
1969 
1973  std::vector<std::string> subsection_path;
1974 
1978  std::string entry_name;
1979 
1983  std::string entry_value;
1984 
1989  std::vector<std::string> different_values;
1990 
1995 
2000  std::size_t
2001  memory_consumption() const;
2002  };
2003 
2007  std::vector<Entry> multiple_choices;
2008 
2013  unsigned int n_branches;
2014 
2018  void
2019  init_branches();
2020 
2027  void
2028  init_branches_current_section();
2029 
2033  void
2034  fill_entry_values(const unsigned int run_no);
2035 };
2036 
2037 
2038 // ---------------------- inline and template functions --------------------
2039 template <class Archive>
2040 inline void
2041 ParameterHandler::save(Archive &ar, const unsigned int) const
2042 {
2043  // Forward to serialization
2044  // function in the base class.
2045  ar &static_cast<const Subscriptor &>(*this);
2046 
2047  ar &*entries.get();
2048 
2049  std::vector<std::string> descriptions;
2050 
2051  for (unsigned int j = 0; j < patterns.size(); ++j)
2052  descriptions.push_back(patterns[j]->description());
2053 
2054  ar &descriptions;
2055 }
2056 
2057 
2058 template <class Archive>
2059 inline void
2060 ParameterHandler::load(Archive &ar, const unsigned int)
2061 {
2062  // Forward to serialization
2063  // function in the base class.
2064  ar &static_cast<Subscriptor &>(*this);
2065 
2066  ar &*entries.get();
2067 
2068  std::vector<std::string> descriptions;
2069  ar & descriptions;
2070 
2071  patterns.clear();
2072  for (unsigned int j = 0; j < descriptions.size(); ++j)
2073  patterns.push_back(Patterns::pattern_factory(descriptions[j]));
2074 }
2075 
2076 
2077 template <class ParameterType>
2078 void
2079 ParameterHandler::add_parameter(const std::string & entry,
2080  ParameterType & parameter,
2081  const std::string & documentation,
2082  const Patterns::PatternBase &pattern)
2083 {
2084  static_assert(std::is_const<ParameterType>::value == false,
2085  "You tried to add a parameter using a type "
2086  "that is const. Use a non-const type.");
2087 
2088  declare_entry(entry,
2090  parameter, pattern.clone()),
2091  pattern,
2092  documentation);
2093 
2094  std::string path = get_current_full_path(entry);
2095  const unsigned int pattern_index =
2096  entries->get<unsigned int>(path + path_separator + "pattern");
2097 
2098  auto action = [&, pattern_index](const std::string &val) {
2100  val, patterns[pattern_index]->clone());
2101  };
2102  add_action(entry, action);
2103 }
2104 
2105 DEAL_II_NAMESPACE_CLOSE
2106 
2107 #endif
void add_parameter(const std::string &entry, ParameterType &parameter, const std::string &documentation=std::string(), const Patterns::PatternBase &pattern=*Patterns::Tools::Convert< ParameterType >::to_pattern())
std::vector< Entry > multiple_choices
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:443
static const char path_separator
#define DeclException2(Exception2, type1, type2, outsequence)
Definition: exceptions.h:420
static::ExceptionBase & ExcEntryAlreadyExists(std::string arg1)
static std::string collate_path_string(const std::vector< std::string > &subsection_path)
std::string get_current_full_path(const std::string &name) const
static::ExceptionBase & ExcInvalidEntryForPatternXML(std::string arg1, std::string arg2, std::string arg3)
static::ExceptionBase & ExcCannotOpenIncludeStatementFile(int arg1, std::string arg2, std::string arg3)
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)
void log_parameters(LogStream &out)
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
static::ExceptionBase & ExcValueDoesNotMatchPattern(std::string arg1, std::string arg2)
void load(Archive &ar, const unsigned int version)
std::vector< std::string > subsection_path
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)
#define DeclException1(Exception1, type1, outsequence)
Definition: exceptions.h:408
std::ostream & print_parameters(std::ostream &out, const OutputStyle style) const
void save(Archive &ar, const unsigned int version) const
#define DeclExceptionMsg(Exception, defaulttext)
Definition: exceptions.h:397
std::string get_current_path() const
std::unique_ptr< boost::property_tree::ptree > entries
#define DeclException5(Exception5, type1, type2, type3, type4, type5, outsequence)
Definition: exceptions.h:459
std::unique_ptr< PatternBase > pattern_factory(const std::string &description)
Definition: patterns.cc:136
virtual void parse_input_from_string(const char *s, const std::string &last_line="")
static::ExceptionBase & ExcAlreadyAtTopLevel()
std::vector< std::unique_ptr< const Patterns::PatternBase > > patterns
bool get_bool(const std::string &entry_name) const
void add_action(const std::string &entry, const std::function< void(const std::string &value)> &action)
double get_double(const std::string &entry_name) const
void print_parameters_section(std::ostream &out, const OutputStyle style, const unsigned int indent_level, const bool include_top_level_elements=false)
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 > different_values
void scan_line(std::string line, const std::string &input_filename, const unsigned int current_line_n)
#define DeclException3(Exception3, type1, type2, type3, outsequence)
Definition: exceptions.h:432
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
void recursively_print_parameters(const std::vector< std::string > &target_subsection_path, const OutputStyle style, const unsigned int indent_level, std::ostream &out) const
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)
std::size_t memory_consumption() const
long int get_integer(const std::string &entry_string) const
ParameterHandler & operator=(const ParameterHandler &)=delete
virtual void parse_input(std::istream &input, const std::string &filename="input file", const std::string &last_line="")