Loading [MathJax]/extensions/TeX/AMSsymbols.js
 deal.II version GIT relicensing-2791-g2e2a880805 2025-03-11 02:00:00+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\}}\)
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages Concepts
parameter_handler.h
Go to the documentation of this file.
1// ------------------------------------------------------------------------
2//
3// SPDX-License-Identifier: LGPL-2.1-or-later
4// Copyright (C) 1998 - 2024 by the deal.II authors
5//
6// This file is part of the deal.II library.
7//
8// Part of the source code is dual licensed under Apache-2.0 WITH
9// LLVM-exception OR LGPL-2.1-or-later. Detailed license information
10// governing the source code and code contributions can be found in
11// LICENSE.md and CONTRIBUTING.md at the top level directory of deal.II.
12//
13// ------------------------------------------------------------------------
14
15#ifndef dealii_parameter_handler_h
16#define dealii_parameter_handler_h
17
18
19#include <deal.II/base/config.h>
20
24
25#include <boost/archive/basic_archive.hpp>
26#include <boost/property_tree/ptree_fwd.hpp>
27#include <boost/property_tree/ptree_serialization.hpp>
28#include <boost/serialization/split_member.hpp>
29
30#include <map>
31#include <memory>
32#include <set>
33#include <string>
34#include <vector>
35
37
38// forward declarations for interfaces and friendship
39#ifndef DOXYGEN
40class LogStream;
42#endif
43
856{
857public:
874 {
879 DefaultStyle = 0x0000,
880
885 Short = 0x0001,
886
891
896 PRM = 0x0010,
897
901 LaTeX = 0x0020,
902
908 Description = 0x0040,
909
917 XML = 0x0080,
918
924 JSON = 0x0100,
925
931
937
943
949
954 };
955
956
957
962
968 virtual ~ParameterHandler() override = default;
969
974
979 operator=(const ParameterHandler &) = delete;
980
1015 virtual void
1016 parse_input(std::istream &input,
1017 const std::string &filename = "input file",
1018 const std::string &last_line = "",
1019 const bool skip_undefined = false);
1020
1042 virtual void
1043 parse_input(const std::string &filename,
1044 const std::string &last_line = "",
1045 const bool skip_undefined = false,
1046 const bool assert_mandatory_entries_are_found = false);
1047
1056 virtual void
1057 parse_input_from_string(const std::string &s,
1058 const std::string &last_line = "",
1059 const bool skip_undefined = false);
1060
1068 virtual void
1069 parse_input_from_xml(std::istream &input, const bool skip_undefined = false);
1070
1078 virtual void
1079 parse_input_from_json(std::istream &input, const bool skip_undefined = false);
1080
1084 void
1085 clear();
1086
1087
1113 void
1114 declare_entry(const std::string &entry,
1115 const std::string &default_value,
1116 const Patterns::PatternBase &pattern = Patterns::Anything(),
1117 const std::string &documentation = "",
1118 const bool has_to_be_set = false);
1119
1137 void
1138 mark_as_deprecated(const std::string &entry, const bool is_deprecated = true);
1139
1187 void
1188 add_action(const std::string &entry,
1189 const std::function<void(const std::string &value)> &action,
1190 const bool execute_action = true);
1191
1207 template <typename ParameterType>
1208 void
1209 add_parameter(const std::string &entry,
1210 ParameterType &parameter,
1211 const std::string &documentation = "",
1212 const Patterns::PatternBase &pattern =
1214 const bool has_to_be_set = false);
1215
1259 void
1260 declare_alias(const std::string &existing_entry_name,
1261 const std::string &alias_name,
1262 const bool alias_is_deprecated = false);
1263
1267 void
1268 enter_subsection(const std::string &subsection,
1269 const bool create_path_if_needed = true);
1270
1274 void
1276
1282 bool
1283 subsection_path_exists(const std::vector<std::string> &sub_path) const;
1284
1294 std::string
1295 get_current_path() const;
1296
1302 std::string
1303 get_current_full_path(const std::string &name) const;
1304
1310 std::string
1311 get_current_full_path(const std::vector<std::string> &sub_path,
1312 const std::string &name) const;
1313
1319 std::string
1320 get(const std::string &entry_string) const;
1321
1332 std::string
1333 get(const std::vector<std::string> &entry_subsection_path,
1334 const std::string &entry_string) const;
1335
1341 long int
1342 get_integer(const std::string &entry_string) const;
1343
1352 long int
1353 get_integer(const std::vector<std::string> &entry_subsection_path,
1354 const std::string &entry_string) const;
1355
1359 double
1360 get_double(const std::string &entry_name) const;
1361
1368 double
1369 get_double(const std::vector<std::string> &entry_subsection_path,
1370 const std::string &entry_string) const;
1376 bool
1377 get_bool(const std::string &entry_name) const;
1378
1387 bool
1388 get_bool(const std::vector<std::string> &entry_subsection_path,
1389 const std::string &entry_string) const;
1390
1400 void
1401 set(const std::string &entry_name, const std::string &new_value);
1402
1413 void
1414 set(const std::string &entry_name, const char *new_value);
1415
1425 void
1426 set(const std::string &entry_name, const long int new_value);
1427
1441 void
1442 set(const std::string &entry_name, const double new_value);
1443
1453 void
1454 set(const std::string &entry_name, const bool new_value);
1455
1528 std::ostream &
1529 print_parameters(std::ostream &out, const OutputStyle style) const;
1530
1531
1532
1553 void
1554 print_parameters(const std::string &filename,
1555 const OutputStyle style = DefaultStyle) const;
1556
1571 void
1572 log_parameters(LogStream &out, const OutputStyle style = DefaultStyle);
1573
1592 void
1594 const OutputStyle style = DefaultStyle);
1595
1600 std::size_t
1601 memory_consumption() const;
1602
1608 template <class Archive>
1609 void
1610 save(Archive &ar, const unsigned int version) const;
1611
1617 template <class Archive>
1618 void
1619 load(Archive &ar, const unsigned int version);
1620
1621#ifdef DOXYGEN
1627 template <class Archive>
1628 void
1629 serialize(Archive &archive, const unsigned int version);
1630#else
1631 // This macro defines the serialize() method that is compatible with
1632 // the templated save() and load() method that have been implemented.
1633 BOOST_SERIALIZATION_SPLIT_MEMBER()
1634#endif
1635
1639 bool
1640 operator==(const ParameterHandler &prm2) const;
1641
1650 std::set<std::string>
1652
1658 void
1660
1670 std::string,
1671 << "The following entry already exists: " << arg1 << '.');
1672
1677 int,
1678 std::string,
1679 std::string,
1680 << "Line <" << arg1 << "> of file <" << arg2 << ">: "
1681 << "Entry <" << arg3 << "> is deprecated.");
1682
1687 std::string,
1688 << "The following deprecated entries were encountered:\n\n"
1689 << arg1);
1690
1695 std::string,
1696 std::string,
1697 << "The string <" << arg1
1698 << "> does not match the given pattern <" << arg2 << ">.");
1704 "You can't leave a subsection if you are already at the top level "
1705 "of the subsection hierarchy.");
1706
1711 std::string,
1712 << "You can't ask for entry <" << arg1
1713 << "> you have not yet declared.");
1714
1722 std::string,
1723 std::string,
1724 << "There are unequal numbers of 'subsection' and 'end' "
1725 "statements in the parameter file <"
1726 << arg1 << ">." << (arg2.size() > 0 ? "\n" + arg2 : ""));
1727
1733 int,
1734 std::string,
1735 std::string,
1736 << "Line <" << arg1 << "> of file <" << arg2
1737 << ">: You are trying to enter a subsection '" << arg3
1738 << "', but the ParameterHandler object does "
1739 << "not know of any such subsection.");
1740
1747 int,
1748 std::string,
1749 std::string,
1750 << "Line <" << arg1 << "> of file <" << arg2 << ">: " << arg3);
1751
1758 int,
1759 std::string,
1760 std::string,
1761 std::string,
1762 std::string,
1763 << "Line <" << arg1 << "> of file <" << arg2
1764 << ">:\n"
1765 " The entry value \n"
1766 << " " << arg3 << '\n'
1767 << " for the entry named\n"
1768 << " " << arg4 << '\n'
1769 << " does not match the given pattern:\n"
1770 << " " << arg5);
1771
1778 "The provided file could not be parsed as a "
1779 "ParameterHandler description.");
1780
1789 int,
1790 std::string,
1791 std::string,
1792 << "Line <" << arg1 << "> of file <" << arg2
1793 << ">: This line "
1794 "contains an 'include' or 'INCLUDE' statement, but the given "
1795 "file to include <"
1796 << arg3 << "> cannot be opened.");
1797
1800private:
1805 static const char path_separator = '.';
1806
1810 std::vector<std::string> subsection_path;
1811
1820 std::unique_ptr<boost::property_tree::ptree> entries;
1821
1830 std::map<std::string, std::pair<bool, bool>> entries_set_status;
1831
1837 std::vector<std::unique_ptr<const Patterns::PatternBase>> patterns;
1838
1845 std::vector<std::function<void(const std::string &)>> actions;
1846
1865 void
1866 scan_line(std::string line,
1867 const std::string &input_filename,
1868 const unsigned int current_line_n,
1869 const bool skip_undefined);
1870
1882 void
1884 const boost::property_tree::ptree &tree,
1885 const std::vector<std::string> &target_subsection_path,
1887 const unsigned int indent_level,
1888 std::ostream &out) const;
1889
1891};
1892
1903{
1904 return static_cast<ParameterHandler::OutputStyle>(
1905 static_cast<unsigned int>(f1) | static_cast<unsigned int>(f2));
1906}
1907
2124{
2125public:
2131 {
2132 public:
2137 virtual ~UserClass() = default;
2138
2143 virtual void
2144 create_new(const unsigned int run_no) = 0;
2145
2149 virtual void
2151 };
2152
2157
2162 virtual ~MultipleParameterLoop() override = default;
2163
2185 virtual void
2186 parse_input(std::istream &input,
2187 const std::string &filename = "input file",
2188 const std::string &last_line = "",
2189 const bool skip_undefined = false) override;
2190
2199
2203 void
2204 loop(UserClass &uc);
2205
2210 std::size_t
2211 memory_consumption() const;
2212
2213private:
2217 class Entry
2218 {
2219 public:
2236
2241 : type(array)
2242 {}
2243
2249 Entry(const std::vector<std::string> &Path,
2250 const std::string &Name,
2251 const std::string &Value);
2252
2256 void
2258
2262 std::vector<std::string> subsection_path;
2263
2267 std::string entry_name;
2268
2272 std::string entry_value;
2273
2278 std::vector<std::string> different_values;
2279
2284
2289 std::size_t
2290 memory_consumption() const;
2291 };
2292
2296 std::vector<Entry> multiple_choices;
2297
2302 unsigned int n_branches;
2303
2307 void
2308 init_branches();
2309
2316 void
2318
2322 void
2323 fill_entry_values(const unsigned int run_no);
2324};
2325
2326
2327// ---------------------- inline and template functions --------------------
2328template <class Archive>
2329inline void
2330ParameterHandler::save(Archive &ar, const unsigned int) const
2331{
2332 // Forward to serialization
2333 // function in the base class.
2334 ar &static_cast<const EnableObserverPointer &>(*this);
2335
2336 ar &*entries.get();
2337
2338 std::vector<std::string> descriptions;
2339
2340 descriptions.reserve(patterns.size());
2341 for (const auto &pattern : patterns)
2342 descriptions.push_back(pattern->description());
2343
2344 ar &descriptions;
2345}
2346
2347
2348template <class Archive>
2349inline void
2350ParameterHandler::load(Archive &ar, const unsigned int)
2351{
2352 // Forward to serialization
2353 // function in the base class.
2354 ar &static_cast<EnableObserverPointer &>(*this);
2355
2356 ar &*entries.get();
2357
2358 std::vector<std::string> descriptions;
2359 ar &descriptions;
2360
2361 patterns.clear();
2362 for (const auto &description : descriptions)
2363 patterns.push_back(Patterns::pattern_factory(description));
2364}
2365
2366
2367template <typename ParameterType>
2368void
2369ParameterHandler::add_parameter(const std::string &entry,
2370 ParameterType &parameter,
2371 const std::string &documentation,
2372 const Patterns::PatternBase &pattern,
2373 const bool has_to_be_set)
2374{
2375 static_assert(std::is_const_v<ParameterType> == false,
2376 "You tried to add a parameter using a type "
2377 "that is const. Use a non-const type.");
2378
2379 declare_entry(entry,
2381 pattern),
2382 pattern,
2383 documentation,
2384 has_to_be_set);
2385
2386 std::string path = get_current_full_path(entry);
2387 const unsigned int pattern_index =
2388 entries->get<unsigned int>(path + path_separator + "pattern");
2389
2390 auto action = [&, pattern_index](const std::string &val) {
2392 val, *patterns[pattern_index]);
2393 };
2394 add_action(entry, action, false);
2395}
2396
2398
2399#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
void fill_entry_values(const unsigned int run_no)
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
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
void enter_subsection(const std::string &subsection, const bool create_path_if_needed=true)
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
ParameterHandler & operator=(const ParameterHandler &)=delete
void mark_as_deprecated(const std::string &entry, const bool is_deprecated=true)
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 assert_that_entries_have_been_set() const
virtual void parse_input_from_json(std::istream &input, const bool skip_undefined=false)
#define DEAL_II_NAMESPACE_OPEN
Definition config.h:40
#define DEAL_II_NAMESPACE_CLOSE
Definition config.h:41
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)
static ::ExceptionBase & ExcEntryIsDeprecated(int arg1, std::string arg2, std::string arg3)
static ::ExceptionBase & ExcEncounteredDeprecatedEntries(std::string arg1)
static ::ExceptionBase & ExcAlreadyAtTopLevel()
#define DeclException2(Exception2, type1, type2, outsequence)
static ::ExceptionBase & ExcInvalidEntryForPattern(int arg1, std::string arg2, std::string arg3, std::string arg4, std::string arg5)
static ::ExceptionBase & ExcEntryUndeclared(std::string arg1)
#define DeclExceptionMsg(Exception, defaulttext)
static ::ExceptionBase & ExcValueDoesNotMatchPattern(std::string arg1, std::string arg2)
static ::ExceptionBase & ExcUnbalancedSubsections(std::string arg1, std::string arg2)
#define DeclException3(Exception3, type1, type2, type3, outsequence)
#define DeclException1(Exception1, type1, outsequence)
static ::ExceptionBase & ExcCannotParseLine(int arg1, std::string arg2, std::string arg3)
static ::ExceptionBase & ExcInvalidXMLParameterFile()
#define DeclException5( Exception5, type1, type2, type3, type4, type5, outsequence)
std::unique_ptr< PatternBase > pattern_factory(const std::string &description)
Definition patterns.cc:137
ParameterHandler::OutputStyle operator|(const ParameterHandler::OutputStyle f1, const ParameterHandler::OutputStyle f2)
static T to_value(const std::string &s, const Patterns::PatternBase &p= *Convert< T >::to_pattern())=delete