https://mooseframework.inl.gov
FlowChannelBase.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 "FlowChannelBase.h"
11 #include "HeatTransferBase.h"
12 #include "ClosuresBase.h"
13 #include "ThermalHydraulicsApp.h"
14 #include "THMMesh.h"
15 
16 #include "libmesh/edge_edge2.h"
17 #include "libmesh/edge_edge3.h"
18 
19 const std::map<std::string, FlowChannelBase::EConvHeatTransGeom>
21  {"PIPE", PIPE}, {"ROD_BUNDLE", ROD_BUNDLE}, {"HEX_ROD_BUNDLE", HEX_ROD_BUNDLE}};
22 
23 const std::map<std::string, FlowChannelBase::EPipeType> FlowChannelBase::_pipe_type_to_enum{
24  {"STRAIGHT", STRAIGHT}, {"CURVED", CURVED}, {"DOWNCOMER", DOWNCOMER}};
25 
26 const std::map<std::string, FlowChannelBase::EPipeLocation> FlowChannelBase::_pipe_location_to_enum{
27  {"INTERIOR", INTERIOR}, {"EDGE", EDGE}, {"CORNER", CORNER}};
28 
31 {
32  return THM::getMooseEnum<EConvHeatTransGeom>(name, _heat_transfer_geom_to_enum);
33 }
34 
36 FlowChannelBase::getPipeType(const std::string & name)
37 {
38  return THM::getMooseEnum<EPipeType>(name, _pipe_type_to_enum);
39 }
40 
43 {
44  return THM::getMooseEnum<EPipeLocation>(name, _pipe_location_to_enum);
45 }
46 
47 template <>
49 THM::stringToEnum(const std::string & s)
50 {
51  return stringToEnum<FlowChannelBase::EConvHeatTransGeom>(
53 }
54 
55 template <>
57 THM::stringToEnum(const std::string & s)
58 {
59  return stringToEnum<FlowChannelBase::EPipeType>(s, FlowChannelBase::_pipe_type_to_enum);
60 }
61 
62 template <>
64 THM::stringToEnum(const std::string & s)
65 {
66  return stringToEnum<FlowChannelBase::EPipeLocation>(s, FlowChannelBase::_pipe_location_to_enum);
67 }
68 
71 {
74 
75  params.addRequiredParam<UserObjectName>("fp", "Fluid properties user object");
76  params.addRequiredParam<FunctionName>(
77  "A", "Area of the flow channel, can be a constant or a function");
78  params.addParam<Real>("roughness", 0.0, "Roughness [m]");
79  params.addParam<FunctionName>("f", "Wall friction factor [-]");
80  params.addParam<MooseEnum>("heat_transfer_geom",
82  "Convective heat transfer geometry");
83  params.addParam<MooseEnum>("pipe_location",
85  "Pipe location within the bundle");
86  params.addParam<Real>("PoD", 1, "Pitch-to-diameter ratio for parallel bundle heat transfer [-]");
87  params.addParam<bool>(
88  "pipe_pars_transferred",
89  false,
90  "Set to true if Dh, P_hf and A are going to be transferred in from an external source");
91  params.addParam<std::vector<std::string>>(
92  "closures",
93  {},
94  "Closures object(s). This is optional since closure relations can be supplied directly by "
95  "Materials as well.");
96  params.addParam<bool>("name_multiple_ht_by_index",
97  true,
98  "If true, when there are multiple heat transfer components connected to "
99  "this flow channel, use their index for naming related quantities; "
100  "otherwise, use the name of the heat transfer component.");
101  params.addParam<std::vector<VariableName>>(
102  "vpp_vars", {}, "Variables to add in an ElementValueSampler");
103 
104  params.setDocString(
105  "orientation",
106  "Direction of flow channel from start position to end position (no need to normalize). For "
107  "curved flow channels, it is the (tangent) direction at the start position.");
108 
109  params.addPrivateParam<std::string>("component_type", "pipe");
110 
111  return params;
112 }
113 
115  : Component1D(params),
116  GravityInterface(params),
117 
118  _flow_model(nullptr),
119  _fp_name(getParam<UserObjectName>("fp")),
120  _gravity_angle(MooseUtils::absoluteFuzzyEqual(_gravity_magnitude, 0.0)
121  ? 0.0
122  : std::acos(_dir * _gravity_vector / (_dir.norm() * _gravity_magnitude)) *
123  180 / M_PI),
124  _pipe_pars_transferred(getParam<bool>("pipe_pars_transferred")),
125  _roughness(getParam<Real>("roughness")),
126  _HT_geometry(getEnumParam<EConvHeatTransGeom>("heat_transfer_geom")),
127  _pipe_location(getEnumParam<EPipeLocation>("pipe_location")),
128  _PoD(getParam<Real>("PoD")),
129  _has_PoD(isParamValid("PoD")),
130  _temperature_mode(false),
131  _n_heat_transfer_connections(0)
132 {
133 }
134 
135 std::shared_ptr<const FlowModel>
137 {
139 
140  return _flow_model;
141 }
142 
143 const FunctionName &
145 {
147 
148  return _area_function;
149 }
150 
151 FunctionName
153 {
154  // Area function has already been created; just need to return its name
155  return getParam<FunctionName>("A");
156 }
157 
158 void
160 {
162 
164 
166  if (_flow_model)
167  {
168  _flow_model->init();
169 
170  const auto & closures_names = getParam<std::vector<std::string>>("closures");
171  for (const auto & closures_name : closures_names)
172  _closures_objects.push_back(getTHMProblem().getClosures(closures_name));
173  }
174 }
175 
176 void
178 {
180 
181  // Determine heat transfer mode based on connected heat transfer components;
182  // if at least one heat transfer component of temperature component is
183  // connected, then it's temperature mode. Otherwise, it's heat flux mode, even
184  // if no heat transfer components at all were provided - in that case, a zero
185  // heat flux is added.
186  for (unsigned int i = 0; i < _heat_transfer_names.size(); i++)
187  {
188  const HeatTransferBase & heat_transfer =
189  getComponentByName<HeatTransferBase>(_heat_transfer_names[i]);
190  if (heat_transfer.isTemperatureType())
191  _temperature_mode = true;
192  }
193 }
194 
195 void
197 {
199 
200  for (const auto & closures : _closures_objects)
201  closures->checkFlowChannel(*this);
202 
203  // check types of heat transfer for all sources; must be all of same type
204  if (_temperature_mode)
205  for (unsigned int i = 0; i < _heat_transfer_names.size(); i++)
206  {
207  const HeatTransferBase & heat_transfer =
208  getComponentByName<HeatTransferBase>(_heat_transfer_names[i]);
209  if (!heat_transfer.isTemperatureType())
210  logError("Heat sources for a flow channel must be all of temperature type or all of heat "
211  "flux type");
212  }
213 }
214 
215 void
217 {
218  // This should be called after initSecondary() because it relies on the names
219  // generated in initSecondary() of heat transfer components
221 
222  _flow_model->addVariables();
223 
224  // total heat flux perimeter
226  {
227  const std::string class_name = "SumIC";
228  InputParameters params = _factory.getValidParams(class_name);
229  params.set<VariableName>("variable") = FlowModel::HEAT_FLUX_PERIMETER;
230  params.set<std::vector<SubdomainName>>("block") = getSubdomainNames();
231  params.set<std::vector<VariableName>>("values") = _P_hf_names;
232  getTHMProblem().addSimInitialCondition(class_name, genName(name(), "P_hf_ic"), params);
233  }
234 
235  _flow_model->addInitialConditions();
236 }
237 
238 void
240 {
242  ts_execute_on = {EXEC_TIMESTEP_BEGIN, EXEC_INITIAL};
243 
244  {
245  std::string class_name = "DirectionMaterial";
246  InputParameters params = _factory.getValidParams(class_name);
247  params.set<std::vector<SubdomainName>>("block") = getSubdomainNames();
248  getTHMProblem().addMaterial(class_name, genName(name(), "dir_mat"), params);
249  }
250 
252  {
253  // Area
254  {
255  std::string class_name = "FunctionAux";
256  InputParameters params = _factory.getValidParams(class_name);
257  params.set<AuxVariableName>("variable") = FlowModel::AREA_LINEAR;
258  params.set<std::vector<SubdomainName>>("block") = getSubdomainNames();
259  params.set<FunctionName>("function") = _area_function;
260  params.set<ExecFlagEnum>("execute_on") = ts_execute_on;
261  const std::string aux_kernel_name = genName(name(), "area_linear_aux");
262  getTHMProblem().addAuxKernel(class_name, aux_kernel_name, params);
263  }
264  {
265  const std::string class_name = "ProjectionAux";
266  InputParameters params = _factory.getValidParams(class_name);
267  params.set<AuxVariableName>("variable") = FlowModel::AREA;
268  params.set<std::vector<SubdomainName>>("block") = getSubdomainNames();
269  params.set<std::vector<VariableName>>("v") = {FlowModel::AREA_LINEAR};
270  params.set<ExecFlagEnum>("execute_on") = ts_execute_on;
271  const std::string aux_kernel_name = genName(name(), "area_aux");
272  getTHMProblem().addAuxKernel(class_name, aux_kernel_name, params);
273  }
274  }
275 }
276 
277 void
279 {
281 
282  ExecFlagEnum execute_on_initial_linear(MooseUtils::getDefaultExecFlagEnum());
283  execute_on_initial_linear = {EXEC_INITIAL, EXEC_LINEAR};
284 
285  // total heat flux perimeter aux kernel
287  {
288  const std::string class_name = "SumAux";
289  InputParameters params = _factory.getValidParams(class_name);
290  params.set<AuxVariableName>("variable") = FlowModel::HEAT_FLUX_PERIMETER;
291  params.set<std::vector<SubdomainName>>("block") = getSubdomainNames();
292  params.set<std::vector<VariableName>>("values") = _P_hf_names;
293  params.set<ExecFlagEnum>("execute_on") = execute_on_initial_linear;
294  getTHMProblem().addAuxKernel(class_name, genName(name(), "P_hf_auxkernel"), params);
295  }
296 
297  // weighted average wall heat flux aux kernel
298  if (!_temperature_mode)
299  {
301  {
302  const std::string class_name = "ADWeightedAverageMaterial";
303  InputParameters params = _factory.getValidParams(class_name);
304  params.set<MaterialPropertyName>("prop_name") = FlowModel::HEAT_FLUX_WALL;
305  params.set<std::vector<SubdomainName>>("block") = getSubdomainNames();
306  params.set<std::vector<MaterialPropertyName>>("values") = _q_wall_names;
307  params.set<std::vector<VariableName>>("weights") = _P_hf_names;
309  class_name, genName(name(), FlowModel::HEAT_FLUX_WALL, "w_avg_mat"), params);
310  }
311  else if (_n_heat_transfer_connections == 0)
312  {
313  const std::string class_name = "ADConstantMaterial";
314  InputParameters params = _factory.getValidParams(class_name);
315  params.set<std::string>("property_name") = FlowModel::HEAT_FLUX_WALL;
316  params.set<std::vector<SubdomainName>>("block") = getSubdomainNames();
317  params.set<Real>("value") = 0;
319  class_name, genName(name(), FlowModel::HEAT_FLUX_WALL, "zero_mat"), params);
320  }
321  }
322 
323  const auto & vpp_vars = getParam<std::vector<VariableName>>("vpp_vars");
324  if (vpp_vars.size() > 0)
325  {
326  const std::string class_name = "ElementValueSampler";
327  InputParameters params = _factory.getValidParams(class_name);
328  params.set<std::vector<SubdomainName>>("block") = getSubdomainNames();
329  params.set<std::vector<VariableName>>("variable") = vpp_vars;
330  params.set<std::string>("sort_by") = sortBy();
331  params.set<ExecFlagEnum>("execute_on") = {EXEC_INITIAL, EXEC_TIMESTEP_END};
332  getTHMProblem().addVectorPostprocessor(class_name, name() + "_vars_vpp", params);
333  }
334 
335  _flow_model->addMooseObjects();
336 
337  for (const auto & closures : _closures_objects)
338  closures->addMooseObjectsFlowChannel(*this);
339 }
340 
341 void
342 FlowChannelBase::addHeatTransferName(const std::string & name) const
343 {
344  _heat_transfer_names.push_back(name);
346 }
347 
348 void
350 {
351  for (unsigned int i = 0; i < _n_heat_transfer_connections; i++)
352  {
353  const HeatTransferBase & heat_transfer =
354  getComponentByName<HeatTransferBase>(_heat_transfer_names[i]);
355 
356  _P_hf_names.push_back(heat_transfer.getHeatedPerimeterName());
357  _T_wall_names.push_back(heat_transfer.getWallTemperatureName());
358  _T_wall_mat_names.push_back(heat_transfer.getWallTemperatureMatName());
359  _q_wall_names.push_back(heat_transfer.getWallHeatFluxName());
360  }
361 }
362 
363 std::string
364 FlowChannelBase::getHeatTransferNamesSuffix(const std::string & ht_name) const
365 {
367 
368  // if there is more than one connected heat transfer component, then number them
370  {
371  // determine index of heat transfer name based on when it was added
372  auto it = std::find(_heat_transfer_names.begin(), _heat_transfer_names.end(), ht_name);
373  if (it != _heat_transfer_names.end())
374  {
375  const unsigned int index = std::distance(_heat_transfer_names.begin(), it);
376 
377  std::string suffix = ":";
378  if (getParam<bool>("name_multiple_ht_by_index"))
379  suffix += std::to_string(index + 1);
380  else
381  suffix += _heat_transfer_names[index];
382 
383  return suffix;
384  }
385  else
386  mooseError(
387  "Heat transfer component '", ht_name, "' was not added to flow channel '", name(), "'");
388  }
389  // else, don't add a suffix; there is no need
390  else
391  return "";
392 }
393 
394 std::vector<std::string>
396 {
398 
399  return _heat_transfer_names;
400 }
static const std::string AREA_LINEAR
Definition: FlowModel.h:103
const FunctionName & getAreaFunctionName() const
Get the name of the function describing the flow channel area.
virtual void init() override
Initializes the component.
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.
Component1DConnection::EEndType stringToEnum(const std::string &s)
std::string sortBy() const
Definition: Component1D.C:169
static InputParameters validParams()
void addParam(const std::string &name, const std::initializer_list< typename T::value_type > &value, const std::string &doc_string)
std::shared_ptr< FlowModel > _flow_model
The flow model used by this flow channel.
void setDocString(const std::string &name, const std::string &doc)
void addPrivateParam(const std::string &name, const T &value)
static const std::string AREA
Definition: FlowModel.h:102
virtual std::shared_ptr< FlowModel > buildFlowModel()=0
EPipeLocation
Pipe location.
std::vector< VariableName > _P_hf_names
heated perimeter names for connected heat transfers
THMProblem & getTHMProblem() const
Gets the THM problem.
Definition: Component.C:135
virtual void addMaterial(const std::string &material_name, const std::string &name, InputParameters &parameters)
const bool & _pipe_pars_transferred
T & set(const std::string &name, bool quiet_mode=false)
bool _temperature_mode
True if there is one or more sources specified by wall temperature.
InputParameters getValidParams(const std::string &name) const
Interface for specifying gravity at the component level.
static const std::map< std::string, EPipeType > _pipe_type_to_enum
Map of pipe type to enum.
const ExecFlagType EXEC_TIMESTEP_END
virtual void addAuxKernel(const std::string &kernel_name, const std::string &name, InputParameters &parameters)
static InputParameters validParams()
EPipeType
Pipe type.
static MooseEnum getPipeType(const std::string &name)
Gets a MooseEnum for pipe type.
bool isRestarting() const
void addRequiredParam(const std::string &name, const std::string &doc_string)
virtual std::shared_ptr< const FlowModel > getFlowModel() const
std::vector< MaterialPropertyName > _q_wall_names
wall heat flux names for connected heat transfers
ExecFlagEnum getDefaultExecFlagEnum()
void logError(Args &&... args) const
Logs an error.
Definition: Component.h:226
virtual void check() const override
Check the component integrity.
EConvHeatTransGeom
Type of convective heat transfer geometry.
std::vector< std::string > _heat_transfer_names
Names of the heat transfer components connected to this component.
const std::string & name() const
unsigned int _n_heat_transfer_connections
Number of connected heat transfer components.
const ExecFlagType EXEC_TIMESTEP_BEGIN
std::vector< std::string > getHeatTransferNames() const
Gets the names of all connected heat transfer components.
const MaterialPropertyName & getWallHeatFluxName() const
Returns wall heat flux name.
void addHeatTransferName(const std::string &ht_name) const
Adds the name of a heat transfer component to the flow channel&#39;s list.
const std::string name
Definition: Setup.h:21
EPipeLocation getPipeLocation() const
Gets the pipe location.
virtual void addVectorPostprocessor(const std::string &pp_name, const std::string &name, InputParameters &parameters)
mesh set up, called primary init
Definition: Component.h:41
virtual void init()
Initializes the component.
Definition: Component.h:405
Base class for 1D components.
Definition: Component1D.h:18
Base class for heat transfer connections.
virtual void getHeatTransferVariableNames()
Populates heat connection variable names lists.
const ExecFlagType EXEC_LINEAR
FunctionName _area_function
Function describing the flow channel area.
virtual void initSecondary()
Perform secondary initialization, which relies on init() being called for all components.
Definition: Component.h:411
virtual void addVariables() override
std::vector< std::shared_ptr< ClosuresBase > > _closures_objects
Closures object(s)
static const std::string HEAT_FLUX_PERIMETER
Definition: FlowModel.h:105
virtual void addMooseObjects() override
void addSimInitialCondition(const std::string &type, const std::string &name, InputParameters params)
Definition: Simulation.C:495
std::vector< VariableName > _T_wall_names
wall temperature auxvariable names for connected heat transfers
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
MooseApp & _app
void checkSetupStatus(const EComponentSetupStatus &status) const
Throws an error if the supplied setup status of this component has not been reached.
Definition: Component.C:117
auto norm(const T &a)
static const std::map< std::string, EPipeLocation > _pipe_location_to_enum
Map of pipe location to enum.
Factory & _factory
The Factory associated with the MooseApp.
Definition: Component.h:497
static InputParameters validParams()
Definition: Component1D.C:14
virtual void check() const override
Check the component integrity.
std::vector< MaterialPropertyName > _T_wall_mat_names
wall temperature material names for connected heat transfers
static const std::string HEAT_FLUX_WALL
Definition: FlowModel.h:104
void mooseError(Args &&... args) const
std::string getHeatTransferNamesSuffix(const std::string &ht_name) const
Gets suffix to add to heat-transfer-related names in a heat transfer component.
const VariableName & getWallTemperatureName() const
Returns wall temperature name.
FlowChannelBase(const InputParameters &params)
static MooseEnum getConvHeatTransGeometry(const std::string &name)
Gets a MooseEnum for convective heat transfer geometry type.
virtual void initSecondary() override
Perform secondary initialization, which relies on init() being called for all components.
virtual const std::vector< SubdomainName > & getSubdomainNames() const
Gets the subdomain names for this component.
Definition: Component.C:345
const VariableName & getHeatedPerimeterName() const
Returns heated perimeter name.
const MaterialPropertyName & getWallTemperatureMatName() const
Returns wall temperature name.
virtual FunctionName createAreaFunctionAndGetName()
Creates the area function if needed and then stores the name.
virtual void addCommonObjects()
Adds objects which are common for single- and two-phase flow.
virtual bool isTemperatureType() const =0
Returns whether this heat transfer is specified by temperature, rather than heat flux.
static const std::map< std::string, EConvHeatTransGeom > _heat_transfer_geom_to_enum
Map of convective heat transfer geometry type to enum.
const ExecFlagType EXEC_INITIAL