Files
JuliaFEM.jl/test/mesh/test_refine.jl
T
Jukka Aho c544c25830 test(mesh): add mesh refinement test
New 166-line test file for mesh refinement operations:
- Tests single Hex8 refinement at 1, 2, and 3 levels
- Tests rectangular Hex8 refinement (longest edge bisection)
- Tests multiple element refinement
- Tests element set preservation during refinement
- Validates element and node count after refinement
- Validates refinement along longest dimension

Tests LongestEdgeBisection strategy for adaptive mesh refinement.
2025-12-15 08:46:00 +02:00

167 lines
5.9 KiB
Julia
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# This file is a part of JuliaFEM.
# License is MIT: see https://github.com/JuliaFEM/JuliaFEM.jl/blob/master/LICENSE.md
using Test
using JuliaFEM
using Tensors
@testset "Mesh refinement" begin
@testset "Single Hex8 refinement - 1 level" begin
# Create a single hex element: unit cube [0,1]³
nodes = [
Vec(0.0, 0.0, 0.0), Vec(1.0, 0.0, 0.0),
Vec(1.0, 1.0, 0.0), Vec(0.0, 1.0, 0.0),
Vec(0.0, 0.0, 1.0), Vec(1.0, 0.0, 1.0),
Vec(1.0, 1.0, 1.0), Vec(0.0, 1.0, 1.0)
]
connectivity = [(UInt32(1), UInt32(2), UInt32(3), UInt32(4),
UInt32(5), UInt32(6), UInt32(7), UInt32(8))]
mesh = Mesh{Hex8}(nodes, connectivity)
# Refine once
strategy = LongestEdgeBisection(1)
refined = refine(mesh, strategy)
# After 1 refinement: 1 element → 2 elements
@test nelements(refined) == 2
# Should have original 8 nodes + 4 new midpoint nodes = 12 nodes
@test nnodes_total(refined) == 12
# Check that all elements have 8 nodes
for conn in refined.connectivity
@test length(conn) == 8
end
println("1 level refinement: ", nelements(mesh), "", nelements(refined), " elements")
end
@testset "Single Hex8 refinement - 2 levels" begin
# Create a single hex element
nodes = [
Vec(0.0, 0.0, 0.0), Vec(1.0, 0.0, 0.0),
Vec(1.0, 1.0, 0.0), Vec(0.0, 1.0, 0.0),
Vec(0.0, 0.0, 1.0), Vec(1.0, 0.0, 1.0),
Vec(1.0, 1.0, 1.0), Vec(0.0, 1.0, 1.0)
]
connectivity = [(UInt32(1), UInt32(2), UInt32(3), UInt32(4),
UInt32(5), UInt32(6), UInt32(7), UInt32(8))]
mesh = Mesh{Hex8}(nodes, connectivity)
# Refine twice
strategy = LongestEdgeBisection(2)
refined = refine(mesh, strategy)
# After 2 refinements: 1 → 2 → 4 elements
@test nelements(refined) == 4
println("2 level refinement: ", nelements(mesh), "", nelements(refined), " elements")
end
@testset "Single Hex8 refinement - 3 levels" begin
# Create a single hex element
nodes = [
Vec(0.0, 0.0, 0.0), Vec(1.0, 0.0, 0.0),
Vec(1.0, 1.0, 0.0), Vec(0.0, 1.0, 0.0),
Vec(0.0, 0.0, 1.0), Vec(1.0, 0.0, 1.0),
Vec(1.0, 1.0, 1.0), Vec(0.0, 1.0, 1.0)
]
connectivity = [(UInt32(1), UInt32(2), UInt32(3), UInt32(4),
UInt32(5), UInt32(6), UInt32(7), UInt32(8))]
mesh = Mesh{Hex8}(nodes, connectivity)
# Refine 3 times
strategy = LongestEdgeBisection(3)
refined = refine(mesh, strategy)
# After 3 refinements: 1 → 2 → 4 → 8 elements
@test nelements(refined) == 8
println("3 level refinement: ", nelements(mesh), "", nelements(refined), " elements")
end
@testset "Rectangular Hex8 refinement" begin
# Create elongated hex element: [0,2] × [0,1] × [0,1]
# Should split along X first (longest dimension)
nodes = [
Vec(0.0, 0.0, 0.0), Vec(2.0, 0.0, 0.0),
Vec(2.0, 1.0, 0.0), Vec(0.0, 1.0, 0.0),
Vec(0.0, 0.0, 1.0), Vec(2.0, 0.0, 1.0),
Vec(2.0, 1.0, 1.0), Vec(0.0, 1.0, 1.0)
]
connectivity = [(UInt32(1), UInt32(2), UInt32(3), UInt32(4),
UInt32(5), UInt32(6), UInt32(7), UInt32(8))]
mesh = Mesh{Hex8}(nodes, connectivity)
strategy = LongestEdgeBisection(1)
refined = refine(mesh, strategy)
@test nelements(refined) == 2
# Check that split happened along X (should create nodes near x=1.0)
# New nodes should be at midpoints
midpoint_nodes = refined.nodes[9:12] # Last 4 nodes are new
for node in midpoint_nodes
# All midpoint nodes should have x ≈ 1.0 (midpoint of [0,2])
@test node[1] 1.0
end
println("Rectangular refinement along longest dimension successful")
end
@testset "Multiple element refinement" begin
# Create 2 hex elements side by side
nodes = [
Vec(0.0, 0.0, 0.0), Vec(1.0, 0.0, 0.0),
Vec(1.0, 1.0, 0.0), Vec(0.0, 1.0, 0.0),
Vec(0.0, 0.0, 1.0), Vec(1.0, 0.0, 1.0),
Vec(1.0, 1.0, 1.0), Vec(0.0, 1.0, 1.0),
# Second element nodes
Vec(2.0, 0.0, 0.0), Vec(2.0, 1.0, 0.0),
Vec(2.0, 0.0, 1.0), Vec(2.0, 1.0, 1.0)
]
connectivity = [
(UInt32(1), UInt32(2), UInt32(3), UInt32(4),
UInt32(5), UInt32(6), UInt32(7), UInt32(8)),
(UInt32(2), UInt32(9), UInt32(10), UInt32(3),
UInt32(6), UInt32(11), UInt32(12), UInt32(7))
]
mesh = Mesh{Hex8}(nodes, connectivity)
strategy = LongestEdgeBisection(1)
refined = refine(mesh, strategy)
# 2 elements → 4 elements after 1 refinement
@test nelements(refined) == 4
println("Multiple element refinement: ", nelements(mesh), "", nelements(refined), " elements")
end
@testset "Element set preservation" begin
# Create mesh with element sets
nodes = [
Vec(0.0, 0.0, 0.0), Vec(1.0, 0.0, 0.0),
Vec(1.0, 1.0, 0.0), Vec(0.0, 1.0, 0.0),
Vec(0.0, 0.0, 1.0), Vec(1.0, 0.0, 1.0),
Vec(1.0, 1.0, 1.0), Vec(0.0, 1.0, 1.0)
]
connectivity = [(UInt32(1), UInt32(2), UInt32(3), UInt32(4),
UInt32(5), UInt32(6), UInt32(7), UInt32(8))]
element_sets = Dict(:volume => Set(UInt32[1]))
mesh = Mesh{Hex8}(nodes, connectivity, element_sets)
strategy = LongestEdgeBisection(2)
refined = refine(mesh, strategy)
# Element set should be preserved and expanded
@test haskey(refined.element_sets, :volume)
@test length(refined.element_sets[:volume]) == 4 # 1 → 2 → 4 elements
println("Element set preservation: OK")
end
end