Skip to content

Commit b91d6e2

Browse files
committed
Add tests for, and fix, finite strain stress iterations
1 parent 93e4475 commit b91d6e2

File tree

5 files changed

+84
-12
lines changed

5 files changed

+84
-12
lines changed

src/stressiterations.jl

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -234,11 +234,11 @@ const State1D = Union{UniaxialStrain, UniaxialStress}
234234
# Translate from reduced dim input to full tensors
235235
expand_tensordim(::AbstractStressState, a::Tensors.AllTensors{3}) = a
236236
#expand_tensordim(::AbstractStressState, v::Vec{dim,T}) where {dim,T} = Vec{3,T}(i->i>dim ? zero(T) : v[i])
237-
function expand_tensordim(::AbstractStressState, a::Tensor{2,dim,T}) where {dim,T}
238-
return Tensor{2,3}((i,j)-> (i<=dim && j<=dim) ? a[i,j] : zero(T))
237+
function expand_tensordim(::AbstractStressState, F::Tensor{2,dim,T}) where {dim,T}
238+
return Tensor{2,3}((i,j)-> (i<=dim && j<=dim) ? F[i,j] : (i == j ? one(T) : zero(T)))
239239
end
240-
function expand_tensordim(::AbstractStressState, a::SymmetricTensor{2,dim,T}) where {dim,T}
241-
return SymmetricTensor{2,3}((i,j)-> (i<=dim && j<=dim) ? a[i,j] : zero(T))
240+
function expand_tensordim(::AbstractStressState, ϵ::SymmetricTensor{2,dim,T}) where {dim,T}
241+
return SymmetricTensor{2,3}((i,j)-> (i<=dim && j<=dim) ? ϵ[i,j] : zero(T))
242242
end
243243

244244
# Translate from full tensors to reduced output

