verification: implicit plasticity oracle cases and documentation

Four cases, each against its closed form: uniaxial tension of a J2 cube to a
logarithmic strain of 0.2 (Kirchhoff stress exact; 0.13 % from the explicit
solver's hypoelastic Cauchy stress, the elastic volume change between the two
laws), the Bauschinger effect of linear kinematic hardening on a load path
back to zero strain (exact), Hill's elastic-perfectly plastic thick cylinder
(bore displacement at a plastic radius of 1.5a within 0.009 %, collapse
pressure within 2e-8; the pending case is now active) and a cantilever's
plastic collapse, converged 3.1 % above beam theory's hinge, the bound a
continuum exceeds. docs/fem.md, the literature, ROADMAP (M15), 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 06:03:36 -04:00
1 parent 17b2c837f2
commit 7a69fe5e2f
21 files changed
+414 -25

No files matched your search

+12
View File
@@ -0,0 +1,12 @@
# Bauschinger effect of linear kinematic hardening
One hex8 cube (E = 200000, ν = 0.3, σ_y = 250, H = 2000, Prager's linear kinematic hardening)
held by symmetry on three faces, its fourth face pulled to a strain of 0.01 and brought back to
zero within one nonlinear static step without nonlinear geometry, by the load path
[[0, 0], [0.5, 1], [1, 0]] in increments of 0.05.
At ε_a the stress is σ_a = σ_y + E_t (ε_a − σ_y/E) = 267.327. The yield surface keeps its size
and moves with the back stress, so unloading is elastic only until σ_a − 2σ_y and then hardens
with E_t: back at zero strain σ = σ_a − 2σ_y − E_t (ε_a − 2σ_y/E) = −247.525. Isotropic hardening
would yield again only at −σ_a and end at −281.835. The equivalent plastic strain accumulates
(σ_a − σ_y)/H forward and E/(E + H)(ε_a − 2σ_y/E) in reverse, 0.0160891.
+45
View File
@@ -0,0 +1,45 @@
{
"title": "Bauschinger effect of linear kinematic hardening: tension, then back to zero strain",
"kind": "theory",
"source": "J2 plasticity with Prager's linear kinematic hardening in uniaxial stress (W. Prager, Ing.-Arch. 1955; Simo and Hughes, Computational Inelasticity, Springer 1998, §2.3): from σ_a = σ_y + E_t (ε_a − σ_y/E) the material unloads elastically by 2σ_y and then hardens with E_t, so at zero strain σ = σ_a − 2σ_y − E_t (ε_a − 2σ_y/E)",
"quantities": [
{
"id": "residual_stress",
"quantity": "axial stress back at zero strain after a pull to ε_a = 0.01",
"measure": {
"command": "solve.probe",
"params": {
"step": "Pull",
"elements": [
1
]
},
"pointer": "/elements/0/stress/0/0"
},
"value": -247.52475247524754,
"tolerance": {
"relative": 1e-06
},
"reason": "a homogeneous small-strain state the element represents exactly, with increments that end at the load path's turn; isotropic hardening would give −281.835 (it yields again only at −σ_a)"
},
{
"id": "plastic_strain",
"quantity": "accumulated equivalent plastic strain",
"measure": {
"command": "solve.probe",
"params": {
"step": "Pull",
"elements": [
1
]
},
"pointer": "/elements/0/plastic_strain/0"
},
"value": 0.016089108910891083,
"tolerance": {
"relative": 1e-06
},
"reason": "(σ_a − σ_y)/H forward plus E/(E + H) (ε_a − 2σ_y/E) in reverse"
}
]
}
+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": 1.6089108910891082e-11,
"value": 0.01608910891089074
},
"residual_stress": {
"band": 2.4752475247524754e-7,
"value": -247.52475247484173
}
}
}
+16
View File
@@ -0,0 +1,16 @@
[
{"command": "mesh.block", "params": {"body": "Cube", "kind": "hex8", "corners": [[0, 0, 0], [1, 0, 0], [1, 1, 0], [0, 1, 0], [0, 0, 1], [1, 0, 1], [1, 1, 1], [0, 1, 1]], "divisions": [1, 1, 1], "faces": {"6": "x0", "3": "y0", "1": "z0", "4": "x1"}}},
{"command": "model.set.create", "params": {"name": "all", "geometry": [{"body": "Cube"}]}},
{"command": "model.set.create", "params": {"name": "x0", "geometry": [{"body": "Cube", "face": "x0"}]}},
{"command": "model.set.create", "params": {"name": "y0", "geometry": [{"body": "Cube", "face": "y0"}]}},
{"command": "model.set.create", "params": {"name": "z0", "geometry": [{"body": "Cube", "face": "z0"}]}},
{"command": "model.set.create", "params": {"name": "x1", "geometry": [{"body": "Cube", "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, "hardening": "kinematic"}}},
{"command": "model.section.create", "params": {"name": "cube", "set": "all", "material": "Steel", "kind": {"type": "solid"}}},
{"command": "model.boundary_condition.create", "params": {"name": "sx", "type": "symmetry", "target": {"set": "x0"}, "plane": "x"}},
{"command": "model.boundary_condition.create", "params": {"name": "sy", "type": "symmetry", "target": {"set": "y0"}, "plane": "y"}},
{"command": "model.boundary_condition.create", "params": {"name": "sz", "type": "symmetry", "target": {"set": "z0"}, "plane": "z"}},
{"command": "model.boundary_condition.create", "params": {"name": "pull", "type": "displacement", "target": {"set": "x1"}, "values": [0.01, null, null, null, null, null]}},
{"command": "model.step.create", "params": {"name": "Pull", "procedure": {"type": "nonlinear_static", "nonlinear_geometry": false, "initial_increment": 0.05, "max_increment": 0.05, "load_path": [[0, 0], [0.5, 1], [1, 0]]}, "boundary_conditions": ["sx", "sy", "sz", "pull"], "loads": []}},
{"command": "solve.nonlinear", "params": {"step": "Pull"}, "id": "solve"}
]