LCOV - code coverage report
Current view: top level - src/materials - Material.C (source / functions) Hit Total Coverage
Test: idaholab/moose framework: 419b9d Lines: 81 84 96.4 %
Date: 2025-08-08 20:01:16 Functions: 8 8 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : //* This file is part of the MOOSE framework
       2             : //* https://mooseframework.inl.gov
       3             : //*
       4             : //* All rights reserved, see COPYRIGHT for full restrictions
       5             : //* https://github.com/idaholab/moose/blob/master/COPYRIGHT
       6             : //*
       7             : //* Licensed under LGPL 2.1, please see LICENSE for details
       8             : //* https://www.gnu.org/licenses/lgpl-2.1.html
       9             : 
      10             : // MOOSE includes
      11             : #include "Material.h"
      12             : 
      13             : InputParameters
      14     2048664 : Material::validParams()
      15             : {
      16             : 
      17     2048664 :   InputParameters params = MaterialBase::validParams();
      18     2048664 :   params += MaterialPropertyInterface::validParams();
      19     2048664 :   MooseEnum const_option("NONE=0 ELEMENT=1 SUBDOMAIN=2", "none");
      20     2048664 :   params.addParam<MooseEnum>(
      21             :       "constant_on",
      22             :       const_option,
      23             :       "When ELEMENT, MOOSE will only call computeQpProperties() for the 0th "
      24             :       "quadrature point, and then copy that value to the other qps."
      25             :       "When SUBDOMAIN, MOOSE will only call computeQpProperties() for the 0th "
      26             :       "quadrature point, and then copy that value to the other qps. Evaluations on element qps "
      27             :       "will be skipped");
      28     2048664 :   params.addParamNamesToGroup("use_displaced_mesh", "Advanced");
      29     4097328 :   return params;
      30     2048664 : }
      31             : 
      32       36228 : Material::Material(const InputParameters & parameters)
      33             :   : MaterialBase(parameters),
      34             :     Coupleable(this, false),
      35             :     MaterialPropertyInterface(this, blockIDs(), boundaryIDs()),
      36       36228 :     _bnd(_material_data_type != Moose::BLOCK_MATERIAL_DATA),
      37       36228 :     _neighbor(_material_data_type == Moose::NEIGHBOR_MATERIAL_DATA),
      38       21894 :     _q_point(_bnd ? (_neighbor ? _assembly.qPointsFaceNeighbor() : _assembly.qPointsFace())
      39       14334 :                   : _assembly.qPoints()),
      40       36228 :     _qrule(_bnd ? (_neighbor ? _assembly.qRuleNeighbor() : _assembly.qRuleFace())
      41       14334 :                 : _assembly.qRule()),
      42       36228 :     _JxW(_bnd ? _assembly.JxWFace() : _assembly.JxW()),
      43       36228 :     _current_elem(_neighbor ? _assembly.neighbor() : _assembly.elem()),
      44       36228 :     _current_subdomain_id(_neighbor ? _assembly.currentNeighborSubdomainID()
      45       25580 :                                     : _assembly.currentSubdomainID()),
      46       36228 :     _current_side(_neighbor ? _assembly.neighborSide() : _assembly.side()),
      47       36228 :     _constant_option(computeConstantOption()),
      48       72456 :     _ghostable(true)
      49             : {
      50             :   // 1. Fill in the MooseVariable dependencies
      51             :   // 2. For ghost calculations we need to check and see whether this has any finite element
      52             :   // variables. If it does, then this material doesn't support ghost calculations
      53             :   // 3. For the purpose of ghost calculations, we will error if this material couples in both finite
      54             :   // element and finite volume variables.
      55       36228 :   const std::vector<MooseVariableFieldBase *> & coupled_vars = getCoupledMooseVars();
      56       36228 :   bool has_fe_vars = false;
      57       36228 :   bool has_fv_vars = false;
      58       56013 :   for (auto * const var : coupled_vars)
      59             :   {
      60       19785 :     addMooseVariableDependency(var);
      61       19785 :     if (var->isFV())
      62         168 :       has_fv_vars = true;
      63             :     else
      64             :     {
      65       19617 :       has_fe_vars = true;
      66       19617 :       _ghostable = false;
      67             :     }
      68             :   }
      69             : 
      70             :   // Note that this check will not catch a case in which a finite volume consumer needs a
      71             :   // non-variable-based property ghosted, but that non-variable-based property is computed within a
      72             :   // material that has finite element coupling (but not finite volume coupling)
      73       36228 :   if (has_fe_vars && has_fv_vars)
      74           0 :     mooseError(
      75             :         "Your material ",
      76           0 :         this->name(),
      77             :         " couples in both FE and FV vars. To support ghost calculations which some FV "
      78             :         "consumers may need, multiphysics simulations should define separate materials for "
      79             :         "coupling in finite element and finite volume variables because we do not have a user "
      80             :         "friendly way of running DerivedMaterial::computeQpProperties and saying 'compute this "
      81             :         "property because it doesn't depend on finite element variables' or 'don't compute this "
      82             :         "property because it *does* depend on finite element variables'");
      83       36228 : }
      84             : 
      85             : void
      86     4493199 : Material::subdomainSetup()
      87             : {
      88     4493199 :   if (_constant_option == ConstantTypeEnum::SUBDOMAIN)
      89             :   {
      90      442652 :     auto nqp = _fe_problem.getMaxQps();
      91             : 
      92      442652 :     MaterialProperties & props = materialData().props();
      93     1074467 :     for (const auto & prop_id : _supplied_prop_ids)
      94      631815 :       props[prop_id].resize(nqp);
      95             : 
      96             :     // consider all properties are active
      97      442652 :     _active_prop_ids.clear();
      98     1074467 :     for (const auto & id : _supplied_prop_ids)
      99      631815 :       _active_prop_ids.insert(id);
     100             : 
     101      442652 :     _qp = 0;
     102      442652 :     computeQpProperties();
     103             : 
     104     1074467 :     for (const auto & prop_id : _supplied_prop_ids)
     105     4591644 :       for (decltype(nqp) qp = 1; qp < nqp; ++qp)
     106     3959829 :         props[prop_id].qpCopy(qp, props[prop_id], 0);
     107             :   }
     108     4493199 : }
     109             : 
     110             : void
     111    28876798 : Material::computeProperties()
     112             : {
     113    28876798 :   if (_constant_option == ConstantTypeEnum::SUBDOMAIN)
     114    13265493 :     return;
     115             : 
     116             :   // Reference to *all* the MaterialProperties in the MaterialData object, not
     117             :   // just the ones for this Material.
     118    15611305 :   MaterialProperties & props = _material_data.props();
     119             : 
     120             :   // If this Material ist set to be constant over elements, we take the
     121             :   // value computed for _qp == 0 and use it at all the quadrature points
     122             :   // in the element.
     123    15611305 :   if (_constant_option == ConstantTypeEnum::ELEMENT)
     124             :   {
     125             :     // Compute MaterialProperty values at the first qp.
     126     3847339 :     _qp = 0;
     127     3847339 :     computeQpProperties();
     128             : 
     129             :     // Now copy the values computed at qp 0 to all the other qps.
     130     9046412 :     for (const auto & prop_id : _supplied_prop_ids)
     131             :     {
     132     5199073 :       auto nqp = _qrule->n_points();
     133    16040172 :       for (decltype(nqp) qp = 1; qp < nqp; ++qp)
     134    10841099 :         props[prop_id].qpCopy(qp, props[prop_id], 0);
     135             :     }
     136             :   }
     137             :   else
     138    64935878 :     for (_qp = 0; _qp < _qrule->n_points(); ++_qp)
     139    53171982 :       computeQpProperties();
     140             : }
     141             : 
     142             : Material::ConstantTypeEnum
     143       36228 : Material::computeConstantOption()
     144             : {
     145       36228 :   auto co = getParam<MooseEnum>("constant_on").getEnum<ConstantTypeEnum>();
     146             : 
     147             :   // If the material is operating on a boundary we'll have to _at least_ run it
     148             :   // once per element, as there is no boundarySetup, and boundaries are worked
     149             :   // on as they are encountered on the elements while looping elements.
     150       36228 :   if (_bnd && co == ConstantTypeEnum::SUBDOMAIN)
     151        9143 :     co = ConstantTypeEnum::ELEMENT;
     152             : 
     153       36228 :   return co;
     154             : }
     155             : 
     156             : MaterialBase &
     157         222 : Material::getMaterialByName(const std::string & name, bool no_warn, bool no_dep)
     158             : {
     159         222 :   if (!no_dep && _mi_feproblem.getCurrentExecuteOnFlag() != EXEC_INITIAL)
     160           0 :     mooseError("To ensure dependency resolution, discrete materials must be retrieved during "
     161             :                "initial setup. This is a code problem.");
     162             : 
     163         222 :   MaterialBase & discrete_mat = MaterialPropertyInterface::getMaterialByName(name, no_warn);
     164             : 
     165         210 :   if (!no_dep)
     166             :   {
     167             :     // Insert the materials requested by the discrete material into the host material who
     168             :     // retrieves this discrete material
     169         210 :     const auto & discrete_requested = discrete_mat.getRequestedItems();
     170         210 :     _requested_props.insert(discrete_requested.begin(), discrete_requested.end());
     171             :   }
     172             : 
     173         210 :   return discrete_mat;
     174             : }
     175             : 
     176             : void
     177       35343 : Material::resolveOptionalProperties()
     178             : {
     179       35991 :   for (auto & proxy : _optional_property_proxies)
     180         648 :     proxy->resolve(*this);
     181       35343 : }
     182             : 
     183             : void
     184        8115 : Material::checkMaterialProperty(const std::string & name, const unsigned int state)
     185             : {
     186             :   // Avoid performing duplicate checks for triple block/face/neighbor materials
     187        8115 :   if (boundaryRestricted() || !_bnd)
     188        2809 :     MaterialPropertyInterface::checkMaterialProperty(name, state);
     189        8115 : }

Generated by: LCOV version 1.14