verification: nonlinear oracle cases and the nonlinear solver's documentation

Theory cases for the nonlinear solver, each frozen as a fixture: uniaxial
stretch of a neo-Hookean block to twice its length (closed form), the
nonlinear patch test on a distorted hex8 mesh, a quarter turn of the same
mesh (objectivity: zero stress), the elastica of a hex20 cantilever at
P L²/(E I) = 1, 2, 5, 10 against Bisshopp–Drucker (0.2–0.5 %), and the
inflation of a thick neo-Hookean tube by a follower pressure against
Rivlin's closed form (0.08 % at the bore). A finite-strain Cook's membrane
is pending its transcribed reference. docs/fem.md describes the
formulation, the material point interface, the follower-pressure choice and
what nonlinear steps refuse; the literature, parity and roadmap pages
follow.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NmAttHhUZTokgPeEJia8sm
This commit is contained in:
jyvikoandClaude Opus 5.5 authored and Irakli Kourtis committed 2026-10-14 04:00:21 -04:00
1 parent 2183fdbe81
commit 8ca2dddeec
27 files changed
+1384 -7

No files matched your search

@@ -0,0 +1,7 @@
# Uniaxial stretch of a neo-Hookean block
A unit cube of 2 × 2 × 2 hex20 elements, symmetry planes x = 0, y = 0, z = 0, the face x = 1
pulled to x = 2 (λ = 2) in a nonlinear static step; E = 10, ν = 0.3 with the neo-Hookean
option (μ = 3.84615, κ = 8.33333). The lateral stretch l = 0.813143719 solves σ_yy = 0 (bisection
on the closed form), and σ_xx = 8.060135422. The deformation is homogeneous, so every element
reproduces it exactly.
@@ -0,0 +1,53 @@
{
"title": "Uniaxial stretch of a neo-Hookean block to twice its length",
"kind": "theory",
"source": "Closed form of the compressible neo-Hookean model W = μ/2 (Ī₁ − 3) + κ/2 (J − 1)² in uniaxial stress (G. A. Holzapfel, Nonlinear Solid Mechanics, Wiley 2000, §6.5, eq. 6.148 with the volumetric term of §6.4): σ_yy = μ J^(−5/3)(l² − Ī/3) + κ(J − 1) = 0 fixes the lateral stretch l, then σ_xx = μ J^(−5/3)(λ² − l²)",
"quantities": [
{
"id": "sigma",
"quantity": "axial Cauchy stress at the corner (1, 1, 1), stretch λ = 2",
"measure": {
"command": "solve.probe",
"params": {
"step": "Stretch",
"at": [
[
1,
1,
1
]
]
},
"pointer": "/nodes/0/stress/0"
},
"value": 8.060135422196785,
"tolerance": {
"relative": 1e-06
},
"reason": "a homogeneous deformation every element represents exactly: the tolerance only admits rounding and the Newton tolerance"
},
{
"id": "lateral",
"quantity": "lateral displacement u_y at the corner (1, 1, 1), l − 1",
"measure": {
"command": "solve.probe",
"params": {
"step": "Stretch",
"at": [
[
1,
1,
1
]
]
},
"pointer": "/nodes/0/displacement/1"
},
"value": -0.1868562805727787,
"tolerance": {
"relative": 1e-06
},
"reason": "a homogeneous deformation every element represents exactly: the tolerance only admits rounding and the Newton tolerance"
}
]
}
@@ -0,0 +1,13 @@
{
"note": "FieldCraft's accepted results for this case, written by `cargo xtask oracle --bless`. A result outside its band fails CI.",
"values": {
"lateral": {
"band": 1.8685628057277872e-10,
"value": -0.18685628056417355
},
"sigma": {
"band": 8.060135422217968e-9,
"value": 8.060135422217968
}
}
}
@@ -0,0 +1,16 @@
[
{"command": "mesh.block", "params": {"body": "Cube", "kind": "hex20", "corners": [[0, 0, 0], [1, 0, 0], [1, 1, 0], [0, 1, 0], [0, 0, 1], [1, 0, 1], [1, 1, 1], [0, 1, 1]], "divisions": [2, 2, 2], "faces": {"6": "x0", "3": "y0", "1": "z0", "4": "x1"}}},
{"command": "model.set.create", "params": {"name": "all", "geometry": [{"body": "Cube"}]}},
{"command": "model.set.create", "params": {"name": "x0", "geometry": [{"body": "Cube", "face": "x0"}]}},
{"command": "model.set.create", "params": {"name": "y0", "geometry": [{"body": "Cube", "face": "y0"}]}},
{"command": "model.set.create", "params": {"name": "z0", "geometry": [{"body": "Cube", "face": "z0"}]}},
{"command": "model.set.create", "params": {"name": "x1", "geometry": [{"body": "Cube", "face": "x1"}]}},
{"command": "model.material.create", "params": {"name": "Rubber", "elastic": {"type": "isotropic", "young": 10.0, "poisson": 0.3}, "hyperelastic": {"type": "neo_hookean"}}},
{"command": "model.section.create", "params": {"name": "cube", "set": "all", "material": "Rubber", "kind": {"type": "solid"}}},
{"command": "model.boundary_condition.create", "params": {"name": "sx", "type": "symmetry", "target": {"set": "x0"}, "plane": "x"}},
{"command": "model.boundary_condition.create", "params": {"name": "sy", "type": "symmetry", "target": {"set": "y0"}, "plane": "y"}},
{"command": "model.boundary_condition.create", "params": {"name": "sz", "type": "symmetry", "target": {"set": "z0"}, "plane": "z"}},
{"command": "model.boundary_condition.create", "params": {"name": "pull", "type": "displacement", "target": {"set": "x1"}, "values": [1.0, null, null, null, null, null]}},
{"command": "model.step.create", "params": {"name": "Stretch", "procedure": {"type": "nonlinear_static"}, "boundary_conditions": ["sx", "sy", "sz", "pull"], "loads": []}},
{"command": "solve.nonlinear", "params": {"step": "Stretch"}, "id": "solve"}
]