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 "WCNSLinearFVScalarTransportPhysics.h" 11 : #include "WCNSFVFlowPhysicsBase.h" 12 : #include "NSFVUtils.h" 13 : #include "NS.h" 14 : 15 : registerNavierStokesPhysicsBaseTasks("NavierStokesApp", WCNSLinearFVScalarTransportPhysics); 16 : registerWCNSFVScalarTransportBaseTasks("NavierStokesApp", WCNSLinearFVScalarTransportPhysics); 17 : registerMooseAction("NavierStokesApp", 18 : WCNSLinearFVScalarTransportPhysics, 19 : "add_interpolation_method_physics"); 20 : 21 : InputParameters 22 67 : WCNSLinearFVScalarTransportPhysics::validParams() 23 : { 24 67 : InputParameters params = WCNSFVScalarTransportPhysicsBase::validParams(); 25 67 : params.addClassDescription("Define the Navier Stokes weakly-compressible scalar field transport " 26 : "equation(s) using the linear finite volume discretization"); 27 67 : params.set<MooseEnum>("passive_scalar_advection_interpolation") = 28 201 : NS::fvAdvectedInterpolationMethods(); 29 134 : params.addParam<InterpolationMethodName>( 30 : "passive_scalar_advection_interpolation_method_name", 31 : "Name of an externally defined FVInterpolationMethod to use for passive scalar advection. " 32 : "When provided, this overrides 'passive_scalar_advection_interpolation'."); 33 134 : params.addParam<bool>("use_nonorthogonal_correction", 34 134 : true, 35 : "If the nonorthogonal correction should be used when computing the normal " 36 : "gradient, notably in the diffusion term."); 37 : 38 : // Not supported 39 67 : params.suppressParameter<MooseEnum>("preconditioning"); 40 : 41 134 : params.addParamNamesToGroup("passive_scalar_advection_interpolation_method_name", 42 : "Numerical scheme"); 43 : 44 67 : return params; 45 0 : } 46 : 47 67 : WCNSLinearFVScalarTransportPhysics::WCNSLinearFVScalarTransportPhysics( 48 67 : const InputParameters & parameters) 49 67 : : WCNSFVScalarTransportPhysicsBase(parameters) 50 : { 51 67 : addRequiredPhysicsTask("add_interpolation_method_physics"); 52 : 53 67 : if (_porous_medium_treatment) 54 0 : _flow_equations_physics->paramError("porous_medium_treatment", 55 : "Porous media scalar advection is currently unimplemented"); 56 67 : } 57 : 58 : void 59 67 : WCNSLinearFVScalarTransportPhysics::addFVInterpolationMethods() 60 : { 61 201 : if (!_has_scalar_equation || isParamValid("passive_scalar_advection_interpolation_method_name")) 62 : return; 63 : 64 183 : addFVAdvectedInterpolationMethod(getParam<MooseEnum>("passive_scalar_advection_interpolation")); 65 : } 66 : 67 : void 68 67 : WCNSLinearFVScalarTransportPhysics::addSolverVariables() 69 : { 70 : // For compatibility with Modules/NavierStokesFV syntax 71 67 : if (!_has_scalar_equation) 72 0 : return; 73 : 74 67 : auto params = getFactory().getValidParams("MooseLinearVariableFVReal"); 75 67 : assignBlocks(params, _blocks); 76 : 77 160 : for (const auto name_i : index_range(_passive_scalar_names)) 78 : { 79 : // Dont add if the user already defined the variable 80 186 : if (!shouldCreateVariable(_passive_scalar_names[name_i], _blocks, /*error if aux*/ true)) 81 : { 82 0 : reportPotentiallyMissedParameters({"system_names", "passive_scalar_scaling"}, 83 : "MooseLinearVariableFVReal"); 84 0 : continue; 85 : } 86 : 87 93 : params.set<SolverSystemName>("solver_sys") = getSolverSystem(name_i); 88 186 : if (isParamValid("passive_scalar_scaling")) 89 0 : params.set<std::vector<Real>>("scaling") = { 90 0 : getParam<std::vector<Real>>("passive_scalar_scaling")[name_i]}; 91 : 92 186 : getProblem().addVariable("MooseLinearVariableFVReal", _passive_scalar_names[name_i], params); 93 : } 94 67 : } 95 : 96 : void 97 17 : WCNSLinearFVScalarTransportPhysics::addScalarTimeKernels() 98 : { 99 17 : std::string kernel_type = "LinearFVTimeDerivative"; 100 17 : InputParameters params = getFactory().getValidParams(kernel_type); 101 17 : assignBlocks(params, _blocks); 102 : 103 42 : for (const auto & vname : _passive_scalar_names) 104 : { 105 50 : params.set<LinearVariableName>("variable") = vname; 106 50 : if (shouldCreateTimeDerivative(vname, _blocks, /*error if already defined */ false)) 107 100 : getProblem().addLinearFVKernel(kernel_type, prefix() + "ins_" + vname + "_time", params); 108 : } 109 34 : } 110 : 111 : void 112 67 : WCNSLinearFVScalarTransportPhysics::addScalarAdvectionKernels() 113 : { 114 : const auto method_name = 115 67 : isParamValid("passive_scalar_advection_interpolation_method_name") 116 67 : ? getParam<InterpolationMethodName>("passive_scalar_advection_interpolation_method_name") 117 : : InterpolationMethodName( 118 262 : std::string(getParam<MooseEnum>("passive_scalar_advection_interpolation"))); 119 : 120 67 : const std::string kernel_type = "LinearFVScalarAdvection"; 121 67 : InputParameters params = getFactory().getValidParams(kernel_type); 122 : 123 67 : assignBlocks(params, _blocks); 124 67 : params.set<UserObjectName>("rhie_chow_user_object") = _flow_equations_physics->rhieChowUOName(); 125 67 : params.set<InterpolationMethodName>("advected_interp_method_name") = method_name; 126 67 : setSlipVelocityParams(params); 127 : 128 160 : for (const auto & vname : _passive_scalar_names) 129 : { 130 186 : params.set<LinearVariableName>("variable") = vname; 131 372 : getProblem().addLinearFVKernel(kernel_type, prefix() + "ins_" + vname + "_advection", params); 132 : } 133 134 : } 134 : 135 : void 136 67 : WCNSLinearFVScalarTransportPhysics::addScalarDiffusionKernels() 137 : { 138 : // Direct specification of diffusion term 139 : const auto passive_scalar_diffusivities = 140 201 : getParam<std::vector<MooseFunctorName>>("passive_scalar_diffusivity"); 141 : 142 67 : if (passive_scalar_diffusivities.size()) 143 : { 144 53 : const std::string kernel_type = "LinearFVDiffusion"; 145 53 : InputParameters params = getFactory().getValidParams(kernel_type); 146 53 : assignBlocks(params, _blocks); 147 53 : params.set<bool>("use_nonorthogonal_correction") = 148 159 : getParam<bool>("use_nonorthogonal_correction"); 149 132 : for (const auto name_i : index_range(_passive_scalar_names)) 150 : { 151 158 : params.set<LinearVariableName>("variable") = _passive_scalar_names[name_i]; 152 158 : params.set<MooseFunctorName>("diffusion_coeff") = 153 158 : passive_scalar_diffusivities[name_i] + (_has_turbulence_model ? "_plus_mut/Sc_t" : ""); 154 158 : getProblem().addLinearFVKernel( 155 237 : kernel_type, prefix() + "ins_" + _passive_scalar_names[name_i] + "_diffusion", params); 156 : } 157 53 : } 158 67 : } 159 : 160 : void 161 30 : WCNSLinearFVScalarTransportPhysics::addScalarSourceKernels() 162 : { 163 30 : const std::string kernel_type = "LinearFVSource"; 164 30 : InputParameters params = getFactory().getValidParams(kernel_type); 165 30 : assignBlocks(params, _blocks); 166 : 167 66 : for (const auto scalar_i : index_range(_passive_scalar_names)) 168 : { 169 72 : params.set<LinearVariableName>("variable") = _passive_scalar_names[scalar_i]; 170 : 171 36 : if (_passive_scalar_sources.size()) 172 : { 173 : // Added for backward compatibility with former Modules/NavierStokesFV syntax 174 24 : params.set<MooseFunctorName>("source_density") = _passive_scalar_sources[scalar_i]; 175 48 : getProblem().addLinearFVKernel( 176 72 : kernel_type, prefix() + "ins_" + _passive_scalar_names[scalar_i] + "_source", params); 177 : } 178 : 179 36 : if (_passive_scalar_coupled_sources.size()) 180 24 : for (const auto i : index_range(_passive_scalar_coupled_sources[scalar_i])) 181 : { 182 24 : params.set<MooseFunctorName>("source_density") = 183 : _passive_scalar_coupled_sources[scalar_i][i]; 184 12 : if (_passive_scalar_sources_coef.size()) 185 0 : params.set<Real>("scaling_factor") = _passive_scalar_sources_coef[scalar_i][i]; 186 : 187 24 : getProblem().addLinearFVKernel(kernel_type, 188 36 : prefix() + "ins_" + _passive_scalar_names[scalar_i] + 189 36 : "_coupled_source_" + std::to_string(i), 190 : params); 191 : } 192 : } 193 60 : } 194 : 195 : void 196 67 : WCNSLinearFVScalarTransportPhysics::addScalarInletBC() 197 : { 198 67 : const auto & inlet_boundaries = _flow_equations_physics->getInletBoundaries(); 199 67 : if (inlet_boundaries.empty()) 200 : return; 201 : 202 : // Boundary checks 203 : // TODO: once we have vectors of MooseEnum, we could use the same templated check for types and 204 : // functors 205 58 : if (inlet_boundaries.size() * _passive_scalar_names.size() != _passive_scalar_inlet_types.size()) 206 0 : paramError( 207 : "passive_scalar_inlet_types", 208 0 : "The number of scalar inlet types (" + std::to_string(_passive_scalar_inlet_types.size()) + 209 0 : ") is not equal to the number of inlet boundaries (" + 210 0 : std::to_string(inlet_boundaries.size()) + ") times the number of passive scalars (" + 211 0 : std::to_string(_passive_scalar_names.size()) + ")"); 212 58 : if (_passive_scalar_names.size() != _passive_scalar_inlet_functors.size()) 213 0 : paramError("passive_scalar_inlet_functors", 214 0 : "The number of groups of inlet functors (" + 215 0 : std::to_string(_passive_scalar_inlet_functors.size()) + 216 0 : ") is not equal to the number of passive scalars (" + 217 0 : std::to_string(_passive_scalar_names.size()) + ")"); 218 : 219 142 : for (const auto name_i : index_range(_passive_scalar_names)) 220 : { 221 84 : if (inlet_boundaries.size() != _passive_scalar_inlet_functors[name_i].size()) 222 0 : paramError("passive_scalar_inlet_functors", 223 0 : "The number of inlet boundary functors for scalar '" + 224 0 : _passive_scalar_names[name_i] + 225 0 : "' does not match the number of inlet boundaries (" + 226 0 : std::to_string(_passive_scalar_inlet_functors[name_i].size()) + ")"); 227 : 228 84 : unsigned int num_inlets = inlet_boundaries.size(); 229 168 : for (unsigned int bc_ind = 0; bc_ind < num_inlets; ++bc_ind) 230 : { 231 84 : if (_passive_scalar_inlet_types[name_i * num_inlets + bc_ind] == "fixed-value") 232 : { 233 84 : const std::string bc_type = "LinearFVAdvectionDiffusionFunctorDirichletBC"; 234 84 : InputParameters params = getFactory().getValidParams(bc_type); 235 168 : params.set<LinearVariableName>("variable") = _passive_scalar_names[name_i]; 236 168 : params.set<MooseFunctorName>("functor") = _passive_scalar_inlet_functors[name_i][bc_ind]; 237 252 : params.set<std::vector<BoundaryName>>("boundary") = {inlet_boundaries[bc_ind]}; 238 : 239 168 : getProblem().addLinearFVBC( 240 84 : bc_type, _passive_scalar_names[name_i] + "_" + inlet_boundaries[bc_ind], params); 241 84 : } 242 0 : else if (_passive_scalar_inlet_types[name_i * num_inlets + bc_ind] == "flux-mass" || 243 0 : _passive_scalar_inlet_types[name_i * num_inlets + bc_ind] == "flux-velocity") 244 : { 245 0 : mooseError("Flux boundary conditions not supported at this time using the linear finite " 246 : "volume discretization"); 247 : } 248 : } 249 : } 250 : } 251 : 252 : unsigned short 253 201 : WCNSLinearFVScalarTransportPhysics::getNumberAlgebraicGhostingLayersNeeded() const 254 : { 255 201 : return 1; 256 : } 257 : 258 : void 259 67 : WCNSLinearFVScalarTransportPhysics::addScalarOutletBC() 260 : { 261 67 : const auto & outlet_boundaries = _flow_equations_physics->getOutletBoundaries(); 262 67 : if (outlet_boundaries.empty()) 263 : return; 264 : 265 116 : for (const auto & outlet_bdy : outlet_boundaries) 266 : { 267 58 : const std::string bc_type = "LinearFVAdvectionDiffusionOutflowBC"; 268 58 : InputParameters params = getFactory().getValidParams(bc_type); 269 174 : params.set<std::vector<BoundaryName>>("boundary") = {outlet_bdy}; 270 58 : params.set<bool>("use_two_term_expansion") = 271 174 : getParam<bool>("passive_scalar_two_term_bc_expansion"); 272 : 273 142 : for (const auto name_i : index_range(_passive_scalar_names)) 274 : { 275 168 : params.set<LinearVariableName>("variable") = _passive_scalar_names[name_i]; 276 168 : getProblem().addLinearFVBC(bc_type, _passive_scalar_names[name_i] + "_" + outlet_bdy, params); 277 : } 278 58 : } 279 : }