https://mooseframework.inl.gov
Loading...
Searching...
No Matches
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
11
13
16{
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",
34 Moose::RelationshipManagerType::GEOMETRIC |
35 Moose::RelationshipManagerType::ALGEBRAIC,
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
85void
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) || (elem->processor_id() != this->processor_id()))
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 if (neighbor)
109 mooseAssert(
110 !neighbor->is_remote(),
111 "The neighbor best not be remote because we request at least one layer of ghosting");
112 T_inf_can_use_neighbor = T_inf_can_use_neighbor && neighbor &&
113 _T_infinity_functor->hasBlocks(neighbor->subdomain_id());
114 htc_can_use_neighbor =
115 htc_can_use_neighbor && neighbor && _htc_functor->hasBlocks(neighbor->subdomain_id());
116 }
117
120
121 const std::string error_msg =
122 "Functor must either be defined on all of the primary side of the boundary or on all "
123 "of the secondary side.";
124 if (_T_infinity_use_neighbor && !T_inf_can_use_neighbor)
125 paramError("T_infinity_functor", error_msg);
126 if (_htc_use_neighbor && !htc_can_use_neighbor)
127 paramError("heat_transfer_coefficient_functor", error_msg);
128}
129
130ADReal
132{
133 if (_T_infinity)
134 return -_test[_i][_qp] * (*_htc)[_qp] * ((*_T_infinity)[_qp] - _u[_qp]);
135 else
136 {
137 // Populate neighbor information, if necessary (optimization on first qp)
139 {
141 mooseAssert(_current_neighbor_elem, "Neighbor element should exist at this point.");
143 }
144
145 // Convenience lambda for getting space argument on either element or neighbor
146 const auto get_space_arg = [this](bool use_neighbor) -> Moose::ElemSideQpArg
147 {
148 if (!use_neighbor)
150 else
152 };
153
154 const auto Tinf_space_arg = get_space_arg(_T_infinity_use_neighbor);
155 const auto htc_space_arg = get_space_arg(_htc_use_neighbor);
156 const auto time_arg = Moose::currentState();
157 return -_test[_i][_qp] * (*_htc_functor)(htc_space_arg, time_arg) *
158 ((*_T_infinity_functor)(Tinf_space_arg, time_arg) - _u[_qp]);
159 }
160}
registerMooseObject("HeatTransferApp", ADConvectiveHeatFluxBC)
DualNumber< Real, DNDerivativeType, true > ADReal
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 Moose::Functor< ADReal > *const _htc_functor
Convective heat transfer coefficient as a functor.
const ADMaterialProperty< Real > *const _T_infinity
Far-field temperature variable.
bool _htc_use_neighbor
Whether the heat transfer coefficient functor should be evaluated on neighbor elements.
const Moose::Functor< ADReal > *const _T_infinity_functor
Far-field temperature functor.
ADConvectiveHeatFluxBC(const InputParameters &parameters)
unsigned int _current_neighbor_side
Corresponding side on the neighbor.
virtual ADReal computeQpResidual() override
const Elem * _current_neighbor_elem
Neighbor of the current element's side (can be nullptr)
static InputParameters validParams()
const ADMaterialProperty< Real > *const _htc
Convective heat transfer coefficient.
virtual void initialSetup() override
Here we check if the functors are defined on primary side of the boundary.
const ADTemplateVariableValue< T > & _u
static InputParameters validParams()
const ADTemplateVariableTestValue< T > & _test
bool hasBoundary(const BoundaryName &name) const
void addParam(const std::string &name, const std::initializer_list< typename T::value_type > &value, const std::string &doc_string)
void addRelationshipManager(const std::string &name, Moose::RelationshipManagerType rm_type, Moose::RelationshipManagerInputParameterCallback input_parameter_callback=nullptr)
void addClassDescription(const std::string &doc_string)
T & set(const std::string &name, bool quiet_mode=false)
bool isParamValid(const std::string &name) const
const unsigned int & _current_side
const QBase *const & _qrule
unsigned int _qp
const Elem *const & _current_elem
const MooseArray< Point > & _q_point
void paramError(const std::string &param, Args... args) const
libMesh::StoredRange< MooseMesh::const_bnd_elem_iterator, const BndElement * > * getBoundaryElementRange()
void max(const T &r, T &o, Request &req) const
const Parallel::Communicator & _communicator
processor_id_type processor_id() const
StateArg currentState()