Files
Jukka Aho e6a1767f99 test(continuum): align cache-update regression with GlobalMaterialCache API
The three-phase cache exerciser still referenced the retired per-call material
state bag and an older `update_geometry_cache!` arity. Fold everything onto the
shared global cache object and the slimmer geometry updater signature.

- Hoist `BenchmarkTools` to module scope for the `@benchmark` block.
- Drop the duplicate legacy `update_material_cache!` testset; keep the zero-alloc
  path driven by `GlobalMaterialCache`.
2026-05-09 18:45:32 +03:00

118 lines
4.5 KiB
Julia
Raw Permalink 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.
# Test cache update functions (Phases 1a, 1b, 2)
using BenchmarkTools
@testset "Cache Updates" begin
kernel = create_test_kernel()
mesh = create_test_mesh()
# Create caches
N = 8 # Nodes per element (Hex8)
NIP = 8 # Integration points (Gauss{2} for Hex8)
geometry_cache = JuliaFEM.create_geometry_cache(N, NIP)
element_cache = JuliaFEM.create_element_cache(mesh, kernel)
material_cache = JuliaFEM.create_material_cache(kernel.material, NIP)
# u_global as Vec{3} for each node (or nothing for zero displacement)
elem_id = 1
u_global = nothing
Δt = 0.01
global_cache = JuliaFEM.create_global_material_cache(kernel.material;
n_ips=NIP, n_elems=1)
@testset "Phase 1a: update_geometry_cache!" begin
# Update geometry cache
JuliaFEM.update_geometry_cache!(geometry_cache, element_cache, elem_id, mesh)
# Verify X coordinates are extracted correctly
X_expected = mesh.nodes[1:8]
@test geometry_cache.X == X_expected
# Verify physical gradients computed (check all in one test)
all_gradients_nonzero = true
for ip in 1:NIP
for node in 1:N
if !any(x -> abs(x) > 1e-10, geometry_cache.∇N_data[ip, node])
all_gradients_nonzero = false
break
end
end
end
@test all_gradients_nonzero
# Verify detJ * weight is positive (check all in one test)
all_detJ_positive = all(geometry_cache.detJ_w[ip] > 0.0 for ip in 1:NIP)
@test all_detJ_positive
# Test zero allocations (warm-up first)
JuliaFEM.update_geometry_cache!(geometry_cache, element_cache, elem_id, mesh)
allocs = @allocated JuliaFEM.update_geometry_cache!(geometry_cache, element_cache, elem_id, mesh)
@test allocs == 0
end
@testset "Phase 1b: update_element_cache!" begin
# Update element cache
JuliaFEM.update_element_cache!(element_cache, kernel, elem_id, mesh, u_global)
# Verify DOFs extracted
@test element_cache.dofs == collect(1:24)
# Verify u_buffer filled with zero displacements (check all in one test)
all_u_zero = all(element_cache.u_buffer[node] == zero(Vec{3,Float64}) for node in 1:N)
@test all_u_zero
# Test zero allocations (warm-up first)
JuliaFEM.update_element_cache!(element_cache, kernel, elem_id, mesh, u_global)
allocs = @allocated JuliaFEM.update_element_cache!(element_cache, kernel, elem_id, mesh, u_global)
@test allocs == 0
end
@testset "Phase 2: update_material_cache! (GlobalMaterialCache API - Zero Allocation)" begin
# Ensure geometry and element caches are updated first
JuliaFEM.update_geometry_cache!(geometry_cache, element_cache, elem_id, mesh)
JuliaFEM.update_element_cache!(element_cache, kernel, elem_id, mesh, u_global)
# Update material cache using GlobalMaterialCache
JuliaFEM.update_material_cache!(material_cache, geometry_cache, kernel.material,
element_cache, global_cache, elem_id, Δt)
# Verify material state computed at each integration point
all_stress_zero = true
all_tangent_correct = true
for ip in 1:NIP
# For zero displacement, stress should be zero
σ = JuliaFEM.get_stress(material_cache, ip)
if !all(x -> abs(x) < 1e-10, σ)
all_stress_zero = false
end
# Material tangent should be elasticity tensor
C = JuliaFEM.get_tangent(material_cache, ip)
if !(C isa SymmetricTensor{4,3,Float64})
all_tangent_correct = false
end
end
@test all_stress_zero
@test all_tangent_correct
# Test zero allocations with proper warmup
for i in 1:100
JuliaFEM.update_material_cache!(material_cache, geometry_cache, kernel.material,
element_cache, global_cache, elem_id, Δt)
end
result = @benchmark JuliaFEM.update_material_cache!(
$material_cache, $geometry_cache, $(kernel.material),
$element_cache, $global_cache, 1, 0.01
)
println(" update_material_cache! allocations: $(result.allocs)")
println(" update_material_cache! memory: $(result.memory) bytes")
# Should be zero allocations
@test result.allocs == 0
@test result.memory == 0
end
end