LCOV - code coverage report
Current view: top level - include/mfem/containers - MFEMContainers.h (source / functions) Hit Total Coverage
Test: idaholab/moose framework: #32971 (54bef8) with base c6cf66 Lines: 56 60 93.3 %
Date: 2026-05-29 20:35:17 Functions: 297 297 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       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             : 
      22             : /// Lightweight adaptor over an std::map from strings to pointer to T
      23             : template <typename T>
      24             : class NamedFieldsMap
      25             : {
      26             : public:
      27             :   using MapType = std::map<std::string, std::shared_ptr<T>>;
      28             :   using const_iterator = typename MapType::const_iterator;
      29             : 
      30             :   /// Default initializer.
      31       24797 :   NamedFieldsMap() = default;
      32             : 
      33             :   /// Destructor.
      34       24797 :   ~NamedFieldsMap() { DeregisterAll(); }
      35             : 
      36             :   /// Construct new field with name field_name and register.
      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             : 
      43             :   /// Register association between field and field_name.
      44       21626 :   void Register(const std::string & field_name, std::shared_ptr<T> field)
      45             :   {
      46       21626 :     CheckFieldIsRegistrable(field_name, field.get());
      47             : 
      48       21626 :     Deregister(field_name);
      49             : 
      50       21626 :     _field_map[field_name] = std::move(field);
      51       21626 :   }
      52             : 
      53             :   /// Unregister association between a field and the field_name.
      54       21626 :   void Deregister(const std::string & field_name) { _field_map.erase(field_name); }
      55             : 
      56             :   /// Predicate to check if a field is registered with name field_name.
      57      126469 :   [[nodiscard]] inline bool Has(const std::string & field_name) const
      58             :   {
      59      126469 :     return FindField(field_name) != end();
      60             :   }
      61             : 
      62             :   /// Returns a shared pointer to the field. This is guaranteed to return a non-null shared pointer.
      63       84878 :   [[nodiscard]] inline std::shared_ptr<T> GetShared(const std::string & field_name) const
      64             :   {
      65       84878 :     CheckFieldIsRegistered(field_name);
      66             : 
      67       84878 :     auto it = FindField(field_name);
      68             : 
      69      169756 :     return EnsureFieldPointerIsNonNull(it);
      70             :   }
      71             : 
      72             :   /// Returns a reference to a field.
      73       28963 :   [[nodiscard]] inline T & GetRef(const std::string & field_name) const
      74             :   {
      75       28963 :     return *GetShared(field_name);
      76             :   }
      77             : 
      78             :   /// Returns a non-owning pointer to the field. This is guaranteed to return a non-null pointer.
      79       41274 :   [[nodiscard]] inline T * Get(const std::string & field_name) const
      80             :   {
      81       41274 :     return GetShared(field_name).get();
      82             :   }
      83             : 
      84             :   /// Returns a non-owning pointer to the field where TDerived is a derived class of class T.
      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             : 
      93             :   /// Returns a vector containing all values for supplied keys.
      94        2774 :   [[nodiscard]] std::vector<T *> Get(const std::vector<std::string> & keys) const
      95             :   {
      96        2774 :     std::vector<T *> values;
      97             : 
      98        4700 :     for (const auto & key : keys)
      99             :     {
     100        1926 :       values.push_back(Get(key));
     101             :     }
     102             : 
     103        2774 :     values.shrink_to_fit();
     104        2774 :     return values;
     105           0 :   }
     106             : 
     107             :   /// Returns a begin const iterator to the registered fields.
     108             :   // NOLINTNEXTLINE(readability-identifier-naming)
     109        1325 :   [[nodiscard]] inline const_iterator begin() const { return _field_map.begin(); }
     110             : 
     111             :   /// Returns an end const iterator to the registered fields.
     112             :   // NOLINTNEXTLINE(readability-identifier-naming)
     113      127794 :   [[nodiscard]] inline const_iterator end() const { return _field_map.end(); }
     114             : 
     115             :   /// Returns the number of elements in the map
     116        1361 :   int size() { return _field_map.size(); }
     117             : 
     118             : protected:
     119             :   /// Returns a const iterator to the field.
     120      211347 :   [[nodiscard]] inline const_iterator FindField(const std::string & field_name) const
     121             :   {
     122      211347 :     return _field_map.find(field_name);
     123             :   }
     124             : 
     125             :   /// Check that the field pointer is valid and the field has not already been registered.
     126       21626 :   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       21626 :   }
     133             : 
     134             :   /// Check that a field exists in the map.
     135       84878 :   void CheckFieldIsRegistered(const std::string & field_name) const
     136             :   {
     137       84878 :     if (!Has(field_name))
     138           0 :       mooseError("The field '" + field_name + "' has not been registered.");
     139       84878 :   }
     140             : 
     141             :   /// Ensure that a returned shared pointer is valid.
     142       84878 :   inline std::shared_ptr<T> EnsureFieldPointerIsNonNull(const_iterator & iterator) const
     143             :   {
     144       84878 :     auto owned_ptr = iterator->second;
     145             :     mooseAssert(owned_ptr, "The field '" + iterator->first + "' is NULL.");
     146       84878 :     return owned_ptr;
     147             :   }
     148             : 
     149             :   /// Ensure that a dynamic cast is successful.
     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             : 
     158             :   /// Clear all associations between names and fields.
     159       24797 :   void DeregisterAll() { _field_map.clear(); }
     160             : 
     161             : private:
     162             :   MapType _field_map{};
     163             : };
     164             : 
     165             : /// Lightweight adaptor over a std::map relating names of GridFunctions with the name of their time
     166             : /// derivatives
     167             : class TimeDerivativeMap
     168             : {
     169             : public:
     170             :   using MapType = std::map<std::string, std::string>;
     171             :   using const_iterator = typename MapType::const_iterator;
     172             : 
     173         151 :   inline void addTimeDerivativeAssociation(const std::string & var_name,
     174             :                                            const std::string & time_derivative_var_name)
     175             :   {
     176         151 :     _field_map.emplace(var_name, time_derivative_var_name);
     177         151 :   }
     178             : 
     179         290 :   inline bool isTimeDerivative(const std::string & time_derivative_var_name) const
     180             :   {
     181         459 :     for (auto const & [map_var_name, map_time_derivative_var_name] : _field_map)
     182             :     {
     183         314 :       if (map_time_derivative_var_name == time_derivative_var_name)
     184         145 :         return true;
     185             :     }
     186         145 :     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        2271 :   inline const std::string & getTimeDerivativeName(const std::string & var_name) const
     195             :   {
     196        2271 :     auto it = _field_map.find(var_name);
     197        2271 :     if (it != _field_map.end())
     198        2271 :       return it->second;
     199             :     else
     200             :     {
     201           0 :       mooseError("No variable representing the time derivative of ", var_name, " found.");
     202             :       return null_str;
     203             :     }
     204             :   }
     205             : 
     206         145 :   inline const std::string & getTimeIntegralName(const std::string & time_derivative_var_name) const
     207             :   {
     208         157 :     for (auto const & [map_var_name, map_time_derivative_var_name] : _field_map)
     209             :     {
     210         157 :       if (map_time_derivative_var_name == time_derivative_var_name)
     211         145 :         return map_var_name;
     212             :     }
     213           0 :     mooseError(
     214             :         "No variable representing the time integral of ", time_derivative_var_name, " found.");
     215             :     return null_str;
     216             :   }
     217             : 
     218        3340 :   inline static std::string createTimeDerivativeName(std::string_view name)
     219             :   {
     220       20040 :     return std::string("d") + std::string(name) + std::string("_dt");
     221             :   }
     222             : 
     223             : private:
     224             :   MapType _field_map;
     225             :   const std::string null_str;
     226             : };
     227             : 
     228             : using FECollections = Moose::MFEM::NamedFieldsMap<mfem::FiniteElementCollection>;
     229             : using FESpaces = Moose::MFEM::NamedFieldsMap<mfem::ParFiniteElementSpace>;
     230             : using SubMeshes = Moose::MFEM::NamedFieldsMap<mfem::ParSubMesh>;
     231             : using GridFunctions = Moose::MFEM::NamedFieldsMap<mfem::ParGridFunction>;
     232             : using ComplexGridFunctions = Moose::MFEM::NamedFieldsMap<mfem::ParComplexGridFunction>;
     233             : 
     234             : } // namespace Moose::MFEM
     235             : 
     236             : #endif

Generated by: LCOV version 1.14