LCOV - code coverage report
Current view: top level - include/mfem/containers - MFEMContainers.h (source / functions) Hit Total Coverage
Test: idaholab/moose framework: 2bf808 Lines: 45 51 88.2 %
Date: 2025-07-17 01:28:37 Functions: 178 196 90.8 %
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 MFEM_ENABLED
      11             : 
      12             : #pragma once
      13             : #include <map>
      14             : #include <set>
      15             : #include <string>
      16             : #include <memory>
      17             : #include <vector>
      18             : #include "libmesh/ignore_warnings.h"
      19             : #include <mfem.hpp>
      20             : #include "libmesh/restore_warnings.h"
      21             : 
      22             : namespace Moose::MFEM
      23             : {
      24             : 
      25             : /// Lightweight adaptor over an std::map from strings to pointer to T
      26             : template <typename T>
      27             : class NamedFieldsMap
      28             : {
      29             : public:
      30             :   using MapType = std::map<std::string, std::shared_ptr<T>>;
      31             :   using const_iterator = typename MapType::const_iterator;
      32             : 
      33             :   /// Default initializer.
      34        2476 :   NamedFieldsMap() = default;
      35             : 
      36             :   /// Destructor.
      37        2476 :   ~NamedFieldsMap() { DeregisterAll(); }
      38             : 
      39             :   /// Construct new field with name field_name and register.
      40             :   template <class FieldType, class... FieldArgs>
      41             :   void Register(const std::string & field_name, FieldArgs &&... args)
      42             :   {
      43             :     Register(field_name, std::make_shared<FieldType>(std::forward<FieldArgs>(args)...));
      44             :   }
      45             : 
      46             :   /// Register association between field and field_name.
      47        1762 :   void Register(const std::string & field_name, std::shared_ptr<T> field)
      48             :   {
      49        1762 :     CheckFieldIsRegistrable(field_name, field.get());
      50             : 
      51        1762 :     Deregister(field_name);
      52             : 
      53        1762 :     _field_map[field_name] = std::move(field);
      54        1762 :   }
      55             : 
      56             :   /// Unregister association between a field and the field_name.
      57        1762 :   void Deregister(const std::string & field_name) { _field_map.erase(field_name); }
      58             : 
      59             :   /// Predicate to check if a field is registered with name field_name.
      60        9281 :   [[nodiscard]] inline bool Has(const std::string & field_name) const
      61             :   {
      62        9281 :     return FindField(field_name) != end();
      63             :   }
      64             : 
      65             :   /// Returns a shared pointer to the field. This is guaranteed to return a non-null shared pointer.
      66        5103 :   [[nodiscard]] inline std::shared_ptr<T> GetShared(const std::string & field_name) const
      67             :   {
      68        5103 :     CheckFieldIsRegistered(field_name);
      69             : 
      70        5103 :     auto it = FindField(field_name);
      71             : 
      72       10206 :     return EnsureFieldPointerIsNonNull(it);
      73             :   }
      74             : 
      75             :   /// Returns a reference to a field.
      76        1895 :   [[nodiscard]] inline T & GetRef(const std::string & field_name) const
      77             :   {
      78        1895 :     return *GetShared(field_name);
      79             :   }
      80             : 
      81             :   /// Returns a non-owning pointer to the field. This is guaranteed to return a non-null pointer.
      82        2674 :   [[nodiscard]] inline T * Get(const std::string & field_name) const
      83             :   {
      84        2674 :     return GetShared(field_name).get();
      85             :   }
      86             : 
      87             :   /// Returns a non-owning pointer to the field where TDerived is a derived class of class T.
      88             :   template <typename TDerived>
      89             :   [[nodiscard]] inline TDerived * Get(const std::string & field_name) const
      90             :   {
      91             :     auto ptr = Get(field_name);
      92             : 
      93             :     return EnsurePointerCastIsNonNull<TDerived>(ptr);
      94             :   }
      95             : 
      96             :   /// Returns a vector containing all values for supplied keys.
      97         292 :   [[nodiscard]] std::vector<T *> Get(const std::vector<std::string> & keys) const
      98             :   {
      99         292 :     std::vector<T *> values;
     100             : 
     101         442 :     for (const auto & key : keys)
     102             :     {
     103         150 :       values.push_back(Get(key));
     104             :     }
     105             : 
     106         292 :     values.shrink_to_fit();
     107         292 :     return values;
     108           0 :   }
     109             : 
     110             :   /// Returns a begin const iterator to the registered fields.
     111             :   // NOLINTNEXTLINE(readability-identifier-naming)
     112         140 :   [[nodiscard]] inline const_iterator begin() const { return _field_map.begin(); }
     113             : 
     114             :   /// Returns an end const iterator to the registered fields.
     115             :   // NOLINTNEXTLINE(readability-identifier-naming)
     116        9421 :   [[nodiscard]] inline const_iterator end() const { return _field_map.end(); }
     117             : 
     118             :   // Returns the number of elements in the map
     119             :   int size() { return _field_map.size(); }
     120             : 
     121             : protected:
     122             :   /// Returns a const iterator to the field.
     123       14384 :   [[nodiscard]] inline const_iterator FindField(const std::string & field_name) const
     124             :   {
     125       14384 :     return _field_map.find(field_name);
     126             :   }
     127             : 
     128             :   /// Check that the field pointer is valid and the field has not already been registered.
     129        1762 :   void CheckFieldIsRegistrable(const std::string & field_name, T * field) const
     130             :   {
     131        1762 :     if (!field)
     132             :     {
     133           0 :       MFEM_ABORT("Cannot register NULL field with name '" << field_name << "'.");
     134             :     }
     135             : 
     136        1762 :     CheckForDoubleRegistration(field_name, field);
     137        1762 :   }
     138             : 
     139             :   /// Check for double-registration of a field. A double-registered field may
     140             :   /// result in undefined behavior.
     141        1762 :   void CheckForDoubleRegistration(const std::string & field_name, T * field) const
     142             :   {
     143        1762 :     if (Has(field_name) && Get(field_name) == field)
     144             :     {
     145           0 :       MFEM_ABORT("The field '" << field_name << "' is already registered.");
     146             :     }
     147        1762 :   }
     148             : 
     149             :   /// Check that a field exists in the map.
     150        5103 :   void CheckFieldIsRegistered(const std::string & field_name) const
     151             :   {
     152        5103 :     if (!Has(field_name))
     153             :     {
     154           0 :       MFEM_ABORT("The field '" << field_name << "' has not been registered.");
     155             :     }
     156        5103 :   }
     157             : 
     158             :   /// Ensure that a returned shared pointer is valid.
     159        5103 :   inline std::shared_ptr<T> EnsureFieldPointerIsNonNull(const_iterator & iterator) const
     160             :   {
     161        5103 :     auto owned_ptr = iterator->second;
     162             : 
     163        5103 :     if (!owned_ptr)
     164             :     {
     165           0 :       MFEM_ABORT("The field '" << iterator->first << "' is NULL.");
     166             :     }
     167             : 
     168        5103 :     return owned_ptr;
     169           0 :   }
     170             : 
     171             :   /// Ensure that a dynamic cast is successful.
     172             :   template <typename TDerived>
     173             :   inline TDerived * EnsurePointerCastIsNonNull(T * ptr) const
     174             :   {
     175             :     auto derived_ptr = dynamic_cast<TDerived *>(ptr);
     176             : 
     177             :     if (!derived_ptr)
     178             :     {
     179             :       MFEM_ABORT("The dynamic cast performed on the field pointer failed.");
     180             :     }
     181             : 
     182             :     return derived_ptr;
     183             :   }
     184             : 
     185             :   /// Clear all associations between names and fields.
     186        2476 :   void DeregisterAll() { _field_map.clear(); }
     187             : 
     188             : private:
     189             :   MapType _field_map{};
     190             : };
     191             : 
     192             : inline std::string
     193         152 : GetTimeDerivativeName(std::string name)
     194             : {
     195         304 :   return std::string("d") + name + std::string("_dt");
     196             : }
     197             : 
     198             : using FECollections = Moose::MFEM::NamedFieldsMap<mfem::FiniteElementCollection>;
     199             : using FESpaces = Moose::MFEM::NamedFieldsMap<mfem::ParFiniteElementSpace>;
     200             : using GridFunctions = Moose::MFEM::NamedFieldsMap<mfem::ParGridFunction>;
     201             : using SubMeshes = Moose::MFEM::NamedFieldsMap<mfem::ParSubMesh>;
     202             : 
     203             : } // namespace Moose::MFEM
     204             : 
     205             : #endif

Generated by: LCOV version 1.14