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 : }