https://mooseframework.inl.gov
CoupledHeatTransferAction.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 "FEProblem.h"
13 
14 registerMooseAction("ThermalHydraulicsApp", CoupledHeatTransferAction, "add_bc");
15 registerMooseAction("ThermalHydraulicsApp", CoupledHeatTransferAction, "add_user_object");
16 registerMooseAction("ThermalHydraulicsApp", CoupledHeatTransferAction, "add_transfer");
17 
20 {
22 
23  params.addClassDescription(
24  "Action that creates the necessary objects, for the solid side, to couple a "
25  "solid heat conduction region to a 1-D flow channel via convective heat transfer");
26 
27  params.addRequiredParam<std::vector<BoundaryName>>("boundary",
28  "Boundary name(s) on the solid side");
29  params.addRequiredParam<VariableName>("T", "Solid side temperature variable");
30  params.addRequiredParam<VariableName>(
31  "T_wall", "Variable on the flow channel side into which to transfer the solid temperature");
32  params.addRequiredParam<std::vector<VariableName>>(
33  "T_fluid", "Variable(s) on the solid side into which to transfer the fluid temperature(s)");
34  params.addRequiredParam<std::vector<VariableName>>(
35  "htc",
36  "Variable(s) on the solid side into which to transfer the heat transfer coefficient(s)");
37  params.addParam<std::vector<VariableName>>(
38  "kappa", "Variables on the solid side into which to transfer the wall contact fractions");
39  params.addRequiredParam<std::vector<UserObjectName>>(
40  "T_fluid_user_objects", "Spatial user object(s) holding the fluid temperature values");
41  params.addRequiredParam<std::vector<UserObjectName>>(
42  "htc_user_objects", "Spatial user object(s) holding the heat transfer coefficient values");
43  params.addParam<std::vector<UserObjectName>>(
44  "kappa_user_objects", "Spatial user object(s) holding the wall contact fraction values");
45 
46  params.addRequiredParam<Point>("position", "Start position of axis in 3-D space [m]");
48  "orientation",
49  "Direction of axis from start position to end position (no need to normalize)");
50  params.addParam<Real>("rotation", 0.0, "Angle of rotation about the x-axis [degrees]");
51  params.addRequiredParam<std::vector<Real>>("length", "Length of each axial section [m]");
52  params.addRequiredParam<std::vector<unsigned int>>("n_elems",
53  "Number of elements in each axial section");
54 
55  params.addRequiredParam<std::string>("multi_app", "The name of the multi-app.");
56 
57  params.addRangeCheckedParam<std::vector<Real>>(
58  "fixed_bounding_box_size",
59  "fixed_bounding_box_size >= 0",
60  "The 'fixed_bounding_box_size' value to use for each MultiAppGeneralFieldUserObjectTransfer. "
61  "If this parameter is not provided, a greedy search will be used instead of bounding boxes, "
62  "which may be slower.");
63 
64  params.addParam<std::vector<Point>>(
65  "positions", "Sub-app positions. Each set of 3 values represents a Point.");
66  params.addParam<FileName>(
67  "positions_file",
68  "Name of file containing sub-app positions. Each set of 3 values represents a Point.");
70  return params;
71 }
72 
74  : Action(params),
75 
76  _boundary(getParam<std::vector<BoundaryName>>("boundary")),
77 
78  _T_solid_var_name(getParam<VariableName>("T")),
79  _T_wall_var_name(getParam<VariableName>("T_wall")),
80  _T_fluid_var_names(getParam<std::vector<VariableName>>("T_fluid")),
81  _htc_var_names(getParam<std::vector<VariableName>>("htc")),
82 
83  _n_phases(_T_fluid_var_names.size()),
84 
85  _T_wall_user_object_name(name() + "_T_avg_uo"),
86  _T_fluid_user_object_names(getParam<std::vector<UserObjectName>>("T_fluid_user_objects")),
87  _htc_user_object_names(getParam<std::vector<UserObjectName>>("htc_user_objects")),
88 
89  _multi_app_name(getParam<std::string>("multi_app"))
90 {
91  if (_htc_var_names.size() != _n_phases || _T_fluid_user_object_names.size() != _n_phases ||
93  mooseError("The parameters 'T_fluid', 'htc', 'T_fluid_user_objects', and 'htc_user_objects' "
94  "must have the same numbers of elements.");
95 
96  if (_n_phases == 1)
97  {
98  if (isParamValid("kappa") || isParamValid("kappa_user_objects"))
99  mooseError("If there is only one phase (e.g., only one element in 'T_fluid'), then the "
100  "parameters 'kappa' and 'kappa_user_objects' must not be provided.");
101  }
102  else
103  {
104  if (!isParamValid("kappa") || !isParamValid("kappa_user_objects"))
105  mooseError("If there is more than one phase (e.g., more than one element in 'T_fluid'), then "
106  "the parameters 'kappa' and 'kappa_user_objects' must be provided.");
107  else
108  {
109  _kappa_var_names = getParam<std::vector<VariableName>>("kappa");
110  _kappa_user_object_names = getParam<std::vector<UserObjectName>>("kappa_user_objects");
112  mooseError("The parameters 'kappa' and 'kappa_user_objects' must have the same number of "
113  "elements as 'T_fluid'.");
114  }
115  }
116 
117  const auto & orientation = getParam<RealVectorValue>("orientation");
119  mooseError("The direction given by the parameter 'orientation' must be aligned with the x, "
120  "y, or z axis.");
121 }
122 
123 void
125 {
126  if (_current_task == "add_bc")
127  addBCs();
128  else if (_current_task == "add_user_object")
129  addUserObjects();
130  else if (_current_task == "add_transfer")
131  addTransfers();
132 }
133 
134 void
136 {
137  for (unsigned int k = 0; k < _n_phases; k++)
138  {
139  const std::string class_name = "CoupledConvectiveHeatFluxBC";
140  InputParameters params = _factory.getValidParams(class_name);
141  params.set<NonlinearVariableName>("variable") = _T_solid_var_name;
142  params.set<std::vector<BoundaryName>>("boundary") = {_boundary};
143  params.set<std::vector<VariableName>>("T_infinity") = {_T_fluid_var_names[k]};
144  params.set<std::vector<VariableName>>("htc") = {_htc_var_names[k]};
145  if (_n_phases > 1)
146  params.set<std::vector<VariableName>>("scale_factor") = {_kappa_var_names[k]};
147  _problem->addBoundaryCondition(class_name, name() + "_bc" + std::to_string(k), params);
148  }
149 }
150 
151 void
153 {
154  // Solid temperature spatial user object
155  {
156  const std::string class_name = "NearestPointLayeredSideAverage";
157  InputParameters params = _factory.getValidParams(class_name);
158  params.set<std::vector<VariableName>>("variable") = {_T_solid_var_name};
159  params.set<std::vector<BoundaryName>>("boundary") = {_boundary};
160 
161  // set sub-app positions
162  if (isParamValid("positions"))
163  params.set<std::vector<Point>>("points") = getParam<std::vector<Point>>("positions");
164  else if (isParamValid("positions_file"))
165  params.set<FileName>("points_file") = getParam<FileName>("positions_file");
166  else
167  params.set<std::vector<Point>>("points") = {Point(0, 0, 0)};
168 
169  const auto & position = getParam<Point>("position");
170  const auto & orientation = getParam<RealVectorValue>("orientation");
171  const auto & rotation = getParam<Real>("rotation");
172  const auto & lengths = getParam<std::vector<Real>>("length");
173  const auto & n_elems = getParam<std::vector<unsigned int>>("n_elems");
174 
175  params.set<MooseEnum>("direction") =
177  params.set<std::vector<Real>>("bounds") =
179  position, orientation, rotation, lengths, n_elems);
180 
181  _problem->addUserObject(class_name, _T_wall_user_object_name, params);
182  }
183 }
184 
185 void
187 {
188  // Transfers to the flow channel application
189 
190  const bool skip_coordinate_collapsing = getParam<bool>("skip_coordinate_collapsing");
191 
192  const bool use_bounding_boxes = isParamValid("fixed_bounding_box_size");
193  std::vector<Real> fixed_bounding_box_size;
194  if (use_bounding_boxes)
195  fixed_bounding_box_size = getParam<std::vector<Real>>("fixed_bounding_box_size");
196 
197  {
198  const std::string class_name = "MultiAppGeneralFieldUserObjectTransfer";
199  InputParameters params = _factory.getValidParams(class_name);
200  params.set<MultiAppName>("to_multi_app") = _multi_app_name;
201  params.set<UserObjectName>("source_user_object") = {_T_wall_user_object_name};
202  params.set<std::vector<AuxVariableName>>("variable") = {_T_wall_var_name};
203  params.set<bool>("skip_coordinate_collapsing") = skip_coordinate_collapsing;
204  params.set<bool>("error_on_miss") = true;
205  if (use_bounding_boxes)
206  params.set<std::vector<Real>>("fixed_bounding_box_size") = fixed_bounding_box_size;
207  else
208  {
209  params.set<bool>("use_bounding_boxes") = false;
210  params.set<bool>("greedy_search") = true;
211  }
212  _problem->addTransfer(class_name, name() + "_T_solid_transfer", params);
213  }
214 
215  // Transfers from the flow channel application. Note that
216  // Note that MultiAppGeneralFieldNearestLocationTransfer should be more optimal
217  // choice in parallel calculations, while MultiAppGeneralFieldUserObjectTransfer should
218  // be more optimal in serial calculations. If these transfers prove to be a significant time
219  // burden, we may want to provide an option to switch these transfer classes.
220  for (unsigned int k = 0; k < _n_phases; k++)
221  {
222  {
223  const std::string class_name = "MultiAppGeneralFieldUserObjectTransfer";
224  InputParameters params = _factory.getValidParams(class_name);
225  params.set<MultiAppName>("from_multi_app") = _multi_app_name;
226  params.set<UserObjectName>("source_user_object") = _T_fluid_user_object_names[k];
227  params.set<std::vector<AuxVariableName>>("variable") = {_T_fluid_var_names[k]};
228  params.set<bool>("skip_coordinate_collapsing") = skip_coordinate_collapsing;
229  params.set<bool>("error_on_miss") = true;
230  if (use_bounding_boxes)
231  params.set<std::vector<Real>>("fixed_bounding_box_size") = fixed_bounding_box_size;
232  else
233  {
234  params.set<bool>("use_bounding_boxes") = false;
235  params.set<bool>("greedy_search") = true;
236  }
237  _problem->addTransfer(class_name, name() + "_T_fluid_transfer" + std::to_string(k), params);
238  }
239  {
240  const std::string class_name = "MultiAppGeneralFieldUserObjectTransfer";
241  InputParameters params = _factory.getValidParams(class_name);
242  params.set<MultiAppName>("from_multi_app") = _multi_app_name;
243  params.set<UserObjectName>("source_user_object") = _htc_user_object_names[k];
244  params.set<std::vector<AuxVariableName>>("variable") = {_htc_var_names[k]};
245  params.set<bool>("skip_coordinate_collapsing") = skip_coordinate_collapsing;
246  params.set<bool>("error_on_miss") = true;
247  if (use_bounding_boxes)
248  params.set<std::vector<Real>>("fixed_bounding_box_size") = fixed_bounding_box_size;
249  else
250  {
251  params.set<bool>("use_bounding_boxes") = false;
252  params.set<bool>("greedy_search") = true;
253  }
254  _problem->addTransfer(class_name, name() + "_htc_transfer" + std::to_string(k), params);
255  }
256  if (_n_phases > 1)
257  {
258  const std::string class_name = "MultiAppGeneralFieldUserObjectTransfer";
259  InputParameters params = _factory.getValidParams(class_name);
260  params.set<MultiAppName>("from_multi_app") = _multi_app_name;
261  params.set<UserObjectName>("source_user_object") = _kappa_user_object_names[k];
262  params.set<std::vector<AuxVariableName>>("variable") = {_kappa_var_names[k]};
263  params.set<bool>("skip_coordinate_collapsing") = skip_coordinate_collapsing;
264  params.set<bool>("error_on_miss") = true;
265  if (use_bounding_boxes)
266  params.set<std::vector<Real>>("fixed_bounding_box_size") = fixed_bounding_box_size;
267  else
268  {
269  params.set<bool>("use_bounding_boxes") = false;
270  params.set<bool>("greedy_search") = true;
271  }
272  _problem->addTransfer(class_name, name() + "_kappa_transfer" + std::to_string(k), params);
273  }
274  }
275 }
const std::vector< UserObjectName > _T_fluid_user_object_names
Spatial user object(s) holding the fluid temperature values.
CoupledHeatTransferAction(const InputParameters &params)
void addParam(const std::string &name, const std::initializer_list< typename T::value_type > &value, const std::string &doc_string)
static InputParameters validParams()
Factory & _factory
const VariableName _T_wall_var_name
Variable on the flow channel side into which to transfer the solid temperature.
T & set(const std::string &name, bool quiet_mode=false)
const std::vector< VariableName > _T_fluid_var_names
Variable(s) on the solid side into which to transfer the fluid temperature(s)
InputParameters getValidParams(const std::string &name) const
const VariableName _T_solid_var_name
Solid side temperature variable name.
void addRequiredParam(const std::string &name, const std::string &doc_string)
const std::vector< VariableName > _htc_var_names
Variable(s) on the solid side into which to transfer the heat transfer coefficient(s) ...
Action that creates the necessary objects, for the solid side, to couple a solid heat conduction regi...
const std::string & name() const
MultiAppName _multi_app_name
Name of the THM multi-app.
registerMooseAction("ThermalHydraulicsApp", CoupledHeatTransferAction, "add_bc")
static InputParameters validParams()
const std::string name
Definition: Setup.h:21
const unsigned int _n_phases
Number of fluid phases.
const std::string & _current_task
const UserObjectName _T_wall_user_object_name
User object name with solid temperature.
const std::vector< UserObjectName > _htc_user_object_names
Spatial user object(s) holding the heat transfer coefficient values.
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
MooseEnum getAlignmentAxis() const
Gets an axis MooseEnum for the axis the component is aligned with.
void mooseError(Args &&... args) const
void addClassDescription(const std::string &doc_string)
std::shared_ptr< FEProblemBase > & _problem
static void addSkipCoordCollapsingParam(InputParameters &params)
std::vector< UserObjectName > _kappa_user_object_names
Spatial user objects holding the wall contact fraction values.
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
std::vector< BoundaryName > _boundary
Boundary where the BC is applied.
std::vector< VariableName > _kappa_var_names
Variables on the solid side into which to transfer the wall contact fractions.
std::vector< Real > getElementBoundaryCoordinates() const
Gets the element boundary coordinates for the aligned axis.
virtual bool isValid() const override
static const std::string k
Definition: NS.h:134