LCOV - code coverage report
Current view: top level - include/materials - MaterialPropertyInterface.h (source / functions) Hit Total Coverage
Test: idaholab/moose framework: #31761 (28487c) with base 701993 Lines: 167 179 93.3 %
Date: 2025-11-11 13:51:07 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       51834 :   const GenericMaterialProperty<T, is_ad> & getGenericMaterialProperty(const std::string & name,
     104             :                                                                        const unsigned int state = 0)
     105             :   {
     106       51834 :     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    16277060 :   virtual const std::unordered_set<unsigned int> & getMatPropDependencies() const
     426             :   {
     427    16277060 :     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             : #ifdef MOOSE_KOKKOS_ENABLED
     575             :   /// Whether the MOOSE object is a Kokkos object
     576             :   const bool _is_kokkos_object;
     577             : #endif
     578             : 
     579             :   /// The type of data
     580             :   const Moose::MaterialDataType _material_data_type;
     581             : 
     582             :   /// The material data class that stores properties
     583             :   MaterialData & _material_data;
     584             : 
     585             :   /**
     586             :    * A helper method for checking material properties
     587             :    * This method was required to avoid a compiler problem with the template
     588             :    * getMaterialProperty method
     589             :    */
     590             :   virtual void checkMaterialProperty(const std::string & name, const unsigned int state);
     591             : 
     592             : #ifdef MOOSE_KOKKOS_ENABLED
     593             :   /**
     594             :    * A virtual method that can be overriden by Kokkos objects to insert additional operations in
     595             :    * getKokkosMaterialProperty
     596             :    * @param prop_name_in The property name
     597             :    * @param state The property state
     598             :    */
     599         258 :   virtual void getKokkosMaterialPropertyHook(const std::string & /* prop_name_in */,
     600             :                                              const unsigned int /* state */)
     601             :   {
     602         258 :   }
     603             : #endif
     604             : 
     605             :   /**
     606             :    * A proxy method for _mi_feproblem.markMatPropRequested(name)
     607             :    */
     608             :   void markMatPropRequested(const std::string &);
     609             : 
     610             :   /**
     611             :    * @return The name of the material property associated with name \p name.
     612             :    *
     613             :    * If \p name is the name of a material property parameter and the parameter is
     614             :    * valid, this will return the value of said parameter. Otherwise, it will just
     615             :    * return the name.
     616             :    */
     617             :   MaterialPropertyName getMaterialPropertyName(const std::string & name) const;
     618             : 
     619             :   /**
     620             :    * @return The default material property with the name \p name, if any.
     621             :    *
     622             :    * "Default" properties are properties whose default values are set from within
     623             :    * the name. That is, if we can cast \p name to a Real, _and_ the prop type is
     624             :    * a Real or RealVectorValue, we'll return said value.
     625             :    */
     626             :   ///@{
     627             :   template <typename T, bool is_ad>
     628             :   const GenericMaterialProperty<T, is_ad> *
     629             :   defaultGenericMaterialProperty(const std::string & name);
     630             :   template <typename T>
     631          53 :   const MaterialProperty<T> * defaultMaterialProperty(const std::string & name)
     632             :   {
     633          53 :     return defaultGenericMaterialProperty<T, false>(name);
     634             :   }
     635             :   template <typename T>
     636          53 :   const ADMaterialProperty<T> * defaultADMaterialProperty(const std::string & name)
     637             :   {
     638          53 :     return defaultGenericMaterialProperty<T, true>(name);
     639             :   }
     640             :   ///@}
     641             : 
     642             :   /**
     643             :    * Check and throw an error if the execution has progressed past the construction stage
     644             :    */
     645             :   void checkExecutionStage();
     646             : 
     647             :   /**
     648             :    * True by default. If false, this class throws an error if any of
     649             :    * the stateful material properties interfaces are used.
     650             :    */
     651             :   bool _stateful_allowed;
     652             : 
     653             :   /**
     654             :    * Initialized to false.  Gets set to true when getMaterialProperty()
     655             :    * is called.  Clients of this class can inquire whether getMaterialProperty()
     656             :    * has been called by calling getMaterialPropertyCalled().
     657             :    */
     658             :   bool _get_material_property_called;
     659             : 
     660             :   /// Storage vector for default properties
     661             :   std::vector<std::unique_ptr<PropertyValue>> _default_properties;
     662             : 
     663             :   /// The set of material properties (as given by their IDs) that _this_ object depends on
     664             :   std::unordered_set<unsigned int> _material_property_dependencies;
     665             : 
     666             :   const MaterialPropertyName _get_suffix;
     667             : 
     668             :   /// Use the interpolated state set up through the ProjectedStatefulMaterialStorageAction
     669             :   const bool _use_interpolated_state;
     670             : 
     671             :   ///@{ name suffixes for interpolated old and older properties
     672             :   static const std::string _interpolated_old;
     673             :   static const std::string _interpolated_older;
     674             :   ///@}
     675             : 
     676             : private:
     677             :   /**
     678             :    * @returns The MaterialDataType given the interface's parameters
     679             :    */
     680             :   Moose::MaterialDataType getMaterialDataType(const std::set<BoundaryID> & boundary_ids) const;
     681             : 
     682             :   /*
     683             :    * A proxy method for _mi_feproblem.getMaxQps()
     684             :    */
     685             :   unsigned int getMaxQps() const;
     686             : 
     687             :   /*
     688             :    * A proxy method for _mi_feproblem.addConsumedPropertyName()
     689             :    */
     690             :   void addConsumedPropertyName(const MooseObjectName & obj_name, const std::string & prop_name);
     691             : 
     692             :   /// BoundaryRestricted flag
     693             :   const bool _mi_boundary_restricted;
     694             : 
     695             :   /// Storage for the block ids created by BlockRestrictable
     696             :   const std::set<SubdomainID> & _mi_block_ids;
     697             : 
     698             :   /// Storage for the boundary ids created by BoundaryRestrictable
     699             :   const std::set<BoundaryID> & _mi_boundary_ids;
     700             : 
     701             :   /// optional material properties
     702             :   std::vector<std::unique_ptr<OptionalMaterialPropertyProxyBase<MaterialPropertyInterface>>>
     703             :       _optional_property_proxies;
     704             : };
     705             : 
     706             : template <class M, typename T, bool is_ad>
     707             : class OptionalMaterialPropertyProxy : public OptionalMaterialPropertyProxyBase<M>
     708             : {
     709             : public:
     710        1728 :   OptionalMaterialPropertyProxy(const std::string & name, const unsigned int state)
     711        1728 :     : OptionalMaterialPropertyProxyBase<M>(name, state)
     712             :   {
     713        1728 :   }
     714        1728 :   const GenericOptionalMaterialProperty<T, is_ad> & value() const { return _value; }
     715        1728 :   void resolve(M & mpi) override
     716             :   {
     717        1728 :     if (mpi.template hasGenericMaterialProperty<T, is_ad>(this->_name))
     718             :     {
     719             :       if constexpr (is_ad)
     720         157 :         if (this->_state > 0)
     721           0 :           mooseError("Non-current (state > 0) material properties are not available as AD");
     722             : 
     723         750 :       _value.set(&mpi.template getGenericMaterialProperty<T, is_ad>(this->_name, this->_state));
     724             :     }
     725        1728 :   }
     726             : 
     727             : private:
     728             :   GenericOptionalMaterialProperty<T, is_ad> _value;
     729             : };
     730             : 
     731             : template <typename T, bool is_ad>
     732             : const GenericMaterialProperty<T, is_ad> *
     733       71487 : MaterialPropertyInterface::defaultGenericMaterialProperty(const std::string & name)
     734             : {
     735             :   if constexpr (std::is_same_v<T, Real> || std::is_same_v<T, RealVectorValue>)
     736             :   {
     737       38773 :     std::istringstream ss(name);
     738             :     Real real_value;
     739             : 
     740             :     // check if the string parsed cleanly into a Real number
     741       38773 :     if (ss >> real_value && ss.eof())
     742             :     {
     743             :       using prop_type = GenericMaterialProperty<T, is_ad>;
     744             : 
     745        9245 :       const auto nqp = Moose::constMaxQpsPerElem;
     746             :       auto & property =
     747        9245 :           _default_properties.emplace_back(std::make_unique<prop_type>(default_property_id));
     748        9245 :       auto & T_property = static_cast<prop_type &>(*property);
     749             : 
     750        9245 :       T_property.resize(nqp);
     751     9254245 :       for (const auto qp : make_range(nqp))
     752     9245000 :         T_property[qp] = real_value;
     753             : 
     754        9245 :       return &T_property;
     755             :     }
     756       38773 :   }
     757             : 
     758       62242 :   return nullptr;
     759             : }
     760             : 
     761             : template <typename T>
     762             : std::pair<const MaterialProperty<T> *, std::set<SubdomainID>>
     763             : MaterialPropertyInterface::getBlockMaterialProperty(const MaterialPropertyName & name_in)
     764             : {
     765             :   const auto name = _get_suffix.empty()
     766             :                         ? static_cast<const std::string &>(name_in)
     767             :                         : MooseUtils::join(std::vector<std::string>({name_in, _get_suffix}), "_");
     768             : 
     769             :   if (_mi_block_ids.empty())
     770             :     mooseError("getBlockMaterialProperty must be called by a block restrictable object");
     771             : 
     772             :   using pair_type = std::pair<const MaterialProperty<T> *, std::set<SubdomainID>>;
     773             : 
     774             :   if (!hasMaterialPropertyByName<T>(name))
     775             :     return pair_type(nullptr, {});
     776             : 
     777             :   // Call first so that the ID gets registered
     778             :   const auto & prop = _material_data.getProperty<T, false>(name, 0, _mi_moose_object);
     779             :   auto blocks = getMaterialPropertyBlocks(name);
     780             :   auto prop_blocks_pair = pair_type(&prop, std::move(blocks));
     781             : 
     782             :   _material_property_dependencies.insert(_material_data.getPropertyId(name));
     783             : 
     784             :   // Update consumed properties in MaterialPropertyDebugOutput
     785             :   addConsumedPropertyName(_mi_moose_object_name, name);
     786             : 
     787             :   return prop_blocks_pair;
     788             : }
     789             : 
     790             : template <typename T>
     791             : bool
     792       11457 : MaterialPropertyInterface::hasMaterialProperty(const std::string & name)
     793             : {
     794             :   // Check if the supplied parameter is a valid input parameter key
     795       11457 :   const auto prop_name = getMaterialPropertyName(name);
     796       22914 :   return hasMaterialPropertyByName<T>(prop_name);
     797       11457 : }
     798             : 
     799             : template <typename T>
     800             : bool
     801       13174 : MaterialPropertyInterface::hasMaterialPropertyByName(const std::string & name_in)
     802             : {
     803       39522 :   const auto name = _get_suffix.empty()
     804       13174 :                         ? name_in
     805       13174 :                         : MooseUtils::join(std::vector<std::string>({name_in, _get_suffix}), "_");
     806       26348 :   return _material_data.haveProperty<T>(name);
     807       13174 : }
     808             : 
     809             : template <typename T, bool is_ad>
     810             : const GenericMaterialProperty<T, is_ad> &
     811           0 : MaterialPropertyInterface::getGenericZeroMaterialProperty(const std::string & name)
     812             : {
     813           0 :   const auto prop_name = getMaterialPropertyName(name);
     814           0 :   return getGenericZeroMaterialPropertyByName<T, is_ad>(prop_name);
     815           0 : }
     816             : 
     817             : template <typename T, bool is_ad>
     818             : const GenericMaterialProperty<T, is_ad> &
     819        1773 : MaterialPropertyInterface::getGenericZeroMaterialPropertyByName(const std::string & prop_name)
     820             : {
     821             :   // if found return the requested property
     822        1773 :   if (hasGenericMaterialPropertyByName<T, is_ad>(prop_name))
     823         244 :     return getGenericMaterialPropertyByName<T, is_ad>(prop_name);
     824             : 
     825        1529 :   return getGenericZeroMaterialProperty<T, is_ad>();
     826             : }
     827             : 
     828             : template <typename T, bool is_ad>
     829             : const GenericMaterialProperty<T, is_ad> &
     830        2077 : MaterialPropertyInterface::getGenericZeroMaterialProperty()
     831             : {
     832             :   // static zero property storage
     833        2077 :   static GenericMaterialProperty<T, is_ad> zero(zero_property_id);
     834             : 
     835             :   // resize to accomodate maximum number of qpoints
     836             :   // (in multiapp scenarios getMaxQps can return different values in each app; we need the max)
     837        2077 :   unsigned int nqp = getMaxQps();
     838        2077 :   if (nqp > zero.size())
     839        1308 :     zero.resize(nqp);
     840             : 
     841             :   // set values for all qpoints to zero
     842       13410 :   for (unsigned int qp = 0; qp < nqp; ++qp)
     843       11333 :     MathUtils::mooseSetToZero(zero[qp]);
     844             : 
     845        2077 :   return zero;
     846             : }
     847             : 
     848             : template <typename T>
     849             : bool
     850         300 : MaterialPropertyInterface::hasADMaterialProperty(const std::string & name)
     851             : {
     852             :   // Check if the supplied parameter is a valid input parameter key
     853         300 :   const auto prop_name = getMaterialPropertyName(name);
     854         600 :   return hasADMaterialPropertyByName<T>(prop_name);
     855         300 : }
     856             : 
     857             : template <typename T>
     858             : bool
     859         356 : MaterialPropertyInterface::hasADMaterialPropertyByName(const std::string & name_in)
     860             : {
     861        1068 :   const auto name = _get_suffix.empty()
     862         356 :                         ? name_in
     863         356 :                         : MooseUtils::join(std::vector<std::string>({name_in, _get_suffix}), "_");
     864         712 :   return _material_data.haveADProperty<T>(name);
     865         356 : }
     866             : 
     867             : template <typename T, bool is_ad>
     868             : const GenericOptionalMaterialProperty<T, is_ad> &
     869         984 : MaterialPropertyInterface::getGenericOptionalMaterialProperty(const std::string & name,
     870             :                                                               const unsigned int state)
     871             : {
     872         984 :   auto proxy = std::make_unique<OptionalMaterialPropertyProxy<MaterialPropertyInterface, T, is_ad>>(
     873             :       name, state);
     874         984 :   auto & optional_property = proxy->value();
     875         984 :   _optional_property_proxies.push_back(std::move(proxy));
     876         984 :   return optional_property;
     877         984 : }
     878             : 
     879             : template <typename T, bool is_ad>
     880             : const GenericMaterialProperty<T, is_ad> &
     881       55333 : MaterialPropertyInterface::getPossiblyConstantGenericMaterialPropertyByName(
     882             :     const MaterialPropertyName & prop_name, MaterialData & material_data, const unsigned int state)
     883             : {
     884             :   // Check if it's just a constant
     885       55333 :   if (const auto * default_property = defaultGenericMaterialProperty<T, is_ad>(prop_name))
     886             :   {
     887        7739 :     _get_material_property_called = true;
     888        7739 :     return *default_property;
     889             :   }
     890             : 
     891       47594 :   if (state > 0 && !_stateful_allowed)
     892           8 :     mooseError("Stateful material properties not allowed for this object."
     893             :                " State ",
     894             :                state,
     895             :                " property for \"",
     896             :                prop_name,
     897             :                "\" was requested.");
     898             : 
     899       47586 :   return this->getGenericMaterialPropertyByName<T, is_ad>(prop_name, material_data, state);
     900             : }
     901             : 
     902             : template <typename T, bool is_ad>
     903             : const GenericMaterialProperty<T, is_ad> &
     904       55333 : MaterialPropertyInterface::getGenericMaterialProperty(const std::string & name,
     905             :                                                       MaterialData & material_data,
     906             :                                                       const unsigned int state)
     907             : {
     908             :   // Check if the supplied parameter is a valid input parameter key
     909       55333 :   const auto prop_name = getMaterialPropertyName(name);
     910             : 
     911       55333 :   return getPossiblyConstantGenericMaterialPropertyByName<T, is_ad>(
     912      110650 :       prop_name, material_data, state);
     913       55325 : }
     914             : 
     915             : template <typename T, bool is_ad>
     916             : const GenericMaterialProperty<T, is_ad> &
     917       57788 : MaterialPropertyInterface::getGenericMaterialPropertyByName(const MaterialPropertyName & name_in,
     918             :                                                             MaterialData & material_data,
     919             :                                                             const unsigned int state)
     920             : {
     921             : #ifdef MOOSE_KOKKOS_ENABLED
     922       39772 :   if (_is_kokkos_object)
     923           0 :     _mi_moose_object.mooseError(
     924             :         "Attempted to retrieve a standard MOOSE material property from a Kokkos object.");
     925             : #endif
     926             : 
     927       57788 :   if (_use_interpolated_state)
     928             :   {
     929         504 :     if (state == 1)
     930           0 :       return getGenericMaterialPropertyByName<T, is_ad>(
     931           0 :           name_in + _interpolated_old, material_data, 0);
     932         504 :     if (state == 2)
     933           0 :       return getGenericMaterialPropertyByName<T, is_ad>(
     934           0 :           name_in + _interpolated_older, material_data, 0);
     935             :   }
     936             : 
     937      173364 :   const auto name = _get_suffix.empty()
     938       57788 :                         ? static_cast<const std::string &>(name_in)
     939       57788 :                         : MooseUtils::join(std::vector<std::string>({name_in, _get_suffix}), "_");
     940             : 
     941       57788 :   checkExecutionStage();
     942       57788 :   checkMaterialProperty(name, state);
     943             : 
     944             :   // mark property as requested
     945       57788 :   markMatPropRequested(name);
     946             : 
     947             :   // Update the boolean flag.
     948       57788 :   _get_material_property_called = true;
     949             : 
     950             :   // Call first so that the ID gets registered
     951       57788 :   auto & prop = material_data.getProperty<T, is_ad>(name, state, _mi_moose_object);
     952             : 
     953             :   // Does the material data used here matter?
     954       57772 :   _material_property_dependencies.insert(material_data.getPropertyId(name));
     955             : 
     956       57772 :   if (state == 0)
     957       53046 :     addConsumedPropertyName(_mi_moose_object_name, name);
     958             : 
     959       57772 :   return prop;
     960       57772 : }
     961             : 
     962             : #ifdef MOOSE_KOKKOS_SCOPE
     963             : template <typename T, unsigned int dimension>
     964             : bool
     965             : MaterialPropertyInterface::hasKokkosMaterialProperty(const std::string & name)
     966             : {
     967             :   // Check if the supplied parameter is a valid input parameter key
     968             :   const auto prop_name = getMaterialPropertyName(name);
     969             :   return hasKokkosMaterialPropertyByName<T, dimension>(prop_name);
     970             : }
     971             : 
     972             : template <typename T, unsigned int dimension>
     973             : bool
     974             : MaterialPropertyInterface::hasKokkosMaterialPropertyByName(const std::string & name_in)
     975             : {
     976             :   const auto name = _get_suffix.empty()
     977             :                         ? name_in
     978             :                         : MooseUtils::join(std::vector<std::string>({name_in, _get_suffix}), "_");
     979             :   return _material_data.haveKokkosProperty<T, dimension>(name);
     980             : }
     981             : 
     982             : template <typename T, unsigned int dimension, unsigned int state>
     983             : Moose::Kokkos::MaterialProperty<T, dimension>
     984        1241 : MaterialPropertyInterface::getKokkosMaterialPropertyByName(const std::string & prop_name_in)
     985             : {
     986        1241 :   if (!_is_kokkos_object)
     987           0 :     _mi_moose_object.mooseError(
     988             :         "Attempted to retrieve a Kokkos material property from a standard MOOSE object.");
     989             : 
     990             :   if constexpr (std::is_same_v<T, Real>)
     991             :   {
     992        1241 :     std::istringstream ss(prop_name_in);
     993             :     Real value;
     994             : 
     995             :     // Check if the string parsed cleanly into a Real number
     996        1241 :     if (ss >> value && ss.eof())
     997           0 :       return Moose::Kokkos::MaterialProperty<T, dimension>(value);
     998        1241 :   }
     999             : 
    1000        2219 :   const auto prop_name =
    1001         978 :       _get_suffix.empty()
    1002         978 :           ? static_cast<const std::string &>(prop_name_in)
    1003         978 :           : MooseUtils::join(std::vector<std::string>({prop_name_in, _get_suffix}), "_");
    1004             : 
    1005        1241 :   checkExecutionStage();
    1006        1241 :   checkMaterialProperty(prop_name, state);
    1007             : 
    1008             :   // Mark property as requested
    1009        1241 :   markMatPropRequested(prop_name);
    1010             : 
    1011             :   // Update the boolean flag
    1012        1241 :   _get_material_property_called = true;
    1013             : 
    1014             :   // Call first so that the ID gets registered
    1015        1241 :   auto prop = _material_data.getKokkosProperty<T, dimension, state>(prop_name);
    1016             : 
    1017             :   // Does the material data used here matter?
    1018        1241 :   _material_property_dependencies.insert(_material_data.getPropertyId(prop_name));
    1019             : 
    1020             :   if constexpr (state == 0)
    1021         469 :     addConsumedPropertyName(_mi_moose_object_name, prop_name);
    1022             : 
    1023        1241 :   getKokkosMaterialPropertyHook(prop_name_in, state);
    1024             : 
    1025        1241 :   return prop;
    1026        1241 : }
    1027             : #endif

Generated by: LCOV version 1.14