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