Reference documentation for deal.II version Git 52b85b2253 2021-11-28 10:49:58 +0100
\(\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 - 2021 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 // Static empty class list
28 std::vector<SmartPointer<ParameterAcceptor>> ParameterAcceptor::class_list;
29 // Static parameter handler
31 
32 ParameterAcceptor::ParameterAcceptor(const std::string &name)
33  : acceptor_id(class_list.size())
34  , section_name(name)
35 {
37  this, boost::core::demangle(typeid(*this).name()).c_str());
38  class_list.push_back(pt);
39 }
40 
41 
42 
44 {
45  class_list[acceptor_id] = nullptr;
46 }
47 
48 
49 
50 std::string
52 {
53  return (!section_name.empty() ? section_name :
54  boost::core::demangle(typeid(*this).name()));
55 }
56 
57 
58 
59 void
61  const std::string & filename,
62  const std::string & output_filename,
63  const ParameterHandler::OutputStyle output_style_for_output_filename,
65  const ParameterHandler::OutputStyle output_style_for_filename)
66 {
68  if (!filename.empty())
69  {
70  try
71  {
72  prm.parse_input(filename);
73  }
74  catch (const ::PathSearch::ExcFileNotFound &)
75  {
76  prm.print_parameters(filename, output_style_for_filename);
77  AssertThrow(false,
78  ExcMessage("You specified <" + filename + "> as input " +
79  "parameter file, but it does not exist. " +
80  "We created it for you."));
81  }
82  }
83 
84  if (!output_filename.empty())
85  prm.print_parameters(output_filename, output_style_for_output_filename);
86 
87  // Finally do the parsing.
89 }
90 
91 
92 
93 void
94 ParameterAcceptor::initialize(std::istream &input_stream, ParameterHandler &prm)
95 
96 {
97  AssertThrow(input_stream, ExcIO());
99  prm.parse_input(input_stream);
101 }
102 
103 
104 
105 void
107 {
108  class_list.clear();
109  prm.clear();
110 }
111 
112 
113 
114 void
116 {}
117 
118 
119 
120 void
122 {}
123 
124 
125 
126 void
128 {
129  for (const auto &instance : class_list)
130  if (instance != nullptr)
131  {
132  instance->enter_my_subsection(prm);
133  instance->parse_parameters(prm);
134  instance->parse_parameters_call_back();
135  instance->leave_my_subsection(prm);
136  }
137 }
138 
139 
140 
141 void
143 {
144  for (const auto &instance : class_list)
145  if (instance != nullptr)
146  {
147  instance->enter_my_subsection(prm);
148  instance->declare_parameters(prm);
149  instance->declare_parameters_call_back();
150  instance->leave_my_subsection(prm);
151  }
152 }
153 
154 
155 
156 std::vector<std::string>
158 {
160  const auto my_section_name = get_section_name();
161  const bool is_absolute = (my_section_name.front() == sep);
162 
163  std::vector<std::string> sections =
164  Utilities::split_string_list(my_section_name, sep);
165 
166  // Split string list removes trailing empty strings, but not
167  // preceding ones. Make sure that if we had an absolute path,
168  // we don't store as first section the empty string.
169  if (is_absolute)
170  sections.erase(sections.begin());
171  else
172  {
173  // If we have a relative path, we prepend the path of the previous class
174  // to ours. This is tricky. If the previous class has a path with a
175  // trailing /, then the full path is used, else only the path except the
176  // last one
177  for (int i = acceptor_id - 1; i >= 0; --i)
178  if (class_list[i] != nullptr)
179  {
180  bool has_trailing = class_list[i]->get_section_name().back() == sep;
181  auto previous_path = class_list[i]->get_section_path();
182 
183  // See if we need to remove last piece of the path
184  if ((previous_path.size() > 0) && has_trailing == false)
185  previous_path.resize(previous_path.size() - 1);
186 
187  sections.insert(sections.begin(),
188  previous_path.begin(),
189  previous_path.end());
190  // Exit the for cycle
191  break;
192  }
193  }
194  // Finally, insert the remaining subsections
195  sections.insert(sections.end(), subsections.begin(), subsections.end());
196  return sections;
197 }
198 
199 
200 
201 void
202 ParameterAcceptor::enter_subsection(const std::string &subsection)
203 {
204  AssertThrow(subsection.find(sep) == std::string::npos,
205  ExcMessage(
206  "A subsection name cannot contain the special character '/'"));
207 
208  AssertThrow(subsection != "",
209  ExcMessage("Cannot create an empty subsection."));
210 
211  subsections.push_back(subsection);
212 }
213 
214 
215 
216 void
218 {
219  AssertThrow(subsections.size() > 0,
220  ExcMessage("There is no subsection to leave here."));
221  subsections.pop_back();
222 }
223 
224 
225 
226 void
228  ParameterHandler &prm = ParameterAcceptor::prm)
229 {
230  const auto sections = get_section_path();
231  for (const auto &sec : sections)
232  {
234  }
235 }
236 
237 
238 
239 void
241  ParameterHandler &prm = ParameterAcceptor::prm)
242 {
243  const auto sections = get_section_path();
244  for (unsigned int i = 0; i < sections.size(); ++i)
245  {
247  }
248 }
249 
std::vector< std::string > split_string_list(const std::string &s, const std::string &delimiter=",")
Definition: utilities.cc:704
const unsigned int acceptor_id
void enter_my_subsection(ParameterHandler &prm)
static ::ExceptionBase & ExcIO()
static void declare_all_parameters(ParameterHandler &prm=ParameterAcceptor::prm)
virtual void parse_parameters(ParameterHandler &prm)
std::ostream & print_parameters(std::ostream &out, const OutputStyle style) const
#define AssertThrow(cond, exc)
Definition: exceptions.h:1571
ParameterAcceptor(const std::string &section_name="")
static std::vector< SmartPointer< ParameterAcceptor > > class_list
virtual ~ParameterAcceptor() override
void enter_subsection(const std::string &subsection)
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 ::ExceptionBase & ExcMessage(std::string arg1)
std::string get_section_name() const
#define Assert(cond, exc)
Definition: exceptions.h:1461
#define DEAL_II_NAMESPACE_CLOSE
Definition: config.h:401
virtual void parse_input(std::istream &input, const std::string &filename="input file", const std::string &last_line="", const bool skip_undefined=false)
static const char sep
std::vector< std::string > get_section_path() const
std::vector< std::string > subsections
void enter_subsection(const std::string &subsection)
virtual void declare_parameters(ParameterHandler &prm)
#define DEAL_II_NAMESPACE_OPEN
Definition: config.h:400
static ParameterHandler prm
static void parse_all_parameters(ParameterHandler &prm=ParameterAcceptor::prm)
const std::string section_name
void leave_my_subsection(ParameterHandler &prm)
static ::ExceptionBase & ExcInternalError()
Expression sec(const Expression &x)