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