Skip to content

Commit b676775

Browse files
authored
Fix issue with singular matrix for finite strain uniaxial response (#20)
1 parent 2defce2 commit b676775

7 files changed

Lines changed: 365 additions & 255 deletions

File tree

Project.toml

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,29 @@
11
name = "MaterialModelsBase"
22
uuid = "af893363-701d-44dc-8b1e-d9a2c129bfc9"
3+
version = "0.4"
34
authors = ["Knut Andreas Meyer and contributors"]
4-
version = "0.3.1"
55

66
[deps]
77
ForwardDiff = "f6369f11-7733-5829-9624-2563aa707210"
88
StaticArrays = "90137ffa-7385-5640-81b9-e52037218182"
99
Tensors = "48a634ad-e948-5137-8d70-aa71f2a747f4"
1010

11+
[sources]
12+
MaterialModelsTesting = {url = "https://github.com/KnutAM/MaterialModelsTesting.jl"}
13+
MechanicalMaterialModels = {url = "https://github.com/KnutAM/MechanicalMaterialModels.jl"}
14+
Newton = {url = "https://github.com/KnutAM/Newton.jl"}
15+
1116
[compat]
1217
julia = "1.11"
1318

1419
[extras]
15-
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"
1620
FiniteDiff = "6a86dc24-6348-571c-b903-95158fe2bd41"
1721
MaterialModelsTesting = "882b014b-b96c-4115-8629-e17fb35110d2"
22+
MechanicalMaterialModels = "b3282f9b-607f-4337-ab95-e5488ab5652c"
23+
Newton = "83aa5b51-0588-403c-85e4-434ec185aae7"
1824
Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c"
25+
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"
1926

20-
[sources]
21-
MaterialModelsTesting = {url = "https://github.com/KnutAM/MaterialModelsTesting.jl"}
22-
#MaterialModelsTesting = {path = "/Users/knutan/.julia/dev/MaterialModelsTesting"}
2327

2428
[targets]
25-
test = ["Test", "FiniteDiff", "MaterialModelsTesting", "Random"]
29+
test = ["FiniteDiff", "MaterialModelsTesting", "MechanicalMaterialModels", "Newton", "Random", "Test"]

src/differentiation.jl

Lines changed: 47 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -157,22 +157,53 @@ function reset_derivatives!(sd::StressStateDerivatives, sd_prev::StressStateDeri
157157
return sd
158158
end
159159

160-
function differentiate_material!(ssd::StressStateDerivatives, stress_state::AbstractStressState, m::AbstractMaterial, ϵ::AbstractTensor, args::Vararg{Any,N}) where {N}
161-
σ_full, dσdϵ_full, state, ϵ_full = stress_state_material_response(stress_state, m, ϵ, args...)
162-
differentiate_material!(ssd.mderiv, m, ϵ_full, args..., dσdϵ_full)
163-
164-
if isa(stress_state, NoIterationState)
165-
copy!(ssd.dσdp, ssd.mderiv.dσdp)
166-
fill!(ssd.dϵdp, 0)
167-
else
168-
sc = stress_controlled_indices(stress_state, ϵ)
169-
ec = strain_controlled_indices(stress_state, ϵ)
170-
dσᶠdϵᶠ_inv = inv(get_unknowns(stress_state, dσdϵ_full)) # f: unknown strain components solved for during stress iterations
171-
ssd.dϵdp[sc, :] .= .-dσᶠdϵᶠ_inv * ssd.mderiv.dσdp[sc, :]
172-
ssd.dσdp[ec, :] .= ssd.mderiv.dσdp[ec, :] .+ ssd.mderiv.dσdϵ[ec, sc] * ssd.dϵdp[sc, :]
173-
ssd.mderiv.dsdp .+= ssd.mderiv.dsdϵ[:, sc] * ssd.dϵdp[sc, :]
174-
end
175-
return reduce_tensordim(stress_state, σ_full), reduce_stiffness(stress_state, dσdϵ_full), state, ϵ_full
160+
function differentiate_material!(ssd::StressStateDerivatives, stress_state::AbstractStressState, m::AbstractMaterial, strain::AbstractTensor, args::Vararg{Any,N}) where {N}
161+
stress_3d, stiff_3d, state, strain_3d = stress_state_material_response(stress_state, m, strain, args...)
162+
differentiate_material!(ssd.mderiv, m, strain_3d, args..., stiff_3d)
163+
_update_derivatives!(ssd, stress_state, strain_3d, stress_3d, stiff_3d)
164+
return reduce_tensordim(stress_state, stress_3d), reduce_stiffness(stress_state, stiff_3d, strain_3d, stress_3d), state, strain_3d
165+
end
166+
167+
function _update_derivatives!(ssd::StressStateDerivatives, ::NoIterationState, args...)
168+
copy!(ssd.dσdp, ssd.mderiv.dσdp)
169+
fill!(ssd.dϵdp, 0)
170+
return ssd
171+
end
172+
173+
# IterationState
174+
# drdp = 0 = ∂r∂p + ∂r∂x * dxdp => dxdp = -∂r∂x\∂r∂p
175+
# r(x(p),P(x,p))
176+
# Calculated: ∂P∂p (for full strain, F) and ∂P∂x (∂P∂F)
177+
# r = r̃(τ(P(x(p), p), x(p)), x(p))
178+
# drdp = ∂r̃∂τ ⋅ [∂τ∂P ⋅ [∂P∂x ⋅ dxdp + ∂P∂p] + ∂τ∂x ⋅ dxdp] + ∂r̃∂x ⋅ dxdp
179+
# = [∂r̃∂τ ⋅ [∂τ∂P ⋅ ∂P∂x + ∂τ∂x] + ∂r̃∂x] ⋅ dxdp + ∂r̃∂τ ⋅ ∂τ∂P ⋅ ∂P∂p = 0
180+
# dxdp = -([∂r̃∂τ ⋅ [∂τ∂P ⋅ ∂P∂x + ∂τ∂x] + ∂r̃∂x])⁻¹ ⋅ [∂r̃∂τ ⋅ ∂τ∂P ⋅ ∂P∂p]
181+
# r = r̂(x(p), p) = r̃(τ(P(x(p), p), x(p)), x(p))
182+
# ∂r̂∂x = get_drdx(...) # This is the function we already have
183+
# ∂r̂∂p = ∂r̃∂τ ⋅ ∂τ∂P ⋅ ∂P∂p
184+
# dxdp = -∂r̂∂x \ ∂r̂∂p
185+
# Small strains, σ = τ = P & r = τ[sc]
186+
# => ∂r̂∂p = ∂r̃∂τᶠ ⋅ ∂τᶠ∂Pᶠ ⋅ ∂Pᶠ∂p = [I ⋅ I ⋅ ∂Pᶠ∂p] = ∂Pᶠ∂p = ∂σᶠ∂p
187+
# => dϵdp = - ∂r̂∂x \ ∂σᶠ∂p
188+
# Finite strains
189+
# ∂r̃∂τ depends on specific gauge constraints
190+
# ∂τ∂P = I ⊗̄ F (τ = P F'; => P_ij F_jk' / dP_lm = δ_il δ_jm F_jk' = δ_il F_km)
191+
# Not yet implemented
192+
193+
# SmallStrains
194+
function _update_derivatives!(ssd::StressStateDerivatives, stress_state::IterationState, ϵ::SymmetricTensor{2,3}, σ::SymmetricTensor{2,3}, dσdϵ::SymmetricTensor{4,3})
195+
sc = stress_controlled_indices(stress_state, ϵ)
196+
ec = strain_controlled_indices(stress_state, ϵ)
197+
minus_∂r∂x_inv = -inv(get_drdx(stress_state, dσdϵ, ϵ, σ)) # -[∂σᶠ∂ϵᶠ]⁻¹
198+
ssd.dϵdp[sc, :] .= minus_∂r∂x_inv * ssd.mderiv.dσdp[sc, :]
199+
ssd.dσdp[ec, :] .= ssd.mderiv.dσdp[ec, :] .+ ssd.mderiv.dσdϵ[ec, sc] * ssd.dϵdp[sc, :]
200+
ssd.mderiv.dsdp .+= ssd.mderiv.dsdϵ[:, sc] * ssd.dϵdp[sc, :]
201+
return ssd
202+
end
203+
204+
# FiniteStrains
205+
function _update_derivatives!(ssd::StressStateDerivatives, stress_state::IterationState, F::Tensor{2,3}, P::Tensor{2,3}, dPdF::Tensor{4,3})
206+
error("StressStateDerivatives calculation for finite strains not implemented, see notes in source file for a start to implement")
176207
end
177208

178209
"""

0 commit comments

Comments
 (0)