Reference documentation for deal.II version 9.0.0
parameter_acceptor.cc
1 //-----------------------------------------------------------
2 //
3 // Copyright (C) 2017 - 2018 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 at
12 // the top level of the deal.II distribution.
13 //
14 //-----------------------------------------------------------
15 
16 #include <deal.II/base/parameter_acceptor.h>
17 #include <deal.II/base/utilities.h>
18 #include <deal.II/base/path_search.h>
19 #include <boost/core/demangle.hpp>
20 #include <fstream>
21 
22 DEAL_II_NAMESPACE_OPEN
23 
24 
25 // Static empty class list
26 std::vector<SmartPointer<ParameterAcceptor> > ParameterAcceptor::class_list;
27 // Static parameter handler
29 
30 ParameterAcceptor::ParameterAcceptor(const std::string &name) :
31  acceptor_id(class_list.size()),
32  section_name(name)
33 {
34  SmartPointer<ParameterAcceptor> pt(this, boost::core::demangle(typeid(*this).name()).c_str());
35  class_list.push_back(pt);
36 }
37 
38 
40 {
41  class_list[acceptor_id] = nullptr;
42 }
43 
45 {
46  return (section_name != "" ? section_name : boost::core::demangle(typeid(*this).name()));
47 }
48 
49 
50 void
51 ParameterAcceptor::initialize(const std::string &filename,
52  const std::string &output_filename,
53  const ParameterHandler::OutputStyle output_style_for_prm_format,
54  ParameterHandler &prm)
55 {
57  if (filename != "")
58  {
59  // check the extension of input file
60  if (filename.substr(filename.find_last_of('.') + 1) == "prm")
61  {
62  try
63  {
64  prm.parse_input(filename);
65  }
66  catch (const ::PathSearch::ExcFileNotFound &)
67  {
68  std::ofstream out(filename);
69  Assert(out, ExcIO());
71  out.close();
72  AssertThrow(false, ExcMessage("You specified <"+filename+"> as input "+
73  "parameter file, but it does not exist. " +
74  "We created it for you."));
75  }
76  }
77  else if (filename.substr(filename.find_last_of('.') + 1) == "xml")
78  {
79  std::ifstream is(filename);
80  if (!is)
81  {
82  std::ofstream out(filename);
83  Assert(out, ExcIO());
85  out.close();
86  AssertThrow(false, ExcMessage("You specified <"+filename+"> as input "+
87  "parameter file, but it does not exist. " +
88  "We created it for you."));
89  }
91  }
92  else
93  AssertThrow(false, ExcMessage("Invalid extension of parameter file. Please use .prm or .xml"));
94  }
95 
96  if (output_filename != "")
97  {
98  std::ofstream outfile(output_filename.c_str());
99  Assert(outfile, ExcIO());
100  std::string extension = output_filename.substr(output_filename.find_last_of('.') + 1);
101 
102  if ( extension == "prm")
103  {
104  outfile << "# Parameter file generated with " << std::endl
105  << "# DEAL_II_PACKAGE_VERSION = " << DEAL_II_PACKAGE_VERSION << std::endl;
106  Assert(output_style_for_prm_format == ParameterHandler::Text ||
107  output_style_for_prm_format == ParameterHandler::ShortText,
108  ExcMessage("Only Text or ShortText can be specified in output_style_for_prm_format."))
109  prm.print_parameters(outfile, output_style_for_prm_format);
110  }
111  else if (extension == "xml")
113  else if (extension == "latex" || extension == "tex")
115  else
117  }
118 
119  // Finally do the parsing.
121 }
122 
123 
124 
125 void ParameterAcceptor::initialize(std::istream &input_stream,
126  ParameterHandler &prm)
127 
128 {
129  AssertThrow(input_stream, ExcIO());
131  prm.parse_input(input_stream);
133 }
134 
135 void
137 {
138  class_list.clear();
139  prm.clear();
140 }
141 
142 
143 
145 {}
146 
147 
148 
150 {}
151 
152 
153 
155 {
156  for (unsigned int i=0; i< class_list.size(); ++i)
157  if (class_list[i] != nullptr)
158  {
159  class_list[i]->enter_my_subsection(prm);
160  class_list[i]->parse_parameters(prm);
161  class_list[i]->parse_parameters_call_back();
162  class_list[i]->leave_my_subsection(prm);
163  }
164 }
165 
167 {
168  for (unsigned int i=0; i< class_list.size(); ++i)
169  if (class_list[i] != nullptr)
170  {
171  class_list[i]->enter_my_subsection(prm);
172  class_list[i]->declare_parameters(prm);
173  class_list[i]->declare_parameters_call_back();
174  class_list[i]->leave_my_subsection(prm);
175  }
176 }
177 
178 
179 std::vector<std::string>
181 {
183  const auto my_section_name = get_section_name();
184  const bool is_absolute = (my_section_name.front() == sep);
185 
186  std::vector<std::string> sections =
187  Utilities::split_string_list(my_section_name, sep);
188 
189  // Split string list removes trailing empty strings, but not
190  // preceding ones. Make sure that if we had an absolute path,
191  // we don't store as first section the empty string.
192  if (is_absolute)
193  sections.erase(sections.begin());
194  else
195  {
196  // If we have a relative path, we prepend the path of the previous class
197  // to ours. This is tricky. If the previous class has a path with a
198  // trailing /, then the full path is used, else only the path except the
199  // last one
200  for (int i=acceptor_id-1; i>=0; --i)
201  if (class_list[i] != nullptr)
202  {
203  bool has_trailing = class_list[i]->get_section_name().back() == sep;
204  auto previous_path = class_list[i]->get_section_path();
205 
206  // See if we need to remove last piece of the path
207  if ( (previous_path.size() > 0) && has_trailing == false)
208  previous_path.resize(previous_path.size()-1);
209 
210  sections.insert(sections.begin(), previous_path.begin(), previous_path.end());
211  // Exit the for cycle
212  break;
213  }
214  }
215  return sections;
216 }
217 
219 {
220  const auto sections = get_section_path();
221  for (const auto &sec : sections)
222  {
223  prm.enter_subsection(sec);
224  }
225 }
226 
228 {
229  const auto sections = get_section_path();
230  for (unsigned int i=0; i<sections.size(); ++i)
231  {
233  }
234 }
235 
236 
237 
238 DEAL_II_NAMESPACE_CLOSE
239 
std::vector< std::string > split_string_list(const std::string &s, const std::string &delimiter=",")
Definition: utilities.cc:283
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:1221
ParameterAcceptor(const std::string &section_name="")
static std::vector< SmartPointer< ParameterAcceptor > > class_list
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:1142
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()
virtual void parse_input(std::istream &input, const std::string &filename="input file", const std::string &last_line="")