src/vector_conversion.jl

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,10 @@
44
55
Return the type of the primary input (strain-like) and associated output (stress-like)
66
to the material model. The default is `SymmetricTensor{2, 3}` for small-strain material
7-
models in 3D, but typically, it can be
8-
* Small strain material model: `SymmetricTensor{2, dim}`
9-
* Large strain material model: `Tensor{2, dim}`
10-
* Traction-separation law: `Vec{dim}`
7+
models in 3D, but it can be
8+
* Small strain material model: Small strain tensor, `ϵ::SymmetricTensor{2, dim}`
9+
* Large strain material model: Deformation gradient, `F::Tensor{2, dim}`
10+
* Traction-separation law: Displacement jump, `Δu::Vec{dim}`
1111
1212
Where `dim = 3` is most common, but any value, 1, 2, or 3, is valid.
1313
"""

test/TestMaterials.jl

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,7 @@ using Tensors, StaticArrays, ForwardDiff
66
import MaterialModelsBase as MMB
77

88
# Exported materials
9-
export LinearElastic, ViscoElastic
10-
# Todo: Also NeoHookean to test nonlinear geometric materials
9+
#export LinearElastic, ViscoElastic
1110

1211
# LinearElastic material
1312
struct LinearElastic{T} <: AbstractMaterial

test/runtests.jl

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,42 @@ using Tensors, StaticArrays
44

55
const MMB = MaterialModelsBase
66

7+
# <temporary, move to TestMaterials>
8+
@kwdef struct StVenant{T} <: AbstractMaterial
9+
G::T
10+
K::T
11+
end
12+
function MMB.material_response(m::StVenant, F::Tensor{2,3}, old, args...)
13+
function free_energy(defgrad)
14+
E = (tdot(defgrad) - one(defgrad)) / 2
15+
Edev = dev(E)
16+
return m.G * Edev Edev + m.K * tr(E)^2 / 2
17+
end
18+
∂P∂F, P, _ = hessian(free_energy, F, :all)
19+
return P, ∂P∂F, old
20+
end
21+
22+
@kwdef struct NeoHooke{T} <: AbstractMaterial
23+
G::T
24+
K::T
25+
end
26+
function MMB.material_response(m::NeoHooke, F::Tensor{2,3}, old, args...)
27+
function free_energy(defgrad)
28+
C = tdot(defgrad)
29+
detC = det(C)
30+
ΨG = (m.G / 2) * (tr(C) / cbrt(detC) - 3)
31+
ΨK = (m.K / 2) * (sqrt(detC) - 1)^2
32+
return ΨG + ΨK
33+
end
34+
∂P∂F, P, _ = hessian(free_energy, F, :all)
35+
return P, ∂P∂F, old
36+
end
37+
38+
MMB.get_tensorbase(::Union{StVenant, NeoHooke}) = Tensor{2,3}
39+
# </temporary>
40+
741
include("TestMaterials.jl")
8-
using .TestMaterials
42+
using .TestMaterials: LinearElastic, ViscoElastic
943
include("utils4testing.jl")
1044

1145
include("vector_conversion.jl")

test/stressiterations.jl

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,11 @@ iter_mandel = ( ([2,3,4,5,6,7,8,9],[2,3,4,5,6]),
1616
ared = rand(TT{2,_getdim(stress_state)})
1717
afull = MMB.expand_tensordim(stress_state, ared)
1818
@test _getdim(afull) == 3 # Full dimensional tensor
19-
@test norm(ared) norm(afull) # Only add zeros
19+
if TT == SymmetricTensor
20+
@test norm(ared) norm(afull) # Only add zeros
21+
else # Add ones to diagonal
22+
@test sqrt(norm(ared)^2 + (3 - _getdim(ared))) norm(afull)
23+
end
2024
# Test invertability of conversions
2125
@test ared MMB.reduce_tensordim(stress_state, afull)
2226
end
@@ -137,6 +141,41 @@ end
137141
@test ϵfull_w == ϵfull
138142
end
139143

144+
@testset "hyperelastic" begin
145+
G = 80.e3 # Shear modulus (μ)
146+
K = 160.e3 # Bulk modulus
147+
E = 9*K*G/(3*K+G) # Young's modulus
148+
ν = E/2G - 1 # Poisson's ratio
149+
λ = K - 2G/3 # Lame parameter
150+
151+
Δϵ = 1e-6 # Small strain to compare with linear case
152+
rtol = 1e-5 # Relative tolerance to compare with linear case
153+
@testset for m in (StVenant(;G, K), NeoHooke(;G, K))
154+
old = initial_material_state(m)
155+
# UniaxialStress
156+
P, dPdF, state, Ffull = material_response(UniaxialStress(), m, Tensor{2,1}((1 + Δϵ,)), old, 0.0)
157+
@test isapprox(P[1,1], E*Δϵ; rtol)
158+
@test isapprox(dPdF[1,1,1,1], E; rtol)
159+
@test Ffull[2,2] Ffull[3,3]
160+
@test Ffull[2,2] 1-ν*Δϵ
161+
162+
# UniaxialStrain
163+
P, dPdF, state, Ffull = material_response(UniaxialStrain(), m, Tensor{2,1}((1 + Δϵ,)), old, 0.0)
164+
@test isapprox(P[1,1], (2G+λ)*Δϵ; rtol)
165+
@test isapprox(dPdF[1,1,1,1], (2G+λ); rtol)
166+
P_full, dPdF_full, _ = material_response(m, Ffull, old, 0.0)
167+
@test isapprox(P_full[2,2], λ*Δϵ; rtol)
168+
169+
# PlaneStress
170+
ϵ = Δϵ * rand(SymmetricTensor{2,2})
171+
F = one(Tensor{2,2}) + ϵ
172+
P, dPdF, state, Ffull = material_response(PlaneStress(), m, F, old, 0.0)
173+
Dvoigt = (E/(1-ν^2))*[1 ν 0; ν 1 0; 0 0 (1-ν)/2]
174+
@test isapprox(tovoigt(symmetric(dPdF)), Dvoigt; rtol)
175+
@test isapprox(P, fromvoigt(SymmetricTensor{4,2}, Dvoigt)ϵ; rtol)
176+
end
177+
end
178+
140179
@testset "visco_elastic" begin
141180
# Test a nonlinear, state and rate dependent, material by running stress iterations.
142181
# Check that state variables and time dependence are handled correctly

0 commit comments

Comments
 (0)