LCOV - code coverage report
Current view: top level - src/materials - Material.C (source / functions) Hit Total Coverage
Test: idaholab/moose framework: 2bf808 Lines: 81 84 96.4 %
Date: 2025-07-17 01:28:37 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     2045458 : Material::validParams()
      15             : {
      16             : 
      17     2045458 :   InputParameters params = MaterialBase::validParams();
      18     2045458 :   params += MaterialPropertyInterface::validParams();
      19     2045458 :   MooseEnum const_option("NONE=0 ELEMENT=1 SUBDOMAIN=2", "none");
      20     2045458 :   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     2045458 :   params.addParamNamesToGroup("use_displaced_mesh", "Advanced");
      29     4090916 :   return params;
      30     2045458 : }
      31             : 
      32       33996 : Material::Material(const InputParameters & parameters)
      33             :   : MaterialBase(parameters),
      34             :     Coupleable(this, false),
      35             :     MaterialPropertyInterface(this, blockIDs(), boundaryIDs()),
      36       33996 :     _bnd(_material_data_type != Moose::BLOCK_MATERIAL_DATA),
      37       33996 :     _neighbor(_material_data_type == Moose::NEIGHBOR_MATERIAL_DATA),
      38       20619 :     _q_point(_bnd ? (_neighbor ? _assembly.qPointsFaceNeighbor() : _assembly.qPointsFace())
      39       13377 :                   : _assembly.qPoints()),
      40       33996 :     _qrule(_bnd ? (_neighbor ? _assembly.qRuleNeighbor() : _assembly.qRuleFace())
      41       13377 :                 : _assembly.qRule()),
      42       33996 :     _JxW(_bnd ? _assembly.JxWFace() : _assembly.JxW()),
      43       33996 :     _current_elem(_neighbor ? _assembly.neighbor() : _assembly.elem()),
      44       33996 :     _current_subdomain_id(_neighbor ? _assembly.currentNeighborSubdomainID()
      45       23971 :                                     : _assembly.currentSubdomainID()),
      46       33996 :     _current_side(_neighbor ? _assembly.neighborSide() : _assembly.side()),
      47       33996 :     _constant_option(computeConstantOption()),
      48       67992 :     _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       33996 :   const std::vector<MooseVariableFieldBase *> & coupled_vars = getCoupledMooseVars();
      56       33996 :   bool has_fe_vars = false;
      57       33996 :   bool has_fv_vars = false;
      58       52407 :   for (auto * const var : coupled_vars)
      59             :   {
      60       18411 :     addMooseVariableDependency(var);
      61       18411 :     if (var->isFV())
      62         156 :       has_fv_vars = true;
      63             :     else
      64             :     {
      65       18255 :       has_fe_vars = true;
      66       18255 :       _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       33996 :   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       33996 : }
      84             : 
      85             : void
      86     4099807 : Material::subdomainSetup()
      87             : {
      88     4099807 :   if (_constant_option == ConstantTypeEnum::SUBDOMAIN)
      89             :   {
      90      410777 :     auto nqp = _fe_problem.getMaxQps();
      91             : 
      92      410777 :     MaterialProperties & props = materialData().props();
      93     1010254 :     for (const auto & prop_id : _supplied_prop_ids)
      94      599477 :       props[prop_id].resize(nqp);
      95             : 
      96             :     // consider all properties are active
      97      410777 :     _active_prop_ids.clear();
      98     1010254 :     for (const auto & id : _supplied_prop_ids)
      99      599477 :       _active_prop_ids.insert(id);
     100             : 
     101      410777 :     _qp = 0;
     102      410777 :     computeQpProperties();
     103             : 
     104     1010254 :     for (const auto & prop_id : _supplied_prop_ids)
     105     4431060 :       for (decltype(nqp) qp = 1; qp < nqp; ++qp)
     106     3831583 :         props[prop_id].qpCopy(qp, props[prop_id], 0);
     107             :   }
     108     4099807 : }
     109             : 
     110             : void
     111    26357136 : Material::computeProperties()
     112             : {
     113    26357136 :   if (_constant_option == ConstantTypeEnum::SUBDOMAIN)
     114    12061668 :     return;
     115             : 
     116             :   // Reference to *all* the MaterialProperties in the MaterialData object, not
     117             :   // just the ones for this Material.
     118    14295468 :   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    14295468 :   if (_constant_option == ConstantTypeEnum::ELEMENT)
     124             :   {
     125             :     // Compute MaterialProperty values at the first qp.
     126     3795168 :     _qp = 0;
     127     3795168 :     computeQpProperties();
     128             : 
     129             :     // Now copy the values computed at qp 0 to all the other qps.
     130     8941968 :     for (const auto & prop_id : _supplied_prop_ids)
     131             :     {
     132     5146800 :       auto nqp = _qrule->n_points();
     133    15903556 :       for (decltype(nqp) qp = 1; qp < nqp; ++qp)
     134    10756756 :         props[prop_id].qpCopy(qp, props[prop_id], 0);
     135             :     }
     136             :   }
     137             :   else
     138    57858918 :     for (_qp = 0; _qp < _qrule->n_points(); ++_qp)
     139    47358685 :       computeQpProperties();
     140             : }
     141             : 
     142             : Material::ConstantTypeEnum
     143       33996 : Material::computeConstantOption()
     144             : {
     145       33996 :   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       33996 :   if (_bnd && co == ConstantTypeEnum::SUBDOMAIN)
     151        8635 :     co = ConstantTypeEnum::ELEMENT;
     152             : 
     153       33996 :   return co;
     154             : }
     155             : 
     156             : MaterialBase &
     157         207 : Material::getMaterialByName(const std::string & name, bool no_warn, bool no_dep)
     158             : {
     159         207 :   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         207 :   MaterialBase & discrete_mat = MaterialPropertyInterface::getMaterialByName(name, no_warn);
     164             : 
     165         195 :   if (!no_dep)
     166             :   {
     167             :     // Insert the materials requested by the discrete material into the host material who
     168             :     // retrieves this discrete material
     169         195 :     const auto & discrete_requested = discrete_mat.getRequestedItems();
     170         195 :     _requested_props.insert(discrete_requested.begin(), discrete_requested.end());
     171             :   }
     172             : 
     173         195 :   return discrete_mat;
     174             : }
     175             : 
     176             : void
     177       33111 : Material::resolveOptionalProperties()
     178             : {
     179       33723 :   for (auto & proxy : _optional_property_proxies)
     180         612 :     proxy->resolve(*this);
     181       33111 : }
     182             : 
     183             : void
     184        7601 : Material::checkMaterialProperty(const std::string & name, const unsigned int state)
     185             : {
     186             :   // Avoid performing duplicate checks for triple block/face/neighbor materials
     187        7601 :   if (boundaryRestricted() || !_bnd)
     188        2633 :     MaterialPropertyInterface::checkMaterialProperty(name, state);
     189        7601 : }

Generated by: LCOV version 1.14