Reference documentation for deal.II version 9.3.3
\(\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 - 2021 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
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
40class LogStream;
42#endif
43
841{
842public:
859 {
864 DefaultStyle = 0x0000,
865
870 Short = 0x0001,
871
876
881 PRM = 0x0010,
882
890
894 LaTeX = 0x0020,
895
901 Description = 0x0040,
902
910 XML = 0x0080,
911
917 JSON = 0x0100,
918
924
932
938
944
950 };
951
952
953
958
964 virtual ~ParameterHandler() override = default;
965
970
975 operator=(const ParameterHandler &) = delete;
976
1011 virtual void
1012 parse_input(std::istream & input,
1013 const std::string &filename = "input file",
1014 const std::string &last_line = "",
1015 const bool skip_undefined = false);
1016
1038 virtual void
1039 parse_input(const std::string &filename,
1040 const std::string &last_line = "",
1041 const bool skip_undefined = false,
1042 const bool assert_mandatory_entries_are_found = false);
1043
1052 virtual void
1053 parse_input_from_string(const std::string &s,
1054 const std::string &last_line = "",
1055 const bool skip_undefined = false);
1056
1064 virtual void
1065 parse_input_from_xml(std::istream &input, const bool skip_undefined = false);
1066
1074 virtual void
1075 parse_input_from_json(std::istream &input, const bool skip_undefined = false);
1076
1080 void
1081 clear();
1082
1083
1109 void
1110 declare_entry(const std::string & entry,
1111 const std::string & default_value,
1112 const Patterns::PatternBase &pattern = Patterns::Anything(),
1113 const std::string & documentation = "",
1114 const bool has_to_be_set = false);
1115
1159 void
1160 add_action(const std::string & entry,
1161 const std::function<void(const std::string &value)> &action);
1162
1178 template <class ParameterType>
1179 void
1180 add_parameter(const std::string & entry,
1181 ParameterType & parameter,
1182 const std::string & documentation = "",
1183 const Patterns::PatternBase &pattern =
1185 const bool has_to_be_set = false);
1186
1230 void
1231 declare_alias(const std::string &existing_entry_name,
1232 const std::string &alias_name,
1233 const bool alias_is_deprecated = false);
1234
1238 void
1239 enter_subsection(const std::string &subsection);
1240
1244 void
1246
1252 bool
1253 subsection_path_exists(const std::vector<std::string> &sub_path) const;
1254
1260 std::string
1261 get(const std::string &entry_string) const;
1262
1273 std::string
1274 get(const std::vector<std::string> &entry_subsection_path,
1275 const std::string & entry_string) const;
1276
1282 long int
1283 get_integer(const std::string &entry_string) const;
1284
1293 long int
1294 get_integer(const std::vector<std::string> &entry_subsection_path,
1295 const std::string & entry_string) const;
1296
1300 double
1301 get_double(const std::string &entry_name) const;
1302
1309 double
1310 get_double(const std::vector<std::string> &entry_subsection_path,
1311 const std::string & entry_string) const;
1317 bool
1318 get_bool(const std::string &entry_name) const;
1319
1328 bool
1329 get_bool(const std::vector<std::string> &entry_subsection_path,
1330 const std::string & entry_string) const;
1331
1341 void
1342 set(const std::string &entry_name, const std::string &new_value);
1343
1354 void
1355 set(const std::string &entry_name, const char *new_value);
1356
1366 void
1367 set(const std::string &entry_name, const long int new_value);
1368
1382 void
1383 set(const std::string &entry_name, const double new_value);
1384
1394 void
1395 set(const std::string &entry_name, const bool new_value);
1396
1469 std::ostream &
1470 print_parameters(std::ostream &out, const OutputStyle style) const;
1471
1472
1473
1494 void
1495 print_parameters(const std::string &filename,
1496 const OutputStyle style = DefaultStyle) const;
1497
1512 void
1513 log_parameters(LogStream &out, const OutputStyle style = DefaultStyle);
1514
1533 void
1535 const OutputStyle style = DefaultStyle);
1536
1541 std::size_t
1542 memory_consumption() const;
1543
1549 template <class Archive>
1550 void
1551 save(Archive &ar, const unsigned int version) const;
1552
1558 template <class Archive>
1559 void
1560 load(Archive &ar, const unsigned int version);
1561
1562#ifdef DOXYGEN
1568 template <class Archive>
1569 void
1570 serialize(Archive &archive, const unsigned int version);
1571#else
1572 // This macro defines the serialize() method that is compatible with
1573 // the templated save() and load() method that have been implemented.
1574 BOOST_SERIALIZATION_SPLIT_MEMBER()
1575#endif
1576
1580 bool
1581 operator==(const ParameterHandler &prm2) const;
1582
1591 std::set<std::string>
1593
1599 void
1601
1611 std::string,
1612 << "The following entry already exists: " << arg1 << ".");
1617 std::string,
1618 std::string,
1619 << "The string <" << arg1
1620 << "> does not match the given pattern <" << arg2 << ">.");
1626 "You can't leave a subsection if you are already at the top level "
1627 "of the subsection hierarchy.");
1632 std::string,
1633 << "You can't ask for entry <" << arg1
1634 << "> you have not yet declared.");
1635
1643 std::string,
1644 std::string,
1645 << "There are unequal numbers of 'subsection' and 'end' "
1646 "statements in the parameter file <"
1647 << arg1 << ">." << (arg2.size() > 0 ? "\n" + arg2 : ""));
1648
1654 int,
1655 std::string,
1656 std::string,
1657 << "Line <" << arg1 << "> of file <" << arg2
1658 << ": There is "
1659 "no such subsection to be entered: "
1660 << arg3);
1661
1668 int,
1669 std::string,
1670 std::string,
1671 << "Line <" << arg1 << "> of file <" << arg2 << ">: " << arg3);
1672
1679 int,
1680 std::string,
1681 std::string,
1682 std::string,
1683 std::string,
1684 << "Line <" << arg1 << "> of file <" << arg2
1685 << ">:\n"
1686 " The entry value \n"
1687 << " " << arg3 << '\n'
1688 << " for the entry named\n"
1689 << " " << arg4 << '\n'
1690 << " does not match the given pattern:\n"
1691 << " " << arg5);
1692
1699 "The provided file could not be parsed as a "
1700 "ParameterHandler description.");
1701
1711
1720 int,
1721 std::string,
1722 std::string,
1723 << "Line <" << arg1 << "> of file <" << arg2
1724 << ">: This line "
1725 "contains an 'include' or 'INCLUDE' statement, but the given "
1726 "file to include <"
1727 << arg3 << "> cannot be opened.");
1728
1730
1731private:
1736 static const char path_separator = '.';
1737
1741 std::vector<std::string> subsection_path;
1742
1751 std::unique_ptr<boost::property_tree::ptree> entries;
1752
1761 std::map<std::string, std::pair<bool, bool>> entries_set_status;
1762
1768 std::vector<std::unique_ptr<const Patterns::PatternBase>> patterns;
1769
1776 std::vector<std::function<void(const std::string &)>> actions;
1777
1786 std::string
1787 get_current_path() const;
1788
1793 std::string
1794 get_current_full_path(const std::string &name) const;
1795
1800 std::string
1801 get_current_full_path(const std::vector<std::string> &sub_path,
1802 const std::string & name) const;
1803
1822 void
1823 scan_line(std::string line,
1824 const std::string &input_filename,
1825 const unsigned int current_line_n,
1826 const bool skip_undefined);
1827
1839 void
1841 const boost::property_tree::ptree & tree,
1842 const std::vector<std::string> & target_subsection_path,
1844 const unsigned int indent_level,
1845 std::ostream & out) const;
1846
1848};
1849
1860{
1861 return static_cast<ParameterHandler::OutputStyle>(
1862 static_cast<unsigned int>(f1) | static_cast<unsigned int>(f2));
1863}
1864
2081{
2082public:
2088 {
2089 public:
2094 virtual ~UserClass() = default;
2095
2100 virtual void
2101 create_new(const unsigned int run_no) = 0;
2102
2106 virtual void
2108 };
2109
2114
2119 virtual ~MultipleParameterLoop() override = default;
2120
2142 virtual void
2143 parse_input(std::istream & input,
2144 const std::string &filename = "input file",
2145 const std::string &last_line = "",
2146 const bool skip_undefined = false) override;
2147
2156
2160 void
2161 loop(UserClass &uc);
2162
2167 std::size_t
2168 memory_consumption() const;
2169
2170private:
2174 class Entry
2175 {
2176 public:
2183 {
2191 array
2193
2198 : type(array)
2199 {}
2200
2206 Entry(const std::vector<std::string> &Path,
2207 const std::string & Name,
2208 const std::string & Value);
2209
2213 void
2215
2219 std::vector<std::string> subsection_path;
2220
2224 std::string entry_name;
2225
2229 std::string entry_value;
2230
2235 std::vector<std::string> different_values;
2236
2241
2246 std::size_t
2247 memory_consumption() const;
2248 };
2249
2253 std::vector<Entry> multiple_choices;
2254
2259 unsigned int n_branches;
2260
2264 void
2265 init_branches();
2266
2273 void
2275
2279 void
2280 fill_entry_values(const unsigned int run_no);
2281};
2282
2283
2284// ---------------------- inline and template functions --------------------
2285template <class Archive>
2286inline void
2287ParameterHandler::save(Archive &ar, const unsigned int) const
2288{
2289 // Forward to serialization
2290 // function in the base class.
2291 ar &static_cast<const Subscriptor &>(*this);
2292
2293 ar &*entries.get();
2294
2295 std::vector<std::string> descriptions;
2296
2297 for (const auto &pattern : patterns)
2298 descriptions.push_back(pattern->description());
2299
2300 ar &descriptions;
2301}
2302
2303
2304template <class Archive>
2305inline void
2306ParameterHandler::load(Archive &ar, const unsigned int)
2307{
2308 // Forward to serialization
2309 // function in the base class.
2310 ar &static_cast<Subscriptor &>(*this);
2311
2312 ar &*entries.get();
2313
2314 std::vector<std::string> descriptions;
2315 ar & descriptions;
2316
2317 patterns.clear();
2318 for (const auto &description : descriptions)
2319 patterns.push_back(Patterns::pattern_factory(description));
2320}
2321
2322
2323template <class ParameterType>
2324void
2325ParameterHandler::add_parameter(const std::string & entry,
2326 ParameterType & parameter,
2327 const std::string & documentation,
2328 const Patterns::PatternBase &pattern,
2329 const bool has_to_be_set)
2330{
2331 static_assert(std::is_const<ParameterType>::value == false,
2332 "You tried to add a parameter using a type "
2333 "that is const. Use a non-const type.");
2334
2335 declare_entry(entry,
2337 pattern),
2338 pattern,
2339 documentation,
2340 has_to_be_set);
2341
2342 std::string path = get_current_full_path(entry);
2343 const unsigned int pattern_index =
2344 entries->get<unsigned int>(path + path_separator + "pattern");
2345
2346 auto action = [&, pattern_index](const std::string &val) {
2348 val, *patterns[pattern_index]);
2349 };
2350 add_action(entry, action);
2351}
2352
2354
2355#endif
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)
ParameterHandler(const ParameterHandler &)=delete
std::ostream & print_parameters(std::ostream &out, const OutputStyle style) const
void add_action(const std::string &entry, const std::function< void(const std::string &value)> &action)
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)
ParameterHandler & operator=(const ParameterHandler &)=delete
void log_parameters_section(LogStream &out, const OutputStyle style=DefaultStyle)
bool subsection_path_exists(const std::vector< std::string > &sub_path) const
virtual ~ParameterHandler() override=default
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
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)
#define DEAL_II_DEPRECATED
Definition: config.h:162
#define DEAL_II_NAMESPACE_OPEN
Definition: config.h:402
#define DEAL_II_NAMESPACE_CLOSE
Definition: config.h:403
static const char path_separator
static ::ExceptionBase & ExcNoSubsection(int arg1, std::string arg2, std::string arg3)
static ::ExceptionBase & ExcCannotOpenIncludeStatementFile(int arg1, std::string arg2, std::string arg3)
static ::ExceptionBase & ExcEntryAlreadyExists(std::string arg1)
std::string get_current_path() const
std::vector< std::unique_ptr< const Patterns::PatternBase > > patterns
std::vector< std::string > subsection_path
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 fill_entry_values(const unsigned int run_no)
virtual void create_new(const unsigned int run_no)=0
std::vector< std::string > different_values
static ::ExceptionBase & ExcAlreadyAtTopLevel()
#define DeclException2(Exception2, type1, type2, outsequence)
Definition: exceptions.h:538
virtual void parse_input(std::istream &input, const std::string &filename="input file", const std::string &last_line="", const bool skip_undefined=false) override
std::size_t memory_consumption() const
static ::ExceptionBase & ExcInvalidEntryForPattern(int arg1, std::string arg2, std::string arg3, std::string arg4, std::string arg5)
ExcValueDoesNotMatchPattern ExcInvalidEntryForPatternXML
static T to_value(const std::string &s, const Patterns::PatternBase &p= *Convert< T >::to_pattern())=delete
std::map< std::string, std::pair< bool, bool > > entries_set_status
std::string get_current_full_path(const std::string &name) const
static ::ExceptionBase & ExcEntryUndeclared(std::string arg1)
#define DeclExceptionMsg(Exception, defaulttext)
Definition: exceptions.h:493
virtual void run(ParameterHandler &prm)=0
static ::ExceptionBase & ExcValueDoesNotMatchPattern(std::string arg1, std::string arg2)
static ::ExceptionBase & ExcUnbalancedSubsections(std::string arg1, std::string arg2)
virtual ~MultipleParameterLoop() override=default
#define DeclException3(Exception3, type1, type2, type3, outsequence)
Definition: exceptions.h:561
void loop(UserClass &uc)
std::vector< Entry > multiple_choices
#define DeclException1(Exception1, type1, outsequence)
Definition: exceptions.h:515
std::vector< std::function< void(const std::string &)> > actions
static ::ExceptionBase & ExcCannotParseLine(int arg1, std::string arg2, std::string arg3)
std::unique_ptr< boost::property_tree::ptree > entries
void scan_line(std::string line, const std::string &input_filename, const unsigned int current_line_n, const bool skip_undefined)
static ::ExceptionBase & ExcInvalidXMLParameterFile()
std::vector< std::string > subsection_path
std::size_t memory_consumption() const
#define DeclException5( Exception5, type1, type2, type3, type4, type5, outsequence)
Definition: exceptions.h:610
std::unique_ptr< PatternBase > pattern_factory(const std::string &description)
Definition: patterns.cc:140
ParameterHandler::OutputStyle operator|(const ParameterHandler::OutputStyle f1, const ParameterHandler::OutputStyle f2)