https://mooseframework.inl.gov
Loading...
Searching...
No Matches
HeatTransferFromHeatStructure3D1Phase.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
11#include "FlowChannel1Phase.h"
14#include "THMMesh.h"
15#include "MooseMesh.h"
16#include "ClosuresBase.h"
17#include "HeatConductionModel.h"
18
20
23{
25
26 params.makeParamRequired<FunctionName>("P_hf");
27 params.makeParamNotRequired<std::string>("flow_channel");
28 params.suppressParameter<std::string>("flow_channel");
29 params.set<std::string>("flow_channel", true) = "";
30 params.addRequiredParam<std::vector<std::string>>(
31 "flow_channels", "List of flow channel component names to connect to");
32 params.addRequiredParam<BoundaryName>(
33 "boundary", "The name of the heat structure boundary this heat transfer is applied on.");
34 params.addRequiredParam<std::string>("hs", "Heat structure name");
35 params.addClassDescription("Connects multiple 1-phase flow channels and a 3D heat structure");
36
37 return params;
38}
39
41 const InputParameters & parameters)
43 _flow_channel_names(getParam<std::vector<std::string>>("flow_channels")),
44 _boundary(getParam<BoundaryName>("boundary")),
45 _hs_name(getParam<std::string>("hs")),
46 _mesh_alignment(constMesh()),
47 _layered_average_uo_direction(MooseEnum("x y z"))
48{
49 for (const auto & fch_name : _flow_channel_names)
50 addDependency(fch_name);
52}
53
54const libMesh::FEType &
59
60void
62{
63 if (hasComponentByName<HeatStructureFromFile3D>(_hs_name))
64 {
65 std::vector<dof_id_type> fchs_elem_ids;
66 for (unsigned int i = 0; i < _flow_channel_names.size(); i++)
67 {
68 auto fch_name = _flow_channel_names[i];
69 if (hasComponentByName<FlowChannel1Phase>(fch_name))
70 {
71 const FlowChannel1Phase & flow_channel = getComponentByName<FlowChannel1Phase>(fch_name);
72 fchs_elem_ids.insert(fchs_elem_ids.end(),
73 flow_channel.getElementIDs().begin(),
74 flow_channel.getElementIDs().end());
75 }
76 }
77
78 const auto & hs = getComponentByName<HeatStructureFromFile3D>(_hs_name);
79 if (hs.hasBoundary(_boundary))
80 {
81 _mesh_alignment.initialize(fchs_elem_ids, hs.getBoundaryInfo(_boundary));
82
83 for (const auto & fc_elem_id : fchs_elem_ids)
84 {
86 {
87 const auto & hs_elem_ids = _mesh_alignment.getCoupledSecondaryElemIDs(fc_elem_id);
88 for (const auto & hs_elem_id : hs_elem_ids)
89 getTHMProblem().augmentSparsity(fc_elem_id, hs_elem_id);
90 }
91 }
92 }
93 }
94}
95
98 const std::string & flow_channel_name) const
99{
100 const FlowChannel1Phase & flow_channel = getComponentByName<FlowChannel1Phase>(flow_channel_name);
101 RealVectorValue direction = flow_channel.getDirection().unit();
102 Real x_dir_norm = std::abs(direction * RealVectorValue(1, 0, 0));
103 Real y_dir_norm = std::abs(direction * RealVectorValue(0, 1, 0));
104 Real z_dir_norm = std::abs(direction * RealVectorValue(0, 0, 1));
105 if (x_dir_norm == 1 && y_dir_norm == 0 && z_dir_norm == 0)
106 return EAxisAlignment::X;
107 else if (x_dir_norm == 0 && y_dir_norm == 1 && z_dir_norm == 0)
108 return EAxisAlignment::Y;
109 else if (x_dir_norm == 0 && y_dir_norm == 0 && z_dir_norm == 1)
110 return EAxisAlignment::Z;
111 else
112 {
113 logError(
114 "The flow channel '", flow_channel_name, "' must be aligned with the x-, y-, or z- axis.");
116 }
117}
118
119void
121{
123
124 std::vector<EAxisAlignment> fch_axis_alignment;
125 std::vector<unsigned int> fch_num_elems;
126 std::vector<Real> fch_lengths;
127 for (const auto & fch_name : _flow_channel_names)
128 {
129 checkComponentOfTypeExistsByName<FlowChannel1Phase>(fch_name);
130
131 if (hasComponentByName<FlowChannel1Phase>(fch_name))
132 {
133 const FlowChannel1Phase & flow_channel = getComponentByName<FlowChannel1Phase>(fch_name);
134
135 flow_channel.addHeatTransferName(name());
136 fch_axis_alignment.push_back(getFlowChannelAxisAlignment(fch_name));
137
138 const auto subdomain_names = flow_channel.getSubdomainNames();
140 _flow_channel_subdomains.end(), subdomain_names.begin(), subdomain_names.end());
141
142 const auto & closures = flow_channel.getClosuresObjects();
143 _flow_channel_closures.insert(_flow_channel_closures.end(), closures.begin(), closures.end());
144
145 fch_num_elems.push_back(flow_channel.getNumElems());
146
147 fch_lengths.push_back(flow_channel.getLength());
148 }
149 }
150
151 // check that all flow channels have the same axis alignment
152 if (fch_axis_alignment.size() > 1)
153 {
154 for (unsigned int i = 1; i < fch_axis_alignment.size(); i++)
155 if (fch_axis_alignment[i] != fch_axis_alignment[0])
156 logError("Flow channel '",
158 "' has a different axis alignment (",
159 fch_axis_alignment[i],
160 "). Make sure all flow channels are aligned with the same axis.");
161 }
162 if (fch_axis_alignment.size() > 0 && fch_axis_alignment[0] != EAxisAlignment::INVALID)
163 _layered_average_uo_direction = fch_axis_alignment[0];
164
165 // check that all flow channels have the same number of elements
166 if (fch_num_elems.size() > 1)
167 {
168 for (unsigned int i = 1; i < fch_num_elems.size(); i++)
169 if (fch_num_elems[i] != fch_num_elems[0])
170 logError("Flow channel '",
172 "' has ",
173 fch_num_elems[i],
174 " elements which is inconsistent with the rest of the flow channels. Make sure "
175 "all flow channels have the same number of elements.");
176 }
177 if (fch_num_elems.size() > 0)
178 _num_layers = fch_num_elems[0];
179
180 // check that all flow channels have the same length
181 if (fch_lengths.size() > 1)
182 {
183 for (unsigned int i = 1; i < fch_lengths.size(); i++)
184 if (fch_lengths[i] != fch_lengths[0])
185 logError("Flow channel '",
187 "' has length equal to ",
188 fch_lengths[i],
189 " which is inconsistent with the rest of the flow channels. Make sure all flow "
190 "channels have the length.");
191 }
192}
193
194void
196{
198
199 for (const auto & fch_name : _flow_channel_names)
200 {
201 if (hasComponentByName<FlowChannel1Phase>(fch_name))
202 {
203 const FlowChannel1Phase & flow_channel = getComponentByName<FlowChannel1Phase>(fch_name);
204 const std::string suffix = flow_channel.getHeatTransferNamesSuffix(name());
209 }
210 }
211}
212
213void
215{
217
218 for (unsigned int i = 0; i < _flow_channel_closures.size(); i++)
219 {
220 auto & clsr = _flow_channel_closures[i];
221 if (clsr != nullptr && hasComponentByName<FlowChannel1Phase>(_flow_channel_names[i]))
222 clsr->checkHeatTransfer(*this, getComponentByName<FlowChannel1Phase>(_flow_channel_names[i]));
223 }
224
225 if (hasComponentByName<HeatStructureFromFile3D>(_hs_name))
226 {
227 const auto & hs = getComponentByName<HeatStructureFromFile3D>(_hs_name);
228 if (!hs.hasBoundary(_boundary))
229 logError("The boundary '", _boundary, "' does not exist on the component '", _hs_name, "'.");
230 }
231 else
232 logError("The component '", _hs_name, "' is not a HeatStructureFromFile3D component.");
233}
234
235void
237{
239 false, _P_hf_name, getTHMProblem().getFlowFEType(), _flow_channel_subdomains);
240
241 _P_hf_fn_name = getParam<FunctionName>("P_hf");
242
243 if (!_app.isRestarting())
245
248 libMesh::FEType(CONSTANT, MONOMIAL),
251 false, _T_wall_name, libMesh::FEType(CONSTANT, MONOMIAL), _flow_channel_subdomains);
252
253 // wall temperature initial condition
254 if (!getTHMProblem().hasInitialConditionsFromFile() && !_app.isRestarting())
255 {
256 const HeatStructureFromFile3D & hs = getComponentByName<HeatStructureFromFile3D>(_hs_name);
258 }
259}
260
261void
263{
265
266 for (unsigned int i = 0; i < _flow_channel_closures.size(); i++)
267 {
268 _flow_channel_closures[i]->addMooseObjectsHeatTransfer(
269 *this, getComponentByName<FlowChannel1Phase>(_flow_channel_names[i]));
270 }
271
273 execute_on = {EXEC_INITIAL, EXEC_LINEAR, EXEC_NONLINEAR};
274
275 std::vector<Point> fch_positions;
276 for (const auto & fch_name : _flow_channel_names)
277 {
278 const FlowChannel1Phase & flow_channel = getComponentByName<FlowChannel1Phase>(fch_name);
279 fch_positions.push_back(flow_channel.getPosition());
280 }
281
282 const UserObjectName T_wall_avg_uo_name = genName(name(), "T_wall_avg_uo");
283 {
284 const std::string class_name = "NearestPointLayeredSideAverage";
285 InputParameters params = _factory.getValidParams(class_name);
286 params.set<std::vector<VariableName>>("variable") = {HeatConductionModel::TEMPERATURE};
287 params.set<std::vector<BoundaryName>>("boundary") = {_boundary};
288 params.set<ExecFlagEnum>("execute_on") = execute_on;
289 params.set<MooseEnum>("direction") = _layered_average_uo_direction;
290 params.set<unsigned int>("num_layers") = _num_layers;
291 params.set<std::vector<Point>>("points") = fch_positions;
292 getTHMProblem().addUserObject(class_name, T_wall_avg_uo_name, params);
293 }
294 {
295 std::string class_name = "SpatialUserObjectAux";
296 InputParameters params = _factory.getValidParams(class_name);
297 params.set<std::vector<SubdomainName>>("block") = _flow_channel_subdomains;
298 params.set<AuxVariableName>("variable") = _T_wall_name;
299 params.set<ExecFlagEnum>("execute_on") = execute_on;
300 params.set<UserObjectName>("user_object") = T_wall_avg_uo_name;
301 getTHMProblem().addAuxKernel(class_name, genName(name(), "T_wall_transfer"), params);
302 }
303 {
304 const std::string class_name = "ADOneD3EqnEnergyHeatFluxFromHeatStructure3D";
305 InputParameters params = _factory.getValidParams(class_name);
306 params.set<std::vector<SubdomainName>>("block") = _flow_channel_subdomains;
307 params.set<std::vector<VariableName>>("P_hf") = {_P_hf_name};
308 params.set<MaterialPropertyName>("Hw") = _Hw_1phase_name;
309 params.set<UserObjectName>("user_object") = T_wall_avg_uo_name;
310 params.set<MaterialPropertyName>("T") = FlowModelSinglePhase::TEMPERATURE;
311 params.set<NonlinearVariableName>("variable") = FlowModelSinglePhase::RHOEA;
312 getTHMProblem().addKernel(class_name, genName(name(), "heat_flux_kernel"), params);
313 }
314
315 const UserObjectName heat_transfer_uo_name = genName(name(), "heat_flux_uo");
316 {
317 const std::string class_name = "ADHeatTransferFromHeatStructure3D1PhaseUserObject";
318 InputParameters params = _factory.getValidParams(class_name);
319 params.set<std::vector<SubdomainName>>("block") = _flow_channel_subdomains;
320 params.set<MeshAlignment1D3D *>("_mesh_alignment") = &_mesh_alignment;
321 params.set<std::vector<VariableName>>("P_hf") = {_P_hf_name};
322 params.set<MaterialPropertyName>("Hw") = _Hw_1phase_name;
323 params.set<MaterialPropertyName>("T") = FlowModelSinglePhase::TEMPERATURE;
324 params.set<ExecFlagEnum>("execute_on") = execute_on;
325 getTHMProblem().addUserObject(class_name, heat_transfer_uo_name, params);
326 }
327 {
328 const std::string class_name = "ADConvectionHeatTransfer3DBC";
329 InputParameters params = _factory.getValidParams(class_name);
330 params.set<std::vector<BoundaryName>>("boundary") = {_boundary};
331 params.set<NonlinearVariableName>("variable") = HeatConductionModel::TEMPERATURE;
332 params.set<UserObjectName>("ht_uo") = heat_transfer_uo_name;
333 getTHMProblem().addBoundaryCondition(class_name, genName(name(), "heat_flux_bc"), params);
334 }
335}
registerMooseObject("ThermalHydraulicsApp", HeatTransferFromHeatStructure3D1Phase)
const ExecFlagType EXEC_INITIAL
const ExecFlagType EXEC_LINEAR
const ExecFlagType EXEC_NONLINEAR
const std::string name
Definition Setup.h:21
virtual void init()
Initializes the component.
Definition Component.h:405
virtual const std::vector< SubdomainName > & getSubdomainNames() const
Gets the subdomain names for this component.
Definition Component.C:345
void logError(Args &&... args) const
Logs an error.
Definition Component.h:226
const std::vector< dof_id_type > & getElementIDs() const
Gets the element IDs corresponding to this component.
Definition Component.C:337
void addDependency(const std::string &dependency)
Adds a component name to the list of dependencies.
Definition Component.C:129
THMProblem & getTHMProblem() const
Gets the THM problem.
Definition Component.C:135
Factory & _factory
The Factory associated with the MooseApp.
Definition Component.h:497
virtual void check() const
Check the component integrity.
Definition Component.h:416
virtual void initSecondary()
Perform secondary initialization, which relies on init() being called for all components.
Definition Component.h:411
virtual RealVectorValue getDirection() const
virtual std::vector< std::shared_ptr< UserObject > > addUserObject(const std::string &user_object_name, const std::string &name, InputParameters &parameters)
virtual void addBoundaryCondition(const std::string &bc_name, const std::string &name, InputParameters &parameters)
virtual void addKernel(const std::string &kernel_name, const std::string &name, InputParameters &parameters)
virtual void addAuxKernel(const std::string &kernel_name, const std::string &name, InputParameters &parameters)
InputParameters getValidParams(const std::string &name) const
Single-component, single-phase flow channel.
std::vector< std::shared_ptr< ClosuresBase > > getClosuresObjects() const
Get the used closures object(s)
void addHeatTransferName(const std::string &ht_name) const
Adds the name of a heat transfer component to the flow channel's list.
std::string getHeatTransferNamesSuffix(const std::string &ht_name) const
Gets suffix to add to heat-transfer-related names in a heat transfer component.
static const std::string HEAT_TRANSFER_COEFFICIENT_WALL
static const std::string TEMPERATURE
static const std::string RHOEA
static const std::string HEAT_FLUX_WALL
Definition FlowModel.h:104
static const std::string TEMPERATURE_WALL
Definition FlowModel.h:108
static const std::string HEAT_FLUX_PERIMETER
Definition FlowModel.h:105
static const libMesh::FEType & feType()
Get the FE type used for heat conduction.
static const std::string TEMPERATURE
Heat structure component that loads the mesh from an ExodusII file.
FunctionName getInitialT() const
Gets the initial temperature function name.
MaterialPropertyName _Hw_1phase_name
1-phase wall heat transfer coefficient name
virtual void addMooseObjects() override
MaterialPropertyName _q_wall_name
wall heat flux name
VariableName _P_hf_name
heated perimeter name
VariableName _T_wall_name
wall temperature name
FunctionName _P_hf_fn_name
heated perimeter function name
std::vector< SubdomainName > _flow_channel_subdomains
Subdomains corresponding to the connected flow channel.
Connects a 1-phase flow channel and a 3D heat structure.
MooseEnum _layered_average_uo_direction
Direction for layered average user objects.
virtual EAxisAlignment getFlowChannelAxisAlignment(const std::string &flow_channel_name) const
virtual void setupMesh() override
Performs mesh setup such as creating mesh or naming mesh sets.
virtual void check() const override
Check the component integrity.
const std::vector< std::string > & _flow_channel_names
name of the connected flow channel
virtual void initSecondary() override
Perform secondary initialization, which relies on init() being called for all components.
HeatTransferFromHeatStructure3D1Phase(const InputParameters &parameters)
std::vector< std::shared_ptr< ClosuresBase > > _flow_channel_closures
Closures associated with each flow channel.
const BoundaryName & _boundary
Boundary names for which the boundary component applies.
virtual const libMesh::FEType & getFEType() override
Get the FE type for wall temperature variable.
MeshAlignment1D3D _mesh_alignment
Mesh alignment object.
unsigned int _num_layers
Number of layers in the flow channel direction.
virtual void init() override
Initializes the component.
Base class for heat transfer connections from temperature for 1-phase flow.
void suppressParameter(const std::string &name)
void addRequiredParam(const std::string &name, const std::string &doc_string)
void addClassDescription(const std::string &doc_string)
void makeParamNotRequired(const std::string &name)
T & set(const std::string &name, bool quiet_mode=false)
void makeParamRequired(const std::string &name)
Builds mapping between a 1D subdomain and a 3D boundary.
void initialize(const std::vector< dof_id_type > &primary_elem_ids, const std::vector< std::tuple< dof_id_type, unsigned short int > > &secondary_boundary_info)
Extracts mesh information and builds the mapping.
bool hasCoupledSecondaryElemIDs(const dof_id_type &primary_elem_id) const
Returns true if the given primary element ID has coupled secondary elements.
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.
bool isRestarting() const
MooseApp & _app
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.
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:68
void addFunctionIC(const VariableName &var_name, const std::string &func_name, const std::vector< SubdomainName > &block_names)
Definition Simulation.C:529
void addSimVariable(bool nl, const VariableName &name, libMesh::FEType fe_type, Real scaling_factor=1.0)
Queues a variable of type MooseVariableScalar to be added to the nonlinear or aux system.
ExecFlagEnum getDefaultExecFlagEnum()