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 2225320 : Material::validParams() 15 : { 16 : 17 2225320 : InputParameters params = MaterialBase::validParams(); 18 2225320 : params += MaterialPropertyInterface::validParams(); 19 8901280 : MooseEnum const_option("NONE=0 ELEMENT=1 SUBDOMAIN=2", "none"); 20 8901280 : 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 6675960 : params.addParamNamesToGroup("use_displaced_mesh", "Advanced"); 29 4450640 : return params; 30 2225320 : } 31 : 32 38685 : Material::Material(const InputParameters & parameters) 33 : : MaterialBase(parameters), 34 : Coupleable(this, false), 35 : MaterialPropertyInterface(this, blockIDs(), boundaryIDs()), 36 38685 : _bnd(_material_data_type != Moose::BLOCK_MATERIAL_DATA), 37 38685 : _neighbor(_material_data_type == Moose::NEIGHBOR_MATERIAL_DATA), 38 23436 : _q_point(_bnd ? (_neighbor ? _assembly.qPointsFaceNeighbor() : _assembly.qPointsFace()) 39 15249 : : _assembly.qPoints()), 40 38685 : _qrule(_bnd ? (_neighbor ? _assembly.qRuleNeighbor() : _assembly.qRuleFace()) 41 15249 : : _assembly.qRule()), 42 38685 : _JxW(_bnd ? _assembly.JxWFace() : _assembly.JxW()), 43 38685 : _current_elem(_neighbor ? _assembly.neighbor() : _assembly.elem()), 44 38685 : _current_subdomain_id(_neighbor ? _assembly.currentNeighborSubdomainID() 45 27266 : : _assembly.currentSubdomainID()), 46 38685 : _current_side(_neighbor ? _assembly.neighborSide() : _assembly.side()), 47 38685 : _constant_option(computeConstantOption()), 48 77370 : _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 38685 : const std::vector<MooseVariableFieldBase *> & coupled_vars = getCoupledMooseVars(); 56 38685 : bool has_fe_vars = false; 57 38685 : bool has_fv_vars = false; 58 58722 : for (auto * const var : coupled_vars) 59 : { 60 20037 : addMooseVariableDependency(var); 61 20037 : if (var->isFV()) 62 168 : has_fv_vars = true; 63 : else 64 : { 65 19869 : has_fe_vars = true; 66 19869 : _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 38685 : 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 38685 : } 84 : 85 : void 86 5134856 : Material::subdomainSetup() 87 : { 88 5134856 : if (_constant_option == ConstantTypeEnum::SUBDOMAIN) 89 : { 90 554532 : auto nqp = _fe_problem.getMaxQps(); 91 : 92 554532 : MaterialProperties & props = materialData().props(); 93 1298283 : for (const auto & prop_id : _supplied_prop_ids) 94 743751 : props[prop_id].resize(nqp); 95 : 96 : // consider all properties are active 97 554532 : _active_prop_ids.clear(); 98 1298283 : for (const auto & id : _supplied_prop_ids) 99 743751 : _active_prop_ids.insert(id); 100 : 101 554532 : _qp = 0; 102 554532 : computeQpProperties(); 103 : 104 1298283 : for (const auto & prop_id : _supplied_prop_ids) 105 5167652 : for (decltype(nqp) qp = 1; qp < nqp; ++qp) 106 4423901 : props[prop_id].qpCopy(qp, props[prop_id], 0); 107 : } 108 5134856 : } 109 : 110 : void 111 32936162 : Material::computeProperties() 112 : { 113 32936162 : if (_constant_option == ConstantTypeEnum::SUBDOMAIN) 114 14798529 : return; 115 : 116 : // Reference to *all* the MaterialProperties in the MaterialData object, not 117 : // just the ones for this Material. 118 18137633 : 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 18137633 : if (_constant_option == ConstantTypeEnum::ELEMENT) 124 : { 125 : // Compute MaterialProperty values at the first qp. 126 3629416 : _qp = 0; 127 3629416 : computeQpProperties(); 128 : 129 : // Now copy the values computed at qp 0 to all the other qps. 130 8610566 : for (const auto & prop_id : _supplied_prop_ids) 131 : { 132 4981150 : auto nqp = _qrule->n_points(); 133 15580780 : for (decltype(nqp) qp = 1; qp < nqp; ++qp) 134 10599630 : props[prop_id].qpCopy(qp, props[prop_id], 0); 135 : } 136 : } 137 : else 138 74014198 : for (_qp = 0; _qp < _qrule->n_points(); ++_qp) 139 59506059 : computeQpProperties(); 140 : } 141 : 142 : Material::ConstantTypeEnum 143 38685 : Material::computeConstantOption() 144 : { 145 77370 : 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 38685 : if (_bnd && co == ConstantTypeEnum::SUBDOMAIN) 151 10277 : co = ConstantTypeEnum::ELEMENT; 152 : 153 38685 : 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 37770 : Material::resolveOptionalProperties() 178 : { 179 38514 : for (auto & proxy : _optional_property_proxies) 180 744 : proxy->resolve(*this); 181 37770 : } 182 : 183 : void 184 8397 : Material::checkMaterialProperty(const std::string & name, const unsigned int state) 185 : { 186 : // Avoid performing duplicate checks for triple block/face/neighbor materials 187 8397 : if (boundaryRestricted() || !_bnd) 188 2903 : MaterialPropertyInterface::checkMaterialProperty(name, state); 189 8397 : }