Line data Source code
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 "SCMQuadPinMeshGenerator.h" 11 : #include "QuadSubChannelMesh.h" 12 : #include "libmesh/edge_edge2.h" 13 : 14 : registerMooseObject("SubChannelApp", SCMQuadPinMeshGenerator); 15 : registerMooseObjectRenamed("SubChannelApp", 16 : QuadPinMeshGenerator, 17 : "06/30/2025 24:00", 18 : SCMQuadPinMeshGenerator); 19 : 20 : InputParameters 21 188 : SCMQuadPinMeshGenerator::validParams() 22 : { 23 188 : InputParameters params = MeshGenerator::validParams(); 24 188 : params.addClassDescription("Creates a mesh of 1D fuel pins in a square lattice arrangement"); 25 376 : params.addRequiredParam<MeshGeneratorName>("input", "The corresponding subchannel mesh"); 26 376 : params.addParam<Real>("unheated_length_entry", 0.0, "Unheated length at entry [m]"); 27 376 : params.addRequiredParam<Real>("heated_length", "Heated length [m]"); 28 376 : params.addParam<Real>("unheated_length_exit", 0.0, "Unheated length at exit [m]"); 29 376 : params.addRequiredParam<Real>("pitch", "Pitch [m]"); 30 376 : params.addRequiredParam<unsigned int>("nx", "Number of subchannels in the x direction [-]"); 31 376 : params.addRequiredParam<unsigned int>("ny", "Number of subchannels in the y direction [-]"); 32 376 : params.addRequiredParam<unsigned int>("n_cells", "The number of cells in the axial direction"); 33 376 : params.addParam<unsigned int>("block_id", 1, "Domain Index"); 34 188 : return params; 35 0 : } 36 : 37 94 : SCMQuadPinMeshGenerator::SCMQuadPinMeshGenerator(const InputParameters & params) 38 : : MeshGenerator(params), 39 94 : _input(getMesh("input")), 40 188 : _unheated_length_entry(getParam<Real>("unheated_length_entry")), 41 188 : _heated_length(getParam<Real>("heated_length")), 42 188 : _unheated_length_exit(getParam<Real>("unheated_length_exit")), 43 188 : _pitch(getParam<Real>("pitch")), 44 188 : _nx(getParam<unsigned int>("nx")), 45 188 : _ny(getParam<unsigned int>("ny")), 46 188 : _n_cells(getParam<unsigned int>("n_cells")), 47 282 : _block_id(getParam<unsigned int>("block_id")) 48 : { 49 94 : Real dz = (_unheated_length_entry + _heated_length + _unheated_length_exit) / _n_cells; 50 1500 : for (unsigned int i = 0; i < _n_cells + 1; i++) 51 1406 : _z_grid.push_back(dz * i); 52 94 : } 53 : 54 : std::unique_ptr<MeshBase> 55 94 : SCMQuadPinMeshGenerator::generate() 56 : { 57 94 : std::unique_ptr<MeshBase> mesh_base = std::move(_input); 58 94 : if (!mesh_base) 59 0 : mesh_base = buildMeshBaseObject(); 60 94 : mesh_base->set_mesh_dimension(3); 61 94 : mesh_base->reserve_elem(_n_cells * (_ny - 1) * (_nx - 1)); 62 94 : mesh_base->reserve_nodes((_n_cells + 1) * (_ny - 1) * (_nx - 1)); 63 94 : _pin_nodes.resize((_nx - 1) * (_ny - 1)); 64 : // number of nodes in subchannel mesh 65 94 : unsigned int node_sub = (_n_cells + 1) * _ny * _nx; 66 : // number of elements in subchannel mesh 67 94 : unsigned int elem_sub = _n_cells * _ny * _nx; 68 : 69 : // Add the points in the shape of a rectilinear grid. The grid is regular 70 : // on the xy-plane with a spacing of `pitch` between points. The grid along 71 : // z is also regular. Store pointers in the _nodes 72 : // array so we can keep track of which points are in which pins. 73 94 : Real offset_x = (_nx - 2) * _pitch / 2.0; 74 94 : Real offset_y = (_ny - 2) * _pitch / 2.0; 75 : unsigned int node_id = node_sub; 76 449 : for (unsigned int iy = 0; iy < _ny - 1; iy++) 77 : { 78 1964 : for (unsigned int ix = 0; ix < _nx - 1; ix++) 79 : { 80 1609 : int i_node = (_nx - 1) * iy + ix; 81 1609 : _pin_nodes[i_node].reserve(_n_cells); 82 25770 : for (unsigned int iz = 0; iz < _n_cells + 1; iz++) 83 : { 84 24161 : _pin_nodes[i_node].push_back(mesh_base->add_point( 85 48322 : Point(_pitch * ix - offset_x, _pitch * iy - offset_y, _z_grid[iz]), node_id++)); 86 : } 87 : } 88 : } 89 : 90 : // Add the elements which in this case are 2-node edges that link each 91 : // subchannel's nodes vertically. 92 : unsigned int elem_id = elem_sub; 93 449 : for (unsigned int iy = 0; iy < _ny - 1; iy++) 94 : { 95 1964 : for (unsigned int ix = 0; ix < _nx - 1; ix++) 96 : { 97 24161 : for (unsigned int iz = 0; iz < _n_cells; iz++) 98 : { 99 22552 : Elem * elem = new Edge2; 100 22552 : elem->subdomain_id() = _block_id; 101 22552 : elem->set_id(elem_id++); 102 22552 : elem = mesh_base->add_elem(elem); 103 22552 : const int indx1 = ((_n_cells + 1) * (_nx - 1)) * iy + (_n_cells + 1) * ix + iz + node_sub; 104 22552 : const int indx2 = 105 22552 : ((_n_cells + 1) * (_nx - 1)) * iy + (_n_cells + 1) * ix + (iz + 1) + node_sub; 106 22552 : elem->set_node(0, mesh_base->node_ptr(indx1)); 107 22552 : elem->set_node(1, mesh_base->node_ptr(indx2)); 108 : } 109 : } 110 : } 111 94 : mesh_base->subdomain_name(_block_id) = name(); 112 94 : mesh_base->prepare_for_use(); 113 : 114 : // move the meta data into QuadSubChannelMesh 115 94 : auto & sch_mesh = static_cast<QuadSubChannelMesh &>(*_mesh); 116 94 : sch_mesh._pin_nodes = _pin_nodes; 117 94 : sch_mesh._pin_mesh_exist = true; 118 : 119 94 : return mesh_base; 120 0 : }