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 "WCNSFVScalarTransportPhysics.h" 11 : #include "WCNSFVFlowPhysicsBase.h" 12 : #include "NSFVBase.h" 13 : #include "NS.h" 14 : 15 : registerNavierStokesPhysicsBaseTasks("NavierStokesApp", WCNSFVScalarTransportPhysics); 16 : registerWCNSFVScalarTransportBaseTasks("NavierStokesApp", WCNSFVScalarTransportPhysics); 17 : 18 : InputParameters 19 604 : WCNSFVScalarTransportPhysics::validParams() 20 : { 21 604 : InputParameters params = WCNSFVScalarTransportPhysicsBase::validParams(); 22 604 : params.addClassDescription("Define the Navier Stokes weakly-compressible scalar field transport " 23 : "equation(s) using the nonlinear finite volume discretization"); 24 604 : params.transferParam<MooseEnum>(NSFVBase::validParams(), "passive_scalar_face_interpolation"); 25 1208 : params.addParamNamesToGroup("passive_scalar_face_interpolation", "Numerical scheme"); 26 604 : return params; 27 0 : } 28 : 29 604 : WCNSFVScalarTransportPhysics::WCNSFVScalarTransportPhysics(const InputParameters & parameters) 30 604 : : WCNSFVScalarTransportPhysicsBase(parameters) 31 : { 32 586 : } 33 : 34 : void 35 578 : WCNSFVScalarTransportPhysics::addSolverVariables() 36 : { 37 : // For compatibility with Modules/NavierStokesFV syntax 38 578 : if (!_has_scalar_equation) 39 401 : return; 40 : 41 177 : auto params = getFactory().getValidParams("INSFVScalarFieldVariable"); 42 177 : assignBlocks(params, _blocks); 43 354 : params.set<MooseEnum>("face_interp_method") = 44 354 : getParam<MooseEnum>("passive_scalar_face_interpolation"); 45 177 : params.set<bool>("two_term_boundary_expansion") = 46 531 : getParam<bool>("passive_scalar_two_term_bc_expansion"); 47 : 48 390 : for (const auto name_i : index_range(_passive_scalar_names)) 49 : { 50 : // Dont add if the user already defined the variable 51 426 : if (!shouldCreateVariable(_passive_scalar_names[name_i], _blocks, /*error if aux*/ true)) 52 : { 53 22 : reportPotentiallyMissedParameters({"system_names", "passive_scalar_scaling"}, 54 : "INSFVScalarFieldVariable"); 55 22 : continue; 56 : } 57 : 58 191 : params.set<SolverSystemName>("solver_sys") = getSolverSystem(name_i); 59 382 : if (isParamValid("passive_scalar_scaling")) 60 0 : params.set<std::vector<Real>>("scaling") = { 61 0 : getParam<std::vector<Real>>("passive_scalar_scaling")[name_i]}; 62 : 63 382 : getProblem().addVariable("INSFVScalarFieldVariable", _passive_scalar_names[name_i], params); 64 : } 65 177 : } 66 : 67 : void 68 21 : WCNSFVScalarTransportPhysics::addScalarTimeKernels() 69 : { 70 42 : for (const auto & vname : _passive_scalar_names) 71 : { 72 21 : const std::string kernel_type = "FVFunctorTimeKernel"; 73 21 : InputParameters params = getFactory().getValidParams(kernel_type); 74 21 : assignBlocks(params, _blocks); 75 42 : params.set<NonlinearVariableName>("variable") = vname; 76 : 77 42 : if (shouldCreateTimeDerivative(vname, _blocks, /* error if already defined */ false)) 78 84 : getProblem().addFVKernel(kernel_type, prefix() + "ins_" + vname + "_time", params); 79 21 : } 80 21 : } 81 : 82 : void 83 161 : WCNSFVScalarTransportPhysics::addScalarAdvectionKernels() 84 : { 85 : const std::string kernel_type = 86 313 : _porous_medium_treatment ? "PINSFVScalarFieldAdvection" : "INSFVScalarFieldAdvection"; 87 161 : InputParameters params = getFactory().getValidParams(kernel_type); 88 : 89 161 : assignBlocks(params, _blocks); 90 161 : params.set<MooseEnum>("velocity_interp_method") = _velocity_interpolation; 91 161 : params.set<UserObjectName>("rhie_chow_user_object") = _flow_equations_physics->rhieChowUOName(); 92 322 : params.set<MooseEnum>("advected_interp_method") = 93 322 : getParam<MooseEnum>("passive_scalar_advection_interpolation"); 94 161 : setSlipVelocityParams(params); 95 161 : if (_porous_medium_treatment) 96 9 : params.set<MooseFunctorName>(NS::porosity) = 97 18 : _flow_equations_physics->getPorosityFunctorName(/*smoothed=*/true); 98 : 99 358 : for (const auto & vname : _passive_scalar_names) 100 : { 101 197 : params.set<NonlinearVariableName>("variable") = vname; 102 788 : getProblem().addFVKernel(kernel_type, prefix() + "ins_" + vname + "_advection", params); 103 : } 104 322 : } 105 : 106 : void 107 161 : WCNSFVScalarTransportPhysics::addScalarDiffusionKernels() 108 : { 109 : // Direct specification of diffusion term 110 : const auto passive_scalar_diffusivities = 111 483 : getParam<std::vector<MooseFunctorName>>("passive_scalar_diffusivity"); 112 : 113 161 : if (passive_scalar_diffusivities.size()) 114 : { 115 138 : const std::string kernel_type = "FVDiffusion"; 116 138 : InputParameters params = getFactory().getValidParams(kernel_type); 117 138 : assignBlocks(params, _blocks); 118 312 : for (const auto name_i : index_range(_passive_scalar_names)) 119 : { 120 348 : params.set<NonlinearVariableName>("variable") = _passive_scalar_names[name_i]; 121 174 : params.set<MooseFunctorName>("coeff") = passive_scalar_diffusivities[name_i]; 122 348 : getProblem().addFVKernel( 123 522 : kernel_type, prefix() + "ins_" + _passive_scalar_names[name_i] + "_diffusion", params); 124 : } 125 138 : } 126 161 : } 127 : 128 : void 129 117 : WCNSFVScalarTransportPhysics::addScalarSourceKernels() 130 : { 131 117 : const std::string kernel_type = "FVCoupledForce"; 132 117 : InputParameters params = getFactory().getValidParams(kernel_type); 133 117 : assignBlocks(params, _blocks); 134 : 135 270 : for (const auto scalar_i : index_range(_passive_scalar_names)) 136 : { 137 306 : params.set<NonlinearVariableName>("variable") = _passive_scalar_names[scalar_i]; 138 153 : if (_passive_scalar_sources.size()) 139 : { 140 : // Added for backward compatibility with former Modules/NavierStokesFV syntax 141 144 : params.set<MooseFunctorName>("v") = _passive_scalar_sources[scalar_i]; 142 288 : getProblem().addFVKernel( 143 432 : kernel_type, prefix() + "ins_" + _passive_scalar_names[scalar_i] + "_source", params); 144 : } 145 : 146 : // Sufficient for all intents and purposes 147 153 : if (_passive_scalar_coupled_sources.size()) 148 216 : for (const auto i : index_range(_passive_scalar_coupled_sources[scalar_i])) 149 : { 150 216 : params.set<MooseFunctorName>("v") = _passive_scalar_coupled_sources[scalar_i][i]; 151 108 : if (_passive_scalar_sources_coef.size()) 152 108 : params.set<Real>("coef") = _passive_scalar_sources_coef[scalar_i][i]; 153 216 : getProblem().addFVKernel(kernel_type, 154 324 : prefix() + "ins_" + _passive_scalar_names[scalar_i] + 155 324 : "_coupled_source_" + std::to_string(i), 156 : params); 157 : } 158 : } 159 234 : } 160 : 161 : void 162 153 : WCNSFVScalarTransportPhysics::addScalarInletBC() 163 : { 164 153 : const auto & inlet_boundaries = _flow_equations_physics->getInletBoundaries(); 165 153 : if (inlet_boundaries.empty()) 166 : return; 167 : 168 : // Boundary checks 169 : // TODO: once we have vectors of MooseEnum, we could use the same templated check for types and 170 : // functors 171 146 : if (inlet_boundaries.size() * _passive_scalar_names.size() != _passive_scalar_inlet_types.size()) 172 0 : paramError( 173 : "passive_scalar_inlet_types", 174 0 : "The number of scalar inlet types (" + std::to_string(_passive_scalar_inlet_types.size()) + 175 0 : ") is not equal to the number of inlet boundaries (" + 176 0 : std::to_string(inlet_boundaries.size()) + ") times the number of passive scalars (" + 177 0 : std::to_string(_passive_scalar_names.size()) + ")"); 178 146 : if (_passive_scalar_names.size() != _passive_scalar_inlet_functors.size()) 179 0 : paramError("passive_scalar_inlet_functors", 180 0 : "The number of groups of inlet functors (" + 181 0 : std::to_string(_passive_scalar_inlet_functors.size()) + 182 0 : ") is not equal to the number of passive scalars (" + 183 0 : std::to_string(_passive_scalar_names.size()) + ")"); 184 : 185 328 : for (const auto name_i : index_range(_passive_scalar_names)) 186 : { 187 182 : if (inlet_boundaries.size() != _passive_scalar_inlet_functors[name_i].size()) 188 0 : paramError("passive_scalar_inlet_functors", 189 0 : "The number of inlet boundary functors for scalar '" + 190 0 : _passive_scalar_names[name_i] + 191 0 : "' does not match the number of inlet boundaries (" + 192 0 : std::to_string(_passive_scalar_inlet_functors[name_i].size()) + ")"); 193 : 194 : unsigned int flux_bc_counter = 0; 195 182 : unsigned int num_inlets = inlet_boundaries.size(); 196 364 : for (unsigned int bc_ind = 0; bc_ind < num_inlets; ++bc_ind) 197 : { 198 182 : if (_passive_scalar_inlet_types[name_i * num_inlets + bc_ind] == "fixed-value") 199 : { 200 140 : const std::string bc_type = "FVADFunctorDirichletBC"; 201 140 : InputParameters params = getFactory().getValidParams(bc_type); 202 280 : params.set<NonlinearVariableName>("variable") = _passive_scalar_names[name_i]; 203 280 : params.set<MooseFunctorName>("functor") = _passive_scalar_inlet_functors[name_i][bc_ind]; 204 420 : params.set<std::vector<BoundaryName>>("boundary") = {inlet_boundaries[bc_ind]}; 205 : 206 280 : getProblem().addFVBC( 207 140 : bc_type, _passive_scalar_names[name_i] + "_" + inlet_boundaries[bc_ind], params); 208 140 : } 209 42 : else if (_passive_scalar_inlet_types[name_i * num_inlets + bc_ind] == "flux-mass" || 210 7 : _passive_scalar_inlet_types[name_i * num_inlets + bc_ind] == "flux-velocity") 211 : { 212 42 : const auto flux_inlet_directions = _flow_equations_physics->getFluxInletDirections(); 213 42 : const auto flux_inlet_pps = _flow_equations_physics->getFluxInletPPs(); 214 : 215 42 : const std::string bc_type = "WCNSFVScalarFluxBC"; 216 42 : InputParameters params = getFactory().getValidParams(bc_type); 217 84 : params.set<NonlinearVariableName>("variable") = _passive_scalar_names[name_i]; 218 84 : params.set<MooseFunctorName>("passive_scalar") = _passive_scalar_names[name_i]; 219 42 : if (flux_inlet_directions.size()) 220 14 : params.set<Point>("direction") = flux_inlet_directions[flux_bc_counter]; 221 42 : if (_passive_scalar_inlet_types[name_i * num_inlets + bc_ind] == "flux-mass") 222 : { 223 35 : params.set<PostprocessorName>("mdot_pp") = flux_inlet_pps[flux_bc_counter]; 224 140 : params.set<PostprocessorName>("area_pp") = "area_pp_" + inlet_boundaries[bc_ind]; 225 : } 226 : else 227 14 : params.set<PostprocessorName>("velocity_pp") = flux_inlet_pps[flux_bc_counter]; 228 : 229 42 : params.set<MooseFunctorName>(NS::density) = _density_name; 230 84 : params.set<PostprocessorName>("scalar_value_pp") = 231 84 : _passive_scalar_inlet_functors[name_i][bc_ind]; 232 126 : params.set<std::vector<BoundaryName>>("boundary") = {inlet_boundaries[bc_ind]}; 233 : 234 42 : params.set<MooseFunctorName>(NS::velocity_x) = _velocity_names[0]; 235 42 : if (dimension() > 1) 236 84 : params.set<MooseFunctorName>(NS::velocity_y) = _velocity_names[1]; 237 42 : if (dimension() > 2) 238 0 : params.set<MooseFunctorName>(NS::velocity_z) = _velocity_names[2]; 239 : 240 84 : getProblem().addFVBC(bc_type, 241 84 : prefix() + _passive_scalar_names[name_i] + "_" + 242 : inlet_boundaries[bc_ind], 243 : params); 244 42 : flux_bc_counter += 1; 245 84 : } 246 : } 247 : } 248 : } 249 : 250 : void 251 153 : WCNSFVScalarTransportPhysics::addScalarOutletBC() 252 : { 253 : // Advection outlet is naturally handled by the advection flux kernel 254 153 : return; 255 : }