Verification oracle: tests/oracle cases, cargo xtask oracle, fixtures, docs/oracle.md, CI job

The oracle binary (modelcraft-testkit) runs each case's recipe through the
command engine, measures its quantities by JSON pointers into step outputs
or commands, compares them with the cited references and the frozen
fixtures, and writes docs/oracle.md. 20 theory cases (patch tests of every
solid element, Timoshenko cantilevers, Lame, Kirsch, beam frequencies,
torsion and bending through couplings, explicit waves and impact, CDT
invariants), 8 published benchmarks (MacNeal-Harder patch, straight and
curved cantilevers, thick cylinder, Scordelis-Lo with solids, NAFEMS LE1,
LE10, FV32) and 10 pending cases with citations.

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-13 21:42:19 -04:00
1 parent a3cb6d749b
commit 6d9452ad84
144 files changed
+5162 -74

No files matched your search

+8
View File
@@ -0,0 +1,8 @@
# NAFEMS LE1 elliptic membrane (hex20 plane stress layer)
Our model of the published problem: the quarter membrane between the ellipses (x/2)² + y² = 1 and
(x/3.25)² + (y/2.75)² = 1, thickness 0.1, E = 210 GPa, ν = 0.3 (MPa and m), u_x = 0 on AB (x = 0),
u_y = 0 on CD (y = 0), an outward pressure of 10 MPa on the outer edge BC. Plane stress is
modelled by half the thickness of hex20 elements with a symmetry plane at the mid-surface and the
other face free: 24 × 48 elements graded 4 : 1 towards the hole, converged at D (32 × 64 with
the same grading changes σ_yy there by 0.003%).
+30
View File
@@ -0,0 +1,30 @@
{
"title": "NAFEMS LE1 elliptic membrane (hex20 plane stress layer)",
"kind": "benchmark",
"source": "NAFEMS, The Standard NAFEMS Benchmarks, TNSB Rev. 3, October 1990, test LE1 (target σ_yy = 92.7 MPa at D); as reproduced in the Abaqus 2017 Benchmarks Guide, 'LE1: Plane stress elements—elliptic membrane'",
"quantities": [
{
"id": "syy_D",
"quantity": "σ_yy at D (2, 0)",
"measure": {
"command": "solve.probe",
"params": {
"step": "Load",
"at": [
[
2,
0,
0
]
]
},
"pointer": "/nodes/0/stress/1"
},
"value": 92.7,
"tolerance": {
"relative": 0.01
},
"reason": "the target is published to three figures; plane stress modelled by a thin solid layer and the stress extrapolated to the edge add a few tenths of a percent"
}
]
}
+9
View File
@@ -0,0 +1,9 @@
{
"note": "ModelCraft's accepted results for this case, written by `cargo xtask oracle --bless`. A result outside its band fails CI.",
"values": {
"syy_D": {
"band": 9.286850287265874e-8,
"value": 92.86850287265874
}
}
}
+16
View File
@@ -0,0 +1,16 @@
[
{"command": "mesh.block", "params": {"body": "Membrane", "kind": "hex20", "corners": [[2, 0, 0], [3.25, 0, 0], [0, 2.75, 0], [0, 1, 0], [2, 0, 0.05], [3.25, 0, 0.05], [0, 2.75, 0.05], [0, 1, 0.05]], "divisions": [24, 48, 1], "bias": [4, 1, 1], "edges": [{"corners": [1, 4], "ellipse": {"center": [0, 0, 0], "axes": [[2, 0, 0], [0, 1, 0]]}}, {"corners": [2, 3], "ellipse": {"center": [0, 0, 0], "axes": [[3.25, 0, 0], [0, 2.75, 0]]}}, {"corners": [5, 8], "ellipse": {"center": [0, 0, 0.05], "axes": [[2, 0, 0], [0, 1, 0]]}}, {"corners": [6, 7], "ellipse": {"center": [0, 0, 0.05], "axes": [[3.25, 0, 0], [0, 2.75, 0]]}}], "faces": {"5": "AB", "3": "CD", "4": "BC", "1": "mid"}}},
{"command": "model.set.create", "params": {"name": "all", "geometry": [{"body": "Membrane"}]}},
{"command": "model.set.create", "params": {"name": "AB", "geometry": [{"body": "Membrane", "face": "AB"}]}},
{"command": "model.set.create", "params": {"name": "CD", "geometry": [{"body": "Membrane", "face": "CD"}]}},
{"command": "model.set.create", "params": {"name": "BC", "geometry": [{"body": "Membrane", "face": "BC"}]}},
{"command": "model.set.create", "params": {"name": "mid", "geometry": [{"body": "Membrane", "face": "mid"}]}},
{"command": "model.material.create", "params": {"name": "Steel", "elastic": {"type": "isotropic", "young": 210000.0, "poisson": 0.3}}},
{"command": "model.section.create", "params": {"name": "membrane", "set": "all", "material": "Steel", "kind": {"type": "solid"}}},
{"command": "model.boundary_condition.create", "params": {"name": "ab", "type": "symmetry", "target": {"set": "AB"}, "plane": "x"}},
{"command": "model.boundary_condition.create", "params": {"name": "cd", "type": "symmetry", "target": {"set": "CD"}, "plane": "y"}},
{"command": "model.boundary_condition.create", "params": {"name": "mid", "type": "symmetry", "target": {"set": "mid"}, "plane": "z"}},
{"command": "model.load.create", "params": {"name": "p", "type": "pressure", "set": "BC", "magnitude": -10.0}},
{"command": "model.step.create", "params": {"name": "Load", "procedure": {"type": "static"}, "boundary_conditions": ["ab", "cd", "mid"], "loads": ["p"]}},
{"command": "solve.static", "params": {}, "id": "solve"}
]