15#include "libmesh/edge_edge2.h"
16#include "libmesh/unstructured_mesh.h"
20 SCMTriSubChannelMeshGenerator,
24 TriSubChannelMeshGenerator,
28 SCMTriPinMeshGenerator,
41 "Creates a mesh of 1D subchannels and 1D pins in a triangular lattice arrangement");
42 params.
addRequiredParam<
unsigned int>(
"n_cells",
"The number of cells in the axial direction");
45 params.
addParam<Real>(
"unheated_length_entry", 0.0,
"Unheated length at entry [m]");
47 params.
addParam<Real>(
"unheated_length_exit", 0.0,
"Unheated length at exit [m]");
50 "Number of fuel-pin rings per assembly, counting the center pin as the first ring [-]");
52 "Flat to flat distance for the hexagonal assembly [m]");
56 "spacer_z", {},
"Axial location of spacers/vanes/mixing vanes [m]");
58 "spacer_k", {},
"K-loss coefficient of spacers/vanes/mixing vanes [-]");
59 params.
addParam<Real>(
"Kij", 0.5,
"Lateral form loss coefficient [-]");
60 params.
addParam<std::vector<Real>>(
"z_blockage",
61 std::vector<Real>({0.0, 0.0}),
62 "axial location of blockage (inlet, outlet) [m]");
63 params.
addParam<std::vector<unsigned int>>(
"index_blockage",
64 std::vector<unsigned int>({0}),
65 "index of subchannels affected by blockage");
68 std::vector<Real>({1.0}),
69 "Area reduction of subchannels affected by blockage (number to muliply the area)");
70 params.
addParam<std::vector<Real>>(
"k_blockage",
71 std::vector<Real>({0.0}),
72 "Form loss coefficient of subchannels affected by blockage");
73 params.
addParam<
unsigned int>(
"block_id", 0,
"Subchannel block id");
74 params.
deprecateParam(
"block_id",
"subchannel_block_id",
"07/01/2027");
75 params.
addParam<
unsigned int>(
"pin_block_id", 1,
"Fuel Pin block id");
81 _unheated_length_entry(getParam<Real>(
"unheated_length_entry")),
82 _heated_length(getParam<Real>(
"heated_length")),
83 _unheated_length_exit(getParam<Real>(
"unheated_length_exit")),
84 _subchannel_block_id(getParam<unsigned
int>(
"subchannel_block_id")),
85 _pin_block_id(getParam<unsigned
int>(
"pin_block_id")),
86 _spacer_z(getParam<
std::vector<Real>>(
"spacer_z")),
87 _spacer_k(getParam<
std::vector<Real>>(
"spacer_k")),
88 _z_blockage(getParam<
std::vector<Real>>(
"z_blockage")),
89 _index_blockage(getParam<
std::vector<unsigned
int>>(
"index_blockage")),
90 _reduction_blockage(getParam<
std::vector<Real>>(
"reduction_blockage")),
91 _k_blockage(getParam<
std::vector<Real>>(
"k_blockage")),
92 _pitch(getParam<Real>(
"pitch")),
93 _kij(getParam<Real>(
"Kij")),
94 _pin_diameter(getParam<Real>(
"pin_diameter")),
95 _n_cells(getParam<unsigned
int>(
"n_cells")),
96 _n_rings(getParam<unsigned
int>(
"nrings")),
98 _flat_to_flat(getParam<Real>(
"flat_to_flat")),
99 _dwire(getParam<Real>(
"dwire")),
100 _hwire(getParam<Real>(
"hwire")),
101 _duct_to_pin_gap(0.5 *
102 (_flat_to_flat - (_n_rings - 1) * _pitch *
std::sqrt(3.0) - _pin_diameter)),
110 "'nrings' must be at least 2. In this mesh generator, the center pin counts as "
111 "the first ring, so a 7-pin bundle uses nrings = 2.");
114 paramError(
"n_cells",
"The number of axial cells must be greater than zero");
118 paramError(
"pitch",
"The pin pitch must be greater than the pin diameter");
120 if (MooseUtils::absoluteFuzzyGreaterThan(
_dwire, pin_gap))
121 paramError(
"dwire",
"The wire diameter must not exceed the pin-to-pin gap");
123 if (total_length <= 0.0)
124 mooseError(
"Total bundle length must be greater than zero");
127 mooseError(
"Size of vector spacer_z should be equal to size of vector spacer_k");
130 if (spacer_z < 0.0 || spacer_z > total_length)
131 paramError(
"spacer_z",
"Location of spacers should be between zero and total bundle length");
134 paramError(
"z_blockage",
"Size of vector z_blockage must be 2");
137 paramError(
"z_blockage",
"z_blockage inlet location must not exceed outlet location");
141 "The area reduction of the blocked subchannels cannot be more than 1");
146 mooseError(
"Size of vectors: index_blockage, reduction_blockage, k_blockage, must be equal "
153 Real L = total_length;
156 std::vector<int> spacer_cell;
158 spacer_cell.emplace_back(std::round(elem *
_n_cells / L));
161 std::vector<Real> kgrid;
165 for (
unsigned int index = 0; index < spacer_cell.size(); index++)
166 kgrid[spacer_cell[index]] +=
_spacer_k[index];
183 Real avg_coor_x = 0.0;
185 Real avg_coor_y = 0.0;
191 unsigned int kgap = 0;
193 unsigned int icorner = 0;
195 const Real positive_flow = 1.0;
197 const Real negative_flow = -1.0;
199 std::vector<std::pair<unsigned int, unsigned int>> gap_fill;
206 for (
unsigned int i = 1; i <
_n_rings; i++)
207 for (
unsigned int j = 0; j < i * 6; j++)
211 unsigned int chancount = 0.0;
213 for (
unsigned int j = 0; j <
_n_rings - 1; j++)
220 "The index of the blocked subchannel cannot be more than the max index of the "
225 mooseError(
"Size of vectors: index_blockage, reduction_blockage, k_blockage, cannot be more "
226 "than the total number of subchannels");
235 for (
unsigned int i = 0; i <
_n_cells + 1; i++)
239 unsigned int index(0);
269 for (
unsigned int j = 0; j < 3; j++)
276 for (
unsigned int iz = 0; iz <
_n_cells + 1; iz++)
281 for (
unsigned int i = 0; i <
_npins; i++)
289 for (
unsigned int i = 1; i <
_n_rings; i++)
427 for (
unsigned int loc_rod = 0; loc_rod <
_npins; loc_rod++)
431 bool rod_in_sc =
false;
460 for (
unsigned int j = 0; j <
_n_gaps; j++)
492 for (
unsigned int j = 0; j <
_n_gaps; j++)
542 for (
unsigned int j = 0; j <
_n_gaps; j++)
554 gap_fill[j].first = 1;
559 gap_fill[j].second = 1;
573 gap_fill[j].first = 1;
578 gap_fill[j].second = 1;
643 for (
unsigned int iz = 0; iz <
_n_cells + 1; iz++)
645 for (
unsigned int i_gap = 0; i_gap <
_n_gaps; i_gap++)
662 for (
unsigned int k = 0; k < 3; k++)
664 for (
unsigned int j = 0; j <
_n_gaps; j++)
693 for (
unsigned int k = 0; k < 2; k++)
695 for (
unsigned int j = 0; j <
_n_gaps; j++)
774 a2 = std::sqrt((x1 - x0) * (x1 - x0) + (y1 - y0) * (y1 - y0)) + a1;
786 a2 = std::sqrt((x1 - x0) * (x1 - x0) + (y1 - y0) * (y1 - y0)) + a1;
813 const unsigned int node_sub = mesh_base.n_nodes();
814 const unsigned int elem_sub = mesh_base.n_elem();
819 unsigned int node_id = node_sub;
820 for (
unsigned int i = 0; i <
_npins; i++)
823 for (
unsigned int iz = 0; iz <
_n_cells + 1; iz++)
829 unsigned int elem_id = elem_sub;
830 for (
unsigned int i = 0; i <
_npins; i++)
831 for (
unsigned int iz = 0; iz <
_n_cells; iz++)
833 Elem * elem = mesh_base.add_elem(std::make_unique<Edge2>());
835 elem->set_id(elem_id++);
836 const int indx1 = (
_n_cells + 1) * i + iz + node_sub;
837 const int indx2 = (
_n_cells + 1) * i + (iz + 1) + node_sub;
838 elem->set_node(0, mesh_base.node_ptr(indx1));
839 elem->set_node(1, mesh_base.node_ptr(indx2));
842 mesh_base.set_subdomain_name(
_pin_block_id,
"fuel_pins",
true);
845std::unique_ptr<MeshBase>
850 BoundaryInfo & boundary_info = mesh_base->get_boundary_info();
851 mesh_base->set_spatial_dimension(3);
859 unsigned int node_id = 0;
863 for (
unsigned int iz = 0; iz <
_n_cells + 1; iz++)
865 _nodes[i].push_back(mesh_base->add_point(
872 unsigned int elem_id = 0;
875 for (
unsigned int iz = 0; iz <
_n_cells; iz++)
877 Elem * elem = mesh_base->add_elem(std::make_unique<Edge2>());
879 elem->set_id(elem_id++);
880 const int indx1 = (
_n_cells + 1) * i + iz;
881 const int indx2 = (
_n_cells + 1) * i + (iz + 1);
882 elem->set_node(0, mesh_base->node_ptr(indx1));
883 elem->set_node(1, mesh_base->node_ptr(indx2));
886 boundary_info.add_side(elem, 0, 0);
888 boundary_info.add_side(elem, 1, 1);
891 boundary_info.sideset_name(0) =
"inlet";
892 boundary_info.sideset_name(1) =
"outlet";
893 boundary_info.nodeset_name(0) =
"inlet";
894 boundary_info.nodeset_name(1) =
"outlet";
900 mesh_base->prepare_for_use();
903 auto & sch_mesh = cast_ref<TriSubChannelMesh &>(*
_mesh);
914 sch_mesh._kij =
_kij;
942 sch_mesh._pin_mesh_exist = (
_npins > 0);
943 sch_mesh.computeAssemblyHydraulicParameters();
ExpressionBuilder::EBTerm pow(const ExpressionBuilder::EBTerm &left, T exponent)
registerMooseObject("SubChannelApp", SCMTriAssemblyMeshGenerator)
registerMooseObjectRenamed("SubChannelApp", SCMTriSubChannelMeshGenerator, "06/30/2027 24:00", SCMTriAssemblyMeshGenerator)
void ErrorVector unsigned int
static InputParameters validParams()
std::unique_ptr< MeshBase > buildMeshBaseObject(unsigned int dim=libMesh::invalid_uint)
void paramError(const std::string ¶m, Args... args) const
void mooseError(Args &&... args) const
Mesh generator that builds a mesh of 1D lines representing subchannels and pins in a triangular assem...
const std::vector< Real > _reduction_blockage
area reduction of subchannels affected by blockage
std::vector< std::vector< Real > > _sign_id_crossflow_map
Defines the global cross-flow direction -1 or 1 for each subchannel and for all gaps that are belongi...
std::unique_ptr< MeshBase > generate() override
const Real _pitch
Distance between the neighbor fuel pins, pitch.
std::vector< std::vector< Node * > > _pin_nodes
pin nodes
const unsigned int _n_rings
number of rings of fuel pins
std::vector< std::vector< unsigned int > > _pin_to_chan_map
stores the map from pins to channels
const std::vector< Real > _k_blockage
form loss coefficient of subchannels affected by blockage
SCMTriAssemblyMeshGenerator(const InputParameters ¶meters)
std::vector< std::pair< unsigned int, unsigned int > > _gap_to_pin_map
stores the fuel pin pairs for each gap each gap
std::vector< std::vector< Real > > _subchannel_position
x,y coordinates of the subchannel centroids
const Real _heated_length
heated length of the fuel Pin
std::vector< std::pair< unsigned int, unsigned int > > _gap_pairs_sf
sweeping flow model gap pairs per channel to specify directional edge flow
std::vector< std::vector< Real > > _k_grid
axial form loss coefficient per computational cell
unsigned int _n_gaps
number of gaps
const std::vector< Real > & _spacer_k
form loss coefficient of the spacers
const Real _flat_to_flat
the distance between flat surfaces of the duct facing each other
const unsigned int _pin_block_id
pin block index
void buildPinMesh(MeshBase &mesh_base)
Build the 1D pin elements and append them to the subchannel mesh.
const std::vector< Real > _z_blockage
axial location of blockage (inlet, outlet) [m]
unsigned int _n_channels
number of subchannels
std::vector< std::pair< unsigned int, unsigned int > > _chan_pairs_sf
sweeping flow model channel pairs to specify directional edge flow
const std::vector< Real > & _spacer_z
axial location of the spacers
std::vector< std::vector< Real > > _pins_in_rings
fuel pins that are belonging to each ring
const Real _unheated_length_exit
unheated length of the fuel Pin at the exit of the assembly
std::vector< EChannelType > _subch_type
subchannel type
const unsigned int _subchannel_block_id
subchannel block index
std::vector< std::vector< Node * > > _nodes
nodes
std::vector< std::vector< Real > > _gij_map
gap size
const Real _hwire
wire lead length
std::vector< std::vector< unsigned int > > _chan_to_gap_map
stores the gaps that forms each subchannel
std::vector< Real > _z_grid
axial location of nodes
unsigned int _npins
number of fuel pins
std::vector< EChannelType > _gap_type
gap type
const Real _pin_diameter
fuel Pin diameter
const Real _duct_to_pin_gap
the gap thickness between the duct and peripheral fuel pins
const Real _dwire
wire diameter
const std::vector< unsigned int > _index_blockage
index of subchannels affected by blockage
static InputParameters validParams()
const Real _unheated_length_entry
unheated length of the fuel Pin at the entry of the assembly
const Real & _kij
Lateral form loss coefficient.
std::vector< std::pair< unsigned int, unsigned int > > _gap_to_chan_map
stores the channel pairs for each gap
std::vector< Point > _pin_position
x,y coordinates of the fuel pins
std::vector< std::vector< unsigned int > > _chan_to_pin_map
stores the fuel pins belonging to each subchannel
const unsigned int _n_cells
number of axial cells
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.
static void pinPositions(std::vector< Point > &positions, unsigned int nrings, Real pitch, Point center)
Calculates and stores the pin positions/centers for a hexagonal assembly containing the given number ...