https://mooseframework.inl.gov
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 
22 registerMooseObjectRenamed("SubChannelApp",
23  SCMQuadSubChannelMeshGenerator,
24  "06/30/2027 24:00",
26 registerMooseObjectRenamed("SubChannelApp",
27  QuadSubChannelMeshGenerator,
28  "06/30/2027 24:00",
30 registerMooseObjectRenamed("SubChannelApp",
31  SCMQuadPinMeshGenerator,
32  "06/30/2027 24:00",
34 registerMooseObjectRenamed("SubChannelApp",
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 {
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 
165 void
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
202  _gap_to_chan_map.resize(_n_gaps);
203  _gap_to_pin_map.resize(_n_gaps);
204  _gapnodes.resize(_n_gaps);
207  _pin_to_chan_map.resize(_n_pins);
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 
250  // Index the east-west gaps.
251  unsigned int i_gap = 0;
252  for (unsigned int iy = 0; iy < _ny; iy++)
253  for (unsigned int ix = 0; ix < _nx - 1; ix++)
254  {
255  const unsigned int i_ch = _nx * iy + ix;
256  const unsigned int j_ch = _nx * iy + (ix + 1);
257  _gap_to_chan_map[i_gap] = {i_ch, j_ch};
258  _chan_to_gap_map[i_ch].push_back(i_gap);
259  _chan_to_gap_map[j_ch].push_back(i_gap);
260  _sign_id_crossflow_map[i_ch].push_back(positive_flow);
261  _sign_id_crossflow_map[j_ch].push_back(negative_flow);
262 
263  // Make a gap size map.
264  if (iy == 0 || iy == _ny - 1)
265  _gij_map[0].push_back((_pitch - _pin_diameter) / 2.0 + _side_gap);
266  else
267  _gij_map[0].push_back(_pitch - _pin_diameter);
268 
269  ++i_gap;
270  }
271 
272  // Index the north-south gaps.
273  for (unsigned int iy = 0; iy < _ny - 1; iy++)
274  for (unsigned int ix = 0; ix < _nx; ix++)
275  {
276  const unsigned int i_ch = _nx * iy + ix;
277  const unsigned int j_ch = _nx * (iy + 1) + ix;
278  _gap_to_chan_map[i_gap] = {i_ch, j_ch};
279  _chan_to_gap_map[i_ch].push_back(i_gap);
280  _chan_to_gap_map[j_ch].push_back(i_gap);
281  _sign_id_crossflow_map[i_ch].push_back(positive_flow);
282  _sign_id_crossflow_map[j_ch].push_back(negative_flow);
283 
284  // Make a gap size map.
285  if (ix == 0 || ix == _nx - 1)
286  _gij_map[0].push_back((_pitch - _pin_diameter) / 2.0 + _side_gap);
287  else
288  _gij_map[0].push_back(_pitch - _pin_diameter);
289 
290  ++i_gap;
291  }
292 
293  for (unsigned int iz = 1; iz < _n_cells + 1; iz++)
294  _gij_map[iz] = _gij_map[0];
295 
296  // Make pin to channel map.
297  for (unsigned int iy = 0; iy < _ny - 1; iy++)
298  for (unsigned int ix = 0; ix < _nx - 1; ix++)
299  {
300  const unsigned int i_pin = (_nx - 1) * iy + ix;
301  const unsigned int i_chan_1 = _nx * iy + ix;
302  const unsigned int i_chan_2 = _nx * (iy + 1) + ix;
303  const unsigned int i_chan_3 = _nx * (iy + 1) + (ix + 1);
304  const unsigned int i_chan_4 = _nx * iy + (ix + 1);
305 
306  _pin_to_chan_map[i_pin].push_back(i_chan_1);
307  _pin_to_chan_map[i_pin].push_back(i_chan_2);
308  _pin_to_chan_map[i_pin].push_back(i_chan_3);
309  _pin_to_chan_map[i_pin].push_back(i_chan_4);
310  }
311 
312  // Set the subchannel positions so that the center of the assembly is the zero point.
313  for (unsigned int iy = 0; iy < _ny; iy++)
314  for (unsigned int ix = 0; ix < _nx; ix++)
315  {
316  const unsigned int i_ch = _nx * iy + ix;
317  const Real offset_x = (_nx - 1) * _pitch / 2.0;
318  const Real offset_y = (_ny - 1) * _pitch / 2.0;
319  _subchannel_position[i_ch][0] = _pitch * ix - offset_x;
320  _subchannel_position[i_ch][1] = _pitch * iy - offset_y;
321  }
322 
323  if (_n_pins > 0)
324  {
325  // Make channel to pin map.
326  for (unsigned int iy = 0; iy < _ny; iy++) // row
327  for (unsigned int ix = 0; ix < _nx; ix++)
328  {
329  const unsigned int i_ch = _nx * iy + ix;
330 
331  // Corners contact 1/4 of one pin.
332  if (iy == 0 && ix == 0)
333  _chan_to_pin_map[i_ch].push_back((_nx - 1) * iy + ix);
334  else if (iy == _ny - 1 && ix == 0)
335  _chan_to_pin_map[i_ch].push_back((_nx - 1) * (iy - 1) + ix);
336  else if (iy == 0 && ix == _nx - 1)
337  _chan_to_pin_map[i_ch].push_back((_nx - 1) * iy + ix - 1);
338  else if (iy == _ny - 1 && ix == _nx - 1)
339  _chan_to_pin_map[i_ch].push_back((_nx - 1) * (iy - 1) + ix - 1);
340  // Sides contact 1/4 of two pins.
341  else if (iy == 0)
342  {
343  _chan_to_pin_map[i_ch].push_back((_nx - 1) * iy + ix);
344  _chan_to_pin_map[i_ch].push_back((_nx - 1) * iy + ix - 1);
345  }
346  else if (iy == _ny - 1)
347  {
348  _chan_to_pin_map[i_ch].push_back((_nx - 1) * (iy - 1) + ix);
349  _chan_to_pin_map[i_ch].push_back((_nx - 1) * (iy - 1) + ix - 1);
350  }
351  else if (ix == 0)
352  {
353  _chan_to_pin_map[i_ch].push_back((_nx - 1) * iy + ix);
354  _chan_to_pin_map[i_ch].push_back((_nx - 1) * (iy - 1) + ix);
355  }
356  else if (ix == _nx - 1)
357  {
358  _chan_to_pin_map[i_ch].push_back((_nx - 1) * iy + ix - 1);
359  _chan_to_pin_map[i_ch].push_back((_nx - 1) * (iy - 1) + ix - 1);
360  }
361  // Interior channels contact 1/4 of four pins.
362  else
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 + ix - 1);
366  _chan_to_pin_map[i_ch].push_back((_nx - 1) * (iy - 1) + ix);
367  _chan_to_pin_map[i_ch].push_back((_nx - 1) * (iy - 1) + ix - 1);
368  }
369  }
370 
371  // Make gap to pin map.
372  for (unsigned int ig = 0; ig < _n_gaps; ig++)
373  {
374  const auto i_ch = _gap_to_chan_map[ig].first;
375  const auto j_ch = _gap_to_chan_map[ig].second;
376  const auto & i_pins = _chan_to_pin_map[i_ch];
377  const auto & j_pins = _chan_to_pin_map[j_ch];
378 
379  // Initialize with default values.
380  _gap_to_pin_map[ig] = {10000, 10000};
381 
382  for (unsigned int i : i_pins)
383  for (unsigned int j : j_pins)
384  if (i == j)
385  {
386  if (_gap_to_pin_map[ig].first == 10000)
387  {
388  _gap_to_pin_map[ig].first = i;
389  _gap_to_pin_map[ig].second = i;
390  }
391  else
392  _gap_to_pin_map[ig].second = i;
393  }
394  }
395  }
396 
397  // Reduce reserved memory in the channel-to-gap map.
398  for (auto & gap : _chan_to_gap_map)
399  gap.shrink_to_fit();
400 
401  // Reduce reserved memory in the channel-to-pin map.
402  for (auto & pin : _chan_to_pin_map)
403  pin.shrink_to_fit();
404 
405  // Reduce reserved memory in the pin-to-channel map.
406  for (auto & pin : _pin_to_chan_map)
407  pin.shrink_to_fit();
408 }
409 
410 void
412  BoundaryInfo & boundary_info)
413 {
414  mesh_base.reserve_elem(mesh_base.n_elem() + _n_cells * _ny * _nx);
415  mesh_base.reserve_nodes(mesh_base.n_nodes() + (_n_cells + 1) * _ny * _nx);
416 
417  _nodes.resize(_nx * _ny);
418 
419  const Real offset_x = (_nx - 1) * _pitch / 2.0;
420  const Real offset_y = (_ny - 1) * _pitch / 2.0;
421 
422  // Add the points in the shape of a rectilinear grid. The grid is regular on the xy-plane with a
423  // spacing of `pitch` between points. The grid along z is irregular to account for pin spacers.
424  // Store pointers in the _nodes array so we can keep track of which points are in which channels.
425  dof_id_type node_id = mesh_base.n_nodes();
426  for (unsigned int iy = 0; iy < _ny; iy++)
427  for (unsigned int ix = 0; ix < _nx; ix++)
428  {
429  const unsigned int i_ch = _nx * iy + ix;
430  _nodes[i_ch].reserve(_n_cells + 1);
431 
432  for (unsigned int iz = 0; iz < _n_cells + 1; iz++)
433  _nodes[i_ch].push_back(mesh_base.add_point(
434  Point(_pitch * ix - offset_x, _pitch * iy - offset_y, _z_grid[iz]), node_id++));
435  }
436 
437  // Add the elements which in this case are 2-node edges that link each subchannel's nodes
438  // vertically.
439  dof_id_type elem_id = mesh_base.n_elem();
440  for (unsigned int iy = 0; iy < _ny; iy++)
441  for (unsigned int ix = 0; ix < _nx; ix++)
442  for (unsigned int iz = 0; iz < _n_cells; iz++)
443  {
444  Elem * elem = mesh_base.add_elem(std::make_unique<Edge2>());
445  elem->subdomain_id() = _subchannel_block_id;
446  elem->set_id(elem_id++);
447 
448  const unsigned int i_ch = _nx * iy + ix;
449  elem->set_node(0, _nodes[i_ch][iz]);
450  elem->set_node(1, _nodes[i_ch][iz + 1]);
451 
452  if (iz == 0)
453  boundary_info.add_side(elem, 0, 0);
454  if (iz == _n_cells - 1)
455  boundary_info.add_side(elem, 1, 1);
456  }
457 
458  mesh_base.subdomain_name(_subchannel_block_id) = "subchannel";
459 }
460 
461 void
463 {
464  mesh_base.reserve_elem(mesh_base.n_elem() + _n_cells * (_ny - 1) * (_nx - 1));
465  mesh_base.reserve_nodes(mesh_base.n_nodes() + (_n_cells + 1) * (_ny - 1) * (_nx - 1));
466 
467  _pin_nodes.resize((_nx - 1) * (_ny - 1));
468 
469  // Add the points in the shape of a rectilinear grid. The grid is regular on the xy-plane with a
470  // spacing of `pitch` between points. The grid along z is also regular. Store pointers in the
471  // _pin_nodes array so we can keep track of which points are in which pins.
472  const Real offset_x = (_nx - 2) * _pitch / 2.0;
473  const Real offset_y = (_ny - 2) * _pitch / 2.0;
474 
475  dof_id_type node_id = mesh_base.n_nodes();
476  for (unsigned int iy = 0; iy < _ny - 1; iy++)
477  for (unsigned int ix = 0; ix < _nx - 1; ix++)
478  {
479  const unsigned int i_pin = (_nx - 1) * iy + ix;
480  _pin_nodes[i_pin].reserve(_n_cells + 1);
481 
482  for (unsigned int iz = 0; iz < _n_cells + 1; iz++)
483  _pin_nodes[i_pin].push_back(mesh_base.add_point(
484  Point(_pitch * ix - offset_x, _pitch * iy - offset_y, _z_grid[iz]), node_id++));
485  }
486 
487  // Add the elements which in this case are 2-node edges that link each pin's nodes vertically.
488  dof_id_type elem_id = mesh_base.n_elem();
489  for (unsigned int iy = 0; iy < _ny - 1; iy++)
490  for (unsigned int ix = 0; ix < _nx - 1; ix++)
491  for (unsigned int iz = 0; iz < _n_cells; iz++)
492  {
493  Elem * elem = mesh_base.add_elem(std::make_unique<Edge2>());
494  elem->subdomain_id() = _pin_block_id;
495  elem->set_id(elem_id++);
496 
497  const unsigned int i_pin = (_nx - 1) * iy + ix;
498  elem->set_node(0, _pin_nodes[i_pin][iz]);
499  elem->set_node(1, _pin_nodes[i_pin][iz + 1]);
500  }
501 
502  mesh_base.subdomain_name(_pin_block_id) = "fuel_pins";
503 }
504 
505 void
507 {
508  // Move the metadata into QuadSubChannelMesh.
510  sch_mesh._heated_length = _heated_length;
512  sch_mesh._z_grid = _z_grid;
513  sch_mesh._k_grid = _k_grid;
514  sch_mesh._spacer_z = _spacer_z;
515  sch_mesh._spacer_k = _spacer_k;
516  sch_mesh._z_blockage = _z_blockage;
517  sch_mesh._index_blockage = _index_blockage;
519  sch_mesh._kij = _kij;
520  sch_mesh._pitch = _pitch;
521  sch_mesh._pin_diameter = _pin_diameter;
522  sch_mesh._n_cells = _n_cells;
523 
524  sch_mesh._nx = _nx;
525  sch_mesh._ny = _ny;
526  sch_mesh._n_channels = _n_channels;
527  sch_mesh._n_gaps = _n_gaps;
528  sch_mesh._n_pins = _n_pins;
529  sch_mesh._side_gap = _side_gap;
530 
531  sch_mesh._nodes = _nodes;
532  sch_mesh._pin_nodes = _pin_nodes;
533  sch_mesh._gapnodes = _gapnodes;
535  sch_mesh._gap_to_pin_map = _gap_to_pin_map;
540  sch_mesh._gij_map = _gij_map;
542  sch_mesh._subch_type = _subch_type;
543 
544  sch_mesh._duct_mesh_exist = false;
545  sch_mesh._pin_mesh_exist = (_n_pins > 0);
546 }
547 
548 std::unique_ptr<MeshBase>
550 {
551  auto mesh_base = buildMeshBaseObject();
552  BoundaryInfo & boundary_info = mesh_base->get_boundary_info();
553 
554  mesh_base->set_spatial_dimension(3);
555 
556  buildSubchannelMesh(*mesh_base, boundary_info);
557 
558  if (_n_pins > 0)
559  buildPinMesh(*mesh_base);
560 
561  boundary_info.sideset_name(0) = "inlet";
562  boundary_info.sideset_name(1) = "outlet";
563  boundary_info.nodeset_name(0) = "inlet";
564  boundary_info.nodeset_name(1) = "outlet";
565 
566  mesh_base->prepare_for_use();
567 
568  auto & sch_mesh = static_cast<QuadSubChannelMesh &>(*_mesh);
569  transferMetadata(sch_mesh);
570  sch_mesh.computeAssemblyHydraulicParameters();
571 
572  return mesh_base;
573 }
std::vector< std::vector< unsigned int > > _chan_to_pin_map
stores the fuel pins belonging to each subchannel
std::vector< std::vector< unsigned int > > _chan_to_gap_map
map relating subchannel index to gap index
Real _unheated_length_entry
unheated length of the fuel Pin at the entry of the assembly
std::vector< std::pair< unsigned int, unsigned int > > _gap_to_pin_map
map relating gap index to fuel pin index
std::vector< std::vector< Node * > > _nodes
channel nodes
Real _heated_length
heated length of the fuel Pin
std::vector< Real > _z_grid
axial location of nodes
Real _kij
lateral form loss coefficient
void buildPinMesh(MeshBase &mesh_base)
Build the 1D pin elements for assemblies with pins.
std::vector< std::vector< Real > > _k_grid
axial form loss coefficient per computational cell
void paramError(const std::string &param, Args... args) const
void addParam(const std::string &name, const std::initializer_list< typename T::value_type > &value, const std::string &doc_string)
unsigned int _n_gaps
Number of gaps per layer.
std::vector< std::vector< Node * > > _pin_nodes
pin nodes
unsigned int _n_pins
number of pins
std::vector< EChannelType > _subch_type
Subchannel type.
Real _unheated_length_exit
unheated length of the fuel Pin at the exit of the assembly
std::vector< std::vector< unsigned int > > _pin_to_chan_map
map relating fuel pin index to subchannel index
std::vector< std::vector< unsigned int > > _pin_to_chan_map
stores the map from pins to channels
std::vector< std::vector< Real > > _k_grid
axial form loss coefficient per computational cell
Real _unheated_length_entry
unheated length of the fuel Pin at the entry of the assembly
registerMooseObject("SubChannelApp", SCMQuadAssemblyMeshGenerator)
std::vector< std::vector< unsigned int > > _chan_to_pin_map
map relating subchannel index to fuel pin index
unsigned int _ny
number of subchannels in the y direction
std::vector< std::vector< Real > > _gij_map
gap size
unsigned int _ny
number of subchannels in the y direction
Creates the mesh of subchannels in a quadrilateral lattice.
std::vector< std::vector< Real > > _subchannel_position
x,y coordinates of the subchannel centroids
void addRequiredParam(const std::string &name, const std::string &doc_string)
SCMQuadAssemblyMeshGenerator(const InputParameters &params)
unsigned int _n_pins
Number of pins.
void transferMetadata(QuadSubChannelMesh &sch_mesh)
Move generated mesh metadata into the concrete QuadSubChannelMesh object.
unsigned int _nx
number of subchannels in the x direction
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::pair< unsigned int, unsigned int > > _gap_to_chan_map
map relating gap index to subchannel index
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< unsigned int > _index_blockage
index of subchannels affected by blockage
std::vector< Real > _spacer_k
form loss coefficient of the spacers
std::vector< Real > _spacer_k
form loss coefficient of the spacers
unsigned int _n_channels
total number of subchannels
unsigned int _subchannel_block_id
subchannel block index
std::vector< Real > _spacer_z
axial location of the spacers
Real _unheated_length_exit
unheated length of the fuel Pin at the exit of the assembly
void buildSubchannelMesh(MeshBase &mesh_base, BoundaryInfo &boundary_info)
Build the 1D subchannel elements and inlet/outlet boundaries.
std::vector< Real > _z_blockage
axial location of blockage (inlet, outlet) [m]
Real _pin_diameter
fuel Pin diameter
void initializeChannelData()
Build subchannel, gap, pin, and cross-flow maps used by QuadSubChannelMesh.
std::vector< Real > _k_blockage
form loss coefficient of subchannels affected by blockage
std::vector< Real > _reduction_blockage
area reduction of subchannels affected by blockage
static InputParameters validParams()
std::vector< Real > _z_grid
axial location of nodes
Real _pitch
Distance between the neighbor fuel pins, pitch.
std::vector< Real > _spacer_z
axial location of the spacers
virtual std::unique_ptr< MeshBase > generate() override
std::vector< std::vector< double > > _sign_id_crossflow_map
Matrix used to give local sign to crossflow quantities.
unsigned int _n_channels
number of subchannels in total
std::vector< std::vector< Real > > _sign_id_crossflow_map
matrix used to give local sign to crossflow quantities
unsigned int _n_gaps
number of gaps per layer
std::vector< std::vector< Node * > > _gapnodes
gap nodes
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
std::vector< std::pair< unsigned int, unsigned int > > _gap_to_pin_map
stores the fuel pin pairs for each gap
std::vector< std::vector< Real > > _gij_map
Vector to store gap size.
Mesh generator that builds a mesh of 1D lines representing subchannels and pins in a quadrilateral as...
Real _pitch
distance between neighbor fuel pins, pitch
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
vector of subchannel nodes
std::vector< std::vector< Node * > > _pin_nodes
vector of fuel pin nodes
void mooseError(Args &&... args) const
std::vector< std::vector< Real > > _subchannel_position
x,y coordinates of the subchannel centroids
void addClassDescription(const std::string &doc_string)
registerMooseObjectRenamed("SubChannelApp", SCMQuadSubChannelMeshGenerator, "06/30/2027 24:00", SCMQuadAssemblyMeshGenerator)
std::vector< Real > _reduction_blockage
area reduction of subchannels affected by blockage
static const std::complex< double > j(0, 1)
Complex number "j" (also known as "i")
std::vector< std::vector< Node * > > _gapnodes
vector of gap (interface between pairs of neighboring subchannels) nodes
unsigned int _nx
number of subchannels in the x direction
Real _kij
Lateral form loss coefficient.
unsigned int _n_cells
number of axial cells
std::unique_ptr< MeshBase > buildMeshBaseObject(unsigned int dim=libMesh::invalid_uint)
std::vector< std::pair< unsigned int, unsigned int > > _gap_to_chan_map
stores the channel pairs for each gap
unsigned int _pin_block_id
pin block index
unsigned int _n_cells
number of axial cells
std::vector< Real > _z_blockage
axial location of blockage (inlet, outlet) [m]
void ErrorVector unsigned int
Real _heated_length
heated length of the fuel Pin
std::vector< EChannelType > _subch_type
subchannel type
std::vector< unsigned int > _index_blockage
index of subchannels affected by blockage
uint8_t dof_id_type
std::vector< std::vector< unsigned int > > _chan_to_gap_map
stores the gaps that form each subchannel