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 "HeatConductionCG.h"
11 : #include "ADHeatConduction.h"
12 : #include "HeatConductionTimeDerivative.h"
13 :
14 : // Register the actions for the objects actually used
15 : registerPhysicsBaseTasks("HeatTransferApp", HeatConductionCG);
16 : registerMooseAction("HeatTransferApp", HeatConductionCG, "add_kernel");
17 : registerMooseAction("HeatTransferApp", HeatConductionCG, "add_bc");
18 : registerMooseAction("HeatTransferApp", HeatConductionCG, "add_variables_physics");
19 : registerMooseAction("HeatTransferApp", HeatConductionCG, "add_ics_physics");
20 : registerMooseAction("HeatTransferApp", HeatConductionCG, "add_preconditioning");
21 :
22 : InputParameters
23 36 : HeatConductionCG::validParams()
24 : {
25 36 : InputParameters params = HeatConductionPhysicsBase::validParams();
26 36 : params.addClassDescription("Creates the heat conduction equation discretized with CG");
27 :
28 : // Material properties
29 36 : params.transferParam<MaterialPropertyName>(ADHeatConduction::validParams(),
30 : "thermal_conductivity");
31 36 : params.transferParam<MaterialPropertyName>(HeatConductionTimeDerivative::validParams(),
32 : "specific_heat");
33 72 : params.addParam<MaterialPropertyName>("density", "density", "Density material property");
34 72 : params.addParamNamesToGroup("thermal_conductivity specific_heat density", "Thermal properties");
35 :
36 72 : params.addParam<bool>(
37 : "use_automatic_differentiation",
38 72 : true,
39 : "Whether to use automatic differentiation for all the terms in the equation");
40 :
41 36 : return params;
42 0 : }
43 :
44 36 : HeatConductionCG::HeatConductionCG(const InputParameters & parameters)
45 72 : : HeatConductionPhysicsBase(parameters), _use_ad(getParam<bool>("use_automatic_differentiation"))
46 : {
47 36 : }
48 :
49 : void
50 36 : HeatConductionCG::addFEKernels()
51 : {
52 : {
53 45 : const std::string kernel_type = _use_ad ? "ADHeatConduction" : "HeatConduction";
54 36 : InputParameters params = getFactory().getValidParams(kernel_type);
55 36 : assignBlocks(params, _blocks);
56 72 : params.set<NonlinearVariableName>("variable") = _temperature_name;
57 36 : if (_use_ad)
58 54 : params.applyParameter(parameters(), "thermal_conductivity");
59 : else
60 18 : params.set<MaterialPropertyName>("diffusion_coefficient") =
61 18 : getParam<MaterialPropertyName>("thermal_conductivity");
62 72 : getProblem().addKernel(kernel_type, prefix() + _temperature_name + "_conduction", params);
63 36 : }
64 72 : if (isParamValid("heat_source_var"))
65 : {
66 36 : const std::string kernel_type = _use_ad ? "ADCoupledForce" : "CoupledForce";
67 27 : InputParameters params = getFactory().getValidParams(kernel_type);
68 54 : params.set<NonlinearVariableName>("variable") = _temperature_name;
69 81 : params.set<std::vector<VariableName>>("v") = {getParam<VariableName>("heat_source_var")};
70 27 : if (isParamValid("heat_source_blocks"))
71 54 : params.set<std::vector<SubdomainName>>("block") =
72 81 : getParam<std::vector<SubdomainName>>("heat_source_blocks");
73 : else
74 0 : assignBlocks(params, _blocks);
75 54 : getProblem().addKernel(kernel_type, prefix() + _temperature_name + "_source", params);
76 27 : }
77 72 : if (isParamValid("heat_source_functor"))
78 : {
79 18 : const std::string kernel_type = "BodyForce";
80 18 : InputParameters params = getFactory().getValidParams(kernel_type);
81 36 : if (isParamValid("heat_source_blocks"))
82 36 : params.set<std::vector<SubdomainName>>("block") =
83 54 : getParam<std::vector<SubdomainName>>("heat_source_blocks");
84 : else
85 0 : assignBlocks(params, _blocks);
86 36 : params.set<NonlinearVariableName>("variable") = _temperature_name;
87 18 : const auto & functor_name = getParam<MooseFunctorName>("heat_source_functor");
88 18 : if (MooseUtils::parsesToReal(functor_name))
89 18 : params.set<Real>("value") = std::stod(functor_name);
90 0 : else if (getProblem().hasFunction(functor_name))
91 0 : params.set<FunctionName>("function") = functor_name;
92 0 : else if (getProblem().hasPostprocessorValueByName(functor_name))
93 0 : params.set<PostprocessorName>("postprocessor") = functor_name;
94 : else
95 0 : paramError("heat_source_functor", "Unsupported functor type.");
96 36 : getProblem().addKernel(kernel_type, prefix() + _temperature_name + "_source_functor", params);
97 18 : }
98 36 : if (shouldCreateTimeDerivative(_temperature_name, _blocks, /*error if already defined*/ false))
99 : {
100 : const std::string kernel_type =
101 0 : _use_ad ? "ADHeatConductionTimeDerivative" : "SpecificHeatConductionTimeDerivative";
102 0 : InputParameters params = getFactory().getValidParams(kernel_type);
103 0 : assignBlocks(params, _blocks);
104 0 : params.set<NonlinearVariableName>("variable") = _temperature_name;
105 0 : if (_use_ad)
106 0 : params.set<MaterialPropertyName>("density_name") = getParam<MaterialPropertyName>("density");
107 : else
108 0 : params.applyParameter(parameters(), "density");
109 0 : params.applyParameter(parameters(), "specific_heat");
110 0 : getProblem().addKernel(kernel_type, prefix() + _temperature_name + "_time", params);
111 0 : }
112 90 : }
113 :
114 : void
115 36 : HeatConductionCG::addFEBCs()
116 : {
117 : // We dont need to add anything for insulated boundaries, 0 flux is the default boundary condition
118 72 : if (isParamValid("heat_flux_boundaries"))
119 : {
120 36 : const std::string bc_type = "FunctorNeumannBC";
121 36 : InputParameters params = getFactory().getValidParams(bc_type);
122 72 : params.set<NonlinearVariableName>("variable") = _temperature_name;
123 :
124 36 : const auto & heat_flux_boundaries = getParam<std::vector<BoundaryName>>("heat_flux_boundaries");
125 : const auto & boundary_heat_fluxes =
126 72 : getParam<std::vector<MooseFunctorName>>("boundary_heat_fluxes");
127 : // Optimization if all the same
128 72 : if (std::set<MooseFunctorName>(boundary_heat_fluxes.begin(), boundary_heat_fluxes.end())
129 36 : .size() == 1 &&
130 : heat_flux_boundaries.size() > 1)
131 : {
132 0 : params.set<std::vector<BoundaryName>>("boundary") = heat_flux_boundaries;
133 0 : params.set<MooseFunctorName>("functor") = boundary_heat_fluxes[0];
134 0 : getProblem().addBoundaryCondition(
135 0 : bc_type, prefix() + _temperature_name + "_heat_flux_bc_all", params);
136 : }
137 : else
138 : {
139 90 : for (const auto i : index_range(heat_flux_boundaries))
140 : {
141 162 : params.set<std::vector<BoundaryName>>("boundary") = {heat_flux_boundaries[i]};
142 54 : params.set<MooseFunctorName>("functor") = boundary_heat_fluxes[i];
143 108 : getProblem().addBoundaryCondition(bc_type,
144 162 : prefix() + _temperature_name + "_heat_flux_bc_" +
145 : heat_flux_boundaries[i],
146 : params);
147 : }
148 : }
149 36 : }
150 72 : if (isParamValid("fixed_temperature_boundaries"))
151 : {
152 36 : const std::string bc_type = "FunctorDirichletBC";
153 36 : InputParameters params = getFactory().getValidParams(bc_type);
154 72 : params.set<NonlinearVariableName>("variable") = _temperature_name;
155 :
156 : const auto & temperature_boundaries =
157 36 : getParam<std::vector<BoundaryName>>("fixed_temperature_boundaries");
158 : const auto & boundary_temperatures =
159 72 : getParam<std::vector<MooseFunctorName>>("boundary_temperatures");
160 : // Optimization if all the same
161 72 : if (std::set<MooseFunctorName>(boundary_temperatures.begin(), boundary_temperatures.end())
162 36 : .size() == 1 &&
163 : temperature_boundaries.size() > 1)
164 : {
165 0 : params.set<std::vector<BoundaryName>>("boundary") = temperature_boundaries;
166 0 : params.set<MooseFunctorName>("functor") = boundary_temperatures[0];
167 0 : getProblem().addBoundaryCondition(
168 0 : bc_type, prefix() + _temperature_name + "_dirichlet_bc_all", params);
169 : }
170 : else
171 : {
172 72 : for (const auto i : index_range(temperature_boundaries))
173 : {
174 108 : params.set<std::vector<BoundaryName>>("boundary") = {temperature_boundaries[i]};
175 36 : params.set<MooseFunctorName>("functor") = boundary_temperatures[i];
176 72 : getProblem().addBoundaryCondition(bc_type,
177 108 : prefix() + _temperature_name + "_dirichlet_bc_" +
178 : temperature_boundaries[i],
179 : params);
180 : }
181 : }
182 36 : }
183 72 : if (isParamValid("fixed_convection_boundaries"))
184 : {
185 36 : const std::string bc_type = "ADConvectiveHeatFluxBC";
186 36 : InputParameters params = getFactory().getValidParams(bc_type);
187 72 : params.set<NonlinearVariableName>("variable") = _temperature_name;
188 :
189 : const auto & convective_boundaries =
190 36 : getParam<std::vector<BoundaryName>>("fixed_convection_boundaries");
191 : const auto & boundary_T_fluid =
192 36 : getParam<std::vector<MooseFunctorName>>("fixed_convection_T_fluid");
193 36 : const auto & boundary_htc = getParam<std::vector<MooseFunctorName>>("fixed_convection_htc");
194 :
195 36 : if (!_use_ad && convective_boundaries.size())
196 0 : paramInfo("use_automatic_differentiation",
197 : "No-AD is not implemented for convection boundaries");
198 :
199 : // Optimization if all the same
200 72 : if (std::set<MooseFunctorName>(boundary_T_fluid.begin(), boundary_T_fluid.end()).size() == 1 &&
201 36 : std::set<MooseFunctorName>(boundary_htc.begin(), boundary_htc.end()).size() == 1 &&
202 : convective_boundaries.size() > 1)
203 : {
204 0 : params.set<std::vector<BoundaryName>>("boundary") = convective_boundaries;
205 0 : params.set<MooseFunctorName>("T_infinity_functor") = boundary_T_fluid[0];
206 0 : params.set<MooseFunctorName>("heat_transfer_coefficient_functor") = boundary_htc[0];
207 0 : getProblem().addBoundaryCondition(
208 0 : bc_type, prefix() + _temperature_name + "_fixed_convection_bc_all", params);
209 : }
210 : else
211 : {
212 : // Check sizes
213 36 : if (convective_boundaries.size() != boundary_T_fluid.size())
214 0 : paramError("fixed_convection_T_fluid",
215 0 : "Should be as many convection boundaries (" +
216 0 : std::to_string(convective_boundaries.size()) +
217 0 : ") as fixed convection temperatures (" +
218 0 : std::to_string(boundary_T_fluid.size()) + ")");
219 36 : if (convective_boundaries.size() != boundary_htc.size())
220 0 : paramError("fixed_convection_htc",
221 0 : "Should be as many convection boundaries (" +
222 0 : std::to_string(convective_boundaries.size()) +
223 0 : ") as fixed convection heat exchange coefficients (" +
224 0 : std::to_string(boundary_htc.size()) + ")");
225 54 : for (const auto i : index_range(convective_boundaries))
226 : {
227 54 : params.set<std::vector<BoundaryName>>("boundary") = {convective_boundaries[i]};
228 36 : params.set<MooseFunctorName>("T_infinity_functor") = boundary_T_fluid[i];
229 18 : params.set<MooseFunctorName>("heat_transfer_coefficient_functor") = boundary_htc[i];
230 36 : getProblem().addBoundaryCondition(bc_type,
231 54 : prefix() + _temperature_name + "_fixed_convection_bc_" +
232 : convective_boundaries[i],
233 : params);
234 : }
235 : }
236 36 : }
237 36 : }
238 :
239 : void
240 36 : HeatConductionCG::addSolverVariables()
241 : {
242 36 : if (!shouldCreateVariable(_temperature_name, _blocks, /*error if aux*/ true))
243 : {
244 0 : reportPotentiallyMissedParameters({"system_names"}, "MooseVariable");
245 0 : return;
246 : }
247 :
248 36 : const std::string variable_type = "MooseVariable";
249 : // defaults to linear lagrange FE family
250 36 : InputParameters params = getFactory().getValidParams(variable_type);
251 36 : params.set<SolverSystemName>("solver_sys") = getSolverSystem(_temperature_name);
252 36 : assignBlocks(params, _blocks);
253 :
254 36 : getProblem().addVariable(variable_type, _temperature_name, params);
255 36 : }
|