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  using std::abs;
115 
116  // Evaluate material properties on the face
117  const auto face_arg = singleSidedFaceArg();
118 
119  // radiation resistance has to be solved iteratively, since we don't know the
120  // surface temperature. We do know that the heat flux in the conduction layers
121  // must match the heat flux in the parallel convection-radiation segment. For a
122  // first guess, take the surface temperature as the average of _T and T_ambient.
123  _T_surface = 0.5 * (_T(face_arg, determineState()) + _T_ambient);
124 
125  // total flux perpendicular to boundary
126  ADReal flux;
127 
128  // resistance component representing the sum of the convection and radiation
129  // resistances, in parallel
131 
132  // other iteration requirements
133  unsigned int iteration = 0;
134  ADReal norm = 2 * _tolerance;
135  ADReal T_surface_previous;
136 
137  // iterate to find the approximate surface temperature needed for evaluating the
138  // radiation resistance. We only do this iteration if we have radiation transfer.
139  if (_emissivity > 1e-8)
140  while (norm > (_tolerance * _alpha))
141  {
142  T_surface_previous = _T_surface;
143 
144  // compute the flux based on the conduction part of the circuit
145  flux = (_T(face_arg, determineState()) - _T_surface) / _conduction_resistance;
146 
148 
149  // use the flux computed from the conduction half to update T_surface
151  _T_surface = _alpha * _T_surface + (1 - _alpha) * T_surface_previous;
152  norm = abs(_T_surface - T_surface_previous) / abs(T_surface_previous);
153 
154  if (iteration == _max_iterations)
155  {
156  mooseWarning("Maximum number of iterations reached in 'FunctorThermalResistanceBC'!");
157  break;
158  }
159  else
160  iteration += 1;
161  }
162 
163  // once we have determined T_surface, we can finally evaluate the complete
164  // resistance to find the overall heat flux. For Cartesian, dividing by the
165  // 'inner_radius' has no effect, but it is required for correct normalization
166  // for cylindrical geometries.
167  flux = (_T(face_arg, determineState()) - _T_ambient) /
169  return flux;
170 }
171 
172 void
174 {
175  const auto face_arg = singleSidedFaceArg();
176 
177  // compute the parallel convection and radiation resistances, assuming they
178  // act on the same surface area size
181 
182  // for Cartesian, dividing by the 'outer_radius' has no effect, but it is
183  // required for correct normalization for cylindrical geometries
184  _parallel_resistance = 1.0 / (hr + _h(face_arg, determineState())) / _outer_radius;
185 }
MetaPhysicL::DualNumber< V, D, asd > abs(const MetaPhysicL::DualNumber< V, D, asd > &a)
ADReal _conduction_resistance
conduction thermal resistance
const Real _T_ambient
ambient temperature for convection and radiation heat transfer
void paramError(const std::string &param, Args... args) const
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
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()
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
void mooseWarning(Args &&... args) const
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.