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 128 : HexagonalSubchannelGapMesh::validParams() 27 : { 28 128 : InputParameters params = HexagonalSubchannelMeshBase::validParams(); 29 256 : params.addRequiredRangeCheckedParam<unsigned int>( 30 : "n_axial", "n_axial > 0", "Number of axial cells"); 31 256 : params.addRequiredRangeCheckedParam<Real>("height", "height > 0", "Height of assembly"); 32 : 33 256 : params.addParam<SubdomainID>("interior_id", 1, "Sideset ID to set for the interior channel gaps"); 34 256 : params.addParam<SubdomainID>( 35 256 : "peripheral_id", 2, "Block ID to set for the peripheral channel gaps"); 36 : 37 128 : params.addClassDescription("Mesh respecting subchannel gaps for a triangular lattice"); 38 128 : return params; 39 0 : } 40 : 41 64 : HexagonalSubchannelGapMesh::HexagonalSubchannelGapMesh(const InputParameters & parameters) 42 : : HexagonalSubchannelMeshBase(parameters), 43 64 : _n_axial(getParam<unsigned int>("n_axial")), 44 128 : _height(getParam<Real>("height")), 45 128 : _interior_id(getParam<SubdomainID>("interior_id")), 46 128 : _peripheral_id(getParam<SubdomainID>("peripheral_id")), 47 64 : _gap_indices(_hex_lattice.gapIndices()) 48 : { 49 64 : } 50 : 51 : std::unique_ptr<MooseMesh> 52 0 : HexagonalSubchannelGapMesh::safeClone() const 53 : { 54 0 : return _app.getFactory().copyConstruct(*this); 55 : } 56 : 57 : void 58 64 : HexagonalSubchannelGapMesh::buildMesh() 59 : { 60 64 : MeshBase & mesh = getMesh(); 61 64 : mesh.clear(); 62 64 : mesh.set_mesh_dimension(2); 63 64 : mesh.set_spatial_dimension(3); 64 : 65 64 : _elem_id_counter = 0; 66 64 : _node_id_counter = 0; 67 : 68 64 : const Real r = _hex_lattice.pinRadius(); 69 64 : Real dz = _height / _n_axial; 70 : 71 364 : for (unsigned int i = 0; i < _n_axial; ++i) 72 : { 73 300 : Real zmin = i * dz; 74 300 : Real zmax = (i + 1) * dz; 75 : 76 7428 : for (unsigned int i = 0; i < _hex_lattice.nInteriorGaps(); ++i) 77 : { 78 7128 : 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 7128 : const auto & center1 = _pin_centers[pins.first]; 83 7128 : const auto & center2 = _pin_centers[pins.second]; 84 7128 : const Point pt1 = center1 + r * (center2 - center1).unit(); 85 7128 : const Point pt2 = center2 + r * (center1 - center2).unit(); 86 : 87 7128 : addQuadElem(pt1, pt2, zmin, zmax, _interior_id); 88 : } 89 : 90 300 : Real d = _hex_lattice.pinBundleSpacing() + _hex_lattice.pinRadius(); 91 : 92 4476 : for (unsigned int i = _hex_lattice.nInteriorGaps(); i < _gap_indices.size(); ++i) 93 : { 94 : const auto & pins = _gap_indices[i]; 95 4176 : int side = std::abs(pins.second) - 1; 96 : 97 4176 : const auto & center1 = _pin_centers[pins.first]; 98 4176 : const Point pt2 = center1 + Point(d * _hex_lattice.sideTranslationX(side), 99 4176 : d * _hex_lattice.sideTranslationY(side), 100 : 0.0); 101 4176 : const Point pt1 = center1 + r * (pt2 - center1).unit(); 102 : 103 4176 : addQuadElem(pt1, pt2, zmin, zmax, _peripheral_id); 104 : } 105 : } 106 : 107 64 : mesh.prepare_for_use(); 108 64 : } 109 : 110 : void 111 11304 : HexagonalSubchannelGapMesh::addQuadElem(const Point & pt1, 112 : const Point & pt2, 113 : const Real & zmin, 114 : const Real & zmax, 115 : const unsigned int & id) 116 : { 117 11304 : auto elem = new Quad4; 118 11304 : elem->set_id(_elem_id_counter++); 119 11304 : _mesh->add_elem(elem); 120 : 121 11304 : Point z0(0.0, 0.0, zmin); 122 11304 : Point z1(0.0, 0.0, zmax); 123 : 124 11304 : auto node_ptr0 = _mesh->add_point(pt1 + z0, _node_id_counter++); 125 11304 : auto node_ptr1 = _mesh->add_point(pt2 + z0, _node_id_counter++); 126 11304 : auto node_ptr2 = _mesh->add_point(pt2 + z1, _node_id_counter++); 127 11304 : auto node_ptr3 = _mesh->add_point(pt1 + z1, _node_id_counter++); 128 : 129 11304 : elem->set_node(0) = node_ptr0; 130 11304 : elem->set_node(1) = node_ptr1; 131 11304 : elem->set_node(2) = node_ptr2; 132 11304 : elem->set_node(3) = node_ptr3; 133 : 134 11304 : elem->subdomain_id() = id; 135 11304 : }