verification: hyperelastic and thermal oracle cases and documentation

Five cases against closed forms: a Mooney-Rivlin block in Treloar's
uniaxial, equibiaxial and pure-shear modes and a Yeoh block in uniaxial
tension (the compressible energy's stresses, exact); a stretched
Mooney-Rivlin tube inflated by a follower pressure (Rivlin's incompressible
solution, 0.6 % at nu = 0.4995); free and fully held thermal expansion at a
thermal stretch of 1.2 (exact); a bar held at its ends heated past yield
(exact). docs/fem.md, the literature, ROADMAP (M15, M17), parity and the
oracle page 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 07:23:06 -04:00
1 parent 3f9e9e30d8
commit d586d84859
25 files changed
+648 -16

No files matched your search

+8
View File
@@ -0,0 +1,8 @@
# A heated bar held at its ends past yield
A steel bar 4 × 1 × 1 of 4 hex8 elements (E = 200000, ν = 0.3, σ_y = 250, H = 2000 isotropic,
α = 1.2·10⁻⁵ from 20 degrees) on symmetry planes at x = 0, y = 0, z = 0 and held at x = 4 (its
axial strain is zero; the lateral faces are free), heated uniformly to 320 by a temperature load
in a nonlinear static step without nonlinear geometry. The mechanical strain is −α ΔT = −0.0036,
2.9 times the yield strain, so the bar yields in compression: σ = −(σ_y + E_t (α ΔT − σ_y/E)) =
−254.653 with E_t = E H/(E + H), and ε_p = (|σ| − σ_y)/H.
+45
View File
@@ -0,0 +1,45 @@
{
"title": "A steel bar held at its ends and heated past yield (small strain)",
"kind": "theory",
"source": "Uniaxial J2 plasticity with linear hardening (Simo and Hughes, Computational Inelasticity, Springer 1998, §2.3) with the additive thermal strain: the bar's total axial strain is held at zero, so its mechanical strain is −α ΔT and σ = −(σ_y + E_t (α ΔT − σ_y/E)) once α ΔT exceeds σ_y/E",
"quantities": [
{
"id": "sigma",
"quantity": "axial stress, ΔT = 300 (α ΔT = 3.6·10⁻³, 2.9 times the yield strain)",
"measure": {
"command": "solve.probe",
"params": {
"step": "Heat",
"elements": [
2
]
},
"pointer": "/elements/0/stress/0/0"
},
"value": -254.65346534653466,
"tolerance": {
"relative": 1e-08
},
"reason": "a homogeneous uniaxial state the elements represent exactly"
},
{
"id": "plastic_strain",
"quantity": "equivalent plastic strain",
"measure": {
"command": "solve.probe",
"params": {
"step": "Heat",
"elements": [
2
]
},
"pointer": "/elements/0/plastic_strain/0"
},
"value": 0.0023267326732673297,
"tolerance": {
"relative": 1e-07
},
"reason": "(|σ| − σ_y)/H, as for the stress"
}
]
}
+13
View File
@@ -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": {
"plastic_strain": {
"band": 2.3267326732675587e-12,
"value": 0.0023267326732675587
},
"sigma": {
"band": 2.5465346534653467e-7,
"value": -254.6534653464418
}
}
}
+17
View File
@@ -0,0 +1,17 @@
[
{"command": "mesh.block", "params": {"body": "Bar", "kind": "hex8", "corners": [[0, 0, 0], [4, 0, 0], [4, 1, 0], [0, 1, 0], [0, 0, 1], [4, 0, 1], [4, 1, 1], [0, 1, 1]], "divisions": [4, 1, 1], "faces": {"6": "x0", "3": "y0", "1": "z0", "4": "x1"}}},
{"command": "model.set.create", "params": {"name": "all", "geometry": [{"body": "Bar"}]}},
{"command": "model.set.create", "params": {"name": "x0", "geometry": [{"body": "Bar", "face": "x0"}]}},
{"command": "model.set.create", "params": {"name": "y0", "geometry": [{"body": "Bar", "face": "y0"}]}},
{"command": "model.set.create", "params": {"name": "z0", "geometry": [{"body": "Bar", "face": "z0"}]}},
{"command": "model.set.create", "params": {"name": "x1", "geometry": [{"body": "Bar", "face": "x1"}]}},
{"command": "model.material.create", "params": {"name": "Steel", "elastic": {"type": "isotropic", "young": 200000.0, "poisson": 0.3}, "plastic": {"type": "bilinear", "yield_stress": 250.0, "hardening_modulus": 2000.0}, "thermal": {"expansion": 1.2e-05, "reference_temperature": 20.0}}},
{"command": "model.section.create", "params": {"name": "bar", "set": "all", "material": "Steel", "kind": {"type": "solid"}}},
{"command": "model.boundary_condition.create", "params": {"name": "sx0", "type": "symmetry", "target": {"set": "x0"}, "plane": "x"}},
{"command": "model.boundary_condition.create", "params": {"name": "sy0", "type": "symmetry", "target": {"set": "y0"}, "plane": "y"}},
{"command": "model.boundary_condition.create", "params": {"name": "sz0", "type": "symmetry", "target": {"set": "z0"}, "plane": "z"}},
{"command": "model.boundary_condition.create", "params": {"name": "sx1", "type": "symmetry", "target": {"set": "x1"}, "plane": "x"}},
{"command": "model.load.create", "params": {"name": "heat", "type": "temperature", "target": {"set": "all"}, "value": 320.0}},
{"command": "model.step.create", "params": {"name": "Heat", "procedure": {"type": "nonlinear_static", "nonlinear_geometry": false}, "boundary_conditions": ["sx0", "sy0", "sz0", "sx1"], "loads": ["heat"]}},
{"command": "solve.nonlinear", "params": {"step": "Heat"}, "id": "solve"}
]