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 "WCNSFVFluidHeatTransferPhysicsBase.h"
11 : #include "WCNSFVCoupledAdvectionPhysicsHelper.h"
12 : #include "WCNSFVFlowPhysics.h"
13 : #include "PINSFVEnergyAnisotropicDiffusion.h"
14 : #include "NSFVBase.h"
15 :
16 : InputParameters
17 1314 : WCNSFVFluidHeatTransferPhysicsBase::validParams()
18 : {
19 1314 : InputParameters params = NavierStokesPhysicsBase::validParams();
20 1314 : params += WCNSFVCoupledAdvectionPhysicsHelper::validParams();
21 1314 : params.addClassDescription("Define the Navier Stokes weakly-compressible energy equation");
22 :
23 1314 : params += NSFVBase::commonFluidEnergyEquationParams();
24 1314 : params.transferParam<bool>(PINSFVEnergyAnisotropicDiffusion::validParams(),
25 : "effective_conductivity");
26 :
27 : // TODO Remove the parameter once NavierStokesFV syntax has been removed
28 2628 : params.addParam<bool>("add_energy_equation",
29 : "Whether to add the energy equation. This parameter is not necessary if "
30 : "using the Physics syntax");
31 2628 : params.addParam<bool>("solve_for_enthalpy",
32 2628 : false,
33 : "Whether to solve for the enthalpy or the temperature of the fluid");
34 2628 : params.addParam<NonlinearVariableName>(
35 : "fluid_temperature_variable", NS::T_fluid, "Name of the fluid temperature variable");
36 :
37 : // Initial conditions
38 2628 : params.addParam<FunctionName>(
39 : "initial_enthalpy",
40 : "Initial value of the enthalpy variable, only to be used when solving for enthalpy");
41 :
42 : // New functor boundary conditions
43 2628 : params.deprecateParam("energy_inlet_function", "energy_inlet_functors", "01/01/2025");
44 2628 : params.deprecateParam("energy_wall_function", "energy_wall_functors", "01/01/2025");
45 :
46 : // Spatial finite volume discretization scheme
47 1314 : params.transferParam<MooseEnum>(NSFVBase::validParams(), "energy_advection_interpolation");
48 1314 : params.transferParam<MooseEnum>(NSFVBase::validParams(), "energy_face_interpolation");
49 1314 : params.transferParam<bool>(NSFVBase::validParams(), "energy_two_term_bc_expansion");
50 :
51 2628 : params.addParamNamesToGroup("specific_heat thermal_conductivity thermal_conductivity_blocks "
52 : "use_external_enthalpy_material",
53 : "Material properties");
54 2628 : params.addParamNamesToGroup("energy_advection_interpolation energy_face_interpolation "
55 : "energy_two_term_bc_expansion",
56 : "Numerical scheme");
57 2628 : params.addParamNamesToGroup("energy_inlet_types energy_inlet_functors",
58 : "Inlet boundary conditions");
59 2628 : params.addParamNamesToGroup("energy_wall_types energy_wall_functors", "Wall boundary conditions");
60 :
61 1314 : return params;
62 0 : }
63 :
64 1314 : WCNSFVFluidHeatTransferPhysicsBase::WCNSFVFluidHeatTransferPhysicsBase(
65 1314 : const InputParameters & parameters)
66 : : NavierStokesPhysicsBase(parameters),
67 : WCNSFVCoupledAdvectionPhysicsHelper(this),
68 1314 : _has_energy_equation(
69 2628 : isParamValid("add_energy_equation")
70 3942 : ? getParam<bool>("add_energy_equation")
71 3223 : : (usingNavierStokesFVSyntax() ? isParamSetByUser("energy_inlet_function") : true)),
72 2628 : _solve_for_enthalpy(getParam<bool>("solve_for_enthalpy")),
73 1314 : _fluid_enthalpy_name(getSpecificEnthalpyName()),
74 2628 : _fluid_temperature_name(getParam<NonlinearVariableName>("fluid_temperature_variable")),
75 1314 : _specific_heat_name(getParam<MooseFunctorName>("specific_heat")),
76 3942 : _thermal_conductivity_blocks(
77 1314 : parameters.isParamValid("thermal_conductivity_blocks")
78 1314 : ? getParam<std::vector<std::vector<SubdomainName>>>("thermal_conductivity_blocks")
79 : : std::vector<std::vector<SubdomainName>>()),
80 2628 : _thermal_conductivity_name(getParam<std::vector<MooseFunctorName>>("thermal_conductivity")),
81 2628 : _ambient_convection_blocks(
82 : getParam<std::vector<std::vector<SubdomainName>>>("ambient_convection_blocks")),
83 2628 : _ambient_convection_alpha(getParam<std::vector<MooseFunctorName>>("ambient_convection_alpha")),
84 2628 : _ambient_temperature(getParam<std::vector<MooseFunctorName>>("ambient_temperature")),
85 2628 : _energy_inlet_types(getParam<MultiMooseEnum>("energy_inlet_types")),
86 2628 : _energy_inlet_functors(getParam<std::vector<MooseFunctorName>>("energy_inlet_functors")),
87 2628 : _energy_wall_types(getParam<MultiMooseEnum>("energy_wall_types")),
88 3942 : _energy_wall_functors(getParam<std::vector<MooseFunctorName>>("energy_wall_functors"))
89 : {
90 : // For compatibility with Modules/NavierStokesFV syntax
91 1314 : if (!_has_energy_equation)
92 : return;
93 :
94 741 : if (_solve_for_enthalpy)
95 19 : saveSolverVariableName(_fluid_enthalpy_name);
96 : else
97 722 : saveSolverVariableName(_fluid_temperature_name);
98 :
99 : // set block restrictions if not set by user
100 : // This should probably be done for all the coupled physics, tbd
101 1482 : if (!isParamSetByUser("block"))
102 728 : _blocks = _flow_equations_physics->blocks();
103 :
104 : // Parameter checks
105 1482 : checkSecondParamSetOnlyIfFirstOneTrue("solve_for_enthalpy", "initial_enthalpy");
106 1482 : checkVectorParamsSameLengthIfSet<MooseFunctorName, MooseFunctorName>("ambient_convection_alpha",
107 : "ambient_temperature");
108 1482 : checkSecondParamSetOnlyIfFirstOneSet("external_heat_source", "external_heat_source_coeff");
109 :
110 : // Check boundary parameters if provided.
111 : // The boundaries are checked again when the boundary conditions are added as we want
112 : // to be able to more boundary conditions to a Physics dynamically
113 1482 : if (isParamValid("energy_inlet_types"))
114 1424 : checkVectorParamAndMultiMooseEnumLength<MooseFunctorName>("energy_inlet_functors",
115 : "energy_inlet_types");
116 1482 : if (isParamSetByUser("energy_wall_boundaries"))
117 18 : checkVectorParamsSameLengthIfSet<BoundaryName, MooseFunctorName>(
118 : "energy_wall_boundaries", "energy_wall_functors", false);
119 1482 : if (isParamValid("energy_wall_types"))
120 1476 : checkVectorParamAndMultiMooseEnumLength<MooseFunctorName>("energy_wall_functors",
121 : "energy_wall_types");
122 0 : }
123 :
124 : void
125 1272 : WCNSFVFluidHeatTransferPhysicsBase::addFVKernels()
126 : {
127 : // For compatibility with Modules/NavierStokesFV syntax
128 1272 : if (!_has_energy_equation)
129 : return;
130 :
131 703 : if (shouldCreateTimeDerivative(_solve_for_enthalpy ? _fluid_enthalpy_name
132 : : _fluid_temperature_name,
133 703 : _blocks,
134 : /*error if already defined*/ false))
135 182 : addEnergyTimeKernels();
136 :
137 703 : addEnergyAdvectionKernels();
138 703 : addEnergyHeatConductionKernels();
139 1394 : if (getParam<std::vector<MooseFunctorName>>("ambient_temperature").size())
140 243 : addEnergyAmbientConvection();
141 1394 : if (isParamValid("external_heat_source"))
142 142 : addEnergyExternalHeatSource();
143 : }
144 :
145 : void
146 1262 : WCNSFVFluidHeatTransferPhysicsBase::addFVBCs()
147 : {
148 : // For compatibility with Modules/NavierStokesFV syntax
149 1262 : if (!_has_energy_equation)
150 : return;
151 :
152 693 : addEnergyInletBC();
153 691 : addEnergyWallBC();
154 689 : addEnergyOutletBC();
155 689 : addEnergySeparatorBC();
156 : }
157 :
158 : void
159 12930 : WCNSFVFluidHeatTransferPhysicsBase::actOnAdditionalTasks()
160 : {
161 : // Turbulence physics would not be initialized before this task
162 12930 : if (_current_task == "get_turbulence_physics")
163 1286 : _turbulence_physics = getCoupledTurbulencePhysics();
164 12930 : }
165 :
166 : bool
167 703 : WCNSFVFluidHeatTransferPhysicsBase::processThermalConductivity()
168 : {
169 1404 : checkBlockwiseConsistency<MooseFunctorName>("thermal_conductivity_blocks",
170 : {"thermal_conductivity"});
171 : bool have_scalar = false;
172 : bool have_vector = false;
173 :
174 1423 : for (unsigned int i = 0; i < _thermal_conductivity_name.size(); ++i)
175 : {
176 : // First, check if the name is just a number (only in case of isotropic conduction)
177 722 : if (MooseUtils::parsesToReal(_thermal_conductivity_name[i]))
178 : have_scalar = true;
179 : // Now we determine what kind of functor we are dealing with
180 : else
181 : {
182 363 : if (getProblem().hasFunctorWithType<ADReal>(_thermal_conductivity_name[i],
183 405 : /*thread_id=*/0) ||
184 42 : getProblem().hasFunctorWithType<Real>(_thermal_conductivity_name[i],
185 : /*thread_id=*/0))
186 : have_scalar = true;
187 : else
188 : {
189 42 : if (getProblem().hasFunctorWithType<ADRealVectorValue>(_thermal_conductivity_name[i],
190 : /*thread_id=*/0))
191 : have_vector = true;
192 : else
193 0 : paramError("thermal_conductivity",
194 : "We only allow functor of type Real/ADReal or ADRealVectorValue for thermal "
195 0 : "conductivity! Functor '" +
196 : _thermal_conductivity_name[i] + "' is not of the requested type.");
197 : }
198 : }
199 : }
200 :
201 701 : if (have_vector && !_porous_medium_treatment)
202 2 : paramError("thermal_conductivity", "Cannot use anisotropic diffusion with non-porous flows!");
203 :
204 699 : if (have_vector == have_scalar)
205 2 : paramError("thermal_conductivity",
206 : "The entries on thermal conductivity shall either be scalars of vectors, mixing "
207 : "them is not supported!");
208 697 : return have_vector;
209 : }
210 :
211 : void
212 1274 : WCNSFVFluidHeatTransferPhysicsBase::addInitialConditions()
213 : {
214 : // For compatibility with Modules/NavierStokesFV syntax
215 1274 : if (!_has_energy_equation)
216 569 : return;
217 707 : if (!_define_variables && parameters().isParamSetByUser("initial_temperature"))
218 2 : paramError(
219 : "initial_temperature",
220 : "T_fluid is defined externally of WCNSFVFluidHeatTransferPhysicsBase, so should the inital "
221 : "condition");
222 : // do not set initial conditions if we are not defining variables
223 703 : if (!_define_variables)
224 : return;
225 :
226 703 : InputParameters params = getFactory().getValidParams("FunctionIC");
227 703 : assignBlocks(params, _blocks);
228 :
229 2109 : if (shouldCreateIC(_fluid_temperature_name,
230 : _blocks,
231 2109 : /*whether IC is a default*/ !isParamSetByUser("initial_temperature"),
232 1406 : /*error if already an IC*/ isParamSetByUser("initial_temperature")))
233 : {
234 669 : params.set<VariableName>("variable") = _fluid_temperature_name;
235 2007 : params.set<FunctionName>("function") = getParam<FunctionName>("initial_temperature");
236 :
237 1338 : getProblem().addInitialCondition("FunctionIC", _fluid_temperature_name + "_ic", params);
238 : }
239 1425 : if (parameters().isParamValid("initial_enthalpy") &&
240 19 : shouldCreateIC(_fluid_enthalpy_name,
241 : _blocks,
242 : /*whether IC is a default*/ false,
243 : /*error if already an IC*/ true))
244 : {
245 19 : params.set<VariableName>("variable") = _fluid_enthalpy_name;
246 57 : params.set<FunctionName>("function") = getParam<FunctionName>("initial_enthalpy");
247 :
248 38 : getProblem().addInitialCondition("FunctionIC", _fluid_enthalpy_name + "_ic", params);
249 : }
250 703 : }
251 :
252 : void
253 1272 : WCNSFVFluidHeatTransferPhysicsBase::addMaterials()
254 : {
255 : // For compatibility with Modules/NavierStokesFV syntax
256 1272 : if (!_has_energy_equation)
257 569 : return;
258 :
259 : // Note that this material choice would not work for Newton-INSFV + solve_for_enthalpy
260 : const auto object_type =
261 703 : _solve_for_enthalpy ? "LinearFVEnthalpyFunctorMaterial" : "INSFVEnthalpyFunctorMaterial";
262 :
263 703 : InputParameters params = getFactory().getValidParams(object_type);
264 703 : assignBlocks(params, _blocks);
265 :
266 703 : if (_solve_for_enthalpy)
267 : {
268 19 : params.set<MooseFunctorName>(NS::pressure) = _flow_equations_physics->getPressureName();
269 19 : params.set<MooseFunctorName>(NS::T_fluid) = _fluid_temperature_name;
270 38 : params.set<MooseFunctorName>(NS::specific_enthalpy) = _fluid_enthalpy_name;
271 19 : if (isParamValid(NS::fluid))
272 19 : params.set<UserObjectName>(NS::fluid) = getParam<UserObjectName>(NS::fluid);
273 : else
274 : {
275 0 : if (!getProblem().hasFunctor("h_from_p_T_functor", 0) ||
276 0 : !getProblem().hasFunctor("T_from_p_h_functor", 0))
277 0 : paramError(NS::fluid,
278 : "Either 'fp' must be specified or the 'h_from_p_T_functor' and "
279 : "'T_from_p_h_functor' must be defined outside the Physics");
280 : // Note: we could define those in the Physics if cp is constant
281 0 : params.set<MooseFunctorName>("h_from_p_T_functor") = "h_from_p_T_functor";
282 0 : params.set<MooseFunctorName>("T_from_p_h_functor") = "T_from_p_h_functor";
283 : }
284 : }
285 : else
286 : {
287 684 : params.set<MooseFunctorName>(NS::density) = _density_name;
288 684 : params.set<MooseFunctorName>(NS::cp) = _specific_heat_name;
289 1368 : params.set<MooseFunctorName>("temperature") = _fluid_temperature_name;
290 : }
291 :
292 2109 : getProblem().addMaterial(object_type, prefix() + "enthalpy_material", params);
293 703 : }
294 :
295 : unsigned short
296 3810 : WCNSFVFluidHeatTransferPhysicsBase::getNumberAlgebraicGhostingLayersNeeded() const
297 : {
298 7620 : unsigned short necessary_layers = getParam<unsigned short>("ghost_layers");
299 3810 : necessary_layers =
300 3810 : std::max(necessary_layers, _flow_equations_physics->getNumberAlgebraicGhostingLayersNeeded());
301 11430 : if (getParam<MooseEnum>("energy_face_interpolation") == "skewness-corrected")
302 0 : necessary_layers = std::max(necessary_layers, (unsigned short)3);
303 :
304 3810 : return necessary_layers;
305 : }
|