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 
38 namespace libMesh
39 {
44 template<typename P>
45 void print_helper(std::ostream & os, const P * param);
46 
47 template<typename P>
48 void print_helper(std::ostream & os, const std::vector<P> * param);
49 
50 template<typename P>
51 void print_helper(std::ostream & os, const std::vector<std::vector<P>> * param);
52 
53 template<typename P>
54 void print_helper(std::ostream & os, const std::vector<std::vector<std::vector<P>>> * param);
55 
56 template<typename P1, typename P2, typename C, typename A>
57 void print_helper(std::ostream & os, const std::map<P1, P2, C, A> * param);
58 
59 template <typename P, typename C, typename A>
60 void print_helper(std::ostream & os, const std::set<P, C, A> * param);
61 
72 {
73 public:
74 
78  Parameters () = default;
79 
84  Parameters (const Parameters &);
85 
89  virtual ~Parameters () = default;
90 
95  virtual Parameters & operator= (const Parameters & source);
96 
102  virtual Parameters & operator+= (const Parameters & source);
103 
111  template <typename T>
112  bool have_parameter (std::string_view) const;
113 
118  template <typename T>
119  const T & get (std::string_view) const;
120 
126  template <typename T>
127  void insert (const std::string &);
128 
135  template <typename T>
136  T & set (const std::string &);
137 
142  virtual void set_attributes(const std::string &, bool /*inserted_only*/) {}
143 
147  void remove (std::string_view);
148 
152  std::size_t n_parameters () const { return _values.size(); }
153 
154 #ifdef LIBMESH_HAVE_RTTI
155 
158  template <typename T>
159  unsigned int n_parameters () const;
160 #endif // LIBMESH_HAVE_RTTI
161 
165  virtual void clear ();
166 
170  void print (std::ostream & os=libMesh::out) const;
171 
175  class Value : public ReferenceCountedObject<Value>
176  {
177  public:
178 
182  virtual ~Value() = default;
183 
184 #ifdef LIBMESH_HAVE_RTTI
185 
189  virtual std::string type () const = 0;
190 #endif // LIBMESH_HAVE_RTTI
191 
196  virtual void print(std::ostream &) const = 0;
197 
202  virtual std::unique_ptr<Value> clone () const = 0;
203  };
204 
209  template <typename T>
210  class Parameter : public Value
211  {
212  public:
213 
217  const T & get () const { return _value; }
218 
222  T & set () { return _value; }
223 
224 #ifdef LIBMESH_HAVE_RTTI
225 
228  virtual std::string type () const override;
229 #endif // LIBMESH_HAVE_RTTI
230 
234  virtual void print(std::ostream &) const override;
235 
239  virtual std::unique_ptr<Value> clone () const override;
240 
241  private:
246  };
247 
251  typedef std::map<std::string, std::unique_ptr<Value>, std::less<>> map_type;
252 
256  typedef map_type::iterator iterator;
257 
261  typedef map_type::const_iterator const_iterator;
262 
266  iterator begin();
267 
271  const_iterator begin() const;
272 
276  iterator end();
277 
281  const_iterator end() const;
282 
283 protected:
284 
289 };
290 
291 // ------------------------------------------------------------
292 // Parameters::Parameter<> class inline methods
293 
294 // This only works with Run-Time Type Information, even though
295 // typeid(T) *should* be determinable at compile time regardless...
296 #ifdef LIBMESH_HAVE_RTTI
297 template <typename T>
298 inline
299 std::string Parameters::Parameter<T>::type () const
300 {
301  return demangle(typeid(T).name());
302 }
303 #endif
304 
305 template <typename T>
306 inline
307 void Parameters::Parameter<T>::print (std::ostream & os) const
308 {
309  // Call helper function overloaded for basic scalar and vector types
310  print_helper(os, static_cast<const T *>(&_value));
311 }
312 
313 template <typename T>
314 inline
315 std::unique_ptr<Parameters::Value> Parameters::Parameter<T>::clone () const
316 {
317  auto copy = std::make_unique<Parameter<T>>();
318 
319  copy->_value = this->_value; // assign value
320 
321  return copy; // as unique_ptr to base class
322 }
323 
324 
325 // ------------------------------------------------------------
326 // Parameters class inline methods
327 inline
329 {
330  _values.clear();
331 }
332 
333 
334 
335 inline
337 {
338  this->Parameters::clear();
339  *this += source;
340 
341  return *this;
342 }
343 
344 inline
346 {
347  // Overwrite each value (if it exists) or create a new entry
348  for (const auto & [key, value] : source._values)
349  _values[key] = value->clone();
350 
351  return *this;
352 }
353 
354 inline
356 {
357  // calls assignment operator
358  *this = p;
359 }
360 
361 
362 
363 inline
364 void Parameters::print (std::ostream & os) const
365 {
366  Parameters::const_iterator it = _values.begin();
367 
368  os << "Name\t Type\t Value\n"
369  << "---------------------\n";
370  while (it != _values.end())
371  {
372  os << " " << it->first
373 #ifdef LIBMESH_HAVE_RTTI
374  << "\t " << it->second->type()
375 #endif // LIBMESH_HAVE_RTTI
376  << "\t "; it->second->print(os);
377  os << '\n';
378 
379  ++it;
380  }
381 }
382 
383 
384 
385 // Declare this now that Parameters::print() is defined.
386 // By declaring this early we can use it in subsequent
387 // methods. Required for gcc-4.0.2 -- 11/30/2005, BSK
388 inline
389 std::ostream & operator << (std::ostream & os, const Parameters & p)
390 {
391  p.print(os);
392  return os;
393 }
394 
395 
396 
397 template <typename T>
398 inline
399 bool Parameters::have_parameter (std::string_view name) const
400 {
402 
403  if (it != _values.end())
404  {
405 #ifdef LIBMESH_HAVE_RTTI
406 
407  if (dynamic_cast<const Parameter<T> *>(it->second.get()))
408  return true;
409 
410 #else // !LIBMESH_HAVE_RTTI
411 
412  // cast_ptr will simply do a static_cast here when RTTI is not
413  // enabled, and it will return a non-nullptr regardless of
414  // whether or not the cast actually succeeds.
415  libmesh_warning("Parameters::have_parameter() may return false positives when RTTI is not enabled.");
416 
417  if (cast_ptr<const Parameter<T> *>(it->second.get()))
418  return true;
419 
420 #endif
421  }
422 
423  return false;
424 }
425 
426 
427 
428 template <typename T>
429 inline
430 const T & Parameters::get (std::string_view name) const
431 {
432  if (!this->have_parameter<T>(name))
433  {
434  std::ostringstream oss;
435 
436  oss << "ERROR: no";
437 #ifdef LIBMESH_HAVE_RTTI
438  oss << ' ' << demangle(typeid(T).name());
439 #endif
440  oss << " parameter named \""
441  << name << "\" found.\n\n"
442  << "Known parameters:\n"
443  << *this;
444 
445  libmesh_error_msg(oss.str());
446  }
447 
449 
450  libmesh_assert(it != _values.end());
451  libmesh_assert(it->second);
452 
453  // Get pointer to derived type
454  auto ptr = cast_ptr<Parameter<T> *>(it->second.get());
455 
456  // Return const reference
457  return ptr->get();
458 }
459 
460 template <typename T>
461 inline
462 void Parameters::insert (const std::string & name)
463 {
464  if (!this->have_parameter<T>(name))
465  _values[name] = std::make_unique<Parameter<T>>();
466 
467  set_attributes(name, true);
468 }
469 
470 
471 template <typename T>
472 inline
473 T & Parameters::set (const std::string & name)
474 {
475  if (!this->have_parameter<T>(name))
476  _values[name] = std::make_unique<Parameter<T>>();
477 
478  set_attributes(name, false);
479 
480  // Get pointer to existing or just-added entry
481  auto ptr = cast_ptr<Parameter<T> *>(_values[name].get());
482 
483  // Return writeable reference
484  return ptr->set();
485 }
486 
487 inline
488 void Parameters::remove (std::string_view name)
489 {
490  Parameters::iterator it = _values.find(name);
491 
492  if (it != _values.end())
493  _values.erase(it);
494 }
495 
496 
497 
498 #ifdef LIBMESH_HAVE_RTTI
499 template <typename T>
500 inline
501 unsigned int Parameters::n_parameters () const
502 {
503  unsigned int cnt = 0;
504 
505  for (const auto & pr : _values)
506  if (dynamic_cast<Parameter<T> *>(pr.second.get()))
507  cnt++;
508 
509  return cnt;
510 }
511 #endif
512 
513 inline
515 {
516  return _values.begin();
517 }
518 
519 inline
521 {
522  return _values.begin();
523 }
524 
525 inline
527 {
528  return _values.end();
529 }
530 
531 inline
533 {
534  return _values.end();
535 }
536 
537 //non-member scalar print function
538 template<typename P>
539 void print_helper(std::ostream & os, const P * param)
540 {
541  os << *param;
542 }
543 
544 template<>
545 inline
546 void print_helper(std::ostream & os, const char * param)
547 {
548  // Specialization so that we don't print out unprintable characters
549  os << static_cast<int>(*param);
550 }
551 
552 template<>
553 inline
554 void print_helper(std::ostream & os, const unsigned char * param)
555 {
556  // Specialization so that we don't print out unprintable characters
557  os << static_cast<int>(*param);
558 }
559 
560 //non-member vector print function
561 template<typename P>
562 void print_helper(std::ostream & os, const std::vector<P> * param)
563 {
564  for (const auto & p : *param)
565  os << p << " ";
566 }
567 
568 //non-member vector<vector> print function
569 template<typename P>
570 void print_helper(std::ostream & os, const std::vector<std::vector<P>> * param)
571 {
572  for (const auto & pv : *param)
573  for (const auto & p : pv)
574  os << p << " ";
575 }
576 
577 //non-member vector<vector<vector>> print function
578 template<typename P>
579 void print_helper(std::ostream & os, const std::vector<std::vector<std::vector<P>>> * param)
580 {
581  for (const auto & pvv : *param)
582  for (const auto & pv : pvv)
583  for (const auto & p : pv)
584  os << p << " ";
585 }
586 
587 //non-member map print function
588 template<typename P1, typename P2, typename C, typename A>
589 void print_helper(std::ostream & os, const std::map<P1, P2, C, A> * param)
590 {
591  os << '{';
592  std::size_t sz = param->size();
593  for (auto KV : *param)
594  {
595  os << '\'' << KV.first << "\' => \'" << KV.second << '\'';
596  if (--sz)
597  os << ", ";
598  }
599  os << '}';
600 }
601 
602 //non-member set print function
603 template<typename P, typename C, typename A>
604 void print_helper(std::ostream & os, const std::set<P, C, A> * param)
605 {
606  for (const auto & p : *param)
607  os << p << " ";
608 }
609 
610 
611 } // namespace libMesh
612 
613 #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
bool have_parameter(std::string_view) const
Definition: parameters.h:399
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:539
This class provides the ability to map between arbitrary, user-defined strings and several data types...
Definition: parameters.h:71
map_type _values
Data structure to map names with values.
Definition: parameters.h:288
Tnew cast_ptr(Told *oldvar)
void print(std::ostream &os=libMesh::out) const
Prints the contents, by default to libMesh::out.
Definition: parameters.h:364
virtual std::unique_ptr< Value > clone() const override
Clone this value.
Definition: parameters.h:315
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:251
The libMesh namespace provides an interface to certain functionality in the library.
virtual Parameters & operator+=(const Parameters &source)
Addition/Assignment operator.
Definition: parameters.h:345
virtual std::unique_ptr< Value > clone() const =0
Clone this value.
Concrete definition of a parameter value for a specified type.
Definition: parameters.h:210
virtual Parameters & operator=(const Parameters &source)
Assignment operator.
Definition: parameters.h:336
iterator end()
Iterator pointing to the end of the set of parameters.
Definition: parameters.h:526
const T & get(std::string_view) const
Definition: parameters.h:430
void remove(std::string_view)
Removes the specified parameter from the list, if it exists.
Definition: parameters.h:488
Abstract definition of a parameter value.
Definition: parameters.h:175
libmesh_assert(ctx)
virtual ~Value()=default
Destructor.
iterator begin()
Iterator pointing to the beginning of the set of parameters.
Definition: parameters.h:514
This class implements reference counting.
std::string demangle(const char *name)
Mostly system independent demangler.
T _value
Stored parameter value.
Definition: parameters.h:245
virtual std::string type() const override
String identifying the type of parameter stored.
Definition: parameters.h:299
virtual void print(std::ostream &) const override
Prints the parameter value to the specified stream.
Definition: parameters.h:307
T & set(const std::string &)
Definition: parameters.h:473
OStreamProxy out
virtual void clear()
Clears internal data structures & frees any allocated memory.
Definition: parameters.h:328
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:462
std::size_t n_parameters() const
Definition: parameters.h:152
Parameters()=default
Default constructor.
map_type::const_iterator const_iterator
Constant parameter map iterator.
Definition: parameters.h:261
virtual void set_attributes(const std::string &, bool)
Overridable function to set any extended attributes for classes inheriting from this class...
Definition: parameters.h:142
map_type::iterator iterator
Parameter map iterator.
Definition: parameters.h:256