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