Reference documentation for deal.II version 9.5.0
\(\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// Copyright (C) 2017 - 2023 by the deal.II authors
4//
5// This file is part of the deal.II library.
6//
7// The deal.II library is free software; you can use it, redistribute
8// it, and/or modify it under the terms of the GNU Lesser General
9// Public License as published by the Free Software Foundation; either
10// version 2.1 of the License, or (at your option) any later version.
11// The full text of the license can be found in the file LICENSE.md at
12// the top level directory of deal.II.
13//
14//-----------------------------------------------------------
15
19
20#include <boost/core/demangle.hpp>
21
22#include <fstream>
23
25
26
27namespace internal
28{
30 {
31 bool
33 {
34 return p1->get_acceptor_id() < p2->get_acceptor_id();
35 }
36 };
37} // namespace internal
38
39
40// Static mutex for the class list
42
43// Static empty class set
44std::set<ParameterAcceptor *, internal::ParameterAcceptorCompare>
46
47// Static parameter handler
49
51 : acceptor_id(ParameterAcceptor::get_next_free_id())
52 , section_name(name)
53{
54 std::lock_guard<std::mutex> l(class_list_mutex);
55 class_list.insert(this);
56}
57
58
59
61{
62 std::lock_guard<std::mutex> l(class_list_mutex);
63 // Notice that it is possible that the class is no longer in the static list.
64 // This happens when the clear() method has been called. We must guard that
65 // this is not the case, and therefore we only remove ourselves from the list
66 // if we are actually there.
67 if (class_list.find(this) != class_list.end())
68 class_list.erase(this);
69}
70
71
72
73std::string
75{
76 return (!section_name.empty() ? section_name :
77 boost::core::demangle(typeid(*this).name()));
78}
79
80
81
82void
84 const std::string & filename,
85 const std::string & output_filename,
86 const ParameterHandler::OutputStyle output_style_for_output_filename,
87 ParameterHandler & prm,
88 const ParameterHandler::OutputStyle output_style_for_filename)
89{
91 if (!filename.empty())
92 {
93 try
94 {
95 prm.parse_input(filename);
96 }
97 catch (const ::PathSearch::ExcFileNotFound &)
98 {
99 prm.print_parameters(filename, output_style_for_filename);
100 AssertThrow(false,
101 ExcMessage("You specified <" + filename + "> as input " +
102 "parameter file, but it does not exist. " +
103 "We created it for you."));
104 }
105 }
106
107 if (!output_filename.empty())
108 prm.print_parameters(output_filename, output_style_for_output_filename);
109
110 // Finally do the parsing.
112}
113
114
115
116void
117ParameterAcceptor::initialize(std::istream &input_stream, ParameterHandler &prm)
118
119{
120 AssertThrow(input_stream.fail() == false, ExcIO());
122 prm.parse_input(input_stream);
124}
125
126
127
128void
130{
131 std::lock_guard<std::mutex> l(class_list_mutex);
132 class_list.clear();
133 prm.clear();
134}
135
136
137
138void
140{}
141
142
143
144void
146{}
147
148
149
150void
152{
153 for (const auto &instance : class_list)
154 {
155 instance->enter_my_subsection(prm);
156 instance->parse_parameters(prm);
157 instance->parse_parameters_call_back();
158 instance->leave_my_subsection(prm);
159 }
160}
161
162
163
164void
166{
167 for (const auto &instance : class_list)
168 {
169 instance->enter_my_subsection(prm);
170 instance->declare_parameters(prm);
171 instance->declare_parameters_call_back();
172 instance->leave_my_subsection(prm);
173 }
174}
175
176
177
178std::vector<std::string>
180{
181 const auto my_section_name = get_section_name();
182 const bool is_absolute = (my_section_name.front() == sep);
183
184 std::vector<std::string> sections =
185 Utilities::split_string_list(my_section_name, sep);
186
187 // Split string list removes trailing empty strings, but not
188 // preceding ones. Make sure that if we had an absolute path,
189 // we don't store as first section the empty string.
190 if (is_absolute)
191 sections.erase(sections.begin());
192 else
193 {
194 // If we have a relative path, we prepend the path of the previous class
195 // to ours. This is tricky. If the previous class has a path with a
196 // trailing /, then the full path is used, else only the path except the
197 // last one
198 for (auto acceptor_it = class_list.rbegin();
199 acceptor_it != class_list.rend();
200 ++acceptor_it)
201 {
202 const auto acceptor = *acceptor_it;
203 if (acceptor->get_acceptor_id() >= get_acceptor_id())
204 continue;
205 bool has_trailing = acceptor->get_section_name().back() == sep;
206 auto previous_path = acceptor->get_section_path();
207
208 // See if we need to remove last piece of the path
209 if ((previous_path.size() > 0) && has_trailing == false)
210 previous_path.resize(previous_path.size() - 1);
211
212 sections.insert(sections.begin(),
213 previous_path.begin(),
214 previous_path.end());
215 // Exit the for cycle
216 break;
217 }
218 }
219 // Finally, insert the remaining subsections
220 sections.insert(sections.end(), subsections.begin(), subsections.end());
221 return sections;
222}
223
224
225
226void
227ParameterAcceptor::enter_subsection(const std::string &subsection)
228{
229 AssertThrow(subsection.find(sep) == std::string::npos,
231 "A subsection name cannot contain the special character '/'"));
232
233 AssertThrow(subsection != "",
234 ExcMessage("Cannot create an empty subsection."));
235
236 subsections.push_back(subsection);
237}
238
239
240
241void
243{
244 AssertThrow(subsections.size() > 0,
245 ExcMessage("There is no subsection to leave here."));
246 subsections.pop_back();
247}
248
249
250
251void
254{
255 const auto sections = get_section_path();
256 for (const auto &sec : sections)
257 {
259 }
260}
261
262
263
264void
267{
268 const auto sections = get_section_path();
269 for (unsigned int i = 0; i < sections.size(); ++i)
270 {
272 }
273}
274
275
276
277inline unsigned int
279{
280 return acceptor_id;
281}
282
283
284
285unsigned int
287{
288 static std::mutex id_mutex;
289 std::lock_guard<std::mutex> lock(id_mutex);
290 static int current_id = 0;
291 return current_id++;
292}
293
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)
std::ostream & print_parameters(std::ostream &out, const OutputStyle style) const
void enter_subsection(const std::string &subsection)
#define DEAL_II_NAMESPACE_OPEN
Definition config.h:472
#define DEAL_II_NAMESPACE_CLOSE
Definition config.h:473
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:702
bool operator()(const ParameterAcceptor *p1, const ParameterAcceptor *p2) const