https://mooseframework.inl.gov
QuadSubChannelMesh.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 "QuadSubChannelMesh.h"
11 #include <cmath>
12 #include <limits>
13 #include "libmesh/edge_edge2.h"
14 #include "libmesh/unstructured_mesh.h"
15 
16 registerMooseObject("SubChannelApp", QuadSubChannelMesh);
17 
20 {
22  params.addClassDescription("Creates an subchannel mesh container for a square "
23  "lattice arrangement");
24  return params;
25 }
26 
28 
30  : SubChannelMesh(other_mesh),
31  _nx(other_mesh._nx),
32  _ny(other_mesh._ny),
33  _n_channels(other_mesh._n_channels),
34  _n_gaps(other_mesh._n_gaps),
35  _n_pins(other_mesh._n_pins),
36  _side_gap(other_mesh._side_gap),
37  _nodes(other_mesh._nodes),
38  _pin_nodes(other_mesh._pin_nodes),
39  _gapnodes(other_mesh._gapnodes),
40  _gap_to_chan_map(other_mesh._gap_to_chan_map),
41  _gap_to_pin_map(other_mesh._gap_to_pin_map),
42  _chan_to_gap_map(other_mesh._chan_to_gap_map),
43  _chan_to_pin_map(other_mesh._chan_to_pin_map),
44  _pin_to_chan_map(other_mesh._pin_to_chan_map),
45  _sign_id_crossflow_map(other_mesh._sign_id_crossflow_map),
46  _gij_map(other_mesh._gij_map),
47  _subch_type(other_mesh._subch_type)
48 {
49  if (_nx < 2 && _ny < 2)
50  mooseError(name(),
51  ": The number of subchannels cannot be less than 2 in both directions (x and y). "
52  "Smallest assembly allowed is either 2X1 or 1X2. ");
53 }
54 
55 std::unique_ptr<MooseMesh>
57 {
58  return _app.getFactory().copyConstruct(*this);
59 }
60 
61 void
63 {
64 }
65 
66 void
68 {
69  _assembly_flow_area = 0.0;
72 
73  const Real z = _z_grid.empty() ? 0.0 : _z_grid.front();
74 
75  for (unsigned int i_ch = 0; i_ch < _n_channels; i_ch++)
76  {
79  }
80 
81  if (_assembly_wetted_perimeter == 0.0)
82  mooseError(name(), ": Assembly wetted perimeter is zero; cannot compute hydraulic diameter.");
83 
85 }
86 
87 Real
88 QuadSubChannelMesh::getSubchannelFlowArea(unsigned int i_chan, Real z) const
89 {
90  Real standard_area = 0.0;
91  Real rod_area = 0.0;
92  Real additional_area = 0.0;
93 
94  const auto subch_type = getSubchannelType(i_chan);
95  if (subch_type == EChannelType::CORNER)
96  {
97  standard_area = 0.25 * _pitch * _pitch;
98  rod_area = 0.25 * 0.25 * libMesh::pi * _pin_diameter * _pin_diameter;
99  additional_area = _pitch * _side_gap + _side_gap * _side_gap;
100  }
101  else if (subch_type == EChannelType::EDGE)
102  {
103  standard_area = 0.5 * _pitch * _pitch;
104  rod_area = 0.5 * 0.25 * libMesh::pi * _pin_diameter * _pin_diameter;
105  additional_area = _pitch * _side_gap;
106  }
107  else
108  {
109  standard_area = _pitch * _pitch;
110  rod_area = 0.25 * libMesh::pi * _pin_diameter * _pin_diameter;
111  }
112 
113  Real flow_area = standard_area + additional_area - rod_area;
114 
115  unsigned int blockage_index = 0;
116  for (const auto & i_blockage : _index_blockage)
117  {
118  if (i_chan == i_blockage && z >= _z_blockage.front() && z <= _z_blockage.back())
119  flow_area *= _reduction_blockage[blockage_index];
120  blockage_index++;
121  }
122 
123  return flow_area;
124 }
125 
126 Real
128 {
129  const Real rod_circumference = libMesh::pi * _pin_diameter;
130  const auto subch_type = getSubchannelType(i_chan);
131 
132  if (subch_type == EChannelType::CORNER)
133  return 0.25 * rod_circumference + _pitch + 2.0 * _side_gap;
134  else if (subch_type == EChannelType::EDGE)
135  return 0.5 * rod_circumference + _pitch;
136  else
137  return rod_circumference;
138 }
139 
140 unsigned int
142 {
143  Real offset_x = (_nx - 1) * _pitch / 2.0;
144  Real offset_y = (_ny - 1) * _pitch / 2.0;
145  unsigned int i = (p(0) + offset_x + 0.5 * _pitch) / _pitch;
146  unsigned int j = (p(1) + offset_y + 0.5 * _pitch) / _pitch;
147  return j * _nx + i;
148 }
149 
150 unsigned int
151 QuadSubChannelMesh::channelIndex(const Point & pt) const
152 {
153  // this is identical to getSubchannelIndexFromPoint, but when it is given a point "outside" the
154  // normal subchannel geometry (i.e. a point that lies in a gap around the lattice) we still report
155  // a valid subchannel index this is needed for transferring the solution onto a visualization mesh
156 
157  Real offset_x = (_nx - 1) * _pitch / 2.0;
158  Real offset_y = (_ny - 1) * _pitch / 2.0;
159  int i = (pt(0) + offset_x + 0.5 * _pitch) / _pitch;
160  int j = (pt(1) + offset_y + 0.5 * _pitch) / _pitch;
161 
162  i = std::max(0, i);
163  i = std::min(i, (int)(_nx - 1));
164 
165  j = std::max(0, j);
166  j = std::min(j, (int)(_ny - 1));
167 
168  return j * _nx + i;
169 }
170 
171 unsigned int
173 {
174  if (_n_pins == 0)
175  mooseError(name(), ": Cannot compute a pin index because this mesh has no pins.");
176 
177  Real offset_x = (_nx - 2) * _pitch / 2.0;
178  Real offset_y = (_ny - 2) * _pitch / 2.0;
179  unsigned int i = (p(0) + offset_x) / _pitch;
180  unsigned int j = (p(1) + offset_y) / _pitch;
181  return j * (_nx - 1) + i;
182 }
183 
184 unsigned int
185 QuadSubChannelMesh::pinIndex(const Point & p) const
186 {
187  if (_n_pins == 0)
188  mooseError(name(), ": Cannot compute a pin index because this mesh has no pins.");
189 
190  Real offset_x = (_nx - 2) * _pitch / 2.0;
191  Real offset_y = (_ny - 2) * _pitch / 2.0;
192  unsigned int i = (p(0) + offset_x) / _pitch;
193  unsigned int j = (p(1) + offset_y) / _pitch;
194  return j * (_nx - 1) + i;
195 }
196 
197 void
199  unsigned int nx, unsigned int ny, Real pitch, Real elev, std::vector<Point> & pin_centers)
200 {
201  mooseAssert(nx >= 2, "Number of channels in x-direction must be 2 or more.");
202  mooseAssert(ny >= 2, "Number of channels in y-direction must be 2 or more.");
203 
204  Real offset_x = (nx - 2) * pitch / 2.0;
205  Real offset_y = (ny - 2) * pitch / 2.0;
206  for (unsigned int iy = 0; iy < ny - 1; iy++)
207  for (unsigned int ix = 0; ix < nx - 1; ix++)
208  pin_centers.push_back(Point(pitch * ix - offset_x, pitch * iy - offset_y, elev));
209 }
static InputParameters validParams()
registerMooseObject("SubChannelApp", QuadSubChannelMesh)
EChannelType getSubchannelType(unsigned int index) const override
Return the type of the subchannel for given subchannel index.
Real getSubchannelFlowArea(unsigned int i_chan, Real z) const override
Return undeformed flow area for a subchannel at an axial location, including any blockage reduction...
std::vector< Real > _z_grid
axial location of nodes
unsigned int pinIndex(const Point &p) const override
std::unique_ptr< MooseMesh > safeClone() const override
unsigned int _ny
number of subchannels in the y direction
Creates the mesh of subchannels in a quadrilateral lattice.
unsigned int channelIndex(const Point &point) const override
std::unique_ptr< T > copyConstruct(const T &object)
Factory & getFactory()
unsigned int _n_pins
Number of pins.
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...
const std::string & name() const
void buildMesh() override
unsigned int getSubchannelIndexFromPoint(const Point &p) const override
Return a subchannel index for a given physical point p
static const std::string pitch
void computeAssemblyHydraulicParameters()
Compute undeformed bundle-average inlet hydraulic quantities from generated mesh geometry.
Real _assembly_wetted_perimeter
Undeformed bundle inlet wetted perimeter.
std::vector< Real > _z_blockage
axial location of blockage (inlet, outlet) [m]
Real _pin_diameter
fuel Pin diameter
std::vector< Real > _reduction_blockage
area reduction of subchannels affected by blockage
Real _pitch
Distance between the neighbor fuel pins, pitch.
Real _assembly_flow_area
Undeformed bundle inlet flow area.
static void generatePinCenters(unsigned int nx, unsigned int ny, Real pitch, Real elev, std::vector< Point > &pin_centers)
Generate pin centers.
unsigned int _n_channels
number of subchannels in total
static InputParameters validParams()
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
MooseApp & _app
QuadSubChannelMesh(const InputParameters &parameters)
const Real p
void mooseError(Args &&... args) const
void addClassDescription(const std::string &doc_string)
unsigned int getPinIndexFromPoint(const Point &p) const override
Return a pin index for a given physical point p
static const std::complex< double > j(0, 1)
Complex number "j" (also known as "i")
Base class for subchannel meshes.
unsigned int _nx
number of subchannels in the x direction
Real getSubchannelWettedPerimeter(unsigned int i_chan) const override
Return undeformed wetted perimeter for a subchannel.
Real _assembly_hydraulic_diameter
Undeformed bundle-average hydraulic diameter.
std::vector< unsigned int > _index_blockage
index of subchannels affected by blockage
const Real pi