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 : #include "ADVolumeJunctionBaseUserObject.h" 11 : #include "MooseVariableScalar.h" 12 : #include "FEProblemBase.h" 13 : #include "metaphysicl/parallel_numberarray.h" 14 : #include "metaphysicl/parallel_dualnumber.h" 15 : #include "metaphysicl/parallel_semidynamicsparsenumberarray.h" 16 : #include "libmesh/parallel_algebra.h" 17 : 18 : InputParameters 19 2372 : ADVolumeJunctionBaseUserObject::validParams() 20 : { 21 2372 : InputParameters params = ADFlowJunctionUserObject::validParams(); 22 : 23 4744 : params.addParam<bool>( 24 4744 : "use_scalar_variables", true, "True if the junction variables are scalar variables"); 25 4744 : params.addParam<subdomain_id_type>( 26 : "junction_subdomain_id", 27 : libMesh::invalid_uint, 28 : "Junction subdomain ID (required if 'use_scalar_variables' is 'false')"); 29 : 30 4744 : params.addRequiredParam<Real>("volume", "Volume of the junction"); 31 4744 : params.addRequiredParam<std::vector<UserObjectName>>( 32 : "numerical_flux_names", 33 : "The names of the user objects that compute the numerical flux at each flow channel."); 34 2372 : params.addClassDescription("User object to compute fluxes and residuals for a volume junction"); 35 2372 : return params; 36 0 : } 37 : 38 1298 : ADVolumeJunctionBaseUserObject::ADVolumeJunctionBaseUserObject(const InputParameters & params) 39 : : ADFlowJunctionUserObject(params), 40 1298 : _use_scalar_variables(getParam<bool>("use_scalar_variables")), 41 2596 : _junction_subdomain_id(getParam<subdomain_id_type>("junction_subdomain_id")), 42 2596 : _volume(getParam<Real>("volume")), 43 3894 : _numerical_flux_names(getParam<std::vector<UserObjectName>>("numerical_flux_names")) 44 : { 45 1298 : if (_numerical_flux_names.size() != _n_connections) 46 0 : mooseError(name(), 47 : ": The number of supplied numerical flux objects '", 48 0 : _numerical_flux_names.size(), 49 : "' does not match the number of connections '", 50 0 : _n_connections, 51 : "'."); 52 : 53 5192 : if (!_use_scalar_variables && !isParamSetByUser("junction_subdomain_id")) 54 0 : mooseError("If 'use_scalar_variables' is set to false, 'junction_subdomain_id' is required."); 55 1298 : } 56 : 57 : void 58 1221 : ADVolumeJunctionBaseUserObject::initialSetup() 59 : { 60 1221 : _n_flux_eq = _flow_variable_names.size(); 61 1221 : _n_scalar_eq = _scalar_variable_names.size(); 62 : 63 1221 : _scalar_dofs.resize(_n_scalar_eq); 64 1221 : _cached_junction_var_values.resize(_n_scalar_eq); 65 1221 : _flow_channel_dofs.resize(_n_connections); 66 1221 : _residual.resize(_n_scalar_eq); 67 1221 : } 68 : 69 : void 70 108906 : ADVolumeJunctionBaseUserObject::initialize() 71 : { 72 217812 : _flux.assign(_n_connections, std::vector<ADReal>(_n_flux_eq, 0.0)); 73 653436 : for (auto & i : _residual) 74 : { 75 544530 : i.value() = 0; 76 544530 : i.derivatives() = DNDerivativeType(); 77 : } 78 : _connection_indices.clear(); 79 : 80 108906 : auto junction_vars = getJunctionVariables(); 81 : 82 : // Cache the junction variable values and get their dof indices 83 108906 : if (!_use_scalar_variables) 84 : { 85 653436 : for (unsigned int i = 0; i < _n_scalar_eq; i++) 86 : { 87 544530 : _cached_junction_var_values[i] = 0; 88 544530 : _scalar_dofs[i] = 0; 89 : } 90 : 91 4775506 : for (const Elem * elem : *_mesh.getActiveLocalElementRange()) 92 : { 93 4666600 : if (elem->subdomain_id() == _junction_subdomain_id) 94 : { 95 : // Reinitialize the element 96 75479 : _fe_problem.setCurrentSubdomainID(elem, _tid); 97 75479 : _fe_problem.prepare(elem, _tid); 98 75479 : _fe_problem.reinitElem(elem, _tid); 99 : 100 : // Cache the junction variable values and Dof indices 101 452874 : for (unsigned int i = 0; i < _n_scalar_eq; i++) 102 : { 103 377395 : _cached_junction_var_values[i] = (*_junction_var_values[i])[0]; 104 : 105 377395 : auto && dofs = junction_vars[i]->dofIndices(); 106 : mooseAssert(dofs.size() == 1, 107 : "There should be exactly 1 coupled DoF index for the variable '" + 108 : junction_vars[i]->name() + "'."); 109 377395 : _scalar_dofs[i] = dofs[0]; 110 : } 111 : } 112 : } 113 : 114 108906 : comm().sum(_cached_junction_var_values); 115 108906 : comm().sum(_scalar_dofs); 116 : } 117 : else 118 : { 119 0 : for (unsigned int i = 0; i < _junction_var_values.size(); i++) 120 0 : _cached_junction_var_values[i] = (*_junction_var_values[i])[0]; 121 : 122 0 : for (unsigned int i = 0; i < _n_scalar_eq; i++) 123 : { 124 0 : auto && dofs = junction_vars[i]->dofIndices(); 125 : mooseAssert(dofs.size() == 1, 126 : "There should be exactly 1 coupled DoF index for the variable '" + 127 : junction_vars[i]->name() + "'."); 128 0 : _scalar_dofs[i] = dofs[0]; 129 : } 130 : } 131 108906 : } 132 : 133 : void 134 136247 : ADVolumeJunctionBaseUserObject::storeConnectionData() 135 : { 136 : // Get the connection index 137 136247 : const unsigned int c = getBoundaryIDIndex(); 138 136247 : _connection_indices.push_back(c); 139 : 140 : // Get flow channel Dofs and basic function values 141 136247 : _flow_channel_dofs[c].clear(); 142 544988 : for (unsigned int j = 0; j < _n_flux_eq; j++) 143 : { 144 408741 : MooseVariable * var = getVar(_flow_variable_names[j], 0); 145 : 146 : auto && dofs = var->dofIndices(); 147 817482 : for (unsigned int k = 0; k < dofs.size(); k++) 148 408741 : _flow_channel_dofs[c].push_back(dofs[k]); 149 : } 150 136247 : } 151 : 152 : void 153 110319 : ADVolumeJunctionBaseUserObject::execute() 154 : { 155 110319 : storeConnectionData(); 156 : 157 110319 : const unsigned int c = getBoundaryIDIndex(); 158 110319 : computeFluxesAndResiduals(c); 159 110317 : } 160 : 161 : void 162 21434 : ADVolumeJunctionBaseUserObject::threadJoin(const UserObject & uo) 163 : { 164 : const auto & volume_junction_uo = static_cast<const ADVolumeJunctionBaseUserObject &>(uo); 165 : 166 : // Store the data computed/retrieved in the other threads 167 36637 : for (unsigned int i = 0; i < volume_junction_uo._connection_indices.size(); i++) 168 : { 169 15203 : const unsigned int c = volume_junction_uo._connection_indices[i]; 170 : 171 15203 : _flux[c] = volume_junction_uo._flux[c]; 172 15203 : _flow_channel_dofs[c] = volume_junction_uo._flow_channel_dofs[c]; 173 : } 174 : 175 : // Add the scalar residuals from the other threads 176 128604 : for (unsigned int i = 0; i < _n_scalar_eq; i++) 177 107170 : _residual[i] += volume_junction_uo._residual[i]; 178 21434 : } 179 : 180 : const std::vector<ADReal> & 181 298205 : ADVolumeJunctionBaseUserObject::getResidual() const 182 : { 183 : Threads::spin_mutex::scoped_lock lock(Threads::spin_mtx); 184 : 185 298205 : return _residual; 186 : } 187 : 188 : const std::vector<ADReal> & 189 407005 : ADVolumeJunctionBaseUserObject::getFlux(const unsigned int & connection_index) const 190 : { 191 : Threads::spin_mutex::scoped_lock lock(Threads::spin_mtx); 192 : 193 407005 : checkValidConnectionIndex(connection_index); 194 407005 : return _flux[connection_index]; 195 : } 196 : 197 : std::vector<const MooseVariableBase *> 198 108906 : ADVolumeJunctionBaseUserObject::getJunctionVariables() const 199 : { 200 108906 : std::vector<const MooseVariableBase *> vars(_scalar_variable_names.size()); 201 653436 : for (unsigned int i = 0; i < _scalar_variable_names.size(); i++) 202 544530 : vars[i] = getJunctionVar(_scalar_variable_names[i], 0); 203 108906 : return vars; 204 : } 205 : 206 : const MooseVariableBase * 207 544530 : ADVolumeJunctionBaseUserObject::getJunctionVar(const std::string & var_name, unsigned int i) const 208 : { 209 : const MooseVariableBase * var; 210 544530 : if (_use_scalar_variables) 211 0 : var = getScalarVar(var_name, i); 212 : else 213 544530 : var = getVar(var_name, i); 214 544530 : return var; 215 : } 216 : 217 : const ADVariableValue & 218 6490 : ADVolumeJunctionBaseUserObject::coupledJunctionValue(const std::string & var_name, 219 : unsigned int i) const 220 : { 221 6490 : return _use_scalar_variables ? adCoupledScalarValue(var_name, i) : adCoupledValue(var_name, i); 222 : }