Build a graph for owned dofs and apply graph reordering function with multiple dofmaps. The dofmaps are 2D arrays, of fixed width, stored in `dofmap_t` format. The dofmaps all refer to dof indices in the same range [0:owned_size). @param[in] dofmaps The local dofmaps (cell -> dofs) @param[in] owned_size Number of dofs owned by this process @param[in] original_to_contiguous Map from dof indices in
| 51 | /// @return Map from original_to_contiguous[i] to new index after |
| 52 | /// reordering |
| 53 | std::vector<int> |
| 54 | reorder_owned(const std::vector<dofmap_t>& dofmaps, std::int32_t owned_size, |
| 55 | const std::vector<int>& original_to_contiguous, |
| 56 | const std::function<std::vector<int>( |
| 57 | const graph::AdjacencyList<std::int32_t>&)>& reorder_fn) |
| 58 | { |
| 59 | std::vector<std::int32_t> graph_data, graph_offsets; |
| 60 | |
| 61 | // Compute maximum number of graph out edges edges per dof |
| 62 | std::vector<int> num_edges(owned_size); |
| 63 | for (auto& dofmap : dofmaps) |
| 64 | { |
| 65 | std::size_t num_cells = dofmap.array.size() / dofmap.width; |
| 66 | std::vector<std::int32_t> node_temp; |
| 67 | for (std::size_t cell = 0; cell < num_cells; ++cell) |
| 68 | { |
| 69 | node_temp.clear(); |
| 70 | for (std::int32_t i = 0; i < dofmap.width; ++i) |
| 71 | { |
| 72 | std::int32_t node |
| 73 | = original_to_contiguous[dofmap.array[cell * dofmap.width + i]]; |
| 74 | if (node < owned_size) |
| 75 | node_temp.push_back(node); |
| 76 | } |
| 77 | for (std::int32_t node : node_temp) |
| 78 | num_edges[node] += node_temp.size() - 1; |
| 79 | } |
| 80 | } |
| 81 | |
| 82 | // Compute adjacency list with duplicate edges |
| 83 | std::vector<std::int32_t> offsets(num_edges.size() + 1, 0); |
| 84 | std::partial_sum(num_edges.begin(), num_edges.end(), |
| 85 | std::next(offsets.begin(), 1)); |
| 86 | std::vector<std::int32_t> edges(offsets.back()); |
| 87 | for (auto& dofmap : dofmaps) |
| 88 | { |
| 89 | std::size_t num_cells = dofmap.array.size() / dofmap.width; |
| 90 | std::vector<std::int32_t> node_temp; |
| 91 | |
| 92 | for (std::size_t cell = 0; cell < num_cells; ++cell) |
| 93 | { |
| 94 | node_temp.clear(); |
| 95 | for (std::int32_t i = 0; i < dofmap.width; ++i) |
| 96 | { |
| 97 | std::int32_t node |
| 98 | = original_to_contiguous[dofmap.array[cell * dofmap.width + i]]; |
| 99 | if (node < owned_size) |
| 100 | node_temp.push_back(node); |
| 101 | } |
| 102 | |
| 103 | for (std::size_t i = 0; i < node_temp.size(); ++i) |
| 104 | { |
| 105 | std::int32_t node_0 = node_temp[i]; |
| 106 | for (std::size_t j = i + 1; j < node_temp.size(); ++j) |
| 107 | { |
| 108 | std::int32_t node_1 = node_temp[j]; |
| 109 | edges[offsets[node_0]++] = node_1; |
| 110 | edges[offsets[node_1]++] = node_0; |
no test coverage detected