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 
45  params.addClassDescription("Couples a 2D heat structure boundary to a 3D heat structure boundary "
46  "using gap heat transfer.");
47 
48  return params;
49 }
50 
52  : BoundaryBase(parameters),
53 
54  _hs_name_2d(getParam<std::string>("heat_structure_2d")),
55  _hs_name_3d(getParam<std::string>("heat_structure_3d")),
56  _boundary_2d(getParam<BoundaryName>("boundary_2d")),
57  _boundary_3d(getParam<BoundaryName>("boundary_3d")),
58 
59  _mesh_alignment(constMesh())
60 {
63 }
64 
65 void
67 {
69 
70  if (hasComponentByName<HeatStructureCylindricalBase>(_hs_name_2d) &&
71  hasComponentByName<HeatStructureFromFile3D>(_hs_name_3d))
72  {
73  const auto & hs_2d = getComponentByName<HeatStructureCylindricalBase>(_hs_name_2d);
74  const auto & hs_3d = getComponentByName<HeatStructureFromFile3D>(_hs_name_3d);
75 
76  if (hs_2d.hasBoundary(_boundary_2d) && hs_3d.hasBoundary(_boundary_3d))
77  {
78  // Initialize the alignment mapping
79  _mesh_alignment.initialize(hs_2d.getBoundaryInfo(_boundary_2d),
80  hs_3d.getBoundaryInfo(_boundary_3d),
81  hs_2d.getPosition(),
82  hs_2d.getDirection());
83 
84  // Add entries to sparsity pattern for coupling
86  for (const auto & elem_id : _mesh_alignment.getSecondaryElemIDs())
87  {
91  }
92  }
93  }
94 }
95 
96 void
98 {
100 
101  if (getParam<bool>("include_radiation"))
102  {
103  if (!(isParamValid("emissivity_2d") && isParamValid("emissivity_3d")))
104  logError("If 'include_radiation' is 'true', then 'emissivity_2d' and 'emissivity_3d' are "
105  "required.");
106  }
107  else
108  {
109  if (isParamValid("emissivity_2d") || isParamValid("emissivity_3d"))
110  logError("If 'include_radiation' is 'false', then neither 'emissivity_2d' nor "
111  "'emissivity_3d' can be specified.");
112  }
113 
114  if (hasComponentByName<HeatStructureCylindricalBase>(_hs_name_2d))
115  {
116  const auto & hs = getComponentByName<HeatStructureCylindricalBase>(_hs_name_2d);
117  if (!hs.hasBoundary(_boundary_2d))
118  logError("The heat structure '",
119  _hs_name_2d,
120  "' does not have the boundary '",
121  _boundary_2d,
122  "'.");
123  }
124  else
125  logError("There is no 2D cylindrical heat structure with the name '", _hs_name_2d, "'.");
126 
127  if (hasComponentByName<HeatStructureFromFile3D>(_hs_name_3d))
128  {
129  const auto & hs = getComponentByName<HeatStructureFromFile3D>(_hs_name_3d);
130  if (!hs.hasBoundary(_boundary_3d))
131  logError("The heat structure '",
132  _hs_name_3d,
133  "' does not have the boundary '",
134  _boundary_3d,
135  "'.");
136  }
137  else
138  logError("There is no 3D heat structure with the name '", _hs_name_3d, "'.");
139 
140  if (hasComponentByName<HeatStructureCylindricalBase>(_hs_name_2d) &&
141  hasComponentByName<HeatStructureFromFile3D>(_hs_name_3d) &&
143  logError("The meshes of the heat structures are not aligned.");
144 
145  const unsigned int needed_ad_container_size = 4 * _mesh_alignment.getMaxCouplingSize() + 6;
146  if (MOOSE_AD_MAX_DOFS_PER_ELEM < needed_ad_container_size)
147  logError("MOOSE must be configured with a larger AD container size (>= ",
148  needed_ad_container_size,
149  "). See HSCoupler2D3D's documentation for more information.");
150 }
151 
152 void
154 {
155  // add side UO on 2D boundary to cache temperature values by element ID
156  const UserObjectName temperature_2d_uo_name = genName(name(), "2d_uo");
157  {
158  const std::string class_name = "StoreVariableByElemIDSideUserObject";
159  InputParameters params = _factory.getValidParams(class_name);
160  params.set<std::vector<BoundaryName>>("boundary") = {_boundary_2d};
161  params.set<std::vector<VariableName>>("variable") = {HeatConductionModel::TEMPERATURE};
162  params.set<ExecFlagEnum>("execute_on") = {EXEC_INITIAL, EXEC_LINEAR, EXEC_NONLINEAR};
163  // This UO needs to execute before the UO on the 3D boundary
164  params.set<int>("execution_order_group") = -1;
165  getTHMProblem().addUserObject(class_name, temperature_2d_uo_name, params);
166  }
167 
168  // get the radius of the 2D heat structure boundary
169  const auto & hs_2d = getComponentByName<HeatStructureCylindricalBase>(_hs_name_2d);
170  const auto radius_2d = hs_2d.getInnerRadius() + hs_2d.getTotalWidth();
171 
172  // add side UO on 3D boundary to compute heat fluxes across each 3D boundary
173  const UserObjectName hs_coupler_2d3d_uo_name = genName(name(), "3d_uo");
174  {
175  const std::string class_name = "HSCoupler2D3DUserObject";
176  InputParameters params = _factory.getValidParams(class_name);
177  params.set<std::vector<BoundaryName>>("boundary") = {_boundary_3d};
178  params.set<std::vector<VariableName>>("temperature") = {HeatConductionModel::TEMPERATURE};
179  params.set<Real>("radius_2d") = radius_2d;
180  if (getParam<bool>("include_radiation"))
181  {
182  params.set<FunctionName>("emissivity_2d") = getParam<FunctionName>("emissivity_2d");
183  params.set<FunctionName>("emissivity_3d") = getParam<FunctionName>("emissivity_3d");
184  }
185  params.set<FunctionName>("gap_thickness") = getParam<FunctionName>("gap_thickness");
186  params.set<FunctionName>("gap_thermal_conductivity") =
187  getParam<FunctionName>("gap_thermal_conductivity");
188  params.set<FunctionName>("gap_htc") = getParam<FunctionName>("gap_htc");
189  params.set<UserObjectName>("temperature_2d_uo") = temperature_2d_uo_name;
190  params.set<MeshAlignment2D3D *>("mesh_alignment") = &_mesh_alignment;
191  params.set<ExecFlagEnum>("execute_on") = {EXEC_INITIAL, EXEC_LINEAR, EXEC_NONLINEAR};
192  getTHMProblem().addUserObject(class_name, hs_coupler_2d3d_uo_name, params);
193  }
194 
195  // add BC on 2D boundary
196  {
197  const std::string class_name = "HSCoupler2D3DBC";
198  InputParameters params = _factory.getValidParams(class_name);
199  params.set<NonlinearVariableName>("variable") = HeatConductionModel::TEMPERATURE;
200  params.set<std::vector<BoundaryName>>("boundary") = {_boundary_2d};
201  params.set<UserObjectName>("hs_coupler_2d3d_uo") = hs_coupler_2d3d_uo_name;
202  getTHMProblem().addBoundaryCondition(class_name, genName(name(), class_name, "2d"), params);
203  }
204 
205  // add BC on 3D boundary
206  {
207  const std::string class_name = "HSCoupler2D3DBC";
208  InputParameters params = _factory.getValidParams(class_name);
209  params.set<NonlinearVariableName>("variable") = HeatConductionModel::TEMPERATURE;
210  params.set<std::vector<BoundaryName>>("boundary") = {_boundary_3d};
211  params.set<UserObjectName>("hs_coupler_2d3d_uo") = hs_coupler_2d3d_uo_name;
212  getTHMProblem().addBoundaryCondition(class_name, genName(name(), class_name, "3d"), params);
213  }
214 }
MeshAlignment2D3D _mesh_alignment
Mesh alignment.
Definition: HSCoupler2D3D.h:41
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:306
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.
Definition: HSCoupler2D3D.C:97
virtual const std::string & name() const
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:215
bool isParamValid(const std::string &name) const
const BoundaryName & _boundary_2d
2D heat structure boundary
Definition: HSCoupler2D3D.h:36
virtual void check() const
Check the component integrity.
Definition: Component.h:301
static const std::string TEMPERATURE
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:51
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:446
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:66
void addClassDescription(const std::string &doc_string)
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