mirror of
https://github.com/JuliaFEM/JuliaFEM.jl.git
synced 2026-08-06 04:21:33 +00:00
fc43bd457b
New 137-line test file included in main test/runtests.jl: - Tests extract_strain() function (displacement gradient → strain tensor) - Tests extract_strain_rate() function (velocity gradient → strain rate tensor) - Tests pure extension, shear deformation, and general deformation cases - Tests quasi-static strain rate from increments - Validates symmetric tensor properties and engineering shear strain Ensures strain extraction functions work correctly for continuum mechanics.
138 lines
4.7 KiB
Julia
138 lines
4.7 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 "Strain Extraction" begin
|
|
@testset "extract_strain" begin
|
|
# Pure extension in x-direction
|
|
∇u = Tensor{2,3}((1.1, 0.0, 0.0,
|
|
0.0, 1.0, 0.0,
|
|
0.0, 0.0, 1.0))
|
|
ε = extract_strain(∇u)
|
|
|
|
@test ε isa SymmetricTensor{2,3}
|
|
@test ε[1,1] ≈ 1.1 # ε_xx
|
|
@test ε[2,2] ≈ 1.0 # ε_yy
|
|
@test ε[3,3] ≈ 1.0 # ε_zz
|
|
@test ε[1,2] ≈ 0.0 # ε_xy (symmetric)
|
|
|
|
# Shear deformation
|
|
∇u_shear = Tensor{2,3}((1.0, 0.1, 0.0,
|
|
0.2, 1.0, 0.0,
|
|
0.0, 0.0, 1.0))
|
|
ε_shear = extract_strain(∇u_shear)
|
|
|
|
@test ε_shear[1,1] ≈ 1.0
|
|
@test ε_shear[2,2] ≈ 1.0
|
|
@test ε_shear[1,2] ≈ 0.15 # (0.1 + 0.2) / 2 = 0.15 (engineering shear strain / 2)
|
|
@test ε_shear[2,1] ≈ 0.15 # Symmetric
|
|
|
|
# General deformation
|
|
∇u_general = Tensor{2,3}((1.05, 0.03, 0.02,
|
|
0.04, 1.08, 0.01,
|
|
0.02, 0.03, 1.10))
|
|
ε_general = extract_strain(∇u_general)
|
|
|
|
@test ε_general[1,1] ≈ 1.05
|
|
@test ε_general[2,2] ≈ 1.08
|
|
@test ε_general[3,3] ≈ 1.10
|
|
@test ε_general[1,2] ≈ (0.03 + 0.04) / 2
|
|
@test ε_general[1,3] ≈ (0.02 + 0.02) / 2
|
|
@test ε_general[2,3] ≈ (0.01 + 0.03) / 2
|
|
end
|
|
|
|
@testset "extract_strain_rate" begin
|
|
# Constant strain rate (steady extension)
|
|
∇u̇ = Tensor{2,3}((0.01, 0.0, 0.0,
|
|
0.0, -0.005, 0.0,
|
|
0.0, 0.0, -0.005))
|
|
ε̇ = extract_strain_rate(∇u̇)
|
|
|
|
@test ε̇ isa SymmetricTensor{2,3}
|
|
@test ε̇[1,1] ≈ 0.01 # Extension in x
|
|
@test ε̇[2,2] ≈ -0.005 # Contraction in y (Poisson effect)
|
|
@test ε̇[3,3] ≈ -0.005 # Contraction in z (Poisson effect)
|
|
@test ε̇[1,2] ≈ 0.0
|
|
|
|
# Shear rate
|
|
∇u̇_shear = Tensor{2,3}((0.0, 0.01, 0.0,
|
|
0.02, 0.0, 0.0,
|
|
0.0, 0.0, 0.0))
|
|
ε̇_shear = extract_strain_rate(∇u̇_shear)
|
|
|
|
@test ε̇_shear[1,2] ≈ (0.01 + 0.02) / 2
|
|
@test ε̇_shear[2,1] ≈ (0.01 + 0.02) / 2 # Symmetric
|
|
end
|
|
|
|
@testset "Quasi-static strain rate from increments" begin
|
|
# Simulate quasi-static loading with increments
|
|
Δt = 1.0
|
|
|
|
# Initial configuration
|
|
∇u_old = Tensor{2,3}((1.0, 0.0, 0.0,
|
|
0.0, 1.0, 0.0,
|
|
0.0, 0.0, 1.0))
|
|
|
|
# New configuration after load step
|
|
∇u_new = Tensor{2,3}((1.01, 0.0, 0.0,
|
|
0.0, 0.99, 0.0,
|
|
0.0, 0.0, 0.99))
|
|
|
|
# Compute strain rate from increment
|
|
∇u_rate = (∇u_new - ∇u_old) / Δt
|
|
ε̇_quasi = extract_strain_rate(∇u_rate)
|
|
|
|
@test ε̇_quasi[1,1] ≈ 0.01 # Strain rate from increment
|
|
@test ε̇_quasi[2,2] ≈ -0.01 # Poisson effect
|
|
@test ε̇_quasi[3,3] ≈ -0.01
|
|
|
|
# This is needed for rate-dependent materials even in quasi-static!
|
|
@test ε̇_quasi ≠ zero(SymmetricTensor{2,3})
|
|
end
|
|
|
|
@testset "Type stability" begin
|
|
∇u = Tensor{2,3}((1.1, 0.0, 0.0,
|
|
0.0, 1.0, 0.0,
|
|
0.0, 0.0, 1.0))
|
|
|
|
# Type inference
|
|
@inferred extract_strain(∇u)
|
|
@inferred extract_strain_rate(∇u)
|
|
|
|
# Zero allocations
|
|
ε = extract_strain(∇u) # Warmup
|
|
allocs = @allocated extract_strain(∇u)
|
|
@test allocs == 0
|
|
|
|
ε̇ = extract_strain_rate(∇u) # Warmup
|
|
allocs = @allocated extract_strain_rate(∇u)
|
|
@test allocs == 0
|
|
end
|
|
|
|
@testset "Compatibility with LocalField" begin
|
|
# Test that strain extraction works with LocalField structure
|
|
u = Vec{3}((0.1, 0.2, 0.3))
|
|
∇u = Tensor{2,3}((1.01, 0.02, 0.0,
|
|
0.03, 1.04, 0.0,
|
|
0.0, 0.0, 1.05))
|
|
u̇ = zero(Vec{3})
|
|
∇u̇ = Tensor{2,3}((0.01, 0.0, 0.0,
|
|
0.0, 0.02, 0.0,
|
|
0.0, 0.0, 0.03))
|
|
|
|
u_local = LocalField(u, ∇u, u̇, ∇u̇)
|
|
|
|
# Extract strain from LocalField
|
|
ε = extract_strain(u_local.gradient)
|
|
ε̇ = extract_strain_rate(u_local.gradient_rate)
|
|
|
|
@test ε isa SymmetricTensor{2,3}
|
|
@test ε̇ isa SymmetricTensor{2,3}
|
|
@test ε[1,1] ≈ 1.01
|
|
@test ε̇[1,1] ≈ 0.01
|
|
end
|
|
end
|