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,8 @@
# Large-deflection cantilever (elastica)
A cantilever L = 10, b = 1, h = 0.5 (L/h = 20) of 40 × 1 × 2 hex20 elements, clamped at x = 0,
E = 10⁴, ν = 0 (an elastic material in a nonlinear step: St Venant–Kirchhoff, exact for large
rotations with these small strains), under a dead vertical tip force P spread over the end face.
Four steps at P L²/(E I) = 1, 2, 5 and 10 (rotations of the tip 0.46 to 1.43 rad). The tip's
neutral-axis node (10, 0, 0.25) is compared with the elastica (Bisshopp–Drucker), whose values
were computed by shooting and agree with Mattiasson's table.
@@ -0,0 +1,199 @@
{
"title": "Large-deflection cantilever under a dead tip load against the elastica (solids)",
"kind": "theory",
"source": "The elastica of a cantilever under a vertical end load: K. E. Bisshopp, D. C. Drucker, Large deflection of cantilever beams, Quarterly of Applied Mathematics 3(3):272–275, 1945 (elliptic-integral solution); values computed by integrating θ″ = −(P/EI) cos θ by shooting (our own RK4, 20000 steps), agreeing with the table of K. Mattiasson, Numerical results from large deflection beam and frame problems analysed by means of elliptic integrals, IJNME 17(1):145–153, 1981, to all six digits",
"quantities": [
{
"id": "v1",
"quantity": "tip deflection δ_v/L at P L²/(E I) = 1",
"measure": {
"command": "solve.probe",
"params": {
"step": "K1",
"at": [
[
10.0,
0,
0.25
]
]
},
"pointer": "/nodes/0/displacement/2",
"scale": -0.1
},
"value": 0.301721,
"tolerance": {
"relative": 0.01
},
"reason": "hex20, 40 × 2 through the depth, L/h = 20: shear deformation (0.6 (h/L)² ≈ 0.15 % of the deflection) and the clamp's local restraint, both absent from the elastica"
},
{
"id": "u1",
"quantity": "tip shortening δ_h/L at P L²/(E I) = 1",
"measure": {
"command": "solve.probe",
"params": {
"step": "K1",
"at": [
[
10.0,
0,
0.25
]
]
},
"pointer": "/nodes/0/displacement/0",
"scale": -0.1
},
"value": 0.056433,
"tolerance": {
"relative": 0.02
},
"reason": "as δ_v; the shortening is the smaller, second-order quantity, so its relative error is about twice the deflection's"
},
{
"id": "v2",
"quantity": "tip deflection δ_v/L at P L²/(E I) = 2",
"measure": {
"command": "solve.probe",
"params": {
"step": "K2",
"at": [
[
10.0,
0,
0.25
]
]
},
"pointer": "/nodes/0/displacement/2",
"scale": -0.1
},
"value": 0.493457,
"tolerance": {
"relative": 0.01
},
"reason": "hex20, 40 × 2 through the depth, L/h = 20: shear deformation (0.6 (h/L)² ≈ 0.15 % of the deflection) and the clamp's local restraint, both absent from the elastica"
},
{
"id": "u2",
"quantity": "tip shortening δ_h/L at P L²/(E I) = 2",
"measure": {
"command": "solve.probe",
"params": {
"step": "K2",
"at": [
[
10.0,
0,
0.25
]
]
},
"pointer": "/nodes/0/displacement/0",
"scale": -0.1
},
"value": 0.160642,
"tolerance": {
"relative": 0.02
},
"reason": "as δ_v; the shortening is the smaller, second-order quantity, so its relative error is about twice the deflection's"
},
{
"id": "v5",
"quantity": "tip deflection δ_v/L at P L²/(E I) = 5",
"measure": {
"command": "solve.probe",
"params": {
"step": "K5",
"at": [
[
10.0,
0,
0.25
]
]
},
"pointer": "/nodes/0/displacement/2",
"scale": -0.1
},
"value": 0.713792,
"tolerance": {
"relative": 0.01
},
"reason": "hex20, 40 × 2 through the depth, L/h = 20: shear deformation (0.6 (h/L)² ≈ 0.15 % of the deflection) and the clamp's local restraint, both absent from the elastica"
},
{
"id": "u5",
"quantity": "tip shortening δ_h/L at P L²/(E I) = 5",
"measure": {
"command": "solve.probe",
"params": {
"step": "K5",
"at": [
[
10.0,
0,
0.25
]
]
},
"pointer": "/nodes/0/displacement/0",
"scale": -0.1
},
"value": 0.387628,
"tolerance": {
"relative": 0.02
},
"reason": "as δ_v; the shortening is the smaller, second-order quantity, so its relative error is about twice the deflection's"
},
{
"id": "v10",
"quantity": "tip deflection δ_v/L at P L²/(E I) = 10",
"measure": {
"command": "solve.probe",
"params": {
"step": "K10",
"at": [
[
10.0,
0,
0.25
]
]
},
"pointer": "/nodes/0/displacement/2",
"scale": -0.1
},
"value": 0.810609,
"tolerance": {
"relative": 0.01
},
"reason": "hex20, 40 × 2 through the depth, L/h = 20: shear deformation (0.6 (h/L)² ≈ 0.15 % of the deflection) and the clamp's local restraint, both absent from the elastica"
},
{
"id": "u10",
"quantity": "tip shortening δ_h/L at P L²/(E I) = 10",
"measure": {
"command": "solve.probe",
"params": {
"step": "K10",
"at": [
[
10.0,
0,
0.25
]
]
},
"pointer": "/nodes/0/displacement/0",
"scale": -0.1
},
"value": 0.554996,
"tolerance": {
"relative": 0.02
},
"reason": "as δ_v; the shortening is the smaller, second-order quantity, so its relative error is about twice the deflection's"
}
]
}
@@ -0,0 +1,37 @@
{
"note": "FieldCraft's accepted results for this case, written by `cargo xtask oracle --bless`. A result outside its band fails CI.",
"values": {
"u1": {
"band": 5.6632559447764666e-11,
"value": 0.056632559447764665
},
"u10": {
"band": 5.579973985797526e-10,
"value": 0.5579973985797526
},
"u2": {
"band": 1.6132061646961728e-10,
"value": 0.16132061646961726
},
"u5": {
"band": 3.895481979257076e-10,
"value": 0.3895481979257076
},
"v1": {
"band": 3.02260079032045e-10,
"value": 0.30226007903204494
},
"v10": {
"band": 8.142088468220408e-10,
"value": 0.8142088468220408
},
"v2": {
"band": 4.945495713426414e-10,
"value": 0.4945495713426413
},
"v5": {
"band": 7.159758984663589e-10,
"value": 0.7159758984663589
}
}
}
@@ -0,0 +1,21 @@
[
{"command": "mesh.block", "params": {"body": "Beam", "kind": "hex20", "corners": [[0, 0, 0], [10.0, 0, 0], [10.0, 1.0, 0], [0, 1.0, 0], [0, 0, 0.5], [10.0, 0, 0.5], [10.0, 1.0, 0.5], [0, 1.0, 0.5]], "divisions": [40, 1, 2], "faces": {"6": "root", "4": "tip"}}},
{"command": "model.set.create", "params": {"name": "all", "geometry": [{"body": "Beam"}]}},
{"command": "model.set.create", "params": {"name": "root", "geometry": [{"body": "Beam", "face": "root"}]}},
{"command": "model.set.create", "params": {"name": "tip", "geometry": [{"body": "Beam", "face": "tip"}]}},
{"command": "model.material.create", "params": {"name": "Steel", "elastic": {"type": "isotropic", "young": 10000.0, "poisson": 0.0}}},
{"command": "model.section.create", "params": {"name": "beam", "set": "all", "material": "Steel", "kind": {"type": "solid"}}},
{"command": "model.boundary_condition.create", "params": {"name": "clamp", "type": "fixed", "target": {"set": "root"}}},
{"command": "model.load.create", "params": {"name": "P1", "type": "force", "target": {"set": "tip"}, "vector": [0, 0, -1.0416666666666667]}},
{"command": "model.step.create", "params": {"name": "K1", "procedure": {"type": "nonlinear_static"}, "boundary_conditions": ["clamp"], "loads": ["P1"]}},
{"command": "model.load.create", "params": {"name": "P2", "type": "force", "target": {"set": "tip"}, "vector": [0, 0, -2.0833333333333335]}},
{"command": "model.step.create", "params": {"name": "K2", "procedure": {"type": "nonlinear_static"}, "boundary_conditions": ["clamp"], "loads": ["P2"]}},
{"command": "model.load.create", "params": {"name": "P5", "type": "force", "target": {"set": "tip"}, "vector": [0, 0, -5.208333333333334]}},
{"command": "model.step.create", "params": {"name": "K5", "procedure": {"type": "nonlinear_static"}, "boundary_conditions": ["clamp"], "loads": ["P5"]}},
{"command": "model.load.create", "params": {"name": "P10", "type": "force", "target": {"set": "tip"}, "vector": [0, 0, -10.416666666666668]}},
{"command": "model.step.create", "params": {"name": "K10", "procedure": {"type": "nonlinear_static"}, "boundary_conditions": ["clamp"], "loads": ["P10"]}},
{"command": "solve.nonlinear", "params": {"step": "K1"}, "id": "solve1"},
{"command": "solve.nonlinear", "params": {"step": "K2"}, "id": "solve2"},
{"command": "solve.nonlinear", "params": {"step": "K5"}, "id": "solve5"},
{"command": "solve.nonlinear", "params": {"step": "K10"}, "id": "solve10"}
]