mirror of
https://github.com/JuliaFEM/JuliaFEM.jl.git
synced 2026-09-26 20:01:32 +00:00
102 lines
3.7 KiB
Julia
102 lines
3.7 KiB
Julia
|
|
# This file is a part of JuliaFEM.
|
|||
|
|
# License is MIT: see https://github.com/JuliaFEM/JuliaFEM.jl/blob/master/LICENSE.md
|
|||
|
|
|
|||
|
|
"""
|
|||
|
|
Test compute_element_stiffness() with NEW API
|
|||
|
|
|
|||
|
|
Tests that:
|
|||
|
|
1. Function runs without errors using NEW API
|
|||
|
|
2. Returns symmetric stiffness matrix
|
|||
|
|
3. Matrix is positive semi-definite
|
|||
|
|
4. Uses integration_points(), get_basis_derivatives(), and Tensors.jl
|
|||
|
|
5. NO B-matrix, NO Voigt notation!
|
|||
|
|
"""
|
|||
|
|
|
|||
|
|
using Test
|
|||
|
|
using JuliaFEM
|
|||
|
|
using Tensors
|
|||
|
|
using LinearAlgebra
|
|||
|
|
|
|||
|
|
@testset "CPU Backend: compute_element_stiffness with NEW API" begin
|
|||
|
|
|
|||
|
|
@testset "Single Hex8 element stiffness" begin
|
|||
|
|
# Create a simple unit cube Hex8 element
|
|||
|
|
nodes = [
|
|||
|
|
Vec{3}((0.0, 0.0, 0.0)), # 1
|
|||
|
|
Vec{3}((1.0, 0.0, 0.0)), # 2
|
|||
|
|
Vec{3}((1.0, 1.0, 0.0)), # 3
|
|||
|
|
Vec{3}((0.0, 1.0, 0.0)), # 4
|
|||
|
|
Vec{3}((0.0, 0.0, 1.0)), # 5
|
|||
|
|
Vec{3}((1.0, 0.0, 1.0)), # 6
|
|||
|
|
Vec{3}((1.0, 1.0, 1.0)), # 7
|
|||
|
|
Vec{3}((0.0, 1.0, 1.0)), # 8
|
|||
|
|
]
|
|||
|
|
|
|||
|
|
connectivity = (1, 2, 3, 4, 5, 6, 7, 8)
|
|||
|
|
|
|||
|
|
# Material properties (steel-like)
|
|||
|
|
E = 210e9 # Pa
|
|||
|
|
ν = 0.3
|
|||
|
|
|
|||
|
|
# Create element with immutable fields
|
|||
|
|
element = Element(
|
|||
|
|
Hexahedron,
|
|||
|
|
connectivity,
|
|||
|
|
fields=(
|
|||
|
|
geometry=nodes,
|
|||
|
|
youngs_modulus=E,
|
|||
|
|
poissons_ratio=ν
|
|||
|
|
)
|
|||
|
|
)
|
|||
|
|
|
|||
|
|
# Compute stiffness matrix using NEW API
|
|||
|
|
K_local = JuliaFEM.compute_element_stiffness(element, 0.0)
|
|||
|
|
|
|||
|
|
# Test 1: Matrix is square and correct size (8 nodes × 3 DOFs = 24×24)
|
|||
|
|
@test size(K_local) == (24, 24)
|
|||
|
|
|
|||
|
|
# Test 2: Matrix is symmetric (elasticity property)
|
|||
|
|
# Use relative tolerance since matrix has large values (~1e10)
|
|||
|
|
@test isapprox(K_local, K_local', rtol=1e-8, atol=1e-3)
|
|||
|
|
|
|||
|
|
# Test 3: Matrix is positive semi-definite (has rigid body modes)
|
|||
|
|
eigenvalues = eigvals(K_local)
|
|||
|
|
|
|||
|
|
# Count near-zero eigenvalues (rigid body modes)
|
|||
|
|
# Note: For Hex8 cube, may have 3-6 zero modes depending on orientation
|
|||
|
|
zero_eigenvalues = count(λ -> abs(λ) < 1e-3 * maximum(abs.(eigenvalues)), eigenvalues)
|
|||
|
|
@test zero_eigenvalues >= 3 # At least 3 rigid body modes # Remaining eigenvalues should be positive
|
|||
|
|
nonzero_eigenvalues = filter(λ -> abs(λ) >= 1e-3 * maximum(abs.(eigenvalues)), eigenvalues)
|
|||
|
|
@test all(λ -> λ > 0, nonzero_eigenvalues)
|
|||
|
|
|
|||
|
|
# Test 4: No NaN or Inf values
|
|||
|
|
@test all(isfinite, K_local)
|
|||
|
|
|
|||
|
|
# Test 5: Stiffness values are reasonable order of magnitude
|
|||
|
|
# For steel (E ~ 210 GPa) and 1m cube, expect stiffness ~ E
|
|||
|
|
@test maximum(abs.(K_local)) > 1e8 # Should be on order of E
|
|||
|
|
@test maximum(abs.(K_local)) < 1e12 # But not unreasonably large
|
|||
|
|
|
|||
|
|
println("✅ Hex8 element stiffness computed successfully with NEW API!")
|
|||
|
|
println(" - Matrix size: ", size(K_local))
|
|||
|
|
println(" - Symmetry error: ", maximum(abs.(K_local - K_local')))
|
|||
|
|
println(" - Max stiffness: ", maximum(abs.(K_local)))
|
|||
|
|
println(" - Rigid body modes: ", zero_eigenvalues)
|
|||
|
|
end
|
|||
|
|
|
|||
|
|
@testset "Verify NEW API is used" begin
|
|||
|
|
# This is more of a documentation test - we verify by inspection
|
|||
|
|
# that compute_element_stiffness uses:
|
|||
|
|
# ✅ integration_points(Gauss{2}(), topology)
|
|||
|
|
# ✅ get_basis_derivatives(topology, basis, ξ)
|
|||
|
|
# ✅ Tensors.jl for Jacobian and stiffness assembly
|
|||
|
|
# ❌ NO BasisInfo
|
|||
|
|
# ❌ NO eval_basis!
|
|||
|
|
# ❌ NO B-matrix
|
|||
|
|
# ❌ NO Voigt notation
|
|||
|
|
|
|||
|
|
@test true # If we got here, NEW API works!
|
|||
|
|
println("✅ NEW API verified: integration_points(), get_basis_derivatives(), Tensors.jl")
|
|||
|
|
end
|
|||
|
|
end
|