https://mooseframework.inl.gov
HSCoupler2D2DRadiation.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 "HSCoupler2D2DRadiation.h"
12 #include "THMMesh.h"
13 #include "MooseUtils.h"
14 
15 registerMooseObject("ThermalHydraulicsApp", HSCoupler2D2DRadiation);
16 
19 {
21 
22  params.addRequiredParam<std::vector<std::string>>("heat_structures",
23  "The heat structures to couple");
24  params.addRequiredParam<std::vector<BoundaryName>>(
25  "boundaries", "The boundaries of the heat structures to couple");
26  params.addRequiredRangeCheckedParam<std::vector<Real>>(
27  "emissivities",
28  "emissivities > 0 & emissivities < 1",
29  "Emissivities of each heat structure surface");
30  params.addRequiredRangeCheckedParam<std::vector<std::vector<Real>>>(
31  "view_factors",
32  "view_factors >= 0 & view_factors <= 1",
33  "The view factors between each surface, as a matrix. The row/column ordering corresponds to "
34  "the ordering in 'heat_structures', with an additional row and column if "
35  "'include_environment' is set to 'true'. Each row must sum to one.");
36  params.addRequiredParam<bool>(
37  "include_environment",
38  "Whether or not to include an environment surrounding all of the surfaces. If the heat "
39  "structure surfaces themselves form an enclosure, then set this parameter to 'false'.");
40  params.addParam<Real>(
41  "T_environment",
42  "Environment temperature [K]. Only set if 'include_environment' is set to true.");
43 
44  params.addClassDescription("Couples boundaries of multiple 2D heat structures via radiation");
45 
46  return params;
47 }
48 
50  : BoundaryBase(parameters),
51 
52  _hs_names(getParam<std::vector<std::string>>("heat_structures")),
53  _hs_boundaries(getParam<std::vector<BoundaryName>>("boundaries")),
54  _include_environment(getParam<bool>("include_environment")),
55  _n_hs(_hs_names.size()),
56  _n_surfaces(_include_environment ? _n_hs + 1 : _n_hs),
57 
58  _mesh_alignment(constMesh())
59 {
60  for (unsigned int i = 0; i < _n_hs; ++i)
62 }
63 
64 void
66 {
68 
69  // If there is more than one heat structure, initialize mesh alignment and
70  // augment the sparsity pattern
71  if (_n_hs >= 2)
72  {
73  // get boundary info vectors for all boundaries
74  std::vector<std::vector<std::tuple<dof_id_type, unsigned short int>>> boundary_infos;
75  for (const auto i : index_range(_hs_names))
76  {
77  if (hasComponentByName<HeatStructureBase>(_hs_names[i]))
78  {
79  const auto & hs = getComponentByName<HeatStructureBase>(_hs_names[i]);
80  if (i < _hs_boundaries.size() && hs.hasBoundary(_hs_boundaries[i]))
81  boundary_infos.push_back(hs.getBoundaryInfo(_hs_boundaries[i]));
82  }
83  }
84 
85  // Initialize the alignment mapping
86  if (hasComponentByName<HeatStructureBase>(_hs_names[0]))
87  {
88  const auto & hs = getComponentByName<HeatStructureBase>(_hs_names[0]);
89  _mesh_alignment.initialize(boundary_infos, hs.getPosition(), hs.getDirection());
90  }
91 
92  // Add entries to sparsity pattern for coupling
94  for (const auto & primary_elem_id : _mesh_alignment.getPrimaryElemIDs())
95  {
96  const auto & coupled_elem_ids = _mesh_alignment.getCoupledSecondaryElemIDs(primary_elem_id);
97  std::vector<dof_id_type> elem_ids;
98  elem_ids.push_back(primary_elem_id);
99  elem_ids.insert(elem_ids.end(), coupled_elem_ids.begin(), coupled_elem_ids.end());
100 
101  for (unsigned int i = 0; i < elem_ids.size(); ++i)
102  for (unsigned int j = i + 1; j < elem_ids.size(); ++j)
103  getTHMProblem().augmentSparsity(elem_ids[i], elem_ids[j]);
104  }
105  }
106 }
107 
108 void
110 {
112 
113  checkEqualSize<BoundaryName, std::string>("boundaries", "heat_structures");
114  checkEqualSize<Real, std::string>("emissivities", "heat_structures");
115 
116  // check view factor matrix dimensions
117  const auto & view_factors = getParam<std::vector<std::vector<Real>>>("view_factors");
118  bool correct_size = true;
119  if (view_factors.size() == _n_surfaces)
120  {
121  for (const auto i : index_range(view_factors))
122  if (view_factors[i].size() != _n_surfaces)
123  correct_size = false;
124  }
125  else
126  correct_size = false;
127  if (!correct_size)
128  logError("The parameter 'view_factors' must be a square matrix of size ",
129  _n_surfaces,
130  ". For example, a size 2 matrix is provided as '0.2 0.8; 0.7 0.3'. The row/column "
131  "ordering corresponds to the ordering in 'heat_structures', with an additional "
132  "row/column if 'include_environment' is set to 'true'.");
133 
134  // check that all view factor matrix rows sum to one
135  bool all_row_sums_unity = true;
136  for (const auto i : index_range(view_factors))
138  std::accumulate(view_factors[i].begin(), view_factors[i].end(), 0.0), 1.0))
139  all_row_sums_unity = false;
140  if (!all_row_sums_unity)
141  logError("All rows in 'view_factors' must sum to one.");
142 
143  if (_n_hs > 1 && !_mesh_alignment.meshesAreAligned())
144  logError("The meshes of the heat structures are not aligned.");
145 
146  for (const auto i : index_range(_hs_names))
147  {
148  // for now we only allow cylindrical heat structures
149  checkComponentOfTypeExistsByName<HeatStructureCylindricalBase>(_hs_names[i]);
150 
151  if (hasComponentByName<HeatStructureBase>(_hs_names[i]))
152  {
153  const auto & hs = getComponentByName<HeatStructureBase>(_hs_names[i]);
154  if (i < _hs_boundaries.size() && !hs.hasBoundary(_hs_boundaries[i]))
155  logError("The heat structure '",
156  _hs_names[i],
157  "' does not have the boundary '",
158  _hs_boundaries[i],
159  "'.");
160  }
161  }
162 }
163 
164 void
166 {
167  // add side UO on 2D boundary to cache temperature values by element ID
168  const UserObjectName temperature_uo_name = genName(name(), "temperature_uo");
169  {
170  const std::string class_name = "StoreVariableByElemIDSideUserObject";
171  InputParameters params = _factory.getValidParams(class_name);
172  params.set<std::vector<BoundaryName>>("boundary") = _hs_boundaries;
173  params.set<std::vector<VariableName>>("variable") = {HeatConductionModel::TEMPERATURE};
174  params.set<ExecFlagEnum>("execute_on") = {EXEC_INITIAL, EXEC_LINEAR, EXEC_NONLINEAR};
175  // This UO needs to execute before the UO below
176  params.set<int>("execution_order_group") = -1;
177  getTHMProblem().addUserObject(class_name, temperature_uo_name, params);
178  }
179 
180  // add side UO to compute heat fluxes across each boundary
181  const UserObjectName hs_coupler_2d2d_uo_name = genName(name(), "uo");
182  {
183  const std::string class_name = "HSCoupler2D2DRadiationUserObject";
184  InputParameters params = _factory.getValidParams(class_name);
185  params.set<std::vector<BoundaryName>>("boundary") = {_hs_boundaries[0]};
187  parameters(), {"emissivities", "view_factors", "include_environment", "T_environment"});
188  params.set<UserObjectName>("temperature_uo") = temperature_uo_name;
189  params.set<MeshAlignment2D2D *>("mesh_alignment") = &_mesh_alignment;
190  params.set<ExecFlagEnum>("execute_on") = {EXEC_INITIAL, EXEC_LINEAR, EXEC_NONLINEAR};
191  getTHMProblem().addUserObject(class_name, hs_coupler_2d2d_uo_name, params);
192  }
193 
194  // BCs
195  for (unsigned int i = 0; i < _n_hs; ++i)
196  {
197  const auto & hs = getComponentByName<HeatStructureCylindricalBase>(_hs_names[i]);
198 
199  const std::string class_name = "HSCoupler2D2DRadiationRZBC";
200  InputParameters params = _factory.getValidParams(class_name);
201  params.set<NonlinearVariableName>("variable") = HeatConductionModel::TEMPERATURE;
202  params.set<std::vector<BoundaryName>>("boundary") = {_hs_boundaries[i]};
203  params.set<UserObjectName>("hs_coupler_2d2d_uo") = hs_coupler_2d2d_uo_name;
204  params.set<Point>("axis_point") = hs.getPosition();
205  params.set<RealVectorValue>("axis_dir") = hs.getDirection();
206  getTHMProblem().addBoundaryCondition(class_name, genName(name(), class_name, i), params);
207  }
208 }
void addRequiredRangeCheckedParam(const std::string &name, const std::string &parsed_function, const std::string &doc_string)
const unsigned int _n_hs
Number of heat structures.
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.
bool absoluteFuzzyEqual(const T &var1, const T2 &var2, const T3 &tol=libMesh::TOLERANCE *libMesh::TOLERANCE)
static InputParameters validParams()
Definition: BoundaryBase.C:13
void addParam(const std::string &name, const std::initializer_list< typename T::value_type > &value, const std::string &doc_string)
void applySpecificParameters(const InputParameters &common, const std::vector< std::string > &include, bool allow_private=false)
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
virtual void check() const override
Check the component integrity.
T & set(const std::string &name, bool quiet_mode=false)
InputParameters getValidParams(const std::string &name) const
const std::vector< std::string > _hs_names
Heat structure names.
registerMooseObject("ThermalHydraulicsApp", HSCoupler2D2DRadiation)
Base class for components of a boundary type.
Definition: BoundaryBase.h:18
HSCoupler2D2DRadiation(const InputParameters &parameters)
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.
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
virtual void check() const
Check the component integrity.
Definition: Component.h:301
MeshAlignment2D2D _mesh_alignment
Mesh alignment object.
Couples boundaries of multiple 2D heat structures via radiation.
const std::vector< BoundaryName > _hs_boundaries
Heat structure boundary names.
Builds mapping between multiple 2D boundaries.
static const std::string TEMPERATURE
virtual void addMooseObjects() override
const std::vector< dof_id_type > & getPrimaryElemIDs() const
Returns the list of element IDs on the primary boundary.
const ExecFlagType EXEC_LINEAR
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)
virtual void setupMesh() override
Performs mesh setup such as creating mesh or naming mesh sets.
void addClassDescription(const std::string &doc_string)
const InputParameters & parameters() const
static const std::complex< double > j(0, 1)
Complex number "j" (also known as "i")
const std::vector< dof_id_type > & getCoupledSecondaryElemIDs(const dof_id_type &primary_elem_id) const
Gets the coupled secondary element IDs for a given primary element ID.
const unsigned int _n_surfaces
Number of surfaces.
static InputParameters validParams()
auto index_range(const T &sizable)
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
void initialize(const std::vector< std::vector< std::tuple< dof_id_type, unsigned short int >>> &boundary_infos, const Point &axis_point, const RealVectorValue &axis_direction)
Extracts mesh information and builds the mapping.
const ExecFlagType EXEC_INITIAL