LCOV - code coverage report
Current view: top level - include/materials - MaterialBase.h (source / functions) Hit Total Coverage
Test: idaholab/moose framework: 6f668f Lines: 88 95 92.6 %
Date: 2025-09-22 20:01:15 Functions: 88 99 88.9 %
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             : // MOOOSE includes
      13             : #include "MooseObject.h"
      14             : #include "BlockRestrictable.h"
      15             : #include "BoundaryRestrictable.h"
      16             : #include "SetupInterface.h"
      17             : #include "MooseVariableDependencyInterface.h"
      18             : #include "ScalarCoupleable.h"
      19             : #include "FunctionInterface.h"
      20             : #include "DistributionInterface.h"
      21             : #include "UserObjectInterface.h"
      22             : #include "TransientInterface.h"
      23             : #include "PostprocessorInterface.h"
      24             : #include "VectorPostprocessorInterface.h"
      25             : #include "DependencyResolverInterface.h"
      26             : #include "Restartable.h"
      27             : #include "MeshChangedInterface.h"
      28             : #include "OutputInterface.h"
      29             : #include "RandomInterface.h"
      30             : #include "ElementIDInterface.h"
      31             : #include "MaterialProperty.h"
      32             : #include "MaterialData.h"
      33             : #include "MathUtils.h"
      34             : #include "Assembly.h"
      35             : #include "GeometricSearchInterface.h"
      36             : #include "ADFunctorInterface.h"
      37             : #include "SolutionInvalidInterface.h"
      38             : #include "MaterialPropertyInterface.h"
      39             : 
      40             : #define usingMaterialBaseMembers                                                                   \
      41             :   usingMooseObjectMembers;                                                                         \
      42             :   usingTransientInterfaceMembers;                                                                  \
      43             :   using MaterialBase::_subproblem;                                                                 \
      44             :   using MaterialBase::_fe_problem;                                                                 \
      45             :   using MaterialBase::_tid;                                                                        \
      46             :   using MaterialBase::_assembly;                                                                   \
      47             :   using MaterialBase::_qp;                                                                         \
      48             :   using MaterialBase::_coord;                                                                      \
      49             :   using MaterialBase::_normals;                                                                    \
      50             :   using MaterialBase::_mesh
      51             : 
      52             : // forward declarations
      53             : class MaterialBase;
      54             : class MooseMesh;
      55             : class SubProblem;
      56             : class FaceInfo;
      57             : class FEProblemBase;
      58             : 
      59             : /**
      60             :  * MaterialBases compute MaterialProperties.
      61             :  */
      62             : class MaterialBase : public MooseObject,
      63             :                      public BlockRestrictable,
      64             :                      public BoundaryRestrictable,
      65             :                      public SetupInterface,
      66             :                      public MooseVariableDependencyInterface,
      67             :                      public ScalarCoupleable,
      68             :                      public FunctionInterface,
      69             :                      public DistributionInterface,
      70             :                      public UserObjectInterface,
      71             :                      public TransientInterface,
      72             :                      public PostprocessorInterface,
      73             :                      public VectorPostprocessorInterface,
      74             :                      public DependencyResolverInterface,
      75             :                      public Restartable,
      76             :                      public MeshChangedInterface,
      77             :                      public OutputInterface,
      78             :                      public RandomInterface,
      79             :                      public ElementIDInterface,
      80             :                      protected GeometricSearchInterface,
      81             :                      protected ADFunctorInterface,
      82             :                      protected SolutionInvalidInterface
      83             : {
      84             : public:
      85             :   static InputParameters validParams();
      86             : 
      87             :   MaterialBase(const InputParameters & parameters);
      88             : 
      89             : #ifdef MOOSE_KOKKOS_ENABLED
      90             :   /**
      91             :    * Special constructor used for Kokkos functor copy during parallel dispatch
      92             :    */
      93             :   MaterialBase(const MaterialBase & object, const Moose::Kokkos::FunctorCopy & key);
      94             : #endif
      95             : 
      96             :   /**
      97             :    * Initialize stateful properties (if material has some)
      98             :    *
      99             :    * This is _only_ called if this material has properties that are
     100             :    * requested as stateful
     101             :    */
     102             :   virtual void initStatefulProperties(const unsigned int n_points);
     103             : 
     104           0 :   virtual bool isInterfaceMaterial() { return false; };
     105             : 
     106             :   /**
     107             :    * Performs the quadrature point loop, calling computeQpProperties
     108             :    */
     109             :   virtual void computeProperties() = 0;
     110             : 
     111             :   /**
     112             :    * Resets the properties at each quadrature point (see resetQpProperties), only called if 'compute
     113             :    * = false'.
     114             :    *
     115             :    * This method is called internally by MOOSE, you probably don't want to mess with this.
     116             :    */
     117             :   virtual void resetProperties();
     118             : 
     119             :   /**
     120             :    * A method for (re)computing the properties of a MaterialBase.
     121             :    *
     122             :    * This is intended to be called from other objects, by first calling
     123             :    * MaterialPropertyInterface::getMaterial and then calling this method on the MaterialBase object
     124             :    * returned.
     125             :    */
     126             :   virtual void computePropertiesAtQp(unsigned int qp);
     127             : 
     128             :   ///@{
     129             :   /**
     130             :    * Declare the property named "name"
     131             :    */
     132             :   template <typename T>
     133       42418 :   MaterialProperty<T> & declarePropertyByName(const std::string & prop_name)
     134             :   {
     135       42418 :     return declareGenericPropertyByName<T, false>(prop_name);
     136             :   }
     137             :   template <typename T>
     138             :   MaterialProperty<T> & declareProperty(const std::string & name);
     139             :   template <typename T>
     140       11569 :   ADMaterialProperty<T> & declareADPropertyByName(const std::string & prop_name)
     141             :   {
     142       11569 :     return declareGenericPropertyByName<T, true>(prop_name);
     143             :   }
     144             :   template <typename T>
     145             :   ADMaterialProperty<T> & declareADProperty(const std::string & name);
     146             : 
     147             :   template <typename T, bool is_ad>
     148       35198 :   auto & declareGenericProperty(const std::string & prop_name)
     149             :   {
     150             :     if constexpr (is_ad)
     151        9908 :       return declareADProperty<T>(prop_name);
     152             :     else
     153       25290 :       return declareProperty<T>(prop_name);
     154             :   }
     155             :   template <typename T, bool is_ad>
     156             :   GenericMaterialProperty<T, is_ad> & declareGenericPropertyByName(const std::string & prop_name);
     157             :   ///@}
     158             : 
     159             :   /**
     160             :    * Return a material property that is initialized to zero by default and does
     161             :    * not need to (but can) be declared by another material.
     162             :    */
     163             :   template <typename T, bool is_ad>
     164             :   const GenericMaterialProperty<T, is_ad> &
     165             :   getGenericZeroMaterialProperty(const std::string & name);
     166             :   template <typename T, bool is_ad>
     167             :   const GenericMaterialProperty<T, is_ad> &
     168             :   getGenericZeroMaterialPropertyByName(const std::string & prop_name);
     169             : 
     170             :   /**
     171             :    * Return a constant zero anonymous material property
     172             :    */
     173             :   template <typename T, bool is_ad>
     174             :   const GenericMaterialProperty<T, is_ad> & getGenericZeroMaterialProperty();
     175             : 
     176             :   /// for backwards compatibility
     177             :   template <typename T, typename... Ts>
     178             :   const MaterialProperty<T> & getZeroMaterialProperty(Ts... args)
     179             :   {
     180             :     return getGenericZeroMaterialProperty<T, false>(args...);
     181             :   }
     182             : 
     183             :   /// for backwards compatibility
     184             :   template <typename T, typename... Ts>
     185             :   const MaterialProperty<T> & getZeroMaterialPropertyByName(Ts... args)
     186             :   {
     187             :     return getGenericZeroMaterialPropertyByName<T, false>(args...);
     188             :   }
     189             : 
     190             :   /**
     191             :    * Return a set of properties accessed with getMaterialProperty
     192             :    * @return A reference to the set of properties with calls to getMaterialProperty
     193             :    */
     194       22553 :   virtual const std::set<std::string> & getRequestedItems() override { return _requested_props; }
     195             : 
     196             :   /**
     197             :    * Return a set of properties accessed with declareProperty
     198             :    * @return A reference to the set of properties with calls to declareProperty
     199             :    */
     200      238577 :   virtual const std::set<std::string> & getSuppliedItems() override { return _supplied_props; }
     201             : 
     202             :   /**
     203             :    * Get the prop ids corresponding to \p declareProperty
     204             :    * @return A reference to the set of properties with calls to \p declareProperty
     205             :    */
     206      707081 :   const std::set<unsigned int> & getSuppliedPropIDs() { return _supplied_prop_ids; }
     207             : 
     208             :   void checkStatefulSanity() const;
     209             : 
     210             :   /**
     211             :    * Get the list of output objects that this class is restricted
     212             :    * @return A vector of OutputNames
     213             :    */
     214             :   std::set<OutputName> getOutputs();
     215             : 
     216             :   /**
     217             :    * Returns true of the MaterialData type is not associated with volume data
     218             :    */
     219             :   virtual bool isBoundaryMaterial() const = 0;
     220             : 
     221             :   /**
     222             :    * Subdomain setup evaluating material properties when required
     223             :    */
     224             :   virtual void subdomainSetup() override;
     225             : 
     226             :   /**
     227             :    * Retrieve the set of material properties that _this_ object depends on.
     228             :    *
     229             :    * @return The IDs corresponding to the material properties that
     230             :    * MUST be reinited before evaluating this object
     231             :    */
     232             :   virtual const std::unordered_set<unsigned int> & getMatPropDependencies() const = 0;
     233             : 
     234             :   /**
     235             :    * @return Whether this material has stateful properties
     236             :    */
     237         689 :   bool hasStatefulProperties() const { return _has_stateful_property; }
     238             : 
     239             :   /**
     240             :    * @return Whether this material has restored properties
     241             :    */
     242             :   bool hasRestoredProperties() const;
     243             : 
     244             :   /**
     245             :    * Whether this material supports ghosted computations. This is important for finite volume
     246             :    * calculations in which variables have defined values on ghost cells/elements and for which these
     247             :    * ghost values may need to flow through material calculations to be eventually consumed by FV
     248             :    * flux kernels or boundary conditions
     249             :    */
     250           0 :   virtual bool ghostable() const { return false; }
     251             : 
     252       21816 :   void setFaceInfo(const FaceInfo & fi) { _face_info = &fi; }
     253             : 
     254             :   /**
     255             :    * Build the materials required by a set of consumer objects
     256             :    */
     257             :   template <typename Consumers>
     258             :   static std::deque<MaterialBase *>
     259             :   buildRequiredMaterials(const Consumers & mat_consumers,
     260             :                          const std::vector<std::shared_ptr<MaterialBase>> & mats,
     261             :                          const bool allow_stateful);
     262             : 
     263             :   /**
     264             :    * Set active properties of this material
     265             :    * Note: This function is called by FEProblemBase::setActiveMaterialProperties in an element loop
     266             :    *       typically when switching subdomains.
     267             :    */
     268             :   void setActiveProperties(const std::unordered_set<unsigned int> & needed_props);
     269             : 
     270             :   /**
     271             :    * @return Whether or not this material should forcefully call
     272             :    * initStatefulProperties() even if it doesn't produce properties
     273             :    * that needs state.
     274             :    *
     275             :    * Please don't set this to true :(
     276             :    */
     277      245558 :   bool forceStatefulInit() const { return _force_stateful_init; }
     278             : 
     279             : protected:
     280             :   /**
     281             :    * Users must override this method.
     282             :    */
     283             :   virtual void computeQpProperties();
     284             : 
     285             :   /**
     286             :    * Resets the properties prior to calculation of traditional materials (only if 'compute =
     287             :    * false').
     288             :    *
     289             :    * This method must be overridden in your class. This is called just prior to the re-calculation
     290             :    * of
     291             :    * traditional material properties to ensure that the properties are in a proper state for
     292             :    * calculation.
     293             :    */
     294             :   virtual void resetQpProperties();
     295             : 
     296             :   /**
     297             :    * Initialize stateful properties at quadrature points.  Note when using this function you only
     298             :    * need to address
     299             :    * the "current" material properties not the old ones directly, i.e. if you have a property named
     300             :    * "_diffusivity"
     301             :    * and an older property named "_diffusivity_old".  You only need to initialize diffusivity.
     302             :    * MOOSE will use
     303             :    * copy that initial value to the old and older values as necessary.
     304             :    *
     305             :    * This is _only_ called if this material has properties that are
     306             :    * requested as stateful
     307             :    */
     308             :   virtual void initQpStatefulProperties();
     309             : 
     310             :   virtual const MaterialData & materialData() const = 0;
     311             :   virtual MaterialData & materialData() = 0;
     312             :   virtual Moose::MaterialDataType materialDataType() = 0;
     313             : 
     314           0 :   virtual const FEProblemBase & miProblem() const { return _fe_problem; }
     315           0 :   virtual FEProblemBase & miProblem() { return _fe_problem; }
     316             : 
     317             :   virtual const QBase & qRule() const = 0;
     318             : 
     319             :   /**
     320             :    * Check whether a material property is active
     321             :    */
     322        5548 :   bool isPropertyActive(const unsigned int prop_id) const
     323             :   {
     324        5548 :     return _active_prop_ids.count(prop_id) > 0;
     325             :   }
     326             : 
     327             :   SubProblem & _subproblem;
     328             : 
     329             :   FEProblemBase & _fe_problem;
     330             :   THREAD_ID _tid;
     331             :   Assembly & _assembly;
     332             : 
     333             :   unsigned int _qp;
     334             : 
     335             :   const MooseArray<Real> & _coord;
     336             :   /// normals at quadrature points (valid only in boundary materials)
     337             :   const MooseArray<Point> & _normals;
     338             : 
     339             :   MooseMesh & _mesh;
     340             : 
     341             :   /// Coordinate system
     342             :   const Moose::CoordinateSystemType & _coord_sys;
     343             : 
     344             :   /// Set of properties accessed via get method
     345             :   std::set<std::string> _requested_props;
     346             : 
     347             :   /// Set of properties declared
     348             :   std::set<std::string> _supplied_props;
     349             : 
     350             :   /// The ids of the supplied properties, i.e. the indices where they
     351             :   /// are stored in the _material_data->props().  Note: these ids ARE
     352             :   /// NOT IN THE SAME ORDER AS THE _supplied_props set, which is
     353             :   /// ordered alphabetically by name.  The intention of this container
     354             :   /// is to allow rapid copying of MaterialProperty values in
     355             :   /// MaterialBase::computeProperties() without looking up the ids from
     356             :   /// the name strings each time.
     357             :   std::set<unsigned int> _supplied_prop_ids;
     358             : 
     359             :   /// The ids of the current active supplied properties
     360             :   std::unordered_set<unsigned int> _active_prop_ids;
     361             : 
     362             :   /// If False MOOSE does not compute this property
     363             :   const bool _compute;
     364             : 
     365             :   enum QP_Data_Type
     366             :   {
     367             :     CURR,
     368             :     PREV
     369             :   };
     370             : 
     371             :   /// The minimum states requested (0 = current, 1 = old, 2 = older)
     372             :   /// This is sparse and is used to keep track of whether or not stateful
     373             :   /// properties are requested without state 0 being requested
     374             :   std::unordered_map<unsigned int, unsigned int> _props_to_min_states;
     375             : 
     376             :   /// Small helper function to call store{Subdomain,Boundary}MatPropName
     377             :   void registerPropName(const std::string & prop_name, bool is_get, const unsigned int state);
     378             : 
     379             :   /// Check and throw an error if the execution has progressed past the construction stage
     380             :   void checkExecutionStage();
     381             : 
     382             :   std::vector<unsigned int> _displacements;
     383             : 
     384             :   bool _has_stateful_property;
     385             : 
     386             :   bool _overrides_init_stateful_props = true;
     387             : 
     388             :   const FaceInfo * _face_info = nullptr;
     389             : 
     390             :   /// Suffix to append to the name of the material property/ies when declaring it/them
     391             :   const MaterialPropertyName _declare_suffix;
     392             : 
     393             : private:
     394             :   /**
     395             :    * Helper method for adding a material property name to the material property requested set
     396             :    */
     397             :   void markMatPropRequested(const std::string & name);
     398             : 
     399             :   /**
     400             :    * Adds to a map based on block ids of material properties for which a zero
     401             :    * value can be returned. These properties are optional and will not trigger a
     402             :    * missing material property error.
     403             :    *
     404             :    * @param block_id The block id for the MaterialProperty
     405             :    * @param name The name of the property
     406             :    */
     407             :   void storeSubdomainZeroMatProp(SubdomainID block_id, const MaterialPropertyName & name);
     408             : 
     409             :   /**
     410             :    * Adds to a map based on boundary ids of material properties for which a zero
     411             :    * value can be returned. These properties are optional and will not trigger a
     412             :    * missing material property error.
     413             :    *
     414             :    * @param boundary_id The block id for the MaterialProperty
     415             :    * @param name The name of the property
     416             :    */
     417             :   void storeBoundaryZeroMatProp(BoundaryID boundary_id, const MaterialPropertyName & name);
     418             : 
     419             :   /**
     420             :    * @return The maximum number of quadrature points in use on any element in this problem.
     421             :    */
     422             :   unsigned int getMaxQps() const;
     423             : 
     424             :   /// Whether or not to force stateful init; see forceStatefulInit()
     425             :   const bool _force_stateful_init;
     426             : 
     427             :   /// To let it access the declaration suffix
     428             :   friend class FunctorMaterial;
     429             : };
     430             : 
     431             : template <typename T>
     432             : MaterialProperty<T> &
     433       42418 : MaterialBase::declareProperty(const std::string & name)
     434             : {
     435             :   // Check if the supplied parameter is a valid input parameter key
     436       42418 :   std::string prop_name = name;
     437       42418 :   if (_pars.have_parameter<MaterialPropertyName>(name))
     438         633 :     prop_name = _pars.get<MaterialPropertyName>(name);
     439             : 
     440       84836 :   return declarePropertyByName<T>(prop_name);
     441       42418 : }
     442             : 
     443             : template <typename T, bool is_ad>
     444             : GenericMaterialProperty<T, is_ad> &
     445       64264 : MaterialBase::declareGenericPropertyByName(const std::string & prop_name)
     446             : {
     447      128738 :   const auto prop_name_modified =
     448       64264 :       _declare_suffix.empty()
     449       64264 :           ? prop_name
     450       64894 :           : MooseUtils::join(std::vector<std::string>({prop_name, _declare_suffix}), "_");
     451             : 
     452             :   // Call this before so that the ID is valid
     453       64264 :   auto & prop = materialData().declareProperty<T, is_ad>(prop_name_modified, *this);
     454             : 
     455       64264 :   registerPropName(prop_name_modified, false, 0);
     456       64264 :   return prop;
     457       64474 : }
     458             : 
     459             : template <typename T, bool is_ad>
     460             : const GenericMaterialProperty<T, is_ad> &
     461        4362 : MaterialBase::getGenericZeroMaterialProperty(const std::string & name)
     462             : {
     463             :   // Check if the supplied parameter is a valid input parameter key
     464        4362 :   std::string prop_name = name;
     465        4362 :   if (_pars.have_parameter<MaterialPropertyName>(name))
     466           0 :     prop_name = _pars.get<MaterialPropertyName>(name);
     467             : 
     468        8724 :   return getGenericZeroMaterialPropertyByName<T, is_ad>(prop_name);
     469        4362 : }
     470             : 
     471             : template <typename T, bool is_ad>
     472             : const GenericMaterialProperty<T, is_ad> &
     473        9522 : MaterialBase::getGenericZeroMaterialPropertyByName(const std::string & prop_name)
     474             : {
     475        9522 :   checkExecutionStage();
     476        9522 :   auto & preload_with_zero = materialData().getProperty<T, is_ad>(prop_name, 0, *this);
     477             : 
     478        9522 :   _requested_props.insert(prop_name);
     479        9522 :   registerPropName(prop_name, true, 0);
     480        9522 :   markMatPropRequested(prop_name);
     481             : 
     482             :   // Register this material on these blocks and boundaries as a zero property with relaxed
     483             :   // consistency checking
     484       19044 :   for (std::set<SubdomainID>::const_iterator it = blockIDs().begin(); it != blockIDs().end(); ++it)
     485        9522 :     storeSubdomainZeroMatProp(*it, prop_name);
     486       19044 :   for (std::set<BoundaryID>::const_iterator it = boundaryIDs().begin(); it != boundaryIDs().end();
     487        9522 :        ++it)
     488        9522 :     storeBoundaryZeroMatProp(*it, prop_name);
     489             : 
     490             :   // set values for all qpoints to zero
     491             :   // (in multiapp scenarios getMaxQps can return different values in each app; we need the max)
     492        9522 :   unsigned int nqp = getMaxQps();
     493        9522 :   if (nqp > preload_with_zero.size())
     494        7500 :     preload_with_zero.resize(nqp);
     495       52734 :   for (unsigned int qp = 0; qp < nqp; ++qp)
     496       43212 :     MathUtils::mooseSetToZero(preload_with_zero[qp]);
     497             : 
     498        9522 :   return preload_with_zero;
     499             : }
     500             : 
     501             : template <typename T, bool is_ad>
     502             : const GenericMaterialProperty<T, is_ad> &
     503         612 : MaterialBase::getGenericZeroMaterialProperty()
     504             : {
     505             :   // static zero property storage
     506         612 :   static GenericMaterialProperty<T, is_ad> zero(MaterialPropertyInterface::zero_property_id);
     507             : 
     508             :   // resize to accomodate maximum number of qpoints
     509             :   // (in multiapp scenarios getMaxQps can return different values in each app; we need the max)
     510         612 :   unsigned int nqp = getMaxQps();
     511         612 :   if (nqp > zero.size())
     512          30 :     zero.resize(nqp);
     513             : 
     514             :   // set values for all qpoints to zero
     515        3060 :   for (unsigned int qp = 0; qp < nqp; ++qp)
     516        2448 :     MathUtils::mooseSetToZero(zero[qp]);
     517             : 
     518         612 :   return zero;
     519             : }
     520             : 
     521             : template <typename T>
     522             : ADMaterialProperty<T> &
     523       11569 : MaterialBase::declareADProperty(const std::string & name)
     524             : {
     525             :   // Check if the supplied parameter is a valid input parameter key
     526       11569 :   std::string prop_name = name;
     527       11569 :   if (_pars.have_parameter<MaterialPropertyName>(name))
     528         434 :     prop_name = _pars.get<MaterialPropertyName>(name);
     529             : 
     530       23138 :   return declareADPropertyByName<T>(prop_name);
     531       11569 : }
     532             : 
     533             : template <typename Consumers>
     534             : std::deque<MaterialBase *>
     535        3487 : MaterialBase::buildRequiredMaterials(const Consumers & mat_consumers,
     536             :                                      const std::vector<std::shared_ptr<MaterialBase>> & mats,
     537             :                                      const bool allow_stateful)
     538             : {
     539        3487 :   std::deque<MaterialBase *> required_mats;
     540             : 
     541        3487 :   std::unordered_set<unsigned int> needed_mat_props;
     542        7494 :   for (const auto & consumer : mat_consumers)
     543             :   {
     544        4007 :     const auto & mp_deps = consumer->getMatPropDependencies();
     545        4007 :     needed_mat_props.insert(mp_deps.begin(), mp_deps.end());
     546             :   }
     547             : 
     548             :   // A predicate of calling this function is that these materials come in already sorted by
     549             :   // dependency with the front of the container having no other material dependencies and following
     550             :   // materials potentially depending on the ones in front of them. So we can start at the back and
     551             :   // iterate forward checking whether the current material supplies anything that is needed, and if
     552             :   // not we discard it
     553       17798 :   for (auto it = mats.rbegin(); it != mats.rend(); ++it)
     554             :   {
     555       14311 :     auto * const mat = it->get();
     556       14311 :     bool supplies_needed = false;
     557             : 
     558       14311 :     const auto & supplied_props = mat->getSuppliedPropIDs();
     559             : 
     560             :     // Do O(N) with the small container
     561       43881 :     for (const auto supplied_prop : supplied_props)
     562             :     {
     563       32539 :       if (needed_mat_props.count(supplied_prop))
     564             :       {
     565        2969 :         supplies_needed = true;
     566        2969 :         break;
     567             :       }
     568             :     }
     569             : 
     570       14311 :     if (!supplies_needed)
     571       11342 :       continue;
     572             : 
     573        2969 :     if (!allow_stateful && mat->hasStatefulProperties())
     574           0 :       ::mooseError(
     575             :           "Someone called buildRequiredMaterials with allow_stateful = false but a material "
     576             :           "dependency ",
     577           0 :           mat->name(),
     578             :           " computes stateful properties.");
     579             : 
     580        2969 :     const auto & mp_deps = mat->getMatPropDependencies();
     581        2969 :     needed_mat_props.insert(mp_deps.begin(), mp_deps.end());
     582        2969 :     required_mats.push_front(mat);
     583             :   }
     584             : 
     585        6974 :   return required_mats;
     586        3487 : }

Generated by: LCOV version 1.14