13 #include "libmesh/unstructured_mesh.h" 14 #include "libmesh/face_quad4.h" 22 params.
addClassDescription(
"Creates a mesh of 2D duct cells around a square-lattice subassembly");
23 params.
addRequiredParam<MeshGeneratorName>(
"input",
"The corresponding subchannel mesh");
24 params.
addParam<
unsigned int>(
"block_id", 2,
"Subdomain id for the duct mesh cells");
25 params.
addRequiredParam<
unsigned int>(
"n_cells",
"The number of cells in the axial direction");
26 params.
addParam<
Real>(
"unheated_length_entry", 0.0,
"Unheated length at entry [m]");
28 params.
addParam<
Real>(
"unheated_length_exit", 0.0,
"Unheated length at exit [m]");
33 "Number of channels in the x direction for the subchannel assembly. Must be more than 1 to " 38 "Number of channels in the y direction for the subchannel assembly. Must be more than 1 to " 41 "Gap between duct wall and outer pin lattice: distance(edge pin " 42 "center, duct wall) = pitch/2 + side_gap [m]");
49 _n_cells(getParam<unsigned
int>(
"n_cells")),
50 _unheated_length_entry(getParam<
Real>(
"unheated_length_entry")),
51 _heated_length(getParam<
Real>(
"heated_length")),
52 _unheated_length_exit(getParam<
Real>(
"unheated_length_exit")),
53 _block_id(getParam<unsigned
int>(
"block_id")),
54 _pitch(getParam<
Real>(
"pitch")),
55 _nx(getParam<unsigned
int>(
"nx")),
56 _ny(getParam<unsigned
int>(
"ny")),
57 _side_gap(getParam<
Real>(
"side_gap"))
63 std::unique_ptr<MeshBase>
66 std::unique_ptr<MeshBase> mesh_base = std::move(
_input);
67 mesh_base->set_mesh_dimension(3);
69 std::vector<Point> cross_sec;
71 std::vector<Point> points;
73 std::vector<std::vector<size_t>> elem_point_indices;
75 std::vector<Node *> duct_nodes;
79 mesh_base->prepare_for_use();
91 unsigned int point)
const 93 return layer * points_per_layer + point;
100 const Point &
center)
const 103 corners[0] =
center + Point(-half_x, -half_y, 0);
104 corners[1] =
center + Point(half_x, -half_y, 0);
105 corners[2] =
center + Point(half_x, half_y, 0);
106 corners[3] =
center + Point(-half_x, half_y, 0);
118 const Real half_x = 0.5 * (nx - 1) *
pitch + side_gap;
119 const Real half_y = 0.5 * (ny - 1) *
pitch + side_gap;
126 for (
unsigned int i = 0; i < nx; ++i)
131 else if (i == nx - 1)
136 cross_sec.emplace_back(
x, -half_y, 0.0);
140 for (
unsigned int j = 1;
j + 1 < ny; ++
j)
143 cross_sec.emplace_back(half_x,
y, 0.0);
147 for (
unsigned int i = 0; i < nx; ++i)
149 const unsigned int ii = nx - 1 - i;
154 else if (ii == nx - 1)
159 cross_sec.emplace_back(
x, half_y, 0.0);
163 for (
unsigned int j = 1;
j + 1 < ny; ++
j)
165 const unsigned int jj = ny - 1 -
j;
167 cross_sec.emplace_back(-half_x,
y, 0.0);
175 const std::vector<Point> & cross_sec,
176 const std::vector<Real> & z_layers)
const 178 points.resize(cross_sec.size() * z_layers.size());
179 for (
size_t i = 0; i < z_layers.size(); i++)
180 for (
size_t j = 0;
j < cross_sec.size();
j++)
182 Point(cross_sec[
j](0), cross_sec[
j](1), z_layers[i]);
187 unsigned int n_layers,
188 unsigned int points_per_layer)
const 190 elem_point_indices.clear();
191 for (
unsigned int i = 0; i < n_layers - 1; i++)
193 const unsigned int bottom = i;
194 const unsigned int top = i + 1;
195 for (
unsigned int j = 0;
j < points_per_layer;
j++)
197 const unsigned int left =
j;
198 const unsigned int right = (
j + 1) % points_per_layer;
199 elem_point_indices.push_back({
ductPointIndex(points_per_layer, bottom, left),
209 std::vector<Node *> & duct_nodes,
210 const std::vector<Point> & points,
211 const std::vector<std::vector<size_t>> & elem_point_indices,
216 duct_nodes.reserve(points.size());
217 for (
const auto &
p : points)
218 duct_nodes.push_back(
mesh->add_point(
p));
221 for (
const auto & elem_indices : elem_point_indices)
223 mooseAssert(elem_indices.size() == 4,
224 "Expected 4 node indices per element when building QUAD4 elements.");
226 auto elem = Elem::build(ElemType::QUAD4);
227 elem->subdomain_id() = block;
230 for (
unsigned int i = 0; i < 4; ++i)
232 const auto idx = elem_indices[i];
233 mooseAssert(
idx < duct_nodes.size(),
"Element node index out of range.");
234 elem->set_node(i, duct_nodes[
idx]);
238 mesh->add_elem(elem.release());
Mesh generator for a square/rectangular duct around a square-lattice subassembly. ...
std::unique_ptr< MeshBase > generate() override
registerMooseObject("SubChannelApp", SCMQuadDuctMeshGenerator)
T & getMesh(MooseMesh &mesh)
function to cast mesh
std::vector< Real > _z_grid
axial location of nodes
const unsigned int _n_cells
number of axial cells
std::unique_ptr< MeshBase > & _input
Mesh that comes from another generator.
const std::vector< double > y
Creates the mesh of subchannels in a quadrilateral lattice.
const Real _unheated_length_entry
static InputParameters validParams()
size_t ductPointIndex(unsigned int points_per_layer, unsigned int layer, unsigned int point) const
Maps a duct cross-section point and axial layer to a linear point index.
void ductPoints(std::vector< Point > &points, const std::vector< Point > &cross_sec, const std::vector< Real > &z_layers) const
Computes all 3D point locations used to construct the duct mesh.
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.
SCMQuadDuctMeshGenerator(const InputParameters ¶meters)
const std::string & name() const
void ductCorners(std::vector< Point > &corners, Real half_x, Real half_y, const Point ¢er) const
Computes the x-y corner coordinates of a rectangular duct cross-section.
const std::vector< double > x
static const std::string pitch
static InputParameters validParams()
const Real _unheated_length_exit
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
void setChannelToDuctMaps(const std::vector< Node *> &duct_nodes)
Function that sets the channel-to-duct maps.
void buildDuct(std::unique_ptr< MeshBase > &mesh, std::vector< Node *> &duct_nodes, const std::vector< Point > &points, const std::vector< std::vector< size_t >> &elem_point_indices, SubdomainID block) const
Builds duct mesh nodes and elements and inserts them into the mesh.
const Real _heated_length
static const std::complex< double > j(0, 1)
Complex number "j" (also known as "i")
const Real _pitch
lattice geometry
void ductCrossSec(std::vector< Point > &cross_sec, unsigned int nx, unsigned int ny, Real pitch, Real side_gap) const
Generates the points along the rectangular duct cross-section boundary.
void ErrorVector unsigned int
const unsigned int _block_id
block index
void ductElems(std::vector< std::vector< size_t >> &elem_point_indices, unsigned int n_layers, unsigned int points_per_layer) const
Determines element connectivity for the duct mesh.
static const std::string center