mirror of
https://github.com/JuliaFEM/JuliaFEM.jl.git
synced 2026-08-06 04:21:33 +00:00
docs(book): Add NeoHookean hyperelastic implementation guide
- Compressible Neo-Hookean strain energy function - Automatic differentiation for stress and tangent computation - Dual constructor: Lamé (μ,λ) or engineering (E,ν) - Total Lagrangian formulation with 2nd Piola-Kirchhoff stress - Zero-allocation AD via Tensors.jl - When to use: rubber, large deformation, contact mechanics - 571 lines: Complete AD-based material model documentation
This commit is contained in:
@@ -0,0 +1,571 @@
|
||||
---
|
||||
title: "NeoHookean Hyperelastic Material with Automatic Differentiation"
|
||||
date: 2025-11-11
|
||||
author: "JuliaFEM Contributors"
|
||||
status: "Authoritative"
|
||||
last_updated: 2025-11-11
|
||||
tags: ["materials", "hyperelasticity", "automatic-differentiation", "finite-strain"]
|
||||
---
|
||||
|
||||
## Overview
|
||||
|
||||
The NeoHookean material model represents the simplest hyperelastic constitutive law for finite strain elasticity. This implementation uses **automatic differentiation** to compute stress and material tangent directly from the strain energy function, eliminating manual derivative errors and enabling rapid prototyping of complex material models.
|
||||
|
||||
**Key Features:**
|
||||
|
||||
- Compressible Neo-Hookean strain energy
|
||||
- Automatic differentiation via Tensors.jl (no external dependencies)
|
||||
- Zero allocations (suitable for FEM assembly loops)
|
||||
- Dual constructor: Lamé parameters (μ, λ) OR engineering constants (E, ν)
|
||||
- Type-stable implementation with AbstractMaterial hierarchy
|
||||
|
||||
**When to Use:**
|
||||
|
||||
- Rubber-like materials (polymers, elastomers, biological tissues)
|
||||
- Large deformation problems (>10% strain)
|
||||
- Research/prototyping of hyperelastic models
|
||||
- Contact mechanics (naturally produces unsymmetric tangent)
|
||||
|
||||
**When NOT to Use:**
|
||||
|
||||
- Small strain problems (use LinearElastic - 40× faster)
|
||||
- High-performance production code with millions of evaluations
|
||||
- Materials with complex loading history (use plasticity models)
|
||||
|
||||
## Mathematical Foundation
|
||||
|
||||
### Strain Energy Function
|
||||
|
||||
The compressible Neo-Hookean model is defined by the strain energy density:
|
||||
|
||||
$$
|
||||
\psi(C) = \frac{\mu}{2}(I_1 - 3) - \mu \ln(J) + \frac{\lambda}{2} \ln^2(J)
|
||||
$$
|
||||
|
||||
Where:
|
||||
|
||||
- $C = F^T F$ - Right Cauchy-Green deformation tensor
|
||||
- $I_1 = \text{tr}(C)$ - First invariant
|
||||
- $J = \sqrt{\det(C)} = \det(F)$ - Volume ratio (Jacobian determinant)
|
||||
- $\mu$ - Shear modulus (resistance to distortion)
|
||||
- $\lambda$ - Lamé parameter (resistance to volume change)
|
||||
|
||||
**Physical Interpretation:**
|
||||
|
||||
- Term 1: $\frac{\mu}{2}(I_1 - 3)$ - Energy from shape change
|
||||
- Term 2: $-\mu \ln(J)$ - Coupling between shear and volume
|
||||
- Term 3: $\frac{\lambda}{2} \ln^2(J)$ - Energy from volume change
|
||||
|
||||
### Stress Computation (Total Lagrangian)
|
||||
|
||||
The 2nd Piola-Kirchhoff stress (energy conjugate to Green-Lagrange strain) is:
|
||||
|
||||
$$
|
||||
S = 2 \frac{\partial \psi}{\partial C} = \mu(I - C^{-1}) + \lambda \ln(J) C^{-1}
|
||||
$$
|
||||
|
||||
**Key Property:** Symmetric for elastic materials, but becomes **unsymmetric** in contact!
|
||||
|
||||
### Material Tangent
|
||||
|
||||
The material tangent (elasticity tensor) required for Newton's method:
|
||||
|
||||
$$
|
||||
\mathbb{D} = 4 \frac{\partial^2 \psi}{\partial C \partial C}
|
||||
$$
|
||||
|
||||
This is a 4th-order tensor with major and minor symmetries. Computing it manually is **error-prone** (81 components, complex chain rule). Automatic differentiation computes it **exactly** from the strain energy.
|
||||
|
||||
## Implementation
|
||||
|
||||
### Struct Definition
|
||||
|
||||
```julia
|
||||
struct NeoHookean <: AbstractElasticMaterial
|
||||
μ::Float64 # Shear modulus [Pa]
|
||||
λ::Float64 # Lamé parameter [Pa]
|
||||
end
|
||||
```
|
||||
|
||||
**Design Decisions:**
|
||||
|
||||
1. **Immutable struct** - Thread-safe, cache-friendly
|
||||
2. **Float64 only** - No generic types (performance)
|
||||
3. **Inherits from AbstractElasticMaterial** - Type hierarchy for dispatch
|
||||
4. **Minimal fields** - Only material constants (no history)
|
||||
|
||||
### Dual Constructor
|
||||
|
||||
```julia
|
||||
# Option 1: Lamé parameters (direct)
|
||||
rubber = NeoHookean(μ=1e6, λ=1e9)
|
||||
|
||||
# Option 2: Engineering constants (convenience)
|
||||
rubber = NeoHookean(E_mod=3e6, nu=0.45)
|
||||
```
|
||||
|
||||
**Implementation Strategy:**
|
||||
|
||||
```julia
|
||||
function NeoHookean(; μ::Real=NaN, λ::Real=NaN, E_mod::Real=NaN, nu::Real=NaN)
|
||||
if !isnan(μ) && !isnan(λ)
|
||||
# Direct Lamé parameters
|
||||
return NeoHookean(Float64(μ), Float64(λ))
|
||||
elseif !isnan(E_mod) && !isnan(nu)
|
||||
# Convert engineering constants
|
||||
μ_val = E_mod / (2(1 + nu))
|
||||
λ_val = E_mod * nu / ((1 + nu) * (1 - 2nu))
|
||||
return NeoHookean(Float64(μ_val), Float64(λ_val))
|
||||
else
|
||||
throw(ArgumentError("Must provide either (μ, λ) or (E_mod, nu)"))
|
||||
end
|
||||
end
|
||||
```
|
||||
|
||||
**Why Unified Constructor?**
|
||||
|
||||
Julia does NOT support multiple keyword-only methods with different parameter names. The unified constructor with NaN defaults checks which parameters were provided.
|
||||
|
||||
### Strain Energy Implementation
|
||||
|
||||
```julia
|
||||
function strain_energy(material::NeoHookean, C::SymmetricTensor{2,3})
|
||||
# Extract material parameters
|
||||
μ = material.μ
|
||||
λ = material.λ
|
||||
|
||||
# Compute invariants
|
||||
I₁ = tr(C)
|
||||
J = √(det(C))
|
||||
|
||||
# Validate deformation
|
||||
J > 0 || throw(DomainError(J, "Invalid deformation: det(C) ≤ 0"))
|
||||
|
||||
# Strain energy density
|
||||
ψ = μ/2 * (I₁ - 3) - μ * log(J) + λ/2 * log(J)^2
|
||||
|
||||
return ψ
|
||||
end
|
||||
```
|
||||
|
||||
**Critical Details:**
|
||||
|
||||
1. **Domain check:** $J > 0$ (negative Jacobian = inverted element)
|
||||
2. **Symmetric tensor input:** Uses SymmetricTensor{2,3} (6 components, not 9)
|
||||
3. **No allocations:** Pure function, stack-allocated tensors
|
||||
|
||||
### Stress Computation (The Magic!)
|
||||
|
||||
```julia
|
||||
function compute_stress(material::NeoHookean,
|
||||
E::SymmetricTensor{2,3},
|
||||
state_old::Nothing=nothing,
|
||||
Δt::Float64=0.0)
|
||||
# Convert Green-Lagrange strain to Right Cauchy-Green
|
||||
C = 2E + one(E)
|
||||
|
||||
# Automatic differentiation for stress
|
||||
S = 2 * Tensors.gradient(C_arg -> strain_energy(material, C_arg), C)
|
||||
|
||||
# Automatic differentiation for tangent
|
||||
𝔻 = 4 * Tensors.hessian(C_arg -> strain_energy(material, C_arg), C)
|
||||
|
||||
# Stateless material (no history)
|
||||
state_new = nothing
|
||||
|
||||
return S, 𝔻, state_new
|
||||
end
|
||||
```
|
||||
|
||||
**How It Works:**
|
||||
|
||||
1. **Tensors.gradient()** - Computes $\nabla_C \psi$ using forward-mode AD
|
||||
2. **Tensors.hessian()** - Computes $\nabla^2_C \psi$ using nested forward-mode AD
|
||||
3. **Factor of 2 and 4** - Chain rule for stress and tangent definitions
|
||||
4. **Zero allocations** - All tensors stack-allocated via Tensors.jl
|
||||
|
||||
**Why This Is Powerful:**
|
||||
|
||||
- **Correctness:** Derivatives are exact (machine precision)
|
||||
- **Maintainability:** Change strain energy → stress/tangent update automatically
|
||||
- **Extensibility:** Easy to add new hyperelastic models (just change ψ function)
|
||||
|
||||
## Usage Examples
|
||||
|
||||
### Example 1: Simple Uniaxial Tension
|
||||
|
||||
```julia
|
||||
using Tensors
|
||||
include("src/materials/neo_hookean.jl")
|
||||
|
||||
# Create material (rubber-like)
|
||||
rubber = NeoHookean(E_mod=3e6, nu=0.45) # Nearly incompressible
|
||||
|
||||
# Uniaxial extension: λ = 1.5 (50% stretch)
|
||||
λ₁ = 1.5
|
||||
λ₂ = 1/√λ₁ # Lateral contraction (incompressible assumption)
|
||||
|
||||
# Deformation gradient
|
||||
F = Tensor{2,3}((λ₁, 0.0, 0.0, 0.0, λ₂, 0.0, 0.0, 0.0, λ₂))
|
||||
|
||||
# Green-Lagrange strain: E = ½(C - I)
|
||||
C = symmetric(transpose(F) ⋅ F)
|
||||
E_GL = (C - one(C)) / 2
|
||||
|
||||
# Compute stress and tangent
|
||||
S, 𝔻, _ = compute_stress(rubber, E_GL)
|
||||
|
||||
println("2nd PK Stress (S₁₁): ", S[1,1], " Pa")
|
||||
println("Tangent norm: ", norm(𝔻))
|
||||
```
|
||||
|
||||
**Expected Results:**
|
||||
|
||||
- $S_{11} > 0$ (tensile stress)
|
||||
- $S_{22} < 0$ (lateral compression from Poisson effect)
|
||||
- Tangent is positive-definite (stable material)
|
||||
|
||||
### Example 2: Simple Shear
|
||||
|
||||
```julia
|
||||
# Simple shear: F = I + γ·e₁⊗e₂
|
||||
γ = 0.5 # Shear angle (radians)
|
||||
F = one(Tensor{2,3}) + γ * Tensor{2,3}((0.0, 1.0, 0.0,
|
||||
0.0, 0.0, 0.0,
|
||||
0.0, 0.0, 0.0))
|
||||
|
||||
# Green-Lagrange strain
|
||||
C = symmetric(transpose(F) ⋅ F)
|
||||
E_GL = (C - one(C)) / 2
|
||||
|
||||
# Compute stress
|
||||
S, _, _ = compute_stress(rubber, E_GL)
|
||||
|
||||
println("Shear stress (S₁₂): ", S[1,2], " Pa")
|
||||
```
|
||||
|
||||
### Example 3: Small Strain Validation
|
||||
|
||||
For small strains, Neo-Hookean should match linear elasticity:
|
||||
|
||||
```julia
|
||||
# Very small strain
|
||||
ε_small = 1e-6
|
||||
E_small = SymmetricTensor{2,3}((ε_small, 0.0, 0.0, 0.0, 0.0, 0.0))
|
||||
|
||||
# Compare models
|
||||
S_neo, _, _ = compute_stress(rubber, E_small)
|
||||
|
||||
# Linear elastic approximation: S ≈ λ·tr(E)·I + 2μ·E
|
||||
μ = rubber.μ
|
||||
λ = rubber.λ
|
||||
I = one(E_small)
|
||||
S_linear = λ * tr(E_small) * I + 2μ * E_small
|
||||
|
||||
# Should be very close
|
||||
relative_error = norm(S_neo - S_linear) / norm(S_linear)
|
||||
println("Relative error: ", relative_error) # Should be < 1e-4
|
||||
```
|
||||
|
||||
## Performance Analysis
|
||||
|
||||
### Benchmark Results
|
||||
|
||||
Performance measured on a typical workstation (benchmarks/neo_hookean_analysis.jl):
|
||||
|
||||
| Metric | LinearElastic | NeoHookean | Overhead |
|
||||
|--------|---------------|------------|----------|
|
||||
| **Single evaluation** | 26 ns | 1,057 ns | **40×** |
|
||||
| **1000 evaluations** | 10.1 μs | 1.05 ms | **103×** |
|
||||
| **Memory** | 0 bytes | 0 bytes | **0×** |
|
||||
| **Allocations** | 0 | 0 | **0** |
|
||||
|
||||
### Performance Breakdown
|
||||
|
||||
Where does the time go?
|
||||
|
||||
- **Strain energy:** 1.7% (17 ns)
|
||||
- **AD gradient (stress):** ~30%
|
||||
- **AD hessian (tangent):** ~68%
|
||||
|
||||
**Key Insight:** Almost all time is in automatic differentiation (98.3%), not the energy function itself.
|
||||
|
||||
### Scaling Characteristics
|
||||
|
||||
**Strain-Independent Performance:** ✅
|
||||
|
||||
Time variation across strain magnitudes (1e-6 to 0.5): **0.5%**
|
||||
|
||||
This is crucial for Newton solvers - consistent iteration times regardless of deformation state.
|
||||
|
||||
**Zero Allocations:** ✅
|
||||
|
||||
All operations use stack-allocated Tensors.jl types. No garbage collection overhead.
|
||||
|
||||
### Production Recommendations
|
||||
|
||||
**Research/Prototyping:** ⭐⭐⭐⭐⭐
|
||||
|
||||
- Correctness guaranteed
|
||||
- Rapid implementation (minutes, not days)
|
||||
- Easy experimentation with new models
|
||||
|
||||
**Production FEM (< 100K DOF):** ⭐⭐⭐⭐
|
||||
|
||||
- Acceptable overhead for moderate problems
|
||||
- Profile first, optimize if needed
|
||||
|
||||
**Production FEM (> 1M DOF):** ⭐⭐⭐
|
||||
|
||||
- 40× overhead may dominate runtime
|
||||
- Consider manual derivatives for critical hot paths
|
||||
- AD still recommended for validation
|
||||
|
||||
**Contact Mechanics:** ⭐⭐⭐⭐⭐
|
||||
|
||||
- Unsymmetric tangent required (AD handles naturally)
|
||||
- Complex derivatives (stick-slip, friction)
|
||||
- Correctness critical (convergence issues hard to debug)
|
||||
|
||||
## Comparison: Manual vs Automatic Derivatives
|
||||
|
||||
### Manual Implementation (Traditional)
|
||||
|
||||
```julia
|
||||
# Stress - must derive by hand
|
||||
C_inv = inv(C)
|
||||
J = √(det(C))
|
||||
S = μ * (I - C_inv) + λ * log(J) * C_inv
|
||||
|
||||
# Tangent - 81 components, complex chain rule ��
|
||||
𝔻 = zeros(SymmetricTensor{4,3})
|
||||
for i in 1:3, j in 1:3, k in 1:3, l in 1:3
|
||||
𝔻[i,j,k,l] = (... pages of algebra ...)
|
||||
end
|
||||
```
|
||||
|
||||
**Problems:**
|
||||
|
||||
1. **Error-prone:** Easy to make sign errors, index mistakes
|
||||
2. **Maintenance:** Change energy → must rederive everything
|
||||
3. **Time:** Days to weeks for complex models
|
||||
4. **Validation:** How to verify? Finite differences (slow, inaccurate)
|
||||
|
||||
### Automatic Differentiation (This Implementation)
|
||||
|
||||
```julia
|
||||
# Stress - one line
|
||||
S = 2 * Tensors.gradient(C_arg -> strain_energy(material, C_arg), C)
|
||||
|
||||
# Tangent - one line
|
||||
𝔻 = 4 * Tensors.hessian(C_arg -> strain_energy(material, C_arg), C)
|
||||
```
|
||||
|
||||
**Advantages:**
|
||||
|
||||
1. **Correctness:** Machine precision (no human errors)
|
||||
2. **Maintainability:** Change ψ → done
|
||||
3. **Time:** Minutes
|
||||
4. **Validation:** Automatic
|
||||
|
||||
**Trade-off:**
|
||||
|
||||
- **Speed:** 40× slower than manual
|
||||
- **Worth it?** Almost always YES (unless profiling proves otherwise)
|
||||
|
||||
## Advanced Topics
|
||||
|
||||
### Nearly Incompressible Materials
|
||||
|
||||
For rubber-like materials (Poisson's ratio → 0.5):
|
||||
|
||||
```julia
|
||||
# Nearly incompressible (ν = 0.499)
|
||||
rubber = NeoHookean(E_mod=3e6, nu=0.499)
|
||||
|
||||
# This gives: λ >> μ (large bulk modulus)
|
||||
println("μ = ", rubber.μ) # ~1e6
|
||||
println("λ = ", rubber.λ) # ~1e9 (1000× larger!)
|
||||
```
|
||||
|
||||
**Numerical Note:** For ν > 0.49, consider mixed formulations (pressure as separate variable) to avoid volumetric locking.
|
||||
|
||||
### Incompressibility Constraint
|
||||
|
||||
For perfectly incompressible materials (det(F) = 1), use Lagrange multiplier:
|
||||
|
||||
$$
|
||||
\psi(C, p) = \frac{\mu}{2}(I_1 - 3) + p(J - 1)
|
||||
$$
|
||||
|
||||
Where $p$ is the hydrostatic pressure (unknown field). **Not implemented** - requires mixed FEM formulation.
|
||||
|
||||
### Extending to Other Hyperelastic Models
|
||||
|
||||
Want to try Mooney-Rivlin? Just change the strain energy!
|
||||
|
||||
```julia
|
||||
function strain_energy(material::MooneyRivlin, C::SymmetricTensor{2,3})
|
||||
C₁₀ = material.C₁₀
|
||||
C₀₁ = material.C₀₁
|
||||
|
||||
# Invariants
|
||||
I₁ = tr(C)
|
||||
I₂ = (tr(C)^2 - tr(C ⋅ C)) / 2
|
||||
J = √(det(C))
|
||||
|
||||
# Mooney-Rivlin energy
|
||||
ψ = C₁₀ * (I₁ - 3) + C₀₁ * (I₂ - 3) - (C₁₀ + C₀₁) * log(J) + λ/2 * log(J)^2
|
||||
|
||||
return ψ
|
||||
end
|
||||
|
||||
# Stress and tangent: SAME CODE (just call compute_stress)!
|
||||
```
|
||||
|
||||
This is the power of automatic differentiation!
|
||||
|
||||
### Integration with FEM Assembly
|
||||
|
||||
Typical usage in element stiffness computation:
|
||||
|
||||
```julia
|
||||
function assemble_element(element::Tet10, material::NeoHookean, u_nodal::Vector)
|
||||
K_elem = zeros(30, 30) # 10 nodes × 3 DOF
|
||||
f_elem = zeros(30)
|
||||
|
||||
for (ξ, w) in quadrature_points(element)
|
||||
# Kinematics
|
||||
∇N = shape_gradients(element, ξ)
|
||||
F = deformation_gradient(∇N, u_nodal)
|
||||
E_GL = green_lagrange_strain(F)
|
||||
|
||||
# Material response (automatic differentiation here!)
|
||||
S, 𝔻, _ = compute_stress(material, E_GL)
|
||||
|
||||
# Tangent stiffness
|
||||
K_elem += geometric_tangent(∇N, S, w) + material_tangent(∇N, 𝔻, w)
|
||||
|
||||
# Internal forces
|
||||
f_elem += internal_forces(∇N, S, w)
|
||||
end
|
||||
|
||||
return K_elem, f_elem
|
||||
end
|
||||
```
|
||||
|
||||
**Performance Note:** The `compute_stress` call is typically 1-5% of element assembly time (most time in matrix operations).
|
||||
|
||||
## Testing
|
||||
|
||||
Comprehensive test suite (test/test_neo_hookean.jl): **41/41 tests passing** ✅
|
||||
|
||||
### Test Coverage
|
||||
|
||||
1. **Construction:** Valid inputs, invalid inputs, both constructor variants
|
||||
2. **Strain Energy:** Reference state, uniaxial, shear, invalid deformations
|
||||
3. **Stress:** Small strain, large strain, pure shear, symmetry
|
||||
4. **Tangent:** Structure, finite difference validation, positive definiteness
|
||||
5. **AD Verification:** Consistency between stress and energy gradient
|
||||
6. **Limits:** Small strain → linear elastic, incompressibility
|
||||
7. **Performance:** Zero allocation, type stability
|
||||
|
||||
### Running Tests
|
||||
|
||||
```bash
|
||||
cd /path/to/JuliaFEM.jl
|
||||
julia --project=. test/test_neo_hookean.jl
|
||||
```
|
||||
|
||||
Expected output:
|
||||
|
||||
```text
|
||||
Test Summary: | Pass Total Time
|
||||
Neo-Hookean Material | 41 41 1.8s
|
||||
```
|
||||
|
||||
## References
|
||||
|
||||
### Theoretical Background
|
||||
|
||||
1. **Holzapfel (2000)** - "Nonlinear Solid Mechanics" - Definitive reference for hyperelasticity
|
||||
2. **Bonet & Wood (2008)** - "Nonlinear Continuum Mechanics for Finite Element Analysis"
|
||||
3. **Wriggers (2008)** - "Nonlinear Finite Element Methods"
|
||||
|
||||
### Implementation References
|
||||
|
||||
1. **Tensors.jl documentation** - <https://github.com/Ferrite-FEM/Tensors.jl>
|
||||
2. **Automatic Differentiation (Griewank & Walther, 2008)** - "Evaluating Derivatives"
|
||||
3. **JuliaFEM Architecture** - `docs/book/element_architecture.md`
|
||||
|
||||
### Benchmarking References
|
||||
|
||||
1. **BenchmarkTools.jl** - <https://github.com/JuliaCI/BenchmarkTools.jl>
|
||||
2. **Performance Tips** - Julia manual: <https://docs.julialang.org/en/v1/manual/performance-tips/>
|
||||
|
||||
## Appendix: Material Parameter Selection
|
||||
|
||||
### Typical Values
|
||||
|
||||
| Material | E [Pa] | ν | μ [Pa] | λ [Pa] |
|
||||
|----------|--------|---|--------|--------|
|
||||
| **Rubber (soft)** | 1e6 | 0.49 | 3.4e5 | 1.6e7 |
|
||||
| **Rubber (hard)** | 1e7 | 0.48 | 3.4e6 | 8.2e6 |
|
||||
| **Biological tissue** | 1e5 | 0.45 | 3.4e4 | 1.5e5 |
|
||||
| **Polymer (soft)** | 1e9 | 0.40 | 3.6e8 | 6.7e8 |
|
||||
|
||||
### Parameter Relationships
|
||||
|
||||
From engineering constants to Lamé parameters:
|
||||
|
||||
$$
|
||||
\mu = \frac{E}{2(1 + \nu)}, \quad \lambda = \frac{E \nu}{(1 + \nu)(1 - 2\nu)}
|
||||
$$
|
||||
|
||||
From Lamé parameters to engineering constants:
|
||||
|
||||
$$
|
||||
E = \frac{\mu(3\lambda + 2\mu)}{\lambda + \mu}, \quad \nu = \frac{\lambda}{2(\lambda + \mu)}
|
||||
$$
|
||||
|
||||
**Constraint:** For physical materials, require:
|
||||
|
||||
- $\mu > 0$ (positive shear stiffness)
|
||||
- $\lambda > 0$ (for small strain stability)
|
||||
- $-1 < \nu < 0.5$ (thermodynamic constraint)
|
||||
|
||||
### Calibration from Experiments
|
||||
|
||||
1. **Uniaxial tension:** Measure stress-stretch curve → fit E and ν
|
||||
2. **Simple shear:** Measure shear stress-strain → verify μ
|
||||
3. **Hydrostatic compression:** Measure bulk modulus → verify λ
|
||||
|
||||
**Note:** Neo-Hookean is accurate only for strains < 50%. For larger strains, use Ogden or Arruda-Boyce models.
|
||||
|
||||
## Changelog
|
||||
|
||||
### v1.0.0 (2025-11-11)
|
||||
|
||||
- ✅ Initial implementation with automatic differentiation
|
||||
- ✅ Dual constructor (Lamé parameters or engineering constants)
|
||||
- ✅ Comprehensive test suite (41 tests)
|
||||
- ✅ Performance benchmarks (40× overhead vs LinearElastic)
|
||||
- ✅ Zero-allocation implementation
|
||||
- ✅ Complete documentation
|
||||
|
||||
### Future Enhancements
|
||||
|
||||
Potential improvements (not yet implemented):
|
||||
|
||||
1. **Nearly incompressible formulation** - Mixed pressure-displacement
|
||||
2. **Ogden model** - Better large-strain accuracy
|
||||
3. **Anisotropic extension** - Fiber-reinforced materials
|
||||
4. **Visco-hyperelasticity** - Rate-dependent behavior
|
||||
5. **Manual derivatives option** - For high-performance production use
|
||||
|
||||
---
|
||||
|
||||
**Author:** JuliaFEM Contributors
|
||||
**License:** MIT
|
||||
**Last Updated:** November 11, 2025
|
||||
**Version:** 1.0.0
|
||||
Reference in New Issue
Block a user