deal2lkit: A ToolKit library for Deal.II
parameter_acceptor.cc
Go to the documentation of this file.
1 //-----------------------------------------------------------
2 //
3 // Copyright (C) 2015 - 2016 by the deal2lkit authors
4 //
5 // This file is part of the deal2lkit library.
6 //
7 // The deal2lkit 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 deal2lkit distribution.
13 //
14 //-----------------------------------------------------------
15 
17 #include <deal2lkit/utilities.h>
18 #include <deal.II/base/point.h>
19 #include <deal.II/base/revision.h>
20 #include <deal2lkit/revision.h>
21 #include <fstream>
22 
23 D2K_NAMESPACE_OPEN
24 
25 
26 // Static empty class list
27 std::vector<SmartPointer<ParameterAcceptor> > ParameterAcceptor::class_list;
28 // Static parameter handler
30 
31 ParameterAcceptor::ParameterAcceptor(const std::string name) :
32  acceptor_id(class_list.size()),
33  section_name(name)
34 {
35  SmartPointer<ParameterAcceptor> pt(this, type(*this).c_str());
36  class_list.push_back(pt);
37 }
38 
39 
41 {
43 }
44 
46 {
47  return (section_name != "" ? section_name : type(*this));
48 }
49 
50 
51 void
52 ParameterAcceptor::initialize(const std::string filename,
53  const std::string out_filename)
54 {
55  // prm.clear();
57  if (filename != "")
58  {
59 #pragma GCC diagnostic push
60 #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
61  // check the extension of input file
62  if (filename.substr(filename.find_last_of(".") + 1) == "prm")
63  prm.read_input(filename);
64  else if (filename.substr(filename.find_last_of(".") + 1) == "xml")
65  {
66  std::ifstream is(filename);
68 #pragma GCC diagnostic pop
69  }
70  else
71  AssertThrow(false, ExcMessage("Invalid extension of parameter file. Please use .prm or .xml"));
72  }
74  if (out_filename != "")
75  {
76  std::ofstream outfile(out_filename.c_str());
77  Assert(outfile, ExcIO());
78  std::string extension = out_filename.substr(out_filename.find_last_of(".") + 1);
79 
80  if ( extension == "prm")
81  {
82  outfile << "# Parameter file generated with " << std::endl
83  << "# D2K_GIT_BRANCH= " << D2K_GIT_BRANCH << std::endl
84  << "# D2K_GIT_SHORTREV= " << D2K_GIT_SHORTREV << std::endl
85  << "# DEAL_II_GIT_BRANCH= " << DEAL_II_GIT_BRANCH << std::endl
86  << "# DEAL_II_GIT_SHORTREV= " << DEAL_II_GIT_SHORTREV << std::endl;
88  }
89  else if (extension == "xml")
91  else if (extension == "latex" || extension == "tex")
93  else
95  }
96 }
97 
98 void
100 {
101  for (unsigned int i=0; i<class_list.size(); ++i)
102  if (class_list[i] != NULL)
103  class_list[i]->parameters.clear();
104 
105  class_list.clear();
106  prm.clear();
107 }
108 
109 void
111 {
112  deallog.push("ParameterAcceptor");
113  for (unsigned int i=0; i<class_list.size(); ++i)
114  {
115  deallog << "Class " << i << ":";
116  if (class_list[i])
117  deallog << class_list[i]->get_section_name() << std::endl;
118  else
119  deallog << " NULL" << std::endl;
120  }
121  deallog.pop();
122 }
123 
125 {
126  for (unsigned int i=0; i< class_list.size(); ++i)
127  if (class_list[i] != NULL)
128  {
129  class_list[i]->enter_my_subsection(prm);
130  class_list[i]->parse_parameters(prm);
131  class_list[i]->parse_parameters_call_back();
132  class_list[i]->leave_my_subsection(prm);
133  }
134 }
135 
137 {
138  for (unsigned int i=0; i< class_list.size(); ++i)
139  if (class_list[i] != NULL)
140  {
141  class_list[i]->enter_my_subsection(prm);
142  class_list[i]->declare_parameters(prm);
143  class_list[i]->leave_my_subsection(prm);
144  }
145 }
146 
147 
148 std::vector<std::string>
150 {
152  std::vector<std::string> sections =
154  bool is_absolute = false;
155  if (sections.size() > 1)
156  {
157  // Handle the cases of a leading "/"
158  if (sections[0] == "")
159  {
160  is_absolute = true;
161  sections.erase(sections.begin());
162  }
163  }
164  if (is_absolute == false)
165  {
166  // In all other cases, we scan for earlier classes, and prepend the
167  // first absolute path (in reverse order) we find to ours
168  for (int i=acceptor_id-1; i>=0; --i)
169  if (class_list[i] != NULL)
170  if (class_list[i]->get_section_name().front() == sep)
171  {
172  bool has_trailing = class_list[i]->get_section_name().back() == sep;
173  // Absolute path found
175  Assert(secs[0] == "", ExcInternalError());
176  // Insert all sections except first and last
177  sections.insert(sections.begin(), secs.begin()+1, secs.end()-(has_trailing ? 0 : 1));
178  // exit from for cycle
179  break;
180  }
181  }
182  return sections;
183 }
184 
186 {
187  std::vector<std::string> sections = get_section_path();
188  for (auto sec : sections)
189  {
190  prm.enter_subsection(sec);
191  }
192 }
193 
195 {
196  std::vector<std::string> sections = get_section_path();
197  for (auto sec : sections)
198  {
199  prm.leave_subsection();
200  }
201 }
202 
203 
204 
207 template<>
208 std_cxx11::shared_ptr<Patterns::PatternBase> ParameterAcceptor::to_pattern<std::string>(const std::string &)
209 {
210  return SP(new Patterns::Anything());
211 }
212 
213 template<>
214 std::string ParameterAcceptor::to_string<std::string>(const std::string &entry)
215 {
216  return entry;
217 }
218 
219 template<>
220 std::string ParameterAcceptor::to_type<std::string>(const std::string &parameter)
221 {
222  return parameter;
223 }
224 
226 template<>
227 std_cxx11::shared_ptr<Patterns::PatternBase> ParameterAcceptor::to_pattern<double>(const double &)
228 {
229  return SP(new Patterns::Double());
230 }
231 
232 template<>
233 std::string ParameterAcceptor::to_string<double>(const double &entry)
234 {
235  return std::to_string(entry);
236 }
237 
238 template<>
239 double ParameterAcceptor::to_type<double>(const std::string &parameter)
240 {
241  return std::stod(parameter);
242 }
243 
244 
246 template<>
247 std_cxx11::shared_ptr<Patterns::PatternBase> ParameterAcceptor::to_pattern<int>(const int &)
248 {
249  return SP(new Patterns::Integer());
250 }
251 
252 template<>
253 std::string ParameterAcceptor::to_string<int>(const int &entry)
254 {
255  return std::to_string(entry);
256 }
257 
258 template<>
259 int ParameterAcceptor::to_type<int>(const std::string &parameter)
260 {
261  return std::stoi(parameter);
262 }
263 
264 
266 template<>
267 std_cxx11::shared_ptr<Patterns::PatternBase> ParameterAcceptor::to_pattern<unsigned int>(const unsigned int &)
268 {
269  return SP(new Patterns::Integer(0));
270 }
271 
272 template<>
273 std::string ParameterAcceptor::to_string<unsigned int>(const unsigned int &entry)
274 {
275  return std::to_string(entry);
276 }
277 
278 template<>
279 unsigned int ParameterAcceptor::to_type<unsigned int>(const std::string &parameter)
280 {
281  return (unsigned int)std::stoi(parameter);
282 }
283 
284 
286 template<>
287 std_cxx11::shared_ptr<Patterns::PatternBase> ParameterAcceptor::to_pattern<bool>(const bool &)
288 {
289  return SP(new Patterns::Bool());
290 }
291 
292 template<>
293 std::string ParameterAcceptor::to_string<bool>(const bool &entry)
294 {
295  return std::string((entry ? "true" : "false"));
296 }
297 
298 template<>
299 bool ParameterAcceptor::to_type<bool>(const std::string &parameter)
300 {
301  return (parameter == "true" || parameter == "1");
302 }
303 
304 
306 #define MYP(dim) \
307  template<>\
308  std_cxx11::shared_ptr<Patterns::PatternBase> ParameterAcceptor::to_pattern<Point<dim> >(const Point<dim> &) {\
309  return SP(new Patterns::List(Patterns::Double(),dim,dim));\
310  }\
311  \
312  template<>\
313  std::string ParameterAcceptor::to_string<Point<dim> >(const Point<dim> &entry) {\
314  return print(entry);\
315  }\
316  \
317  template<>\
318  Point<dim> ParameterAcceptor::to_type<Point<dim> >(const std::string &parameter) {\
319  Point<dim> p;\
320  auto ps = Utilities::split_string_list(parameter);\
321  AssertDimension(ps.size(), dim);\
322  for(unsigned int i=0; i<dim; ++i)\
323  p[i] = std::stod(ps[i]);\
324  return p;\
325  }
326 
327 MYP(1)
328 MYP(2)
329 MYP(3)
330 #undef MYP
331 
332 
334 #define MYV(type, sep) \
335  template<>\
336  std_cxx11::shared_ptr<Patterns::PatternBase> ParameterAcceptor::to_pattern<std::vector<type> >(const std::vector<type> &) {\
337  type p;\
338  return SP(new Patterns::List(*to_pattern(p),0,Patterns::List::max_int_value,sep));\
339  }\
340  \
341  template<>\
342  std::string ParameterAcceptor::to_string<std::vector<type> >(const std::vector<type> &entry) {\
343  std::ostringstream s; \
344  if(entry.size() > 0) \
345  s << to_string(entry[0]); \
346  for(unsigned int i=1; i<entry.size(); ++i) \
347  s << std::string(sep) << " " << to_string(entry[i]); \
348  return s.str();\
349  }\
350  \
351  template<>\
352  std::vector<type> ParameterAcceptor::to_type<std::vector<type> >(const std::string &parameter) {\
353  auto ps = Utilities::split_string_list(parameter,sep[0]);\
354  std::vector<type> p(ps.size());\
355  for(unsigned int i=0; i<ps.size(); ++i)\
356  p[i] = to_type<type>(ps[i]);\
357  return p;\
358  }
359 
360 MYV(std::string, ",")
361 MYV(double, ",")
362 MYV(int, ",")
363 MYV(unsigned int, ",")
364 // MYV(bool, ",")
365 MYV(Point<1>, ";")
366 MYV(Point<2>, ";")
367 MYV(Point<3>, ";")
368 
369 
370 MYV(std::vector<std::string>, ";")
371 MYV(std::vector<double>, ";")
372 MYV(std::vector<int>, ";")
373 MYV(std::vector<unsigned int>, ";")
374 // MYV(std::vector<std::vector<bool> >, ";")
375 // MYV(std::vector<Point<1> >, ";")
376 // MYV(std::vector<Point<2> >, ";")
377 // MYV(std::vector<Point<3> >, ";")
378 #undef MYV
379 
380 namespace
381 {
382  template<class T>
383  inline bool to_boost_any(const std::string &entry, boost::any &boost_parameter)
384  {
385  if (boost_parameter.type() == typeid(T *))
386  {
387  T &parameter = *(boost::any_cast<T *>(boost_parameter));
388  parameter = ParameterAcceptor::to_type<T>(entry);
389  return true;
390  }
391  else
392  {
393  return false;
394  }
395  }
396 }
397 
399 {
400  for (auto &it : parameters)
401  {
402  const std::string &entry= prm.get(it.first);
403  boost::any &boost_parameter = it.second;
404 
405  if (to_boost_any<std::string>(entry, boost_parameter)) {}
406  else if (to_boost_any<double>(entry, boost_parameter)) {}
407  else if (to_boost_any<int>(entry, boost_parameter)) {}
408  else if (to_boost_any<unsigned int>(entry, boost_parameter)) {}
409  else if (to_boost_any<bool>(entry, boost_parameter)) {}
410  else if (to_boost_any<Point<1> >(entry, boost_parameter)) {}
411  else if (to_boost_any<Point<2> >(entry, boost_parameter)) {}
412  else if (to_boost_any<Point<3> >(entry, boost_parameter)) {}
413  else if (to_boost_any<std::vector<std::string> >(entry, boost_parameter)) {}
414  else if (to_boost_any<std::vector<double> >(entry, boost_parameter)) {}
415  else if (to_boost_any<std::vector<int> >(entry, boost_parameter)) {}
416  else if (to_boost_any<std::vector<unsigned int> >(entry, boost_parameter)) {}
417 // else if (to_boost_any<std::vector<bool> >(entry, boost_parameter)) {}
418  else if (to_boost_any<std::vector<Point<1> > >(entry, boost_parameter)) {}
419  else if (to_boost_any<std::vector<Point<2> > >(entry, boost_parameter)) {}
420  else if (to_boost_any<std::vector<Point<3> > >(entry, boost_parameter)) {}
421  else if (to_boost_any<std::vector<std::vector<std::string> > >(entry, boost_parameter)) {}
422  else if (to_boost_any<std::vector<std::vector<double> > >(entry, boost_parameter)) {}
423  else if (to_boost_any<std::vector<std::vector<int> > >(entry, boost_parameter)) {}
424  else if (to_boost_any<std::vector<std::vector<unsigned int> > >(entry, boost_parameter)) {}
425 // else if (to_boost_any<std::vector<std::vector<bool> > >(entry, boost_parameter)) {}
426  else
427  {
428  AssertThrow(false, ExcNotImplemented());
429  }
430  }
431 }
432 
434 
435 D2K_NAMESPACE_CLOSE
436 
static void clear()
Clear class list and global parameter file.
static ParameterHandler prm
Static parameter.
static::ExceptionBase & ExcIO()
static void log_info()
Print information about all stored classes.
virtual ~ParameterAcceptor()
The destructor sets to zero the pointer relative to this index, so that it is safe to destroy the mot...
static const char sep
Separator between section and subsection.
STL namespace.
#define AssertThrow(cond, exc)
shared_ptr< T > SP(T *t)
Construct a shared pointer to a non const class T.
Definition: utilities.h:483
std::string get(const std::string &entry_string) const
void enter_my_subsection(ParameterHandler &prm)
Make sure we enter the right subsection of the global parameter file.
void enter_subsection(const std::string &subsection)
virtual void parse_parameters_call_back()
Parse parameter call back.
std::string get_section_name() const
Return the section name of this class.
static::ExceptionBase & ExcMessage(std::string arg1)
const std::string section_name
The subsection name for this class.
virtual bool read_input(std::istream &input, const std::string &filename="input file", const std::string &last_line="") 1
virtual bool read_input_from_xml(std::istream &input) 1
void leave_my_subsection(ParameterHandler &prm)
This function undoes what the enter_my_subsection() function did.
static void declare_all_parameters(ParameterHandler &prm=ParameterAcceptor::prm)
Initialize the ParameterHandler with all derived classes parameters.This function enters the subsecti...
std::string type(const T &t)
Return a human readable name of the type passed as argument.
Definition: utilities.h:461
#define Assert(cond, exc)
void leave_subsection()
#define MYP(dim)
point
virtual void parse_parameters(ParameterHandler &prm)
Parse the parameter file.
ParameterAcceptor(const std::string section_name="")
The constructor adds derived classes to the list of acceptors.
#define MYV(type, sep)
vector
std::ostream & print_parameters(std::ostream &out, const OutputStyle style)
std::vector< std::string > split_string_list(const std::string &s, const char delimiter=',')
static void initialize(const std::string filename="", const std::string outfilename="")
Call declare_all_parameters(), read filename (if it is present as input parameter) and parse_all_para...
static::ExceptionBase & ExcNotImplemented()
static void parse_all_parameters(ParameterHandler &prm=ParameterAcceptor::prm)
Parse the given ParameterHandler.
static std::vector< SmartPointer< ParameterAcceptor > > class_list
A list containing all constructed classes of type ParameterAcceptor.
std::map< std::string, boost::any > parameters
A map of parameters that are initialized in this class with the functions add_parameters.
std::vector< std::string > get_section_path() const
Travers all registered classes, and figure out what subsections we need to enter. ...
const unsigned int acceptor_id
The index of this specific class within the class list.
static::ExceptionBase & ExcInternalError()