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 1371 : WCNSFVFluidHeatTransferPhysicsBase::validParams()
18 : {
19 1371 : InputParameters params = NavierStokesPhysicsBase::validParams();
20 1371 : params += WCNSFVCoupledAdvectionPhysicsHelper::validParams();
21 1371 : params.addClassDescription("Define the Navier Stokes weakly-compressible energy equation");
22 :
23 1371 : params += NSFVBase::commonFluidEnergyEquationParams();
24 1371 : params.transferParam<bool>(PINSFVEnergyAnisotropicDiffusion::validParams(),
25 : "effective_conductivity");
26 :
27 : // TODO Remove the parameter once NavierStokesFV syntax has been removed
28 2742 : 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 2742 : params.addParam<bool>("solve_for_enthalpy",
32 2742 : false,
33 : "Whether to solve for the enthalpy or the temperature of the fluid");
34 2742 : params.addParam<NonlinearVariableName>(
35 : "fluid_temperature_variable", NS::T_fluid, "Name of the fluid temperature variable");
36 :
37 1371 : params.addParam<UserObjectName>(NS::fluid, "Fluid properties userobject");
38 1371 : params.addParamNamesToGroup(NS::fluid, "Material properties");
39 :
40 : // Initial conditions
41 2742 : params.addParam<FunctionName>(
42 : "initial_enthalpy",
43 : "Initial value of the enthalpy variable, only to be used when solving for enthalpy");
44 :
45 : // Spatial finite volume discretization scheme
46 1371 : params.transferParam<MooseEnum>(NSFVBase::validParams(), "energy_advection_interpolation");
47 1371 : params.transferParam<MooseEnum>(NSFVBase::validParams(), "energy_face_interpolation");
48 1371 : params.transferParam<bool>(NSFVBase::validParams(), "energy_two_term_bc_expansion");
49 :
50 2742 : params.addParamNamesToGroup("specific_heat thermal_conductivity thermal_conductivity_blocks "
51 : "use_external_enthalpy_material",
52 : "Material properties");
53 2742 : params.addParamNamesToGroup("energy_advection_interpolation energy_face_interpolation "
54 : "energy_two_term_bc_expansion",
55 : "Numerical scheme");
56 2742 : params.addParamNamesToGroup("energy_inlet_types energy_inlet_functors",
57 : "Inlet boundary conditions");
58 2742 : params.addParamNamesToGroup("energy_wall_types energy_wall_functors", "Wall boundary conditions");
59 :
60 1371 : return params;
61 0 : }
62 :
63 1371 : WCNSFVFluidHeatTransferPhysicsBase::WCNSFVFluidHeatTransferPhysicsBase(
64 1371 : const InputParameters & parameters)
65 : : NavierStokesPhysicsBase(parameters),
66 : WCNSFVCoupledAdvectionPhysicsHelper(this),
67 1371 : _has_energy_equation(
68 2742 : isParamValid("add_energy_equation")
69 4113 : ? getParam<bool>("add_energy_equation")
70 3337 : : (usingNavierStokesFVSyntax() ? isParamSetByUser("energy_inlet_functors") : true)),
71 2742 : _solve_for_enthalpy(getParam<bool>("solve_for_enthalpy")),
72 1371 : _fluid_enthalpy_name(getSpecificEnthalpyName()),
73 2742 : _fluid_temperature_name(getParam<NonlinearVariableName>("fluid_temperature_variable")),
74 1371 : _specific_heat_name(getParam<MooseFunctorName>("specific_heat")),
75 4113 : _thermal_conductivity_blocks(
76 1371 : parameters.isParamValid("thermal_conductivity_blocks")
77 1371 : ? getParam<std::vector<std::vector<SubdomainName>>>("thermal_conductivity_blocks")
78 : : std::vector<std::vector<SubdomainName>>()),
79 2742 : _thermal_conductivity_name(getParam<std::vector<MooseFunctorName>>("thermal_conductivity")),
80 2742 : _ambient_convection_blocks(
81 : getParam<std::vector<std::vector<SubdomainName>>>("ambient_convection_blocks")),
82 2742 : _ambient_convection_alpha(getParam<std::vector<MooseFunctorName>>("ambient_convection_alpha")),
83 2742 : _ambient_temperature(getParam<std::vector<MooseFunctorName>>("ambient_temperature")),
84 2742 : _energy_inlet_types(getParam<MultiMooseEnum>("energy_inlet_types")),
85 2742 : _energy_inlet_functors(getParam<std::vector<MooseFunctorName>>("energy_inlet_functors")),
86 2742 : _energy_wall_types(getParam<MultiMooseEnum>("energy_wall_types")),
87 4113 : _energy_wall_functors(getParam<std::vector<MooseFunctorName>>("energy_wall_functors"))
88 : {
89 : // For compatibility with Modules/NavierStokesFV syntax
90 1371 : if (!_has_energy_equation)
91 : return;
92 :
93 798 : if (_solve_for_enthalpy)
94 76 : saveSolverVariableName(_fluid_enthalpy_name);
95 : else
96 722 : saveSolverVariableName(_fluid_temperature_name);
97 :
98 : // set block restrictions if not set by user
99 : // This should probably be done for all the coupled physics, tbd
100 1596 : if (!isParamSetByUser("block"))
101 785 : _blocks = _flow_equations_physics->blocks();
102 :
103 : // Parameter checks
104 1596 : checkSecondParamSetOnlyIfFirstOneTrue("solve_for_enthalpy", "initial_enthalpy");
105 1596 : checkVectorParamsSameLengthIfSet<MooseFunctorName, MooseFunctorName>("ambient_convection_alpha",
106 : "ambient_temperature");
107 1596 : checkSecondParamSetOnlyIfFirstOneSet("external_heat_source", "external_heat_source_coeff");
108 :
109 : // Check boundary parameters if provided.
110 : // The boundaries are checked again when the boundary conditions are added as we want
111 : // to be able to more boundary conditions to a Physics dynamically
112 1596 : if (isParamValid("energy_inlet_types"))
113 1538 : checkVectorParamAndMultiMooseEnumLength<MooseFunctorName>("energy_inlet_functors",
114 : "energy_inlet_types");
115 1596 : if (isParamSetByUser("energy_wall_boundaries"))
116 94 : checkVectorParamsSameLengthIfSet<BoundaryName, MooseFunctorName>(
117 : "energy_wall_boundaries", "energy_wall_functors", false);
118 1596 : if (isParamValid("energy_wall_types"))
119 1552 : checkVectorParamAndMultiMooseEnumLength<MooseFunctorName>("energy_wall_functors",
120 : "energy_wall_types");
121 0 : }
122 :
123 : void
124 1329 : WCNSFVFluidHeatTransferPhysicsBase::addFVKernels()
125 : {
126 : // For compatibility with Modules/NavierStokesFV syntax
127 1329 : if (!_has_energy_equation)
128 : return;
129 :
130 760 : if (shouldCreateTimeDerivative(_solve_for_enthalpy ? _fluid_enthalpy_name
131 : : _fluid_temperature_name,
132 760 : _blocks,
133 : /*error if already defined*/ false))
134 182 : addEnergyTimeKernels();
135 :
136 760 : addEnergyAdvectionKernels();
137 760 : addEnergyHeatConductionKernels();
138 1508 : if (getParam<std::vector<MooseFunctorName>>("ambient_temperature").size())
139 243 : addEnergyAmbientConvection();
140 1508 : if (isParamValid("external_heat_source"))
141 161 : addEnergyExternalHeatSource();
142 : }
143 :
144 : void
145 1319 : WCNSFVFluidHeatTransferPhysicsBase::addFVBCs()
146 : {
147 : // For compatibility with Modules/NavierStokesFV syntax
148 1319 : if (!_has_energy_equation)
149 : return;
150 :
151 750 : addEnergyInletBC();
152 748 : addEnergyWallBC();
153 746 : addEnergyOutletBC();
154 746 : addEnergySeparatorBC();
155 : }
156 :
157 : void
158 13500 : WCNSFVFluidHeatTransferPhysicsBase::actOnAdditionalTasks()
159 : {
160 : // Turbulence physics would not be initialized before this task
161 13500 : if (_current_task == "get_turbulence_physics")
162 1343 : _turbulence_physics = getCoupledTurbulencePhysics();
163 13500 : }
164 :
165 : bool
166 760 : WCNSFVFluidHeatTransferPhysicsBase::processThermalConductivity()
167 : {
168 1518 : checkBlockwiseConsistency<MooseFunctorName>("thermal_conductivity_blocks",
169 : {"thermal_conductivity"});
170 : bool have_scalar = false;
171 : bool have_vector = false;
172 :
173 1537 : for (unsigned int i = 0; i < _thermal_conductivity_name.size(); ++i)
174 : {
175 : // First, check if the name is just a number (only in case of isotropic conduction)
176 779 : if (MooseUtils::parsesToReal(_thermal_conductivity_name[i]))
177 : have_scalar = true;
178 : // Now we determine what kind of functor we are dealing with
179 : else
180 : {
181 420 : if (getProblem().hasFunctorWithType<ADReal>(_thermal_conductivity_name[i],
182 462 : /*thread_id=*/0) ||
183 42 : getProblem().hasFunctorWithType<Real>(_thermal_conductivity_name[i],
184 : /*thread_id=*/0))
185 : have_scalar = true;
186 : else
187 : {
188 42 : if (getProblem().hasFunctorWithType<ADRealVectorValue>(_thermal_conductivity_name[i],
189 : /*thread_id=*/0))
190 : have_vector = true;
191 : else
192 0 : paramError("thermal_conductivity",
193 : "We only allow functor of type Real/ADReal or ADRealVectorValue for thermal "
194 0 : "conductivity! Functor '" +
195 : _thermal_conductivity_name[i] + "' is not of the requested type.");
196 : }
197 : }
198 : }
199 :
200 758 : if (have_vector && !_porous_medium_treatment)
201 2 : paramError("thermal_conductivity", "Cannot use anisotropic diffusion with non-porous flows!");
202 :
203 756 : if (have_vector == have_scalar)
204 2 : paramError("thermal_conductivity",
205 : "The entries on thermal conductivity shall either be scalars of vectors, mixing "
206 : "them is not supported!");
207 754 : return have_vector;
208 : }
209 :
210 : void
211 1331 : WCNSFVFluidHeatTransferPhysicsBase::addInitialConditions()
212 : {
213 : // For compatibility with Modules/NavierStokesFV syntax
214 1331 : if (!_has_energy_equation)
215 569 : return;
216 764 : if (!_define_variables && parameters().isParamSetByUser("initial_temperature"))
217 2 : paramError(
218 : "initial_temperature",
219 : "T_fluid is defined externally of WCNSFVFluidHeatTransferPhysicsBase, so should the inital "
220 : "condition");
221 : // do not set initial conditions if we are not defining variables
222 760 : if (!_define_variables)
223 : {
224 0 : reportPotentiallyMissedParameters({"initial_temperature", "initial_enthalpy"}, "FunctionIC");
225 0 : return;
226 : }
227 :
228 760 : InputParameters params = getFactory().getValidParams("FVFunctionIC");
229 760 : assignBlocks(params, _blocks);
230 :
231 : // initial_temperature has a default so we should almost always set it (see shouldCreateIC logic)
232 : {
233 : bool temperature_ic_used = false;
234 760 : if (variableExists(_fluid_temperature_name, false) &&
235 1406 : shouldCreateIC(_fluid_temperature_name,
236 : _blocks,
237 1463 : /*whether IC is a default*/ !isParamSetByUser("initial_temperature"),
238 2166 : /*error if already an IC*/ isParamSetByUser("initial_temperature")))
239 : {
240 674 : params.set<VariableName>("variable") = _fluid_temperature_name;
241 2022 : params.set<FunctionName>("function") = getParam<FunctionName>("initial_temperature");
242 :
243 1348 : getProblem().addFVInitialCondition("FVFunctionIC", _fluid_temperature_name + "_ic", params);
244 : temperature_ic_used = true;
245 : }
246 : // Needed to solve for enthalpy: an initial condition on enthalpy based on the initial
247 : // temperature
248 1596 : if (isParamValid(NS::fluid) && _solve_for_enthalpy && !isParamValid("initial_enthalpy") &&
249 76 : shouldCreateIC(_fluid_enthalpy_name,
250 : _blocks,
251 798 : /*whether IC is a default*/ !isParamSetByUser("initial_temperature"),
252 836 : /*error if already an IC*/ isParamSetByUser("initial_temperature")))
253 : {
254 : // from the FluidProperties module
255 : InputParameters params =
256 38 : getFactory().getValidParams("SpecificEnthalpyFromPressureTemperatureIC");
257 38 : assignBlocks(params, _blocks);
258 76 : params.set<VariableName>("variable") = _fluid_enthalpy_name;
259 38 : params.set<UserObjectName>(NS::fluid) = getParam<UserObjectName>(NS::fluid);
260 114 : params.set<std::vector<VariableName>>("p") = {_flow_equations_physics->getPressureName()};
261 : Real temp;
262 114 : if (MooseUtils::parsesToReal(getParam<FunctionName>("initial_temperature"), &temp))
263 : {
264 38 : params.defaultCoupledValue("T", temp, 0);
265 38 : params.set<std::vector<VariableName>>("T") = {};
266 : }
267 : else
268 0 : paramError("initial_temperature", "Only Real values supported when solving for enthalpy");
269 114 : getProblem().addInitialCondition(
270 38 : "SpecificEnthalpyFromPressureTemperatureIC", _fluid_enthalpy_name + "_ic", params);
271 : temperature_ic_used = true;
272 38 : }
273 :
274 1530 : if (!temperature_ic_used && isParamSetByUser("initial_temperature"))
275 0 : reportPotentiallyMissedParameters({"initial_temperature"}, "FunctionIC");
276 : }
277 2318 : if (isParamValid("initial_enthalpy") && _solve_for_enthalpy &&
278 38 : shouldCreateIC(_fluid_enthalpy_name,
279 : _blocks,
280 : /*whether IC is a default*/ false,
281 : /*error if already an IC*/ false))
282 : {
283 38 : params.set<VariableName>("variable") = _fluid_enthalpy_name;
284 114 : params.set<FunctionName>("function") = getParam<FunctionName>("initial_enthalpy");
285 :
286 76 : getProblem().addFVInitialCondition("FVFunctionIC", _fluid_enthalpy_name + "_ic", params);
287 : }
288 1444 : else if (isParamValid("initial_enthalpy"))
289 0 : reportPotentiallyMissedParameters({"initial_enthalpy"}, "FunctionIC");
290 798 : }
291 :
292 : void
293 76 : WCNSFVFluidHeatTransferPhysicsBase::defineKOverCpFunctors(const bool use_ad)
294 : {
295 : // Define alpha, the diffusion coefficient when solving for enthalpy, on each block
296 152 : for (unsigned int i = 0; i < _thermal_conductivity_name.size(); ++i)
297 : {
298 76 : const auto object_type = use_ad ? "ADParsedFunctorMaterial" : "ParsedFunctorMaterial";
299 76 : InputParameters params = getFactory().getValidParams(object_type);
300 76 : assignBlocks(params, _blocks);
301 : std::vector<std::string> f_names;
302 76 : if (!MooseUtils::parsesToReal(_thermal_conductivity_name[i]))
303 76 : f_names.push_back(_thermal_conductivity_name[i]);
304 76 : if (!MooseUtils::parsesToReal(getSpecificHeatName()))
305 76 : f_names.push_back(getSpecificHeatName());
306 152 : params.set<std::vector<std::string>>("functor_names") = f_names;
307 152 : params.set<std::string>("expression") =
308 228 : _thermal_conductivity_name[i] + "/" + getSpecificHeatName();
309 152 : params.set<std::string>("property_name") = _thermal_conductivity_name[i] + "_by_cp";
310 228 : getProblem().addMaterial(
311 152 : object_type, prefix() + "rho_alpha_from_" + _thermal_conductivity_name[i], params);
312 76 : }
313 76 : }
314 :
315 : unsigned short
316 3981 : WCNSFVFluidHeatTransferPhysicsBase::getNumberAlgebraicGhostingLayersNeeded() const
317 : {
318 7962 : unsigned short necessary_layers = getParam<unsigned short>("ghost_layers");
319 3981 : necessary_layers =
320 3981 : std::max(necessary_layers, _flow_equations_physics->getNumberAlgebraicGhostingLayersNeeded());
321 11943 : if (getParam<MooseEnum>("energy_face_interpolation") == "skewness-corrected")
322 0 : necessary_layers = std::max(necessary_layers, (unsigned short)3);
323 :
324 3981 : return necessary_layers;
325 : }
|