Line data Source code
1 : /********************************************************************/ 2 : /* SOFTWARE COPYRIGHT NOTIFICATION */ 3 : /* Cardinal */ 4 : /* */ 5 : /* (c) 2021 UChicago Argonne, LLC */ 6 : /* ALL RIGHTS RESERVED */ 7 : /* */ 8 : /* Prepared by UChicago Argonne, LLC */ 9 : /* Under Contract No. DE-AC02-06CH11357 */ 10 : /* With the U. S. Department of Energy */ 11 : /* */ 12 : /* Prepared by Battelle Energy Alliance, LLC */ 13 : /* Under Contract No. DE-AC07-05ID14517 */ 14 : /* With the U. S. Department of Energy */ 15 : /* */ 16 : /* See LICENSE for full restrictions */ 17 : /********************************************************************/ 18 : 19 : #include "HexagonalSubchannelGapMesh.h" 20 : #include "libmesh/face_quad4.h" 21 : #include "libmesh/unstructured_mesh.h" 22 : 23 : registerMooseObject("CardinalApp", HexagonalSubchannelGapMesh); 24 : 25 : InputParameters 26 144 : HexagonalSubchannelGapMesh::validParams() 27 : { 28 144 : InputParameters params = HexagonalSubchannelMeshBase::validParams(); 29 288 : params.addRequiredRangeCheckedParam<unsigned int>( 30 : "n_axial", "n_axial > 0", "Number of axial cells"); 31 288 : params.addRequiredRangeCheckedParam<Real>("height", "height > 0", "Height of assembly"); 32 : 33 288 : params.addParam<SubdomainID>("interior_id", 1, "Sideset ID to set for the interior channel gaps"); 34 288 : params.addParam<SubdomainID>( 35 288 : "peripheral_id", 2, "Block ID to set for the peripheral channel gaps"); 36 : 37 144 : params.addClassDescription("Mesh respecting subchannel gaps for a triangular lattice"); 38 144 : return params; 39 0 : } 40 : 41 72 : HexagonalSubchannelGapMesh::HexagonalSubchannelGapMesh(const InputParameters & parameters) 42 : : HexagonalSubchannelMeshBase(parameters), 43 72 : _n_axial(getParam<unsigned int>("n_axial")), 44 144 : _height(getParam<Real>("height")), 45 144 : _interior_id(getParam<SubdomainID>("interior_id")), 46 144 : _peripheral_id(getParam<SubdomainID>("peripheral_id")), 47 72 : _gap_indices(_hex_lattice.gapIndices()) 48 : { 49 72 : } 50 : 51 : std::unique_ptr<MooseMesh> 52 0 : HexagonalSubchannelGapMesh::safeClone() const 53 : { 54 0 : return _app.getFactory().copyConstruct(*this); 55 : } 56 : 57 : void 58 72 : HexagonalSubchannelGapMesh::buildMesh() 59 : { 60 72 : MeshBase & mesh = getMesh(); 61 72 : mesh.clear(); 62 72 : mesh.set_mesh_dimension(2); 63 72 : mesh.set_spatial_dimension(3); 64 : 65 72 : _elem_id_counter = 0; 66 72 : _node_id_counter = 0; 67 : 68 72 : const Real r = _hex_lattice.pinRadius(); 69 72 : Real dz = _height / _n_axial; 70 : 71 428 : for (unsigned int i = 0; i < _n_axial; ++i) 72 : { 73 356 : Real zmin = i * dz; 74 356 : Real zmax = (i + 1) * dz; 75 : 76 8156 : for (unsigned int i = 0; i < _hex_lattice.nInteriorGaps(); ++i) 77 : { 78 7800 : const auto & pins = _gap_indices[i]; 79 : 80 : // to ensure accurate areas (in case anyone wants that), we need to adjust the points 81 : // to not overlap with the pincells that would be here 82 7800 : const auto & center1 = _pin_centers[pins.first]; 83 7800 : const auto & center2 = _pin_centers[pins.second]; 84 7800 : const Point pt1 = center1 + r * (center2 - center1).unit(); 85 7800 : const Point pt2 = center2 + r * (center1 - center2).unit(); 86 : 87 7800 : addQuadElem(pt1, pt2, zmin, zmax, _interior_id); 88 : } 89 : 90 356 : Real d = _hex_lattice.pinBundleSpacing() + _hex_lattice.pinRadius(); 91 : 92 5204 : for (unsigned int i = _hex_lattice.nInteriorGaps(); i < _gap_indices.size(); ++i) 93 : { 94 : const auto & pins = _gap_indices[i]; 95 4848 : int side = std::abs(pins.second) - 1; 96 : 97 4848 : const auto & center1 = _pin_centers[pins.first]; 98 4848 : const Point pt2 = center1 + Point(d * _hex_lattice.sideTranslationX(side), 99 4848 : d * _hex_lattice.sideTranslationY(side), 100 : 0.0); 101 4848 : const Point pt1 = center1 + r * (pt2 - center1).unit(); 102 : 103 4848 : addQuadElem(pt1, pt2, zmin, zmax, _peripheral_id); 104 : } 105 : } 106 : 107 72 : mesh.prepare_for_use(); 108 72 : } 109 : 110 : void 111 12648 : HexagonalSubchannelGapMesh::addQuadElem(const Point & pt1, 112 : const Point & pt2, 113 : const Real & zmin, 114 : const Real & zmax, 115 : const unsigned int & id) 116 : { 117 12648 : auto elem = new Quad4; 118 12648 : elem->set_id(_elem_id_counter++); 119 12648 : _mesh->add_elem(elem); 120 : 121 12648 : Point z0(0.0, 0.0, zmin); 122 12648 : Point z1(0.0, 0.0, zmax); 123 : 124 12648 : auto node_ptr0 = _mesh->add_point(pt1 + z0, _node_id_counter++); 125 12648 : auto node_ptr1 = _mesh->add_point(pt2 + z0, _node_id_counter++); 126 12648 : auto node_ptr2 = _mesh->add_point(pt2 + z1, _node_id_counter++); 127 12648 : auto node_ptr3 = _mesh->add_point(pt1 + z1, _node_id_counter++); 128 : 129 12648 : elem->set_node(0) = node_ptr0; 130 12648 : elem->set_node(1) = node_ptr1; 131 12648 : elem->set_node(2) = node_ptr2; 132 12648 : elem->set_node(3) = node_ptr3; 133 : 134 12648 : elem->subdomain_id() = id; 135 12648 : }