mirror of
https://github.com/JuliaFEM/JuliaFEM.jl.git
synced 2026-09-10 04:50:49 +00:00
c544c25830
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.
167 lines
5.9 KiB
Julia
167 lines
5.9 KiB
Julia
# 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
|