From 8f52df8d9b47e5ecd5e2f245ba8ba7735863a0a3 Mon Sep 17 00:00:00 2001 From: Jukka Aho Date: Sat, 9 May 2026 18:28:27 +0300 Subject: [PATCH] chore(test): delete mesh parallel feature stubs Remove unmaintained parallel mesh experiments. - Drop `test/mesh/test_parallel_features.jl`. --- test/mesh/test_parallel_features.jl | 297 ---------------------------- 1 file changed, 297 deletions(-) delete mode 100644 test/mesh/test_parallel_features.jl diff --git a/test/mesh/test_parallel_features.jl b/test/mesh/test_parallel_features.jl deleted file mode 100644 index 88c3edb..0000000 --- a/test/mesh/test_parallel_features.jl +++ /dev/null @@ -1,297 +0,0 @@ -# This file is a part of JuliaFEM. -# License is MIT: see https://github.com/JuliaFEM/JuliaFEM.jl/blob/master/LICENSE.md - -using Test -using Tensors - -# Mock topology types -abstract type AbstractTopology end -struct Tet4 <: AbstractTopology end -nnodes(::Type{Tet4}) = 4 - -# Include mesh implementation -include("../src/mesh/mesh.jl") - -@testset "Mesh Parallel Features - Naming, Coloring, Permutation, Ghosts" begin - - # Setup: Create a simple two-element mesh - function make_test_mesh() - nodes = [ - Vec(0.0, 0.0, 0.0), # 1 - Vec(1.0, 0.0, 0.0), # 2 - Vec(0.0, 1.0, 0.0), # 3 - Vec(0.0, 0.0, 1.0), # 4 - Vec(1.0, 1.0, 0.0) # 5 - ] - connectivity = [ - (UInt32(1), UInt32(2), UInt32(3), UInt32(4)), # Element 1 - (UInt32(2), UInt32(5), UInt32(3), UInt32(4)) # Element 2 - ] - return Mesh{Tet4}(nodes, connectivity) - end - - @testset "Node Naming - Industrial ID Ranges" begin - mesh = make_test_mesh() - - # Assign industrial ID ranges (part 1: 10M+, part 2: 20M+) - set_node_id!(mesh, UInt32(1), 10_000_001) - set_node_id!(mesh, UInt32(2), 10_000_002) - set_node_id!(mesh, UInt32(3), 20_000_001) - - # Retrieve by ID - @test get_node_by_id(mesh, 10_000_001) == UInt32(1) - @test get_node_by_id(mesh, 10_000_002) == UInt32(2) - @test get_node_by_id(mesh, 20_000_001) == UInt32(3) - - # Non-existent ID should error - @test_throws AssertionError get_node_by_id(mesh, 99999) - end - - @testset "Node Naming - Symbolic Names (Code Aster Style)" begin - mesh = make_test_mesh() - - # Assign symbolic names - set_node_id!(mesh, UInt32(1), :N1) - set_node_id!(mesh, UInt32(2), :N2) - set_node_id!(mesh, UInt32(5), :corner_node) - - # Retrieve by symbol - @test get_node_by_id(mesh, :N1) == UInt32(1) - @test get_node_by_id(mesh, :N2) == UInt32(2) - @test get_node_by_id(mesh, :corner_node) == UInt32(5) - - # Non-existent symbol should error - @test_throws AssertionError get_node_by_id(mesh, :nonexistent) - end - - @testset "Element Naming - Industrial ID Ranges" begin - mesh = make_test_mesh() - - # Assign element IDs - set_element_id!(mesh, UInt32(1), 30_000_001) - set_element_id!(mesh, UInt32(2), 30_000_002) - - # Retrieve by ID - @test get_element_by_id(mesh, 30_000_001) == UInt32(1) - @test get_element_by_id(mesh, 30_000_002) == UInt32(2) - - # Non-existent ID should error - @test_throws AssertionError get_element_by_id(mesh, 99999) - end - - @testset "Element Naming - Symbolic Names" begin - mesh = make_test_mesh() - - # Assign symbolic names - set_element_id!(mesh, UInt32(1), :E1) - set_element_id!(mesh, UInt32(2), :E2) - - # Retrieve by symbol - @test get_element_by_id(mesh, :E1) == UInt32(1) - @test get_element_by_id(mesh, :E2) == UInt32(2) - end - - @testset "Node Coloring - Load Balancing" begin - mesh = make_test_mesh() - - # Initially all nodes uncolored (color = 0) - for i in 1:nnodes_total(mesh) - @test get_node_color(mesh, UInt32(i)) == UInt32(0) - end - - # Assign nodes to MPI ranks (colors 1-4) - for i in 1:nnodes_total(mesh) - rank = mod(i - 1, 4) + 1 # Round-robin: 1,2,3,4,1 - set_node_color!(mesh, UInt32(i), UInt32(rank)) - end - - # Verify colors - @test get_node_color(mesh, UInt32(1)) == UInt32(1) - @test get_node_color(mesh, UInt32(2)) == UInt32(2) - @test get_node_color(mesh, UInt32(3)) == UInt32(3) - @test get_node_color(mesh, UInt32(4)) == UInt32(4) - @test get_node_color(mesh, UInt32(5)) == UInt32(1) - end - - @testset "Element Coloring - Graph Coloring for Threading" begin - mesh = make_test_mesh() - - # Initially all elements uncolored - @test get_element_color(mesh, UInt32(1)) == UInt32(0) - @test get_element_color(mesh, UInt32(2)) == UInt32(0) - - # Assign colors (elements sharing nodes get different colors) - set_element_color!(mesh, UInt32(1), UInt32(1)) - set_element_color!(mesh, UInt32(2), UInt32(2)) # Shares nodes with elem 1 - - # Verify colors - @test get_element_color(mesh, UInt32(1)) == UInt32(1) - @test get_element_color(mesh, UInt32(2)) == UInt32(2) - - # Get elements by color - color1_elems = get_elements_with_color(mesh, UInt32(1)) - color2_elems = get_elements_with_color(mesh, UInt32(2)) - - @test UInt32(1) in color1_elems - @test UInt32(2) in color2_elems - @test length(color1_elems) == 1 - @test length(color2_elems) == 1 - end - - @testset "Ghost Nodes - MPI Domain Decomposition" begin - mesh = make_test_mesh() - - # Initially no ghost nodes - @test !is_ghost_node(mesh, UInt32(1)) - @test !is_ghost_node(mesh, UInt32(2)) - - # Mark nodes 2,3,4 as ghosts (owned by another rank) - mark_ghost_node!(mesh, UInt32(2)) - mark_ghost_node!(mesh, UInt32(3)) - mark_ghost_node!(mesh, UInt32(4)) - - # Verify ghost status - @test !is_ghost_node(mesh, UInt32(1)) # Local - @test is_ghost_node(mesh, UInt32(2)) # Ghost - @test is_ghost_node(mesh, UInt32(3)) # Ghost - @test is_ghost_node(mesh, UInt32(4)) # Ghost - @test !is_ghost_node(mesh, UInt32(5)) # Local - - # Get local nodes (non-ghost) - local_nodes = get_local_nodes(mesh) - @test UInt32(1) in local_nodes - @test UInt32(5) in local_nodes - @test !(UInt32(2) in local_nodes) - @test !(UInt32(3) in local_nodes) - @test !(UInt32(4) in local_nodes) - @test length(local_nodes) == 2 - end - - @testset "Ghost Elements - MPI Domain Decomposition" begin - mesh = make_test_mesh() - - # Initially no ghost elements - @test !is_ghost_element(mesh, UInt32(1)) - @test !is_ghost_element(mesh, UInt32(2)) - - # Mark element 2 as ghost - mark_ghost_element!(mesh, UInt32(2)) - - # Verify ghost status - @test !is_ghost_element(mesh, UInt32(1)) # Local - @test is_ghost_element(mesh, UInt32(2)) # Ghost - - # Get local elements - local_elems = get_local_elements(mesh) - @test UInt32(1) in local_elems - @test !(UInt32(2) in local_elems) - @test length(local_elems) == 1 - end - - @testset "Node Permutation - Identity (Initial State)" begin - mesh = make_test_mesh() - - # Initially identity permutation - for i in 1:nnodes_total(mesh) - @test mesh.node_permutation[i] == UInt32(i) - @test mesh.node_inverse_permutation[i] == UInt32(i) - end - - # Forward and inverse should be consistent - for i in 1:nnodes_total(mesh) - j = get_reordered_node_index(mesh, UInt32(i)) - @test get_original_node_index(mesh, j) == UInt32(i) - end - end - - @testset "Node Permutation - Custom Reordering" begin - mesh = make_test_mesh() - - # Apply custom permutation (reverse order for simplicity) - n = nnodes_total(mesh) - perm = UInt32[n, n-1, n-2, n-3, n-4] # [5, 4, 3, 2, 1] - apply_node_permutation!(mesh, perm) - - # Verify permutation - @test mesh.node_permutation == perm - - # Verify inverse permutation - @test mesh.node_inverse_permutation == UInt32[5, 4, 3, 2, 1] - - # Check forward mapping: original 1 → reordered 5 - @test get_reordered_node_index(mesh, UInt32(1)) == UInt32(5) - @test get_reordered_node_index(mesh, UInt32(5)) == UInt32(1) - - # Check inverse mapping: reordered 1 → original 5 - @test get_original_node_index(mesh, UInt32(1)) == UInt32(5) - @test get_original_node_index(mesh, UInt32(5)) == UInt32(1) - - # Verify consistency - for i in 1:n - j = get_reordered_node_index(mesh, UInt32(i)) - @test get_original_node_index(mesh, j) == UInt32(i) - end - end - - @testset "Node Permutation - Invalid Permutation" begin - mesh = make_test_mesh() - - # Wrong size - @test_throws AssertionError apply_node_permutation!(mesh, UInt32[1, 2]) - - # Invalid permutation (duplicate) - @test_throws AssertionError apply_node_permutation!(mesh, UInt32[1, 1, 2, 3, 4]) - - # Invalid permutation (out of range) - @test_throws AssertionError apply_node_permutation!(mesh, UInt32[1, 2, 3, 4, 6]) - end - - @testset "Element Permutation - Cache Optimization" begin - mesh = make_test_mesh() - - # Initially identity - @test mesh.element_permutation == UInt32[1, 2] - - # Apply custom permutation (swap elements) - perm = UInt32[2, 1] - apply_element_permutation!(mesh, perm) - - # Verify permutation - @test mesh.element_permutation == perm - end - - @testset "Combined Features - Industrial Workflow" begin - mesh = make_test_mesh() - - # 1. Assign industrial IDs (multi-part assembly) - set_node_id!(mesh, UInt32(1), 10_000_001) - set_node_id!(mesh, UInt32(2), 10_000_002) - set_node_id!(mesh, UInt32(3), 20_000_001) # Part 2 starts here - - set_element_id!(mesh, UInt32(1), 30_000_001) - set_element_id!(mesh, UInt32(2), 30_000_002) - - # 2. Apply bandwidth minimization (RCM-like) - perm = UInt32[2, 1, 3, 4, 5] # Simulated RCM result - apply_node_permutation!(mesh, perm) - - # 3. Color elements for parallel assembly - set_element_color!(mesh, UInt32(1), UInt32(1)) - set_element_color!(mesh, UInt32(2), UInt32(2)) - - # 4. Mark ghost nodes (MPI partitioning) - mark_ghost_node!(mesh, UInt32(3)) - mark_ghost_node!(mesh, UInt32(4)) - - # Verify everything works together - @test get_node_by_id(mesh, 10_000_001) == UInt32(1) - @test get_element_by_id(mesh, 30_000_001) == UInt32(1) - @test get_reordered_node_index(mesh, UInt32(1)) == UInt32(2) - @test get_element_color(mesh, UInt32(1)) == UInt32(1) - @test is_ghost_node(mesh, UInt32(3)) - @test length(get_local_nodes(mesh)) == 3 # 5 nodes - 2 ghosts = 3 local - end - -end - -println("✅ All parallel features tests passed!")