deal.II version GIT relicensing-2287-g6548a49e0a 2024-12-20 18:30: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_acceptor.cc
Go to the documentation of this file.
1// ------------------------------------------------------------------------
2//
3// SPDX-License-Identifier: LGPL-2.1-or-later
4// Copyright (C) 2017 - 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
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. erase() does the
64 // righy thing anyway by only removing this class if it's still in the list.
65 class_list.erase(this);
66}
67
68
69
70std::string
72{
73 return (!section_name.empty() ? section_name :
74 boost::core::demangle(typeid(*this).name()));
75}
76
77
78
79void
81 const std::string &filename,
82 const std::string &output_filename,
83 const ParameterHandler::OutputStyle output_style_for_output_filename,
85 const ParameterHandler::OutputStyle output_style_for_filename)
86{
88 if (!filename.empty())
89 {
90 try
91 {
92 prm.parse_input(filename);
93 }
94 catch (const ::ExcFileNotOpen &)
95 {
96 prm.print_parameters(filename, output_style_for_filename);
97 AssertThrow(false,
98 ExcMessage("You specified <" + filename + "> as input " +
99 "parameter file, but it does not exist. " +
100 "We created it for you."));
101 }
102 }
103
104 if (!output_filename.empty())
105 prm.print_parameters(output_filename, output_style_for_output_filename);
106
107 // Finally do the parsing.
109}
110
111
112
113void
114ParameterAcceptor::initialize(std::istream &input_stream, ParameterHandler &prm)
115
116{
117 AssertThrow(input_stream.fail() == false, ExcIO());
119 prm.parse_input(input_stream);
121}
122
123
124
125void
127{
128 std::lock_guard<std::mutex> l(class_list_mutex);
129 class_list.clear();
130 prm.clear();
131}
132
133
134
135void
138
139
140
141void
144
145
146
147void
149{
150 for (const auto &instance : class_list)
151 {
152 instance->enter_my_subsection(prm);
153 instance->parse_parameters(prm);
154 instance->parse_parameters_call_back();
155 instance->leave_my_subsection(prm);
156 }
157}
158
159
160
161void
163{
164 for (const auto &instance : class_list)
165 {
166 instance->enter_my_subsection(prm);
167 instance->declare_parameters(prm);
168 instance->declare_parameters_call_back();
169 instance->leave_my_subsection(prm);
170 }
171}
172
173
174
175std::vector<std::string>
177{
178 const auto my_section_name = get_section_name();
179 const bool is_absolute = (my_section_name.front() == sep);
180
181 std::vector<std::string> sections =
182 Utilities::split_string_list(my_section_name, sep);
183
184 // Split string list removes trailing empty strings, but not
185 // preceding ones. Make sure that if we had an absolute path,
186 // we don't store as first section the empty string.
187 if (is_absolute)
188 sections.erase(sections.begin());
189 else
190 {
191 // If we have a relative path, we prepend the path of the previous class
192 // to ours. This is tricky. If the previous class has a path with a
193 // trailing /, then the full path is used, else only the path except the
194 // last one
195 for (auto acceptor_it = class_list.rbegin();
196 acceptor_it != class_list.rend();
197 ++acceptor_it)
198 {
199 const auto *const acceptor = *acceptor_it;
200 if (acceptor->get_acceptor_id() >= get_acceptor_id())
201 continue;
202 bool has_trailing = acceptor->get_section_name().back() == sep;
203 auto previous_path = acceptor->get_section_path();
204
205 // See if we need to remove last piece of the path
206 if ((previous_path.size() > 0) && has_trailing == false)
207 previous_path.resize(previous_path.size() - 1);
208
209 sections.insert(sections.begin(),
210 previous_path.begin(),
211 previous_path.end());
212 // Exit the for cycle
213 break;
214 }
215 }
216 // Finally, insert the remaining subsections
217 sections.insert(sections.end(), subsections.begin(), subsections.end());
218 return sections;
219}
220
221
222
223void
224ParameterAcceptor::enter_subsection(const std::string &subsection)
225{
226 AssertThrow(subsection.find(sep) == std::string::npos,
228 "A subsection name cannot contain the special character '/'"));
229
230 AssertThrow(subsection != "",
231 ExcMessage("Cannot create an empty subsection."));
232
233 subsections.push_back(subsection);
234}
235
236
237
238void
240{
241 AssertThrow(subsections.size() > 0,
242 ExcMessage("There is no subsection to leave here."));
243 subsections.pop_back();
244}
245
246
247
248void
251{
252 const auto sections = get_section_path();
253 for (const auto &sec : sections)
254 {
256 }
257}
258
259
260
261void
264{
265 const auto sections = get_section_path();
266 for (unsigned int i = 0; i < sections.size(); ++i)
267 {
269 }
270}
271
272
273
274inline unsigned int
279
280
281
282unsigned int
284{
285 static std::mutex id_mutex;
286 std::lock_guard<std::mutex> lock(id_mutex);
287 static int current_id = 0;
288 return current_id++;
289}
290
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:498
#define DEAL_II_NAMESPACE_CLOSE
Definition config.h:499
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