forked from 1b-agent/fieldcraft-upstream
tests: add NAFEMS LE2 and LE3 shell oracle cases
LE2, the cylindrical shell bending patch test, in its two load cases (edge moment; pressure with the balancing edge traction) on an 8 × 8 MITC4 patch: tangential stress at E 59.936 and 59.904 against 60. LE3, the hemispherical shell with point loads, on a 32 × 32 longitude-latitude mesh (planar quad4 cells, tri3 at the pole): radial displacement at A 0.18418 against 0.185. Both meshes are written node by node from the generator each README lists, with the refinement that supports its tolerance. Targets are transcribed from the reproductions of TNSB Rev. 3 in the Abaqus 2016 Benchmarks Guide and the ESRD StressCheck NAFEMS guide. Part of #97.
This commit is contained in:
1 parent
853131e5a1
commit
68aff646b2
9 files changed
+2547
-1
No files matched your search
+6
-1
@@ -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.
|
||||
|
||||
**277 of 283 quantities pass** (6 known failure(s)) in 73 active cases: 62 theory, 11 published benchmark, 0 experiment; 8 pending cases wait for capabilities still being built.
|
||||
**280 of 286 quantities pass** (6 known failure(s)) in 75 active cases: 62 theory, 13 published benchmark, 0 experiment; 8 pending cases wait for capabilities still being built.
|
||||
|
||||
## Theory: closed-form solutions, patch tests and mesh invariants
|
||||
|
||||
@@ -293,6 +293,9 @@ Generated by `cargo xtask oracle` from [`tests/oracle/`](../tests/oracle/); the
|
||||
| [nafems-le1](../tests/oracle/nafems-le1/) | σ_yy at D (2, 0) | 92.7 | 92.869 | 0.182% | 1% | pass | matches |
|
||||
| [nafems-le1-plane-stress](../tests/oracle/nafems-le1-plane-stress/) | σ_yy at D (2, 0) | 92.7 | 92.648 | -0.0559% | 1% | pass | matches |
|
||||
| [nafems-le10](../tests/oracle/nafems-le10/) | σ_yy at D (2, 0, 0.3) on the loaded face | -5.38 | -5.3339 | 0.857% | 2% | pass | matches |
|
||||
| [nafems-le2](../tests/oracle/nafems-le2/) | tangential stress at E, outer surface, load case 1 (edge moment) | 60 | 59.936 | -0.107% | 1% | pass | matches |
|
||||
| [nafems-le2](../tests/oracle/nafems-le2/) | tangential stress at E, outer surface, load case 2 (pressure and edge traction) | 60 | 59.904 | -0.161% | 1% | pass | matches |
|
||||
| [nafems-le3](../tests/oracle/nafems-le3/) | radial displacement at A (10, 0, 0), m | 0.185 | 0.18418 | -0.446% | 2% | pass | matches |
|
||||
| [pinched-cylinder](../tests/oracle/pinched-cylinder/) | radial displacement under the load, mid-surface | -1.8248e-5 | -1.8038e-5 | 1.15% | 2% | pass | matches |
|
||||
| [scordelis-lo-roof-shell](../tests/oracle/scordelis-lo-roof-shell/) | vertical displacement at the midpoint of the free edge, mid-surface | -0.3024 | -0.29901 | 1.12% | 2% | pass | matches |
|
||||
| [scordelis-lo-roof-solid](../tests/oracle/scordelis-lo-roof-solid/) | vertical displacement at the midpoint of the free edge, mid-surface | -0.3024 | -0.3014 | 0.33% | 2% | pass | matches |
|
||||
@@ -335,6 +338,8 @@ Generated by `cargo xtask oracle` from [`tests/oracle/`](../tests/oracle/); the
|
||||
- **[nafems-le1](../tests/oracle/nafems-le1/)** (benchmark): NAFEMS LE1 elliptic membrane (hex20 plane stress layer). 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'. Tolerances — syy_D: 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
|
||||
- **[nafems-le1-plane-stress](../tests/oracle/nafems-le1-plane-stress/)** (benchmark): NAFEMS LE1 elliptic membrane with 2D plane stress elements (quad8). 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'. Tolerances — syy_D: the target is published to three figures; the stress extrapolated to the edge on a converged mesh adds a few tenths of a percent
|
||||
- **[nafems-le10](../tests/oracle/nafems-le10/)** (benchmark): NAFEMS LE10 thick plate under pressure (hex20). Source: NAFEMS, The Standard NAFEMS Benchmarks, TNSB Rev. 3, October 1990, test LE10 (target σ_yy = −5.38 MPa at D); as reproduced in the Abaqus 2017 Benchmarks Guide, 'LE10: Thick plate under pressure'. Tolerances — syy_D: the target is published to three figures; at D the stress is extrapolated to a corner where the hole edge meets the loaded face, and published converged solutions scatter by 1–2% (Abaqus Benchmarks Guide fine meshes: −5.51 to −5.89)
|
||||
- **[nafems-le2](../tests/oracle/nafems-le2/)** (benchmark): NAFEMS LE2 cylindrical shell bending patch test (MITC4 shells). Source: NAFEMS, The Standard NAFEMS Benchmarks, TNSB Rev. 3, October 1990, test LE2 (target: tangential stress 60 MPa on the outer surface at E, both load cases); the problem and target as reproduced in the Abaqus 2016 Benchmarks Guide, section 4.2.2 'LE2: Cylindrical shell bending patch test', and in the ESRD StressCheck Benchmarks Guide 'The Standard NAFEMS Benchmarks: Linear Elastic Tests' (2018), p. 8. Tolerances — stt_E_moment: the target is the exact thin-shell value (6M/t²) and the stress is uniform over the patch; the 8 × 8 flat facets tilt the element axes by ±1.875° from the hoop direction, which moves 0.1% of it into σ_zz, and 16 × 16 is within 0.03% (see README); stt_E_pressure: the target is the exact membrane value (pR/t) and the stress is uniform over the patch; as in load case 1 the facets' tilt and the pressure on flat facets keep 8 × 8 within 0.2%, 16 × 16 within 0.05% (see README)
|
||||
- **[nafems-le3](../tests/oracle/nafems-le3/)** (benchmark): NAFEMS LE3 hemispherical shell with point loads (MITC4 shells). Source: NAFEMS, The Standard NAFEMS Benchmarks, TNSB Rev. 3, October 1990, test LE3 (target: radial displacement 0.185 m at A); the problem and target as reproduced in the Abaqus 2016 Benchmarks Guide, section 4.2.3 'LE3: Hemispherical shell with point loads', and in the ESRD StressCheck Benchmarks Guide 'The Standard NAFEMS Benchmarks: Linear Elastic Tests' (2018), p. 12. Tolerances — ur_A: the target is published to three figures; the displacement under a point load on a shear-deformable shell keeps growing slowly as the mesh is refined (32 × 32 is 0.44% low, 64 × 64 0.16%; see README)
|
||||
- **[nl-contact-patch](../tests/oracle/nl-contact-patch/)** (theory): Contact patch test: two blocks with non-matching meshes in uniaxial compression (implicit mortar contact). Source: The contact patch test: a contact discretisation must transmit a uniform pressure across a non-matching interface exactly; Taylor & Papadopoulos, On a patch test for contact problems in two dimensions, Nonlinear Computational Mechanics, Springer 1991, 690–702; Crisfield, Re-visiting the contact patch test, IJNME 48:435–449, 2000; passed by mortar methods: Puso & Laursen, CMAME 193:601–629, 2004. Uniaxial stress between frictionless symmetry planes is uniform in both blocks. Tolerances — small_lower_corner: small sliding is linear and its mortar integrals exact on these rectangular faces: a uniform stress is the discrete solution up to the convergence tolerance (10⁻¹⁰); small_lower_centre: as for the corner element; small_lower_base: as for the corner element; small_upper_top: as for the corner element; small_lateral: frictionless symmetry planes and a frictionless interface leave the blocks free to expand sideways; the non-matching interface must not hold them; small_pressure: the mortar multipliers are the nodal values of the contact pressure, uniform and equal to the stress across the interface; small_force: the pressure carries the whole load across the interface; finite_lower_corner: finite sliding is exact up to the geometric terms of the gaps the augmentation leaves (10⁻⁵ of the element thickness) and the default convergence tolerances; finite_lower_centre: as for the corner element; finite_lower_base: as for the corner element; finite_upper_top: as for the corner element; finite_lateral: frictionless symmetry planes and a frictionless interface leave the blocks free to expand sideways; the non-matching interface must not hold them; finite_pressure: the mortar multipliers are the nodal values of the contact pressure, uniform and equal to the stress across the interface; finite_force: the pressure carries the whole load across the interface; small_stress: the squeeze less the penetration the augmented Lagrangian leaves (up to 10⁻⁵ of the element thickness, a few 10⁻⁵ of the squeeze)
|
||||
- **[nl-contact-patch-axisymmetric](../tests/oracle/nl-contact-patch-axisymmetric/)** (theory): Contact patch test, axisymmetric: two rings with non-matching edges in axial compression (implicit mortar contact). Source: The contact patch test: a contact discretisation must transmit a uniform pressure across a non-matching interface exactly; Taylor & Papadopoulos, On a patch test for contact problems in two dimensions, Nonlinear Computational Mechanics, Springer 1991, 690–702; passed by 2D mortar methods: Yang, Laursen & Meng, IJNME 62:1183–1225, 2005. Uniaxial stress between frictionless supports is uniform in both blocks. Tolerances — small_lower_corner: small sliding is linear and its edge mortar integrals exact (degree-3 Gauss on the overlaps): the uniform stress is the discrete solution up to the convergence tolerance; small_lower_far: as for the corner element; small_lower_base: as for the corner element; small_upper_top: as for the corner element; small_lateral: a frictionless interface (and symmetry plane) leaves the blocks free to expand sideways; the non-matching interface must not hold them; small_pressure: the mortar multipliers are the nodal values of the contact pressure, uniform and equal to the stress across the interface; small_force: the pressure carries the whole load across the interface (both are totals over the circumference); finite_lower_corner: finite sliding is exact up to the geometric terms of the gaps the augmentation leaves (10⁻⁵ of the element thickness) and the default convergence tolerances; finite_lower_far: as for the corner element; finite_lower_base: as for the corner element; finite_upper_top: as for the corner element; finite_lateral: a frictionless interface (and symmetry plane) leaves the blocks free to expand sideways; the non-matching interface must not hold them; finite_pressure: the mortar multipliers are the nodal values of the contact pressure, uniform and equal to the stress across the interface; finite_force: the pressure carries the whole load across the interface (both are totals over the circumference); small_stress: the squeeze less the penetration the augmented Lagrangian leaves (up to 10⁻⁵ of the element thickness)
|
||||
- **[nl-contact-patch-plane-strain](../tests/oracle/nl-contact-patch-plane-strain/)** (theory): Contact patch test in plane strain: two blocks with non-matching edges in uniaxial compression (implicit mortar contact). Source: The contact patch test: a contact discretisation must transmit a uniform pressure across a non-matching interface exactly; Taylor & Papadopoulos, On a patch test for contact problems in two dimensions, Nonlinear Computational Mechanics, Springer 1991, 690–702; passed by 2D mortar methods: Yang, Laursen & Meng, IJNME 62:1183–1225, 2005. Uniaxial stress between frictionless supports is uniform in both blocks. Tolerances — small_lower_corner: small sliding is linear and its edge mortar integrals exact (degree-3 Gauss on the overlaps): the uniform stress is the discrete solution up to the convergence tolerance; small_lower_far: as for the corner element; small_lower_base: as for the corner element; small_upper_top: as for the corner element; small_lateral: a frictionless interface (and symmetry plane) leaves the blocks free to expand sideways; the non-matching interface must not hold them; small_pressure: the mortar multipliers are the nodal values of the contact pressure, uniform and equal to the stress across the interface; small_force: the pressure carries the whole load across the interface (both are totals over the thickness); finite_lower_corner: finite sliding is exact up to the geometric terms of the gaps the augmentation leaves (10⁻⁵ of the element thickness) and the default convergence tolerances; finite_lower_far: as for the corner element; finite_lower_base: as for the corner element; finite_upper_top: as for the corner element; finite_lateral: a frictionless interface (and symmetry plane) leaves the blocks free to expand sideways; the non-matching interface must not hold them; finite_pressure: the mortar multipliers are the nodal values of the contact pressure, uniform and equal to the stress across the interface; finite_force: the pressure carries the whole load across the interface (both are totals over the thickness); small_stress: the squeeze less the penetration the augmented Lagrangian leaves (up to 10⁻⁵ of the element thickness)
|
||||
|
||||
@@ -0,0 +1,110 @@
|
||||
# NAFEMS LE2 cylindrical shell bending patch test (MITC4 shells)
|
||||
|
||||
Our model of the published problem: a 30° sector of a cylindrical shell of mid-surface radius
|
||||
1000 mm, axial length 500 mm and thickness 10 mm, E = 210 GPa, ν = 0.3 (N, mm, MPa). The straight
|
||||
edge AB is clamped, the curved edges AD and BC keep their axial displacement (planes of symmetry
|
||||
across the axis), and the other straight edge DC carries the load. Two load cases, one step each:
|
||||
|
||||
1. **Moment**: a uniform edge moment of 1000 N·mm/mm on DC about the axis;
|
||||
2. **Pressure**: 0.6 MPa outward on the mid-surface, with a hoop traction of 60 MPa on DC (600 N/mm
|
||||
over the thickness), the membrane force that balances it.
|
||||
|
||||
Both put the patch in a uniform state with a hoop stress of 60 MPa on the outer surface (6M/t² in
|
||||
bending, pR/t in membrane), the published target at E. The descriptions we read do not place E;
|
||||
since the exact stress is the same everywhere on the patch, we read it at the patch centre
|
||||
(250, 0, 1000), the node on the y = 0 plane where the hoop direction is the global y axis, so the
|
||||
tangential stress is σ_yy.
|
||||
|
||||
## The mesh
|
||||
|
||||
The patch is curved, so the recipe writes its 81 nodes and 64 quad4 elements one by one with
|
||||
`mesh.node.add` and `mesh.element.add` ([docs/verification.md](../../../docs/verification.md)).
|
||||
The axis is x and the arc runs from φ = −15° (AB) to φ = 15° (DC): node 1 + i + 9 j lies at
|
||||
(500 i/8, 1000 sin φ_j, 1000 cos φ_j) with φ_j = −15° + 30° j/8, and element 1 + i + 8 j is
|
||||
[node(i, j), node(i + 1, j), node(i + 1, j + 1), node(i, j + 1)], so its normal points away from
|
||||
the axis and the shell's top surface is the outer one (the surface nodal stresses report).
|
||||
|
||||
The edge moment and edge traction are written as consistent nodal loads on DC: an end node of the
|
||||
edge takes half of an inner node's share (two loads with `"distribution": "per_node"`). The
|
||||
pressure acts on the elements' inner faces (face 2, the reversed node order), pushing outward.
|
||||
|
||||
The recipe was generated with this script (`python3 le2.py 8 > recipe.json`):
|
||||
|
||||
```python
|
||||
import json, math, sys
|
||||
|
||||
def le2(n):
|
||||
"""NAFEMS LE2 cylindrical patch (mm, N, MPa): R = 1000, axial length 500, 30° arc from φ = −15° (AB) to 15° (DC)."""
|
||||
m = n # elements round the arc, as many as along the axis
|
||||
R, L, half = 1000.0, 500.0, math.radians(15.0)
|
||||
label = lambda i, j: 1 + i + (n + 1) * j
|
||||
commands = []
|
||||
for j in range(m + 1):
|
||||
for i in range(n + 1):
|
||||
phi = -half + 2 * half * j / m
|
||||
commands.append({"command": "mesh.node.add", "params": {"label": label(i, j), "xyz": [L * i / n, R * math.sin(phi), R * math.cos(phi)]}})
|
||||
for j in range(m):
|
||||
for i in range(n):
|
||||
# i along the axis, j round the arc: e3 points away from the axis, so top is the outer surface
|
||||
nodes = [label(i, j), label(i + 1, j), label(i + 1, j + 1), label(i, j + 1)]
|
||||
commands.append({"command": "mesh.element.add", "params": {"label": 1 + i + n * j, "kind": "quad4", "nodes": nodes}})
|
||||
h = L / n
|
||||
ends = [label(0, m), label(n, m)]
|
||||
inner = [label(i, m) for i in range(1, n)]
|
||||
t = [0.0, math.cos(half), -math.sin(half)] # the hoop direction at DC, away from AB
|
||||
return commands + [
|
||||
{"command": "model.set.create", "params": {"name": "patch", "elements": list(range(1, n * m + 1))}},
|
||||
{"command": "model.set.create", "params": {"name": "inside", "faces": [{"element": e, "face": 2} for e in range(1, n * m + 1)]}},
|
||||
{"command": "model.set.create", "params": {"name": "AB", "nodes": [label(i, 0) for i in range(n + 1)]}},
|
||||
{"command": "model.set.create", "params": {"name": "AD_BC", "nodes": sorted([label(0, j) for j in range(m + 1)] + [label(n, j) for j in range(m + 1)])}},
|
||||
{"command": "model.set.create", "params": {"name": "DC_ends", "nodes": ends}},
|
||||
{"command": "model.set.create", "params": {"name": "DC_inner", "nodes": inner}},
|
||||
{"command": "model.material.create", "params": {"name": "Steel", "elastic": {"type": "isotropic", "young": 210000.0, "poisson": 0.3}}},
|
||||
{"command": "model.section.create", "params": {"name": "patch", "set": "patch", "material": "Steel", "kind": {"type": "shell", "thickness": 10.0}}},
|
||||
{"command": "model.boundary_condition.create", "params": {"name": "AB", "type": "displacement", "target": {"set": "AB"}, "values": [0, 0, 0, 0, 0, 0]}},
|
||||
{"command": "model.boundary_condition.create", "params": {"name": "AD_BC", "type": "symmetry", "target": {"set": "AD_BC"}, "plane": "x"}},
|
||||
# load case 1: an edge moment of 1000 N·mm/mm on DC about the axis, as consistent nodal moments
|
||||
{"command": "model.load.create", "params": {"name": "moment_ends", "type": "moment", "target": {"set": "DC_ends"}, "vector": [-1000.0 * h / 2, 0, 0], "distribution": "per_node"}},
|
||||
{"command": "model.load.create", "params": {"name": "moment_inner", "type": "moment", "target": {"set": "DC_inner"}, "vector": [-1000.0 * h, 0, 0], "distribution": "per_node"}},
|
||||
# load case 2: 0.6 MPa outward on the mid-surface, 60 MPa × 10 mm hoop traction on DC
|
||||
{"command": "model.load.create", "params": {"name": "pressure", "type": "pressure", "set": "inside", "magnitude": 0.6}},
|
||||
{"command": "model.load.create", "params": {"name": "pull_ends", "type": "force", "target": {"set": "DC_ends"}, "vector": [0.0, 600.0 * h / 2 * t[1], 600.0 * h / 2 * t[2]], "distribution": "per_node"}},
|
||||
{"command": "model.load.create", "params": {"name": "pull_inner", "type": "force", "target": {"set": "DC_inner"}, "vector": [0.0, 600.0 * h * t[1], 600.0 * h * t[2]], "distribution": "per_node"}},
|
||||
{"command": "model.step.create", "params": {"name": "Moment", "procedure": {"type": "static"}, "boundary_conditions": ["AB", "AD_BC"], "loads": ["moment_ends", "moment_inner"]}},
|
||||
{"command": "model.step.create", "params": {"name": "Pressure", "procedure": {"type": "static"}, "boundary_conditions": ["AB", "AD_BC"], "loads": ["pressure", "pull_ends", "pull_inner"]}},
|
||||
{"command": "solve.run", "params": {}, "id": "solve"},
|
||||
]
|
||||
|
||||
n = int(sys.argv[1]) if len(sys.argv) > 1 else 8
|
||||
print("[\n " + ",\n ".join(json.dumps(c) for c in le2(n)) + "\n]")
|
||||
```
|
||||
|
||||
## Refinement
|
||||
|
||||
Every row is the listing above with the row's divisions, solved and probed at E as the case
|
||||
does; the case mesh is 8 × 8:
|
||||
|
||||
| cells | σ_yy at E, moment | error | σ_yy at E, pressure | error |
|
||||
|---|---|---|---|---|
|
||||
| 4 × 4 | 59.743 | −0.43% | 59.615 | −0.64% |
|
||||
| 8 × 8 (this case) | 59.936 | −0.11% | 59.904 | −0.16% |
|
||||
| 16 × 16 | 59.984 | −0.03% | 59.976 | −0.04% |
|
||||
| 32 × 32 | 59.996 | −0.01% | 59.994 | −0.01% |
|
||||
|
||||
The error falls as the square of the facet angle: each flat element is tilted by half its arc
|
||||
angle from the hoop direction at E, so a share sin²(Δφ/2) of the hoop stress shows in σ_zz instead
|
||||
(σ_yy + σ_zz is 60.000 in every row of load case 1). The next refinement of the case mesh moves the
|
||||
value by 0.05% (moment) and 0.07% (pressure), well under a tenth of the 1% tolerance.
|
||||
|
||||
## Tolerance
|
||||
|
||||
1%: the target is exact for a thin shell and FieldCraft converges to it; the 8 × 8 mesh carries
|
||||
a 0.1–0.2% facet error, a fifth of the tolerance or less. `fixture.json` holds the 8 × 8 values:
|
||||
the mesh is written by the recipe, so it is bit-identical on every platform.
|
||||
|
||||
## Running it
|
||||
|
||||
```sh
|
||||
cargo xtask oracle --case nafems-le2
|
||||
cargo xtask oracle --bless nafems-le2 # only after the case passes
|
||||
```
|
||||
@@ -0,0 +1,23 @@
|
||||
{
|
||||
"title": "NAFEMS LE2 cylindrical shell bending patch test (MITC4 shells)",
|
||||
"kind": "benchmark",
|
||||
"source": "NAFEMS, The Standard NAFEMS Benchmarks, TNSB Rev. 3, October 1990, test LE2 (target: tangential stress 60 MPa on the outer surface at E, both load cases); the problem and target as reproduced in the Abaqus 2016 Benchmarks Guide, section 4.2.2 'LE2: Cylindrical shell bending patch test', and in the ESRD StressCheck Benchmarks Guide 'The Standard NAFEMS Benchmarks: Linear Elastic Tests' (2018), p. 8",
|
||||
"quantities": [
|
||||
{
|
||||
"id": "stt_E_moment",
|
||||
"quantity": "tangential stress at E, outer surface, load case 1 (edge moment)",
|
||||
"measure": {"command": "solve.probe", "params": {"step": "Moment", "at": [[250, 0, 1000]]}, "pointer": "/nodes/0/stress/1"},
|
||||
"value": 60.0,
|
||||
"tolerance": {"relative": 0.01},
|
||||
"reason": "the target is the exact thin-shell value (6M/t²) and the stress is uniform over the patch; the 8 × 8 flat facets tilt the element axes by ±1.875° from the hoop direction, which moves 0.1% of it into σ_zz, and 16 × 16 is within 0.03% (see README)"
|
||||
},
|
||||
{
|
||||
"id": "stt_E_pressure",
|
||||
"quantity": "tangential stress at E, outer surface, load case 2 (pressure and edge traction)",
|
||||
"measure": {"command": "solve.probe", "params": {"step": "Pressure", "at": [[250, 0, 1000]]}, "pointer": "/nodes/0/stress/1"},
|
||||
"value": 60.0,
|
||||
"tolerance": {"relative": 0.01},
|
||||
"reason": "the target is the exact membrane value (pR/t) and the stress is uniform over the patch; as in load case 1 the facets' tilt and the pressure on flat facets keep 8 × 8 within 0.2%, 16 × 16 within 0.05% (see README)"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -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": {
|
||||
"stt_E_moment": {
|
||||
"band": 6.000000000000001e-8,
|
||||
"value": 59.93576769689798
|
||||
},
|
||||
"stt_E_pressure": {
|
||||
"band": 6.000000000000001e-8,
|
||||
"value": 59.90367733652293
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,165 @@
|
||||
[
|
||||
{"command": "mesh.node.add", "params": {"label": 1, "xyz": [0.0, -258.81904510252076, 965.9258262890684]}},
|
||||
{"command": "mesh.node.add", "params": {"label": 2, "xyz": [62.5, -258.81904510252076, 965.9258262890684]}},
|
||||
{"command": "mesh.node.add", "params": {"label": 3, "xyz": [125.0, -258.81904510252076, 965.9258262890684]}},
|
||||
{"command": "mesh.node.add", "params": {"label": 4, "xyz": [187.5, -258.81904510252076, 965.9258262890684]}},
|
||||
{"command": "mesh.node.add", "params": {"label": 5, "xyz": [250.0, -258.81904510252076, 965.9258262890684]}},
|
||||
{"command": "mesh.node.add", "params": {"label": 6, "xyz": [312.5, -258.81904510252076, 965.9258262890684]}},
|
||||
{"command": "mesh.node.add", "params": {"label": 7, "xyz": [375.0, -258.81904510252076, 965.9258262890684]}},
|
||||
{"command": "mesh.node.add", "params": {"label": 8, "xyz": [437.5, -258.81904510252076, 965.9258262890684]}},
|
||||
{"command": "mesh.node.add", "params": {"label": 9, "xyz": [500.0, -258.81904510252076, 965.9258262890684]}},
|
||||
{"command": "mesh.node.add", "params": {"label": 10, "xyz": [0.0, -195.09032201612825, 980.7852804032304]}},
|
||||
{"command": "mesh.node.add", "params": {"label": 11, "xyz": [62.5, -195.09032201612825, 980.7852804032304]}},
|
||||
{"command": "mesh.node.add", "params": {"label": 12, "xyz": [125.0, -195.09032201612825, 980.7852804032304]}},
|
||||
{"command": "mesh.node.add", "params": {"label": 13, "xyz": [187.5, -195.09032201612825, 980.7852804032304]}},
|
||||
{"command": "mesh.node.add", "params": {"label": 14, "xyz": [250.0, -195.09032201612825, 980.7852804032304]}},
|
||||
{"command": "mesh.node.add", "params": {"label": 15, "xyz": [312.5, -195.09032201612825, 980.7852804032304]}},
|
||||
{"command": "mesh.node.add", "params": {"label": 16, "xyz": [375.0, -195.09032201612825, 980.7852804032304]}},
|
||||
{"command": "mesh.node.add", "params": {"label": 17, "xyz": [437.5, -195.09032201612825, 980.7852804032304]}},
|
||||
{"command": "mesh.node.add", "params": {"label": 18, "xyz": [500.0, -195.09032201612825, 980.7852804032304]}},
|
||||
{"command": "mesh.node.add", "params": {"label": 19, "xyz": [0.0, -130.52619222005157, 991.4448613738103]}},
|
||||
{"command": "mesh.node.add", "params": {"label": 20, "xyz": [62.5, -130.52619222005157, 991.4448613738103]}},
|
||||
{"command": "mesh.node.add", "params": {"label": 21, "xyz": [125.0, -130.52619222005157, 991.4448613738103]}},
|
||||
{"command": "mesh.node.add", "params": {"label": 22, "xyz": [187.5, -130.52619222005157, 991.4448613738103]}},
|
||||
{"command": "mesh.node.add", "params": {"label": 23, "xyz": [250.0, -130.52619222005157, 991.4448613738103]}},
|
||||
{"command": "mesh.node.add", "params": {"label": 24, "xyz": [312.5, -130.52619222005157, 991.4448613738103]}},
|
||||
{"command": "mesh.node.add", "params": {"label": 25, "xyz": [375.0, -130.52619222005157, 991.4448613738103]}},
|
||||
{"command": "mesh.node.add", "params": {"label": 26, "xyz": [437.5, -130.52619222005157, 991.4448613738103]}},
|
||||
{"command": "mesh.node.add", "params": {"label": 27, "xyz": [500.0, -130.52619222005157, 991.4448613738103]}},
|
||||
{"command": "mesh.node.add", "params": {"label": 28, "xyz": [0.0, -65.40312923014305, 997.8589232386034]}},
|
||||
{"command": "mesh.node.add", "params": {"label": 29, "xyz": [62.5, -65.40312923014305, 997.8589232386034]}},
|
||||
{"command": "mesh.node.add", "params": {"label": 30, "xyz": [125.0, -65.40312923014305, 997.8589232386034]}},
|
||||
{"command": "mesh.node.add", "params": {"label": 31, "xyz": [187.5, -65.40312923014305, 997.8589232386034]}},
|
||||
{"command": "mesh.node.add", "params": {"label": 32, "xyz": [250.0, -65.40312923014305, 997.8589232386034]}},
|
||||
{"command": "mesh.node.add", "params": {"label": 33, "xyz": [312.5, -65.40312923014305, 997.8589232386034]}},
|
||||
{"command": "mesh.node.add", "params": {"label": 34, "xyz": [375.0, -65.40312923014305, 997.8589232386034]}},
|
||||
{"command": "mesh.node.add", "params": {"label": 35, "xyz": [437.5, -65.40312923014305, 997.8589232386034]}},
|
||||
{"command": "mesh.node.add", "params": {"label": 36, "xyz": [500.0, -65.40312923014305, 997.8589232386034]}},
|
||||
{"command": "mesh.node.add", "params": {"label": 37, "xyz": [0.0, 0.0, 1000.0]}},
|
||||
{"command": "mesh.node.add", "params": {"label": 38, "xyz": [62.5, 0.0, 1000.0]}},
|
||||
{"command": "mesh.node.add", "params": {"label": 39, "xyz": [125.0, 0.0, 1000.0]}},
|
||||
{"command": "mesh.node.add", "params": {"label": 40, "xyz": [187.5, 0.0, 1000.0]}},
|
||||
{"command": "mesh.node.add", "params": {"label": 41, "xyz": [250.0, 0.0, 1000.0]}},
|
||||
{"command": "mesh.node.add", "params": {"label": 42, "xyz": [312.5, 0.0, 1000.0]}},
|
||||
{"command": "mesh.node.add", "params": {"label": 43, "xyz": [375.0, 0.0, 1000.0]}},
|
||||
{"command": "mesh.node.add", "params": {"label": 44, "xyz": [437.5, 0.0, 1000.0]}},
|
||||
{"command": "mesh.node.add", "params": {"label": 45, "xyz": [500.0, 0.0, 1000.0]}},
|
||||
{"command": "mesh.node.add", "params": {"label": 46, "xyz": [0.0, 65.40312923014305, 997.8589232386034]}},
|
||||
{"command": "mesh.node.add", "params": {"label": 47, "xyz": [62.5, 65.40312923014305, 997.8589232386034]}},
|
||||
{"command": "mesh.node.add", "params": {"label": 48, "xyz": [125.0, 65.40312923014305, 997.8589232386034]}},
|
||||
{"command": "mesh.node.add", "params": {"label": 49, "xyz": [187.5, 65.40312923014305, 997.8589232386034]}},
|
||||
{"command": "mesh.node.add", "params": {"label": 50, "xyz": [250.0, 65.40312923014305, 997.8589232386034]}},
|
||||
{"command": "mesh.node.add", "params": {"label": 51, "xyz": [312.5, 65.40312923014305, 997.8589232386034]}},
|
||||
{"command": "mesh.node.add", "params": {"label": 52, "xyz": [375.0, 65.40312923014305, 997.8589232386034]}},
|
||||
{"command": "mesh.node.add", "params": {"label": 53, "xyz": [437.5, 65.40312923014305, 997.8589232386034]}},
|
||||
{"command": "mesh.node.add", "params": {"label": 54, "xyz": [500.0, 65.40312923014305, 997.8589232386034]}},
|
||||
{"command": "mesh.node.add", "params": {"label": 55, "xyz": [0.0, 130.5261922200516, 991.4448613738103]}},
|
||||
{"command": "mesh.node.add", "params": {"label": 56, "xyz": [62.5, 130.5261922200516, 991.4448613738103]}},
|
||||
{"command": "mesh.node.add", "params": {"label": 57, "xyz": [125.0, 130.5261922200516, 991.4448613738103]}},
|
||||
{"command": "mesh.node.add", "params": {"label": 58, "xyz": [187.5, 130.5261922200516, 991.4448613738103]}},
|
||||
{"command": "mesh.node.add", "params": {"label": 59, "xyz": [250.0, 130.5261922200516, 991.4448613738103]}},
|
||||
{"command": "mesh.node.add", "params": {"label": 60, "xyz": [312.5, 130.5261922200516, 991.4448613738103]}},
|
||||
{"command": "mesh.node.add", "params": {"label": 61, "xyz": [375.0, 130.5261922200516, 991.4448613738103]}},
|
||||
{"command": "mesh.node.add", "params": {"label": 62, "xyz": [437.5, 130.5261922200516, 991.4448613738103]}},
|
||||
{"command": "mesh.node.add", "params": {"label": 63, "xyz": [500.0, 130.5261922200516, 991.4448613738103]}},
|
||||
{"command": "mesh.node.add", "params": {"label": 64, "xyz": [0.0, 195.09032201612825, 980.7852804032304]}},
|
||||
{"command": "mesh.node.add", "params": {"label": 65, "xyz": [62.5, 195.09032201612825, 980.7852804032304]}},
|
||||
{"command": "mesh.node.add", "params": {"label": 66, "xyz": [125.0, 195.09032201612825, 980.7852804032304]}},
|
||||
{"command": "mesh.node.add", "params": {"label": 67, "xyz": [187.5, 195.09032201612825, 980.7852804032304]}},
|
||||
{"command": "mesh.node.add", "params": {"label": 68, "xyz": [250.0, 195.09032201612825, 980.7852804032304]}},
|
||||
{"command": "mesh.node.add", "params": {"label": 69, "xyz": [312.5, 195.09032201612825, 980.7852804032304]}},
|
||||
{"command": "mesh.node.add", "params": {"label": 70, "xyz": [375.0, 195.09032201612825, 980.7852804032304]}},
|
||||
{"command": "mesh.node.add", "params": {"label": 71, "xyz": [437.5, 195.09032201612825, 980.7852804032304]}},
|
||||
{"command": "mesh.node.add", "params": {"label": 72, "xyz": [500.0, 195.09032201612825, 980.7852804032304]}},
|
||||
{"command": "mesh.node.add", "params": {"label": 73, "xyz": [0.0, 258.81904510252076, 965.9258262890684]}},
|
||||
{"command": "mesh.node.add", "params": {"label": 74, "xyz": [62.5, 258.81904510252076, 965.9258262890684]}},
|
||||
{"command": "mesh.node.add", "params": {"label": 75, "xyz": [125.0, 258.81904510252076, 965.9258262890684]}},
|
||||
{"command": "mesh.node.add", "params": {"label": 76, "xyz": [187.5, 258.81904510252076, 965.9258262890684]}},
|
||||
{"command": "mesh.node.add", "params": {"label": 77, "xyz": [250.0, 258.81904510252076, 965.9258262890684]}},
|
||||
{"command": "mesh.node.add", "params": {"label": 78, "xyz": [312.5, 258.81904510252076, 965.9258262890684]}},
|
||||
{"command": "mesh.node.add", "params": {"label": 79, "xyz": [375.0, 258.81904510252076, 965.9258262890684]}},
|
||||
{"command": "mesh.node.add", "params": {"label": 80, "xyz": [437.5, 258.81904510252076, 965.9258262890684]}},
|
||||
{"command": "mesh.node.add", "params": {"label": 81, "xyz": [500.0, 258.81904510252076, 965.9258262890684]}},
|
||||
{"command": "mesh.element.add", "params": {"label": 1, "kind": "quad4", "nodes": [1, 2, 11, 10]}},
|
||||
{"command": "mesh.element.add", "params": {"label": 2, "kind": "quad4", "nodes": [2, 3, 12, 11]}},
|
||||
{"command": "mesh.element.add", "params": {"label": 3, "kind": "quad4", "nodes": [3, 4, 13, 12]}},
|
||||
{"command": "mesh.element.add", "params": {"label": 4, "kind": "quad4", "nodes": [4, 5, 14, 13]}},
|
||||
{"command": "mesh.element.add", "params": {"label": 5, "kind": "quad4", "nodes": [5, 6, 15, 14]}},
|
||||
{"command": "mesh.element.add", "params": {"label": 6, "kind": "quad4", "nodes": [6, 7, 16, 15]}},
|
||||
{"command": "mesh.element.add", "params": {"label": 7, "kind": "quad4", "nodes": [7, 8, 17, 16]}},
|
||||
{"command": "mesh.element.add", "params": {"label": 8, "kind": "quad4", "nodes": [8, 9, 18, 17]}},
|
||||
{"command": "mesh.element.add", "params": {"label": 9, "kind": "quad4", "nodes": [10, 11, 20, 19]}},
|
||||
{"command": "mesh.element.add", "params": {"label": 10, "kind": "quad4", "nodes": [11, 12, 21, 20]}},
|
||||
{"command": "mesh.element.add", "params": {"label": 11, "kind": "quad4", "nodes": [12, 13, 22, 21]}},
|
||||
{"command": "mesh.element.add", "params": {"label": 12, "kind": "quad4", "nodes": [13, 14, 23, 22]}},
|
||||
{"command": "mesh.element.add", "params": {"label": 13, "kind": "quad4", "nodes": [14, 15, 24, 23]}},
|
||||
{"command": "mesh.element.add", "params": {"label": 14, "kind": "quad4", "nodes": [15, 16, 25, 24]}},
|
||||
{"command": "mesh.element.add", "params": {"label": 15, "kind": "quad4", "nodes": [16, 17, 26, 25]}},
|
||||
{"command": "mesh.element.add", "params": {"label": 16, "kind": "quad4", "nodes": [17, 18, 27, 26]}},
|
||||
{"command": "mesh.element.add", "params": {"label": 17, "kind": "quad4", "nodes": [19, 20, 29, 28]}},
|
||||
{"command": "mesh.element.add", "params": {"label": 18, "kind": "quad4", "nodes": [20, 21, 30, 29]}},
|
||||
{"command": "mesh.element.add", "params": {"label": 19, "kind": "quad4", "nodes": [21, 22, 31, 30]}},
|
||||
{"command": "mesh.element.add", "params": {"label": 20, "kind": "quad4", "nodes": [22, 23, 32, 31]}},
|
||||
{"command": "mesh.element.add", "params": {"label": 21, "kind": "quad4", "nodes": [23, 24, 33, 32]}},
|
||||
{"command": "mesh.element.add", "params": {"label": 22, "kind": "quad4", "nodes": [24, 25, 34, 33]}},
|
||||
{"command": "mesh.element.add", "params": {"label": 23, "kind": "quad4", "nodes": [25, 26, 35, 34]}},
|
||||
{"command": "mesh.element.add", "params": {"label": 24, "kind": "quad4", "nodes": [26, 27, 36, 35]}},
|
||||
{"command": "mesh.element.add", "params": {"label": 25, "kind": "quad4", "nodes": [28, 29, 38, 37]}},
|
||||
{"command": "mesh.element.add", "params": {"label": 26, "kind": "quad4", "nodes": [29, 30, 39, 38]}},
|
||||
{"command": "mesh.element.add", "params": {"label": 27, "kind": "quad4", "nodes": [30, 31, 40, 39]}},
|
||||
{"command": "mesh.element.add", "params": {"label": 28, "kind": "quad4", "nodes": [31, 32, 41, 40]}},
|
||||
{"command": "mesh.element.add", "params": {"label": 29, "kind": "quad4", "nodes": [32, 33, 42, 41]}},
|
||||
{"command": "mesh.element.add", "params": {"label": 30, "kind": "quad4", "nodes": [33, 34, 43, 42]}},
|
||||
{"command": "mesh.element.add", "params": {"label": 31, "kind": "quad4", "nodes": [34, 35, 44, 43]}},
|
||||
{"command": "mesh.element.add", "params": {"label": 32, "kind": "quad4", "nodes": [35, 36, 45, 44]}},
|
||||
{"command": "mesh.element.add", "params": {"label": 33, "kind": "quad4", "nodes": [37, 38, 47, 46]}},
|
||||
{"command": "mesh.element.add", "params": {"label": 34, "kind": "quad4", "nodes": [38, 39, 48, 47]}},
|
||||
{"command": "mesh.element.add", "params": {"label": 35, "kind": "quad4", "nodes": [39, 40, 49, 48]}},
|
||||
{"command": "mesh.element.add", "params": {"label": 36, "kind": "quad4", "nodes": [40, 41, 50, 49]}},
|
||||
{"command": "mesh.element.add", "params": {"label": 37, "kind": "quad4", "nodes": [41, 42, 51, 50]}},
|
||||
{"command": "mesh.element.add", "params": {"label": 38, "kind": "quad4", "nodes": [42, 43, 52, 51]}},
|
||||
{"command": "mesh.element.add", "params": {"label": 39, "kind": "quad4", "nodes": [43, 44, 53, 52]}},
|
||||
{"command": "mesh.element.add", "params": {"label": 40, "kind": "quad4", "nodes": [44, 45, 54, 53]}},
|
||||
{"command": "mesh.element.add", "params": {"label": 41, "kind": "quad4", "nodes": [46, 47, 56, 55]}},
|
||||
{"command": "mesh.element.add", "params": {"label": 42, "kind": "quad4", "nodes": [47, 48, 57, 56]}},
|
||||
{"command": "mesh.element.add", "params": {"label": 43, "kind": "quad4", "nodes": [48, 49, 58, 57]}},
|
||||
{"command": "mesh.element.add", "params": {"label": 44, "kind": "quad4", "nodes": [49, 50, 59, 58]}},
|
||||
{"command": "mesh.element.add", "params": {"label": 45, "kind": "quad4", "nodes": [50, 51, 60, 59]}},
|
||||
{"command": "mesh.element.add", "params": {"label": 46, "kind": "quad4", "nodes": [51, 52, 61, 60]}},
|
||||
{"command": "mesh.element.add", "params": {"label": 47, "kind": "quad4", "nodes": [52, 53, 62, 61]}},
|
||||
{"command": "mesh.element.add", "params": {"label": 48, "kind": "quad4", "nodes": [53, 54, 63, 62]}},
|
||||
{"command": "mesh.element.add", "params": {"label": 49, "kind": "quad4", "nodes": [55, 56, 65, 64]}},
|
||||
{"command": "mesh.element.add", "params": {"label": 50, "kind": "quad4", "nodes": [56, 57, 66, 65]}},
|
||||
{"command": "mesh.element.add", "params": {"label": 51, "kind": "quad4", "nodes": [57, 58, 67, 66]}},
|
||||
{"command": "mesh.element.add", "params": {"label": 52, "kind": "quad4", "nodes": [58, 59, 68, 67]}},
|
||||
{"command": "mesh.element.add", "params": {"label": 53, "kind": "quad4", "nodes": [59, 60, 69, 68]}},
|
||||
{"command": "mesh.element.add", "params": {"label": 54, "kind": "quad4", "nodes": [60, 61, 70, 69]}},
|
||||
{"command": "mesh.element.add", "params": {"label": 55, "kind": "quad4", "nodes": [61, 62, 71, 70]}},
|
||||
{"command": "mesh.element.add", "params": {"label": 56, "kind": "quad4", "nodes": [62, 63, 72, 71]}},
|
||||
{"command": "mesh.element.add", "params": {"label": 57, "kind": "quad4", "nodes": [64, 65, 74, 73]}},
|
||||
{"command": "mesh.element.add", "params": {"label": 58, "kind": "quad4", "nodes": [65, 66, 75, 74]}},
|
||||
{"command": "mesh.element.add", "params": {"label": 59, "kind": "quad4", "nodes": [66, 67, 76, 75]}},
|
||||
{"command": "mesh.element.add", "params": {"label": 60, "kind": "quad4", "nodes": [67, 68, 77, 76]}},
|
||||
{"command": "mesh.element.add", "params": {"label": 61, "kind": "quad4", "nodes": [68, 69, 78, 77]}},
|
||||
{"command": "mesh.element.add", "params": {"label": 62, "kind": "quad4", "nodes": [69, 70, 79, 78]}},
|
||||
{"command": "mesh.element.add", "params": {"label": 63, "kind": "quad4", "nodes": [70, 71, 80, 79]}},
|
||||
{"command": "mesh.element.add", "params": {"label": 64, "kind": "quad4", "nodes": [71, 72, 81, 80]}},
|
||||
{"command": "model.set.create", "params": {"name": "patch", "elements": [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64]}},
|
||||
{"command": "model.set.create", "params": {"name": "inside", "faces": [{"element": 1, "face": 2}, {"element": 2, "face": 2}, {"element": 3, "face": 2}, {"element": 4, "face": 2}, {"element": 5, "face": 2}, {"element": 6, "face": 2}, {"element": 7, "face": 2}, {"element": 8, "face": 2}, {"element": 9, "face": 2}, {"element": 10, "face": 2}, {"element": 11, "face": 2}, {"element": 12, "face": 2}, {"element": 13, "face": 2}, {"element": 14, "face": 2}, {"element": 15, "face": 2}, {"element": 16, "face": 2}, {"element": 17, "face": 2}, {"element": 18, "face": 2}, {"element": 19, "face": 2}, {"element": 20, "face": 2}, {"element": 21, "face": 2}, {"element": 22, "face": 2}, {"element": 23, "face": 2}, {"element": 24, "face": 2}, {"element": 25, "face": 2}, {"element": 26, "face": 2}, {"element": 27, "face": 2}, {"element": 28, "face": 2}, {"element": 29, "face": 2}, {"element": 30, "face": 2}, {"element": 31, "face": 2}, {"element": 32, "face": 2}, {"element": 33, "face": 2}, {"element": 34, "face": 2}, {"element": 35, "face": 2}, {"element": 36, "face": 2}, {"element": 37, "face": 2}, {"element": 38, "face": 2}, {"element": 39, "face": 2}, {"element": 40, "face": 2}, {"element": 41, "face": 2}, {"element": 42, "face": 2}, {"element": 43, "face": 2}, {"element": 44, "face": 2}, {"element": 45, "face": 2}, {"element": 46, "face": 2}, {"element": 47, "face": 2}, {"element": 48, "face": 2}, {"element": 49, "face": 2}, {"element": 50, "face": 2}, {"element": 51, "face": 2}, {"element": 52, "face": 2}, {"element": 53, "face": 2}, {"element": 54, "face": 2}, {"element": 55, "face": 2}, {"element": 56, "face": 2}, {"element": 57, "face": 2}, {"element": 58, "face": 2}, {"element": 59, "face": 2}, {"element": 60, "face": 2}, {"element": 61, "face": 2}, {"element": 62, "face": 2}, {"element": 63, "face": 2}, {"element": 64, "face": 2}]}},
|
||||
{"command": "model.set.create", "params": {"name": "AB", "nodes": [1, 2, 3, 4, 5, 6, 7, 8, 9]}},
|
||||
{"command": "model.set.create", "params": {"name": "AD_BC", "nodes": [1, 9, 10, 18, 19, 27, 28, 36, 37, 45, 46, 54, 55, 63, 64, 72, 73, 81]}},
|
||||
{"command": "model.set.create", "params": {"name": "DC_ends", "nodes": [73, 81]}},
|
||||
{"command": "model.set.create", "params": {"name": "DC_inner", "nodes": [74, 75, 76, 77, 78, 79, 80]}},
|
||||
{"command": "model.material.create", "params": {"name": "Steel", "elastic": {"type": "isotropic", "young": 210000.0, "poisson": 0.3}}},
|
||||
{"command": "model.section.create", "params": {"name": "patch", "set": "patch", "material": "Steel", "kind": {"type": "shell", "thickness": 10.0}}},
|
||||
{"command": "model.boundary_condition.create", "params": {"name": "AB", "type": "displacement", "target": {"set": "AB"}, "values": [0, 0, 0, 0, 0, 0]}},
|
||||
{"command": "model.boundary_condition.create", "params": {"name": "AD_BC", "type": "symmetry", "target": {"set": "AD_BC"}, "plane": "x"}},
|
||||
{"command": "model.load.create", "params": {"name": "moment_ends", "type": "moment", "target": {"set": "DC_ends"}, "vector": [-31250.0, 0, 0], "distribution": "per_node"}},
|
||||
{"command": "model.load.create", "params": {"name": "moment_inner", "type": "moment", "target": {"set": "DC_inner"}, "vector": [-62500.0, 0, 0], "distribution": "per_node"}},
|
||||
{"command": "model.load.create", "params": {"name": "pressure", "type": "pressure", "set": "inside", "magnitude": 0.6}},
|
||||
{"command": "model.load.create", "params": {"name": "pull_ends", "type": "force", "target": {"set": "DC_ends"}, "vector": [0.0, 18111.109242920033, -4852.857095672264], "distribution": "per_node"}},
|
||||
{"command": "model.load.create", "params": {"name": "pull_inner", "type": "force", "target": {"set": "DC_inner"}, "vector": [0.0, 36222.218485840065, -9705.714191344528], "distribution": "per_node"}},
|
||||
{"command": "model.step.create", "params": {"name": "Moment", "procedure": {"type": "static"}, "boundary_conditions": ["AB", "AD_BC"], "loads": ["moment_ends", "moment_inner"]}},
|
||||
{"command": "model.step.create", "params": {"name": "Pressure", "procedure": {"type": "static"}, "boundary_conditions": ["AB", "AD_BC"], "loads": ["pressure", "pull_ends", "pull_inner"]}},
|
||||
{"command": "solve.run", "params": {}, "id": "solve"}
|
||||
]
|
||||
@@ -0,0 +1,108 @@
|
||||
# NAFEMS LE3 hemispherical shell with point loads (MITC4 shells)
|
||||
|
||||
Our model of the published problem: a quarter of a closed hemisphere of mid-surface radius 10 m
|
||||
and thickness 0.04 m, E = 68.25 GPa, ν = 0.3 (m, kN, kPa: E = 6.825 × 10⁷), centred at the origin
|
||||
with its pole E on +z. A radial force of 2 kN pulls outward at A (10, 0, 0) on the equator and one
|
||||
of 2 kN pushes inward at C (0, 10, 0). The edge AE lies on the plane y = 0 and CE on x = 0, both
|
||||
planes of symmetry; u_z = 0 at E holds the shell vertically; the equator is free. The target is
|
||||
the radial displacement at A, u_x there.
|
||||
|
||||
(LE3 has no hole at the pole, unlike the MacNeal–Harder hemisphere of
|
||||
`pinched-hemisphere`, which has an 18° hole and different loads.)
|
||||
|
||||
## The mesh
|
||||
|
||||
The surface is doubly curved, so the recipe writes its nodes and elements one by one with
|
||||
`mesh.node.add` and `mesh.element.add` ([docs/verification.md](../../../docs/verification.md)).
|
||||
Meridians every 90°/32 of longitude λ and parallels every 90°/32 of latitude β divide the quarter
|
||||
into cells; node 1 + i + 33 j lies at R (cos β_j cos λ_i, cos β_j sin λ_i, sin β_j), and the pole is
|
||||
node 1057. Every cell below the top parallel is a quad4 whose four corners lie on two parallels,
|
||||
symmetric about its mid-meridian, so it is planar (flat shells model a curved surface best with
|
||||
flat facets); the 32 cells at the pole are tri3 (MITC3) triangles that share the pole node. All
|
||||
elements run counter-clockwise seen from outside.
|
||||
|
||||
A first mesh projected three faces of a cube onto the sphere (no pole, all quad4), but its cells
|
||||
are warped, and the flat MITC4 element on warped cells was far too stiff (0.147 at 32 × 32 per
|
||||
face). The longitude–latitude mesh converges as the table shows.
|
||||
|
||||
The recipe was generated with this script (`python3 le3.py 32 > recipe.json`):
|
||||
|
||||
```python
|
||||
import json, math, sys
|
||||
|
||||
def le3(n):
|
||||
"""NAFEMS LE3 hemisphere quadrant (m, kN, kPa): R = 10, x ≥ 0, y ≥ 0, z ≥ 0, pole E on +z.
|
||||
|
||||
Meridians every 90°/n of longitude λ, parallels every 90°/n of latitude β; the cells are planar
|
||||
trapezoids and the ring at the pole is triangles."""
|
||||
R = 10.0
|
||||
label = lambda i, j: 1 + i + (n + 1) * j # longitude i, latitude j < n
|
||||
pole = 1 + (n + 1) * n
|
||||
commands = []
|
||||
for j in range(n):
|
||||
for i in range(n + 1):
|
||||
lam, beta = math.pi / 2 * i / n, math.pi / 2 * j / n
|
||||
xyz = [R * math.cos(beta) * math.cos(lam), R * math.cos(beta) * math.sin(lam), R * math.sin(beta)]
|
||||
commands.append({"command": "mesh.node.add", "params": {"label": label(i, j), "xyz": xyz}})
|
||||
commands.append({"command": "mesh.node.add", "params": {"label": pole, "xyz": [0.0, 0.0, R]}})
|
||||
k = 0
|
||||
for j in range(n):
|
||||
for i in range(n):
|
||||
k += 1
|
||||
if j < n - 1:
|
||||
kind, nodes = "quad4", [label(i, j), label(i + 1, j), label(i + 1, j + 1), label(i, j + 1)]
|
||||
else:
|
||||
kind, nodes = "tri3", [label(i, j), label(i + 1, j), pole]
|
||||
commands.append({"command": "mesh.element.add", "params": {"label": k, "kind": kind, "nodes": nodes}})
|
||||
A, C = label(0, 0), label(n, 0)
|
||||
return commands + [
|
||||
{"command": "model.set.create", "params": {"name": "shell", "elements": list(range(1, k + 1))}},
|
||||
{"command": "model.set.create", "params": {"name": "AE", "nodes": [label(0, j) for j in range(n)] + [pole]}},
|
||||
{"command": "model.set.create", "params": {"name": "CE", "nodes": [label(n, j) for j in range(n)] + [pole]}},
|
||||
{"command": "model.set.create", "params": {"name": "A", "nodes": [A]}},
|
||||
{"command": "model.set.create", "params": {"name": "C", "nodes": [C]}},
|
||||
{"command": "model.set.create", "params": {"name": "E", "nodes": [pole]}},
|
||||
{"command": "model.material.create", "params": {"name": "Alloy", "elastic": {"type": "isotropic", "young": 6.825e7, "poisson": 0.3}}},
|
||||
{"command": "model.section.create", "params": {"name": "shell", "set": "shell", "material": "Alloy", "kind": {"type": "shell", "thickness": 0.04}}},
|
||||
{"command": "model.boundary_condition.create", "params": {"name": "AE", "type": "symmetry", "target": {"set": "AE"}, "plane": "y"}},
|
||||
{"command": "model.boundary_condition.create", "params": {"name": "CE", "type": "symmetry", "target": {"set": "CE"}, "plane": "x"}},
|
||||
{"command": "model.boundary_condition.create", "params": {"name": "E", "type": "displacement", "target": {"set": "E"}, "values": [None, None, 0, None, None, None]}},
|
||||
{"command": "model.load.create", "params": {"name": "pull_A", "type": "force", "target": {"set": "A"}, "vector": [2.0, 0, 0]}},
|
||||
{"command": "model.load.create", "params": {"name": "push_C", "type": "force", "target": {"set": "C"}, "vector": [0, -2.0, 0]}},
|
||||
{"command": "model.step.create", "params": {"name": "Load", "procedure": {"type": "static"}, "boundary_conditions": ["AE", "CE", "E"], "loads": ["pull_A", "push_C"]}},
|
||||
{"command": "solve.static", "params": {}, "id": "solve"},
|
||||
]
|
||||
|
||||
n = int(sys.argv[1]) if len(sys.argv) > 1 else 32
|
||||
print("[\n " + ",\n ".join(json.dumps(c) for c in le3(n)) + "\n]")
|
||||
```
|
||||
|
||||
## Refinement
|
||||
|
||||
Every row is the listing above with the row's divisions, solved and probed at A as the case does;
|
||||
the case mesh is 32 × 32:
|
||||
|
||||
| cells | u_x at A (m) | error |
|
||||
|---|---|---|
|
||||
| 8 × 8 | 0.18197 | −1.64% |
|
||||
| 16 × 16 | 0.18324 | −0.95% |
|
||||
| 32 × 32 (this case) | 0.18418 | −0.44% |
|
||||
| 64 × 64 | 0.18469 | −0.17% |
|
||||
|
||||
The result rises with every refinement and its increments shrink, but slowly: under a point load,
|
||||
a shell with transverse shear flexibility has no finite limit, only a very slow (logarithmic)
|
||||
growth (the ESRD guide makes the same remark for its own p-version solution, 0.1844). The next
|
||||
refinement moves the case value by 0.28%, a seventh of the tolerance.
|
||||
|
||||
## Tolerance
|
||||
|
||||
2%: the target is published to three figures and the displacement under a point load is not a
|
||||
converging quantity in the strict sense (above); 32 × 32 is within 0.44%. `fixture.json` holds the
|
||||
32 × 32 value: the mesh is written by the recipe, so it is bit-identical on every platform.
|
||||
|
||||
## Running it
|
||||
|
||||
```sh
|
||||
cargo xtask oracle --case nafems-le3
|
||||
cargo xtask oracle --bless nafems-le3 # only after the case passes
|
||||
```
|
||||
@@ -0,0 +1,15 @@
|
||||
{
|
||||
"title": "NAFEMS LE3 hemispherical shell with point loads (MITC4 shells)",
|
||||
"kind": "benchmark",
|
||||
"source": "NAFEMS, The Standard NAFEMS Benchmarks, TNSB Rev. 3, October 1990, test LE3 (target: radial displacement 0.185 m at A); the problem and target as reproduced in the Abaqus 2016 Benchmarks Guide, section 4.2.3 'LE3: Hemispherical shell with point loads', and in the ESRD StressCheck Benchmarks Guide 'The Standard NAFEMS Benchmarks: Linear Elastic Tests' (2018), p. 12",
|
||||
"quantities": [
|
||||
{
|
||||
"id": "ur_A",
|
||||
"quantity": "radial displacement at A (10, 0, 0), m",
|
||||
"measure": {"command": "solve.probe", "params": {"step": "Load", "at": [[10, 0, 0]]}, "pointer": "/nodes/0/displacement/0"},
|
||||
"value": 0.185,
|
||||
"tolerance": {"relative": 0.02},
|
||||
"reason": "the target is published to three figures; the displacement under a point load on a shear-deformable shell keeps growing slowly as the mesh is refined (32 × 32 is 0.44% low, 64 × 64 0.16%; see README)"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"note": "FieldCraft's accepted results for this case, written by `cargo xtask oracle --bless`. A result outside its band fails CI.",
|
||||
"values": {
|
||||
"ur_A": {
|
||||
"band": 1.85e-10,
|
||||
"value": 0.18417526380456614
|
||||
}
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large.
Load diff
Reference in new issue
Block a user