@@ -157,22 +157,53 @@ function reset_derivatives!(sd::StressStateDerivatives, sd_prev::StressStateDeri
157157 return sd
158158end
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" )
176207end
177208
178209"""
0 commit comments