Files
OneCAD-Simulation/tests/oracle/explicit-contact-patch/expected.json
T
jyvikoandClaude Opus 5.5 a30d0b5c5b explicit: deformable contact and friction, verified by bars, sliding blocks, the patch test and Hertz
Segment-to-segment penalty contact between element faces: each secondary
face and each main face facing it are projected onto the secondary face's
plane, split into triangles, clipped (Sutherland–Hodgman) and integrated
with a three-point rule per sub-triangle (Puso–Laursen segmentation, the
penalty at the integration points as Fischer–Wriggers), so a uniform
pressure gives the consistent nodal forces on both meshes and the contact
patch test passes on non-matching meshes. Every contact runs both ways at
half the penalty: pairs with each surface as the secondary, general and
self contact face against face. A bucket grid of face boxes every
increment, faces integrated in parallel and their forces added in face
order: the same numbers on any thread count.

The penalty per area ε = s γ min(m/A)/Δt² comes from the lumped masses,
each node's directional area and the stable increment, bounded by
Gershgorin's row sums so contact never shortens the increment. Coulomb
friction with exponential decay by a regularised return map at the
secondary nodes; rigid walls take Coulomb impulses. Contact work and
friction dissipation join the energy balance; each contact reports its
peak force, first and last contact, deepest penetration, friction and the
nodes adjusted at the start (initial penetrations adjusted strain-free or
refused with the node, face and depth); a cap on contact faces.

Verified (crates/explicit/tests/contact.rs, tests/oracle/explicit-*):
colliding bars (2L/c +1.2%, ρcAv₀/2, KE kept to 0.005%, contact energy
back to 8e-5 of it), blocks sliding to a stop on a rigid wall and on a
plate under constant and decaying friction (0.005–0.2%), the patch test
(σ_zz uniform to 0.06%), two spheres colliding against Hertz (peak +2.3%,
duration −0.4%; the oracle case waits for a graded sphere mesher), a free
body untouched by general contact, determinism across threads. Oracle
measures gain `over` (ratios). Existing fixtures do not move.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01NmAttHhUZTokgPeEJia8sm
2026-10-14 12:49:45 -04:00

176 lines
4.4 KiB
JSON
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
{
"title": "Contact patch test: two blocks with non-matching meshes in uniaxial compression (explicit contact)",
"kind": "theory",
"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. Uniaxial stress between frictionless symmetry planes is uniform in both blocks",
"quantities": [
{
"id": "lower_corner",
"quantity": "σ_zz of the lower block's corner element under the interface (element 10) over that of the upper block's corner element over it (element 19)",
"measure": {
"command": "solve.probe",
"params": {
"step": "Squeeze",
"elements": [
10
]
},
"pointer": "/elements/0/stress/2",
"over": {
"command": "solve.probe",
"params": {
"step": "Squeeze",
"elements": [
19
]
},
"pointer": "/elements/0/stress/2"
}
},
"value": 1.0,
"tolerance": {
"relative": 0.005
},
"reason": "a uniform stress is an equilibrium of the discrete system (the integrated contact forces are the consistent nodal forces of a uniform pressure on both meshes); what is left is the ringing of the loading, a hundred wave transits slow"
},
{
"id": "lower_centre",
"quantity": "σ_zz of the lower block's centre element under the interface (element 14) over that of element 19",
"measure": {
"command": "solve.probe",
"params": {
"step": "Squeeze",
"elements": [
14
]
},
"pointer": "/elements/0/stress/2",
"over": {
"command": "solve.probe",
"params": {
"step": "Squeeze",
"elements": [
19
]
},
"pointer": "/elements/0/stress/2"
}
},
"value": 1.0,
"tolerance": {
"relative": 0.005
},
"reason": "as for the corner element"
},
{
"id": "lower_base",
"quantity": "σ_zz of the lower block's bottom corner element (element 1) over that of element 19",
"measure": {
"command": "solve.probe",
"params": {
"step": "Squeeze",
"elements": [
1
]
},
"pointer": "/elements/0/stress/2",
"over": {
"command": "solve.probe",
"params": {
"step": "Squeeze",
"elements": [
19
]
},
"pointer": "/elements/0/stress/2"
}
},
"value": 1.0,
"tolerance": {
"relative": 0.005
},
"reason": "as for the corner element"
},
{
"id": "upper_top",
"quantity": "σ_zz of the upper block's top far corner element (element 26) over that of element 19",
"measure": {
"command": "solve.probe",
"params": {
"step": "Squeeze",
"elements": [
26
]
},
"pointer": "/elements/0/stress/2",
"over": {
"command": "solve.probe",
"params": {
"step": "Squeeze",
"elements": [
19
]
},
"pointer": "/elements/0/stress/2"
}
},
"value": 1.0,
"tolerance": {
"relative": 0.005
},
"reason": "as for the corner element"
},
{
"id": "force",
"quantity": "the force across the interface over −σ_zz A (A = 1)",
"measure": {
"from": "solve",
"pointer": "/contacts/0/peak_force",
"over": {
"command": "solve.probe",
"params": {
"step": "Squeeze",
"elements": [
19
]
},
"pointer": "/elements/0/stress/2",
"scale": -1.0
}
},
"value": 1.0,
"tolerance": {
"relative": 0.01
},
"reason": "the integrated contact pressure carries the whole load; the largest force of the run is the final one in a slow squeeze, up to the ringing"
},
{
"id": "lateral",
"quantity": "σ_xx of element 14 over its σ_zz (uniaxial stress: 0)",
"measure": {
"command": "solve.probe",
"params": {
"step": "Squeeze",
"elements": [
14
]
},
"pointer": "/elements/0/stress/0",
"over": {
"command": "solve.probe",
"params": {
"step": "Squeeze",
"elements": [
14
]
},
"pointer": "/elements/0/stress/2"
}
},
"value": 0.0,
"tolerance": {
"absolute": 0.005
},
"reason": "frictionless symmetry planes and a frictionless interface leave the blocks free to expand sideways; the non-matching interface must not hold them"
}
]
}