Line data Source code
1 : //* This file is part of the MOOSE framework 2 : //* https://www.mooseframework.org 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 "KokkosMesh.h" 11 : 12 : #include "MooseMesh.h" 13 : 14 : #include "libmesh/reference_elem.h" 15 : 16 : namespace Moose 17 : { 18 : namespace Kokkos 19 : { 20 : 21 : void 22 1392 : Mesh::update() 23 : { 24 1392 : initMap(); 25 1392 : initElement(); 26 1392 : } 27 : 28 : void 29 1392 : Mesh::initMap() 30 : { 31 1392 : if (!_maps) 32 699 : _maps = std::make_shared<MeshMap>(); 33 : 34 1392 : _maps->_subdomain_id_mapping.clear(); 35 1392 : _maps->_boundary_id_mapping.clear(); 36 1392 : _maps->_elem_type_id_mapping.clear(); 37 1392 : _maps->_local_elem_id_mapping.clear(); 38 1392 : _maps->_local_node_id_mapping.clear(); 39 1392 : _maps->_subdomain_elem_ids.clear(); 40 1392 : _maps->_subdomain_node_ids.clear(); 41 : 42 2890 : for (auto subdomain : _mesh.meshSubdomains()) 43 : { 44 1498 : _maps->_subdomain_id_mapping[subdomain] = _maps->_subdomain_id_mapping.size(); 45 1498 : _maps->_subdomain_elem_ids[subdomain]; 46 1498 : _maps->_subdomain_node_ids[subdomain]; 47 : 48 133894 : for (const auto elem : _mesh.getMesh().active_local_subdomain_elements_ptr_range(subdomain)) 49 : { 50 66198 : if (!_maps->_elem_type_id_mapping.count(elem->type())) 51 1392 : _maps->_elem_type_id_mapping[elem->type()] = _maps->_elem_type_id_mapping.size(); 52 : 53 66198 : auto eid = _maps->_local_elem_id_mapping.size(); 54 : 55 66198 : _maps->_local_elem_id_mapping[elem] = eid; 56 66198 : _maps->_subdomain_elem_ids[subdomain].insert(eid); 57 : 58 330070 : for (const auto & node : elem->node_ref_range()) 59 : { 60 263872 : if (!_maps->_local_node_id_mapping.count(&node)) 61 85052 : _maps->_local_node_id_mapping[&node] = _maps->_local_node_id_mapping.size(); 62 : 63 263872 : if (node.processor_id() == _mesh.processor_id()) 64 260460 : _maps->_subdomain_node_ids[subdomain].insert(_maps->_local_node_id_mapping[&node]); 65 : } 66 1498 : } 67 : } 68 : 69 6384 : for (auto boundary : _mesh.meshBoundaryIds()) 70 4992 : _maps->_boundary_id_mapping[boundary] = _maps->_boundary_id_mapping.size(); 71 1392 : } 72 : 73 : void 74 1392 : Mesh::initElement() 75 : { 76 : // Cache reference element data 77 : 78 1392 : auto num_elem_types = getElementTypeMap().size(); 79 : 80 1392 : _num_sides.create(num_elem_types); 81 1392 : _num_nodes.create(num_elem_types); 82 1392 : _num_side_nodes.create(num_elem_types); 83 : 84 2784 : for (auto & [elem_type, elem_type_id] : getElementTypeMap()) 85 : { 86 1392 : auto elem = &libMesh::ReferenceElem::get(elem_type); 87 : 88 1392 : _num_sides[elem_type_id] = elem->n_sides(); 89 1392 : _num_nodes[elem_type_id] = elem->n_nodes(); 90 : 91 1392 : _num_side_nodes[elem_type_id].create(elem->n_sides()); 92 : 93 6552 : for (unsigned int side = 0; side < elem->n_sides(); ++side) 94 5160 : _num_side_nodes[elem_type_id][side] = elem->side_ptr(side)->n_nodes(); 95 : } 96 : 97 1392 : _num_sides.copyToDevice(); 98 1392 : _num_nodes.copyToDevice(); 99 1392 : _num_side_nodes.copyToDeviceNested(); 100 : 101 : // Cache element data 102 : 103 1392 : auto num_elems = getContiguousElementMap().size(); 104 : 105 1392 : _elem_info.create(num_elems); 106 1392 : _elem_neighbor.create(_mesh.getMaxSidesPerElem(), num_elems); 107 1392 : _elem_neighbor = libMesh::DofObject::invalid_id; 108 : 109 67590 : for (auto & [elem, eid] : getContiguousElementMap()) 110 : { 111 66198 : auto elem_type = getElementTypeID(elem); 112 : 113 66198 : _elem_info[eid].type = elem_type; 114 66198 : _elem_info[eid].id = eid; 115 66198 : _elem_info[eid].subdomain = getContiguousSubdomainID(elem->subdomain_id()); 116 : } 117 : 118 1392 : _elem_info.copyToDevice(); 119 1392 : _elem_neighbor.copyToDevice(); 120 : 121 : // Cache node data 122 : 123 1392 : auto num_nodes = getContiguousNodeMap().size(); 124 : 125 1392 : _points.create(num_nodes); 126 1392 : _nodes.create(_mesh.getMaxNodesPerElem(), num_elems); 127 1392 : _nodes_face.create(_mesh.getMaxNodesPerSide(), _mesh.getMaxSidesPerElem(), num_elems); 128 1392 : _boundary_nodes.create(_mesh.meshBoundaryIds().size()); 129 : 130 86444 : for (auto & [node, nid] : getContiguousNodeMap()) 131 85052 : _points[nid] = *node; 132 : 133 67590 : for (auto & [elem, eid] : getContiguousElementMap()) 134 : { 135 330070 : for (unsigned int node = 0; node < elem->n_nodes(); ++node) 136 263872 : _nodes(node, eid) = getContiguousNodeID(elem->node_ptr(node)); 137 : 138 322390 : for (unsigned int side = 0; side < elem->n_sides(); ++side) 139 798376 : for (unsigned int node = 0; node < elem->side_ptr(side)->n_nodes(); ++node) 140 542184 : _nodes_face(node, side, eid) = getContiguousNodeID(elem->side_ptr(side)->node_ptr(node)); 141 : } 142 : 143 6384 : for (auto boundary : _mesh.meshBoundaryIds()) 144 : { 145 4992 : std::set<ContiguousNodeID> nodes; 146 : 147 27622 : for (const auto node : as_range(_mesh.getMesh().bid_nodes_begin(boundary), 148 66850 : _mesh.getMesh().bid_nodes_end(boundary))) 149 37152 : if (node->processor_id() == _mesh.processor_id()) 150 37928 : nodes.insert(getContiguousNodeID(node)); 151 : 152 4992 : _boundary_nodes[getContiguousBoundaryID(boundary)] = nodes; 153 4992 : } 154 : 155 1392 : _points.copyToDevice(); 156 1392 : _nodes.copyToDevice(); 157 1392 : _nodes_face.copyToDevice(); 158 1392 : _boundary_nodes.copyToDevice(); 159 1392 : } 160 : 161 : ContiguousSubdomainID 162 201583 : Mesh::getContiguousSubdomainID(const SubdomainID subdomain) const 163 : { 164 201583 : if (!_maps->_subdomain_id_mapping.count(subdomain)) 165 0 : mooseError("Subdomain ", subdomain, " does not have Kokkos contiguous subdomain ID"); 166 : 167 201583 : return _maps->_subdomain_id_mapping.at(subdomain); 168 : } 169 : 170 : ContiguousBoundaryID 171 5152 : Mesh::getContiguousBoundaryID(const BoundaryID boundary) const 172 : { 173 5152 : if (!_maps->_boundary_id_mapping.count(boundary)) 174 0 : mooseError("Boundary ", boundary, " does not have Kokkos contiguous boundary ID"); 175 : 176 5152 : return _maps->_boundary_id_mapping.at(boundary); 177 : } 178 : 179 : unsigned int 180 66198 : Mesh::getElementTypeID(const Elem * elem) const 181 : { 182 : mooseAssert(elem, "Element pointer is null"); 183 : 184 66198 : if (!_maps->_elem_type_id_mapping.count(elem->type())) 185 0 : mooseError("Element type ", elem->type(), " does not have Kokkos element type ID"); 186 : 187 66198 : return _maps->_elem_type_id_mapping.at(elem->type()); 188 : } 189 : 190 : ContiguousElementID 191 36589 : Mesh::getContiguousElementID(const Elem * elem) const 192 : { 193 : mooseAssert(elem, "Element pointer is null"); 194 : 195 36589 : if (!_maps->_local_elem_id_mapping.count(elem)) 196 0 : mooseError("Element ", elem->id(), " does not have Kokkos contiguous element ID"); 197 : 198 36589 : return _maps->_local_elem_id_mapping.at(elem); 199 : } 200 : 201 : ContiguousNodeID 202 849445 : Mesh::getContiguousNodeID(const Node * node) const 203 : { 204 : mooseAssert(node, "Node pointer is null"); 205 : 206 849445 : if (!_maps->_local_node_id_mapping.count(node)) 207 0 : mooseError("Node ", node->id(), " does not have Kokkos contiguous node ID"); 208 : 209 849445 : return _maps->_local_node_id_mapping.at(node); 210 : } 211 : 212 : } // namespace Kokkos 213 : } // namespace Moose