https://mooseframework.inl.gov
Loading...
Searching...
No Matches
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
14registerMooseAction("ThermalHydraulicsApp", CoupledHeatTransferAction, "add_bc");
15registerMooseAction("ThermalHydraulicsApp", CoupledHeatTransferAction, "add_user_object");
16registerMooseAction("ThermalHydraulicsApp", CoupledHeatTransferAction, "add_transfer");
17
20{
22
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]");
47 params.addRequiredParam<RealVectorValue>(
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{
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
123void
125{
126 if (_current_task == "add_bc")
127 addBCs();
128 else if (_current_task == "add_user_object")
130 else if (_current_task == "add_transfer")
131 addTransfers();
132}
133
134void
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
151void
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
185void
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}
registerMooseAction("ThermalHydraulicsApp", CoupledHeatTransferAction, "add_bc")
const std::string name
Definition Setup.h:21
void isValid(MooseObject *obj)
static InputParameters validParams()
std::shared_ptr< FEProblemBase > & _problem
const std::string & _current_task
Action that creates the necessary objects, for the solid side, to couple a solid heat conduction regi...
const UserObjectName _T_wall_user_object_name
User object name with solid temperature.
std::vector< BoundaryName > _boundary
Boundary where the BC is applied.
static InputParameters validParams()
std::vector< VariableName > _kappa_var_names
Variables on the solid side into which to transfer the wall contact fractions.
const std::vector< VariableName > _T_fluid_var_names
Variable(s) on the solid side into which to transfer the fluid temperature(s)
MultiAppName _multi_app_name
Name of the THM multi-app.
const std::vector< UserObjectName > _htc_user_object_names
Spatial user object(s) holding the heat transfer coefficient values.
CoupledHeatTransferAction(const InputParameters &params)
const std::vector< UserObjectName > _T_fluid_user_object_names
Spatial user object(s) holding the fluid temperature values.
const VariableName _T_solid_var_name
Solid side temperature variable name.
const unsigned int _n_phases
Number of fluid phases.
const VariableName _T_wall_var_name
Variable on the flow channel side into which to transfer the solid temperature.
const std::vector< VariableName > _htc_var_names
Variable(s) on the solid side into which to transfer the heat transfer coefficient(s)
std::vector< UserObjectName > _kappa_user_object_names
Spatial user objects holding the wall contact fraction values.
std::vector< Real > getElementBoundaryCoordinates() const
Gets the element boundary coordinates for the aligned axis.
MooseEnum getAlignmentAxis() const
Gets an axis MooseEnum for the axis the component is aligned with.
InputParameters getValidParams(const std::string &name) const
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)
T & set(const std::string &name, bool quiet_mode=false)
void addRangeCheckedParam(const std::string &name, const T &value, const std::string &parsed_function, const std::string &doc_string)
const std::string & name() const
void mooseError(Args &&... args) const
bool isParamValid(const std::string &name) const
static void addSkipCoordCollapsingParam(InputParameters &params)
Factory & _factory