https://mooseframework.inl.gov
ADConvectiveHeatFluxBC.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 "ADConvectiveHeatFluxBC.h"
11 
13 
16 {
18  params.addClassDescription(
19  "Convective heat transfer boundary condition with temperature and heat "
20  "transfer coefficient given by material properties.");
21  // Using material properties
22  params.addParam<MaterialPropertyName>("T_infinity",
23  "Material property for far-field temperature");
24  params.addParam<MaterialPropertyName>("heat_transfer_coefficient",
25  "Material property for heat transfer coefficient");
26  // Using functors
27  params.addParam<MooseFunctorName>("T_infinity_functor", "Functor for far-field temperature");
28  params.addParam<MooseFunctorName>("heat_transfer_coefficient_functor",
29  "Functor for heat transfer coefficient");
30  // In the case where we are coupling a FV variable (via functors) that are block restricted on the
31  // neighboring side of boundary, we need to have two layers of ghosting to do the face
32  // interpolation.
33  params.addRelationshipManager("ElementSideNeighborLayers",
36  [](const InputParameters & obj_params, InputParameters & rm_params)
37  {
38  rm_params.set<unsigned short>("layers") =
39  obj_params.isParamValid("T_infinity_functor") ? 2 : 1;
40  });
41  return params;
42 }
43 
45  : ADIntegratedBC(parameters),
46  _T_infinity(isParamValid("T_infinity") ? &getADMaterialProperty<Real>("T_infinity") : nullptr),
47  _htc(isParamValid("heat_transfer_coefficient")
48  ? &getADMaterialProperty<Real>("heat_transfer_coefficient")
49  : nullptr),
50  _T_infinity_functor(
51  isParamValid("T_infinity_functor") ? &getFunctor<ADReal>("T_infinity_functor") : nullptr),
52  _htc_functor(isParamValid("heat_transfer_coefficient_functor")
53  ? &getFunctor<ADReal>("heat_transfer_coefficient_functor")
54  : nullptr)
55 {
56  if (_T_infinity || _htc)
57  {
59  paramError("T_infinity_functor",
60  "Either material properties or functors should be specified for both T_infinity "
61  "and the heat transfer coefficient.");
62  if (_htc_functor)
63  paramError("heat_transfer_coefficient_functor",
64  "Either material properties or functors should be specified for both T_infinity "
65  "and the heat transfer coefficient");
66  if (!_htc)
67  paramError("heat_transfer_coefficient",
68  "Heat transfer coefficient material property must be specified");
69  if (!_T_infinity)
70  paramError("T_infinity", "Far field temperature material property must be specified");
71  }
73  {
74  if (!_htc_functor)
75  paramError("heat_transfer_coefficient_functor",
76  "Heat transfer coefficient functor must be specified");
78  paramError("T_infinity_functor", "Far field temperature functor must be specified");
79  }
80  else
81  paramError("T_infinity",
82  "Far field temperature and heat transfer coefficients must be specified");
83 }
84 
85 void
87 {
88  if (_T_infinity)
89  return;
90 
91  bool T_inf_can_use_neighbor = true;
92  bool htc_can_use_neighbor = true;
93  // Loop over elements on the primary side of all boundaries
94  for (const auto & bnd_elem : *_mesh.getBoundaryElementRange())
95  {
96  const auto & [elem, side, bid] = *bnd_elem;
97  // Skip if this boundary is not part of the restriction
98  if (!hasBoundary(bid))
99  continue;
100 
101  // Use neighbors if the functor is not defined on all primary blocks
103  _T_infinity_use_neighbor || !_T_infinity_functor->hasBlocks(elem->subdomain_id());
104  _htc_use_neighbor = _htc_use_neighbor || !_htc_functor->hasBlocks(elem->subdomain_id());
105 
106  // Determine if neighbor can be used, just in case
107  const auto neighbor = elem->neighbor_ptr(side);
108  T_inf_can_use_neighbor = T_inf_can_use_neighbor && neighbor &&
109  _T_infinity_functor->hasBlocks(neighbor->subdomain_id());
110  htc_can_use_neighbor =
111  htc_can_use_neighbor && neighbor && _htc_functor->hasBlocks(neighbor->subdomain_id());
112  }
113 
114  const std::string error_msg =
115  "Functor must either be defined on all of the primary side of the boundary or on all "
116  "of the secondary side.";
117  if (_T_infinity_use_neighbor && !T_inf_can_use_neighbor)
118  paramError("T_infinity_functor", error_msg);
119  if (_htc_use_neighbor && !htc_can_use_neighbor)
120  paramError("heat_transfer_coefficient_functor", error_msg);
121 }
122 
123 ADReal
125 {
126  if (_T_infinity)
127  return -_test[_i][_qp] * (*_htc)[_qp] * ((*_T_infinity)[_qp] - _u[_qp]);
128  else
129  {
130  // Populate neighbor information, if necessary (optimization on first qp)
132  {
134  mooseAssert(_current_neighbor_elem, "Neighbor element should exist at this point.");
136  }
137 
138  // Convenience lambda for getting space argument on either element or neighbor
139  const auto get_space_arg = [this](bool use_neighbor) -> Moose::ElemSideQpArg
140  {
141  if (!use_neighbor)
143  else
145  };
146 
147  const auto Tinf_space_arg = get_space_arg(_T_infinity_use_neighbor);
148  const auto htc_space_arg = get_space_arg(_htc_use_neighbor);
149  const auto time_arg = Moose::currentState();
150  return -_test[_i][_qp] * (*_htc_functor)(htc_space_arg, time_arg) *
151  ((*_T_infinity_functor)(Tinf_space_arg, time_arg) - _u[_qp]);
152  }
153 }
Boundary condition for convective heat flux where temperature and heat transfer coefficient are given...
bool _T_infinity_use_neighbor
Whether the far-field temperature functor should be evaluated on neighbor elements.
const ADTemplateVariableValue< T > & _u
registerMooseObject("HeatTransferApp", ADConvectiveHeatFluxBC)
void addParam(const std::string &name, const std::initializer_list< typename T::value_type > &value, const std::string &doc_string)
virtual ADReal computeQpResidual() override
static InputParameters validParams()
const Elem *const & _current_elem
const ADMaterialProperty< Real > *const _htc
Convective heat transfer coefficient.
T & set(const std::string &name, bool quiet_mode=false)
const Elem * _current_neighbor_elem
Neighbor of the current element&#39;s side (can be nullptr)
const ADMaterialProperty< Real > *const _T_infinity
Far-field temperature variable.
void addRelationshipManager(const std::string &name, Moose::RelationshipManagerType rm_type, Moose::RelationshipManagerInputParameterCallback input_parameter_callback=nullptr)
ADConvectiveHeatFluxBC(const InputParameters &parameters)
DualNumber< Real, DNDerivativeType, true > ADReal
static InputParameters validParams()
unsigned int _qp
const MooseArray< Point > & _q_point
unsigned int _current_neighbor_side
Corresponding side on the neighbor.
virtual void initialSetup() override
Here we check if the functors are defined on primary side of the boundary.
void paramError(const std::string &param, Args... args) const
bool hasBoundary(const BoundaryName &name) const
const QBase *const & _qrule
const unsigned int & _current_side
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
const ADTemplateVariableTestValue< T > & _test
const Moose::Functor< ADReal > *const _T_infinity_functor
Far-field temperature functor.
bool _htc_use_neighbor
Whether the heat transfer coefficient functor should be evaluated on neighbor elements.
void addClassDescription(const std::string &doc_string)
libMesh::StoredRange< MooseMesh::const_bnd_elem_iterator, const BndElement *> * getBoundaryElementRange()
StateArg currentState()
const Moose::Functor< ADReal > *const _htc_functor
Convective heat transfer coefficient as a functor.
bool isParamValid(const std::string &name) const