#include <catch2/catch_test_macros.hpp> #include <catch2/matchers/catch_matchers_all.hpp> #include <MeshDataBaseForTests.hpp> #include <mesh/Connectivity.hpp> #include <mesh/ItemArray.hpp> #include <mesh/ItemArrayUtils.hpp> #include <mesh/Mesh.hpp> #include <utils/Messenger.hpp> // Instantiate to ensure full coverage is performed template class ItemArray<int, ItemType::cell>; // clazy:excludeall=non-pod-global-static TEST_CASE("ItemArrayUtils", "[mesh]") { SECTION("Synchronize") { SECTION("1D") { const Mesh<Connectivity<1>>& mesh_1d = MeshDataBaseForTests::get().cartesianMesh<1>(); const Connectivity<1>& connectivity = mesh_1d.connectivity(); SECTION("node") { WeakNodeArray<size_t> weak_node_array{connectivity, 4}; auto node_number = connectivity.nodeNumber(); for (NodeId i_node = 0; i_node < mesh_1d.numberOfNodes(); ++i_node) { SubArray array = weak_node_array[i_node]; const size_t number = node_number[i_node]; for (size_t i = 0; i < array.size(); ++i) { array[i] = number + (parallel::rank() + 1) * i; } } NodeArray<const size_t> node_array{weak_node_array}; REQUIRE(node_array.connectivity_ptr() == weak_node_array.connectivity_ptr()); { // before synchronization auto node_owner = connectivity.nodeOwner(); auto node_is_owned = connectivity.nodeIsOwned(); bool is_synchronized = (parallel::size() > 1); bool is_valid = true; for (NodeId i_node = 0; i_node < mesh_1d.numberOfNodes(); ++i_node) { SubArray array = node_array[i_node]; const size_t number = node_number[i_node]; const size_t owner = node_owner[i_node]; if (node_is_owned[i_node]) { for (size_t i = 0; i < array.size(); ++i) { is_valid &= (array[i] == number + (owner + 1) * i); } } else { for (size_t i = 0; i < array.size(); ++i) { is_synchronized &= (array[i] == number + (owner + 1) * i); } } } REQUIRE(is_valid); REQUIRE(not is_synchronized); } synchronize(weak_node_array); { // after synchronization auto node_owner = connectivity.nodeOwner(); bool is_synchronized = true; for (NodeId i_node = 0; i_node < mesh_1d.numberOfNodes(); ++i_node) { SubArray array = node_array[i_node]; const size_t number = node_number[i_node]; const size_t owner = node_owner[i_node]; for (size_t i = 0; i < array.size(); ++i) { is_synchronized &= (array[i] == number + (owner + 1) * i); } } REQUIRE(is_synchronized); } } SECTION("edge") { WeakEdgeArray<size_t> weak_edge_array{connectivity, 4}; auto edge_number = connectivity.edgeNumber(); for (EdgeId i_edge = 0; i_edge < mesh_1d.numberOfEdges(); ++i_edge) { SubArray array = weak_edge_array[i_edge]; const size_t number = edge_number[i_edge]; for (size_t i = 0; i < array.size(); ++i) { array[i] = number + (parallel::rank() + 1) * i; } } EdgeArray<const size_t> edge_array{weak_edge_array}; REQUIRE(edge_array.connectivity_ptr() == weak_edge_array.connectivity_ptr()); { // before synchronization auto edge_owner = connectivity.edgeOwner(); auto edge_is_owned = connectivity.edgeIsOwned(); bool is_synchronized = (parallel::size() > 1); bool is_valid = true; for (EdgeId i_edge = 0; i_edge < mesh_1d.numberOfEdges(); ++i_edge) { SubArray array = edge_array[i_edge]; const size_t number = edge_number[i_edge]; const size_t owner = edge_owner[i_edge]; if (edge_is_owned[i_edge]) { for (size_t i = 0; i < array.size(); ++i) { is_valid &= (array[i] == number + (owner + 1) * i); } } else { for (size_t i = 0; i < array.size(); ++i) { is_synchronized &= (array[i] == number + (owner + 1) * i); } } } REQUIRE(is_valid); REQUIRE(not is_synchronized); } synchronize(weak_edge_array); { // after synchronization auto edge_owner = connectivity.edgeOwner(); bool is_synchronized = true; for (EdgeId i_edge = 0; i_edge < mesh_1d.numberOfEdges(); ++i_edge) { SubArray array = edge_array[i_edge]; const size_t number = edge_number[i_edge]; const size_t owner = edge_owner[i_edge]; for (size_t i = 0; i < array.size(); ++i) { is_synchronized &= (array[i] == number + (owner + 1) * i); } } REQUIRE(is_synchronized); } } SECTION("face") { WeakFaceArray<size_t> weak_face_array{connectivity, 4}; auto face_number = connectivity.faceNumber(); for (FaceId i_face = 0; i_face < mesh_1d.numberOfFaces(); ++i_face) { SubArray array = weak_face_array[i_face]; const size_t number = face_number[i_face]; for (size_t i = 0; i < array.size(); ++i) { array[i] = number + (parallel::rank() + 1) * i; } } FaceArray<const size_t> face_array{weak_face_array}; REQUIRE(face_array.connectivity_ptr() == weak_face_array.connectivity_ptr()); { // before synchronization auto face_owner = connectivity.faceOwner(); auto face_is_owned = connectivity.faceIsOwned(); bool is_synchronized = (parallel::size() > 1); bool is_valid = true; for (FaceId i_face = 0; i_face < mesh_1d.numberOfFaces(); ++i_face) { SubArray array = face_array[i_face]; const size_t number = face_number[i_face]; const size_t owner = face_owner[i_face]; if (face_is_owned[i_face]) { for (size_t i = 0; i < array.size(); ++i) { is_valid &= (array[i] == number + (owner + 1) * i); } } else { for (size_t i = 0; i < array.size(); ++i) { is_synchronized &= (array[i] == number + (owner + 1) * i); } } } REQUIRE(is_valid); REQUIRE(not is_synchronized); } synchronize(weak_face_array); { // after synchronization auto face_owner = connectivity.faceOwner(); bool is_synchronized = true; for (FaceId i_face = 0; i_face < mesh_1d.numberOfFaces(); ++i_face) { SubArray array = face_array[i_face]; const size_t number = face_number[i_face]; const size_t owner = face_owner[i_face]; for (size_t i = 0; i < array.size(); ++i) { is_synchronized &= (array[i] == number + (owner + 1) * i); } } REQUIRE(is_synchronized); } } SECTION("cell") { WeakCellArray<size_t> weak_cell_array{connectivity, 4}; auto cell_number = connectivity.cellNumber(); for (CellId i_cell = 0; i_cell < mesh_1d.numberOfCells(); ++i_cell) { SubArray array = weak_cell_array[i_cell]; const size_t number = cell_number[i_cell]; for (size_t i = 0; i < array.size(); ++i) { array[i] = number + (parallel::rank() + 1) * i; } } CellArray<const size_t> cell_array{weak_cell_array}; REQUIRE(cell_array.connectivity_ptr() == weak_cell_array.connectivity_ptr()); { // before synchronization auto cell_owner = connectivity.cellOwner(); auto cell_is_owned = connectivity.cellIsOwned(); bool is_synchronized = (parallel::size() > 1); bool is_valid = true; for (CellId i_cell = 0; i_cell < mesh_1d.numberOfCells(); ++i_cell) { SubArray array = cell_array[i_cell]; const size_t number = cell_number[i_cell]; const size_t owner = cell_owner[i_cell]; if (cell_is_owned[i_cell]) { for (size_t i = 0; i < array.size(); ++i) { is_valid &= (array[i] == number + (owner + 1) * i); } } else { for (size_t i = 0; i < array.size(); ++i) { is_synchronized &= (array[i] == number + (owner + 1) * i); } } } REQUIRE(is_valid); REQUIRE(not is_synchronized); } synchronize(weak_cell_array); { // after synchronization auto cell_owner = connectivity.cellOwner(); bool is_synchronized = true; for (CellId i_cell = 0; i_cell < mesh_1d.numberOfCells(); ++i_cell) { SubArray array = cell_array[i_cell]; const size_t number = cell_number[i_cell]; const size_t owner = cell_owner[i_cell]; for (size_t i = 0; i < array.size(); ++i) { is_synchronized &= (array[i] == number + (owner + 1) * i); } } REQUIRE(is_synchronized); } } } SECTION("2D") { const Mesh<Connectivity<2>>& mesh_2d = MeshDataBaseForTests::get().cartesianMesh<2>(); const Connectivity<2>& connectivity = mesh_2d.connectivity(); SECTION("node") { WeakNodeArray<size_t> weak_node_array{connectivity, 3}; auto node_number = connectivity.nodeNumber(); for (NodeId i_node = 0; i_node < mesh_2d.numberOfNodes(); ++i_node) { SubArray array = weak_node_array[i_node]; const size_t number = node_number[i_node]; for (size_t i = 0; i < array.size(); ++i) { array[i] = number + (parallel::rank() + 1) * i; } } NodeArray<const size_t> node_array{weak_node_array}; REQUIRE(node_array.connectivity_ptr() == weak_node_array.connectivity_ptr()); { // before synchronization auto node_owner = connectivity.nodeOwner(); auto node_is_owned = connectivity.nodeIsOwned(); bool is_synchronized = (parallel::size() > 1); bool is_valid = true; for (NodeId i_node = 0; i_node < mesh_2d.numberOfNodes(); ++i_node) { SubArray array = node_array[i_node]; const size_t number = node_number[i_node]; const size_t owner = node_owner[i_node]; if (node_is_owned[i_node]) { for (size_t i = 0; i < array.size(); ++i) { is_valid &= (array[i] == number + (owner + 1) * i); } } else { for (size_t i = 0; i < array.size(); ++i) { is_synchronized &= (array[i] == number + (owner + 1) * i); } } } REQUIRE(is_valid); REQUIRE(not is_synchronized); } synchronize(weak_node_array); { // after synchronization auto node_owner = connectivity.nodeOwner(); bool is_synchronized = true; for (NodeId i_node = 0; i_node < mesh_2d.numberOfNodes(); ++i_node) { SubArray array = node_array[i_node]; const size_t number = node_number[i_node]; const size_t owner = node_owner[i_node]; for (size_t i = 0; i < array.size(); ++i) { is_synchronized &= (array[i] == number + (owner + 1) * i); } } REQUIRE(is_synchronized); } } SECTION("edge") { WeakEdgeArray<size_t> weak_edge_array{connectivity, 3}; auto edge_number = connectivity.edgeNumber(); for (EdgeId i_edge = 0; i_edge < mesh_2d.numberOfEdges(); ++i_edge) { SubArray array = weak_edge_array[i_edge]; const size_t number = edge_number[i_edge]; for (size_t i = 0; i < array.size(); ++i) { array[i] = number + (parallel::rank() + 1) * i; } } EdgeArray<const size_t> edge_array{weak_edge_array}; REQUIRE(edge_array.connectivity_ptr() == weak_edge_array.connectivity_ptr()); { // before synchronization auto edge_owner = connectivity.edgeOwner(); auto edge_is_owned = connectivity.edgeIsOwned(); bool is_synchronized = (parallel::size() > 1); bool is_valid = true; for (EdgeId i_edge = 0; i_edge < mesh_2d.numberOfEdges(); ++i_edge) { SubArray array = edge_array[i_edge]; const size_t number = edge_number[i_edge]; const size_t owner = edge_owner[i_edge]; if (edge_is_owned[i_edge]) { for (size_t i = 0; i < array.size(); ++i) { is_valid &= (array[i] == number + (owner + 1) * i); } } else { for (size_t i = 0; i < array.size(); ++i) { is_synchronized &= (array[i] == number + (owner + 1) * i); } } } REQUIRE(is_valid); REQUIRE(not is_synchronized); } synchronize(weak_edge_array); { // after synchronization auto edge_owner = connectivity.edgeOwner(); bool is_synchronized = true; for (EdgeId i_edge = 0; i_edge < mesh_2d.numberOfEdges(); ++i_edge) { SubArray array = edge_array[i_edge]; const size_t number = edge_number[i_edge]; const size_t owner = edge_owner[i_edge]; for (size_t i = 0; i < array.size(); ++i) { is_synchronized &= (array[i] == number + (owner + 1) * i); } } REQUIRE(is_synchronized); } } SECTION("face") { WeakFaceArray<size_t> weak_face_array{connectivity, 3}; auto face_number = connectivity.faceNumber(); for (FaceId i_face = 0; i_face < mesh_2d.numberOfFaces(); ++i_face) { SubArray array = weak_face_array[i_face]; const size_t number = face_number[i_face]; for (size_t i = 0; i < array.size(); ++i) { array[i] = number + (parallel::rank() + 1) * i; } } FaceArray<const size_t> face_array{weak_face_array}; REQUIRE(face_array.connectivity_ptr() == weak_face_array.connectivity_ptr()); { // before synchronization auto face_owner = connectivity.faceOwner(); auto face_is_owned = connectivity.faceIsOwned(); bool is_synchronized = (parallel::size() > 1); bool is_valid = true; for (FaceId i_face = 0; i_face < mesh_2d.numberOfFaces(); ++i_face) { SubArray array = face_array[i_face]; const size_t number = face_number[i_face]; const size_t owner = face_owner[i_face]; if (face_is_owned[i_face]) { for (size_t i = 0; i < array.size(); ++i) { is_valid &= (array[i] == number + (owner + 1) * i); } } else { for (size_t i = 0; i < array.size(); ++i) { is_synchronized &= (array[i] == number + (owner + 1) * i); } } } REQUIRE(is_valid); REQUIRE(not is_synchronized); } synchronize(weak_face_array); { // after synchronization auto face_owner = connectivity.faceOwner(); bool is_synchronized = true; for (FaceId i_face = 0; i_face < mesh_2d.numberOfFaces(); ++i_face) { SubArray array = face_array[i_face]; const size_t number = face_number[i_face]; const size_t owner = face_owner[i_face]; for (size_t i = 0; i < array.size(); ++i) { is_synchronized &= (array[i] == number + (owner + 1) * i); } } REQUIRE(is_synchronized); } } SECTION("cell") { WeakCellArray<size_t> weak_cell_array{connectivity, 3}; auto cell_number = connectivity.cellNumber(); for (CellId i_cell = 0; i_cell < mesh_2d.numberOfCells(); ++i_cell) { SubArray array = weak_cell_array[i_cell]; const size_t number = cell_number[i_cell]; for (size_t i = 0; i < array.size(); ++i) { array[i] = number + (parallel::rank() + 1) * i; } } CellArray<const size_t> cell_array{weak_cell_array}; REQUIRE(cell_array.connectivity_ptr() == weak_cell_array.connectivity_ptr()); { // before synchronization auto cell_owner = connectivity.cellOwner(); auto cell_is_owned = connectivity.cellIsOwned(); bool is_synchronized = (parallel::size() > 1); bool is_valid = true; for (CellId i_cell = 0; i_cell < mesh_2d.numberOfCells(); ++i_cell) { SubArray array = cell_array[i_cell]; const size_t number = cell_number[i_cell]; const size_t owner = cell_owner[i_cell]; if (cell_is_owned[i_cell]) { for (size_t i = 0; i < array.size(); ++i) { is_valid &= (array[i] == number + (owner + 1) * i); } } else { for (size_t i = 0; i < array.size(); ++i) { is_synchronized &= (array[i] == number + (owner + 1) * i); } } } REQUIRE(is_valid); REQUIRE(not is_synchronized); } synchronize(weak_cell_array); { // after synchronization auto cell_owner = connectivity.cellOwner(); bool is_synchronized = true; for (CellId i_cell = 0; i_cell < mesh_2d.numberOfCells(); ++i_cell) { SubArray array = cell_array[i_cell]; const size_t number = cell_number[i_cell]; const size_t owner = cell_owner[i_cell]; for (size_t i = 0; i < array.size(); ++i) { is_synchronized &= (array[i] == number + (owner + 1) * i); } } REQUIRE(is_synchronized); } } } SECTION("3D") { const Mesh<Connectivity<3>>& mesh_3d = MeshDataBaseForTests::get().cartesianMesh<3>(); const Connectivity<3>& connectivity = mesh_3d.connectivity(); SECTION("node") { WeakNodeArray<size_t> weak_node_array{connectivity, 4}; auto node_number = connectivity.nodeNumber(); for (NodeId i_node = 0; i_node < mesh_3d.numberOfNodes(); ++i_node) { SubArray array = weak_node_array[i_node]; const size_t number = node_number[i_node]; for (size_t i = 0; i < array.size(); ++i) { array[i] = number + (parallel::rank() + 1) * i; } } NodeArray<const size_t> node_array{weak_node_array}; REQUIRE(node_array.connectivity_ptr() == weak_node_array.connectivity_ptr()); { // before synchronization auto node_owner = connectivity.nodeOwner(); auto node_is_owned = connectivity.nodeIsOwned(); bool is_synchronized = (parallel::size() > 1); bool is_valid = true; for (NodeId i_node = 0; i_node < mesh_3d.numberOfNodes(); ++i_node) { SubArray array = node_array[i_node]; const size_t number = node_number[i_node]; const size_t owner = node_owner[i_node]; if (node_is_owned[i_node]) { for (size_t i = 0; i < array.size(); ++i) { is_valid &= (array[i] == number + (owner + 1) * i); } } else { for (size_t i = 0; i < array.size(); ++i) { is_synchronized &= (array[i] == number + (owner + 1) * i); } } } REQUIRE(is_valid); REQUIRE(not is_synchronized); } synchronize(weak_node_array); { // after synchronization auto node_owner = connectivity.nodeOwner(); bool is_synchronized = true; for (NodeId i_node = 0; i_node < mesh_3d.numberOfNodes(); ++i_node) { SubArray array = node_array[i_node]; const size_t number = node_number[i_node]; const size_t owner = node_owner[i_node]; for (size_t i = 0; i < array.size(); ++i) { is_synchronized &= (array[i] == number + (owner + 1) * i); } } REQUIRE(is_synchronized); } } SECTION("edge") { WeakEdgeArray<size_t> weak_edge_array{connectivity, 4}; auto edge_number = connectivity.edgeNumber(); for (EdgeId i_edge = 0; i_edge < mesh_3d.numberOfEdges(); ++i_edge) { SubArray array = weak_edge_array[i_edge]; const size_t number = edge_number[i_edge]; for (size_t i = 0; i < array.size(); ++i) { array[i] = number + (parallel::rank() + 1) * i; } } EdgeArray<const size_t> edge_array{weak_edge_array}; REQUIRE(edge_array.connectivity_ptr() == weak_edge_array.connectivity_ptr()); { // before synchronization auto edge_owner = connectivity.edgeOwner(); auto edge_is_owned = connectivity.edgeIsOwned(); bool is_synchronized = (parallel::size() > 1); bool is_valid = true; for (EdgeId i_edge = 0; i_edge < mesh_3d.numberOfEdges(); ++i_edge) { SubArray array = edge_array[i_edge]; const size_t number = edge_number[i_edge]; const size_t owner = edge_owner[i_edge]; if (edge_is_owned[i_edge]) { for (size_t i = 0; i < array.size(); ++i) { is_valid &= (array[i] == number + (owner + 1) * i); } } else { for (size_t i = 0; i < array.size(); ++i) { is_synchronized &= (array[i] == number + (owner + 1) * i); } } } REQUIRE(is_valid); REQUIRE(not is_synchronized); } synchronize(weak_edge_array); { // after synchronization auto edge_owner = connectivity.edgeOwner(); bool is_synchronized = true; for (EdgeId i_edge = 0; i_edge < mesh_3d.numberOfEdges(); ++i_edge) { SubArray array = edge_array[i_edge]; const size_t number = edge_number[i_edge]; const size_t owner = edge_owner[i_edge]; for (size_t i = 0; i < array.size(); ++i) { is_synchronized &= (array[i] == number + (owner + 1) * i); } } REQUIRE(is_synchronized); } } SECTION("face") { WeakFaceArray<size_t> weak_face_array{connectivity, 4}; auto face_number = connectivity.faceNumber(); for (FaceId i_face = 0; i_face < mesh_3d.numberOfFaces(); ++i_face) { SubArray array = weak_face_array[i_face]; const size_t number = face_number[i_face]; for (size_t i = 0; i < array.size(); ++i) { array[i] = number + (parallel::rank() + 1) * i; } } FaceArray<const size_t> face_array{weak_face_array}; REQUIRE(face_array.connectivity_ptr() == weak_face_array.connectivity_ptr()); { // before synchronization auto face_owner = connectivity.faceOwner(); auto face_is_owned = connectivity.faceIsOwned(); bool is_synchronized = (parallel::size() > 1); bool is_valid = true; for (FaceId i_face = 0; i_face < mesh_3d.numberOfFaces(); ++i_face) { SubArray array = face_array[i_face]; const size_t number = face_number[i_face]; const size_t owner = face_owner[i_face]; if (face_is_owned[i_face]) { for (size_t i = 0; i < array.size(); ++i) { is_valid &= (array[i] == number + (owner + 1) * i); } } else { for (size_t i = 0; i < array.size(); ++i) { is_synchronized &= (array[i] == number + (owner + 1) * i); } } } REQUIRE(is_valid); REQUIRE(not is_synchronized); } synchronize(weak_face_array); { // after synchronization auto face_owner = connectivity.faceOwner(); bool is_synchronized = true; for (FaceId i_face = 0; i_face < mesh_3d.numberOfFaces(); ++i_face) { SubArray array = face_array[i_face]; const size_t number = face_number[i_face]; const size_t owner = face_owner[i_face]; for (size_t i = 0; i < array.size(); ++i) { is_synchronized &= (array[i] == number + (owner + 1) * i); } } REQUIRE(is_synchronized); } } SECTION("cell") { WeakCellArray<size_t> weak_cell_array{connectivity, 4}; auto cell_number = connectivity.cellNumber(); for (CellId i_cell = 0; i_cell < mesh_3d.numberOfCells(); ++i_cell) { SubArray array = weak_cell_array[i_cell]; const size_t number = cell_number[i_cell]; for (size_t i = 0; i < array.size(); ++i) { array[i] = number + (parallel::rank() + 1) * i; } } CellArray<const size_t> cell_array{weak_cell_array}; REQUIRE(cell_array.connectivity_ptr() == weak_cell_array.connectivity_ptr()); { // before synchronization auto cell_owner = connectivity.cellOwner(); auto cell_is_owned = connectivity.cellIsOwned(); bool is_synchronized = (parallel::size() > 1); bool is_valid = true; for (CellId i_cell = 0; i_cell < mesh_3d.numberOfCells(); ++i_cell) { SubArray array = cell_array[i_cell]; const size_t number = cell_number[i_cell]; const size_t owner = cell_owner[i_cell]; if (cell_is_owned[i_cell]) { for (size_t i = 0; i < array.size(); ++i) { is_valid &= (array[i] == number + (owner + 1) * i); } } else { for (size_t i = 0; i < array.size(); ++i) { is_synchronized &= (array[i] == number + (owner + 1) * i); } } } REQUIRE(is_valid); REQUIRE(not is_synchronized); } synchronize(weak_cell_array); { // after synchronization auto cell_owner = connectivity.cellOwner(); bool is_synchronized = true; for (CellId i_cell = 0; i_cell < mesh_3d.numberOfCells(); ++i_cell) { SubArray array = cell_array[i_cell]; const size_t number = cell_number[i_cell]; const size_t owner = cell_owner[i_cell]; for (size_t i = 0; i < array.size(); ++i) { is_synchronized &= (array[i] == number + (owner + 1) * i); } } REQUIRE(is_synchronized); } } } } }