libMesh
parameters.h
Go to the documentation of this file.
1 // The libMesh Finite Element Library.
2 // Copyright (C) 2002-2025 Benjamin S. Kirk, John W. Peterson, Roy H. Stogner
3 
4 // This library is free software; you can redistribute it and/or
5 // modify it under the terms of the GNU Lesser General Public
6 // License as published by the Free Software Foundation; either
7 // version 2.1 of the License, or (at your option) any later version.
8 
9 // This library is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 // Lesser General Public License for more details.
13 
14 // You should have received a copy of the GNU Lesser General Public
15 // License along with this library; if not, write to the Free Software
16 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 
18 
19 
20 #ifndef LIBMESH_PARAMETERS_H
21 #define LIBMESH_PARAMETERS_H
22 
23 // Local includes
24 #include "libmesh/libmesh_common.h"
25 #include "libmesh/reference_counted_object.h"
26 #include "libmesh/print_trace.h"
27 
28 // C++ includes
29 #include <cstddef>
30 #include <map>
31 #include <sstream>
32 #include <string>
33 #include <typeinfo>
34 #include <vector>
35 #include <memory>
36 #include <set>
37 #ifdef LIBMESH_HAVE_RTTI
38 #include <typeinfo>
39 #endif
40 
41 namespace libMesh
42 {
47 template<typename P>
48 void print_helper(std::ostream & os, const P * param);
49 
50 template<typename P>
51 void print_helper(std::ostream & os, const std::vector<P> * param);
52 
53 template<typename P>
54 void print_helper(std::ostream & os, const std::vector<std::vector<P>> * param);
55 
56 template<typename P>
57 void print_helper(std::ostream & os, const std::vector<std::vector<std::vector<P>>> * param);
58 
59 template<typename P1, typename P2, typename C, typename A>
60 void print_helper(std::ostream & os, const std::map<P1, P2, C, A> * param);
61 
62 template <typename P, typename C, typename A>
63 void print_helper(std::ostream & os, const std::set<P, C, A> * param);
64 
75 {
76 public:
77 
81  Parameters () = default;
82 
87  Parameters (const Parameters &);
88 
92  virtual ~Parameters () = default;
93 
98  virtual Parameters & operator= (const Parameters & source);
99 
105  virtual Parameters & operator+= (const Parameters & source);
106 
114  template <typename T>
115  bool have_parameter (std::string_view) const;
116 
121  template <typename T>
122  const T & get (std::string_view) const;
123 
129  template <typename T>
130  void insert (const std::string &);
131 
138  template <typename T>
139  T & set (const std::string &);
140 
145  virtual void set_attributes(const std::string &, bool /*inserted_only*/) {}
146 
150  void remove (std::string_view);
151 
155  std::size_t n_parameters () const { return _values.size(); }
156 
157 #ifdef LIBMESH_HAVE_RTTI
158 
161  template <typename T>
162  unsigned int n_parameters () const;
163 #endif // LIBMESH_HAVE_RTTI
164 
168  virtual void clear ();
169 
173  void print (std::ostream & os=libMesh::out) const;
174 
178  class Value : public ReferenceCountedObject<Value>
179  {
180  public:
181 
185  virtual ~Value() = default;
186 
187 #ifdef LIBMESH_HAVE_RTTI
188 
192  virtual const std::type_info & type_info () const = 0;
193 
198  virtual std::string type () const = 0;
199 #endif // LIBMESH_HAVE_RTTI
200 
205  virtual void print(std::ostream &) const = 0;
206 
211  virtual std::unique_ptr<Value> clone () const = 0;
212  };
213 
218  template <typename T>
219  class Parameter : public Value
220  {
221  public:
222 
226  const T & get () const { return _value; }
227 
231  T & set () { return _value; }
232 
233 #ifdef LIBMESH_HAVE_RTTI
234 
237  virtual const std::type_info & type_info () const override;
238 
242  virtual std::string type () const override;
243 #endif // LIBMESH_HAVE_RTTI
244 
248  virtual void print(std::ostream &) const override;
249 
253  virtual std::unique_ptr<Value> clone () const override;
254 
255  private:
260  };
261 
265  typedef std::map<std::string, std::unique_ptr<Value>, std::less<>> map_type;
266 
270  typedef map_type::iterator iterator;
271 
275  typedef map_type::const_iterator const_iterator;
276 
280  iterator begin();
281 
285  const_iterator begin() const;
286 
290  iterator end();
291 
295  const_iterator end() const;
296 
297 protected:
298 
303 };
304 
305 // ------------------------------------------------------------
306 // Parameters::Parameter<> class inline methods
307 
308 // These only work with Run-Time Type Information, even though
309 // typeid(T) *should* be determinable at compile time regardless...
310 #ifdef LIBMESH_HAVE_RTTI
311 template <typename T>
312 inline
313 const std::type_info & Parameters::Parameter<T>::type_info () const
314 {
315  return typeid(T);
316 }
317 
318 template <typename T>
319 inline
320 std::string Parameters::Parameter<T>::type () const
321 {
322  return demangle(type_info().name());
323 }
324 #endif
325 
326 template <typename T>
327 inline
328 void Parameters::Parameter<T>::print (std::ostream & os) const
329 {
330  // Call helper function overloaded for basic scalar and vector types
331  print_helper(os, static_cast<const T *>(&_value));
332 }
333 
334 template <typename T>
335 inline
336 std::unique_ptr<Parameters::Value> Parameters::Parameter<T>::clone () const
337 {
338  auto copy = std::make_unique<Parameter<T>>();
339 
340  copy->_value = this->_value; // assign value
341 
342  return copy; // as unique_ptr to base class
343 }
344 
345 
346 // ------------------------------------------------------------
347 // Parameters class inline methods
348 inline
350 {
351  _values.clear();
352 }
353 
354 
355 
356 inline
358 {
359  this->Parameters::clear();
360  *this += source;
361 
362  return *this;
363 }
364 
365 inline
367 {
368  // Overwrite each value (if it exists) or create a new entry
369  for (const auto & [key, value] : source._values)
370  _values[key] = value->clone();
371 
372  return *this;
373 }
374 
375 inline
377 {
378  // calls assignment operator
379  *this = p;
380 }
381 
382 
383 
384 inline
385 void Parameters::print (std::ostream & os) const
386 {
387  Parameters::const_iterator it = _values.begin();
388 
389  os << "Name\t Type\t Value\n"
390  << "---------------------\n";
391  while (it != _values.end())
392  {
393  os << " " << it->first
394 #ifdef LIBMESH_HAVE_RTTI
395  << "\t " << it->second->type()
396 #endif // LIBMESH_HAVE_RTTI
397  << "\t "; it->second->print(os);
398  os << '\n';
399 
400  ++it;
401  }
402 }
403 
404 
405 
406 // Declare this now that Parameters::print() is defined.
407 // By declaring this early we can use it in subsequent
408 // methods. Required for gcc-4.0.2 -- 11/30/2005, BSK
409 inline
410 std::ostream & operator << (std::ostream & os, const Parameters & p)
411 {
412  p.print(os);
413  return os;
414 }
415 
416 
417 
418 template <typename T>
419 inline
420 bool Parameters::have_parameter (std::string_view name) const
421 {
423 
424  if (it != _values.end())
425  {
426 #ifdef LIBMESH_HAVE_RTTI
427 
428  if (dynamic_cast<const Parameter<T> *>(it->second.get()))
429  return true;
430 
431 #else // !LIBMESH_HAVE_RTTI
432 
433  // cast_ptr will simply do a static_cast here when RTTI is not
434  // enabled, and it will return a non-nullptr regardless of
435  // whether or not the cast actually succeeds.
436  libmesh_warning("Parameters::have_parameter() may return false positives when RTTI is not enabled.");
437 
438  if (cast_ptr<const Parameter<T> *>(it->second.get()))
439  return true;
440 
441 #endif
442  }
443 
444  return false;
445 }
446 
447 
448 
449 template <typename T>
450 inline
451 const T & Parameters::get (std::string_view name) const
452 {
453  if (!this->have_parameter<T>(name))
454  {
455  std::ostringstream oss;
456 
457  oss << "ERROR: no";
458 #ifdef LIBMESH_HAVE_RTTI
459  oss << ' ' << demangle(typeid(T).name());
460 #endif
461  oss << " parameter named \""
462  << name << "\" found.\n\n"
463  << "Known parameters:\n"
464  << *this;
465 
466  libmesh_error_msg(oss.str());
467  }
468 
470 
471  libmesh_assert(it != _values.end());
472  libmesh_assert(it->second);
473 
474  // Get pointer to derived type
475  auto ptr = cast_ptr<Parameter<T> *>(it->second.get());
476 
477  // Return const reference
478  return ptr->get();
479 }
480 
481 template <typename T>
482 inline
483 void Parameters::insert (const std::string & name)
484 {
485  if (!this->have_parameter<T>(name))
486  _values[name] = std::make_unique<Parameter<T>>();
487 
488  set_attributes(name, true);
489 }
490 
491 
492 template <typename T>
493 inline
494 T & Parameters::set (const std::string & name)
495 {
496  if (!this->have_parameter<T>(name))
497  _values[name] = std::make_unique<Parameter<T>>();
498 
499  set_attributes(name, false);
500 
501  // Get pointer to existing or just-added entry
502  auto ptr = cast_ptr<Parameter<T> *>(_values[name].get());
503 
504  // Return writeable reference
505  return ptr->set();
506 }
507 
508 inline
509 void Parameters::remove (std::string_view name)
510 {
511  Parameters::iterator it = _values.find(name);
512 
513  if (it != _values.end())
514  _values.erase(it);
515 }
516 
517 
518 
519 #ifdef LIBMESH_HAVE_RTTI
520 template <typename T>
521 inline
522 unsigned int Parameters::n_parameters () const
523 {
524  unsigned int cnt = 0;
525 
526  for (const auto & pr : _values)
527  if (dynamic_cast<Parameter<T> *>(pr.second.get()))
528  cnt++;
529 
530  return cnt;
531 }
532 #endif
533 
534 inline
536 {
537  return _values.begin();
538 }
539 
540 inline
542 {
543  return _values.begin();
544 }
545 
546 inline
548 {
549  return _values.end();
550 }
551 
552 inline
554 {
555  return _values.end();
556 }
557 
558 //non-member scalar print function
559 template<typename P>
560 void print_helper(std::ostream & os, const P * param)
561 {
562  os << *param;
563 }
564 
565 template<>
566 inline
567 void print_helper(std::ostream & os, const char * param)
568 {
569  // Specialization so that we don't print out unprintable characters
570  os << static_cast<int>(*param);
571 }
572 
573 template<>
574 inline
575 void print_helper(std::ostream & os, const unsigned char * param)
576 {
577  // Specialization so that we don't print out unprintable characters
578  os << static_cast<int>(*param);
579 }
580 
581 //non-member vector print function
582 template<typename P>
583 void print_helper(std::ostream & os, const std::vector<P> * param)
584 {
585  for (const auto & p : *param)
586  os << p << " ";
587 }
588 
589 //non-member vector<vector> print function
590 template<typename P>
591 void print_helper(std::ostream & os, const std::vector<std::vector<P>> * param)
592 {
593  for (const auto & pv : *param)
594  for (const auto & p : pv)
595  os << p << " ";
596 }
597 
598 //non-member vector<vector<vector>> print function
599 template<typename P>
600 void print_helper(std::ostream & os, const std::vector<std::vector<std::vector<P>>> * param)
601 {
602  for (const auto & pvv : *param)
603  for (const auto & pv : pvv)
604  for (const auto & p : pv)
605  os << p << " ";
606 }
607 
608 //non-member map print function
609 template<typename P1, typename P2, typename C, typename A>
610 void print_helper(std::ostream & os, const std::map<P1, P2, C, A> * param)
611 {
612  os << '{';
613  std::size_t sz = param->size();
614  for (auto KV : *param)
615  {
616  os << '\'' << KV.first << "\' => \'" << KV.second << '\'';
617  if (--sz)
618  os << ", ";
619  }
620  os << '}';
621 }
622 
623 //non-member set print function
624 template<typename P, typename C, typename A>
625 void print_helper(std::ostream & os, const std::set<P, C, A> * param)
626 {
627  for (const auto & p : *param)
628  os << p << " ";
629 }
630 
631 
632 } // namespace libMesh
633 
634 #endif // LIBMESH_PARAMETERS_H
std::string name(const ElemQuality q)
This function returns a string containing some name for q.
Definition: elem_quality.C:42
virtual const std::type_info & type_info() const override
std::type_info for type of parameter stored.
Definition: parameters.h:313
bool have_parameter(std::string_view) const
Definition: parameters.h:420
virtual void print(std::ostream &) const =0
Prints the parameter value to the specified stream.
virtual ~Parameters()=default
Destructor.
virtual std::string type() const =0
String identifying the type of parameter stored.
void print_helper(std::ostream &os, const P *param)
Helper functions for printing scalar, vector, vector<vector> and vector<vector<vector>> types...
Definition: parameters.h:560
This class provides the ability to map between arbitrary, user-defined strings and several data types...
Definition: parameters.h:74
map_type _values
Data structure to map names with values.
Definition: parameters.h:302
Tnew cast_ptr(Told *oldvar)
void print(std::ostream &os=libMesh::out) const
Prints the contents, by default to libMesh::out.
Definition: parameters.h:385
virtual std::unique_ptr< Value > clone() const override
Clone this value.
Definition: parameters.h:336
std::ostream & operator<<(std::ostream &os, const OrderWrapper &order)
Overload stream operators.
Definition: fe_type.h:182
std::map< std::string, std::unique_ptr< Value >, std::less<> > map_type
The type of the map that we store internally.
Definition: parameters.h:265
The libMesh namespace provides an interface to certain functionality in the library.
virtual Parameters & operator+=(const Parameters &source)
Addition/Assignment operator.
Definition: parameters.h:366
virtual std::unique_ptr< Value > clone() const =0
Clone this value.
Concrete definition of a parameter value for a specified type.
Definition: parameters.h:219
virtual Parameters & operator=(const Parameters &source)
Assignment operator.
Definition: parameters.h:357
iterator end()
Iterator pointing to the end of the set of parameters.
Definition: parameters.h:547
const T & get(std::string_view) const
Definition: parameters.h:451
void remove(std::string_view)
Removes the specified parameter from the list, if it exists.
Definition: parameters.h:509
Abstract definition of a parameter value.
Definition: parameters.h:178
libmesh_assert(ctx)
virtual ~Value()=default
Destructor.
iterator begin()
Iterator pointing to the beginning of the set of parameters.
Definition: parameters.h:535
This class implements reference counting.
std::string demangle(const char *name)
Mostly system independent demangler.
T _value
Stored parameter value.
Definition: parameters.h:259
virtual std::string type() const override
String identifying the type of parameter stored.
Definition: parameters.h:320
virtual void print(std::ostream &) const override
Prints the parameter value to the specified stream.
Definition: parameters.h:328
T & set(const std::string &)
Definition: parameters.h:494
OStreamProxy out
virtual void clear()
Clears internal data structures & frees any allocated memory.
Definition: parameters.h:349
static const bool value
Definition: xdr_io.C:55
void insert(const std::string &)
Inserts a new Parameter into the object but does not return a writable reference. ...
Definition: parameters.h:483
std::size_t n_parameters() const
Definition: parameters.h:155
Parameters()=default
Default constructor.
map_type::const_iterator const_iterator
Constant parameter map iterator.
Definition: parameters.h:275
virtual void set_attributes(const std::string &, bool)
Overridable function to set any extended attributes for classes inheriting from this class...
Definition: parameters.h:145
map_type::iterator iterator
Parameter map iterator.
Definition: parameters.h:270
virtual const std::type_info & type_info() const =0
std::type_info for type of parameter stored.