Reference documentation for deal.II version GIT relicensing-870-g40dcf97519 2024-06-20 23:40:02+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_acceptor.cc
Go to the documentation of this file.
1// ------------------------------------------------------------------------
2//
3// SPDX-License-Identifier: LGPL-2.1-or-later
4// Copyright (C) 2017 - 2023 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
18
19#include <boost/core/demangle.hpp>
20
21#include <fstream>
22
24
25
26namespace internal
27{
29 {
30 bool
32 {
33 return p1->get_acceptor_id() < p2->get_acceptor_id();
34 }
35 };
36} // namespace internal
37
38
39// Static mutex for the class list
41
42// Static empty class set
43std::set<ParameterAcceptor *, internal::ParameterAcceptorCompare>
45
46// Static parameter handler
48
50 : acceptor_id(ParameterAcceptor::get_next_free_id())
51 , section_name(name)
52{
53 std::lock_guard<std::mutex> l(class_list_mutex);
54 class_list.insert(this);
55}
56
57
58
60{
61 std::lock_guard<std::mutex> l(class_list_mutex);
62 // Notice that it is possible that the class is no longer in the static list.
63 // This happens when the clear() method has been called. We must guard that
64 // this is not the case, and therefore we only remove ourselves from the list
65 // if we are actually there.
66 if (class_list.find(this) != class_list.end())
67 class_list.erase(this);
68}
69
70
71
72std::string
74{
75 return (!section_name.empty() ? section_name :
76 boost::core::demangle(typeid(*this).name()));
77}
78
79
80
81void
83 const std::string &filename,
84 const std::string &output_filename,
85 const ParameterHandler::OutputStyle output_style_for_output_filename,
87 const ParameterHandler::OutputStyle output_style_for_filename)
88{
90 if (!filename.empty())
91 {
92 try
93 {
94 prm.parse_input(filename);
95 }
96 catch (const ::PathSearch::ExcFileNotFound &)
97 {
98 prm.print_parameters(filename, output_style_for_filename);
99 AssertThrow(false,
100 ExcMessage("You specified <" + filename + "> as input " +
101 "parameter file, but it does not exist. " +
102 "We created it for you."));
103 }
104 }
105
106 if (!output_filename.empty())
107 prm.print_parameters(output_filename, output_style_for_output_filename);
108
109 // Finally do the parsing.
111}
112
113
114
115void
116ParameterAcceptor::initialize(std::istream &input_stream, ParameterHandler &prm)
117
118{
119 AssertThrow(input_stream.fail() == false, ExcIO());
121 prm.parse_input(input_stream);
123}
124
125
126
127void
129{
130 std::lock_guard<std::mutex> l(class_list_mutex);
131 class_list.clear();
132 prm.clear();
133}
134
135
136
137void
140
141
142
143void
146
147
148
149void
151{
152 for (const auto &instance : class_list)
153 {
154 instance->enter_my_subsection(prm);
155 instance->parse_parameters(prm);
156 instance->parse_parameters_call_back();
157 instance->leave_my_subsection(prm);
158 }
159}
160
161
162
163void
165{
166 for (const auto &instance : class_list)
167 {
168 instance->enter_my_subsection(prm);
169 instance->declare_parameters(prm);
170 instance->declare_parameters_call_back();
171 instance->leave_my_subsection(prm);
172 }
173}
174
175
176
177std::vector<std::string>
179{
180 const auto my_section_name = get_section_name();
181 const bool is_absolute = (my_section_name.front() == sep);
182
183 std::vector<std::string> sections =
184 Utilities::split_string_list(my_section_name, sep);
185
186 // Split string list removes trailing empty strings, but not
187 // preceding ones. Make sure that if we had an absolute path,
188 // we don't store as first section the empty string.
189 if (is_absolute)
190 sections.erase(sections.begin());
191 else
192 {
193 // If we have a relative path, we prepend the path of the previous class
194 // to ours. This is tricky. If the previous class has a path with a
195 // trailing /, then the full path is used, else only the path except the
196 // last one
197 for (auto acceptor_it = class_list.rbegin();
198 acceptor_it != class_list.rend();
199 ++acceptor_it)
200 {
201 auto *const acceptor = *acceptor_it;
202 if (acceptor->get_acceptor_id() >= get_acceptor_id())
203 continue;
204 bool has_trailing = acceptor->get_section_name().back() == sep;
205 auto previous_path = acceptor->get_section_path();
206
207 // See if we need to remove last piece of the path
208 if ((previous_path.size() > 0) && has_trailing == false)
209 previous_path.resize(previous_path.size() - 1);
210
211 sections.insert(sections.begin(),
212 previous_path.begin(),
213 previous_path.end());
214 // Exit the for cycle
215 break;
216 }
217 }
218 // Finally, insert the remaining subsections
219 sections.insert(sections.end(), subsections.begin(), subsections.end());
220 return sections;
221}
222
223
224
225void
226ParameterAcceptor::enter_subsection(const std::string &subsection)
227{
228 AssertThrow(subsection.find(sep) == std::string::npos,
230 "A subsection name cannot contain the special character '/'"));
231
232 AssertThrow(subsection != "",
233 ExcMessage("Cannot create an empty subsection."));
234
235 subsections.push_back(subsection);
236}
237
238
239
240void
242{
243 AssertThrow(subsections.size() > 0,
244 ExcMessage("There is no subsection to leave here."));
245 subsections.pop_back();
246}
247
248
249
250void
253{
254 const auto sections = get_section_path();
255 for (const auto &sec : sections)
256 {
258 }
259}
260
261
262
263void
266{
267 const auto sections = get_section_path();
268 for (unsigned int i = 0; i < sections.size(); ++i)
269 {
271 }
272}
273
274
275
276inline unsigned int
281
282
283
284unsigned int
286{
287 static std::mutex id_mutex;
288 std::lock_guard<std::mutex> lock(id_mutex);
289 static int current_id = 0;
290 return current_id++;
291}
292
virtual ~ParameterAcceptor() override
std::string get_section_name() const
static const char sep
static void declare_all_parameters(ParameterHandler &prm=ParameterAcceptor::prm)
unsigned int get_acceptor_id() const
const unsigned int acceptor_id
const std::string section_name
ParameterAcceptor(const std::string &section_name="")
std::vector< std::string > subsections
static void initialize(const std::string &filename="", const std::string &output_filename="", const ParameterHandler::OutputStyle output_style_for_output_filename=ParameterHandler::Short, ParameterHandler &prm=ParameterAcceptor::prm, const ParameterHandler::OutputStyle output_style_for_filename=ParameterHandler::DefaultStyle)
static ParameterHandler prm
void leave_my_subsection(ParameterHandler &prm)
void enter_subsection(const std::string &subsection)
virtual void parse_parameters(ParameterHandler &prm)
static unsigned int get_next_free_id()
static void parse_all_parameters(ParameterHandler &prm=ParameterAcceptor::prm)
void enter_my_subsection(ParameterHandler &prm)
static std::mutex class_list_mutex
static std::set< ParameterAcceptor *, internal::ParameterAcceptorCompare > class_list
virtual void declare_parameters(ParameterHandler &prm)
std::vector< std::string > get_section_path() const
virtual void parse_input(std::istream &input, const std::string &filename="input file", const std::string &last_line="", const bool skip_undefined=false)
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
#define DEAL_II_NAMESPACE_OPEN
Definition config.h:502
#define DEAL_II_NAMESPACE_CLOSE
Definition config.h:503
static ::ExceptionBase & ExcIO()
static ::ExceptionBase & ExcMessage(std::string arg1)
#define AssertThrow(cond, exc)
std::vector< std::string > split_string_list(const std::string &s, const std::string &delimiter=",")
Definition utilities.cc:701
bool operator()(const ParameterAcceptor *p1, const ParameterAcceptor *p2) const