https://mooseframework.inl.gov
Loading...
Searching...
No Matches
SCMQuadAssemblyMeshGenerator.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 "SubChannelMesh.h"
12
13#include "libmesh/edge_edge2.h"
14
15#include <algorithm>
16#include <cmath>
17#include <limits>
18#include <memory>
19#include <numeric>
20
23 SCMQuadSubChannelMeshGenerator,
24 "06/30/2027 24:00",
27 QuadSubChannelMeshGenerator,
28 "06/30/2027 24:00",
31 SCMQuadPinMeshGenerator,
32 "06/30/2027 24:00",
35 QuadPinMeshGenerator,
36 "06/30/2027 24:00",
38
41{
43 params.addClassDescription("Creates one mesh containing both 1D subchannels and 1D pins in a "
44 "square lattice arrangement");
45
46 params.addRequiredParam<Real>("pitch", "Pitch [m]");
47 params.addRequiredParam<Real>("pin_diameter", "Rod diameter [m]");
48 params.addParam<Real>("unheated_length_entry", 0.0, "Unheated length at entry [m]");
49 params.addRequiredParam<Real>("heated_length", "Heated length [m]");
50 params.addParam<Real>("unheated_length_exit", 0.0, "Unheated length at exit [m]");
51
52 params.addParam<std::vector<Real>>(
53 "spacer_z", {}, "Axial location of spacers/vanes/mixing vanes [m]");
54 params.addParam<std::vector<Real>>(
55 "spacer_k", {}, "K-loss coefficient of spacers/vanes/mixing vanes [-]");
56
57 params.addParam<std::vector<Real>>("z_blockage",
58 std::vector<Real>({0.0, 0.0}),
59 "Axial location of blockage (inlet, outlet) [m]");
60 params.addParam<std::vector<unsigned int>>("index_blockage",
61 std::vector<unsigned int>({0}),
62 "Index of subchannels affected by blockage");
63 params.addParam<std::vector<Real>>("reduction_blockage",
64 std::vector<Real>({1.0}),
65 "Area reduction of subchannels affected by blockage");
66 params.addParam<std::vector<Real>>(
67 "k_blockage", std::vector<Real>({0.0}), "Form loss coefficient of blocked subchannels");
68
69 params.addParam<Real>("Kij", 0.5, "Lateral form loss coefficient [-]");
70 params.addRequiredParam<unsigned int>("n_cells", "The number of cells in the axial direction");
71 params.addRequiredParam<unsigned int>("nx", "Number of channels in the x direction [-]");
72 params.addRequiredParam<unsigned int>("ny", "Number of channels in the y direction [-]");
73
74 params.addRequiredParam<Real>(
75 "side_gap",
76 "The side gap, not to be confused with the gap between pins; this refers to the gap next "
77 "to the duct or else the distance between the subchannel centroid and the duct wall. "
78 "distance(edge pin center, duct wall) = pitch / 2 + side_gap [m]");
79
80 params.addParam<unsigned int>("subchannel_block_id", 0, "Subchannel block id");
81 params.addParam<unsigned int>("pin_block_id", 1, "Fuel Pin block id");
82
83 return params;
84}
85
87 : MeshGenerator(params),
88 _unheated_length_entry(getParam<Real>("unheated_length_entry")),
89 _heated_length(getParam<Real>("heated_length")),
90 _unheated_length_exit(getParam<Real>("unheated_length_exit")),
91 _spacer_z(getParam<std::vector<Real>>("spacer_z")),
92 _spacer_k(getParam<std::vector<Real>>("spacer_k")),
93 _z_blockage(getParam<std::vector<Real>>("z_blockage")),
94 _index_blockage(getParam<std::vector<unsigned int>>("index_blockage")),
95 _reduction_blockage(getParam<std::vector<Real>>("reduction_blockage")),
96 _k_blockage(getParam<std::vector<Real>>("k_blockage")),
97 _kij(getParam<Real>("Kij")),
98 _pitch(getParam<Real>("pitch")),
99 _pin_diameter(getParam<Real>("pin_diameter")),
100 _n_cells(getParam<unsigned int>("n_cells")),
101 _nx(getParam<unsigned int>("nx")),
102 _ny(getParam<unsigned int>("ny")),
103 _n_channels(0),
104 _n_gaps(0),
105 _n_pins(0),
106 _side_gap(getParam<Real>("side_gap")),
107 _subchannel_block_id(getParam<unsigned int>("subchannel_block_id")),
108 _pin_block_id(getParam<unsigned int>("pin_block_id"))
109{
110 const Real total_length = _unheated_length_entry + _heated_length + _unheated_length_exit;
111
112 if (_n_cells == 0)
113 paramError("n_cells", "The number of axial cells must be greater than zero");
114
115 if (total_length <= 0.0)
116 mooseError("Total bundle length must be greater than zero");
117
118 if (_nx == 0 || _ny == 0)
119 mooseError("The number of subchannels must be greater than zero in each direction");
120
121 if (_nx < 2 && _ny < 2)
122 mooseError("The number of subchannels cannot be less than 2 in both directions. "
123 "Smallest assembly allowed is either 2X1 or 1X2.");
124
125 _n_channels = _nx * _ny;
126 _n_gaps = (_nx - 1) * _ny + (_ny - 1) * _nx;
127 _n_pins = (_nx - 1) * (_ny - 1);
128
129 if (_spacer_z.size() != _spacer_k.size())
130 mooseError("Size of vector spacer_z should equal size of spacer_k");
131
132 for (const auto spacer_z : _spacer_z)
133 if (spacer_z < 0.0 || spacer_z > total_length)
134 paramError("spacer_z", "Spacer locations must be between zero and total bundle length");
135
136 if (_z_blockage.size() != 2)
137 paramError("z_blockage", "Size of vector z_blockage must be 2");
138
139 if (_z_blockage.front() > _z_blockage.back())
140 paramError("z_blockage", "z_blockage inlet location must not exceed outlet location");
141
142 if (!_index_blockage.empty() &&
143 *std::max_element(_index_blockage.begin(), _index_blockage.end()) > (_n_channels - 1))
144 paramError("index_blockage", "Blocked subchannel index exceeds valid subchannel range");
145
146 if (!_reduction_blockage.empty() &&
147 *std::max_element(_reduction_blockage.begin(), _reduction_blockage.end()) > 1.0)
148 paramError("reduction_blockage", "Area reduction of blocked subchannels cannot exceed 1");
149
150 if ((_index_blockage.size() > _n_channels) || (_reduction_blockage.size() > _n_channels) ||
151 (_k_blockage.size() > _n_channels))
152 mooseError("Sizes of blockage-related vectors cannot exceed total number of subchannels");
153
154 if ((_index_blockage.size() != _reduction_blockage.size()) ||
155 (_index_blockage.size() != _k_blockage.size()) ||
156 (_reduction_blockage.size() != _k_blockage.size()))
157 mooseError("index_blockage, reduction_blockage, and k_blockage must have equal size");
158
161
163}
164
165void
167{
168 // Defining the total length from 3 axial sections
170
171 // Defining the position of the spacer grid in the numerical solution array
172 std::vector<int> spacer_cell;
173 for (const auto & elem : _spacer_z)
174 spacer_cell.emplace_back(std::round(elem * _n_cells / L));
175
176 // Defining the arrays for axial resistances
177 std::vector<Real> kgrid(_n_cells + 1, 0.0);
178 _k_grid.resize(_n_channels, std::vector<Real>(_n_cells + 1));
179
180 // Summing the spacer resistance to the 1D grid resistance array
181 for (unsigned int index = 0; index < spacer_cell.size(); index++)
182 kgrid[spacer_cell[index]] += _spacer_k[index];
183
184 // Creating the 2D grid resistance array
185 for (unsigned int i = 0; i < _n_channels; i++)
186 _k_grid[i] = kgrid;
187
188 // Add blockage resistance to the 2D grid resistance array
189 const Real dz = L / _n_cells;
190 for (unsigned int i = 0; i < _n_cells + 1; i++)
191 if ((dz * i >= _z_blockage.front() && dz * i <= _z_blockage.back()))
192 {
193 unsigned int index = 0;
194 for (const auto & i_ch : _index_blockage)
195 {
196 _k_grid[i_ch][i] += _k_blockage[index];
197 index++;
198 }
199 }
200
201 // Defining the size of the maps
203 _gap_to_pin_map.resize(_n_gaps);
204 _gapnodes.resize(_n_gaps);
209 _gij_map.resize(_n_cells + 1);
211
212 for (unsigned int i = 0; i < _n_channels; i++)
213 {
214 _subchannel_position[i].reserve(3);
215 for (unsigned int j = 0; j < 3; j++)
216 _subchannel_position.at(i).push_back(0.0);
217 }
218
219 for (unsigned int iz = 0; iz < _n_cells + 1; iz++)
220 _gij_map[iz].reserve(_n_gaps);
221
222 // Defining the signs for positive and negative flows
223 const Real positive_flow = 1.0;
224 const Real negative_flow = -1.0;
225
226 // Defining the subchannel types
227 _subch_type.resize(_n_channels);
228 for (unsigned int iy = 0; iy < _ny; iy++)
229 for (unsigned int ix = 0; ix < _nx; ix++)
230 {
231 const unsigned int i_ch = _nx * iy + ix;
232 const bool is_corner = (ix == 0 && iy == 0) || (ix == _nx - 1 && iy == 0) ||
233 (ix == 0 && iy == _ny - 1) || (ix == _nx - 1 && iy == _ny - 1);
234 const bool is_edge = (ix == 0 || iy == 0 || ix == _nx - 1 || iy == _ny - 1);
235
236 // Two channels side by side (a 1x2/2x1 grid) only occurs in verification cases; treat both
237 // as CENTER. The smallest physical assembly is 2x2 subchannels around a single pin.
238 if (_n_channels == 2)
240 else if (_n_channels == 4)
242 else if (is_corner)
244 else if (is_edge)
246 else
248 }
249
262 unsigned int i_gap = 0;
263 for (unsigned int iy = 0; iy < _ny; iy++)
264 for (unsigned int ix = 0; ix < _nx - 1; ix++)
265 {
266 const unsigned int i_ch = _nx * iy + ix;
267 const unsigned int j_ch = _nx * iy + (ix + 1);
268 _gap_to_chan_map[i_gap] = {i_ch, j_ch};
269 _chan_to_gap_map[i_ch].push_back(i_gap);
270 _chan_to_gap_map[j_ch].push_back(i_gap);
271 _sign_id_crossflow_map[i_ch].push_back(positive_flow);
272 _sign_id_crossflow_map[j_ch].push_back(negative_flow);
273
274 // Make a gap size map.
275 if (iy == 0 || iy == _ny - 1)
276 _gij_map[0].push_back((_pitch - _pin_diameter) / 2.0 + _side_gap);
277 else
278 _gij_map[0].push_back(_pitch - _pin_diameter);
279
280 ++i_gap;
281 }
282
283 // Index the north-south gaps.
284 for (unsigned int iy = 0; iy < _ny - 1; iy++)
285 for (unsigned int ix = 0; ix < _nx; ix++)
286 {
287 const unsigned int i_ch = _nx * iy + ix;
288 const unsigned int j_ch = _nx * (iy + 1) + ix;
289 _gap_to_chan_map[i_gap] = {i_ch, j_ch};
290 _chan_to_gap_map[i_ch].push_back(i_gap);
291 _chan_to_gap_map[j_ch].push_back(i_gap);
292 _sign_id_crossflow_map[i_ch].push_back(positive_flow);
293 _sign_id_crossflow_map[j_ch].push_back(negative_flow);
294
295 // Make a gap size map.
296 if (ix == 0 || ix == _nx - 1)
297 _gij_map[0].push_back((_pitch - _pin_diameter) / 2.0 + _side_gap);
298 else
299 _gij_map[0].push_back(_pitch - _pin_diameter);
300
301 ++i_gap;
302 }
303
304 for (unsigned int iz = 1; iz < _n_cells + 1; iz++)
305 _gij_map[iz] = _gij_map[0];
306
307 // Make pin to channel map.
308 for (unsigned int iy = 0; iy < _ny - 1; iy++)
309 for (unsigned int ix = 0; ix < _nx - 1; ix++)
310 {
311 const unsigned int i_pin = (_nx - 1) * iy + ix;
312 const unsigned int i_chan_1 = _nx * iy + ix;
313 const unsigned int i_chan_2 = _nx * (iy + 1) + ix;
314 const unsigned int i_chan_3 = _nx * (iy + 1) + (ix + 1);
315 const unsigned int i_chan_4 = _nx * iy + (ix + 1);
316
317 _pin_to_chan_map[i_pin].push_back(i_chan_1);
318 _pin_to_chan_map[i_pin].push_back(i_chan_2);
319 _pin_to_chan_map[i_pin].push_back(i_chan_3);
320 _pin_to_chan_map[i_pin].push_back(i_chan_4);
321 }
322
323 // Set the subchannel positions so that the center of the assembly is the zero point.
324 for (unsigned int iy = 0; iy < _ny; iy++)
325 for (unsigned int ix = 0; ix < _nx; ix++)
326 {
327 const unsigned int i_ch = _nx * iy + ix;
328 const Real offset_x = (_nx - 1) * _pitch / 2.0;
329 const Real offset_y = (_ny - 1) * _pitch / 2.0;
330 _subchannel_position[i_ch][0] = _pitch * ix - offset_x;
331 _subchannel_position[i_ch][1] = _pitch * iy - offset_y;
332 }
333
334 if (_n_pins > 0)
335 {
336 // Make channel to pin map.
337 for (unsigned int iy = 0; iy < _ny; iy++) // row
338 for (unsigned int ix = 0; ix < _nx; ix++)
339 {
340 const unsigned int i_ch = _nx * iy + ix;
341
342 // Corners contact 1/4 of one pin.
343 if (iy == 0 && ix == 0)
344 _chan_to_pin_map[i_ch].push_back((_nx - 1) * iy + ix);
345 else if (iy == _ny - 1 && ix == 0)
346 _chan_to_pin_map[i_ch].push_back((_nx - 1) * (iy - 1) + ix);
347 else if (iy == 0 && ix == _nx - 1)
348 _chan_to_pin_map[i_ch].push_back((_nx - 1) * iy + ix - 1);
349 else if (iy == _ny - 1 && ix == _nx - 1)
350 _chan_to_pin_map[i_ch].push_back((_nx - 1) * (iy - 1) + ix - 1);
351 // Sides contact 1/4 of two pins.
352 else if (iy == 0)
353 {
354 _chan_to_pin_map[i_ch].push_back((_nx - 1) * iy + ix);
355 _chan_to_pin_map[i_ch].push_back((_nx - 1) * iy + ix - 1);
356 }
357 else if (iy == _ny - 1)
358 {
359 _chan_to_pin_map[i_ch].push_back((_nx - 1) * (iy - 1) + ix);
360 _chan_to_pin_map[i_ch].push_back((_nx - 1) * (iy - 1) + ix - 1);
361 }
362 else if (ix == 0)
363 {
364 _chan_to_pin_map[i_ch].push_back((_nx - 1) * iy + ix);
365 _chan_to_pin_map[i_ch].push_back((_nx - 1) * (iy - 1) + ix);
366 }
367 else if (ix == _nx - 1)
368 {
369 _chan_to_pin_map[i_ch].push_back((_nx - 1) * iy + ix - 1);
370 _chan_to_pin_map[i_ch].push_back((_nx - 1) * (iy - 1) + ix - 1);
371 }
372 // Interior channels contact 1/4 of four pins.
373 else
374 {
375 _chan_to_pin_map[i_ch].push_back((_nx - 1) * iy + ix);
376 _chan_to_pin_map[i_ch].push_back((_nx - 1) * iy + ix - 1);
377 _chan_to_pin_map[i_ch].push_back((_nx - 1) * (iy - 1) + ix);
378 _chan_to_pin_map[i_ch].push_back((_nx - 1) * (iy - 1) + ix - 1);
379 }
380 }
381
382 // Make gap to pin map.
383 for (unsigned int ig = 0; ig < _n_gaps; ig++)
384 {
385 const auto i_ch = _gap_to_chan_map[ig].first;
386 const auto j_ch = _gap_to_chan_map[ig].second;
387 const auto & i_pins = _chan_to_pin_map[i_ch];
388 const auto & j_pins = _chan_to_pin_map[j_ch];
389
390 // Initialize with default values.
391 _gap_to_pin_map[ig] = {10000, 10000};
392
393 for (unsigned int i : i_pins)
394 for (unsigned int j : j_pins)
395 if (i == j)
396 {
397 if (_gap_to_pin_map[ig].first == 10000)
398 {
399 _gap_to_pin_map[ig].first = i;
400 _gap_to_pin_map[ig].second = i;
401 }
402 else
403 _gap_to_pin_map[ig].second = i;
404 }
405 }
406 }
407
408 // Reduce reserved memory in the channel-to-gap map.
409 for (auto & gap : _chan_to_gap_map)
410 gap.shrink_to_fit();
411
412 // Reduce reserved memory in the channel-to-pin map.
413 for (auto & pin : _chan_to_pin_map)
414 pin.shrink_to_fit();
415
416 // Reduce reserved memory in the pin-to-channel map.
417 for (auto & pin : _pin_to_chan_map)
418 pin.shrink_to_fit();
419}
420
421void
423 BoundaryInfo & boundary_info)
424{
425 mesh_base.reserve_elem(mesh_base.n_elem() + _n_cells * _ny * _nx);
426 mesh_base.reserve_nodes(mesh_base.n_nodes() + (_n_cells + 1) * _ny * _nx);
427
428 _nodes.resize(_nx * _ny);
429
430 const Real offset_x = (_nx - 1) * _pitch / 2.0;
431 const Real offset_y = (_ny - 1) * _pitch / 2.0;
432
433 // Add the points in the shape of a rectilinear grid. The grid is regular on the xy-plane with a
434 // spacing of `pitch` between points. The grid along z is irregular to account for pin spacers.
435 // Store pointers in the _nodes array so we can keep track of which points are in which channels.
436 dof_id_type node_id = mesh_base.n_nodes();
437 for (unsigned int iy = 0; iy < _ny; iy++)
438 for (unsigned int ix = 0; ix < _nx; ix++)
439 {
440 const unsigned int i_ch = _nx * iy + ix;
441 _nodes[i_ch].reserve(_n_cells + 1);
442
443 for (unsigned int iz = 0; iz < _n_cells + 1; iz++)
444 _nodes[i_ch].push_back(mesh_base.add_point(
445 Point(_pitch * ix - offset_x, _pitch * iy - offset_y, _z_grid[iz]), node_id++));
446 }
447
448 // Add the elements which in this case are 2-node edges that link each subchannel's nodes
449 // vertically.
450 dof_id_type elem_id = mesh_base.n_elem();
451 for (unsigned int iy = 0; iy < _ny; iy++)
452 for (unsigned int ix = 0; ix < _nx; ix++)
453 for (unsigned int iz = 0; iz < _n_cells; iz++)
454 {
455 Elem * elem = mesh_base.add_elem(std::make_unique<Edge2>());
456 elem->subdomain_id() = _subchannel_block_id;
457 elem->set_id(elem_id++);
458
459 const unsigned int i_ch = _nx * iy + ix;
460 elem->set_node(0, _nodes[i_ch][iz]);
461 elem->set_node(1, _nodes[i_ch][iz + 1]);
462
463 if (iz == 0)
464 boundary_info.add_side(elem, 0, 0);
465 if (iz == _n_cells - 1)
466 boundary_info.add_side(elem, 1, 1);
467 }
468
469 mesh_base.set_subdomain_name(_subchannel_block_id, "subchannel", true);
470}
471
472void
474{
475 mesh_base.reserve_elem(mesh_base.n_elem() + _n_cells * (_ny - 1) * (_nx - 1));
476 mesh_base.reserve_nodes(mesh_base.n_nodes() + (_n_cells + 1) * (_ny - 1) * (_nx - 1));
477
478 _pin_nodes.resize((_nx - 1) * (_ny - 1));
479
480 // Add the points in the shape of a rectilinear grid. The grid is regular on the xy-plane with a
481 // spacing of `pitch` between points. The grid along z is also regular. Store pointers in the
482 // _pin_nodes array so we can keep track of which points are in which pins.
483 const Real offset_x = (_nx - 2) * _pitch / 2.0;
484 const Real offset_y = (_ny - 2) * _pitch / 2.0;
485
486 dof_id_type node_id = mesh_base.n_nodes();
487 for (unsigned int iy = 0; iy < _ny - 1; iy++)
488 for (unsigned int ix = 0; ix < _nx - 1; ix++)
489 {
490 const unsigned int i_pin = (_nx - 1) * iy + ix;
491 _pin_nodes[i_pin].reserve(_n_cells + 1);
492
493 for (unsigned int iz = 0; iz < _n_cells + 1; iz++)
494 _pin_nodes[i_pin].push_back(mesh_base.add_point(
495 Point(_pitch * ix - offset_x, _pitch * iy - offset_y, _z_grid[iz]), node_id++));
496 }
497
498 // Add the elements which in this case are 2-node edges that link each pin's nodes vertically.
499 dof_id_type elem_id = mesh_base.n_elem();
500 for (unsigned int iy = 0; iy < _ny - 1; iy++)
501 for (unsigned int ix = 0; ix < _nx - 1; ix++)
502 for (unsigned int iz = 0; iz < _n_cells; iz++)
503 {
504 Elem * elem = mesh_base.add_elem(std::make_unique<Edge2>());
505 elem->subdomain_id() = _pin_block_id;
506 elem->set_id(elem_id++);
507
508 const unsigned int i_pin = (_nx - 1) * iy + ix;
509 elem->set_node(0, _pin_nodes[i_pin][iz]);
510 elem->set_node(1, _pin_nodes[i_pin][iz + 1]);
511 }
512
513 mesh_base.set_subdomain_name(_pin_block_id, "fuel_pins", true);
514}
515
516void
518{
519 // Move the metadata into QuadSubChannelMesh.
523 sch_mesh._z_grid = _z_grid;
524 sch_mesh._k_grid = _k_grid;
525 sch_mesh._spacer_z = _spacer_z;
526 sch_mesh._spacer_k = _spacer_k;
527 sch_mesh._z_blockage = _z_blockage;
530 sch_mesh._kij = _kij;
531 sch_mesh._pitch = _pitch;
532 sch_mesh._pin_diameter = _pin_diameter;
533 sch_mesh._n_cells = _n_cells;
534
535 sch_mesh._nx = _nx;
536 sch_mesh._ny = _ny;
537 sch_mesh._n_channels = _n_channels;
538 sch_mesh._n_gaps = _n_gaps;
539 sch_mesh._n_pins = _n_pins;
540 sch_mesh._side_gap = _side_gap;
541
542 sch_mesh._nodes = _nodes;
543 sch_mesh._pin_nodes = _pin_nodes;
544 sch_mesh._gapnodes = _gapnodes;
551 sch_mesh._gij_map = _gij_map;
553 sch_mesh._subch_type = _subch_type;
554
555 sch_mesh._duct_mesh_exist = false;
556 sch_mesh._pin_mesh_exist = (_n_pins > 0);
557}
558
559std::unique_ptr<MeshBase>
561{
562 auto mesh_base = buildMeshBaseObject();
563 BoundaryInfo & boundary_info = mesh_base->get_boundary_info();
564
565 mesh_base->set_spatial_dimension(3);
566
567 buildSubchannelMesh(*mesh_base, boundary_info);
568
569 if (_n_pins > 0)
570 buildPinMesh(*mesh_base);
571
572 boundary_info.sideset_name(0) = "inlet";
573 boundary_info.sideset_name(1) = "outlet";
574 boundary_info.nodeset_name(0) = "inlet";
575 boundary_info.nodeset_name(1) = "outlet";
576
577 mesh_base->prepare_for_use();
578
579 auto & sch_mesh = static_cast<QuadSubChannelMesh &>(*_mesh);
580 transferMetadata(sch_mesh);
581 sch_mesh.computeAssemblyHydraulicParameters();
582
583 return mesh_base;
584}
registerMooseObject("SubChannelApp", SCMQuadAssemblyMeshGenerator)
registerMooseObjectRenamed("SubChannelApp", SCMQuadSubChannelMeshGenerator, "06/30/2027 24:00", SCMQuadAssemblyMeshGenerator)
void ErrorVector unsigned int
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)
static InputParameters validParams()
std::unique_ptr< MeshBase > buildMeshBaseObject(unsigned int dim=libMesh::invalid_uint)
void paramError(const std::string &param, Args... args) const
void mooseError(Args &&... args) const
Creates the mesh of subchannels in a quadrilateral lattice.
std::vector< std::pair< unsigned int, unsigned int > > _gap_to_pin_map
map relating gap index to fuel pin index
std::vector< std::vector< double > > _sign_id_crossflow_map
Matrix used to give local sign to crossflow quantities.
std::vector< std::vector< unsigned int > > _pin_to_chan_map
map relating fuel pin index to subchannel index
unsigned int _ny
number of subchannels in the y direction
std::vector< std::vector< Real > > _gij_map
Vector to store gap size.
std::vector< EChannelType > _subch_type
Subchannel type.
std::vector< std::vector< Node * > > _gapnodes
vector of gap (interface between pairs of neighboring subchannels) nodes
std::vector< std::vector< Node * > > _pin_nodes
vector of fuel pin nodes
std::vector< std::vector< unsigned int > > _chan_to_pin_map
map relating subchannel index to fuel pin index
Real _side_gap
The side gap, not to be confused with the gap between pins, this refers to the gap next to the duct o...
unsigned int _n_gaps
Number of gaps per layer.
unsigned int _n_pins
Number of pins.
unsigned int _nx
number of subchannels in the x direction
std::vector< std::vector< unsigned int > > _chan_to_gap_map
map relating subchannel index to gap index
std::vector< std::vector< Node * > > _nodes
vector of subchannel nodes
unsigned int _n_channels
number of subchannels in total
std::vector< std::pair< unsigned int, unsigned int > > _gap_to_chan_map
map relating gap index to subchannel index
Mesh generator that builds a mesh of 1D lines representing subchannels and pins in a quadrilateral as...
std::vector< std::vector< Node * > > _gapnodes
gap nodes
void buildSubchannelMesh(MeshBase &mesh_base, BoundaryInfo &boundary_info)
Build the 1D subchannel elements and inlet/outlet boundaries.
std::vector< std::vector< Real > > _gij_map
gap size
std::vector< std::vector< Real > > _sign_id_crossflow_map
matrix used to give local sign to crossflow quantities
std::vector< unsigned int > _index_blockage
index of subchannels affected by blockage
unsigned int _nx
number of subchannels in the x direction
std::vector< std::vector< unsigned int > > _pin_to_chan_map
stores the map from pins to channels
Real _unheated_length_exit
unheated length of the fuel Pin at the exit of the assembly
std::vector< Real > _z_blockage
axial location of blockage (inlet, outlet) [m]
unsigned int _n_cells
number of axial cells
std::vector< Real > _spacer_z
axial location of the spacers
void buildPinMesh(MeshBase &mesh_base)
Build the 1D pin elements for assemblies with pins.
std::vector< Real > _z_grid
axial location of nodes
void initializeChannelData()
Build subchannel, gap, pin, and cross-flow maps used by QuadSubChannelMesh.
std::vector< EChannelType > _subch_type
subchannel type
std::vector< std::vector< Real > > _subchannel_position
x,y coordinates of the subchannel centroids
std::vector< Real > _spacer_k
form loss coefficient of the spacers
Real _pitch
distance between neighbor fuel pins, pitch
std::vector< Real > _reduction_blockage
area reduction of subchannels affected by blockage
std::vector< Real > _k_blockage
form loss coefficient of subchannels affected by blockage
std::vector< std::pair< unsigned int, unsigned int > > _gap_to_pin_map
stores the fuel pin pairs for each gap
std::vector< std::pair< unsigned int, unsigned int > > _gap_to_chan_map
stores the channel pairs for each gap
std::vector< std::vector< unsigned int > > _chan_to_pin_map
stores the fuel pins belonging to each subchannel
void transferMetadata(QuadSubChannelMesh &sch_mesh)
Move generated mesh metadata into the concrete QuadSubChannelMesh object.
unsigned int _n_channels
total number of subchannels
virtual std::unique_ptr< MeshBase > generate() override
std::vector< std::vector< Node * > > _pin_nodes
pin nodes
Real _heated_length
heated length of the fuel Pin
unsigned int _pin_block_id
pin block index
unsigned int _n_gaps
number of gaps per layer
unsigned int _ny
number of subchannels in the y direction
SCMQuadAssemblyMeshGenerator(const InputParameters &params)
Real _kij
lateral form loss coefficient
Real _side_gap
The side gap, not to be confused with the gap between pins, this refers to the gap next to the duct o...
std::vector< std::vector< Node * > > _nodes
channel nodes
std::vector< std::vector< Real > > _k_grid
axial form loss coefficient per computational cell
std::vector< std::vector< unsigned int > > _chan_to_gap_map
stores the gaps that form each subchannel
unsigned int _subchannel_block_id
subchannel block index
Real _unheated_length_entry
unheated length of the fuel Pin at the entry of the assembly
std::vector< unsigned int > _index_blockage
index of subchannels affected by blockage
std::vector< Real > _z_grid
axial location of nodes
std::vector< Real > _reduction_blockage
area reduction of subchannels affected by blockage
Real _kij
Lateral form loss coefficient.
Real _unheated_length_exit
unheated length of the fuel Pin at the exit of the assembly
std::vector< Real > _z_blockage
axial location of blockage (inlet, outlet) [m]
std::vector< Real > _spacer_z
axial location of the spacers
static void generateZGrid(Real unheated_length_entry, Real heated_length, Real unheated_length_exit, unsigned int n_cells, std::vector< Real > &z_grid)
Generate the spacing in z-direction using heated and unteaded lengths.
std::vector< Real > _spacer_k
form loss coefficient of the spacers
std::vector< std::vector< Real > > _subchannel_position
x,y coordinates of the subchannel centroids
std::vector< std::vector< Real > > _k_grid
axial form loss coefficient per computational cell
Real _pin_diameter
fuel Pin diameter
Real _unheated_length_entry
unheated length of the fuel Pin at the entry of the assembly
Real _pitch
Distance between the neighbor fuel pins, pitch.
unsigned int _n_cells
number of axial cells
Real _heated_length
heated length of the fuel Pin