#ifndef CONNECTIVITY_UTILS_HPP #define CONNECTIVITY_UTILS_HPP #include <map> #include <Kokkos_Core.hpp> #include <Kokkos_StaticCrsGraph.hpp> typedef Kokkos::StaticCrsGraph<unsigned int, Kokkos::HostSpace> ConnectivityMatrix; class ConnectivityUtils { public: void computeNodeCellConnectivity(const Kokkos::View<const unsigned int**> cell_nodes, const Kokkos::View<const unsigned short*> cell_nb_nodes, const size_t& number_of_cells, size_t& max_nb_node_per_cell, size_t& number_of_nodes, Kokkos::View<const unsigned short*>& node_nb_cells, Kokkos::View<const unsigned int**>& node_cells, Kokkos::View<const unsigned short**>& node_cell_local_node, ConnectivityMatrix& node_to_cell_matrix, ConnectivityMatrix& node_to_cell_local_node_matrix) { std::map<unsigned int, std::vector<unsigned int>> node_cells_map; using namespace Kokkos::Experimental; Kokkos::parallel_reduce(number_of_cells, KOKKOS_LAMBDA(const int& j, size_t& nb_max) { const size_t n = cell_nb_nodes[j]; if (n > nb_max) nb_max = n; }, Kokkos::Max<size_t>(max_nb_node_per_cell)); for (unsigned int j=0; j<number_of_cells; ++j) { for (unsigned int r=0; r<cell_nb_nodes[j]; ++r) { node_cells_map[cell_nodes(j,r)].push_back(j); } } { size_t i=0; for (const auto& i_cell_vector : node_cells_map) { const auto& [node_id, cell_vector] = i_cell_vector; if (node_id != i) { std::cerr << "sparse node numerotation NIY\n"; std::exit(0); } ++i; } } number_of_nodes = node_cells_map.size(); Kokkos::View<unsigned short*> built_node_nb_cells("node_nb_cells", node_cells_map.size()); size_t max_node_cells = 0; for (const auto& i_cell_vector : node_cells_map) { const auto& [i, cells_vector] = i_cell_vector; const size_t nb_cells = cells_vector.size(); built_node_nb_cells[i] = nb_cells; if (nb_cells > max_node_cells) { max_node_cells = nb_cells; } } node_nb_cells = built_node_nb_cells; Kokkos::View<unsigned int**> built_node_cells("node_cells", node_cells_map.size(), max_node_cells); for (const auto& i_cell_vector : node_cells_map) { const auto& [i, cells_vector] = i_cell_vector; for (size_t j=0; j<cells_vector.size(); ++j) { built_node_cells(i,j) = cells_vector[j]; } } node_cells = built_node_cells; std::vector<std::vector<unsigned int>> node_to_cell_vector(node_cells_map.size()); for (const auto& i_cell_vector : node_cells_map) { const auto& [r, cells_vector] = i_cell_vector; node_to_cell_vector[r] = cells_vector; } node_to_cell_matrix = Kokkos::create_staticcrsgraph<ConnectivityMatrix>("node_to_cell_matrix", node_to_cell_vector); Kokkos::View<unsigned short**> built_node_cell_local_node("node_cell_local_node", node_cells_map.size(), max_node_cells); Kokkos::parallel_for(number_of_nodes, KOKKOS_LAMBDA(const unsigned int& r){ for (unsigned short J=0; J<node_nb_cells[r]; ++J) { const unsigned int j = node_cells(r,J); for (unsigned int R=0; R<cell_nb_nodes[j]; ++R) { if (cell_nodes(j,R) == r) { built_node_cell_local_node(r,J)=R; break; } } } }); node_cell_local_node = built_node_cell_local_node; std::vector<std::vector<unsigned int>> node_to_cell_local_node_vector(node_cells_map.size()); for (unsigned int r=0; r<node_cells_map.size(); ++r) { node_to_cell_local_node_vector[r].resize(node_nb_cells[r]); for (unsigned short J=0; J<node_nb_cells[r]; ++J) { const unsigned int j = node_cells(r,J); for (unsigned int R=0; R<cell_nb_nodes[j]; ++R) { if (cell_nodes(j,R) == r) { node_to_cell_local_node_vector[r][J] = R; break; } } } } node_to_cell_local_node_matrix = Kokkos::create_staticcrsgraph<ConnectivityMatrix>("node_to_cell_local_node_matrix", node_to_cell_local_node_vector); } }; #endif // CONNECTIVITY_UTILS_HPP