Reference documentation for deal.II version 9.1.1
\(\newcommand{\dealcoloneq}{\mathrel{\vcenter{:}}=}\)
parameter_acceptor.cc
1 //-----------------------------------------------------------
2 //
3 // Copyright (C) 2017 - 2019 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 
16 #include <deal.II/base/parameter_acceptor.h>
17 #include <deal.II/base/path_search.h>
18 #include <deal.II/base/utilities.h>
19 
20 #include <boost/core/demangle.hpp>
21 
22 #include <fstream>
23 
24 DEAL_II_NAMESPACE_OPEN
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 
43 {
44  class_list[acceptor_id] = nullptr;
45 }
46 
47 std::string
49 {
50  return (!section_name.empty() ? section_name :
51  boost::core::demangle(typeid(*this).name()));
52 }
53 
54 
55 void
57  const std::string & filename,
58  const std::string & output_filename,
59  const ParameterHandler::OutputStyle output_style_for_prm_format,
60  ParameterHandler & prm)
61 {
63  if (!filename.empty())
64  {
65  // check the extension of input file
66  if (filename.substr(filename.find_last_of('.') + 1) == "prm")
67  {
68  try
69  {
70  prm.parse_input(filename);
71  }
72  catch (const ::PathSearch::ExcFileNotFound &)
73  {
74  std::ofstream out(filename);
75  Assert(out, ExcIO());
77  out.close();
78  AssertThrow(false,
79  ExcMessage("You specified <" + filename +
80  "> as input " +
81  "parameter file, but it does not exist. " +
82  "We created it for you."));
83  }
84  }
85  else if (filename.substr(filename.find_last_of('.') + 1) == "xml")
86  {
87  std::ifstream is(filename);
88  if (!is)
89  {
90  std::ofstream out(filename);
91  Assert(out, ExcIO());
93  out.close();
94  AssertThrow(false,
95  ExcMessage("You specified <" + filename +
96  "> as input " +
97  "parameter file, but it does not exist. " +
98  "We created it for you."));
99  }
101  }
102  else
103  AssertThrow(
104  false,
105  ExcMessage(
106  "Invalid extension of parameter file. Please use .prm or .xml"));
107  }
108 
109  if (!output_filename.empty())
110  {
111  std::ofstream outfile(output_filename.c_str());
112  Assert(outfile, ExcIO());
113  std::string extension =
114  output_filename.substr(output_filename.find_last_of('.') + 1);
115 
116  if (extension == "prm")
117  {
118  outfile << "# Parameter file generated with " << std::endl
119  << "# DEAL_II_PACKAGE_VERSION = " << DEAL_II_PACKAGE_VERSION
120  << std::endl;
121  Assert(
122  output_style_for_prm_format == ParameterHandler::Text ||
123  output_style_for_prm_format == ParameterHandler::ShortText,
124  ExcMessage(
125  "Only Text or ShortText can be specified in output_style_for_prm_format."))
126  prm.print_parameters(outfile, output_style_for_prm_format);
127  }
128  else if (extension == "xml")
130  else if (extension == "latex" || extension == "tex")
132  else
133  AssertThrow(false, ExcNotImplemented());
134  }
135 
136  // Finally do the parsing.
138 }
139 
140 
141 
142 void
143 ParameterAcceptor::initialize(std::istream &input_stream, ParameterHandler &prm)
144 
145 {
146  AssertThrow(input_stream, ExcIO());
148  prm.parse_input(input_stream);
150 }
151 
152 void
154 {
155  class_list.clear();
156  prm.clear();
157 }
158 
159 
160 
161 void
163 {}
164 
165 
166 
167 void
169 {}
170 
171 
172 
173 void
175 {
176  for (const auto &instance : class_list)
177  if (instance != nullptr)
178  {
179  instance->enter_my_subsection(prm);
180  instance->parse_parameters(prm);
181  instance->parse_parameters_call_back();
182  instance->leave_my_subsection(prm);
183  }
184 }
185 
186 void
188 {
189  for (const auto &instance : class_list)
190  if (instance != nullptr)
191  {
192  instance->enter_my_subsection(prm);
193  instance->declare_parameters(prm);
194  instance->declare_parameters_call_back();
195  instance->leave_my_subsection(prm);
196  }
197 }
198 
199 
200 std::vector<std::string>
202 {
204  const auto my_section_name = get_section_name();
205  const bool is_absolute = (my_section_name.front() == sep);
206 
207  std::vector<std::string> sections =
208  Utilities::split_string_list(my_section_name, sep);
209 
210  // Split string list removes trailing empty strings, but not
211  // preceding ones. Make sure that if we had an absolute path,
212  // we don't store as first section the empty string.
213  if (is_absolute)
214  sections.erase(sections.begin());
215  else
216  {
217  // If we have a relative path, we prepend the path of the previous class
218  // to ours. This is tricky. If the previous class has a path with a
219  // trailing /, then the full path is used, else only the path except the
220  // last one
221  for (int i = acceptor_id - 1; i >= 0; --i)
222  if (class_list[i] != nullptr)
223  {
224  bool has_trailing = class_list[i]->get_section_name().back() == sep;
225  auto previous_path = class_list[i]->get_section_path();
226 
227  // See if we need to remove last piece of the path
228  if ((previous_path.size() > 0) && has_trailing == false)
229  previous_path.resize(previous_path.size() - 1);
230 
231  sections.insert(sections.begin(),
232  previous_path.begin(),
233  previous_path.end());
234  // Exit the for cycle
235  break;
236  }
237  }
238  return sections;
239 }
240 
241 void
244 {
245  const auto sections = get_section_path();
246  for (const auto &sec : sections)
247  {
248  prm.enter_subsection(sec);
249  }
250 }
251 
252 void
255 {
256  const auto sections = get_section_path();
257  for (unsigned int i = 0; i < sections.size(); ++i)
258  {
260  }
261 }
262 
263 
264 
265 DEAL_II_NAMESPACE_CLOSE
std::vector< std::string > split_string_list(const std::string &s, const std::string &delimiter=",")
Definition: utilities.cc:566
const unsigned int acceptor_id
static void initialize(const std::string &filename="", const std::string &output_filename="", const ParameterHandler::OutputStyle output_style_for_prm_format=ParameterHandler::ShortText, ParameterHandler &prm=ParameterAcceptor::prm)
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:1519
ParameterAcceptor(const std::string &section_name="")
static std::vector< SmartPointer< ParameterAcceptor > > class_list
virtual ~ParameterAcceptor() override
void enter_subsection(const std::string &subsection)
virtual void parse_input_from_xml(std::istream &input)
static ::ExceptionBase & ExcMessage(std::string arg1)
std::string get_section_name() const
#define Assert(cond, exc)
Definition: exceptions.h:1407
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
virtual void declare_parameters(ParameterHandler &prm)
static ParameterHandler prm
static ::ExceptionBase & ExcNotImplemented()
static void parse_all_parameters(ParameterHandler &prm=ParameterAcceptor::prm)
const std::string section_name
void leave_my_subsection(ParameterHandler &prm)
static ::ExceptionBase & ExcInternalError()