Reference documentation for deal.II version GIT a3f17f8a20 2023-06-02 10:50: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\}}\)
parameter_acceptor.cc
Go to the documentation of this file.
1 //-----------------------------------------------------------
2 //
3 // Copyright (C) 2017 - 2022 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 
18 #include <deal.II/base/utilities.h>
19 
20 #include <boost/core/demangle.hpp>
21 
22 #include <fstream>
23 
25 
26 
27 namespace internal
28 {
30  {
31  bool
32  operator()(const ParameterAcceptor *p1, const ParameterAcceptor *p2) const
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
44 std::set<ParameterAcceptor *, internal::ParameterAcceptorCompare>
46 
47 // Static parameter handler
49 
50 ParameterAcceptor::ParameterAcceptor(const std::string &name)
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 
73 std::string
75 {
76  return (!section_name.empty() ? section_name :
77  boost::core::demangle(typeid(*this).name()));
78 }
79 
80 
81 
82 void
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 
116 void
117 ParameterAcceptor::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 
128 void
130 {
131  std::lock_guard<std::mutex> l(class_list_mutex);
132  class_list.clear();
133  prm.clear();
134 }
135 
136 
137 
138 void
140 {}
141 
142 
143 
144 void
146 {}
147 
148 
149 
150 void
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 
164 void
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 
178 std::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 
226 void
227 ParameterAcceptor::enter_subsection(const std::string &subsection)
228 {
229  AssertThrow(subsection.find(sep) == std::string::npos,
230  ExcMessage(
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 
241 void
243 {
244  AssertThrow(subsections.size() > 0,
245  ExcMessage("There is no subsection to leave here."));
246  subsections.pop_back();
247 }
248 
249 
250 
251 void
254 {
255  const auto sections = get_section_path();
256  for (const auto &sec : sections)
257  {
259  }
260 }
261 
262 
263 
264 void
267 {
268  const auto sections = get_section_path();
269  for (unsigned int i = 0; i < sections.size(); ++i)
270  {
272  }
273 }
274 
275 
276 
277 inline unsigned int
279 {
280  return acceptor_id;
281 }
282 
283 
284 
285 unsigned 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:474
#define DEAL_II_NAMESPACE_CLOSE
Definition: config.h:475
static ::ExceptionBase & ExcIO()
static ::ExceptionBase & ExcMessage(std::string arg1)
#define AssertThrow(cond, exc)
Definition: exceptions.h:1703
Expression sec(const Expression &x)
Tensor< 2, dim, Number > l(const Tensor< 2, dim, Number > &F, const Tensor< 2, dim, Number > &dF_dt)
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