Commit Graph
270 Commits
Author SHA1 Message Date
jyvikoandClaude Opus 5.5 7d689fb6a2 UI: the CPU viewport image never exceeds the texture size limit
A Retina window 2300 pixels wide drew its CPU viewport (the offscreen capture's
path) into a 2300 x 1412 texture, past egui's 2048 limit, and the app aborted.
The image is now scaled to fit the context's max_texture_side and drawn
stretched, as an image over the renderer's own limit already was. Fixes #237.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UhhZMBTviDQxZvwnyP89fo
2026-10-14 19:50:37 -04:00
jyvikoandClaude Opus 5.5 0b6b6c966c Engine: mesh.cells meshes a partitioned part cell by cell
Each cell (a body of the open design) gets its own method: structured hex where
one fits (auto falls back to tet and says why), or tet. All go into one mesh.
Cells on either side of a partition are joined: where their element faces
match node for node the nodes are merged; otherwise (hex next to tet, or
different divisions) the two partition faces get a set each and a dual mortar
tie, the reported hex-tet transition. A 40 mm bar cut in half, one half hex,
the other tet, stretches F L / (E A) to 1e-6.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UhhZMBTviDQxZvwnyP89fo
2026-10-14 19:50:37 -04:00
jyvikoandClaude Opus 5.5 1fbb5581ea Mesh: merge coincident nodes, keeping tags and sets on the survivor
Model::merge_nodes replaces merged nodes by their survivors in elements (node
order kept, so face and edge tags hold) and in set node lists, moves a vertex
tag to an untagged survivor, and refuses a merge that would collapse an
element. fieldcraft_mesh::join::coincident_nodes / merge_coincident find the
nodes within a distance of a lower-labelled survivor, deterministically.
Meshing cell by cell and mirroring use them; node merging commands will too.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UhhZMBTviDQxZvwnyP89fo
2026-10-14 19:50:37 -04:00
jyvikoandClaude Opus 5.5 f6d227d8cb UI: datum planes and axes in the viewport, datums and partitions in the browser
Datum planes draw as a hatched square around the model, axes as a line through
it, each with its name, in the desktop viewport and the headless render. The
browser's Geometry node lists the datums and the partitions with the datum
each cuts by.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UhhZMBTviDQxZvwnyP89fo
2026-10-14 19:37:37 -04:00
jyvikoandClaude Opus 5.5 22f1006f71 Surface: close T-junctions left by independently tessellated faces
A face boundary vertex lying (within the weld distance) on an undivided edge of
the neighbouring face splits that edge's triangle. Only edges no other triangle
uses are looked at, so closed surfaces are unchanged. The half of a crank arm
cut on its symmetry plane tessellates with such a junction where the cut face
meets the top face; it now meshes (tet and swept hex).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UhhZMBTviDQxZvwnyP89fo
2026-10-14 19:37:37 -04:00
jyvikoandClaude Opus 5.5 1c16972cf2 Engine: geometry.datum, geometry.datum.axis and geometry.partition
Datum planes by principal plane and offset, three points, or point and
normal; datum axes by principal axis, two points, or point and direction.
geometry.partition cuts the open design by a datum plane and keeps the
partition in the model, so geometry.open, file.open and undo cut the design
again. Requirements, forms and the Prepare entries are wired; features.md
lists them as ready.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UhhZMBTviDQxZvwnyP89fo
2026-10-14 19:37:37 -04:00
jyvikoandClaude Opus 5.5 b0d0fc9900 Model: datum planes and axes, and partitions by datum plane
Datums are named planes (point, unit normal) and axes (point, unit direction);
a partition names the datum plane that cuts and, optionally, the bodies. A
datum a partition uses cannot be deleted or turned into an axis. Both are
stored in model.json, partitions in the order they cut.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UhhZMBTviDQxZvwnyP89fo
2026-10-14 19:37:37 -04:00
jyvikoandClaude Opus 5.5 321add294b Geometry: partition a design's bodies by planes, with paired cut-face names
Design::partitioned cuts the bodies as opened by planes in order (SolidCraft's
split_by_plane, in memory). Cells are <body>/a and <body>/b by side of the plane;
the two faces of each cut are partition:<name>:a and :b, and every other face
inherits the name of the face it is a piece of (<name>#k when a cell holds
several pieces). A cut that misses or names an unknown body is reported as a
design error, not fatal.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UhhZMBTviDQxZvwnyP89fo
2026-10-14 19:37:37 -04:00
jyvikoandClaude Opus 5.5 4c91f9b731 deps: move the SolidCraft pin to a629236 (main, 2026-10-14)
Moves every solidcraft-* rev and the truck/egui-wgpu patches (same list upstream) from
de1479029dd6 to a629236650c4. Extrude gained a 'thin' option; the sample plate keeps a
solid extrude (thin: None). THIRD-PARTY-LICENSES.txt regenerated (solidcraft 0.8.0 -> 0.11.0).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UhhZMBTviDQxZvwnyP89fo
2026-10-14 19:05:38 -04:00
jyvikoandClaude Opus 5.5 8409101483 UI: grey ribbon entries, search results and Solve that miss what they need
The ribbon buttons, drop-down rows, command search and the title bar's Solve read
Session::availability: greyed, with what is missing (and where to get it) in the tooltip.
Starting such an entry opens no form; the status bar names what is missing. ui.toolbar
reports each entry's `enabled` and `unavailable`, ui.inspect the Solve button's.

