deal.II version GIT relicensing-2017-g7ae82fad8b 2024-10-22 19:20: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\}}\)
Loading...
Searching...
No Matches
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 <string>
33#include <vector>
34
36
37// forward declarations for interfaces and friendship
38#ifndef DOXYGEN
39class LogStream;
41#endif
42
855{
856public:
873 {
878 DefaultStyle = 0x0000,
879
884 Short = 0x0001,
885
890
895 PRM = 0x0010,
896
900 LaTeX = 0x0020,
901
907 Description = 0x0040,
908
916 XML = 0x0080,
917
923 JSON = 0x0100,
924
930
936
942
948
953 };
954
955
956
961
967 virtual ~ParameterHandler() override = default;
968
973
978 operator=(const ParameterHandler &) = delete;
979
1014 virtual void
1015 parse_input(std::istream &input,
1016 const std::string &filename = "input file",
1017 const std::string &last_line = "",
1018 const bool skip_undefined = false);
1019
1041 virtual void
1042 parse_input(const std::string &filename,
1043 const std::string &last_line = "",
1044 const bool skip_undefined = false,
1045 const bool assert_mandatory_entries_are_found = false);
1046
1055 virtual void
1056 parse_input_from_string(const std::string &s,
1057 const std::string &last_line = "",
1058 const bool skip_undefined = false);
1059
1067 virtual void
1068 parse_input_from_xml(std::istream &input, const bool skip_undefined = false);
1069
1077 virtual void
1078 parse_input_from_json(std::istream &input, const bool skip_undefined = false);
1079
1083 void
1084 clear();
1085
1086
1112 void
1113 declare_entry(const std::string &entry,
1114 const std::string &default_value,
1115 const Patterns::PatternBase &pattern = Patterns::Anything(),
1116 const std::string &documentation = "",
1117 const bool has_to_be_set = false);
1118
1136 void
1137 mark_as_deprecated(const std::string &entry, const bool is_deprecated = true);
1138
1186 void
1187 add_action(const std::string &entry,
1188 const std::function<void(const std::string &value)> &action,
1189 const bool execute_action = true);
1190
1206 template <typename ParameterType>
1207 void
1208 add_parameter(const std::string &entry,
1209 ParameterType &parameter,
1210 const std::string &documentation = "",
1211 const Patterns::PatternBase &pattern =
1213 const bool has_to_be_set = false);
1214
1258 void
1259 declare_alias(const std::string &existing_entry_name,
1260 const std::string &alias_name,
1261 const bool alias_is_deprecated = false);
1262
1266 void
1267 enter_subsection(const std::string &subsection,
1268 const bool create_path_if_needed = true);
1269
1273 void
1275
1281 bool
1282 subsection_path_exists(const std::vector<std::string> &sub_path) const;
1283
1293 std::string
1294 get_current_path() const;
1295
1301 std::string
1302 get_current_full_path(const std::string &name) const;
1303
1309 std::string
1310 get_current_full_path(const std::vector<std::string> &sub_path,
1311 const std::string &name) const;
1312
1318 std::string
1319 get(const std::string &entry_string) const;
1320
1331 std::string
1332 get(const std::vector<std::string> &entry_subsection_path,
1333 const std::string &entry_string) const;
1334
1340 long int
1341 get_integer(const std::string &entry_string) const;
1342
1351 long int
1352 get_integer(const std::vector<std::string> &entry_subsection_path,
1353 const std::string &entry_string) const;
1354
1358 double
1359 get_double(const std::string &entry_name) const;
1360
1367 double
1368 get_double(const std::vector<std::string> &entry_subsection_path,
1369 const std::string &entry_string) const;
1375 bool
1376 get_bool(const std::string &entry_name) const;
1377
1386 bool
1387 get_bool(const std::vector<std::string> &entry_subsection_path,
1388 const std::string &entry_string) const;
1389
1399 void
1400 set(const std::string &entry_name, const std::string &new_value);
1401
1412 void
1413 set(const std::string &entry_name, const char *new_value);
1414
1424 void
1425 set(const std::string &entry_name, const long int new_value);
1426
1440 void
1441 set(const std::string &entry_name, const double new_value);
1442
1452 void
1453 set(const std::string &entry_name, const bool new_value);
1454
1527 std::ostream &
1528 print_parameters(std::ostream &out, const OutputStyle style) const;
1529
1530
1531
1552 void
1553 print_parameters(const std::string &filename,
1554 const OutputStyle style = DefaultStyle) const;
1555
1570 void
1571 log_parameters(LogStream &out, const OutputStyle style = DefaultStyle);
1572
1591 void
1593 const OutputStyle style = DefaultStyle);
1594
1599 std::size_t
1600 memory_consumption() const;
1601
1607 template <class Archive>
1608 void
1609 save(Archive &ar, const unsigned int version) const;
1610
1616 template <class Archive>
1617 void
1618 load(Archive &ar, const unsigned int version);
1619
1620#ifdef DOXYGEN
1626 template <class Archive>
1627 void
1628 serialize(Archive &archive, const unsigned int version);
1629#else
1630 // This macro defines the serialize() method that is compatible with
1631 // the templated save() and load() method that have been implemented.
1632 BOOST_SERIALIZATION_SPLIT_MEMBER()
1633#endif
1634
1638 bool
1639 operator==(const ParameterHandler &prm2) const;
1640
1649 std::set<std::string>
1651
1657 void
1659
1669 std::string,
1670 << "The following entry already exists: " << arg1 << '.');
1671
1676 int,
1677 std::string,
1678 std::string,
1679 << "Line <" << arg1 << "> of file <" << arg2 << ">: "
1680 << "Entry <" << arg3 << "> is deprecated.");
1681
1686 std::string,
1687 << "The following deprecated entries were encountered:\n\n"
1688 << arg1);
1689
1694 std::string,
1695 std::string,
1696 << "The string <" << arg1
1697 << "> does not match the given pattern <" << arg2 << ">.");
1703 "You can't leave a subsection if you are already at the top level "
1704 "of the subsection hierarchy.");
1705
1710 std::string,
1711 << "You can't ask for entry <" << arg1
1712 << "> you have not yet declared.");
1713
1721 std::string,
1722 std::string,
1723 << "There are unequal numbers of 'subsection' and 'end' "
1724 "statements in the parameter file <"
1725 << arg1 << ">." << (arg2.size() > 0 ? "\n" + arg2 : ""));
1726
1732 int,
1733 std::string,
1734 std::string,
1735 << "Line <" << arg1 << "> of file <" << arg2
1736 << ">: You are trying to enter a subsection '" << arg3
1737 << "', but the ParameterHandler object does "
1738 << "not know of any such subsection.");
1739
1746 int,
1747 std::string,
1748 std::string,
1749 << "Line <" << arg1 << "> of file <" << arg2 << ">: " << arg3);
1750
1757 int,
1758 std::string,
1759 std::string,
1760 std::string,
1761 std::string,
1762 << "Line <" << arg1 << "> of file <" << arg2
1763 << ">:\n"
1764 " The entry value \n"
1765 << " " << arg3 << '\n'
1766 << " for the entry named\n"
1767 << " " << arg4 << '\n'
1768 << " does not match the given pattern:\n"
1769 << " " << arg5);
1770
1777 "The provided file could not be parsed as a "
1778 "ParameterHandler description.");
1779
1788 int,
1789 std::string,
1790 std::string,
1791 << "Line <" << arg1 << "> of file <" << arg2
1792 << ">: This line "
1793 "contains an 'include' or 'INCLUDE' statement, but the given "
1794 "file to include <"
1795 << arg3 << "> cannot be opened.");
1796
1799private:
1804 static const char path_separator = '.';
1805
1809 std::vector<std::string> subsection_path;
1810
1819 std::unique_ptr<boost::property_tree::ptree> entries;
1820
1829 std::map<std::string, std::pair<bool, bool>> entries_set_status;
1830
1836 std::vector<std::unique_ptr<const Patterns::PatternBase>> patterns;
1837
1844 std::vector<std::function<void(const std::string &)>> actions;
1845
1864 void
1865 scan_line(std::string line,
1866 const std::string &input_filename,
1867 const unsigned int current_line_n,
1868 const bool skip_undefined);
1869
1881 void
1883 const boost::property_tree::ptree &tree,
1884 const std::vector<std::string> &target_subsection_path,
1886 const unsigned int indent_level,
1887 std::ostream &out) const;
1888
1890};
1891
1902{
1903 return static_cast<ParameterHandler::OutputStyle>(
1904 static_cast<unsigned int>(f1) | static_cast<unsigned int>(f2));
1905}
1906
2123{
2124public:
2130 {
2131 public:
2136 virtual ~UserClass() = default;
2137
2142 virtual void
2143 create_new(const unsigned int run_no) = 0;
2144
2148 virtual void
2150 };
2151
2156
2161 virtual ~MultipleParameterLoop() override = default;
2162
2184 virtual void
2185 parse_input(std::istream &input,
2186 const std::string &filename = "input file",
2187 const std::string &last_line = "",
2188 const bool skip_undefined = false) override;
2189
2198
2202 void
2203 loop(UserClass &uc);
2204
2209 std::size_t
2210 memory_consumption() const;
2211
2212private:
2216 class Entry
2217 {
2218 public:
2235
2240 : type(array)
2241 {}
2242
2248 Entry(const std::vector<std::string> &Path,
2249 const std::string &Name,
2250 const std::string &Value);
2251
2255 void
2257
2261 std::vector<std::string> subsection_path;
2262
2266 std::string entry_name;
2267
2271 std::string entry_value;
2272
2277 std::vector<std::string> different_values;
2278
2283
2288 std::size_t
2289 memory_consumption() const;
2290 };
2291
2295 std::vector<Entry> multiple_choices;
2296
2301 unsigned int n_branches;
2302
2306 void
2307 init_branches();
2308
2315 void
2317
2321 void
2322 fill_entry_values(const unsigned int run_no);
2323};
2324
2325
2326// ---------------------- inline and template functions --------------------
2327template <class Archive>
2328inline void
2329ParameterHandler::save(Archive &ar, const unsigned int) const
2330{
2331 // Forward to serialization
2332 // function in the base class.
2333 ar &static_cast<const EnableObserverPointer &>(*this);
2334
2335 ar &*entries.get();
2336
2337 std::vector<std::string> descriptions;
2338
2339 descriptions.reserve(patterns.size());
2340 for (const auto &pattern : patterns)
2341 descriptions.push_back(pattern->description());
2342
2343 ar &descriptions;
2344}
2345
2346
2347template <class Archive>
2348inline void
2349ParameterHandler::load(Archive &ar, const unsigned int)
2350{
2351 // Forward to serialization
2352 // function in the base class.
2353 ar &static_cast<EnableObserverPointer &>(*this);
2354
2355 ar &*entries.get();
2356
2357 std::vector<std::string> descriptions;
2358 ar &descriptions;
2359
2360 patterns.clear();
2361 for (const auto &description : descriptions)
2362 patterns.push_back(Patterns::pattern_factory(description));
2363}
2364
2365
2366template <typename ParameterType>
2367void
2368ParameterHandler::add_parameter(const std::string &entry,
2369 ParameterType &parameter,
2370 const std::string &documentation,
2371 const Patterns::PatternBase &pattern,
2372 const bool has_to_be_set)
2373{
2374 static_assert(std::is_const_v<ParameterType> == false,
2375 "You tried to add a parameter using a type "
2376 "that is const. Use a non-const type.");
2377
2378 declare_entry(entry,
2380 pattern),
2381 pattern,
2382 documentation,
2383 has_to_be_set);
2384
2385 std::string path = get_current_full_path(entry);
2386 const unsigned int pattern_index =
2387 entries->get<unsigned int>(path + path_separator + "pattern");
2388
2389 auto action = [&, pattern_index](const std::string &val) {
2391 val, *patterns[pattern_index]);
2392 };
2393 add_action(entry, action, false);
2394}
2395
2397
2398#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:498
#define DEAL_II_NAMESPACE_CLOSE
Definition config.h:499
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)
Definition exceptions.h:534
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)
Definition exceptions.h:489
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)
Definition exceptions.h:557
#define DeclException1(Exception1, type1, outsequence)
Definition exceptions.h:511
static ::ExceptionBase & ExcCannotParseLine(int arg1, std::string arg2, std::string arg3)
static ::ExceptionBase & ExcInvalidXMLParameterFile()
#define DeclException5( Exception5, type1, type2, type3, type4, type5, outsequence)
Definition exceptions.h:606
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