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