deal.II version GIT relicensing-6834-g5b78e6bcdf 2026-10-01 11:20:01+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: Apache-2.0 WITH LLVM-exception OR LGPL-2.1-or-later
4// Copyright (C) 2017 - 2026 by the deal.II authors
5//
6// This file is part of the deal.II library.
7//
8// Detailed license information governing the source code and contributions
9// can be found in LICENSE.md and CONTRIBUTING.md at the top level directory.
10//
11// -----------------------------------------------------------------------------
12
13#include <deal.II/base/config.h>
14
20
21#include <boost/core/demangle.hpp>
22#include <boost/iterator/iterator_facade.hpp>
23#include <boost/move/utility_core.hpp>
24#include <boost/signals2/optional_last_value.hpp>
25#include <boost/smart_ptr/make_shared_object.hpp>
26
27#include <fstream>
28#include <functional>
29#include <iterator>
30#include <list>
31#include <set>
32#include <typeinfo>
33
34
36
37
38namespace internal
39{
41 {
42 bool
44 {
45 return p1->get_acceptor_id() < p2->get_acceptor_id();
46 }
47 };
48} // namespace internal
49
50
51// Static mutex for the class list
53
54// Static empty class set
55std::set<ParameterAcceptor *, internal::ParameterAcceptorCompare>
57
58// Static parameter handler
60
62 : acceptor_id(ParameterAcceptor::get_next_free_id())
63 , section_name(name)
64{
65 std::scoped_lock l(class_list_mutex);
66 class_list.insert(this);
67}
68
69
70
72{
73 std::scoped_lock l(class_list_mutex);
74 // Notice that it is possible that the class is no longer in the static list.
75 // This happens when the clear() method has been called. erase() does the
76 // righy thing anyway by only removing this class if it's still in the list.
77 class_list.erase(this);
78}
79
80
81
82std::string
84{
85 return (!section_name.empty() ? section_name :
86 boost::core::demangle(typeid(*this).name()));
87}
88
89
90
91void
93 const std::string &filename,
94 const std::string &output_filename,
95 const ParameterHandler::OutputStyle output_style_for_output_filename,
97 const ParameterHandler::OutputStyle output_style_for_filename)
98{
100 if (!filename.empty())
101 {
102 try
103 {
104 prm.parse_input(filename);
105 }
106 catch (const ::ExcFileNotOpen &)
107 {
108 prm.print_parameters(filename, output_style_for_filename);
109 AssertThrow(false,
110 ExcMessage("You specified <" + filename + "> as input " +
111 "parameter file, but it does not exist. " +
112 "We created it for you."));
113 }
114 }
115
116 if (!output_filename.empty())
117 prm.print_parameters(output_filename, output_style_for_output_filename);
118
119 // Finally do the parsing.
121}
122
123
124
125void
126ParameterAcceptor::initialize(std::istream &input_stream, ParameterHandler &prm)
127
128{
129 AssertThrow(input_stream.fail() == false, ExcIO());
131 prm.parse_input(input_stream);
133}
134
135
136
137void
139{
140 std::scoped_lock l(class_list_mutex);
141 class_list.clear();
142 prm.clear();
143}
144
145
146
147void
150
151
152
153void
156
157
158
159void
161{
162 for (const auto &instance : class_list)
163 {
164 instance->enter_my_subsection(prm);
165 instance->parse_parameters(prm);
166 instance->parse_parameters_call_back();
167 instance->leave_my_subsection(prm);
168 }
169}
170
171
172
173void
175{
176 for (const auto &instance : class_list)
177 {
178 instance->enter_my_subsection(prm);
179 instance->declare_parameters(prm);
180 instance->declare_parameters_call_back();
181 instance->leave_my_subsection(prm);
182 }
183}
184
185
186
187std::vector<std::string>
189{
190 const auto my_section_name = get_section_name();
191 const bool is_absolute = (my_section_name.front() == sep);
192
193 std::vector<std::string> sections =
194 Utilities::split_string_list(my_section_name, sep);
195
196 // Split string list removes trailing empty strings, but not
197 // preceding ones. Make sure that if we had an absolute path,
198 // we don't store as first section the empty string.
199 if (is_absolute)
200 sections.erase(sections.begin());
201 else
202 {
203 // If we have a relative path, we prepend the path of the previous class
204 // to ours. This is tricky. If the previous class has a path with a
205 // trailing /, then the full path is used, else only the path except the
206 // last one
207 for (auto acceptor_it = class_list.rbegin();
208 acceptor_it != class_list.rend();
209 ++acceptor_it)
210 {
211 const auto *const acceptor = *acceptor_it;
212 if (acceptor->get_acceptor_id() >= get_acceptor_id())
213 continue;
214 bool has_trailing = acceptor->get_section_name().back() == sep;
215 auto previous_path = acceptor->get_section_path();
216
217 // See if we need to remove last piece of the path
218 if ((previous_path.size() > 0) && has_trailing == false)
219 previous_path.resize(previous_path.size() - 1);
220
221 sections.insert(sections.begin(),
222 previous_path.begin(),
223 previous_path.end());
224 // Exit the for cycle
225 break;
226 }
227 }
228 // Finally, insert the remaining subsections
229 sections.insert(sections.end(), subsections.begin(), subsections.end());
230 return sections;
231}
232
233
234
235void
236ParameterAcceptor::enter_subsection(const std::string &subsection)
237{
238 AssertThrow(subsection.find(sep) == std::string::npos,
240 "A subsection name cannot contain the special character '/'"));
241
242 AssertThrow(subsection != "",
243 ExcMessage("Cannot create an empty subsection."));
244
245 subsections.push_back(subsection);
246}
247
248
249
250void
252{
253 AssertThrow(subsections.size() > 0,
254 ExcMessage("There is no subsection to leave here."));
255 subsections.pop_back();
256}
257
258
259
260void
263{
264 const auto sections = get_section_path();
265 for (const auto &sec : sections)
266 {
268 }
269}
270
271
272
273void
276{
277 const auto sections = get_section_path();
278 for (unsigned int i = 0; i < sections.size(); ++i)
279 {
281 }
282}
283
284
285
286unsigned int
291
292
293
294unsigned int
296{
297 static std::mutex id_mutex;
298 std::scoped_lock lock(id_mutex);
299 static int current_id = 0;
300 return current_id++;
301}
302
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:38
#define DEAL_II_NAMESPACE_CLOSE
Definition config.h:39
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:695
bool operator()(const ParameterAcceptor *p1, const ParameterAcceptor *p2) const