Fixes #220

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UhhZMBTviDQxZvwnyP89fo
2026-10-14 18:43:29 -04:00
jyvikoandClaude Opus 5.5 e0d5adba23 Engine: each command lists what it needs, and execute checks it first
CommandSpec gains `requires: &[Requirement]` (crates/engine/src/requirement.rs): an open
design, geometry, nodes, a mesh, something to analyse, materials and sections for the
elements, sets, the definition an edit or delete acts on, a step, a result. Session::execute
checks them before running, so a command missing one fails at once with no partial work,
naming each missing piece and the toolbar entry that provides it ("Needs a material —
Properties › Material"). Requirements are real prerequisites (the model's own reference
checks and model.check's rules), never a workflow order. engine.commands / list_commands
list them.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UhhZMBTviDQxZvwnyP89fo
2026-10-14 18:43:29 -04:00
jyvikoandClaude Opus 5.5 06b98f01c7 Undo: a new model is untitled, and undoing it brings the old file back (#214)
geometry.open with "model": "new" cleared the model but kept the session's
file path, so File > Save wrote the new model over the previous one. The path
and the revision saved there (which document the session is) were not part of
the undo state. A step now records the document when its command changed it:
the new model is untitled and unsaved; undo restores the old file and its
clean state, redo the untitled model (or the file it was saved to since).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UhhZMBTviDQxZvwnyP89fo
2026-10-14 18:25:09 -04:00
jyvikoandClaude Opus 5.5 2188d891ff Test: text typed into one form never lands in the next
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UhhZMBTviDQxZvwnyP89fo
2026-10-14 18:16:25 -04:00
jyvikoandClaude Opus 5.5 1fc9d1e8d5 Form widgets carry ids scoped by the form's opening and field path
A form's text fields had positional egui ids, so focus and typed text moved to the
field at the same place in the next form (#219).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UhhZMBTviDQxZvwnyP89fo
2026-10-14 18:16:25 -04:00
jyvikoandClaude Opus 5.5 94a10a1bf3 Open a design of another part: ask whether to start a new model
Opening (File > Open, a drop, the recent list) a design that has none of the
bodies the model's mesh and sets are on now asks, like the unsaved-changes
prompt: Start a new model with this design (default, Enter), Keep the
current model (the status names what no longer resolves), or Cancel. The
opened session waits for the answer; the same design opens without asking.
ui.inspect shows the prompt as {"design": path}; ui.prompt answers it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UhhZMBTviDQxZvwnyP89fo
2026-10-14 18:07:30 -04:00
jyvikoandClaude Opus 5.5 14e2d25e68 MCP open: pass a design's model choice to geometry.open
The open tool's schema and description name the keep/new choice and the
reply's related/stale report; docs/mcp.md says the same.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UhhZMBTviDQxZvwnyP89fo
2026-10-14 18:07:30 -04:00
jyvikoandClaude Opus 5.5 4a60674530 geometry.open: choose to keep the model or start a new one, and report what is stale
Opening a design over a model kept its mesh and every definition silently,
even when the design was another part (#145, #114). geometry.open now takes
`model`: "keep" (default: same-design reopen keeps the mesh and sets that
follow persistent face names) or "new" (clears mesh, definitions and
imported surfaces, keeps the unit system). The reply says whether the design
is `related` to the model's geometry references and lists `stale` mesh
bodies and sets. One undo step either way.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UhhZMBTviDQxZvwnyP89fo
2026-10-14 18:07:30 -04:00
jyvikoandClaude Opus 5.5 ddde08fb4c Results view: hover over contours is an outline, not a pink fill (#207)
While result contours are shown, the hovered item's face fill is left out
and only its outline, edges and nodes are drawn, so the hover never hides
the colours under the pointer. Picker::hover is the hover's own overlay.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UhhZMBTviDQxZvwnyP89fo
2026-10-14 17:53:46 -04:00
jyvikoandClaude Opus 5.5 a8f6be3bee docs: examples gallery as an even grid
A Markdown table sizes its columns by the captions, so the pictures came out
at different sizes; an HTML table with a third of the width per cell keeps
them even. The crank-arm picture is scaled to 1400x860 like the others, and
flow-past (no picture yet) moves to the end.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UhhZMBTviDQxZvwnyP89fo
2026-10-14 17:46:19 -04:00
jyvikoandClaude Opus 5.5 872dfdb421 release: check the licences in the installed package's file list
The Ubuntu and Fedora container images skip documentation when installing, so
the file is missing on disk even though the package carries it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UhhZMBTviDQxZvwnyP89fo
2026-10-14 17:25:34 -04:00
jyvikoandClaude Opus 5.5 854ced2888 release: a Maintainer address the .deb accepts; no Debian changelog for an upstream package
lintian rejected the Maintainer field without an e-mail address, and the missing
changelog of a package built upstream rather than by a distribution.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UhhZMBTviDQxZvwnyP89fo
2026-10-14 17:25:34 -04:00
jyvikoandClaude Opus 5.5 c8bd641e27 release: Linux .deb and .rpm packages (#125)
cargo-deb and cargo-generate-rpm (pinned) package the same stripped binaries and files as the
tar.gz under /usr. The release job compares the file lists, runs lintian, and installs both
packages in Ubuntu 22.04 and Fedora containers.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UhhZMBTviDQxZvwnyP89fo
2026-10-14 17:25:34 -04:00
jyvikoandClaude Opus 5.5 48cae3eb1d engine: heated-bracket test allows the clamped bore's 2.1 % on Linux
The heavy test asked the upright's top to grow within 2 % of free thermal
expansion; the clamped bore holds it back by 2.1 % on the Linux CI's tet mesh,
which differs from macOS's (#115). 3 % still catches a wrong expansion
coefficient or temperature.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UhhZMBTviDQxZvwnyP89fo
2026-10-14 16:54:01 -04:00
jyvikoandClaude Opus 5.5 227c4544ed solver: mortar contact in 2D models
Plane strain, plane stress and axisymmetric models take contact pairs and
general (self) contact on the linear edges of tri3 and quad4 elements:
edges oriented out of their elements, the edge mortar of fem with the
thickness or 2 pi r in the weights, the element's area over the edge's
length as the thickness under it, and the in-plane rows of the tangent
blocks. Verified by the contact patch test in plane strain and
axisymmetric (to 1e-9 small sliding, 1e-4 finite), Hertz's line contact
on quad4 edges (Johnson 1985, 4.3; equal to the hex8 model's to 1e-5),
and a hybrid rubber C-ring closing on itself that moves node for node as
the one-layer solid ring.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UhhZMBTviDQxZvwnyP89fo
2026-10-14 16:30:44 -04:00
jyvikoandClaude Opus 5.5 6baa189231 fem: hybrid plane strain and axisymmetric elements
One constant pressure per element (mean dilatation, Nagtegaal, Parks &
Rice 1974; the hoop strain in the divergence) for quad4, quad8 and tri6:
the linear stiffness, stresses and thermal load, and the finite- and
small-strain forms of nonlinear steps with their consistent tangent. The
linear triangle and plane stress are refused by name.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UhhZMBTviDQxZvwnyP89fo
2026-10-14 16:30:44 -04:00
jyvikoandClaude Opus 5.5 2ca5f84113 model: exterior edges of 2D elements
The boundary of a 2D model, which general contact takes by default.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UhhZMBTviDQxZvwnyP89fo
2026-10-14 16:30:44 -04:00
jyvikoandClaude Opus 5.5 6da3055a1c fem: mortar integration over the edges of 2D models
Segment-to-segment overlap of two edges projected along the secondary
normal (Yang, Laursen & Meng 2005), three-point Gauss-Legendre with the
out-of-plane measure (thickness or 2 pi r) in the weight, over the same
Real scalars as faces so the solver gets exact derivatives.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UhhZMBTviDQxZvwnyP89fo
2026-10-14 16:30:44 -04:00
jyvikoandClaude Opus 5.5 6bd52c0b29 engine: crank-arm sample, a bicycle crank swept all-hex and solved
file.sample crank-arm: a 170 mm 6061-T6 crank built in SolidCraft
(crates/engine/samples/crank-arm.json), swept along z by mesh.hex.generate
as 7274 hex20 elements of 3 mm (scaled Jacobian min 0.17). The hex variant
drops the pocket floor fillet and boss chamfers, and its root arcs meet the
bosses 20 degrees off tangent so the arm's top face has no zero-angle cusp.
The square bore is fixed and 1500 N acts on the pedal hole; the faces are
picked by their surfaces, not their names. Its heavy test matches the root
bending stress to M/Z = 62.6 MPa within 3 % (0.3 % in practice).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UhhZMBTviDQxZvwnyP89fo
2026-10-14 16:20:35 -04:00
jyvikoandClaude Opus 5.5 98d263ae54 docs: examples gallery in the README
An Examples section before Build: a tile per sample with its picture, one
line and its name for File > Samples or fieldcraft --sample NAME, linking
docs/examples.md; the roadmap notes the gallery.

Closes #167

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UhhZMBTviDQxZvwnyP89fo
2026-10-14 15:55:22 -04:00
jyvikoandClaude Opus 5.5 0b7f3021d9 engine: bracket-hex sample, the partitioned bracket meshed all-hex and solved
file.sample bracket-hex: the corpus bracket split into 30 SolidCraft cells,
meshed by mesh.hex.blocks as one conforming hex20 mesh of 3 mm, clamped at
the upright and loaded at the foot. The sample's script finds the clamp and
load faces in every cell that has them. Its test matches the tip deflection
of a fine tet10 solution within 1 % and checks the clamp carries the load.

Closes #166

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UhhZMBTviDQxZvwnyP89fo
2026-10-14 15:55:22 -04:00
jyvikoandClaude Opus 5.5 f5a0a1289a engine: heated-bracket sample, steady heat and thermal stress in steel
file.sample heated-bracket: the corpus filleted bracket in steel, tet10, its
hole bores clamped, the upright's end held at 120 C and the rest cooled by
still air; one coupled temperature-displacement step. Its test checks the
temperatures against the heater and the air, then warms the bracket evenly,
clamps one hole, and matches the free thermal expansion alpha dT times the
distance from the hole along x.

Closes #165

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UhhZMBTviDQxZvwnyP89fo
2026-10-14 15:55:22 -04:00
jyvikoandClaude Opus 5.5 ecdff11e72 engine: flow-past sample, air past an L-bracket on the floor
file.sample flow-past: air at 25 mm/s past the upright L-bracket in a box of
2.5 mm lattice cells (Re 83), inlet, outlet, a no-slip floor and slip walls;
the fluid step reports the force on each named face. Its test holds the
drag coefficient on the upright's frontal area between 1 and 3.5 (2.3) and
the lattice's mass change under 1 %. No picture: the viewport does not draw
flow results yet (M12).

Part of #164 (its streamlines wait for a flow display in the viewport)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UhhZMBTviDQxZvwnyP89fo
2026-10-14 15:55:22 -04:00
jyvikoandClaude Opus 5.5 cf8ed71e4f engine: rubber-seal sample, a Mooney-Rivlin gasket ring squeezed 25 %
file.sample rubber-seal: a gasket ring of hybrid hex8 elements in four
mapped quarter blocks, squeezed 2.5 mm between plates bonded to it
(nonlinear static, Mooney-Rivlin rubber). Its test frees the plates and
matches the closed form for incompressible uniaxial compression within 3 %,
and bounds the bonded ring's extra stiffness. The plates are prescribed
displacements until implicit contact (#161) can press it into a groove.

Closes #163

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UhhZMBTviDQxZvwnyP89fo
2026-10-14 15:55:22 -04:00
jyvikoandClaude Opus 5.5 581646bdac engine: drop-test sample, an aluminium bracket dropped onto a tilted floor
file.sample drop-test: an L-bracket standing on its foot (a SolidCraft script
in sample.rs) swept into hex8, falling 2 m onto a rigid floor tilted 15 deg;
explicit dynamics for 1 ms with gravity and plasticity. Its test checks the
mass against rho V, the impact speed sqrt(2 g h) and kinetic energy, the
energy balance and the momentum the floor takes. docs/examples.md starts
with it, and its picture is docs/media/examples/drop-test.png.

Closes #162

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UhhZMBTviDQxZvwnyP89fo
2026-10-14 15:55:22 -04:00
jyvikoandClaude Opus 5.5 c9a765aa02 engine: samples can build their geometry from a SolidCraft script
A sample may carry a SolidCraft script (the corpus recipe form) whose design
opens before its commands run, and its script sees the design's bodies.
fieldcraft-engine now builds fieldcraft-geometry with its scripts feature.
The start screen scrolls its sample list, and a test keeps the file.sample
form's choices in step with the samples.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UhhZMBTviDQxZvwnyP89fo
2026-10-14 15:55:22 -04:00
jyvikoandClaude Opus 5.5 0220e2d8bb engine, docs: self-contact in nonlinear static steps
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UhhZMBTviDQxZvwnyP89fo
2026-10-14 15:47:17 -04:00
jyvikoandClaude Opus 5.5 85f0905db1 solver: single-surface (self) contact in nonlinear static steps
General contact, on a set's faces or every exterior face of the solids, is mortar contact
with one face list as both sides: each face against every other one that faces it, shares no
node with its element and is not reached through more than half an element, paired both
ways. Tested by a nearly incompressible Mooney-Rivlin C-ring (hybrid hex8) closing on itself
(no penetration beyond the mortar's weak enforcement, mirror symmetry to 1e-6) and, heavy, a
rubber bellows whose folds press on each other.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UhhZMBTviDQxZvwnyP89fo
2026-10-14 15:47:17 -04:00
jyvikoandClaude Opus 5.5 2b1c52d021 verification: the tie patch test
An oracle case of uniaxial tension across a tie of non-matching meshes; the tie formulation
in docs/fem.md and the literature survey; ROADMAP M7 and parity updated.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UhhZMBTviDQxZvwnyP89fo
2026-10-14 15:28:02 -04:00
jyvikoandClaude Opus 5.5 794aa9f158 decks: ties as Abaqus *TIE and LS-DYNA tied contact
Nastran refuses them by name.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UhhZMBTviDQxZvwnyP89fo
2026-10-14 15:28:02 -04:00
jyvikoandClaude Opus 5.5 7e9366f726 engine: interaction.tie, tie.edit and tie.delete
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UhhZMBTviDQxZvwnyP89fo
2026-10-14 15:28:02 -04:00
jyvikoandClaude Opus 5.5 f9981d305e solver: ties by dual mortar constraints
Each secondary node follows the main surface under it as the weighted average
u_A = sum_J (M_AJ / sum_K M_AK) u_J with M_AJ = int psi_A N_J over the reference overlaps and
psi the secondary faces' dual shape functions (Wohlmuth 2000), so the secondary mortar
matrix is diagonal; the rows join the couplings' constraint elimination in every implicit
analysis. Uncovered secondary nodes stay free with a warning; heat transfer and explicit
dynamics refuse ties by name. Tested by the tie patch test on non-matching hex8/tet4 meshes.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UhhZMBTviDQxZvwnyP89fo
2026-10-14 15:28:02 -04:00
jyvikoandClaude Opus 5.5 8d2fa980a5 model: ties between surfaces
A tie names a main and a secondary face set and an optional position tolerance; it refers to
its sets, round-trips, is bounded in number and checked for solid faces.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UhhZMBTviDQxZvwnyP89fo
2026-10-14 15:28:02 -04:00
jyvikoandClaude Opus 5.5 a91ac5baf9 verification: Coulomb friction between sliding blocks
An oracle case of a block pressed on another and slid with static and kinetic coefficients
(mu_k N carried once slipping), and the docs of the friction formulation; ROADMAP M7 and
parity updated.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UhhZMBTviDQxZvwnyP89fo
2026-10-14 15:14:14 -04:00
jyvikoandClaude Opus 5.5 32c5c1b307 engine: friction output of implicit contact
solve.nonlinear counts the slipping nodes, solve.probe gives a secondary node's shear traction
and slip, and the results display draws contact_shear and contact_slip, contact_status coding
stick and slip.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UhhZMBTviDQxZvwnyP89fo
2026-10-14 15:14:14 -04:00
jyvikoandClaude Opus 5.5 6ca3233aaa solver: Coulomb friction for implicit mortar contact
A return map at the closed secondary nodes on the mortar slip in its rate form (w_A = B_A dx,
B_A = [int Phi_A N_i P, -int Phi_A N_j P]): stick within mu p_A, slip back to the cone, static
coefficient for a node that stuck in the last increment and kinetic for one that slipped; the
friction does the virtual work t . B_A dx, so a slipping interface carries mu N exactly. The
tangent is symmetrised (stick and slip stiffness kept, the coupling to the pressure and the
change of B left out; the residual is exact). Tractions and slip states are committed with the
converged increment. After a chattering cutback, nodes open by less than 1e-3 of their
element's thickness keep their penalty in the tangent for the rest of the step. Results carry
the shear traction, the slip and stick/slip status.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UhhZMBTviDQxZvwnyP89fo
2026-10-14 15:14:14 -04:00
jyvikoandClaude Opus 5.5 945a2076c3 verification: implicit contact patch test and Hertz line contact
Two oracle cases: the contact patch test on non-matching meshes in small and finite sliding,
and Hertz's cylinder on a flat under force control (peak pressure, pressure distribution,
subsurface stress). docs/fem.md describes the formulation, the literature survey its papers;
ROADMAP M7 and parity are updated.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UhhZMBTviDQxZvwnyP89fo
2026-10-14 14:58:32 -04:00
jyvikoandClaude Opus 5.5 5770288f47 engine: contact output of nonlinear static steps
solve.nonlinear summarises each contact (normal force, largest pressure, closed nodes, deepest
penetration, augmentations), solve.probe gives a secondary node's pressure, gap and status per
contact, and the results display draws contact_pressure, contact_gap and contact_status. The
contact commands, the catalogue and the model docs say what nonlinear static steps do with a
pair.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UhhZMBTviDQxZvwnyP89fo
2026-10-14 14:58:32 -04:00
jyvikoandClaude Opus 5.5 8871f6721d solver: mortar contact in nonlinear static steps
Frictionless contact pairs enforced by an augmented Lagrangian: nodal pressures from the
mortar weighted gaps, Uzawa updates after each converged increment until the gaps are within
1e-5 of the element thickness, and the consistent tangent (outer products of the weighted
gap gradients and the pressure-weighted Hessians from the automatic differentiation of the
mortar integrals). Finite sliding searches and integrates on the current configuration every
evaluation; without nonlinear geometry the pairs and their mortar integrals are fixed in the
reference configuration (small sliding, linear and exact). The tangent's pattern takes the
face pairs' blocks; the step cuts back when the active set chatters. Initial overclosure is
offset or refused; general contact, 2D models and arc length are refused by name; the linear
analyses refuse contact by name instead of the mesh.

With contact the convergence force scale comes from the converged states, the loads and the
current state. The loads-and-reactions balance check takes the nodal reactions into its scale
(no spurious warning for a part squeezed between held faces).

Tests: the contact patch test on non-matching hex8/tet4 meshes (exact with small sliding,
to 1e-4 with finite sliding), Hertz cylinder on a flat (peak pressure within 3%, half-width
bracketed) with quadratic Newton convergence, overclosure, thread-count determinism and the
refusals; Hertz sphere on a flat (heavy).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UhhZMBTviDQxZvwnyP89fo
2026-10-14 14:58:32 -04:00
jyvikoandClaude Opus 5.5 37f338c9e8 fem: mortar segmentation of face pairs with forward-mode automatic differentiation
The overlap of a secondary face with a main face (projection onto the secondary plane,
Sutherland-Hodgman clipping of their triangles, Radon's seven-point rule on the overlap's
fan) and the inverse linear and bilinear maps of both faces, written over a Real scalar so
that f64, Dual (gradient) and Hyper (gradient and packed Hessian, 24 variables) give the
values and the exact linearisation of the segmentation, the normal and the projection.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UhhZMBTviDQxZvwnyP89fo
2026-10-14 14:58:32 -04:00
jyvikoandClaude Opus 5.5 e8b0831884 release: version 0.5.7
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UhhZMBTviDQxZvwnyP89fo
v0.5.7
2026-10-14 14:30:47 -04:00