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::Kokkos 17 : { 18 : 19 : void 20 2265 : Mesh::update() 21 : { 22 2265 : initMap(); 23 2265 : initElement(); 24 : 25 2265 : _initialized = true; 26 2265 : } 27 : 28 : void 29 2265 : Mesh::initMap() 30 : { 31 2265 : if (!_maps) 32 2265 : _maps = std::make_shared<MeshMap>(); 33 : 34 2265 : if (_elem_id_integer == libMesh::invalid_uint) 35 6795 : _elem_id_integer = _mesh.getMesh().add_elem_integer("kokkos_contiguous_elem_id"); 36 : 37 2265 : if (_node_id_integer == libMesh::invalid_uint) 38 6795 : _node_id_integer = _mesh.getMesh().add_node_integer("kokkos_contiguous_node_id"); 39 : 40 2265 : _num_local_elems = 0; 41 2265 : _num_local_nodes = 0; 42 : 43 2265 : _maps->subdomain_id_mapping.clear(); 44 2265 : _maps->boundary_id_mapping.clear(); 45 2265 : _maps->elem_type_id_mapping.clear(); 46 2265 : _maps->local_nodes.clear(); 47 2265 : _maps->semi_local_node_id_mapping.clear(); 48 2265 : _maps->subdomain_elem_id_ranges.clear(); 49 2265 : _maps->subdomain_node_ids.clear(); 50 2265 : _maps->boundary_node_ids.clear(); 51 : 52 2265 : std::unordered_set<ElemType> elem_types; 53 2265 : std::unordered_set<Node *> semi_local_nodes; 54 : 55 5211 : for (const auto subdomain : _mesh.meshSubdomains()) 56 : { 57 2946 : _maps->subdomain_id_mapping[subdomain] = _maps->subdomain_id_mapping.size(); 58 2946 : _maps->subdomain_node_ids[subdomain]; 59 : 60 2946 : dof_id_type begin = libMesh::DofObject::invalid_id; 61 2946 : dof_id_type eid = libMesh::DofObject::invalid_id; 62 : 63 646865 : for (auto elem : _mesh.getMesh().active_local_subdomain_elements_ptr_range(subdomain)) 64 : { 65 643919 : elem_types.insert(elem->type()); 66 : 67 643919 : eid = _num_local_elems; 68 643919 : elem->set_extra_integer(_elem_id_integer, _num_local_elems++); 69 : 70 643919 : if (begin == libMesh::DofObject::invalid_id) 71 2754 : begin = eid; 72 : 73 3254267 : for (auto & node : elem->node_ref_range()) 74 2610348 : if (node.processor_id() != _mesh.processor_id()) 75 13914 : semi_local_nodes.insert(&node); 76 2946 : } 77 : 78 2946 : _maps->subdomain_elem_id_ranges[subdomain] = eid != libMesh::DofObject::invalid_id 79 3200 : ? std::make_pair(begin, eid + 1) 80 1696 : : std::make_pair(begin, eid); 81 : } 82 : 83 11314 : for (const auto boundary : _mesh.meshBoundaryIds()) 84 : { 85 9049 : _maps->boundary_id_mapping[boundary] = _maps->boundary_id_mapping.size(); 86 9049 : _maps->boundary_node_ids[boundary]; 87 : } 88 : 89 : // Setup node maps 90 : 91 4526 : for (const auto type : elem_types) 92 2261 : _maps->elem_type_id_mapping[type] = _maps->elem_type_id_mapping.size(); 93 : 94 3496 : _maps->local_nodes.insert( 95 2462 : _maps->local_nodes.end(), _mesh.localNodesBegin(), _mesh.localNodesEnd()); 96 3496 : _maps->local_nodes.insert( 97 1231 : _maps->local_nodes.end(), semi_local_nodes.begin(), semi_local_nodes.end()); 98 : 99 711105 : for (auto node : _maps->local_nodes) 100 : { 101 708840 : if (node->processor_id() == _mesh.processor_id()) 102 : { 103 701428 : node->set_extra_integer(_node_id_integer, _num_local_nodes); 104 : 105 1488921 : for (auto subdomain : _mesh.getNodeBlockIds(*node)) 106 787493 : _maps->subdomain_node_ids[subdomain].push_back(_num_local_nodes); 107 : } 108 : else 109 7412 : _maps->semi_local_node_id_mapping[node] = _num_local_nodes; 110 : 111 708840 : ++_num_local_nodes; 112 : } 113 : 114 121720 : for (const auto bnd_node : as_range(_mesh.bndNodesBegin(), _mesh.bndNodesEnd())) 115 119455 : if (bnd_node->_node->processor_id() == _mesh.processor_id()) 116 101082 : _maps->boundary_node_ids[bnd_node->_bnd_id].insert(getContiguousNodeID(bnd_node->_node)); 117 2265 : } 118 : 119 : void 120 2265 : Mesh::initElement() 121 : { 122 : // Cache reference element data 123 : 124 2265 : const auto num_elem_types = getNumLocalElementTypes(); 125 : 126 2265 : _num_sides.create(num_elem_types); 127 2265 : _num_nodes.create(num_elem_types); 128 2265 : _num_side_nodes.create(num_elem_types); 129 2265 : _local_side_node.create(num_elem_types); 130 : 131 4526 : for (auto & [elem_type, elem_type_id] : getElementTypeMap()) 132 : { 133 2261 : auto elem = &libMesh::ReferenceElem::get(elem_type); 134 : 135 2261 : _num_sides[elem_type_id] = elem->n_sides(); 136 2261 : _num_nodes[elem_type_id] = elem->n_nodes(); 137 : 138 2261 : _num_side_nodes[elem_type_id].create(elem->n_sides()); 139 2261 : _local_side_node[elem_type_id].create(elem->n_nodes(), elem->n_sides()); 140 : 141 10977 : for (unsigned int side = 0; side < elem->n_sides(); ++side) 142 : { 143 8716 : _num_side_nodes[elem_type_id][side] = elem->side_ptr(side)->n_nodes(); 144 : 145 26670 : for (unsigned int node = 0; node < elem->side_ptr(side)->n_nodes(); ++node) 146 17954 : _local_side_node[elem_type_id](node, side) = elem->local_side_node(side, node); 147 : } 148 : 149 2261 : _num_side_nodes[elem_type_id].moveToDevice(); 150 2261 : _local_side_node[elem_type_id].moveToDevice(); 151 : } 152 : 153 2265 : _num_sides.moveToDevice(); 154 2265 : _num_nodes.moveToDevice(); 155 2265 : _num_side_nodes.copyToDevice(); 156 2265 : _local_side_node.copyToDevice(); 157 : 158 : // Cache element data 159 : 160 2265 : const auto num_elems = getNumLocalElements(); 161 2265 : const auto num_subdomains = getNumSubdomains(); 162 : 163 2265 : _elem_info.create(num_elems); 164 2265 : _elem_neighbor.create(_mesh.getMaxSidesPerElem(), num_elems); 165 2265 : _extra_elem_ids.create(num_elems, _mesh.getMesh().n_elem_integers()); 166 2265 : _starting_elem_id.create(num_subdomains); 167 : 168 2265 : _elem_neighbor = libMesh::DofObject::invalid_id; 169 2265 : _extra_elem_ids = libMesh::DofObject::invalid_id; 170 : 171 5211 : for (const auto subdomain : _mesh.meshSubdomains()) 172 : { 173 2946 : const auto sid = getContiguousSubdomainID(subdomain); 174 : 175 1290784 : for (const auto elem : _mesh.getMesh().active_local_subdomain_elements_ptr_range(subdomain)) 176 : { 177 643919 : const auto elem_type = getElementTypeID(elem); 178 643919 : const auto eid = getContiguousElementID(elem); 179 : 180 643919 : _elem_info[eid].type = elem_type; 181 643919 : _elem_info[eid].id = eid; 182 643919 : _elem_info[eid].subdomain = sid; 183 : 184 2296354 : for (const auto i : make_range(_mesh.getMesh().n_elem_integers())) 185 1652435 : _extra_elem_ids(eid, i) = elem->get_extra_integer(i); 186 2946 : } 187 : 188 2946 : _starting_elem_id[sid] = *getSubdomainContiguousElementIDRange(subdomain).begin(); 189 : } 190 : 191 2265 : _elem_info.moveToDevice(); 192 2265 : _elem_neighbor.moveToDevice(); 193 2265 : _extra_elem_ids.moveToDevice(); 194 2265 : _starting_elem_id.moveToDevice(); 195 : 196 : // Cache node data 197 : 198 2265 : const auto num_nodes = getNumLocalNodes(); 199 : 200 2265 : _points.create(num_nodes); 201 2265 : _nodes.create(_mesh.getMaxNodesPerElem(), num_elems); 202 2265 : _boundary_nodes.create(_mesh.meshBoundaryIds().size()); 203 : 204 711105 : for (const auto node : getLocalNodes()) 205 708840 : _points[getContiguousNodeID(node)] = *node; 206 : 207 1290103 : for (const auto elem : _mesh.getMesh().active_local_element_ptr_range()) 208 : { 209 643919 : const auto eid = getContiguousElementID(elem); 210 : 211 3254267 : for (unsigned int node = 0; node < elem->n_nodes(); ++node) 212 2610348 : _nodes(node, eid) = getContiguousNodeID(elem->node_ptr(node)); 213 2265 : } 214 : 215 11314 : for (const auto boundary : _mesh.meshBoundaryIds()) 216 9049 : _boundary_nodes[getContiguousBoundaryID(boundary)].copySet<false, true>( 217 4949 : _maps->boundary_node_ids[boundary]); 218 : 219 2265 : _points.moveToDevice(); 220 2265 : _nodes.moveToDevice(); 221 2265 : _boundary_nodes.copyToDevice(); 222 2265 : } 223 : 224 : ContiguousSubdomainID 225 1120822 : Mesh::getContiguousSubdomainID(const SubdomainID subdomain) const 226 : { 227 1120822 : return libmesh_map_find(_maps->subdomain_id_mapping, subdomain); 228 : } 229 : 230 : ContiguousBoundaryID 231 9289 : Mesh::getContiguousBoundaryID(const BoundaryID boundary) const 232 : { 233 9289 : return libmesh_map_find(_maps->boundary_id_mapping, boundary); 234 : } 235 : 236 : unsigned int 237 643919 : Mesh::getElementTypeID(const Elem * elem) const 238 : { 239 : mooseAssert(elem, "Element pointer is null"); 240 : 241 643919 : return libmesh_map_find(_maps->elem_type_id_mapping, elem->type()); 242 : } 243 : 244 : ContiguousElementID 245 3800149 : Mesh::getContiguousElementID(const Elem * elem) const 246 : { 247 : mooseAssert(elem, "Element pointer is null"); 248 : 249 3800149 : return elem->get_extra_integer(_elem_id_integer); 250 : } 251 : 252 : ContiguousNodeID 253 4888960 : Mesh::getContiguousNodeID(const Node * node) const 254 : { 255 : mooseAssert(node, "Node pointer is null"); 256 : 257 4888960 : if (node->processor_id() == _mesh.processor_id()) 258 4867634 : return node->get_extra_integer(_node_id_integer); 259 : else 260 21326 : return libmesh_map_find(_maps->semi_local_node_id_mapping, node); 261 : } 262 : 263 : } // namespace Moose::Kokkos