test(materials): add global material cache test

New 98-line test file included in main test/runtests.jl:
- Tests GlobalMaterialCache construction for stateless and stateful materials
- Tests state access and update operations (get_state, set_state!, update_cache!, reset_cache!)
- Tests state variable helpers (get_state_variable, set_state_variable)
- Tests integration with material traits (create_global_material_cache)
- Validates cache structure and state management for time-dependent materials

Ensures material cache system works correctly for storing state variables at integration points.
This commit is contained in:
Jukka Aho
2025-12-15 06:36:03 +02:00
parent e3527dac93
commit b5772b141b
@@ -0,0 +1,98 @@
# 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 "Global Material Cache" begin
@testset "Basic construction" begin
# Test stateless material
mat = LinearElastic(E=210e9, ν=0.3)
cache = create_global_material_cache(mat, n_ips=4, n_elems=10)
@test cache isa GlobalMaterialCache
@test size(cache.states) == (4, 10)
@test size(cache.states_old) == (4, 10)
# All states should be empty NamedTuple for stateless
for elem_id in 1:10, ip in 1:4
@test get_state(cache, ip, elem_id) === NamedTuple()
@test get_old_state(cache, ip, elem_id) === NamedTuple()
end
end
@testset "State access and update" begin
# Create a simple stateful cache
StateType = NamedTuple{(,), Tuple{Float64}}
cache = GlobalMaterialCache{StateType}(2, 3) # 2 IPs, 3 elements
# Test initial zeros
@test get_state(cache, 1, 1).κ == 0.0
@test get_state(cache, 2, 3).κ == 0.0
# Set a state
set_state!(cache, 1, 2, (κ=0.5,))
@test get_state(cache, 1, 2).κ == 0.5
@test get_old_state(cache, 1, 2).κ == 0.0 # Old unchanged
# Update cache (copy current → old)
update_cache!(cache)
@test get_old_state(cache, 1, 2).κ == 0.5 # Now matches current
# Modify current
set_state!(cache, 1, 2, (κ=0.8,))
@test get_state(cache, 1, 2).κ == 0.8
@test get_old_state(cache, 1, 2).κ == 0.5 # Still from previous step
# Reset
reset_cache!(cache)
@test get_state(cache, 1, 2).κ == 0.0
@test get_old_state(cache, 1, 2).κ == 0.0
end
@testset "State variable helpers" begin
# Create cache with plasticity-like state
StateType = NamedTuple{(:ε_p, :α, ), Tuple{SymmetricTensor{2,3,Float64,6}, SymmetricTensor{2,3,Float64,6}, Float64}}
cache = GlobalMaterialCache{StateType}(1, 1)
# Set a complex state
ε_p_val = SymmetricTensor{2,3}((0.001, 0.0, 0.0, 0.0, 0.0, 0.0))
α_val = SymmetricTensor{2,3}((100e6, 0.0, 0.0, 0.0, 0.0, 0.0))
κ_val = 0.01
state = (ε_p=ε_p_val, α=α_val, κ=κ_val)
set_state!(cache, 1, 1, state)
# Get state and extract variables
retrieved_state = get_state(cache, 1, 1)
extracted_ε_p = get_state_variable(retrieved_state, PlasticStrain)
extracted_α = get_state_variable(retrieved_state, Backstress)
extracted_κ = get_state_variable(retrieved_state, EquivalentPlasticStrain)
@test extracted_ε_p == ε_p_val
@test extracted_α == α_val
@test extracted_κ == κ_val
# Test immutable update
new_κ = 0.02
new_state = set_state_variable(retrieved_state, EquivalentPlasticStrain, new_κ)
@test new_state.κ == new_κ
@test new_state.ε_p == ε_p_val # Unchanged
@test new_state.α == α_val # Unchanged
# Original unchanged (immutable)
@test retrieved_state.κ == κ_val
end
@testset "Integration with traits" begin
# Verify that cache creation uses material traits correctly
mat = LinearElastic(E=210e9, ν=0.3)
# Material should be stateless
@test required_state_variables(mat) === ()
# Cache should be empty
cache = create_global_material_cache(mat, n_ips=2, n_elems=5)
@test cache isa GlobalMaterialCache{NamedTuple{(),Tuple{}}}
end
end