Docs: the crank's one-datum workflow, its gallery images and the Decompose status

examples.md and mcp.md tell the one-datum workflow and its numbers; the
crank gallery captures and Start card thumbnails are taken again on this
build; ROADMAP marks the automatic blocks of extruded cross-sections done,
and features.md's Decompose entry says what is left (3D parts).

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01UhhZMBTviDQxZvwnyP89fo
This commit is contained in:
jyvikoandClaude Opus 5.5 authored and Irakli Kourtis committed 2026-10-15 01:50:49 -04:00
1 parent 8e45f2c275
commit 43e2144090
9 files changed
+29 -21

No files matched your search

+1 -1
View File
@@ -31,7 +31,7 @@ pressure) is a degree of freedom of the existing DOF framework, not a separate s
| M2 Tet meshing and size field | Size field (global, curvature and proximity; edge seeds done: `mesh.seed.edge` on persistent design edge names (`<face>|<face>`) with a count or size, geometric bias and an exact, min or free constraint, shown as ticks and under Mesh › Seeds, honoured by the hex sweep, extrude, revolve, mapped, blocks and cells meshers through interval assignment (conflicting exact seeds named) and by the tet mesher, which divides the edge at the seed's nodes and grades its size field from them; per-face seeds to do; the `fieldcraft_mesh::size::SizeField` trait and edge-division helpers are in); Bowyer–Watson Delaunay (exact, symbolic perturbation, verified; `fieldcraft-mesh::delaunay`, done); robust CDT boundary recovery (Diazzi et al. 2023: implicit LNC Steiner points on segments, gift-wrapping facet recovery, inside/outside labelling, B-rep face tags on boundary tet faces, flip repair of rounding (§5.1) checked by the validity gate; `fieldcraft-mesh::cdt` and `mesh.tet.generate`, done: all 20 valid corpus parts); quality stage (done: `fieldcraft-mesh::tet` — curvature-graded size field, edge-collapse coarsening, constrained Delaunay refinement with boundary points on the B-rep faces and curves, ODT smoothing, Klingner–Shewchuk improvement, tet4 and tet10 with mid-side nodes on the B-rep, quality report; one validity criterion shared by the gate and both solvers; the filleted-bracket fillet stress converges, tests/oracle); mesh verify per set | in progress |
| M3 First deck | Sets and surfaces bound to SolidCraft face, edge, vertex and body names, resolved after meshing; materials (isotropic and orthotropic elastic, density) with a unit-system label and consistency check; sections (solid, shell, beam profiles) assigned by set; element formulation per region mapped to each solver; BCs (fixed, displacement, symmetry); loads (force and moment on reference points, pressure, gravity); reference points with kinematic and distributing coupling; steps (linear static, frequency) with explicit per-step load and BC tables and output presets; `model.check` naming every missing or bad item; `model.*` and `mesh.tag` commands (model definition: done); writers for Abaqus input (done: `deck.write`), Nastran SOL 101/103 (done: `deck.write`) and LS-DYNA implicit (done); the `.fieldcraft` file (text definition, binary mesh, geometry references reopened on load, journal; atomic saves, autosave and recovery; undo/redo on the journal: done) | in progress |
| M4 Own solver and first results | Element library per docs/elements.md (1D and 2D first); Linear static and modal solver (tet4/10, wedge6, hex8, hex20; sparse direct, Lanczos), verified against analytic solutions (solver: done — `fieldcraft-fem` kernels, `fieldcraft-solver` with nested dissection, sparse Cholesky and block Lanczos, `solve.static`/`solve.frequency`/`solve.probe`, patch, cantilever, Lamé, Kirsch and beam-frequency tests; reference points with kinematic and distributing couplings and moments by master–slave constraint elimination, verified by rigid motion, clamping, Saint-Venant tension, bending and tube torsion; 1D elements I: rod2/rod3 trusses, point masses, rotary inertia, springs and dashpots in both solvers and all three decks, verified by the method of joints, the three-bar truss, spring–mass, two-mass chain and torsional pendulum frequencies, and damped decay; 2D elements: plane stress, plane strain and axisymmetric tri3, tri6, quad4 (incompatible modes QM6), quad8 with two degrees of freedom per node, centrifugal loads, `mesh.planar` 2D meshes of polygons and planar faces, verified by patch tests, Kirsch, Lamé (plane strain and axisymmetric), rotating discs and cylinders, and a plane stress cantilever; deck mapping to Abaqus CPS/CPE/CAX, Nastran membranes, LS-DYNA ELFORM 12/13); shells and beams (done: quad4 MITC4 and tri3 MITC3 flat shells with a Hughes–Brezzi drilling rotation, two-node Timoshenko beams with profile properties and orientations, six degrees of freedom at shell and beam nodes shared with solids and trusses, section forces and surface stresses, verified by shell patch tests, Navier's plate, cantilever and portal-frame beams, and the Scordelis–Lo and pinched-cylinder benchmarks); results display (done: `results.*` commands, deformed shape to scale, banded contours of displacement, von Mises, principal and component stresses with a legend, mode shapes with their frequencies and animation, probing a node by clicking it, reaction force and moment sums per set, stale results marked after an edit; explicit steps: field frames by slider or animation with contours per frame, energy histories plotted) | started |
| M5 Structured hex | 2D quad meshing of faces (`fieldcraft-mesh::quad`: transfinite mapped meshes, free all-quad meshes of polygons with holes on prescribed boundary nodes, exact planar quad validity, shared `SizeField` and even edge divisions; done for planar faces); mapped hex of six-sided regions (trivariate TFI, curved faces) and sweep meshing (multi-level extrusions with imprinted cross-sections, revolutions, one-to-one sweeps through linking faces; interval assignment, hex8/hex20 on the geometry, B-rep face tags, `mesh.hex.generate`/`sweep`/`mapped`: done, 16 of 21 corpus parts all-hex); conforming interfaces between cells (done: `mesh.hex.blocks` meshes a part split with SolidCraft's Split Body into mapped blocks as one conforming mesh — composite faces for seams and tangent faces, interval assignment over all cells, shared faces meshed once, grading off holes and fillets, free-internal-face check; the filleted bracket in 30 cells, hex20 within 0.1 % of a fine tet10 tip deflection); partitions inside FieldCraft (done: datum planes and axes, `geometry.partition` cuts the open design by a datum plane, kept in the model and replayed when the design opens, the two faces of each cut paired by name); cells meshed each with its own method into one mesh (done: `mesh.cells` — hex where a method fits, else tet; matching interfaces merged node for node, others, such as hex next to tet, tied by dual mortar, verified by a tied hex–tet bar in tension to 1e-6); meshing half a symmetric part and mirroring it (done: `mesh.mirror` reflects hex8/hex20/tet4/tet10/wedge6 across a datum plane, right-handed, nodes on the plane merged, tags carried to the image half; a mirrored half bar equals the whole bar's mesh and bending deflection to 1e-12; samples `crank-arm` and `crank-mirror`: the half cut into seven cells, each swept structured, seeded to merge, and mirrored, scaled Jacobian ≥ 0.37; or solving the half: `model.boundary_condition.symmetry` on a datum plane, a half bar with half the load bends as the whole to 1e-11); three-sided sweep regions mapped as triangle primitives (done: midpoint subdivision, dominance constraints in interval assignment); pyramid transitions; automatic decomposition into sweepable and mappable regions, proposed as SolidCraft splits | started |
| M5 Structured hex | 2D quad meshing of faces (`fieldcraft-mesh::quad`: transfinite mapped meshes, free all-quad meshes of polygons with holes on prescribed boundary nodes, exact planar quad validity, shared `SizeField` and even edge divisions; done for planar faces); mapped hex of six-sided regions (trivariate TFI, curved faces) and sweep meshing (multi-level extrusions with imprinted cross-sections, revolutions, one-to-one sweeps through linking faces; interval assignment, hex8/hex20 on the geometry, B-rep face tags, `mesh.hex.generate`/`sweep`/`mapped`: done, 16 of 21 corpus parts all-hex); conforming interfaces between cells (done: `mesh.hex.blocks` meshes a part split with SolidCraft's Split Body into mapped blocks as one conforming mesh — composite faces for seams and tangent faces, interval assignment over all cells, shared faces meshed once, grading off holes and fillets, free-internal-face check; the filleted bracket in 30 cells, hex20 within 0.1 % of a fine tet10 tip deflection); partitions inside FieldCraft (done: datum planes and axes, `geometry.partition` cuts the open design by a datum plane, kept in the model and replayed when the design opens, the two faces of each cut paired by name); cells meshed each with its own method into one mesh (done: `mesh.cells` — hex where a method fits, else tet; matching interfaces merged node for node, others, such as hex next to tet, tied by dual mortar, verified by a tied hex–tet bar in tension to 1e-6); meshing half a symmetric part and mirroring it (done: `mesh.mirror` reflects hex8/hex20/tet4/tet10/wedge6 across a datum plane, right-handed, nodes on the plane merged, tags carried to the image half; a mirrored half bar equals the whole bar's mesh and bending deflection to 1e-12; samples `crank-arm` and `crank-mirror`: one datum, the half extruded in automatic blocks and mirrored, scaled Jacobian ≥ 0.37; or solving the half: `model.boundary_condition.symmetry` on a datum plane, a half bar with half the load bends as the whole to 1e-11); three-sided sweep regions mapped as triangle primitives (done: midpoint subdivision, dominance constraints in interval assignment); automatic blocks of extruded cross-sections (done: `hex::decompose` — holes separated, O-grids, cuts from concave corners and fillets chosen by block quality, kept only when no worse than the free mesh; nothing added to the model); pyramid transitions; automatic decomposition of 3D parts into sweepable and mappable regions | started |
| M6 Automatic hex | Octree/grid all-hex for any part (first version: done — `fieldcraft-mesh::octree`, `mesh.hex.octree`: 3-refinement grid with conforming templates refined by curvature, thickness and narrow faces, a core cleared to a manifold boundary, feature map onto it, padding and a pillow per patch capturing every sharp curve, foldover-free fitting, certified validity, B-rep face tags; the corpus hex column and the filleted-bracket oracle case; next: transitions for concave refined regions so thin and curved parts stop over-refining); hex-dominant by tet recombination; polycube for blocky parts; layers through thin walls; mesh editing and orphan-mesh import | started |
| M7 Assemblies, contact and friction | Needs M15. Part instances from SolidCraft occurrences; tie between non-matching meshes (mortar: done — `interaction.tie`, dual mortar constraints in the implicit analyses, Abaqus `*TIE` and LS-DYNA tied contact, the tie patch test); implicit contact: surface-to-surface mortar and node-to-surface, penalty and augmented Lagrange, self-contact, automatic pair detection (mortar contact pairs with Coulomb friction in nonlinear static steps: done — segment-to-segment mortar with the consistent tangent by automatic differentiation of the segmentation, augmented Lagrangian with Uzawa updates to a gap tolerance, semismooth active set with a chattering cutback, small sliding without nonlinear geometry and finite sliding with it, overclosure adjusted or refused, Coulomb friction (stick/slip return map, static and kinetic coefficients, symmetrised tangent), pressure, gap, status, shear and slip output; verified by the contact patch test, Hertz cylinder and sphere, Newton's quadratic rate and sliding blocks; the linear analyses refuse contact by name); friction: Coulomb with stick–slip, static/kinetic, anisotropic, pressure-, rate- and temperature-dependent coefficients; contact output (pressure, slip, status); thermal contact conductance and frictional heating; wear (Archard); bolt pretension, connectors with behaviour (elastic, damped, stops, locks); amplitudes, multiple steps, restart; nonlinear steps in all three decks. Verified by Hertz (sphere and cylinder), the Cattaneo–Mindlin partial-slip problem, the sliding block, NAFEMS contact benchmarks | started |
| M8 Materials, explicit, shells, composites | Plasticity, hyperelasticity, damage data per solver; explicit dynamics decks (Abaqus/Explicit, LS-DYNA); midsurface shells; composite layups and material orientations, continuum shells on swept hex; hybrid (mixed u–p) hex8/hex20/tet10 for nearly incompressible materials (done); heat transfer (solids done: steady and θ-method transient conduction with flux, convection and sources, thermal strain in static steps (solids and 2D) and explicit dynamics (with plasticity), coupled temperature–displacement, `solve.heat`; deck output, 2D/shell/beam conduction planned) | started |
+8 -1
View File
@@ -325,7 +325,14 @@ pub static CATALOGUE: &[Capability] = &[
"One mesh of a partitioned part, a method per cell (hex, tet, or all hex as conforming blocks); cells joined across partitions",
&["mesh.hex.blocks"],
),
soon("mesh.hex.decompose", "Decompose", Mesh, "Structured Hex", "M5", "Find sweepable and mappable regions and propose the splits"),
soon(
"mesh.hex.decompose",
"Decompose",
Mesh,
"Structured Hex",
"M5",
"Find sweepable and mappable regions of 3D parts (extruded cross-sections are already cut into blocks by Hex Mesh)",
),
soon("mesh.transition", "Transition", Mesh, "Structured Hex", "M5", "Conforming tet–hex interfaces with pyramids"),
ready(
"mesh.hex.octree",
Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 15 KiB

+14 -16
View File
@@ -121,7 +121,7 @@ links made with it still open): seen from below, where the pocket is. How the ha
meshed and mirrored is told under `crank-arm`.
**Look at:** the pocket from below: straight mapped rows along its sides and floor, and at each
end its corner fillets cut off by the diagonal partitions into three-sided triangle primitives;
end its corner fillets as three-sided triangle primitives, cut off by the mesher's own blocks;
the two halves, mirror images across the arm's middle.
**Check:** as `crank-arm`.
@@ -140,27 +140,25 @@ arm's top face, where any hex is degenerate). 6061-T6 (E = 68 900 MPa, ν = 0.33
bore's faces fixed, 1500 N on the pedal hole in the crank's plane, across the arm (−y). Linear
static: about 5 s to open and 7 s to solve.
The mesh is built as an analyst builds a structured one. A datum plane on the symmetry plane
(`Sym`, y = 0) partitions the crank (`Half`); the half `CrankArm/a` is cut into seven cells:
across the arm at x = 30 (the root, beyond the spindle boss), 60 and 110 (the pocket's straight
middle) and 148 (before the pedal boss), and on two diagonals (`D1`, `D2`) through the centres
of the pocket's corner fillets, radial to them so they meet the pocket wall square. Every
cell's cross-section then splits into regions that map: the half ring round each bore (an
O-grid), four-sided blocks (transfinite), and the pocket's four corners, three-sided, as
triangle primitives. Exact edge seeds (`mesh.seed.edge`) give every cut the same divisions on
its two sides, so `mesh.cells` sweeps each cell (`extrude`, hex20 of 3 mm) and merges all six
cuts node for node, and `mesh.mirror` reflects the half onto `CrankArm/b`: 7 710 hex20
elements, 37 938 nodes, all valid, scaled Jacobian min 0.37, mean 0.92, edge ratio at most 7.0
(the swept crank before: min 0.17, its free-paved middle at the pocket the worst).
The mesh needs one datum. A datum plane on the symmetry plane (`Sym`, y = 0) partitions the
crank (`Half`); `mesh.hex.generate` extrudes the half `CrankArm/a` (hex20 of 3 mm) and cuts its
cross-section into mappable blocks itself, inside the mesher (nothing is added to the model):
the half ring round each bore as four-sided blocks, the pocket's R5 corners as three-sided
triangle primitives, and four-sided blocks along the arm, split where the pocket's fillets meet
it. Interval assignment gives every block's sides matching counts, with no seeds.
`mesh.mirror` reflects the half onto `CrankArm/b`: 8 664 hex20 elements, all valid, scaled
Jacobian min 0.37 (at the corners where the root arcs meet the bosses 20° off tangent), mean
0.91. Before the mesher cut blocks itself the same crank took seven partitions and eleven exact
seeds for 0.37 (and the swept half without them: min 0.009, its middle free-paved).
**Look at:** the mesh (Prepare ▸ Mesh): rows running straight along the arm, the O-grids round
the bores, eight layers through the arm, and the von Mises contours: the bending stress grows
along the arm toward the root; the peak, 145 MPa, sits at a square-bore corner where the rigid
along the arm toward the root; the peak, 117 MPa, sits at a square-bore corner where the rigid
clamp meets the free face, a support singularity.
**Check:** σxx on the arm's sides at x = 29 mm is −62.43 and +62.43 MPa, equal and opposite as
**Check:** σxx on the arm's sides at x = 29 mm is −62.44 and +62.44 MPa, equal and opposite as
the mirror-image halves are, against the beam formula
M/Z = 1500 · 141 / (16 · 35.6² / 6) = 62.6 MPa (0.3 %); a 41 815-element tet10 solution of the
M/Z = 1500 · 141 / (16 · 35.6² / 6) = 62.6 MPa (0.25 %); a 41 815-element tet10 solution of the
full part gives 62.3 MPa. The pedal bore moves 0.75 mm down (tet10: 0.70–0.75 mm; Euler–Bernoulli
with a rigid clamp: 0.58 mm, without shear or the boss's compliance), and the spindle carries the
whole 1500 N and 255 N·m.
+1 -1
View File
@@ -37,7 +37,7 @@ the control channel and AI agents over MCP (docs/mcp.md) run the same commands.
| Structured Hex | Quad Faces — All-quad meshes of faces on shared edge nodes | coming soon (M5) | |
| Structured Hex | Hex Mesh — Structured hex mesh of a body: automatic, or extruded, swept, revolved or mapped (the Method drop-down) | ready | `mesh.hex.generate`, (`mesh.hex.sweep`), (`mesh.hex.mapped`) |
| Structured Hex | Partitioned Mesh — One mesh of a partitioned part, a method per cell (hex, tet, or all hex as conforming blocks); cells joined across partitions | ready | `mesh.cells`, (`mesh.hex.blocks`) |
| Structured Hex | Decompose — Find sweepable and mappable regions and propose the splits | coming soon (M5) | |
| Structured Hex | Decompose — Find sweepable and mappable regions of 3D parts (extruded cross-sections are already cut into blocks by Hex Mesh) | coming soon (M5) | |
| Structured Hex | Transition — Conforming tet–hex interfaces with pyramids | coming soon (M5) | |
| Automatic Hex | Octree Hex — Unstructured all-hex mesh of any part: adaptive grid, boundary layers on every sharp edge, untangled and proven valid | ready | `mesh.hex.octree` |
| Automatic Hex | Hex-Dominant — Hex-dominant mesh by recombining tets | coming soon (M6) | |
+5 -2
View File
@@ -128,7 +128,9 @@ and `mesh` (each one's parameters: `list_commands`):
`partition:<name>:a` and `partition:<name>:b`; every other face keeps the name of the face it
is a piece of. The partition is part of the model: saving and opening it, or opening the
design again after an edit, cuts the design again. `inspect_model` lists the cells.
3. `mesh` with method `hex`, `hex_sweep`, `hex_mapped` or `tet` on one cell (`{"body":
3. `mesh` with method `hex` on an extruded cell needs no further cuts: its cross-section is cut
into mappable blocks inside the mesher (O-grids round holes, triangle primitives at fillets,
four-sided blocks), so a symmetric part takes one datum. Or `mesh` with method `hex`, `hex_sweep`, `hex_mapped` or `tet` on one cell (`{"body":
"Part/b"}`), or method `cells` for all cells with a method each (`{"methods": {"Part/a":
"tet"}, "default": "auto"}`): cells whose faces match on a partition are merged, others are
tied (the reply lists each interface).
@@ -138,7 +140,8 @@ and `mesh` (each one's parameters: `list_commands`):
5. Or keep the half: `model.boundary_condition.symmetry {name, datum}` holds it on the plane
(zero normal displacement), with half the load.
`file.sample {"name": "crank-mirror"}` opens the crank arm built this way (docs/examples.md).
`file.sample {"name": "crank-mirror"}` opens the crank arm built this way: one datum (`Sym`), its
partition, `hex` on the half and `mirror` (docs/examples.md).
## Edge seeds
Binary file not shown.

Before

Width:  |  Height:  |  Size: 268 KiB

After

Width:  |  Height:  |  Size: 271 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 239 KiB

After

Width:  |  Height:  |  Size: 252 KiB