https://mooseframework.inl.gov
MFEMContainers.h
Go to the documentation of this file.
1 //* This file is part of the MOOSE framework
2 //* https://mooseframework.inl.gov
3 //*
4 //* All rights reserved, see COPYRIGHT for full restrictions
5 //* https://github.com/idaholab/moose/blob/master/COPYRIGHT
6 //*
7 //* Licensed under LGPL 2.1, please see LICENSE for details
8 //* https://www.gnu.org/licenses/lgpl-2.1.html
9 
10 #ifdef MOOSE_MFEM_ENABLED
11 
12 #pragma once
13 
14 #include <map>
15 #include <set>
16 #include <string>
17 #include <vector>
18 
19 namespace Moose::MFEM
20 {
21 
23 template <typename T>
25 {
26 public:
27  using MapType = std::map<std::string, std::shared_ptr<T>>;
28  using const_iterator = typename MapType::const_iterator;
29 
31  NamedFieldsMap() = default;
32 
35 
37  template <class FieldType, class... FieldArgs>
38  void Register(const std::string & field_name, FieldArgs &&... args)
39  {
40  Register(field_name, std::make_shared<FieldType>(std::forward<FieldArgs>(args)...));
41  }
42 
44  void Register(const std::string & field_name, std::shared_ptr<T> field)
45  {
46  CheckFieldIsRegistrable(field_name, field.get());
47 
48  Deregister(field_name);
49 
50  _field_map[field_name] = std::move(field);
51  }
52 
54  void Deregister(const std::string & field_name) { _field_map.erase(field_name); }
55 
57  [[nodiscard]] inline bool Has(const std::string & field_name) const
58  {
59  return FindField(field_name) != end();
60  }
61 
63  [[nodiscard]] inline std::shared_ptr<T> GetShared(const std::string & field_name) const
64  {
65  CheckFieldIsRegistered(field_name);
66 
67  auto it = FindField(field_name);
68 
69  return EnsureFieldPointerIsNonNull(it);
70  }
71 
73  [[nodiscard]] inline T & GetRef(const std::string & field_name) const
74  {
75  return *GetShared(field_name);
76  }
77 
79  [[nodiscard]] inline T * Get(const std::string & field_name) const
80  {
81  return GetShared(field_name).get();
82  }
83 
85  template <typename TDerived>
86  [[nodiscard]] inline TDerived * Get(const std::string & field_name) const
87  {
88  auto ptr = Get(field_name);
89 
90  return EnsurePointerCastIsNonNull<TDerived>(ptr);
91  }
92 
94  [[nodiscard]] std::vector<T *> Get(const std::vector<std::string> & keys) const
95  {
96  std::vector<T *> values;
97 
98  for (const auto & key : keys)
99  {
100  values.push_back(Get(key));
101  }
102 
103  values.shrink_to_fit();
104  return values;
105  }
106 
108  // NOLINTNEXTLINE(readability-identifier-naming)
109  [[nodiscard]] inline const_iterator begin() const { return _field_map.begin(); }
110 
112  // NOLINTNEXTLINE(readability-identifier-naming)
113  [[nodiscard]] inline const_iterator end() const { return _field_map.end(); }
114 
116  int size() { return _field_map.size(); }
117 
118 protected:
120  [[nodiscard]] inline const_iterator FindField(const std::string & field_name) const
121  {
122  return _field_map.find(field_name);
123  }
124 
126  void CheckFieldIsRegistrable([[maybe_unused]] const std::string & field_name,
127  [[maybe_unused]] T * field) const
128  {
129  mooseAssert(field, "Cannot register NULL field with name '" + field_name + "'.");
130  mooseAssert(!Has(field_name) || Get(field_name) != field,
131  "The field '" + field_name + "' is already registered.");
132  }
133 
135  void CheckFieldIsRegistered(const std::string & field_name) const
136  {
137  if (!Has(field_name))
138  mooseError("The field '" + field_name + "' has not been registered.");
139  }
140 
142  inline std::shared_ptr<T> EnsureFieldPointerIsNonNull(const_iterator & iterator) const
143  {
144  auto owned_ptr = iterator->second;
145  mooseAssert(owned_ptr, "The field '" + iterator->first + "' is NULL.");
146  return owned_ptr;
147  }
148 
150  template <typename TDerived>
151  inline TDerived * EnsurePointerCastIsNonNull(T * ptr) const
152  {
153  auto derived_ptr = dynamic_cast<TDerived *>(ptr);
154  mooseAssert(derived_ptr, "The dynamic cast performed on the field pointer failed.");
155  return derived_ptr;
156  }
157 
159  void DeregisterAll() { _field_map.clear(); }
160 
161 private:
163 };
164 
168 {
169 public:
170  using MapType = std::map<std::string, std::string>;
171  using const_iterator = typename MapType::const_iterator;
172 
173  inline void addTimeDerivativeAssociation(const std::string & var_name,
174  const std::string & time_derivative_var_name)
175  {
176  _field_map.emplace(var_name, time_derivative_var_name);
177  }
178 
179  inline bool isTimeDerivative(const std::string & time_derivative_var_name) const
180  {
181  for (auto const & [map_var_name, map_time_derivative_var_name] : _field_map)
182  {
183  if (map_time_derivative_var_name == time_derivative_var_name)
184  return true;
185  }
186  return false;
187  }
188 
189  inline bool hasTimeDerivative(const std::string & var_name) const
190  {
191  return _field_map.count(var_name);
192  }
193 
194  inline const std::string & getTimeDerivativeName(const std::string & var_name) const
195  {
196  auto it = _field_map.find(var_name);
197  if (it != _field_map.end())
198  return it->second;
199  else
200  {
201  mooseError("No variable representing the time derivative of ", var_name, " found.");
202  return null_str;
203  }
204  }
205 
206  inline const std::string & getTimeIntegralName(const std::string & time_derivative_var_name) const
207  {
208  for (auto const & [map_var_name, map_time_derivative_var_name] : _field_map)
209  {
210  if (map_time_derivative_var_name == time_derivative_var_name)
211  return map_var_name;
212  }
213  mooseError(
214  "No variable representing the time integral of ", time_derivative_var_name, " found.");
215  return null_str;
216  }
217 
218  inline static std::string createTimeDerivativeName(std::string_view name)
219  {
220  return std::string("d") + std::string(name) + std::string("_dt");
221  }
222 
223 private:
225  const std::string null_str;
226 };
227 
233 
234 } // namespace Moose::MFEM
235 
236 #endif
std::string name(const ElemQuality q)
static std::string createTimeDerivativeName(std::string_view name)
std::map< std::string, std::string > MapType
void CheckFieldIsRegistrable([[maybe_unused]] const std::string &field_name, [[maybe_unused]] T *field) const
Check that the field pointer is valid and the field has not already been registered.
bool Has(const std::string &field_name) const
Predicate to check if a field is registered with name field_name.
bool isTimeDerivative(const std::string &time_derivative_var_name) const
typename MapType::const_iterator const_iterator
void mooseError(Args &&... args)
Emit an error message with the given stringified, concatenated args and terminate the application...
Definition: MooseError.h:311
bool hasTimeDerivative(const std::string &var_name) const
void CheckFieldIsRegistered(const std::string &field_name) const
Check that a field exists in the map.
const_iterator FindField(const std::string &field_name) const
Returns a const iterator to the field.
std::shared_ptr< T > EnsureFieldPointerIsNonNull(const_iterator &iterator) const
Ensure that a returned shared pointer is valid.
Lightweight adaptor over a std::map relating names of GridFunctions with the name of their time deriv...
const std::string & getTimeIntegralName(const std::string &time_derivative_var_name) const
Lightweight adaptor over an std::map from strings to pointer to T.
typename MapType::const_iterator const_iterator
const_iterator end() const
Returns an end const iterator to the registered fields.
std::map< std::string, std::shared_ptr< mfem::ParNonlinearForm > > MapType
TDerived * EnsurePointerCastIsNonNull(T *ptr) const
Ensure that a dynamic cast is successful.
void addTimeDerivativeAssociation(const std::string &var_name, const std::string &time_derivative_var_name)
T * Get(const std::string &field_name) const
Returns a non-owning pointer to the field. This is guaranteed to return a non-null pointer...
const_iterator begin() const
Returns a begin const iterator to the registered fields.
std::shared_ptr< T > GetShared(const std::string &field_name) const
Returns a shared pointer to the field. This is guaranteed to return a non-null shared pointer...
NamedFieldsMap()=default
Default initializer.
void Register(const std::string &field_name, std::shared_ptr< T > field)
Register association between field and field_name.
TDerived * Get(const std::string &field_name) const
Returns a non-owning pointer to the field where TDerived is a derived class of class T...
void Deregister(const std::string &field_name)
Unregister association between a field and the field_name.
void Register(const std::string &field_name, FieldArgs &&... args)
Construct new field with name field_name and register.
int size()
Returns the number of elements in the map.
Utilities for converting between vector(s) of libMesh Points and MFEM Vector(s).
T & GetRef(const std::string &field_name) const
Returns a reference to a field.
void DeregisterAll()
Clear all associations between names and fields.
std::vector< T * > Get(const std::vector< std::string > &keys) const
Returns a vector containing all values for supplied keys.
const std::string & getTimeDerivativeName(const std::string &var_name) const