oracle: filleted L-bracket on the octree all-hex mesh

A slow theory case: the corpus bracket meshed by mesh.hex.octree at 7, 5 and 4 mm, clamped
at the base and loaded by 2 kN. Checks equilibrium, that every element is certified valid,
the mesh volume against the CAD volume, the beam bending stress of the upright leg
(sigma = M c / I = 145.3 MPa, within 5%) and the convergence of the fillet von Mises stress
against the 4 mm mesh.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
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:38:11 -04:00
1 parent 7d2696057f
commit a719ae7e5b
6 files changed
+479 -1

No files matched your search

+9 -1
View File
@@ -2,7 +2,7 @@
Generated by `cargo xtask oracle` from [`tests/oracle/`](../tests/oracle/); the policy is [verification.md](verification.md). Every case is our own model, built with FieldCraft commands from the problem's published description, and compared with the reference value its `expected.json` cites, within the stated tolerance and for the stated reason. Accepted results are frozen in each case's `fixture.json`: a later change that moves one beyond its band (10⁻⁹ of its size) fails CI even while the reference still passes. No reference value was produced with a commercial product.
**163 of 169 quantities pass** (6 known failure(s)) in 49 active cases: 40 theory, 9 published benchmark, 0 experiment; 9 pending cases wait for capabilities still being built.
**170 of 176 quantities pass** (6 known failure(s)) in 50 active cases: 41 theory, 9 published benchmark, 0 experiment; 9 pending cases wait for capabilities still being built.
## Theory: closed-form solutions, patch tests and mesh invariants
@@ -90,6 +90,13 @@ Generated by `cargo xtask oracle` from [`tests/oracle/`](../tests/oracle/); the
| [nl-thermal-expansion](../tests/oracle/nl-thermal-expansion/) | stress of the held block, σ_xx (hydrostatic) | -3.5108 | -3.5108 | < 1e-7% | 1e-8 rel. | pass | matches |
| [nl-yeoh-uniaxial](../tests/oracle/nl-yeoh-uniaxial/) | axial Cauchy stress, stretch λ = 2 | 3.1743 | 3.1743 | < 1e-7% | 1e-6 rel. | pass | matches |
| [nl-yeoh-uniaxial](../tests/oracle/nl-yeoh-uniaxial/) | lateral displacement at (1, 1, 1): l − 1 | -0.28545 | -0.28545 | < 1e-7% | 1e-6 rel. | pass | matches |
| [octree-filleted-bracket](../tests/oracle/octree-filleted-bracket/) | x reaction on the clamped face (5 mm mesh) | -2000 | -2000 | < 1e-7% | 1e-6 rel. | pass | matches |
| [octree-filleted-bracket](../tests/oracle/octree-filleted-bracket/) | elements the certified Jacobian check does not prove valid (5 mm mesh) | 0 | 0 | ≈ 0 | exact | pass | matches |
| [octree-filleted-bracket](../tests/oracle/octree-filleted-bracket/) | mesh volume against the CAD volume (5 mm mesh) | 32145 | 32177 | 0.1% | 0.3% | pass | matches |
| [octree-filleted-bracket](../tests/oracle/octree-filleted-bracket/) | σ_yy on the outer face of the upright leg at y = 19, z = 6 (5 mm mesh) | 145.31 | 149.26 | 2.72% | 5% | pass | matches |
| [octree-filleted-bracket](../tests/oracle/octree-filleted-bracket/) | σ_yy on the inner face of the upright leg at y = 19, z = 6 (5 mm mesh) | -145.31 | -147.28 | -1.35% | 5% | pass | matches |
| [octree-filleted-bracket](../tests/oracle/octree-filleted-bracket/) | von Mises stress at the middle of the fillet, 7 mm mesh | 143.21 | 138.53 | -3.27% | 5% | pass | matches |
| [octree-filleted-bracket](../tests/oracle/octree-filleted-bracket/) | von Mises stress at the middle of the fillet, 5 mm mesh | 143.21 | 144.53 | 0.921% | 2% | pass | matches |
| [patch-hex20](../tests/oracle/patch-hex20/) | u_x at the corner (1, 1, 1) | -2.5000e-4 | -2.5000e-4 | < 1e-7% | 1e-9 rel. | pass | matches |
| [patch-hex20](../tests/oracle/patch-hex20/) | u_y at the corner (1, 1, 1) | 0.001 | 0.001 | < 1e-7% | 1e-9 rel. | pass | matches |
| [patch-hex20](../tests/oracle/patch-hex20/) | u_z at the corner (1, 1, 1) | 0.00225 | 0.00225 | < 1e-7% | 1e-9 rel. | pass | matches |
@@ -220,6 +227,7 @@ Generated by `cargo xtask oracle` from [`tests/oracle/`](../tests/oracle/); the
- **[nl-rigid-rotation](../tests/oracle/nl-rigid-rotation/)** (theory): A quarter turn strains and stresses nothing (objectivity). Source: Objectivity of the total Lagrangian formulation and of the hyperelastic stress: a rigid motion x = R X + c gives C = I and σ = 0 whatever the rotation (Bonet & Wood 2008, §3.4 and §5.2; T. Belytschko, W. K. Liu, B. Moran, Nonlinear Finite Elements for Continua and Structures, 2nd ed., Wiley 2014, §5.5). Tolerances — ux: the inner nodes follow the rigid rotation exactly; uy: the inner nodes follow the rigid rotation exactly; uz: the inner nodes follow the rigid rotation exactly; von_mises: zero up to rounding of stresses of order E = 1000: a 90° turn leaves no strain
- **[nl-thermal-expansion](../tests/oracle/nl-thermal-expansion/)** (theory): Free and fully constrained thermal expansion at finite strain. Source: The multiplicative split F = F_m F_θ with F_θ = (1 + α ΔT) I (V. A. Lubarda, Appl. Mech. Rev. 57(2):95–108, 2004): a free body follows F = F_θ stress-free; held on every face, F = I and F_m = ϑ⁻¹ I, so the compressible neo-Hookean material carries the pressure of its volume ratio, σ = κ (ϑ⁻³ − 1). Tolerances — free_u: a homogeneous stretch every element represents exactly; free_stress: rounding only; held_stress: a homogeneous state; E = 10, ν = 0.3 (κ = 8.3333), ϑ = 1.2
- **[nl-yeoh-uniaxial](../tests/oracle/nl-yeoh-uniaxial/)** (theory): Yeoh block in uniaxial tension. Source: Uniaxial tension of the decoupled compressible Yeoh energy W = C₁₀ (Ī₁ − 3) + C₂₀ (Ī₁ − 3)² + C₃₀ (Ī₁ − 3)³ + κ/2 (J − 1)² (O. H. Yeoh, Rubber Chem. Technol. 66(5):754–771, 1993): σ = (λ/J) ∂W/∂λ with the lateral stretch found so σ_yy = 0 (bisection; E = 3, ν = 0.49, C₁₀ = μ/2, C₂₀ = −0.02, C₃₀ = 0.004). Tolerances — sigma: a homogeneous deformation the hybrid hex20 represents exactly: the tolerance admits the Newton tolerance and rounding; lateral: a homogeneous deformation the hybrid hex20 represents exactly: the tolerance admits the Newton tolerance and rounding
- **[octree-filleted-bracket](../tests/oracle/octree-filleted-bracket/)** (theory): Filleted L-bracket on the octree all-hex mesh: equilibrium, beam bending, fillet stress convergence. Source: equilibrium; Euler–Bernoulli bending of the 8 × 40 mm leg, σ = M c / I with M = F (50 − y) (S. P. Timoshenko, J. N. Goodier, Theory of Elasticity, 3rd ed., 1970, §102); grid convergence of the fillet stress against the 4 mm mesh of this case (P. J. Roache, Verification and Validation in Computational Science and Engineering, 1998, ch. 5). Tolerances — reaction_x: the reactions balance the 2 kN load to solver precision; invalid: the octree mesher returns only elements proven valid; volume: bilinear boundary faces on the R6 fillet and the two Ø8 holes, and the 1e-3 chordal tessellation they are fitted to; syy_outer: beam theory ignores the corner 5 mm below and the hole 9 mm above; the probe takes the nearest node's extrapolated stress; syy_inner: as for the outer face; fillet_7: the coarsest mesh, within 5% of the 4 mm mesh; fillet_5: converging: within 2% of the 4 mm mesh
- **[patch-hex20](../tests/oracle/patch-hex20/)** (theory): Constant-stress patch test, hex20. Source: Irons and Razzaque, 'Experience with the patch test for convergence of finite elements', in Aziz (ed.), The Mathematical Foundations of the Finite Element Method, Academic Press 1972, pp. 557–587; MacNeal and Harder, Finite Elements in Analysis and Design 1 (1985) 3–20, constant-stress loading, p. 14 Table 7. Tolerances — ux: a patch test is passed exactly: the tolerance only admits rounding; uy: a patch test is passed exactly: the tolerance only admits rounding; uz: a patch test is passed exactly: the tolerance only admits rounding; sxx: a patch test is passed exactly: the tolerance only admits rounding; syy: a patch test is passed exactly: the tolerance only admits rounding; szz: a patch test is passed exactly: the tolerance only admits rounding; sxy: a patch test is passed exactly: the tolerance only admits rounding (stresses of order 1)
- **[patch-hex20-reduced](../tests/oracle/patch-hex20-reduced/)** (theory): Constant-stress patch test, hex20-reduced. Source: Irons and Razzaque, 'Experience with the patch test for convergence of finite elements', in Aziz (ed.), The Mathematical Foundations of the Finite Element Method, Academic Press 1972, pp. 557–587; MacNeal and Harder, Finite Elements in Analysis and Design 1 (1985) 3–20, constant-stress loading, p. 14 Table 7. Tolerances — ux: a patch test is passed exactly: the tolerance only admits rounding; uy: a patch test is passed exactly: the tolerance only admits rounding; uz: a patch test is passed exactly: the tolerance only admits rounding; sxx: a patch test is passed exactly: the tolerance only admits rounding; syy: a patch test is passed exactly: the tolerance only admits rounding; szz: a patch test is passed exactly: the tolerance only admits rounding; sxy: a patch test is passed exactly: the tolerance only admits rounding (stresses of order 1)
- **[patch-hex8](../tests/oracle/patch-hex8/)** (theory): Constant-stress patch test, hex8. Source: Irons and Razzaque, 'Experience with the patch test for convergence of finite elements', in Aziz (ed.), The Mathematical Foundations of the Finite Element Method, Academic Press 1972, pp. 557–587; MacNeal and Harder, Finite Elements in Analysis and Design 1 (1985) 3–20, constant-stress loading, p. 14 Table 7. Tolerances — ux: a patch test is passed exactly: the tolerance only admits rounding; uy: a patch test is passed exactly: the tolerance only admits rounding; uz: a patch test is passed exactly: the tolerance only admits rounding; sxx: a patch test is passed exactly: the tolerance only admits rounding; syy: a patch test is passed exactly: the tolerance only admits rounding; szz: a patch test is passed exactly: the tolerance only admits rounding; sxy: a patch test is passed exactly: the tolerance only admits rounding (stresses of order 1)
@@ -0,0 +1,21 @@
# Filleted L-bracket on the octree all-hex mesh
The corpus part `filleted-bracket` (an 8 mm thick L, 60 × 50 × 40 mm, an R6 fillet inside the
corner and a Ø8 hole through each leg), built with SolidCraft from `design.json` and meshed by
`mesh.hex.octree` (hex8 with incompatible modes, steel E = 210 GPa, ν = 0.3). The bottom face of
the horizontal leg (`F2:side:l1`) is clamped and the top face of the upright leg (`F2:side:l5`)
carries 2 kN along +x.
Checked on the 5 mm mesh: equilibrium; the certified validity of every element; the mesh volume
against the CAD volume; the bending stress of the upright leg at y = 19 on both faces,
σ_yy = M c / I = 2000 · 31 · 4 / 1706.7 = 145.3 MPa (M is exact by statics, the plane-section
stress is the reference, the corner and a hole are near). The von Mises stress at the middle of
the fillet, which has no closed form, is checked for convergence against the 4 mm mesh:
| mesh size | hexahedra | fillet von Mises (MPa) | σ_yy outer / inner at y = 19 (MPa) |
|---|---|---|---|
| 7 mm | 4291 | 138.5 | 149.4 / −146.9 |
| 5 mm | 13273 | 144.5 | 149.3 / −147.3 |
| 4 mm (reference) | 21508 | 143.2 | 147.4 / −145.5 |
A 3 mm mesh needs more than the direct solver's factor cap.
@@ -0,0 +1,89 @@
{
"commands": [
{
"command": "sketch.create",
"params": {
"plane": "XY",
"name": "Profile"
}
},
{
"command": "sketch.line",
"params": {
"points": [
[
0,
0
],
[
60,
0
],
[
60,
8
],
[
8,
8
],
[
8,
50
],
[
0,
50
]
],
"closed": true
}
},
{
"command": "sketch.finish",
"params": {}
},
{
"command": "solid.extrude",
"params": {
"distance": 40,
"body_name": "Bracket"
}
},
{
"command": "solid.fillet",
"params": {
"edges": [
[
8,
8,
20
]
],
"radius": 6
}
},
{
"command": "solid.hole",
"params": {
"position": [
40,
8,
20
],
"diameter": 8
}
},
{
"command": "solid.hole",
"params": {
"position": [
8,
32,
20
],
"diameter": 8
}
}
]
}
@@ -0,0 +1,99 @@
{
"title": "Filleted L-bracket on the octree all-hex mesh: equilibrium, beam bending, fillet stress convergence",
"kind": "theory",
"source": "equilibrium; Euler–Bernoulli bending of the 8 × 40 mm leg, σ = M c / I with M = F (50 − y) (S. P. Timoshenko, J. N. Goodier, Theory of Elasticity, 3rd ed., 1970, §102); grid convergence of the fillet stress against the 4 mm mesh of this case (P. J. Roache, Verification and Validation in Computational Science and Engineering, 1998, ch. 5)",
"slow": true,
"quantities": [
{
"id": "reaction_x",
"quantity": "x reaction on the clamped face (5 mm mesh)",
"measure": {
"from": "solve5",
"pointer": "/reaction_total/0"
},
"value": -2000.0,
"tolerance": {
"relative": 1e-06
},
"reason": "the reactions balance the 2 kN load to solver precision"
},
{
"id": "invalid",
"quantity": "elements the certified Jacobian check does not prove valid (5 mm mesh)",
"measure": {
"from": "quality5",
"pointer": "/invalid/count"
},
"value": 0.0,
"tolerance": {
"exact": true
},
"reason": "the octree mesher returns only elements proven valid"
},
{
"id": "volume",
"quantity": "mesh volume against the CAD volume (5 mm mesh)",
"measure": {
"from": "mesh5",
"pointer": "/bodies/0/volume"
},
"value": 32144.778925,
"tolerance": {
"relative": 0.003
},
"reason": "bilinear boundary faces on the R6 fillet and the two Ø8 holes, and the 1e-3 chordal tessellation they are fitted to"
},
{
"id": "syy_outer",
"quantity": "σ_yy on the outer face of the upright leg at y = 19, z = 6 (5 mm mesh)",
"measure": {
"from": "probe5",
"pointer": "/nodes/1/stress/1"
},
"value": 145.3125,
"tolerance": {
"relative": 0.05
},
"reason": "beam theory ignores the corner 5 mm below and the hole 9 mm above; the probe takes the nearest node's extrapolated stress"
},
{
"id": "syy_inner",
"quantity": "σ_yy on the inner face of the upright leg at y = 19, z = 6 (5 mm mesh)",
"measure": {
"from": "probe5",
"pointer": "/nodes/2/stress/1"
},
"value": -145.3125,
"tolerance": {
"relative": 0.05
},
"reason": "as for the outer face"
},
{
"id": "fillet_7",
"quantity": "von Mises stress at the middle of the fillet, 7 mm mesh",
"measure": {
"from": "probe7",
"pointer": "/nodes/0/von_mises"
},
"value": 143.21,
"tolerance": {
"relative": 0.05
},
"reason": "the coarsest mesh, within 5% of the 4 mm mesh"
},
{
"id": "fillet_5",
"quantity": "von Mises stress at the middle of the fillet, 5 mm mesh",
"measure": {
"from": "probe5",
"pointer": "/nodes/0/von_mises"
},
"value": 143.21,
"tolerance": {
"relative": 0.02
},
"reason": "converging: within 2% of the 4 mm mesh"
}
]
}
@@ -0,0 +1,33 @@
{
"note": "FieldCraft's accepted results for this case, written by `cargo xtask oracle --bless`. A result outside its band fails CI.",
"values": {
"fillet_5": {
"band": 1.4452906175564113e-7,
"value": 144.52906175564112
},
"fillet_7": {
"band": 1.4321000000000002e-7,
"value": 138.5286423070889
},
"invalid": {
"band": 0.0,
"value": 0.0
},
"reaction_x": {
"band": 2.0000000000000003e-6,
"value": -1999.999999998785
},
"syy_inner": {
"band": 1.472793063397077e-7,
"value": -147.2793063397077
},
"syy_outer": {
"band": 1.4926027331710374e-7,
"value": 149.26027331710372
},
"volume": {
"band": 0.00003217691091849411,
"value": 32176.910918494108
}
}
}
@@ -0,0 +1,228 @@
[
{
"command": "model.material.create",
"params": {
"name": "Steel",
"elastic": {
"type": "isotropic",
"young": 210000.0,
"poisson": 0.3
}
}
},
{
"command": "mesh.hex.octree",
"params": {
"body": "Bracket",
"size": 7.0
},
"id": "mesh7"
},
{
"command": "model.set.create",
"params": {
"name": "all",
"geometry": [
{
"body": "Bracket"
}
]
}
},
{
"command": "model.set.create",
"params": {
"name": "base",
"geometry": [
{
"body": "Bracket",
"face": "F2:side:l1"
}
]
}
},
{
"command": "model.set.create",
"params": {
"name": "top",
"geometry": [
{
"body": "Bracket",
"face": "F2:side:l5"
}
]
}
},
{
"command": "model.section.create",
"params": {
"name": "solid",
"set": "all",
"material": "Steel",
"kind": {
"type": "solid"
},
"formulation": {
"incompatible_modes": true
}
}
},
{
"command": "model.boundary_condition.create",
"params": {
"name": "clamp",
"type": "fixed",
"target": {
"set": "base"
}
}
},
{
"command": "model.load.create",
"params": {
"name": "F",
"type": "force",
"target": {
"set": "top"
},
"vector": [
2000.0,
0,
0
]
}
},
{
"command": "model.step.create",
"params": {
"name": "Load",
"procedure": {
"type": "static"
},
"boundary_conditions": [
"clamp"
],
"loads": [
"F"
]
}
},
{
"command": "mesh.quality",
"params": {},
"id": "quality7"
},
{
"command": "solve.static",
"params": {},
"id": "solve7"
},
{
"command": "solve.probe",
"params": {
"step": "Load",
"at": [
[
9.757359312880714,
9.757359312880714,
10.0
],
[
0.0,
19.0,
6.0
],
[
8.0,
19.0,
6.0
]
]
},
"id": "probe7"
},
{
"command": "mesh.hex.octree",
"params": {
"body": "Bracket",
"size": 5.0
},
"id": "mesh5"
},
{
"command": "mesh.quality",
"params": {},
"id": "quality5"
},
{
"command": "solve.static",
"params": {},
"id": "solve5"
},
{
"command": "solve.probe",
"params": {
"step": "Load",
"at": [
[
9.757359312880714,
9.757359312880714,
10.0
],
[
0.0,
19.0,
6.0
],
[
8.0,
19.0,
6.0
]
]
},
"id": "probe5"
},
{
"command": "mesh.hex.octree",
"params": {
"body": "Bracket",
"size": 4.0
},
"id": "mesh4"
},
{
"command": "mesh.quality",
"params": {},
"id": "quality4"
},
{
"command": "solve.static",
"params": {},
"id": "solve4"
},
{
"command": "solve.probe",
"params": {
"step": "Load",
"at": [
[
9.757359312880714,
9.757359312880714,
10.0
],
[
0.0,
19.0,
6.0
],
[
8.0,
19.0,
6.0
]
]
},
"id": "probe4"
}
]