https://mooseframework.inl.gov
FunctorThermalResistanceBC.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 
11 #include "HeatConductionNames.h"
12 
14 
17 {
18  auto params = FVFluxBC::validParams();
19  params.addParam<MooseFunctorName>("temperature", "temperature variable");
20  params.addRequiredParam<Real>(HeatConduction::T_ambient, "constant ambient temperature");
21  params.addRequiredParam<MooseFunctorName>("htc", "heat transfer coefficient");
22 
23  params.addRequiredRangeCheckedParam<Real>(HeatConduction::emissivity,
24  HeatConduction::emissivity + " >= 0.0 & " +
25  HeatConduction::emissivity + " <= 1.0",
26  "emissivity of the surface");
27 
28  params.addRequiredParam<std::vector<Real>>(
29  "thermal_conductivities",
30  "vector of thermal conductivity values used for the conduction layers");
31  params.addRequiredParam<std::vector<Real>>("conduction_thicknesses",
32  "vector of conduction layer thicknesses");
33 
34  MooseEnum geometry("cartesian cylindrical", "cartesian");
35  params.addParam<MooseEnum>("geometry", geometry, "type of geometry");
36  params.addRangeCheckedParam<Real>("inner_radius",
37  "inner_radius > 0.0",
38  "coordinate corresponding to the first resistance layer");
39 
40  params.addRangeCheckedParam<Real>(
41  "step_size", 0.1, "step_size > 0.0", "underrelaxation step size");
42 
43  params.addRangeCheckedParam<unsigned int>(
44  "max_iterations", 100, "max_iterations >= 0", "maximum iterations");
45 
46  params.addRangeCheckedParam<Real>(
47  "tolerance", 1E-3, "tolerance > 0.0", "tolerance to converge iterations");
48  params.addClassDescription("Thermal resistance heat flux boundary condition for the "
49  "fluid and solid energy equations");
50  return params;
51 }
52 
54  : FVFluxBC(parameters),
55  _geometry(getParam<MooseEnum>("geometry").getEnum<Moose::CoordinateSystemType>()),
56  _inner_radius(
57  _geometry == Moose::CoordinateSystemType::COORD_RZ ? getParam<Real>("inner_radius") : 1.0),
58  _T(isParamValid("temperature") ? getFunctor<ADReal>("temperature")
59  : getFunctor<ADReal>("variable")),
60  _T_ambient(getParam<Real>(HeatConduction::T_ambient)),
61  _k(getParam<std::vector<Real>>("thermal_conductivities")),
62  _dx(getParam<std::vector<Real>>("conduction_thicknesses")),
63  _h(getFunctor<ADReal>(getParam<MooseFunctorName>("htc"))),
64  _emissivity(getParam<Real>(HeatConduction::emissivity)),
65  _max_iterations(getParam<unsigned int>("max_iterations")),
66  _tolerance(getParam<Real>("tolerance")),
67  _alpha(getParam<Real>("step_size")),
68  _T_surface(0.0),
69  _outer_radius(_inner_radius),
70  _conduction_resistance(0.0),
71  _parallel_resistance(0.0)
72 {
73  if (_k.size() != _dx.size())
74  paramError("conduction_thicknesses",
75  "Number of specified thermal conductivities must match "
76  "the number of conduction layers!");
77 
78  if (_geometry == Moose::CoordinateSystemType::COORD_RZ)
79  for (const auto & d : _dx)
80  _outer_radius += d;
81 
82  // because the thermal conductivities are constant, we only need to compute
83  // the conduction resistance one time
85 }
86 
87 void
89 {
90  Real r = _inner_radius;
91 
92  for (const auto i : index_range(_k))
93  {
94  switch (_geometry)
95  {
96  case Moose::CoordinateSystemType::COORD_XYZ:
97  _conduction_resistance += _dx[i] / _k[i];
98  break;
99  case Moose::CoordinateSystemType::COORD_RZ:
100  {
101  _conduction_resistance += std::log((_dx[i] + r) / r) / _k[i];
102  r += _dx[i];
103  break;
104  }
105  default:
106  mooseError("Unhandled 'GeometryEnum' in 'FunctorThermalResistanceBC'!");
107  }
108  }
109 }
110 
111 ADReal
113 {
114  // Evaluate material properties on the face
115  const auto face_arg = singleSidedFaceArg();
116 
117  // radiation resistance has to be solved iteratively, since we don't know the
118  // surface temperature. We do know that the heat flux in the conduction layers
119  // must match the heat flux in the parallel convection-radiation segment. For a
120  // first guess, take the surface temperature as the average of _T and T_ambient.
121  _T_surface = 0.5 * (_T(face_arg, determineState()) + _T_ambient);
122 
123  // total flux perpendicular to boundary
124  ADReal flux;
125 
126  // resistance component representing the sum of the convection and radiation
127  // resistances, in parallel
129 
130  // other iteration requirements
131  unsigned int iteration = 0;
132  ADReal norm = 2 * _tolerance;
133  ADReal T_surface_previous;
134 
135  // iterate to find the approximate surface temperature needed for evaluating the
136  // radiation resistance. We only do this iteration if we have radiation transfer.
137  if (_emissivity > 1e-8)
138  while (norm > (_tolerance * _alpha))
139  {
140  T_surface_previous = _T_surface;
141 
142  // compute the flux based on the conduction part of the circuit
143  flux = (_T(face_arg, determineState()) - _T_surface) / _conduction_resistance;
144 
146 
147  // use the flux computed from the conduction half to update T_surface
149  _T_surface = _alpha * _T_surface + (1 - _alpha) * T_surface_previous;
150  norm = std::abs(_T_surface - T_surface_previous) / std::abs(T_surface_previous);
151 
152  if (iteration == _max_iterations)
153  {
154  mooseWarning("Maximum number of iterations reached in 'FunctorThermalResistanceBC'!");
155  break;
156  }
157  else
158  iteration += 1;
159  }
160 
161  // once we have determined T_surface, we can finally evaluate the complete
162  // resistance to find the overall heat flux. For Cartesian, dividing by the
163  // 'inner_radius' has no effect, but it is required for correct normalization
164  // for cylindrical geometries.
165  flux = (_T(face_arg, determineState()) - _T_ambient) /
167  return flux;
168 }
169 
170 void
172 {
173  const auto face_arg = singleSidedFaceArg();
174 
175  // compute the parallel convection and radiation resistances, assuming they
176  // act on the same surface area size
179 
180  // for Cartesian, dividing by the 'outer_radius' has no effect, but it is
181  // required for correct normalization for cylindrical geometries
182  _parallel_resistance = 1.0 / (hr + _h(face_arg, determineState())) / _outer_radius;
183 }
ADReal _conduction_resistance
conduction thermal resistance
const Real _T_ambient
ambient temperature for convection and radiation heat transfer
static InputParameters validParams()
const Moose::Functor< ADReal > & _h
convective heat transfer coefficient
const Real & _alpha
underrelaxation factor (when radiative heat transfer is included)
Moose::StateArg determineState() const
const std::vector< Real > & _dx
thicknesses for each conduction layer, listed in order closest to the boundary
const Real & _emissivity
boundary emissivity
FunctorThermalResistanceBC(const InputParameters &parameters)
COORD_RZ
ADReal _outer_radius
outer radius of surface
Moose::FaceArg singleSidedFaceArg(const FaceInfo *fi=nullptr, Moose::FV::LimiterType limiter_type=Moose::FV::LimiterType::CentralDifference, bool correct_skewness=false, const Moose::StateArg *state_limiter=nullptr) const
const Real _inner_radius
Radius corresponding to the cylindrical surface (when using a cylindrical geometry) ...
DualNumber< Real, DNDerivativeType, true > ADReal
void mooseWarning(Args &&... args) const
static const std::string T_ambient
This BC applies a heat flux to a boundary, where the heat flux is determined using series conduction ...
static InputParameters validParams()
void paramError(const std::string &param, Args... args) const
const unsigned int & _max_iterations
maximum number of iterations (when radiative heat transfer is included)
auto norm(const T &a) -> decltype(std::abs(a))
ADReal _parallel_resistance
parallel convection and radiation thermal resistance
const Real & _tolerance
tolerance of iterations (when radiative heat transfer is included)
ADReal _T_surface
surface temperature
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
registerMooseObject("HeatTransferApp", FunctorThermalResistanceBC)
virtual ADReal computeQpResidual() override
CoordinateSystemType
const Moose::Functor< ADReal > & _T
temperature variable
void mooseError(Args &&... args) const
const Moose::CoordinateSystemType _geometry
Whether to use a cylindrical or cartesian form for the thermal resistances.
const std::vector< Real > & _k
thermal conductivities for each conduction layer, listed in order closest to the boundary ...
void ErrorVector unsigned int
auto index_range(const T &sizable)
static const std::string emissivity
void computeConductionResistance()
Computes the serial resistance of multiple conductive layers.
void computeParallelResistance()
Computes the parallel heat flux resistance for a combined radiation-convection boundary.