https://mooseframework.inl.gov
HSCoupler2D3D.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 "HSCoupler2D3D.h"
13 #include "MeshAlignment2D3D.h"
14 #include "THMMesh.h"
15 
16 registerMooseObject("ThermalHydraulicsApp", HSCoupler2D3D);
17 
20 {
22 
23  params.addRequiredParam<std::string>("heat_structure_2d", "The 2D heat structure to couple");
24  params.addRequiredParam<std::string>("heat_structure_3d", "The 3D heat structure to couple");
25  params.addRequiredParam<BoundaryName>("boundary_2d",
26  "The boundary of the 2D heat structure to couple");
27  params.addRequiredParam<BoundaryName>("boundary_3d",
28  "The boundary of the 3D heat structure to couple");
29 
30  params.addParam<bool>("include_radiation", true, "Include radiation component of heat flux");
31  params.addParam<FunctionName>(
32  "emissivity_2d",
33  "Emissivity of the 2D heat structure boundary as a function of temperature [K]");
34  params.addParam<FunctionName>(
35  "emissivity_3d",
36  "Emissivity of the 3D heat structure boundary as a function of temperature [K]");
37  params.addRequiredParam<FunctionName>("gap_thickness",
38  "Gap thickness [m] as a function of temperature [K]");
39  params.addRequiredParam<FunctionName>(
40  "gap_thermal_conductivity",
41  "Gap thermal conductivity [W/(m-K)] as a function of temperature [K]");
42  params.addParam<FunctionName>(
43  "gap_htc", 0, "Gap heat transfer coefficient [W/(m^2-K)] as a function of temperature [K]");
44  params.addRangeCheckedParam<Real>("symmetry_factor",
45  1.0,
46  "symmetry_factor>=1.0",
47  "Azimuthal symmetry correction factor (>= 1.0). Equal to 2*pi "
48  "divided by the azimuthal angle covered by the 3D mesh.");
49 
50  params.addClassDescription("Couples a 2D heat structure boundary to a 3D heat structure boundary "
51  "using gap heat transfer.");
52 
53  return params;
54 }
55 
57  : BoundaryBase(parameters),
58 
59  _hs_name_2d(getParam<std::string>("heat_structure_2d")),
60  _hs_name_3d(getParam<std::string>("heat_structure_3d")),
61  _boundary_2d(getParam<BoundaryName>("boundary_2d")),
62  _boundary_3d(getParam<BoundaryName>("boundary_3d")),
63  _symmetry_factor(getParam<Real>("symmetry_factor")),
64 
65  _mesh_alignment(constMesh())
66 {
69 }
70 
71 void
73 {
75 
76  if (hasComponentByName<HeatStructureCylindricalBase>(_hs_name_2d) &&
77  hasComponentByName<HeatStructureFromFile3D>(_hs_name_3d))
78  {
79  const auto & hs_2d = getComponentByName<HeatStructureCylindricalBase>(_hs_name_2d);
80  const auto & hs_3d = getComponentByName<HeatStructureFromFile3D>(_hs_name_3d);
81 
82  if (hs_2d.hasBoundary(_boundary_2d) && hs_3d.hasBoundary(_boundary_3d))
83  {
84  // Initialize the alignment mapping
85  _mesh_alignment.initialize(hs_2d.getBoundaryInfo(_boundary_2d),
86  hs_3d.getBoundaryInfo(_boundary_3d),
87  hs_2d.getPosition(),
88  hs_2d.getDirection());
89 
90  // Add entries to sparsity pattern for coupling
92  for (const auto & elem_id : _mesh_alignment.getSecondaryElemIDs())
93  {
97  }
98  }
99  }
100 }
101 
102 void
104 {
106 
107  if (getParam<bool>("include_radiation"))
108  {
109  if (!(isParamValid("emissivity_2d") && isParamValid("emissivity_3d")))
110  logError("If 'include_radiation' is 'true', then 'emissivity_2d' and 'emissivity_3d' are "
111  "required.");
112  }
113  else
114  {
115  if (isParamValid("emissivity_2d") || isParamValid("emissivity_3d"))
116  logError("If 'include_radiation' is 'false', then neither 'emissivity_2d' nor "
117  "'emissivity_3d' can be specified.");
118  }
119 
120  if (hasComponentByName<HeatStructureCylindricalBase>(_hs_name_2d))
121  {
122  const auto & hs = getComponentByName<HeatStructureCylindricalBase>(_hs_name_2d);
123  if (!hs.hasBoundary(_boundary_2d))
124  logError("The heat structure '",
125  _hs_name_2d,
126  "' does not have the boundary '",
127  _boundary_2d,
128  "'.");
129  }
130  else
131  logError("There is no 2D cylindrical heat structure with the name '", _hs_name_2d, "'.");
132 
133  if (hasComponentByName<HeatStructureFromFile3D>(_hs_name_3d))
134  {
135  const auto & hs = getComponentByName<HeatStructureFromFile3D>(_hs_name_3d);
136  if (!hs.hasBoundary(_boundary_3d))
137  logError("The heat structure '",
138  _hs_name_3d,
139  "' does not have the boundary '",
140  _boundary_3d,
141  "'.");
142  }
143  else
144  logError("There is no 3D heat structure with the name '", _hs_name_3d, "'.");
145 
146  if (hasComponentByName<HeatStructureCylindricalBase>(_hs_name_2d) &&
147  hasComponentByName<HeatStructureFromFile3D>(_hs_name_3d) &&
149  logError("The meshes of the heat structures are not aligned.");
150 
151  const unsigned int needed_ad_container_size = 4 * _mesh_alignment.getMaxCouplingSize() + 6;
152  if (MOOSE_AD_MAX_DOFS_PER_ELEM < needed_ad_container_size)
153  logError("MOOSE must be configured with a larger AD container size (>= ",
154  needed_ad_container_size,
155  "). See HSCoupler2D3D's documentation for more information.");
156 }
157 
158 void
160 {
161  // add side UO on 2D boundary to cache temperature values by element ID
162  const UserObjectName temperature_2d_uo_name = genName(name(), "2d_uo");
163  {
164  const std::string class_name = "StoreVariableByElemIDSideUserObject";
165  InputParameters params = _factory.getValidParams(class_name);
166  params.set<std::vector<BoundaryName>>("boundary") = {_boundary_2d};
167  params.set<std::vector<VariableName>>("variable") = {HeatConductionModel::TEMPERATURE};
168  params.set<ExecFlagEnum>("execute_on") = {EXEC_INITIAL, EXEC_LINEAR, EXEC_NONLINEAR};
169  // This UO needs to execute before the UO on the 3D boundary
170  params.set<int>("execution_order_group") = -1;
171  getTHMProblem().addUserObject(class_name, temperature_2d_uo_name, params);
172  }
173 
174  // get the radius of the 2D heat structure boundary
175  const auto & hs_2d = getComponentByName<HeatStructureCylindricalBase>(_hs_name_2d);
176  const auto radius_2d = hs_2d.getInnerRadius() + hs_2d.getTotalWidth();
177 
178  // add side UO on 3D boundary to compute heat fluxes across each 3D boundary
179  const UserObjectName hs_coupler_2d3d_uo_name = genName(name(), "3d_uo");
180  {
181  const std::string class_name = "HSCoupler2D3DUserObject";
182  InputParameters params = _factory.getValidParams(class_name);
183  params.set<std::vector<BoundaryName>>("boundary") = {_boundary_3d};
184  params.set<std::vector<VariableName>>("temperature") = {HeatConductionModel::TEMPERATURE};
185  params.set<Real>("radius_2d") = radius_2d;
186  params.set<Real>("symmetry_factor") = _symmetry_factor;
187  if (getParam<bool>("include_radiation"))
188  {
189  params.set<FunctionName>("emissivity_2d") = getParam<FunctionName>("emissivity_2d");
190  params.set<FunctionName>("emissivity_3d") = getParam<FunctionName>("emissivity_3d");
191  }
192  params.set<FunctionName>("gap_thickness") = getParam<FunctionName>("gap_thickness");
193  params.set<FunctionName>("gap_thermal_conductivity") =
194  getParam<FunctionName>("gap_thermal_conductivity");
195  params.set<FunctionName>("gap_htc") = getParam<FunctionName>("gap_htc");
196  params.set<UserObjectName>("temperature_2d_uo") = temperature_2d_uo_name;
197  params.set<MeshAlignment2D3D *>("mesh_alignment") = &_mesh_alignment;
198  params.set<ExecFlagEnum>("execute_on") = {EXEC_INITIAL, EXEC_LINEAR, EXEC_NONLINEAR};
199  getTHMProblem().addUserObject(class_name, hs_coupler_2d3d_uo_name, params);
200  }
201 
202  // add BC on 2D boundary
203  {
204  const std::string class_name = "HSCoupler2D3DBC";
205  InputParameters params = _factory.getValidParams(class_name);
206  params.set<NonlinearVariableName>("variable") = HeatConductionModel::TEMPERATURE;
207  params.set<std::vector<BoundaryName>>("boundary") = {_boundary_2d};
208  params.set<UserObjectName>("hs_coupler_2d3d_uo") = hs_coupler_2d3d_uo_name;
209  getTHMProblem().addBoundaryCondition(class_name, genName(name(), class_name, "2d"), params);
210  }
211 
212  // add BC on 3D boundary
213  {
214  const std::string class_name = "HSCoupler2D3DBC";
215  InputParameters params = _factory.getValidParams(class_name);
216  params.set<NonlinearVariableName>("variable") = HeatConductionModel::TEMPERATURE;
217  params.set<std::vector<BoundaryName>>("boundary") = {_boundary_3d};
218  params.set<UserObjectName>("hs_coupler_2d3d_uo") = hs_coupler_2d3d_uo_name;
219  getTHMProblem().addBoundaryCondition(class_name, genName(name(), class_name, "3d"), params);
220  }
221 }
MeshAlignment2D3D _mesh_alignment
Mesh alignment.
Definition: HSCoupler2D3D.h:43
std::string genName(const std::string &prefix, unsigned int id, const std::string &suffix="") const
Build a name from a prefix, number and possible suffix.
void initialize(const std::vector< std::tuple< dof_id_type, unsigned short int >> &primary_boundary_info, const std::vector< std::tuple< dof_id_type, unsigned short int >> &secondary_boundary_info, const Point &axis_point, const RealVectorValue &axis_direction)
Extracts mesh information and builds the mapping.
static InputParameters validParams()
Definition: BoundaryBase.C:13
const std::string & _hs_name_3d
3D heat structure name
Definition: HSCoupler2D3D.h:34
void addParam(const std::string &name, const std::initializer_list< typename T::value_type > &value, const std::string &doc_string)
virtual void setupMesh()
Performs mesh setup such as creating mesh or naming mesh sets.
Definition: Component.h:421
THMProblem & getTHMProblem() const
Gets the THM problem.
Definition: Component.C:135
void addDependency(const std::string &dependency)
Adds a component name to the list of dependencies.
Definition: Component.C:129
bool hasCoupledPrimaryElemID(const dof_id_type &secondary_elem_id) const
Returns true if the given secondary element ID has a coupled primary element.
T & set(const std::string &name, bool quiet_mode=false)
InputParameters getValidParams(const std::string &name) const
Couples a 2D heat structure boundary to a 3D heat structure boundary using gap heat transfer...
Definition: HSCoupler2D3D.h:18
Base class for components of a boundary type.
Definition: BoundaryBase.h:18
static InputParameters validParams()
Definition: HSCoupler2D3D.C:19
virtual void check() const override
Check the component integrity.
void addRequiredParam(const std::string &name, const std::string &doc_string)
bool meshesAreAligned() const
Returns true if the primary and secondary meshes are aligned.
const std::string & _hs_name_2d
2D heat structure name
Definition: HSCoupler2D3D.h:32
virtual void addBoundaryCondition(const std::string &bc_name, const std::string &name, InputParameters &parameters)
void logError(Args &&... args) const
Logs an error.
Definition: Component.h:226
const BoundaryName & _boundary_2d
2D heat structure boundary
Definition: HSCoupler2D3D.h:36
virtual void check() const
Check the component integrity.
Definition: Component.h:416
const std::string & name() const
static const std::string TEMPERATURE
const Real _symmetry_factor
Symmetry reduction factor.
Definition: HSCoupler2D3D.h:40
virtual void addMooseObjects() override
const std::vector< dof_id_type > & getSecondaryElemIDs() const
Returns the list of element IDs on the secondary boundary.
const ExecFlagType EXEC_LINEAR
HSCoupler2D3D(const InputParameters &parameters)
Definition: HSCoupler2D3D.C:56
registerMooseObject("ThermalHydraulicsApp", HSCoupler2D3D)
const ExecFlagType EXEC_NONLINEAR
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
Factory & _factory
The Factory associated with the MooseApp.
Definition: Component.h:497
virtual std::vector< std::shared_ptr< UserObject > > addUserObject(const std::string &user_object_name, const std::string &name, InputParameters &parameters)
dof_id_type getCoupledPrimaryElemID(const dof_id_type &secondary_elem_id) const
Gets the coupled primary element ID for a given secondary element ID.
unsigned int getMaxCouplingSize() const
Gets the maximum number of secondary elements coupled to any primary element.
virtual void setupMesh() override
Performs mesh setup such as creating mesh or naming mesh sets.
Definition: HSCoupler2D3D.C:72
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)
bool isParamValid(const std::string &name) const
Builds mapping between a 2D boundary and a 3D boundary.
virtual void augmentSparsity(const dof_id_type &elem_id1, const dof_id_type &elem_id2)
Hint how to augment sparsity pattern between two elements.
Definition: Simulation.C:71
const BoundaryName & _boundary_3d
3D heat structure boundary
Definition: HSCoupler2D3D.h:38
const ExecFlagType EXEC_INITIAL