LCOV - code coverage report
Current view: top level - src/materials - Material.C (source / functions) Hit Total Coverage
Test: idaholab/moose framework: #32971 (54bef8) with base c6cf66 Lines: 80 84 95.2 %
Date: 2026-05-29 20:35:17 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      498257 : Material::validParams()
      15             : {
      16             : 
      17      498257 :   InputParameters params = MaterialBase::validParams();
      18      498257 :   params += MaterialPropertyInterface::validParams();
      19     1494771 :   params.addParam<MooseEnum>(
      20             :       "constant_on",
      21     1494771 :       MooseEnum(getConstantTypeEnumOptions(), "none"),
      22             :       "When ELEMENT, MOOSE will only call computeQpProperties() for the 0th "
      23             :       "quadrature point, and then copy that value to the other qps."
      24             :       "When SUBDOMAIN, MOOSE will only call computeQpProperties() for the 0th "
      25             :       "quadrature point, and then copy that value to the other qps. Evaluations on element qps "
      26             :       "will be skipped");
      27     1494771 :   params.addParamNamesToGroup("use_displaced_mesh", "Advanced");
      28      498257 :   return params;
      29           0 : }
      30             : 
      31       35401 : Material::Material(const InputParameters & parameters)
      32             :   : MaterialBase(parameters),
      33             :     Coupleable(this, false),
      34             :     MaterialPropertyInterface(this, blockIDs(), boundaryIDs()),
      35       35401 :     _bnd(_material_data_type != Moose::BLOCK_MATERIAL_DATA),
      36       35401 :     _neighbor(_material_data_type == Moose::NEIGHBOR_MATERIAL_DATA),
      37       21643 :     _q_point(_bnd ? (_neighbor ? _assembly.qPointsFaceNeighbor() : _assembly.qPointsFace())
      38       13758 :                   : _assembly.qPoints()),
      39       35401 :     _qrule(_bnd ? (_neighbor ? _assembly.qRuleNeighbor() : _assembly.qRuleFace())
      40       13758 :                 : _assembly.qRule()),
      41       35401 :     _JxW(_bnd ? _assembly.JxWFace() : _assembly.JxW()),
      42       35401 :     _current_elem(_neighbor ? _assembly.neighbor() : _assembly.elem()),
      43       35401 :     _current_subdomain_id(_neighbor ? _assembly.currentNeighborSubdomainID()
      44       24842 :                                     : _assembly.currentSubdomainID()),
      45       35401 :     _current_side(_neighbor ? _assembly.neighborSide() : _assembly.side()),
      46       35401 :     _constant_option(computeConstantOption()),
      47       70802 :     _ghostable(true)
      48             : {
      49             :   // 1. Fill in the MooseVariable dependencies
      50             :   // 2. For ghost calculations we need to check and see whether this has any finite element
      51             :   // variables. If it does, then this material doesn't support ghost calculations
      52             :   // 3. For the purpose of ghost calculations, we will error if this material couples in both finite
      53             :   // element and finite volume variables.
      54       35401 :   const std::vector<MooseVariableFieldBase *> & coupled_vars = getCoupledMooseVars();
      55       35401 :   bool has_fe_vars = false;
      56       35401 :   bool has_fv_vars = false;
      57       54257 :   for (auto * const var : coupled_vars)
      58             :   {
      59       18856 :     addMooseVariableDependency(var);
      60       18856 :     if (var->isFV())
      61         156 :       has_fv_vars = true;
      62             :     else
      63             :     {
      64       18700 :       has_fe_vars = true;
      65       18700 :       _ghostable = false;
      66             :     }
      67             :   }
      68             : 
      69             :   // Note that this check will not catch a case in which a finite volume consumer needs a
      70             :   // non-variable-based property ghosted, but that non-variable-based property is computed within a
      71             :   // material that has finite element coupling (but not finite volume coupling)
      72       35401 :   if (has_fe_vars && has_fv_vars)
      73           0 :     mooseError(
      74             :         "Your material ",
      75           0 :         this->name(),
      76             :         " couples in both FE and FV vars. To support ghost calculations which some FV "
      77             :         "consumers may need, multiphysics simulations should define separate materials for "
      78             :         "coupling in finite element and finite volume variables because we do not have a user "
      79             :         "friendly way of running DerivedMaterial::computeQpProperties and saying 'compute this "
      80             :         "property because it doesn't depend on finite element variables' or 'don't compute this "
      81             :         "property because it *does* depend on finite element variables'");
      82       35401 : }
      83             : 
      84             : void
      85     4555743 : Material::subdomainSetup()
      86             : {
      87     4555743 :   if (_constant_option == ConstantTypeEnum::SUBDOMAIN)
      88             :   {
      89      498496 :     auto nqp = _fe_problem.getMaxQps();
      90             : 
      91      498496 :     MaterialProperties & props = materialData().props();
      92     1158960 :     for (const auto & prop_id : _supplied_prop_ids)
      93      660464 :       props[prop_id].resize(nqp);
      94             : 
      95             :     // consider all properties are active
      96      498496 :     _active_prop_ids.clear();
      97     1158960 :     for (const auto & id : _supplied_prop_ids)
      98      660464 :       _active_prop_ids.insert(id);
      99             : 
     100      498496 :     _qp = 0;
     101      498496 :     computeQpProperties();
     102             : 
     103     1158960 :     for (const auto & prop_id : _supplied_prop_ids)
     104     4377091 :       for (decltype(nqp) qp = 1; qp < nqp; ++qp)
     105     3716627 :         props[prop_id].qpCopy(qp, props[prop_id], 0);
     106             :   }
     107     4555743 : }
     108             : 
     109             : void
     110    22788049 : Material::computeProperties()
     111             : {
     112    22788049 :   if (_constant_option == ConstantTypeEnum::SUBDOMAIN)
     113    10757385 :     return;
     114             : 
     115             :   // Reference to *all* the MaterialProperties in the MaterialData object, not
     116             :   // just the ones for this Material.
     117    12030664 :   MaterialProperties & props = _material_data.props();
     118             : 
     119             :   // If this Material ist set to be constant over elements, we take the
     120             :   // value computed for _qp == 0 and use it at all the quadrature points
     121             :   // in the element.
     122    12030664 :   if (_constant_option == ConstantTypeEnum::ELEMENT)
     123             :   {
     124             :     // Compute MaterialProperty values at the first qp.
     125     1568374 :     _qp = 0;
     126     1568374 :     computeQpProperties();
     127             : 
     128             :     // Now copy the values computed at qp 0 to all the other qps.
     129     4167506 :     for (const auto & prop_id : _supplied_prop_ids)
     130             :     {
     131     2599132 :       auto nqp = _qrule->n_points();
     132     9513472 :       for (decltype(nqp) qp = 1; qp < nqp; ++qp)
     133     6914340 :         props[prop_id].qpCopy(qp, props[prop_id], 0);
     134             :     }
     135             :   }
     136             :   else
     137    53665067 :     for (_qp = 0; _qp < _qrule->n_points(); ++_qp)
     138    43202833 :       computeQpProperties();
     139             : }
     140             : 
     141             : Material::ConstantTypeEnum
     142       35401 : Material::computeConstantOption()
     143             : {
     144       70802 :   auto co = getParam<MooseEnum>("constant_on").getEnum<ConstantTypeEnum>();
     145             : 
     146             :   // If the material is operating on a boundary we'll have to _at least_ run it
     147             :   // once per element, as there is no boundarySetup, and boundaries are worked
     148             :   // on as they are encountered on the elements while looping elements.
     149       35401 :   if (_bnd && co == ConstantTypeEnum::SUBDOMAIN)
     150        9371 :     co = ConstantTypeEnum::ELEMENT;
     151             : 
     152       35401 :   return co;
     153             : }
     154             : 
     155             : MaterialBase &
     156         204 : Material::getMaterialByName(const std::string & name, bool no_warn, bool no_dep)
     157             : {
     158         204 :   if (!no_dep && _mi_feproblem.getCurrentExecuteOnFlag() != EXEC_INITIAL)
     159           0 :     mooseError("To ensure dependency resolution, discrete materials must be retrieved during "
     160             :                "initial setup. This is a code problem.");
     161             : 
     162         204 :   MaterialBase & discrete_mat = MaterialPropertyInterface::getMaterialByName(name, no_warn);
     163             : 
     164         195 :   if (!no_dep)
     165             :   {
     166             :     // Insert the materials requested by the discrete material into the host material who
     167             :     // retrieves this discrete material
     168         195 :     const auto & discrete_requested = discrete_mat.getRequestedItems();
     169         195 :     _requested_props.insert(discrete_requested.begin(), discrete_requested.end());
     170             :   }
     171             : 
     172         195 :   return discrete_mat;
     173             : }
     174             : 
     175             : void
     176       34661 : Material::resolveOptionalProperties()
     177             : {
     178       35321 :   for (auto & proxy : _optional_property_proxies)
     179         660 :     proxy->resolve(*this);
     180       34661 : }
     181             : 
     182             : void
     183        7582 : Material::checkMaterialProperty(const std::string & name, const unsigned int state)
     184             : {
     185             :   // Avoid performing duplicate checks for triple block/face/neighbor materials
     186        7582 :   if (boundaryRestricted() || !_bnd)
     187        2612 :     MaterialPropertyInterface::checkMaterialProperty(name, state);
     188        7582 : }

Generated by: LCOV version 1.14