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 2079061 : Material::validParams() 15 : { 16 : 17 2079061 : InputParameters params = MaterialBase::validParams(); 18 2079061 : params += MaterialPropertyInterface::validParams(); 19 8316244 : MooseEnum const_option("NONE=0 ELEMENT=1 SUBDOMAIN=2", "none"); 20 8316244 : 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 6237183 : params.addParamNamesToGroup("use_displaced_mesh", "Advanced"); 29 4158122 : return params; 30 2079061 : } 31 : 32 37596 : Material::Material(const InputParameters & parameters) 33 : : MaterialBase(parameters), 34 : Coupleable(this, false), 35 : MaterialPropertyInterface(this, blockIDs(), boundaryIDs()), 36 37596 : _bnd(_material_data_type != Moose::BLOCK_MATERIAL_DATA), 37 37596 : _neighbor(_material_data_type == Moose::NEIGHBOR_MATERIAL_DATA), 38 22710 : _q_point(_bnd ? (_neighbor ? _assembly.qPointsFaceNeighbor() : _assembly.qPointsFace()) 39 14886 : : _assembly.qPoints()), 40 37596 : _qrule(_bnd ? (_neighbor ? _assembly.qRuleNeighbor() : _assembly.qRuleFace()) 41 14886 : : _assembly.qRule()), 42 37596 : _JxW(_bnd ? _assembly.JxWFace() : _assembly.JxW()), 43 37596 : _current_elem(_neighbor ? _assembly.neighbor() : _assembly.elem()), 44 37596 : _current_subdomain_id(_neighbor ? _assembly.currentNeighborSubdomainID() 45 26540 : : _assembly.currentSubdomainID()), 46 37596 : _current_side(_neighbor ? _assembly.neighborSide() : _assembly.side()), 47 37596 : _constant_option(computeConstantOption()), 48 75192 : _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 37596 : const std::vector<MooseVariableFieldBase *> & coupled_vars = getCoupledMooseVars(); 56 37596 : bool has_fe_vars = false; 57 37596 : bool has_fv_vars = false; 58 57381 : 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 37596 : 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 37596 : } 84 : 85 : void 86 5027631 : Material::subdomainSetup() 87 : { 88 5027631 : if (_constant_option == ConstantTypeEnum::SUBDOMAIN) 89 : { 90 540166 : auto nqp = _fe_problem.getMaxQps(); 91 : 92 540166 : MaterialProperties & props = materialData().props(); 93 1269495 : for (const auto & prop_id : _supplied_prop_ids) 94 729329 : props[prop_id].resize(nqp); 95 : 96 : // consider all properties are active 97 540166 : _active_prop_ids.clear(); 98 1269495 : for (const auto & id : _supplied_prop_ids) 99 729329 : _active_prop_ids.insert(id); 100 : 101 540166 : _qp = 0; 102 540166 : computeQpProperties(); 103 : 104 1269495 : for (const auto & prop_id : _supplied_prop_ids) 105 5138490 : for (decltype(nqp) qp = 1; qp < nqp; ++qp) 106 4409161 : props[prop_id].qpCopy(qp, props[prop_id], 0); 107 : } 108 5027631 : } 109 : 110 : void 111 29192453 : Material::computeProperties() 112 : { 113 29192453 : if (_constant_option == ConstantTypeEnum::SUBDOMAIN) 114 13573713 : return; 115 : 116 : // Reference to *all* the MaterialProperties in the MaterialData object, not 117 : // just the ones for this Material. 118 15618740 : 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 15618740 : if (_constant_option == ConstantTypeEnum::ELEMENT) 124 : { 125 : // Compute MaterialProperty values at the first qp. 126 3854548 : _qp = 0; 127 3854548 : computeQpProperties(); 128 : 129 : // Now copy the values computed at qp 0 to all the other qps. 130 9060830 : for (const auto & prop_id : _supplied_prop_ids) 131 : { 132 5206282 : auto nqp = _qrule->n_points(); 133 16054374 : for (decltype(nqp) qp = 1; qp < nqp; ++qp) 134 10848092 : props[prop_id].qpCopy(qp, props[prop_id], 0); 135 : } 136 : } 137 : else 138 64936928 : for (_qp = 0; _qp < _qrule->n_points(); ++_qp) 139 53172814 : computeQpProperties(); 140 : } 141 : 142 : Material::ConstantTypeEnum 143 37596 : Material::computeConstantOption() 144 : { 145 75192 : 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 37596 : if (_bnd && co == ConstantTypeEnum::SUBDOMAIN) 151 9911 : co = ConstantTypeEnum::ELEMENT; 152 : 153 37596 : 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 36711 : Material::resolveOptionalProperties() 178 : { 179 37455 : for (auto & proxy : _optional_property_proxies) 180 744 : proxy->resolve(*this); 181 36711 : } 182 : 183 : void 184 8187 : Material::checkMaterialProperty(const std::string & name, const unsigned int state) 185 : { 186 : // Avoid performing duplicate checks for triple block/face/neighbor materials 187 8187 : if (boundaryRestricted() || !_bnd) 188 2833 : MaterialPropertyInterface::checkMaterialProperty(name, state); 189 8187 : }