LCOV - code coverage report
Current view: top level - include/materials - MaterialPropertyInterface.h (source / functions) Hit Total Coverage
Test: idaholab/moose framework: 7323e9 Lines: 167 179 93.3 %
Date: 2025-11-05 20:01:15 Functions: 220 296 74.3 %
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             : #pragma once
      11             : 
      12             : #ifdef MOOSE_KOKKOS_ENABLED
      13             : #include "KokkosMaterialPropertyStorage.h"
      14             : #endif
      15             : 
      16             : // MOOSE includes
      17             : #include "MaterialProperty.h"
      18             : #include "MooseTypes.h"
      19             : #include "MaterialData.h"
      20             : #include "MathUtils.h"
      21             : #include "MooseObjectName.h"
      22             : #include "InputParameters.h"
      23             : 
      24             : #include <unordered_map>
      25             : 
      26             : #define usingMaterialPropertyInterfaceMembers                                                      \
      27             :   using MaterialPropertyInterface::_material_data_type;                                            \
      28             :   using MaterialPropertyInterface::_material_data
      29             : 
      30             : // Forward declarations
      31             : class MooseObject;
      32             : class FEProblemBase;
      33             : class SubProblem;
      34             : 
      35             : /**
      36             :  * Helper class for deferred getting of material properties after the construction
      37             :  * phase for materials. This enables "optional material properties" in materials.
      38             :  * It works by returning a reference to a pointer to a material property (rather
      39             :  * than a reference to the property value). The pointer will be set to point to
      40             :  * either an existing material property or to nullptr if the requested property
      41             :  * does not exist.
      42             :  */
      43             : template <class M>
      44             : class OptionalMaterialPropertyProxyBase
      45             : {
      46             : public:
      47        1728 :   OptionalMaterialPropertyProxyBase(const std::string & name, const unsigned int state)
      48        1728 :     : _name(name), _state(state)
      49             :   {
      50        1728 :   }
      51        1428 :   virtual ~OptionalMaterialPropertyProxyBase() {}
      52             :   virtual void resolve(M & material) = 0;
      53             : 
      54             : protected:
      55             :   const std::string _name;
      56             :   const unsigned int _state;
      57             : };
      58             : 
      59             : /**
      60             :  * \class MaterialPropertyInterface
      61             :  * \brief An interface for accessing Materials
      62             :  *
      63             :  * Any object that needs material properties should inherit this interface.
      64             :  * If your object is also restricted to blocks and/or boundaries via the
      65             :  * BlockRestrictable and/or BoundaryRestrictable class, then MaterialPropertyInterface
      66             :  * must be inherited following these two classes for the material property checks
      67             :  * to operate correctly.
      68             :  */
      69             : class MaterialPropertyInterface
      70             : {
      71             : public:
      72             :   MaterialPropertyInterface(const MooseObject * moose_object,
      73             :                             const std::set<SubdomainID> & block_ids,
      74             :                             const std::set<BoundaryID> & boundary_ids);
      75             : 
      76             : #ifdef MOOSE_KOKKOS_ENABLED
      77             :   /**
      78             :    * Special constructor used for Kokkos functor copy during parallel dispatch
      79             :    */
      80             :   MaterialPropertyInterface(const MaterialPropertyInterface & object,
      81             :                             const Moose::Kokkos::FunctorCopy & key);
      82             : #endif
      83             : 
      84             :   static InputParameters validParams();
      85             : 
      86             :   /// The material property ID for a default (parsed from input) property
      87             :   static constexpr PropertyValue::id_type default_property_id =
      88             :       PropertyValue::invalid_property_id - 1;
      89             :   /// The material property ID for a zero property
      90             :   static constexpr PropertyValue::id_type zero_property_id = PropertyValue::invalid_property_id - 2;
      91             : 
      92             :   ///@{
      93             :   /**
      94             :    * Retrieve reference to material property or one of it's old or older values.
      95             :    * The name required by this method is the name that is hard-coded into
      96             :    * your source code as the input parameter key. If no input parameter is found
      97             :    * this behaves like the getMaterialPropertyByName family as a fall back.
      98             :    * @param name The name of the parameter key of the material property to retrieve
      99             :    * @param state The state (current = 0, old = 1, older = 2)
     100             :    * @return Reference to the desired material property
     101             :    */
     102             :   template <typename T, bool is_ad>
     103       50071 :   const GenericMaterialProperty<T, is_ad> & getGenericMaterialProperty(const std::string & name,
     104             :                                                                        const unsigned int state = 0)
     105             :   {
     106       50071 :     return getGenericMaterialProperty<T, is_ad>(name, _material_data, state);
     107             :   }
     108             :   template <typename T>
     109        6226 :   const MaterialProperty<T> & getMaterialProperty(const std::string & name,
     110             :                                                   const unsigned int state = 0)
     111             :   {
     112        6226 :     return getGenericMaterialProperty<T, false>(name, state);
     113             :   }
     114             :   template <typename T>
     115        3366 :   const ADMaterialProperty<T> & getADMaterialProperty(const std::string & name)
     116             :   {
     117        3366 :     return getGenericMaterialProperty<T, true>(name, 0);
     118             :   }
     119             :   template <typename T>
     120         114 :   const MaterialProperty<T> & getMaterialPropertyOld(const std::string & name)
     121             :   {
     122         114 :     return getMaterialProperty<T>(name, 1);
     123             :   }
     124             :   template <typename T>
     125          32 :   const MaterialProperty<T> & getMaterialPropertyOlder(const std::string & name)
     126             :   {
     127          32 :     return getMaterialProperty<T>(name, 2);
     128             :   }
     129             :   ///@}
     130             : 
     131             :   ///@{
     132             :   /**
     133             :    * Retrieve reference to material property or its old or older value
     134             :    * The name required by this method is the name defined in the input file.
     135             :    * @param name The name of the material property to retrieve
     136             :    * @param state The state (current = 0, old = 1, older = 2)
     137             :    * @return Reference to the material property with the name 'name'
     138             :    */
     139             :   template <typename T, bool is_ad>
     140             :   const GenericMaterialProperty<T, is_ad> &
     141        9826 :   getGenericMaterialPropertyByName(const MaterialPropertyName & name, const unsigned int state = 0)
     142             :   {
     143        9826 :     return getGenericMaterialPropertyByName<T, is_ad>(name, _material_data, state);
     144             :   }
     145             :   template <typename T>
     146         217 :   const MaterialProperty<T> & getMaterialPropertyByName(const MaterialPropertyName & name,
     147             :                                                         const unsigned int state = 0)
     148             :   {
     149         217 :     return getGenericMaterialPropertyByName<T, false>(name, state);
     150             :   }
     151             :   template <typename T>
     152          16 :   const ADMaterialProperty<T> & getADMaterialPropertyByName(const MaterialPropertyName & name)
     153             :   {
     154          16 :     return getGenericMaterialPropertyByName<T, true>(name, 0);
     155             :   }
     156             :   template <typename T>
     157             :   const MaterialProperty<T> & getMaterialPropertyOldByName(const MaterialPropertyName & name)
     158             :   {
     159             :     return getMaterialPropertyByName<T>(name, 1);
     160             :   }
     161             :   template <typename T>
     162             :   const MaterialProperty<T> & getMaterialPropertyOlderByName(const MaterialPropertyName & name)
     163             :   {
     164             :     return getMaterialPropertyByName<T>(name, 2);
     165             :   }
     166             :   ///@}
     167             : 
     168             : #ifdef MOOSE_KOKKOS_SCOPE
     169             :   /**
     170             :    * Get a Kokkos material property by property name for any state
     171             :    * @tparam T The property data type
     172             :    * @tparam dimension The property dimension
     173             :    * @tparam state The property state
     174             :    * @param prop_name_in The property name
     175             :    * @returns The Kokkos material property
     176             :    */
     177             :   template <typename T, unsigned int dimension = 0, unsigned int state = 0>
     178             :   Moose::Kokkos::MaterialProperty<T, dimension>
     179             :   getKokkosMaterialPropertyByName(const std::string & prop_name_in);
     180             :   /**
     181             :    * Get an old Kokkos material property by property name
     182             :    * @tparam T The property data type
     183             :    * @tparam dimension The property dimension
     184             :    * @param prop_name The property name
     185             :    * @returns The Kokkos material property
     186             :    */
     187             :   template <typename T, unsigned int dimension = 0>
     188             :   Moose::Kokkos::MaterialProperty<T, dimension>
     189             :   getKokkosMaterialPropertyOldByName(const std::string & prop_name)
     190             :   {
     191             :     return getKokkosMaterialPropertyByName<T, dimension, 1>(prop_name);
     192             :   }
     193             :   /**
     194             :    * Get an older Kokkos material property by property name
     195             :    * @tparam T The property data type
     196             :    * @tparam dimension The property dimension
     197             :    * @param prop_name The property name
     198             :    * @returns The Kokkos material property
     199             :    */
     200             :   template <typename T, unsigned int dimension = 0>
     201             :   Moose::Kokkos::MaterialProperty<T, dimension>
     202             :   getKokkosMaterialPropertyOlderByName(const std::string & prop_name)
     203             :   {
     204             :     return getKokkosMaterialPropertyByName<T, dimension, 2>(prop_name);
     205             :   }
     206             :   /**
     207             :    * Get a Kokkos material property for any state
     208             :    * @tparam T The property data type
     209             :    * @tparam dimension The property dimension
     210             :    * @tparam state The property state
     211             :    * @param name The property name or the parameter name containing the property name
     212             :    * @returns The Kokkos material property
     213             :    */
     214             :   template <typename T, unsigned int dimension = 0, unsigned int state = 0>
     215         445 :   Moose::Kokkos::MaterialProperty<T, dimension> getKokkosMaterialProperty(const std::string & name)
     216             :   {
     217         445 :     return getKokkosMaterialPropertyByName<T, dimension, state>(getMaterialPropertyName(name));
     218             :   }
     219             :   /**
     220             :    * Get an old Kokkos material property
     221             :    * @tparam T The property data type
     222             :    * @tparam dimension The property dimension
     223             :    * @param name The property name or the parameter name containing the property name
     224             :    * @returns The Kokkos material property
     225             :    */
     226             :   template <typename T, unsigned int dimension = 0>
     227             :   Moose::Kokkos::MaterialProperty<T, dimension>
     228         556 :   getKokkosMaterialPropertyOld(const std::string & name)
     229             :   {
     230         556 :     return getKokkosMaterialPropertyByName<T, dimension, 1>(getMaterialPropertyName(name));
     231             :   }
     232             :   /**
     233             :    * Get an older Kokkos material property
     234             :    * @tparam T The property data type
     235             :    * @tparam dimension The property dimension
     236             :    * @param name The property name or the parameter name containing the property name
     237             :    * @returns The Kokkos material property
     238             :    */
     239             :   template <typename T, unsigned int dimension = 0>
     240             :   Moose::Kokkos::MaterialProperty<T, dimension>
     241         216 :   getKokkosMaterialPropertyOlder(const std::string & name)
     242             :   {
     243         216 :     return getKokkosMaterialPropertyByName<T, dimension, 2>(getMaterialPropertyName(name));
     244             :   }
     245             : #endif
     246             : 
     247             :   ///@{ Optional material property getters
     248             :   /// \p state is the property state; 0 = current, 1 = old, 2 = older, etc.
     249             :   template <typename T, bool is_ad>
     250             :   const GenericOptionalMaterialProperty<T, is_ad> &
     251             :   getGenericOptionalMaterialProperty(const std::string & name, const unsigned int state = 0);
     252             : 
     253             :   template <typename T>
     254          56 :   const OptionalMaterialProperty<T> & getOptionalMaterialProperty(const std::string & name,
     255             :                                                                   const unsigned int state = 0)
     256             :   {
     257          56 :     return getGenericOptionalMaterialProperty<T, false>(name, state);
     258             :   }
     259             :   template <typename T>
     260          28 :   const OptionalADMaterialProperty<T> & getOptionalADMaterialProperty(const std::string & name)
     261             :   {
     262          28 :     return getGenericOptionalMaterialProperty<T, true>(name);
     263             :   }
     264             : 
     265             :   template <typename T>
     266          14 :   const OptionalMaterialProperty<T> & getOptionalMaterialPropertyOld(const std::string & name)
     267             :   {
     268          14 :     return getOptionalMaterialProperty<T>(name, 1);
     269             :   }
     270             :   template <typename T>
     271          14 :   const OptionalMaterialProperty<T> & getOptionalMaterialPropertyOlder(const std::string & name)
     272             :   {
     273          14 :     return getOptionalMaterialProperty<T>(name, 2);
     274             :   }
     275             :   ///@}
     276             : 
     277             :   /**
     278             :    * Retrieve pointer to a material property with the mesh blocks where it is defined
     279             :    * The name required by this method is the name defined in the input file.
     280             :    * This function can be thought as the combination of getMaterialPropertyByName and
     281             :    * getMaterialPropertyBlocks.
     282             :    * It can be called after the action of all actions.
     283             :    * @param name The name of the material property to retrieve
     284             :    * @return Pointer to the material property with the name 'name' and the set of blocks where the
     285             :    * property is valid
     286             :    */
     287             :   template <typename T>
     288             :   std::pair<const MaterialProperty<T> *, std::set<SubdomainID>>
     289             :   getBlockMaterialProperty(const MaterialPropertyName & name);
     290             : 
     291             :   /**
     292             :    * Return a material property that is initialized to zero by default and does
     293             :    * not need to (but can) be declared by another material.
     294             :    */
     295             :   template <typename T, bool is_ad>
     296             :   const GenericMaterialProperty<T, is_ad> &
     297             :   getGenericZeroMaterialProperty(const std::string & name);
     298             :   template <typename T, bool is_ad>
     299             :   const GenericMaterialProperty<T, is_ad> &
     300             :   getGenericZeroMaterialPropertyByName(const std::string & prop_name);
     301             : 
     302             :   /**
     303             :    * Return a constant zero anonymous material property
     304             :    */
     305             :   template <typename T, bool is_ad>
     306             :   const GenericMaterialProperty<T, is_ad> & getGenericZeroMaterialProperty();
     307             : 
     308             :   /// for backwards compatibility
     309             :   template <typename T, typename... Ts>
     310             :   const MaterialProperty<T> & getZeroMaterialProperty(Ts... args)
     311             :   {
     312             :     return getGenericZeroMaterialProperty<T, false>(args...);
     313             :   }
     314             : 
     315             :   /**
     316             :    * Retrieve the block ids that the material property is defined
     317             :    * @param name The name of the material property
     318             :    * @return A vector the the block ids for the property
     319             :    */
     320             :   std::set<SubdomainID> getMaterialPropertyBlocks(const std::string & name);
     321             : 
     322             :   /**
     323             :    * Retrieve the block names that the material property is defined
     324             :    * @param name The name of the material property
     325             :    * @return A vector the the block names for the property
     326             :    */
     327             :   std::vector<SubdomainName> getMaterialPropertyBlockNames(const std::string & name);
     328             : 
     329             :   /**
     330             :    * Retrieve the boundary ids that the material property is defined
     331             :    * @param name The name of the material property
     332             :    * @return A vector the the boundary ids for the property
     333             :    */
     334             :   std::set<BoundaryID> getMaterialPropertyBoundaryIDs(const std::string & name);
     335             : 
     336             :   /**
     337             :    * Retrieve the boundary namess that the material property is defined
     338             :    * @param name The name of the material property
     339             :    * @return A vector the the boundary names for the property
     340             :    */
     341             :   std::vector<BoundaryName> getMaterialPropertyBoundaryNames(const std::string & name);
     342             : 
     343             :   /**
     344             :    * Check if block and boundary restrictions of a given material are compatible with the current
     345             :    * material. Error out otherwise.
     346             :    */
     347             :   void checkBlockAndBoundaryCompatibility(std::shared_ptr<MaterialBase> discrete);
     348             : 
     349             :   ///@{
     350             :   /**
     351             :    * Return a MaterialBase reference - usable for computing directly.
     352             :    *
     353             :    * @param name The name of the input parameter or explicit material name.
     354             :    * @param no_warn If true, suppress warning about retrieving the material
     355             :    * potentially during its calculation. If you don't know what this is/means,
     356             :    * then you don't need it.
     357             :    */
     358             :   MaterialBase & getMaterial(const std::string & name);
     359             :   MaterialBase & getMaterialByName(const std::string & name, bool no_warn = false);
     360             :   ///@}
     361             : 
     362             :   /// get a map of MaterialBase pointers for all material objects that this object depends on for each block
     363             :   std::unordered_map<SubdomainID, std::vector<MaterialBase *>>
     364             :   buildRequiredMaterials(bool allow_stateful = true);
     365             : 
     366             :   ///@{
     367             :   /**
     368             :    * Check if the material property exists
     369             :    * @param name the name of the property to query
     370             :    * @return true if the property exists, otherwise false
     371             :    */
     372             :   template <typename T>
     373             :   bool hasMaterialProperty(const std::string & name);
     374             :   template <typename T>
     375             :   bool hasMaterialPropertyByName(const std::string & name);
     376             :   template <typename T>
     377             :   bool hasADMaterialProperty(const std::string & name);
     378             :   template <typename T>
     379             :   bool hasADMaterialPropertyByName(const std::string & name);
     380             : #ifdef MOOSE_KOKKOS_SCOPE
     381             :   template <typename T, unsigned int dimension = 0>
     382             :   bool hasKokkosMaterialProperty(const std::string & name);
     383             :   template <typename T, unsigned int dimension = 0>
     384             :   bool hasKokkosMaterialPropertyByName(const std::string & name);
     385             : #endif
     386             :   ///@}
     387             : 
     388             :   ///@{ generic hasMaterialProperty helper
     389             :   template <typename T, bool is_ad>
     390        5003 :   bool hasGenericMaterialProperty(const std::string & name)
     391             :   {
     392             :     if constexpr (is_ad)
     393         214 :       return hasADMaterialProperty<T>(name);
     394             :     else
     395        4789 :       return hasMaterialProperty<T>(name);
     396             :   }
     397             :   template <typename T, bool is_ad>
     398        1773 :   bool hasGenericMaterialPropertyByName(const std::string & name)
     399             :   {
     400             :     if constexpr (is_ad)
     401          56 :       return hasADMaterialPropertyByName<T>(name);
     402             :     else
     403        1717 :       return hasMaterialPropertyByName<T>(name);
     404             :   }
     405             :   ///@}
     406             : 
     407             :   /**
     408             :    * Derived classes can declare whether or not they work with
     409             :    * stateful material properties.  See, for example, DiracKernel.  By
     410             :    * default, they are allowed.
     411             :    */
     412             :   void statefulPropertiesAllowed(bool);
     413             : 
     414             :   /**
     415             :    * Returns true if getMaterialProperty() has been called, false otherwise.
     416             :    */
     417      368275 :   virtual bool getMaterialPropertyCalled() const { return _get_material_property_called; }
     418             : 
     419             :   /**
     420             :    * Retrieve the set of material properties that _this_ object depends on.
     421             :    *
     422             :    * @return The IDs corresponding to the material properties that
     423             :    * MUST be reinited before evaluating this object
     424             :    */
     425    16242474 :   virtual const std::unordered_set<unsigned int> & getMatPropDependencies() const
     426             :   {
     427    16242474 :     return _material_property_dependencies;
     428             :   }
     429             : 
     430             :   /// resolve all optional properties
     431             :   virtual void resolveOptionalProperties();
     432             : 
     433             :   /**
     434             :    * Retrieve the generic property named "name" for the specified \p material_data at state \p state
     435             :    */
     436             :   template <typename T, bool is_ad>
     437             :   const GenericMaterialProperty<T, is_ad> & getGenericMaterialProperty(
     438             :       const std::string & name, MaterialData & material_data, const unsigned int state = 0);
     439             : 
     440             :   /**
     441             :    * Retrieve the property named "name" for the specified \p material_data
     442             :    *
     443             :    * \p state is the property state; 0 = current, 1 = old, 2 = older, etc.
     444             :    */
     445             :   template <typename T>
     446          42 :   const MaterialProperty<T> & getMaterialProperty(const std::string & name,
     447             :                                                   MaterialData & material_data,
     448             :                                                   const unsigned int state = 0)
     449             :   {
     450          42 :     return getGenericMaterialProperty<T, false>(name, material_data, state);
     451             :   }
     452             : 
     453             :   /**
     454             :    * Retrieve the AD property named "name" for the specified \p material_data
     455             :    *
     456             :    * \p state is the property state; 0 = current, 1 = old, 2 = older, etc.
     457             :    */
     458             :   template <typename T>
     459        1474 :   const ADMaterialProperty<T> & getADMaterialProperty(const std::string & name,
     460             :                                                       MaterialData & material_data)
     461             :   {
     462        1474 :     return getGenericMaterialProperty<T, true>(name, material_data, 0);
     463             :   }
     464             : 
     465             :   /**
     466             :    * Retrieve the generic property named "name" without any deduction for the specified \p
     467             :    * material_data for state \p state
     468             :    */
     469             :   template <typename T, bool is_ad>
     470             :   const GenericMaterialProperty<T, is_ad> & getGenericMaterialPropertyByName(
     471             :       const MaterialPropertyName & name, MaterialData & material_data, const unsigned int state);
     472             : 
     473             :   /**
     474             :    * Retrieve the generic property named "prop_name" without any deduction for the specified \p
     475             :    * material_data for state \p state. This API allows the \p prop_name to be a constant, e.g. it
     476             :    * allows the possibility that \p prop_name is not a name at all
     477             :    */
     478             :   template <typename T, bool is_ad>
     479             :   const GenericMaterialProperty<T, is_ad> &
     480             :   getPossiblyConstantGenericMaterialPropertyByName(const MaterialPropertyName & prop_name,
     481             :                                                    MaterialData & material_data,
     482             :                                                    const unsigned int state);
     483             : 
     484             :   /**
     485             :    * Retrieve the property named "name" without any deduction for the specified \p material_data
     486             :    *
     487             :    * \p state is the property state; 0 = current, 1 = old, 2 = older, etc.
     488             :    */
     489             :   template <typename T>
     490          14 :   const MaterialProperty<T> & getMaterialPropertyByName(const MaterialPropertyName & name,
     491             :                                                         MaterialData & material_data,
     492             :                                                         const unsigned int state = 0)
     493             :   {
     494          14 :     return getGenericMaterialPropertyByName<T, false>(name, material_data, state);
     495             :   }
     496             : 
     497             :   /**
     498             :    * Retrieve the AD property named "name" without any deduction for the specified \q
     499             :    * material_data
     500             :    */
     501             :   template <typename T>
     502             :   const ADMaterialProperty<T> & getADMaterialPropertyByName(const MaterialPropertyName & name,
     503             :                                                             MaterialData & material_data)
     504             :   {
     505             :     return getGenericMaterialPropertyByName<T, true>(name, material_data, 0);
     506             :   }
     507             : 
     508             :   /**
     509             :    * Retrieve the old property deduced from the name \p name for the specified \p material_data
     510             :    */
     511             :   template <typename T>
     512          14 :   const MaterialProperty<T> & getMaterialPropertyOld(const std::string & name,
     513             :                                                      MaterialData & material_data)
     514             :   {
     515          14 :     return getMaterialProperty<T>(name, material_data, 1);
     516             :   }
     517             : 
     518             :   /**
     519             :    * Retrieve the older property deduced from the name \p name for the specified \p
     520             :    * material_data
     521             :    */
     522             :   template <typename T>
     523          14 :   const MaterialProperty<T> & getMaterialPropertyOlder(const std::string & name,
     524             :                                                        MaterialData & material_data)
     525             :   {
     526          14 :     return getMaterialProperty<T>(name, material_data, 2);
     527             :   }
     528             : 
     529             :   /**
     530             :    * Retrieve the old property named \p name without any deduction for the specified \p
     531             :    * material_data
     532             :    */
     533             :   template <typename T>
     534             :   const MaterialProperty<T> & getMaterialPropertyOldByName(const MaterialPropertyName & name,
     535             :                                                            MaterialData & material_data)
     536             :   {
     537             :     return getMaterialPropertyByName<T>(name, material_data, 1);
     538             :   }
     539             : 
     540             :   /**
     541             :    * Retrieve the older property named \p name without any deduction for the specified \p
     542             :    * material_data
     543             :    */
     544             :   template <typename T>
     545             :   const MaterialProperty<T> & getMaterialPropertyOlderByName(const MaterialPropertyName & name,
     546             :                                                              MaterialData & material_data)
     547             :   {
     548             :     return getMaterialPropertyByName<T>(name, material_data, 2);
     549             :   }
     550             : 
     551             : private:
     552             :   /// The MooseObject creating the MaterialPropertyInterface
     553             :   const MooseObject & _mi_moose_object;
     554             : 
     555             : protected:
     556             :   /// Parameters of the object with this interface
     557             :   const InputParameters & _mi_params;
     558             : 
     559             :   /// The name of the object that this interface belongs to
     560             :   const std::string _mi_name;
     561             : 
     562             :   /// The "complete" name of the object that this interface belongs for material property output
     563             :   const MooseObjectName _mi_moose_object_name;
     564             : 
     565             :   /// Reference to the FEProblemBase class
     566             :   FEProblemBase & _mi_feproblem;
     567             : 
     568             :   /// Reference to the subproblem
     569             :   SubProblem & _mi_subproblem;
     570             : 
     571             :   /// Current threaded it
     572             :   const THREAD_ID _mi_tid;
     573             : 
     574             :   /// Whether the MOOSE object is a Kokkos object
     575             :   const bool _is_kokkos_object;
     576             : 
     577             :   /// The type of data
     578             :   const Moose::MaterialDataType _material_data_type;
     579             : 
     580             :   /// The material data class that stores properties
     581             :   MaterialData & _material_data;
     582             : 
     583             :   /**
     584             :    * A helper method for checking material properties
     585             :    * This method was required to avoid a compiler problem with the template
     586             :    * getMaterialProperty method
     587             :    */
     588             :   virtual void checkMaterialProperty(const std::string & name, const unsigned int state);
     589             : 
     590             : #ifdef MOOSE_KOKKOS_ENABLED
     591             :   /**
     592             :    * A virtual method that can be overriden by Kokkos objects to insert additional operations in
     593             :    * getKokkosMaterialProperty
     594             :    * @param prop_name_in The property name
     595             :    * @param state The property state
     596             :    */
     597         258 :   virtual void getKokkosMaterialPropertyHook(const std::string & /* prop_name_in */,
     598             :                                              const unsigned int /* state */)
     599             :   {
     600         258 :   }
     601             : #endif
     602             : 
     603             :   /**
     604             :    * A proxy method for _mi_feproblem.markMatPropRequested(name)
     605             :    */
     606             :   void markMatPropRequested(const std::string &);
     607             : 
     608             :   /**
     609             :    * @return The name of the material property associated with name \p name.
     610             :    *
     611             :    * If \p name is the name of a material property parameter and the parameter is
     612             :    * valid, this will return the value of said parameter. Otherwise, it will just
     613             :    * return the name.
     614             :    */
     615             :   MaterialPropertyName getMaterialPropertyName(const std::string & name) const;
     616             : 
     617             :   /**
     618             :    * @return The default material property with the name \p name, if any.
     619             :    *
     620             :    * "Default" properties are properties whose default values are set from within
     621             :    * the name. That is, if we can cast \p name to a Real, _and_ the prop type is
     622             :    * a Real or RealVectorValue, we'll return said value.
     623             :    */
     624             :   ///@{
     625             :   template <typename T, bool is_ad>
     626             :   const GenericMaterialProperty<T, is_ad> *
     627             :   defaultGenericMaterialProperty(const std::string & name);
     628             :   template <typename T>
     629          53 :   const MaterialProperty<T> * defaultMaterialProperty(const std::string & name)
     630             :   {
     631          53 :     return defaultGenericMaterialProperty<T, false>(name);
     632             :   }
     633             :   template <typename T>
     634          53 :   const ADMaterialProperty<T> * defaultADMaterialProperty(const std::string & name)
     635             :   {
     636          53 :     return defaultGenericMaterialProperty<T, true>(name);
     637             :   }
     638             :   ///@}
     639             : 
     640             :   /**
     641             :    * Check and throw an error if the execution has progressed past the construction stage
     642             :    */
     643             :   void checkExecutionStage();
     644             : 
     645             :   /**
     646             :    * True by default. If false, this class throws an error if any of
     647             :    * the stateful material properties interfaces are used.
     648             :    */
     649             :   bool _stateful_allowed;
     650             : 
     651             :   /**
     652             :    * Initialized to false.  Gets set to true when getMaterialProperty()
     653             :    * is called.  Clients of this class can inquire whether getMaterialProperty()
     654             :    * has been called by calling getMaterialPropertyCalled().
     655             :    */
     656             :   bool _get_material_property_called;
     657             : 
     658             :   /// Storage vector for default properties
     659             :   std::vector<std::unique_ptr<PropertyValue>> _default_properties;
     660             : 
     661             :   /// The set of material properties (as given by their IDs) that _this_ object depends on
     662             :   std::unordered_set<unsigned int> _material_property_dependencies;
     663             : 
     664             :   const MaterialPropertyName _get_suffix;
     665             : 
     666             :   /// Use the interpolated state set up through the ProjectedStatefulMaterialStorageAction
     667             :   const bool _use_interpolated_state;
     668             : 
     669             :   ///@{ name suffixes for interpolated old and older properties
     670             :   static const std::string _interpolated_old;
     671             :   static const std::string _interpolated_older;
     672             :   ///@}
     673             : 
     674             : private:
     675             :   /**
     676             :    * @returns The MaterialDataType given the interface's parameters
     677             :    */
     678             :   Moose::MaterialDataType getMaterialDataType(const std::set<BoundaryID> & boundary_ids) const;
     679             : 
     680             :   /*
     681             :    * A proxy method for _mi_feproblem.getMaxQps()
     682             :    */
     683             :   unsigned int getMaxQps() const;
     684             : 
     685             :   /*
     686             :    * A proxy method for _mi_feproblem.addConsumedPropertyName()
     687             :    */
     688             :   void addConsumedPropertyName(const MooseObjectName & obj_name, const std::string & prop_name);
     689             : 
     690             :   /// BoundaryRestricted flag
     691             :   const bool _mi_boundary_restricted;
     692             : 
     693             :   /// Storage for the block ids created by BlockRestrictable
     694             :   const std::set<SubdomainID> & _mi_block_ids;
     695             : 
     696             :   /// Storage for the boundary ids created by BoundaryRestrictable
     697             :   const std::set<BoundaryID> & _mi_boundary_ids;
     698             : 
     699             :   /// optional material properties
     700             :   std::vector<std::unique_ptr<OptionalMaterialPropertyProxyBase<MaterialPropertyInterface>>>
     701             :       _optional_property_proxies;
     702             : };
     703             : 
     704             : template <class M, typename T, bool is_ad>
     705             : class OptionalMaterialPropertyProxy : public OptionalMaterialPropertyProxyBase<M>
     706             : {
     707             : public:
     708        1728 :   OptionalMaterialPropertyProxy(const std::string & name, const unsigned int state)
     709        1728 :     : OptionalMaterialPropertyProxyBase<M>(name, state)
     710             :   {
     711        1728 :   }
     712        1728 :   const GenericOptionalMaterialProperty<T, is_ad> & value() const { return _value; }
     713        1728 :   void resolve(M & mpi) override
     714             :   {
     715        1728 :     if (mpi.template hasGenericMaterialProperty<T, is_ad>(this->_name))
     716             :     {
     717             :       if constexpr (is_ad)
     718         157 :         if (this->_state > 0)
     719           0 :           mooseError("Non-current (state > 0) material properties are not available as AD");
     720             : 
     721         750 :       _value.set(&mpi.template getGenericMaterialProperty<T, is_ad>(this->_name, this->_state));
     722             :     }
     723        1728 :   }
     724             : 
     725             : private:
     726             :   GenericOptionalMaterialProperty<T, is_ad> _value;
     727             : };
     728             : 
     729             : template <typename T, bool is_ad>
     730             : const GenericMaterialProperty<T, is_ad> *
     731       69724 : MaterialPropertyInterface::defaultGenericMaterialProperty(const std::string & name)
     732             : {
     733             :   if constexpr (std::is_same_v<T, Real> || std::is_same_v<T, RealVectorValue>)
     734             :   {
     735       38729 :     std::istringstream ss(name);
     736             :     Real real_value;
     737             : 
     738             :     // check if the string parsed cleanly into a Real number
     739       38729 :     if (ss >> real_value && ss.eof())
     740             :     {
     741             :       using prop_type = GenericMaterialProperty<T, is_ad>;
     742             : 
     743        9245 :       const auto nqp = Moose::constMaxQpsPerElem;
     744             :       auto & property =
     745        9245 :           _default_properties.emplace_back(std::make_unique<prop_type>(default_property_id));
     746        9245 :       auto & T_property = static_cast<prop_type &>(*property);
     747             : 
     748        9245 :       T_property.resize(nqp);
     749     9254245 :       for (const auto qp : make_range(nqp))
     750     9245000 :         T_property[qp] = real_value;
     751             : 
     752        9245 :       return &T_property;
     753             :     }
     754       38729 :   }
     755             : 
     756       60479 :   return nullptr;
     757             : }
     758             : 
     759             : template <typename T>
     760             : std::pair<const MaterialProperty<T> *, std::set<SubdomainID>>
     761             : MaterialPropertyInterface::getBlockMaterialProperty(const MaterialPropertyName & name_in)
     762             : {
     763             :   const auto name = _get_suffix.empty()
     764             :                         ? static_cast<const std::string &>(name_in)
     765             :                         : MooseUtils::join(std::vector<std::string>({name_in, _get_suffix}), "_");
     766             : 
     767             :   if (_mi_block_ids.empty())
     768             :     mooseError("getBlockMaterialProperty must be called by a block restrictable object");
     769             : 
     770             :   using pair_type = std::pair<const MaterialProperty<T> *, std::set<SubdomainID>>;
     771             : 
     772             :   if (!hasMaterialPropertyByName<T>(name))
     773             :     return pair_type(nullptr, {});
     774             : 
     775             :   // Call first so that the ID gets registered
     776             :   const auto & prop = _material_data.getProperty<T, false>(name, 0, _mi_moose_object);
     777             :   auto blocks = getMaterialPropertyBlocks(name);
     778             :   auto prop_blocks_pair = pair_type(&prop, std::move(blocks));
     779             : 
     780             :   _material_property_dependencies.insert(_material_data.getPropertyId(name));
     781             : 
     782             :   // Update consumed properties in MaterialPropertyDebugOutput
     783             :   addConsumedPropertyName(_mi_moose_object_name, name);
     784             : 
     785             :   return prop_blocks_pair;
     786             : }
     787             : 
     788             : template <typename T>
     789             : bool
     790       11457 : MaterialPropertyInterface::hasMaterialProperty(const std::string & name)
     791             : {
     792             :   // Check if the supplied parameter is a valid input parameter key
     793       11457 :   const auto prop_name = getMaterialPropertyName(name);
     794       22914 :   return hasMaterialPropertyByName<T>(prop_name);
     795       11457 : }
     796             : 
     797             : template <typename T>
     798             : bool
     799       13174 : MaterialPropertyInterface::hasMaterialPropertyByName(const std::string & name_in)
     800             : {
     801       39522 :   const auto name = _get_suffix.empty()
     802       13174 :                         ? name_in
     803       13174 :                         : MooseUtils::join(std::vector<std::string>({name_in, _get_suffix}), "_");
     804       26348 :   return _material_data.haveProperty<T>(name);
     805       13174 : }
     806             : 
     807             : template <typename T, bool is_ad>
     808             : const GenericMaterialProperty<T, is_ad> &
     809           0 : MaterialPropertyInterface::getGenericZeroMaterialProperty(const std::string & name)
     810             : {
     811           0 :   const auto prop_name = getMaterialPropertyName(name);
     812           0 :   return getGenericZeroMaterialPropertyByName<T, is_ad>(prop_name);
     813           0 : }
     814             : 
     815             : template <typename T, bool is_ad>
     816             : const GenericMaterialProperty<T, is_ad> &
     817        1773 : MaterialPropertyInterface::getGenericZeroMaterialPropertyByName(const std::string & prop_name)
     818             : {
     819             :   // if found return the requested property
     820        1773 :   if (hasGenericMaterialPropertyByName<T, is_ad>(prop_name))
     821         244 :     return getGenericMaterialPropertyByName<T, is_ad>(prop_name);
     822             : 
     823        1529 :   return getGenericZeroMaterialProperty<T, is_ad>();
     824             : }
     825             : 
     826             : template <typename T, bool is_ad>
     827             : const GenericMaterialProperty<T, is_ad> &
     828        2077 : MaterialPropertyInterface::getGenericZeroMaterialProperty()
     829             : {
     830             :   // static zero property storage
     831        2077 :   static GenericMaterialProperty<T, is_ad> zero(zero_property_id);
     832             : 
     833             :   // resize to accomodate maximum number of qpoints
     834             :   // (in multiapp scenarios getMaxQps can return different values in each app; we need the max)
     835        2077 :   unsigned int nqp = getMaxQps();
     836        2077 :   if (nqp > zero.size())
     837        1308 :     zero.resize(nqp);
     838             : 
     839             :   // set values for all qpoints to zero
     840       13410 :   for (unsigned int qp = 0; qp < nqp; ++qp)
     841       11333 :     MathUtils::mooseSetToZero(zero[qp]);
     842             : 
     843        2077 :   return zero;
     844             : }
     845             : 
     846             : template <typename T>
     847             : bool
     848         300 : MaterialPropertyInterface::hasADMaterialProperty(const std::string & name)
     849             : {
     850             :   // Check if the supplied parameter is a valid input parameter key
     851         300 :   const auto prop_name = getMaterialPropertyName(name);
     852         600 :   return hasADMaterialPropertyByName<T>(prop_name);
     853         300 : }
     854             : 
     855             : template <typename T>
     856             : bool
     857         356 : MaterialPropertyInterface::hasADMaterialPropertyByName(const std::string & name_in)
     858             : {
     859        1068 :   const auto name = _get_suffix.empty()
     860         356 :                         ? name_in
     861         356 :                         : MooseUtils::join(std::vector<std::string>({name_in, _get_suffix}), "_");
     862         712 :   return _material_data.haveADProperty<T>(name);
     863         356 : }
     864             : 
     865             : template <typename T, bool is_ad>
     866             : const GenericOptionalMaterialProperty<T, is_ad> &
     867         984 : MaterialPropertyInterface::getGenericOptionalMaterialProperty(const std::string & name,
     868             :                                                               const unsigned int state)
     869             : {
     870         984 :   auto proxy = std::make_unique<OptionalMaterialPropertyProxy<MaterialPropertyInterface, T, is_ad>>(
     871             :       name, state);
     872         984 :   auto & optional_property = proxy->value();
     873         984 :   _optional_property_proxies.push_back(std::move(proxy));
     874         984 :   return optional_property;
     875         984 : }
     876             : 
     877             : template <typename T, bool is_ad>
     878             : const GenericMaterialProperty<T, is_ad> &
     879       53570 : MaterialPropertyInterface::getPossiblyConstantGenericMaterialPropertyByName(
     880             :     const MaterialPropertyName & prop_name, MaterialData & material_data, const unsigned int state)
     881             : {
     882             :   // Check if it's just a constant
     883       53570 :   if (const auto * default_property = defaultGenericMaterialProperty<T, is_ad>(prop_name))
     884             :   {
     885        7739 :     _get_material_property_called = true;
     886        7739 :     return *default_property;
     887             :   }
     888             : 
     889       45831 :   if (state > 0 && !_stateful_allowed)
     890           8 :     mooseError("Stateful material properties not allowed for this object."
     891             :                " State ",
     892             :                state,
     893             :                " property for \"",
     894             :                prop_name,
     895             :                "\" was requested.");
     896             : 
     897       45823 :   return this->getGenericMaterialPropertyByName<T, is_ad>(prop_name, material_data, state);
     898             : }
     899             : 
     900             : template <typename T, bool is_ad>
     901             : const GenericMaterialProperty<T, is_ad> &
     902       53570 : MaterialPropertyInterface::getGenericMaterialProperty(const std::string & name,
     903             :                                                       MaterialData & material_data,
     904             :                                                       const unsigned int state)
     905             : {
     906             :   // Check if the supplied parameter is a valid input parameter key
     907       53570 :   const auto prop_name = getMaterialPropertyName(name);
     908             : 
     909       53570 :   return getPossiblyConstantGenericMaterialPropertyByName<T, is_ad>(
     910      107124 :       prop_name, material_data, state);
     911       53562 : }
     912             : 
     913             : template <typename T, bool is_ad>
     914             : const GenericMaterialProperty<T, is_ad> &
     915       56025 : MaterialPropertyInterface::getGenericMaterialPropertyByName(const MaterialPropertyName & name_in,
     916             :                                                             MaterialData & material_data,
     917             :                                                             const unsigned int state)
     918             : {
     919       56025 :   if (_is_kokkos_object)
     920           0 :     mooseError("Attempted to retrieve a standard MOOSE material property from a Kokkos object.");
     921             : 
     922       56025 :   if (_use_interpolated_state)
     923             :   {
     924         504 :     if (state == 1)
     925           0 :       return getGenericMaterialPropertyByName<T, is_ad>(
     926           0 :           name_in + _interpolated_old, material_data, 0);
     927         504 :     if (state == 2)
     928           0 :       return getGenericMaterialPropertyByName<T, is_ad>(
     929           0 :           name_in + _interpolated_older, material_data, 0);
     930             :   }
     931             : 
     932      168075 :   const auto name = _get_suffix.empty()
     933       56025 :                         ? static_cast<const std::string &>(name_in)
     934       56025 :                         : MooseUtils::join(std::vector<std::string>({name_in, _get_suffix}), "_");
     935             : 
     936       56025 :   checkExecutionStage();
     937       56025 :   checkMaterialProperty(name, state);
     938             : 
     939             :   // mark property as requested
     940       56025 :   markMatPropRequested(name);
     941             : 
     942             :   // Update the boolean flag.
     943       56025 :   _get_material_property_called = true;
     944             : 
     945             :   // Call first so that the ID gets registered
     946       56025 :   auto & prop = material_data.getProperty<T, is_ad>(name, state, _mi_moose_object);
     947             : 
     948             :   // Does the material data used here matter?
     949       56009 :   _material_property_dependencies.insert(material_data.getPropertyId(name));
     950             : 
     951       56009 :   if (state == 0)
     952       51283 :     addConsumedPropertyName(_mi_moose_object_name, name);
     953             : 
     954       56009 :   return prop;
     955       56009 : }
     956             : 
     957             : #ifdef MOOSE_KOKKOS_SCOPE
     958             : template <typename T, unsigned int dimension>
     959             : bool
     960             : MaterialPropertyInterface::hasKokkosMaterialProperty(const std::string & name)
     961             : {
     962             :   // Check if the supplied parameter is a valid input parameter key
     963             :   const auto prop_name = getMaterialPropertyName(name);
     964             :   return hasKokkosMaterialPropertyByName<T, dimension>(prop_name);
     965             : }
     966             : 
     967             : template <typename T, unsigned int dimension>
     968             : bool
     969             : MaterialPropertyInterface::hasKokkosMaterialPropertyByName(const std::string & name_in)
     970             : {
     971             :   const auto name = _get_suffix.empty()
     972             :                         ? name_in
     973             :                         : MooseUtils::join(std::vector<std::string>({name_in, _get_suffix}), "_");
     974             :   return _material_data.haveKokkosProperty<T, dimension>(name);
     975             : }
     976             : 
     977             : template <typename T, unsigned int dimension, unsigned int state>
     978             : Moose::Kokkos::MaterialProperty<T, dimension>
     979        1241 : MaterialPropertyInterface::getKokkosMaterialPropertyByName(const std::string & prop_name_in)
     980             : {
     981        1241 :   if (!_is_kokkos_object)
     982           0 :     mooseError("Attempted to retrieve a Kokkos material property from a standard MOOSE object.");
     983             : 
     984             :   if constexpr (std::is_same_v<T, Real>)
     985             :   {
     986        1241 :     std::istringstream ss(prop_name_in);
     987             :     Real value;
     988             : 
     989             :     // Check if the string parsed cleanly into a Real number
     990        1241 :     if (ss >> value && ss.eof())
     991           0 :       return Moose::Kokkos::MaterialProperty<T, dimension>(value);
     992        1241 :   }
     993             : 
     994        2219 :   const auto prop_name =
     995         978 :       _get_suffix.empty()
     996         978 :           ? static_cast<const std::string &>(prop_name_in)
     997         978 :           : MooseUtils::join(std::vector<std::string>({prop_name_in, _get_suffix}), "_");
     998             : 
     999        1241 :   checkExecutionStage();
    1000        1241 :   checkMaterialProperty(prop_name, state);
    1001             : 
    1002             :   // Mark property as requested
    1003        1241 :   markMatPropRequested(prop_name);
    1004             : 
    1005             :   // Update the boolean flag
    1006        1241 :   _get_material_property_called = true;
    1007             : 
    1008             :   // Call first so that the ID gets registered
    1009        1241 :   auto prop = _material_data.getKokkosProperty<T, dimension, state>(prop_name);
    1010             : 
    1011             :   // Does the material data used here matter?
    1012        1241 :   _material_property_dependencies.insert(_material_data.getPropertyId(prop_name));
    1013             : 
    1014             :   if constexpr (state == 0)
    1015         469 :     addConsumedPropertyName(_mi_moose_object_name, prop_name);
    1016             : 
    1017        1241 :   getKokkosMaterialPropertyHook(prop_name_in, state);
    1018             : 
    1019        1241 :   return prop;
    1020        1241 : }
    1021             : #endif

Generated by: LCOV version 1.14