@@ -582,11 +582,65 @@ function constitutive(material::Neohookean, F::SMatrix{3,3,Float64,9})
582582end
583583
584584# ---------------------------------------------------------------------------
585- # AD-based constitutive fallback for Elastic models without a manual
586- # implementation. Specific methods above take dispatch priority; this
587- # catches anything else (e.g. SethHill, or new models added by developers).
588- # Stress (P = ∂W/∂F) and tangent (AA = ∂²W/∂F²) are computed via
589- # ForwardDiff acting on the strain_energy function.
585+ # AD primitives — composable building blocks for mixed manual/AD constitutive
586+ # implementations. Any Elastic model with a strain_energy method can use
587+ # these independently, e.g. manual stress + AD tangent, or vice-versa.
588+ # ---------------------------------------------------------------------------
589+
590+ function stress_ad (material:: Elastic , F:: SMatrix{3,3,Float64,9} )
591+ Fv = Vector {Float64} (undef, 9 )
592+ Fv .= vec (F)
593+ W_func = x -> strain_energy (material, SMatrix {3,3,eltype(x),9} (x))
594+ W = W_func (Fv)
595+ Pv = ForwardDiff. gradient (W_func, Fv)
596+ P = SMatrix {3,3,Float64,9} (reshape (Pv, 3 , 3 ))
597+ return W, P
598+ end
599+
600+ function tangent_ad (material:: Elastic , F:: SMatrix{3,3,Float64,9} )
601+ Fv = Vector {Float64} (undef, 9 )
602+ Fv .= vec (F)
603+ W_func = x -> strain_energy (material, SMatrix {3,3,eltype(x),9} (x))
604+ Hmat = ForwardDiff. hessian (W_func, Fv)
605+ return SArray {Tuple{3,3,3,3},Float64,4,81} (reshape (Hmat, 3 , 3 , 3 , 3 ))
606+ end
607+
608+ # SethHill: manual (W, P) — shares intermediates — plus AD tangent.
609+ function constitutive (material:: SethHill , F:: SMatrix{3,3,Float64,9} )
610+ C = F' * F
611+ F⁻¹ = inv (F)
612+ F⁻ᵀ = F⁻¹'
613+ J = det (F)
614+ Jᵐ = J^ material. m
615+ J⁻ᵐ = 1.0 / Jᵐ
616+ J²ᵐ = Jᵐ * Jᵐ
617+ J⁻²ᵐ = 1.0 / J²ᵐ
618+ Cbar = J^ (- 2 / 3 ) * C
619+ Cbar⁻¹ = J^ (2 / 3 ) * F⁻¹ * F⁻ᵀ
620+ Cbarⁿ = Cbar^ material. n
621+ Cbar⁻ⁿ = Cbar⁻¹^ material. n
622+ Cbar²ⁿ = Cbarⁿ * Cbarⁿ
623+ Cbar⁻²ⁿ = Cbar⁻ⁿ * Cbar⁻ⁿ
624+ trCbarⁿ = tr (Cbarⁿ)
625+ trCbar⁻ⁿ = tr (Cbar⁻ⁿ)
626+ trCbar²ⁿ = tr (Cbar²ⁿ)
627+ trCbar⁻²ⁿ = tr (Cbar⁻²ⁿ)
628+ Wbulk = material. κ / 4 / material. m^ 2 * ((Jᵐ - 1 )^ 2 + (J⁻ᵐ - 1 )^ 2 )
629+ Wshear = material. μ / 4 / material. n^ 2 * (trCbar²ⁿ + trCbar⁻²ⁿ - 2 * trCbarⁿ - 2 * trCbar⁻ⁿ + 6 )
630+ W = Wbulk + Wshear
631+ Pbulk = material. κ / 2 / material. m * (J²ᵐ - Jᵐ - J⁻²ᵐ + J⁻ᵐ) * F⁻ᵀ
632+ Pshear =
633+ material. μ / material. n *
634+ (1 / 3 * (- trCbar²ⁿ + trCbarⁿ + trCbar⁻²ⁿ - trCbar⁻ⁿ) * F⁻ᵀ + F⁻ᵀ * (Cbar²ⁿ - Cbarⁿ - Cbar⁻²ⁿ + Cbar⁻ⁿ))
635+ P = Pbulk + Pshear
636+ AA = tangent_ad (material, F)
637+ return W, P, AA
638+ end
639+
640+ # ---------------------------------------------------------------------------
641+ # Full AD fallback for Elastic models without any manual implementation.
642+ # Specific methods above take dispatch priority; this catches anything else
643+ # (e.g. new models added by a developer who only defines strain_energy).
590644# ---------------------------------------------------------------------------
591645
592646function constitutive (material:: Elastic , F:: SMatrix{3,3,Float64,9} )
0 commit comments