https://mooseframework.inl.gov
Loading...
Searching...
No Matches
HSCoupler2D3DUserObject.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
12#include "MeshAlignment2D3D.h"
13#include "THMUtils.h"
14#include "HeatTransferModels.h"
15#include "Function.h"
16
18
21{
23
24 params.addRequiredCoupledVar("temperature", "Temperature");
25 params.addRequiredParam<Real>("radius_2d", "Radius of the 2D heat structure boundary [m]");
26 params.addParam<FunctionName>(
27 "emissivity_2d",
28 0,
29 "Emissivity of the 2D heat structure boundary as a function of temperature [K]");
30 params.addParam<FunctionName>(
31 "emissivity_3d",
32 0,
33 "Emissivity of the 3D heat structure boundary as a function of temperature [K]");
34 params.addRequiredParam<FunctionName>("gap_thickness",
35 "Gap thickness [m] as a function of temperature [K]");
36 params.addRequiredParam<FunctionName>(
37 "gap_thermal_conductivity",
38 "Gap thermal conductivity [W/(m-K)] as a function of temperature [K]");
39 params.addParam<FunctionName>(
40 "gap_htc", 0, "Gap heat transfer coefficient [W/(m^2-K)] as a function of temperature [K]");
41 params.addRequiredParam<UserObjectName>(
42 "temperature_2d_uo",
43 "StoreVariableByElemIDSideUserObject containing the temperature values on the 2D boundary");
44 params.addRequiredParam<MeshAlignment2D3D *>("mesh_alignment", "Mesh alignment object");
45 params.addRangeCheckedParam<Real>("symmetry_factor",
46 1.0,
47 "symmetry_factor>=1.0",
48 "Azimuthal symmetry correction factor (>= 1.0). Equal to 2*pi "
49 "divided by the azimuthal angle covered by the 3D mesh.");
50
51 params.addClassDescription("Computes heat fluxes for HSCoupler2D3D.");
52
53 return params;
54}
55
57 : SideUserObject(parameters),
58
59 _T_3d(adCoupledValue("temperature")),
60 _r_2d(getParam<Real>("radius_2d")),
61 _emissivity_2d_fn(getFunction("emissivity_2d")),
62 _emissivity_3d_fn(getFunction("emissivity_3d")),
63 _include_radiation(isParamSetByUser("emissivity_2d") && isParamSetByUser("emissivity_3d")),
64 _gap_thickness_fn(getFunction("gap_thickness")),
65 _k_gap_fn(getFunction("gap_thermal_conductivity")),
66 _htc_gap_fn(getFunction("gap_htc")),
67 _temperature_2d_uo(getUserObject<StoreVariableByElemIDSideUserObject>("temperature_2d_uo")),
68 _mesh_alignment(*getParam<MeshAlignment2D3D *>("mesh_alignment")),
69 _symmetry_factor(getParam<Real>("symmetry_factor"))
70{
72}
73
74void
79
80void
82{
83 const auto elem_id_3d = _current_elem->id();
84 const auto elem_id_2d = _mesh_alignment.getCoupledPrimaryElemID(elem_id_3d);
85
87 const auto n_qp_3d = _qrule->n_points();
88
89 const auto & T_2d_values = _temperature_2d_uo.getVariableValues(elem_id_2d);
90 const auto & area_2d = _mesh_alignment.getPrimaryArea(elem_id_2d);
91
92 std::vector<ADReal> heat_flux_3d(n_qp_3d, 0.0);
93 std::vector<ADReal> heat_flux_2d(n_qp_2d, 0.0);
94 for (unsigned int qp_3d = 0; qp_3d < n_qp_3d; qp_3d++)
95 {
96 const auto qp_2d = _mesh_alignment.getCoupledPrimaryElemQpIndex(elem_id_3d, qp_3d);
97
98 const auto & T_2d = T_2d_values[qp_2d];
99 const auto & T_3d = _T_3d[qp_3d];
100 const auto T_gap = 0.5 * (T_2d + T_3d);
101
102 const auto gap_thickness = evaluateTemperatureFunction(_gap_thickness_fn, T_gap);
103 const auto k_gap = evaluateTemperatureFunction(_k_gap_fn, T_gap);
104
105 if (!MooseUtils::absoluteFuzzyGreaterThan(gap_thickness, 0))
106 mooseError("Gap thickness must be > 0.");
107
108 const auto r_3d = _r_2d + gap_thickness;
109
110 const auto heat_flux_cond =
112 auto heat_flux = heat_flux_cond;
113
114 const auto htc = evaluateTemperatureFunction(_htc_gap_fn, T_gap);
115 heat_flux += htc * (T_2d - T_3d);
116
118 {
119 const auto emissivity_2d = evaluateTemperatureFunction(_emissivity_2d_fn, T_2d);
120 const auto emissivity_3d = evaluateTemperatureFunction(_emissivity_3d_fn, T_3d);
121
123 _r_2d, r_3d, emissivity_2d, emissivity_3d, T_2d, T_3d);
124 }
125
126 heat_flux_3d[qp_3d] = heat_flux;
127 heat_flux_2d[qp_2d] -=
128 _symmetry_factor * _JxW[qp_3d] * _coord[qp_3d] * heat_flux / area_2d[qp_2d];
129 }
130
131 // Store values in maps
132 _elem_id_to_heat_flux[elem_id_3d] = heat_flux_3d;
133 auto it = _elem_id_to_heat_flux.find(elem_id_2d);
134 if (it == _elem_id_to_heat_flux.end())
135 _elem_id_to_heat_flux[elem_id_2d] = heat_flux_2d;
136 else
137 {
138 auto & heat_flux_2d_existing = _elem_id_to_heat_flux[elem_id_2d];
139 for (const auto qp_2d : index_range(heat_flux_2d_existing))
140 heat_flux_2d_existing[qp_2d] += heat_flux_2d[qp_2d];
141 }
142}
143
144void
146{
147 const auto & other_uo = static_cast<const HSCoupler2D3DUserObject &>(uo);
148 for (auto & it : other_uo._elem_id_to_heat_flux)
149 if (_elem_id_to_heat_flux.find(it.first) == _elem_id_to_heat_flux.end())
150 _elem_id_to_heat_flux[it.first] = it.second;
151 else
152 {
153 auto & existing = _elem_id_to_heat_flux[it.first];
154 for (const auto qp : index_range(existing))
155 existing[qp] += it.second[qp];
156 }
157}
158
159void
164
165const std::vector<ADReal> &
166HSCoupler2D3DUserObject::getHeatFlux(dof_id_type elem_id) const
167{
168 Threads::spin_mutex::scoped_lock lock(Threads::spin_mtx);
169
170 auto it = _elem_id_to_heat_flux.find(elem_id);
171 if (it != _elem_id_to_heat_flux.end())
172 return it->second;
173 else
174 mooseError(name(), ": Requested heat flux for element ", elem_id, " was not computed.");
175}
176
177ADReal
179{
180 ADReal f = fn.value(T);
181 f.derivatives() = T.derivatives() * fn.timeDerivative(T.value());
182
183 return f;
184}
DualNumber< Real, DNDerivativeType, true > ADReal
Real f(Real x)
Test function for Brents method.
const double T
registerMooseObject("ThermalHydraulicsApp", HSCoupler2D3DUserObject)
virtual Real value(Real t, const Point &p) const
virtual Real timeDerivative(Real t, const Point &p) const
Computes heat fluxes for HSCoupler2D3D.
virtual void execute() override
MeshAlignment2D3D & _mesh_alignment
Mesh alignment object.
const Real _symmetry_factor
Azimuthal symmetry correction factor (= 2*pi / covered_angle; 1.0 for full circle)
const Function & _emissivity_2d_fn
Emissivity of the 2D heat structure boundary as a function of temperature.
ADReal evaluateTemperatureFunction(const Function &fn, const ADReal &T) const
Evaluates a function of temperature.
const Function & _gap_thickness_fn
Gap thickness as a function of temperature.
virtual void threadJoin(const UserObject &uo) override
const Function & _k_gap_fn
Gap thermal conductivity as a function of temperature.
const StoreVariableByElemIDSideUserObject & _temperature_2d_uo
User object containing the temperature values on the 2D boundary.
static InputParameters validParams()
const Real & _r_2d
Radius of the 2D heat structure boundary.
const std::vector< ADReal > & getHeatFlux(dof_id_type elem_id) const
Gets the heat fluxes for each quadrature point for a given element ID.
std::map< dof_id_type, std::vector< ADReal > > _elem_id_to_heat_flux
Map of the element ID to the heat flux.
const Function & _htc_gap_fn
Gap heat transfer coefficient as a function of temperature.
const Function & _emissivity_3d_fn
Emissivity of the 3D heat structure boundary as a function of temperature.
const bool _include_radiation
Include radiation?
const ADVariableValue & _T_3d
Coupled heated perimeter variable.
HSCoupler2D3DUserObject(const InputParameters &parameters)
virtual void initialize() override
virtual void finalize() override
void addRequiredCoupledVar(const std::string &name, const std::string &doc_string)
void addRequiredParam(const std::string &name, const std::string &doc_string)
void addParam(const std::string &name, const std::initializer_list< typename T::value_type > &value, const std::string &doc_string)
void addClassDescription(const std::string &doc_string)
void addRangeCheckedParam(const std::string &name, const T &value, const std::string &parsed_function, const std::string &doc_string)
Builds mapping between a 2D boundary and a 3D boundary.
const std::vector< Real > & getPrimaryArea(const dof_id_type primary_elem_id) const
Gets the area for each quadrature point on a primary element.
void buildCoupledElemQpIndexMapSecondary(Assembly &assembly)
Builds the map used for getting the coupled quadrature point index.
unsigned int getCoupledPrimaryElemQpIndex(const dof_id_type &secondary_elem_id, const unsigned int &secondary_qp) const
Gets the quadrature point index on the primary element corresponding to the quadrature point index on...
unsigned int getPrimaryNumberOfQuadraturePoints() const
Gets the number of quadrature points for faces on the primary boundary.
dof_id_type getCoupledPrimaryElemID(const dof_id_type &secondary_elem_id) const
Gets the coupled primary element ID for a given secondary element ID.
const std::string & name() const
void mooseError(Args &&... args) const
static InputParameters validParams()
const MooseArray< Real > & _coord
const QBase *const & _qrule
const MooseArray< Real > & _JxW
const Elem *const & _current_elem
Stores variable values at each quadrature point on a side by element ID.
const std::vector< ADReal > & getVariableValues(dof_id_type elem_id) const
Gets the variable values at each quadrature point on the provided element.
Assembly & _assembly
const Parallel::Communicator & comm() const
auto cylindricalGapConductionHeatFlux(const T1 &k_gap, const T2 &r_inner, const T3 &r_outer, const T4 &T_inner, const T5 &T_outer)
Computes the conduction heat flux across a cylindrical gap.
auto cylindricalGapRadiationHeatFlux(const T1 &r_inner, const T2 &r_outer, const T3 &emiss_inner, const T4 &emiss_outer, const T5 &T_inner, const T6 &T_outer, const Real &sigma=HeatConduction::Constants::sigma)
Computes the radiation heat flux across a cylindrical gap.
void allGatherADVectorMapSum(const Parallel::Communicator &comm, std::map< dof_id_type, std::vector< ADReal > > &this_map)
Parallel gather of a map of DoF ID to AD vector.
Definition THMUtils.C:58