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 
102  params.setDocString(
103  "orientation",
104  "Direction of flow channel from start position to end position (no need to normalize). For "
105  "curved flow channels, it is the (tangent) direction at the start position.");
106 
107  params.addPrivateParam<std::string>("component_type", "pipe");
108  params.declareControllable("A f");
109 
110  return params;
111 }
112 
114  : Component1D(params),
115  GravityInterface(params),
116 
117  _flow_model(nullptr),
118  _fp_name(getParam<UserObjectName>("fp")),
119  _gravity_angle(MooseUtils::absoluteFuzzyEqual(_gravity_magnitude, 0.0)
120  ? 0.0
121  : std::acos(_dir * _gravity_vector / (_dir.norm() * _gravity_magnitude)) *
122  180 / M_PI),
123  _pipe_pars_transferred(getParam<bool>("pipe_pars_transferred")),
124  _roughness(getParam<Real>("roughness")),
125  _HT_geometry(getEnumParam<EConvHeatTransGeom>("heat_transfer_geom")),
126  _pipe_location(getEnumParam<EPipeLocation>("pipe_location")),
127  _PoD(getParam<Real>("PoD")),
128  _has_PoD(isParamValid("PoD")),
129  _temperature_mode(false),
130  _n_heat_transfer_connections(0)
131 {
132 }
133 
134 std::shared_ptr<const FlowModel>
136 {
138 
139  return _flow_model;
140 }
141 
142 const FunctionName &
144 {
146 
147  return _area_function;
148 }
149 
150 FunctionName
152 {
153  // Area function has already been created; just need to return its name
154  return getParam<FunctionName>("A");
155 }
156 
157 void
159 {
161 
163 
165  if (_flow_model)
166  {
167  _flow_model->init();
168 
169  const auto & closures_names = getParam<std::vector<std::string>>("closures");
170  for (const auto & closures_name : closures_names)
171  _closures_objects.push_back(getTHMProblem().getClosures(closures_name));
172  }
173 }
174 
175 void
177 {
179 
180  // Determine heat transfer mode based on connected heat transfer components;
181  // if at least one heat transfer component of temperature component is
182  // connected, then it's temperature mode. Otherwise, it's heat flux mode, even
183  // if no heat transfer components at all were provided - in that case, a zero
184  // heat flux is added.
185  for (unsigned int i = 0; i < _heat_transfer_names.size(); i++)
186  {
187  const HeatTransferBase & heat_transfer =
188  getComponentByName<HeatTransferBase>(_heat_transfer_names[i]);
189  if (heat_transfer.isTemperatureType())
190  _temperature_mode = true;
191  }
192 }
193 
194 void
196 {
198 
199  for (const auto & closures : _closures_objects)
200  closures->checkFlowChannel(*this);
201 
202  // check types of heat transfer for all sources; must be all of same type
203  if (_temperature_mode)
204  for (unsigned int i = 0; i < _heat_transfer_names.size(); i++)
205  {
206  const HeatTransferBase & heat_transfer =
207  getComponentByName<HeatTransferBase>(_heat_transfer_names[i]);
208  if (!heat_transfer.isTemperatureType())
209  logError("Heat sources for a flow channel must be all of temperature type or all of heat "
210  "flux type");
211  }
212 }
213 
214 void
216 {
217  // This should be called after initSecondary() because it relies on the names
218  // generated in initSecondary() of heat transfer components
220 
221  _flow_model->addVariables();
222 
223  // total heat flux perimeter
225  {
226  const std::string class_name = "SumIC";
227  InputParameters params = _factory.getValidParams(class_name);
228  params.set<VariableName>("variable") = FlowModel::HEAT_FLUX_PERIMETER;
229  params.set<std::vector<SubdomainName>>("block") = getSubdomainNames();
230  params.set<std::vector<VariableName>>("values") = _P_hf_names;
231  getTHMProblem().addSimInitialCondition(class_name, genName(name(), "P_hf_ic"), params);
232  }
233 
234  _flow_model->addInitialConditions();
235 }
236 
237 void
239 {
241  ts_execute_on = {EXEC_TIMESTEP_BEGIN, EXEC_INITIAL};
242 
243  {
244  std::string class_name = "DirectionMaterial";
245  InputParameters params = _factory.getValidParams(class_name);
246  params.set<std::vector<SubdomainName>>("block") = getSubdomainNames();
247  getTHMProblem().addMaterial(class_name, genName(name(), "dir_mat"), params);
248  }
249 
251  {
252  // Area
253  {
254  std::string class_name = "FunctionAux";
255  InputParameters params = _factory.getValidParams(class_name);
256  params.set<AuxVariableName>("variable") = FlowModel::AREA_LINEAR;
257  params.set<std::vector<SubdomainName>>("block") = getSubdomainNames();
258  params.set<FunctionName>("function") = _area_function;
259  params.set<ExecFlagEnum>("execute_on") = ts_execute_on;
260  const std::string aux_kernel_name = genName(name(), "area_linear_aux");
261  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);
274  }
275  }
276 }
277 
278 void
280 {
282 
283  ExecFlagEnum execute_on_initial_linear(MooseUtils::getDefaultExecFlagEnum());
284  execute_on_initial_linear = {EXEC_INITIAL, EXEC_LINEAR};
285 
286  // total heat flux perimeter aux kernel
288  {
289  const std::string class_name = "SumAux";
290  InputParameters params = _factory.getValidParams(class_name);
291  params.set<AuxVariableName>("variable") = FlowModel::HEAT_FLUX_PERIMETER;
292  params.set<std::vector<SubdomainName>>("block") = getSubdomainNames();
293  params.set<std::vector<VariableName>>("values") = _P_hf_names;
294  params.set<ExecFlagEnum>("execute_on") = execute_on_initial_linear;
295  getTHMProblem().addAuxKernel(class_name, genName(name(), "P_hf_auxkernel"), params);
296  }
297 
298  // weighted average wall heat flux aux kernel
299  if (!_temperature_mode)
300  {
302  {
303  const std::string class_name = "ADWeightedAverageMaterial";
304  InputParameters params = _factory.getValidParams(class_name);
305  params.set<MaterialPropertyName>("prop_name") = FlowModel::HEAT_FLUX_WALL;
306  params.set<std::vector<SubdomainName>>("block") = getSubdomainNames();
307  params.set<std::vector<MaterialPropertyName>>("values") = _q_wall_names;
308  params.set<std::vector<VariableName>>("weights") = _P_hf_names;
310  class_name, genName(name(), FlowModel::HEAT_FLUX_WALL, "w_avg_mat"), params);
311  }
312  else if (_n_heat_transfer_connections == 0)
313  {
314  const std::string class_name = "ADConstantMaterial";
315  InputParameters params = _factory.getValidParams(class_name);
316  params.set<std::string>("property_name") = FlowModel::HEAT_FLUX_WALL;
317  params.set<std::vector<SubdomainName>>("block") = getSubdomainNames();
318  params.set<Real>("value") = 0;
320  class_name, genName(name(), FlowModel::HEAT_FLUX_WALL, "zero_mat"), params);
321  }
322  }
323 
324  _flow_model->addMooseObjects();
325 
326  for (const auto & closures : _closures_objects)
327  closures->addMooseObjectsFlowChannel(*this);
328 }
329 
330 void
331 FlowChannelBase::addHeatTransferName(const std::string & name) const
332 {
333  _heat_transfer_names.push_back(name);
335 }
336 
337 void
339 {
340  for (unsigned int i = 0; i < _n_heat_transfer_connections; i++)
341  {
342  const HeatTransferBase & heat_transfer =
343  getComponentByName<HeatTransferBase>(_heat_transfer_names[i]);
344 
345  _P_hf_names.push_back(heat_transfer.getHeatedPerimeterName());
346  _T_wall_names.push_back(heat_transfer.getWallTemperatureName());
347  _T_wall_mat_names.push_back(heat_transfer.getWallTemperatureMatName());
348  _q_wall_names.push_back(heat_transfer.getWallHeatFluxName());
349  }
350 }
351 
352 std::string
353 FlowChannelBase::getHeatTransferNamesSuffix(const std::string & ht_name) const
354 {
356 
357  // if there is more than one connected heat transfer component, then number them
359  {
360  // determine index of heat transfer name based on when it was added
361  auto it = std::find(_heat_transfer_names.begin(), _heat_transfer_names.end(), ht_name);
362  if (it != _heat_transfer_names.end())
363  {
364  const unsigned int index = std::distance(_heat_transfer_names.begin(), it);
365 
366  std::string suffix = ":";
367  if (getParam<bool>("name_multiple_ht_by_index"))
368  suffix += std::to_string(index + 1);
369  else
370  suffix += _heat_transfer_names[index];
371 
372  return suffix;
373  }
374  else
375  mooseError(
376  "Heat transfer component '", ht_name, "' was not added to flow channel '", name(), "'");
377  }
378  // else, don't add a suffix; there is no need
379  else
380  return "";
381 }
382 
383 std::vector<std::string>
385 {
387 
388  return _heat_transfer_names;
389 }
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)
bool absoluteFuzzyEqual(const T &var1, const T2 &var2, const T3 &tol=libMesh::TOLERANCE *libMesh::TOLERANCE)
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.
virtual void addAuxKernel(const std::string &kernel_name, const std::string &name, InputParameters &parameters)
static InputParameters validParams()
void makeFunctionControllableIfConstant(const FunctionName &fn_name, const std::string &control_name, const std::string &param="value") const
Makes a function controllable if it is constant.
Definition: Component.C:141
EPipeType
Pipe type.
static MooseEnum getPipeType(const std::string &name)
Gets a MooseEnum for pipe type.
bool isRestarting() const
virtual const std::string & name() 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:215
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.
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:20
EPipeLocation getPipeLocation() const
Gets the pipe location.
mesh set up, called primary init
Definition: Component.h:40
virtual void init()
Initializes the component.
Definition: Component.h:290
Base class for 1D components.
Definition: Component1D.h:18
Base class for heat transfer connections.
virtual void getHeatTransferVariableNames()
Populates heat connection variable names lists.
auto norm(const T &a) -> decltype(std::abs(a))
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:296
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
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:446
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:307
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.
void declareControllable(const std::string &name, std::set< ExecFlagType > execute_flags={})
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