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