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