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 "SCMTriPinMeshGenerator.h" 11 : #include "TriSubChannelMesh.h" 12 : #include "libmesh/edge_edge2.h" 13 : #include <numeric> 14 : 15 : registerMooseObject("SubChannelApp", SCMTriPinMeshGenerator); 16 : registerMooseObjectRenamed("SubChannelApp", 17 : TriPinMeshGenerator, 18 : "06/30/2025 24:00", 19 : SCMTriPinMeshGenerator); 20 : 21 : InputParameters 22 76 : SCMTriPinMeshGenerator::validParams() 23 : { 24 76 : InputParameters params = MeshGenerator::validParams(); 25 152 : params.addRequiredParam<MeshGeneratorName>("input", "The corresponding subchannel mesh"); 26 76 : params.addClassDescription("Creates a mesh of 1D fuel pins in a triangular lattice arrangement"); 27 152 : params.addParam<Real>("unheated_length_entry", 0.0, "Unheated length at entry [m]"); 28 152 : params.addRequiredParam<Real>("heated_length", "Heated length [m]"); 29 152 : params.addParam<Real>("unheated_length_exit", 0.0, "Unheated length at exit [m]"); 30 152 : params.addRequiredParam<Real>("pitch", "Pitch [m]"); 31 152 : params.addRequiredParam<unsigned int>("nrings", "Number of fuel Pin rings per assembly [-]"); 32 152 : params.addRequiredParam<unsigned int>("n_cells", "The number of cells in the axial direction"); 33 152 : params.addParam<unsigned int>("block_id", 1, "Domain Index"); 34 76 : return params; 35 0 : } 36 : 37 38 : SCMTriPinMeshGenerator::SCMTriPinMeshGenerator(const InputParameters & params) 38 : : MeshGenerator(params), 39 38 : _input(getMesh("input")), 40 76 : _unheated_length_entry(getParam<Real>("unheated_length_entry")), 41 76 : _heated_length(getParam<Real>("heated_length")), 42 76 : _unheated_length_exit(getParam<Real>("unheated_length_exit")), 43 76 : _pitch(getParam<Real>("pitch")), 44 76 : _n_rings(getParam<unsigned int>("nrings")), 45 76 : _n_cells(getParam<unsigned int>("n_cells")), 46 114 : _block_id(getParam<unsigned int>("block_id")) 47 : { 48 38 : Real dz = (_unheated_length_entry + _heated_length + _unheated_length_exit) / _n_cells; 49 1052 : for (unsigned int i = 0; i < _n_cells + 1; i++) 50 1014 : _z_grid.push_back(dz * i); 51 38 : } 52 : 53 : std::unique_ptr<MeshBase> 54 38 : SCMTriPinMeshGenerator::generate() 55 : { 56 : 57 : // Setting up base elements in the mesh 58 38 : std::unique_ptr<MeshBase> mesh_base = std::move(_input); 59 38 : if (!mesh_base) 60 0 : mesh_base = buildMeshBaseObject(); 61 : 62 38 : mesh_base->set_mesh_dimension(3); 63 : 64 : // Defining the Pin positions 65 38 : TriSubChannelMesh::rodPositions(_pin_position, _n_rings, _pitch, Point(0, 0)); 66 : auto _nrods = _pin_position.size(); 67 : 68 : // Reserving memory in the mesh 69 38 : mesh_base->reserve_elem(_n_cells * _nrods); 70 38 : mesh_base->reserve_nodes((_n_cells + 1) * _nrods); 71 38 : _pin_nodes.resize(_nrods); 72 : 73 : // Defining the extent of the subchanel mesh to append pins mesh 74 : // to the current subchannel mesh 75 : unsigned int chancount = 0; 76 174 : for (unsigned int j = 0; j < _n_rings - 1; j++) 77 136 : chancount += j * 6; 78 38 : unsigned int _n_channels = chancount + _nrods - 1 + (_n_rings - 1) * 6 + 6; 79 38 : unsigned int node_sub = (_n_cells + 1) * _n_channels; 80 38 : unsigned int elem_sub = _n_cells * _n_channels; 81 : 82 : // Add the points in the shape of a rectilinear grid. The grid is regular 83 : // on the xy-plane with a spacing of `pitch` between points. The grid along 84 : // z is also regular. Store pointers in the _nodes 85 : // array so we can keep track of which points are in which pins. 86 : unsigned int node_id = node_sub; 87 2290 : for (unsigned int i = 0; i < _nrods; i++) 88 : { 89 2252 : _pin_nodes[i].reserve(_n_cells); 90 48428 : for (unsigned int iz = 0; iz < _n_cells + 1; iz++) 91 : { 92 46176 : _pin_nodes[i].push_back(mesh_base->add_point( 93 92352 : Point(_pin_position[i](0), _pin_position[i](1), _z_grid[iz]), node_id++)); 94 : } 95 : } 96 : 97 : // Add the elements which in this case are 2-node edges that link each 98 : // pin nodes vertically. 99 : unsigned int elem_id = elem_sub; 100 2290 : for (unsigned int i = 0; i < _nrods; i++) 101 : { 102 46176 : for (unsigned int iz = 0; iz < _n_cells; iz++) 103 : { 104 43924 : Elem * elem = new Edge2; 105 43924 : elem->subdomain_id() = _block_id; 106 43924 : elem->set_id(elem_id++); 107 43924 : elem = mesh_base->add_elem(elem); 108 43924 : const int indx1 = (_n_cells + 1) * i + iz + node_sub; 109 43924 : const int indx2 = (_n_cells + 1) * i + (iz + 1) + node_sub; 110 43924 : elem->set_node(0, mesh_base->node_ptr(indx1)); 111 43924 : elem->set_node(1, mesh_base->node_ptr(indx2)); 112 : } 113 : } 114 38 : mesh_base->subdomain_name(_block_id) = name(); 115 38 : mesh_base->prepare_for_use(); 116 : 117 : // move the meta data into TriSubChannelMesh 118 38 : auto & sch_mesh = static_cast<TriSubChannelMesh &>(*_mesh); 119 38 : sch_mesh._pin_nodes = _pin_nodes; 120 38 : sch_mesh._pin_mesh_exist = true; 121 : 122 38 : return mesh_base; 123 0 : }