forked from 1b-agent/fieldcraft-upstream
Rename the project to FieldCraft
Crates fieldcraft-*, binaries fieldcraft and fieldcraft-cli, the .fieldcraft file (format tag fieldcraft/1, manifest fieldcraft.json), FIELDCRAFT_* environment variables, the MCP server name, egui widget ids (fc_*), the app icon document FieldCraft.icon and its generated family, docs and licences. No compatibility shim: no files of the earlier name exist. Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01NmAttHhUZTokgPeEJia8sm
This commit is contained in:
1 parent
9bc4e1b182
commit
d5bd74570f
268 files changed
+1666
-1666
No files matched your search
+12
-12
@@ -4,29 +4,29 @@ Status: accepted (2026-10-13)
|
||||
|
||||
## Context
|
||||
|
||||
ModelCraft is MIT OR Apache-2.0. Everything it links must allow that, and the meshing and solver
|
||||
FieldCraft is MIT OR Apache-2.0. Everything it links must allow that, and the meshing and solver
|
||||
algorithms, where the obvious open-source implementations are GPL-family, must come from papers.
|
||||
|
||||
## Decision
|
||||
|
||||
**Geometry: SolidCraft**, as git dependencies pinned by rev (`solidcraft-kernel`,
|
||||
`solidcraft-geom`, `solidcraft-doc`, `solidcraft-io`; MIT OR Apache-2.0, built on the Apache-2.0
|
||||
truck crates). SolidCraft is the primary geometry source: ModelCraft opens SolidCraft designs and
|
||||
truck crates). SolidCraft is the primary geometry source: FieldCraft opens SolidCraft designs and
|
||||
meshes from SolidCraft's tessellation, and reads face-tagged meshes SolidCraft exports. Other CAD
|
||||
exchange files (STEP, which SolidCraft's kernel already reads) can be added as secondary inputs
|
||||
through the same crate. Only `modelcraft-geometry` may depend on SolidCraft.
|
||||
through the same crate. Only `fieldcraft-geometry` may depend on SolidCraft.
|
||||
|
||||
**Meshing: our own**, implemented from published papers (`docs/meshing/literature.md`).
|
||||
Robust predicates follow Shewchuk's adaptive-precision arithmetic (the paper; his reference
|
||||
`predicates.c` is public domain). A permissive crate may be adopted instead after review; record
|
||||
it here. *Decided 2026-10-13:* our own implementation, `modelcraft_mesh::predicates`, written from
|
||||
it here. *Decided 2026-10-13:* our own implementation, `fieldcraft_mesh::predicates`, written from
|
||||
Shewchuk 1997, Devillers–Teillaud 2011 and Attene 2020 (no `unsafe`, deterministic, wasm-safe, a
|
||||
validated coordinate domain instead of Shewchuk's overflow/underflow caveat, and indirect
|
||||
predicates that `robust` lacks). `robust` (georust, MIT OR Apache-2.0) and `num-bigint` /
|
||||
`num-rational` / `num-traits` (MIT OR Apache-2.0) are dev-dependencies only: differential test
|
||||
oracles, never linked into ModelCraft.
|
||||
oracles, never linked into FieldCraft.
|
||||
|
||||
**Linear algebra: our own.** *Decided 2026-10-13 (implicit solver task):* `modelcraft-solver`
|
||||
**Linear algebra: our own.** *Decided 2026-10-13 (implicit solver task):* `fieldcraft-solver`
|
||||
has its own sparse symmetric storage, nested-dissection ordering (George 1973, by coordinate
|
||||
bisection), up-looking sparse Cholesky (Davis 2006, elimination trees per Liu 1990) and
|
||||
shift-invert block Lanczos with full reorthogonalization (Ericsson–Ruhe 1980, Grimes–Lewis–Simon
|
||||
@@ -44,7 +44,7 @@ parallelism task):* the factorization is now our own supernodal left-looking Cho
|
||||
1994), multithreaded with a fixed operation order (below). Its rounding differs from the old
|
||||
up-looking factor in the last digits; every oracle fixture stays within its band.
|
||||
|
||||
**Threads: rayon** (MIT OR Apache-2.0), in `modelcraft-parallel` only (an L0 crate with no
|
||||
**Threads: rayon** (MIT OR Apache-2.0), in `fieldcraft-parallel` only (an L0 crate with no
|
||||
workspace dependencies; *decided 2026-10-13*). The solvers keep the bit-for-bit rule on any
|
||||
number of threads by construction: work is cut into blocks whose sizes are constants of the
|
||||
algorithm, never derived from the thread count; each floating-point value is computed by one task
|
||||
@@ -57,9 +57,9 @@ per time increment (10⁵–10⁷ increments), so a persistent pool is needed, a
|
||||
re-implement rayon's. rayon was already in the shipped dependency tree (THIRD-PARTY-LICENSES.txt
|
||||
unchanged). In the browser build (`wasm32`) the crate does not depend on rayon and runs the same
|
||||
blocks one after another, with the same results. The thread count is a session and `solve.*`
|
||||
parameter (`threads`, 1–256) whose default is `MODELCRAFT_THREADS` or the available cores. Cost if
|
||||
parameter (`threads`, 1–256) whose default is `FIELDCRAFT_THREADS` or the available cores. Cost if
|
||||
this is wrong: rayon's pool is a process-wide resource and nested pools add latency; replacing it
|
||||
touches only `modelcraft-parallel`.
|
||||
touches only `fieldcraft-parallel`.
|
||||
|
||||
**Allowed:** MIT, BSD-2/3, Apache-2.0, ISC, Zlib, Unicode, MPL-2.0 (as an unmodified dependency),
|
||||
CC0 and public domain.
|
||||
@@ -106,8 +106,8 @@ Thingi10K is not used either (owner decision 2026-10-13: authoring tools unrecor
|
||||
corpus is our own:** parts built with SolidCraft (scripts or designs authored in SolidCraft,
|
||||
committed as their recipes so the geometry is regenerated, not stored) and analytic shapes.
|
||||
Recipes are SolidCraft command scripts run through `solidcraft-engine` (same pinned rev), a
|
||||
dependency of `modelcraft-geometry` only behind its non-default `scripts` feature, which the test
|
||||
tooling (`modelcraft-testkit`) enables; the shipped library opens designs without it.
|
||||
dependency of `fieldcraft-geometry` only behind its non-default `scripts` feature, which the test
|
||||
tooling (`fieldcraft-testkit`) enables; the shipped library opens designs without it.
|
||||
|
||||
**Commercial products** (Abaqus, Nastran, LS-DYNA, LS-PrePost, HyperMesh, ANSA, Femap, Patran,
|
||||
ANSYS) are never run or scripted, and their input files, text and figures are never copied. Deck
|
||||
@@ -120,5 +120,5 @@ docs/verification.md).
|
||||
|
||||
- The tet and hex meshers are significant original work; the literature survey decides the
|
||||
order and the methods.
|
||||
- SolidCraft and ModelCraft move together: bumping the pinned rev bumps the repeated
|
||||
- SolidCraft and FieldCraft move together: bumping the pinned rev bumps the repeated
|
||||
`[patch.crates-io]` entries in the same commit.
|
||||
+41
-41
@@ -1,6 +1,6 @@
|
||||
# Architecture
|
||||
|
||||
ModelCraft turns geometry into finite element models, writes them for the solvers engineers
|
||||
FieldCraft turns geometry into finite element models, writes them for the solvers engineers
|
||||
already use, and solves linear problems itself.
|
||||
|
||||
```
|
||||
@@ -18,33 +18,33 @@ crates in strictly lower layers.
|
||||
|
||||
| Layer | Crate | Role | Status |
|
||||
|---|---|---|---|
|
||||
| L0 | `modelcraft-model` | Solver-neutral FE model: nodes and elements by label, their geometry tags, sets, materials, sections, couplings, BCs, loads and steps, the model check and the resolved view the writers read. Knows no file format and no geometry type. | started |
|
||||
| L0 | `modelcraft-parallel` | Deterministic data parallelism for the solvers: fixed work partitions on a rayon pool, results in block order, the thread-count setting (`MODELCRAFT_THREADS`, `threads`); sequential in the browser. No workspace dependencies. | started |
|
||||
| L1 | `modelcraft-geometry` | The only door to SolidCraft: opens `.solidcraft` designs (rebuilt from their timeline, bodies with persistent face names), B-rep bodies, measures, tessellation into a face-tagged `SurfaceMesh`; face-tagged 3MF files read into the same type without the kernel (docs/formats/tagged-mesh.md). No SolidCraft type in its API. | started |
|
||||
| L1 | `modelcraft-mesh` | Surface preparation (weld, watertightness, feature edges), robust predicates, Delaunay tetrahedralization and refinement, Voronoi-based optimization, hex meshing, quality metrics. | started |
|
||||
| L1 | `modelcraft-fem` | Element kernels shared by every structural solver: the element table (tet4, tet10, wedge6, hex8 full and incompatible modes, hex20 full and reduced), shape functions, quadrature, element stiffness, consistent and lumped mass, body and pressure loads, stresses and their extrapolation, isotropic and orthotropic elasticity, the uniform-strain (one-point) hex8 and tet4 kinematics, hourglass shape vectors and element frequency bounds of the explicit solver, objective stress rates and J2/Johnson–Cook return mapping. Pure functions, no solver loop. | started |
|
||||
| L1 | `modelcraft-decks` | Abaqus input, Nastran bulk data and LS-DYNA keyword readers and writers, to and from `model`. Text out, no file system; `deck.write` saves it. | started |
|
||||
| L1 | `modelcraft-render` | Display data without a GPU dependency: the visible faces, element edges and nodes of a model, the orbit camera, a CPU rasterizer for headless snapshots, geometry surfaces with their face boundaries, deformed shapes and banded contour plots of nodal results, picking. | started |
|
||||
| L2 | `modelcraft-solver` | Implicit solver: assembly from the resolved model, boundary conditions, sparse direct solution, linear static and modal analysis, stresses and reactions. | started |
|
||||
| L2 | `modelcraft-explicit` | Explicit dynamics: central-difference time integration with lumped mass, one-point hex8 with hourglass control, nodal-pressure tet4, bulk viscosity, rigid walls, large deformation with objective rates, plasticity, damage and erosion, energy account, histories and field frames. | started |
|
||||
| L2 | `modelcraft-lbm` | Lattice Boltzmann flow solver on the CPU: D3Q19 two-relaxation-time scheme, bounce-back and slip walls, Zou–He inlets and outlets, obstacles voxelised from the face-tagged surface with exact predicates, momentum-exchange forces per face. Uses `mesh` for the predicates and the boundary surface. | started |
|
||||
| L3 | `modelcraft-fsi` | Fluid–structure coupling between the L2 solvers (later). | planned |
|
||||
| L4 | `modelcraft-doc` | The document: geometry, mesh, model, results, history. | planned |
|
||||
| L5 | `modelcraft-io` | `.modelcraft` files (docs/formats/modelcraft.md): text model definition, binary mesh, geometry references with content hashes, the journal; atomic saves; autosave storage for crash recovery; read and write roots that confine an automation client's file access (`roots`). Bytes in, bytes out; the file system only in `fs`, `recovery` and `roots`. Result files later. | started |
|
||||
| L6 | `modelcraft-engine` | Commands (`CommandSpec`), `Session::execute` with rollback and the panic guard, scripts; every file a command names checked against the session's roots (`Session::file_access`); headless pictures of the session (`view`: model, geometry, deformed shape and contours on the CPU rasterizer). | started |
|
||||
| L7 | `modelcraft-ui-egui`, `modelcraft-mcp` | Desktop UI in the Craft family's layout (title bar with quick actions, workspace ribbon from the catalogue, browser, viewport with navigation bar and orientation gizmo, context panel, command search and command line, journal timeline; native file pickers as host services, background opening and solving; results display with legend and probe; offscreen capture of the whole window) and control channel requests (docs/control-protocol.md); MCP server over stdio (docs/mcp.md): tools over engine commands, a headless session or the running app through its control channel, read and write roots. | ui, mcp started |
|
||||
| testkit | `modelcraft-testkit` | Test tooling, a dev-dependency only: the meshing test corpus (`tests/corpus/*/recipe.json`, analytic shapes) and its runner (`cargo xtask corpus`). | started |
|
||||
| apps | `modelcraft`, `modelcraft-cli`, `modelcraft-web` | Desktop, command line, browser. | desktop, cli started |
|
||||
| L0 | `fieldcraft-model` | Solver-neutral FE model: nodes and elements by label, their geometry tags, sets, materials, sections, couplings, BCs, loads and steps, the model check and the resolved view the writers read. Knows no file format and no geometry type. | started |
|
||||
| L0 | `fieldcraft-parallel` | Deterministic data parallelism for the solvers: fixed work partitions on a rayon pool, results in block order, the thread-count setting (`FIELDCRAFT_THREADS`, `threads`); sequential in the browser. No workspace dependencies. | started |
|
||||
| L1 | `fieldcraft-geometry` | The only door to SolidCraft: opens `.solidcraft` designs (rebuilt from their timeline, bodies with persistent face names), B-rep bodies, measures, tessellation into a face-tagged `SurfaceMesh`; face-tagged 3MF files read into the same type without the kernel (docs/formats/tagged-mesh.md). No SolidCraft type in its API. | started |
|
||||
| L1 | `fieldcraft-mesh` | Surface preparation (weld, watertightness, feature edges), robust predicates, Delaunay tetrahedralization and refinement, Voronoi-based optimization, hex meshing, quality metrics. | started |
|
||||
| L1 | `fieldcraft-fem` | Element kernels shared by every structural solver: the element table (tet4, tet10, wedge6, hex8 full and incompatible modes, hex20 full and reduced), shape functions, quadrature, element stiffness, consistent and lumped mass, body and pressure loads, stresses and their extrapolation, isotropic and orthotropic elasticity, the uniform-strain (one-point) hex8 and tet4 kinematics, hourglass shape vectors and element frequency bounds of the explicit solver, objective stress rates and J2/Johnson–Cook return mapping. Pure functions, no solver loop. | started |
|
||||
| L1 | `fieldcraft-decks` | Abaqus input, Nastran bulk data and LS-DYNA keyword readers and writers, to and from `model`. Text out, no file system; `deck.write` saves it. | started |
|
||||
| L1 | `fieldcraft-render` | Display data without a GPU dependency: the visible faces, element edges and nodes of a model, the orbit camera, a CPU rasterizer for headless snapshots, geometry surfaces with their face boundaries, deformed shapes and banded contour plots of nodal results, picking. | started |
|
||||
| L2 | `fieldcraft-solver` | Implicit solver: assembly from the resolved model, boundary conditions, sparse direct solution, linear static and modal analysis, stresses and reactions. | started |
|
||||
| L2 | `fieldcraft-explicit` | Explicit dynamics: central-difference time integration with lumped mass, one-point hex8 with hourglass control, nodal-pressure tet4, bulk viscosity, rigid walls, large deformation with objective rates, plasticity, damage and erosion, energy account, histories and field frames. | started |
|
||||
| L2 | `fieldcraft-lbm` | Lattice Boltzmann flow solver on the CPU: D3Q19 two-relaxation-time scheme, bounce-back and slip walls, Zou–He inlets and outlets, obstacles voxelised from the face-tagged surface with exact predicates, momentum-exchange forces per face. Uses `mesh` for the predicates and the boundary surface. | started |
|
||||
| L3 | `fieldcraft-fsi` | Fluid–structure coupling between the L2 solvers (later). | planned |
|
||||
| L4 | `fieldcraft-doc` | The document: geometry, mesh, model, results, history. | planned |
|
||||
| L5 | `fieldcraft-io` | `.fieldcraft` files (docs/formats/fieldcraft.md): text model definition, binary mesh, geometry references with content hashes, the journal; atomic saves; autosave storage for crash recovery; read and write roots that confine an automation client's file access (`roots`). Bytes in, bytes out; the file system only in `fs`, `recovery` and `roots`. Result files later. | started |
|
||||
| L6 | `fieldcraft-engine` | Commands (`CommandSpec`), `Session::execute` with rollback and the panic guard, scripts; every file a command names checked against the session's roots (`Session::file_access`); headless pictures of the session (`view`: model, geometry, deformed shape and contours on the CPU rasterizer). | started |
|
||||
| L7 | `fieldcraft-ui-egui`, `fieldcraft-mcp` | Desktop UI in the Craft family's layout (title bar with quick actions, workspace ribbon from the catalogue, browser, viewport with navigation bar and orientation gizmo, context panel, command search and command line, journal timeline; native file pickers as host services, background opening and solving; results display with legend and probe; offscreen capture of the whole window) and control channel requests (docs/control-protocol.md); MCP server over stdio (docs/mcp.md): tools over engine commands, a headless session or the running app through its control channel, read and write roots. | ui, mcp started |
|
||||
| testkit | `fieldcraft-testkit` | Test tooling, a dev-dependency only: the meshing test corpus (`tests/corpus/*/recipe.json`, analytic shapes) and its runner (`cargo xtask corpus`). | started |
|
||||
| apps | `fieldcraft`, `fieldcraft-cli`, `fieldcraft-web` | Desktop, command line, browser. | desktop, cli started |
|
||||
|
||||
Rules beyond the layer order:
|
||||
- Nothing below L7 uses egui, eframe, winit, wgpu or rfd.
|
||||
- Only `modelcraft-geometry` uses `solidcraft-*`, pinned by rev in the workspace `Cargo.toml`.
|
||||
- Only `fieldcraft-geometry` uses `solidcraft-*`, pinned by rev in the workspace `Cargo.toml`.
|
||||
SolidCraft's `[patch.crates-io]` (its fixed truck crates) does not reach dependents, so the
|
||||
workspace repeats it from the same rev; bump both together. The same goes for SolidCraft's
|
||||
patched `egui-wgpu` (MSAA clamped to what the device supports, 1x on OpenGL adapters, so the
|
||||
desktop app's 4x never fails pipeline validation at start).
|
||||
- Everything below the apps builds for `wasm32-unknown-unknown`.
|
||||
- `modelcraft-geometry`'s non-default `scripts` feature builds designs from SolidCraft command
|
||||
- `fieldcraft-geometry`'s non-default `scripts` feature builds designs from SolidCraft command
|
||||
scripts (`script_design`, through `solidcraft-engine`) for the test corpus; the library opens
|
||||
designs without it.
|
||||
|
||||
@@ -56,7 +56,7 @@ Rules beyond the layer order:
|
||||
them), so a load on a named face follows it when the design is edited and opened again.
|
||||
Bodies of components are placed in the world through their occurrences (one body per
|
||||
placement), as SolidCraft displays and exports them.
|
||||
2. **Surface preparation** (`modelcraft-mesh::surface`, `mesh.surface.check`). Weld the tessellation's per-face
|
||||
2. **Surface preparation** (`fieldcraft-mesh::surface`, `mesh.surface.check`). Weld the tessellation's per-face
|
||||
vertex copies (at twice SolidCraft's linear tolerance), check the surface is closed, manifold, consistently and
|
||||
outwardly oriented (voids inwards) and free of self-intersections (exact triangle–triangle tests), and find
|
||||
feature edges (face boundaries, sharp dihedral angles). Defects come back located by triangle, vertex and
|
||||
@@ -64,7 +64,7 @@ Rules beyond the layer order:
|
||||
3. **Tetrahedral meshing.** Bowyer–Watson Delaunay on Shewchuk's adaptive predicates (symbolic
|
||||
perturbation for degeneracies), boundary recovery by the robust constrained Delaunay method of
|
||||
Diazzi et al. 2023 (implicit Steiner points on indirect predicates, gift-wrapping facet
|
||||
recovery; `modelcraft-mesh::cdt`, command `mesh.tet.generate`), so every boundary triangle and
|
||||
recovery; `fieldcraft-mesh::cdt`, command `mesh.tet.generate`), so every boundary triangle and
|
||||
its B-rep face tag survives. Then constrained Delaunay refinement to a
|
||||
size field, ODT smoothing interleaved as in Tournois et al. 2009, and the Klingner–Shewchuk 2007
|
||||
improvement schedule against slivers.
|
||||
@@ -75,12 +75,12 @@ Rules beyond the layer order:
|
||||
frame-field/integer-grid-map methods stay research. Validity uses a certified trilinear Jacobian
|
||||
check (Marschner et al. 2020), not corner Jacobians alone.
|
||||
5. **Structured hex and face meshing.** Faces get all-quad meshes on shared, prescribed edge
|
||||
nodes (`modelcraft-mesh::quad`): transfinite interpolation for four-sided faces (Gordon and
|
||||
nodes (`fieldcraft-mesh::quad`): transfinite interpolation for four-sided faces (Gordon and
|
||||
Hall 1973), and for free faces a half-resolution constrained Delaunay triangulation,
|
||||
recombination (Lee and Lo 1994) and one uniform split that lands on the boundary nodes, then
|
||||
smoothing and untangling; every quad is checked with exact predicates. One `SizeField` trait
|
||||
(`modelcraft-mesh::size`) sets interior sizes and edge divisions, with even counts per loop.
|
||||
Mapped and swept hex build on these face meshes (`modelcraft-mesh::hex`, `mesh.hex.generate`):
|
||||
(`fieldcraft-mesh::size`) sets interior sizes and edge divisions, with even counts per loop.
|
||||
Mapped and swept hex build on these face meshes (`fieldcraft-mesh::hex`, `mesh.hex.generate`):
|
||||
the B-rep topology is recovered from the face-tagged surface; a body is extruded (straight
|
||||
multi-level sweep: the levels' outlines imprinted into one cross-section, cut at reflex corners,
|
||||
regions mapped, O-gridded or free-meshed, then stacked), revolved (the same in a rotating
|
||||
@@ -91,7 +91,7 @@ Rules beyond the layer order:
|
||||
result passes the certified validity gate plus tiling and fidelity checks. A body no method
|
||||
fits gets each method's reason.
|
||||
Without geometry, `mesh.block`
|
||||
(`modelcraft-mesh::block`) meshes one six-sided block from its eight corners and optional
|
||||
(`fieldcraft-mesh::block`) meshes one six-sided block from its eight corners and optional
|
||||
circular or elliptical edges by the same edge-based transfinite interpolation, as hex8, hex20,
|
||||
tet4/tet10 (Kuhn's six tetrahedra per cell) or wedge6, with grading; blocks join where their
|
||||
nodes coincide, face to face (mismatched divisions or kinds are refused), and their named
|
||||
@@ -102,7 +102,7 @@ Rules beyond the layer order:
|
||||
|
||||
## Model definition
|
||||
|
||||
`modelcraft-model` holds the analysis model in no solver's vocabulary (the writers map it to
|
||||
`fieldcraft-model` holds the analysis model in no solver's vocabulary (the writers map it to
|
||||
element names, cards and keywords):
|
||||
|
||||
- **Geometry tags.** Geometry is referred to by name only: a body and, inside it, the persistent
|
||||
@@ -144,27 +144,27 @@ element names, cards and keywords):
|
||||
|
||||
## Implicit solver
|
||||
|
||||
`modelcraft-solver` solves a model's linear static and frequency steps (`solve.static`,
|
||||
`fieldcraft-solver` solves a model's linear static and frequency steps (`solve.static`,
|
||||
`solve.frequency`; `solve.probe` reads the stored results). Methods and papers are cited in the
|
||||
module docs; ADR 0001 records why the linear algebra is our own.
|
||||
|
||||
1. **System.** `Model::resolve()`; each solid section's elements take their material's
|
||||
elasticity matrix and the section's formulation (`modelcraft_fem::element::ELEMENT_TYPES`, one
|
||||
elasticity matrix and the section's formulation (`fieldcraft_fem::element::ELEMENT_TYPES`, one
|
||||
row per element kind: tet4, tet10, wedge6, hex8, hex20); 2D sections (plane stress, plane
|
||||
strain, axisymmetric) take the 2D table (`modelcraft_fem::plane::PLANE_TYPES`: tri3, tri6,
|
||||
strain, axisymmetric) take the 2D table (`fieldcraft_fem::plane::PLANE_TYPES`: tri3, tri6,
|
||||
quad4, quad8), chosen by the section kind, and the model then has two degrees of freedom per
|
||||
node: the 2D elements declare `ElementDofs::new(DofSet::PLANE)` (Ux, Uy) to the `DofLayout`. A 2D model
|
||||
lies in the XY plane (axisymmetric: x the radius, Y the axis; nodes on the axis are held
|
||||
radially), is loaded on element edges, and cannot mix with solids or couplings yet. Rod
|
||||
sections' rod2 and rod3 elements are trusses (`modelcraft_fem::truss`). Point masses, rotary
|
||||
sections' rod2 and rod3 elements are trusses (`fieldcraft_fem::truss`). Point masses, rotary
|
||||
inertia and springs (`Resolved::masses`, `springs`, expanded per node by the model) assemble on
|
||||
the unknowns their nodes are given (`discrete::needs`, `discrete::dof_of`); dashpots are
|
||||
ignored with a warning (no velocities in static and frequency steps). Every reference point a
|
||||
coupling or a discrete element uses gets six degrees of freedom (translations, rotations) after
|
||||
the mesh's. Shell sections make quad4 (MITC4) and tri3 (MITC3) flat shells with a drilling
|
||||
rotation (`modelcraft_fem::shell`; quad8 and tri6 shells are "not supported yet"), beam
|
||||
rotation (`fieldcraft_fem::shell`; quad8 and tri6 shells are "not supported yet"), beam
|
||||
sections two-node Timoshenko beams with the profile's section properties and the section's
|
||||
orientation vector (`modelcraft_fem::beam`); both declare `ElementDofs::new(DofSet::STRUCTURAL)`
|
||||
orientation vector (`fieldcraft_fem::beam`); both declare `ElementDofs::new(DofSet::STRUCTURAL)`
|
||||
(`system::Structural`), so their nodes carry translations and rotations and the solids and
|
||||
trusses sharing those nodes add into the translations. Shells and beams need isotropic
|
||||
materials until material orientations exist, and are 3D only. The step's boundary conditions
|
||||
@@ -226,14 +226,14 @@ source, separate from the analytic gate): the Scordelis–Lo roof and the pinche
|
||||
|
||||
## Explicit solver
|
||||
|
||||
`modelcraft-explicit` integrates a model's `explicit_dynamic` steps in time (`solve.explicit`;
|
||||
`fieldcraft-explicit` integrates a model's `explicit_dynamic` steps in time (`solve.explicit`;
|
||||
`solve.history` and `solve.probe` read the stored histories and frames). Methods and papers are
|
||||
cited in the module docs and in docs/solvers/literature.md (Parts H and J). Both structural solvers
|
||||
number their degrees of freedom with `modelcraft_fem::DofLayout` (docs/fem.md).
|
||||
number their degrees of freedom with `fieldcraft_fem::DofLayout` (docs/fem.md).
|
||||
|
||||
1. **System.** `Model::resolve()`; hex8 sections with reduced integration become one-point
|
||||
uniform-strain hexahedra with Flanagan–Belytschko hourglass control, tet4 sections Bonet–Burton
|
||||
average nodal pressure tetrahedra (`modelcraft_fem::uniform` holds their kinematics), rod2 and
|
||||
average nodal pressure tetrahedra (`fieldcraft_fem::uniform` holds their kinematics), rod2 and
|
||||
rod3 trusses (`discrete`). Point masses add to the lumped mass; springs and dashpots (on the
|
||||
previous half increment's velocity) add internal and viscous forces and their own stable
|
||||
increment. Other element kinds and formulations, couplings, reference points, rotary inertia,
|
||||
@@ -277,7 +277,7 @@ cantilever's free-vibration period against `solve.frequency`.
|
||||
|
||||
## Lattice Boltzmann solver
|
||||
|
||||
`modelcraft-lbm` solves a model's fluid steps (`solve.fluid`; `solve.probe` reads velocity and
|
||||
`fieldcraft-lbm` solves a model's fluid steps (`solve.fluid`; `solve.probe` reads velocity and
|
||||
pressure at points and wall force histories). Papers are cited in the module docs and in
|
||||
`docs/solvers/literature.md` (Part I).
|
||||
|
||||
@@ -322,7 +322,7 @@ journal replays as a script. Each journalled command is also an undo step (the s
|
||||
`edit.redo` puts it back, so the journal always rebuilds the current model. History is bounded by
|
||||
step count and by an estimate of the memory the kept states hold (oldest steps go first).
|
||||
Commands of kind `Session` (`file.*`, `edit.*`) are never journalled. `file.save` and `file.open`
|
||||
write and read `.modelcraft` files; the desktop app autosaves unsaved work for `file.recover`.
|
||||
write and read `.fieldcraft` files; the desktop app autosaves unsaved work for `file.recover`.
|
||||
|
||||
## Test corpus
|
||||
|
||||
@@ -330,10 +330,10 @@ Meshers are measured on our own parts (`docs/adr/0001-libraries.md`, test geomet
|
||||
a SolidCraft command script in `tests/corpus/<name>/recipe.json` (the file `solidcraft-cli run`
|
||||
takes, plus a `corpus` object with its categories and, when it has one, its closed-form volume)
|
||||
with a one-line `README.md`; analytic shapes (sphere, torus, cylinder, thick-walled pipe, plate
|
||||
with a hole) are generated in code. `modelcraft-testkit` runs a recipe in SolidCraft's engine,
|
||||
with a hole) are generated in code. `fieldcraft-testkit` runs a recipe in SolidCraft's engine,
|
||||
saves the design and opens it through `open_design`, the path a person's design takes, so no
|
||||
geometry is stored. `cargo xtask corpus` (a release build of the testkit's `corpus` binary)
|
||||
builds every part, tessellates it and runs each stage of `modelcraft_testkit::runner`, writing
|
||||
builds every part, tessellates it and runs each stage of `fieldcraft_testkit::runner`, writing
|
||||
docs/meshing/corpus.md. A mesher joins by implementing `runner::Stage` (its columns, and a run
|
||||
over the part's tessellated surfaces) and adding itself to `runner::stages()`.
|
||||
|
||||
@@ -343,6 +343,6 @@ over the part's tessellated surfaces) and adding itself to `runner::stages()`.
|
||||
own model of each problem as a command recipe (`recipe.json`, optionally a SolidCraft
|
||||
`design.json`), its cited reference values with tolerances and reasons (`expected.json`), and our
|
||||
frozen results (`fixture.json`). `cargo xtask oracle` runs the testkit's `oracle` binary
|
||||
(`modelcraft_testkit::oracle`): one `Session` per case, quantities read by JSON pointer from step
|
||||
(`fieldcraft_testkit::oracle`): one `Session` per case, quantities read by JSON pointer from step
|
||||
outputs or commands such as `solve.probe {"at": [[x, y, z]]}`, compared with the reference and the
|
||||
fixture; it writes docs/oracle.md. CI runs it as its own job.
|
||||
@@ -1,13 +1,13 @@
|
||||
# Control protocol
|
||||
|
||||
`modelcraft --control PORT` (or `MODELCRAFT_CONTROL_PORT=PORT`) listens on `127.0.0.1:PORT` for
|
||||
`fieldcraft --control PORT` (or `FIELDCRAFT_CONTROL_PORT=PORT`) listens on `127.0.0.1:PORT` for
|
||||
JSON lines. Each request is one line `{"id": …, "method": "…", "params": {…}}`; each reply is one
|
||||
line `{"id": …, "ok": true, "result": …}` or `{"id": …, "ok": false, "error": "…"}`. Requests are
|
||||
handled on the UI thread between frames; pointer and keyboard input is injected as real egui
|
||||
events, one pointer event per frame. The protocol has the same shape as SolidCraft's.
|
||||
|
||||
```text
|
||||
modelcraft --sample --control 7070 # or --sample cantilever | impact
|
||||
fieldcraft --sample --control 7070 # or --sample cantilever | impact
|
||||
{"id":1,"method":"engine.execute","params":{"command":"model.info","params":{}}}
|
||||
→ {"id":1,"ok":true,"result":{"elements":{"hex8":64,"tet4":162},"nodes":199}}
|
||||
{"id":2,"method":"ui.render","params":{"path":"/tmp/model.png","width":900,"height":600}}
|
||||
@@ -28,7 +28,7 @@ checked and clamped (drag steps, wheel lines, window size); `ui.render` refuses
|
||||
| `engine.script` | `commands`: `[{command, params}, …]` | stops at the first error; `journal`: commands that changed the model so far |
|
||||
| `engine.commands` | — | every command: `id`, `label`, `params` (the parameter documentation) |
|
||||
|
||||
Commands never open forms or file pickers when run this way. `modelcraft-cli commands` prints the
|
||||
Commands never open forms or file pickers when run this way. `fieldcraft-cli commands` prints the
|
||||
same registry. `file.sample {name}` opens a sample (`parts`, `cantilever`, `impact`) and
|
||||
`solve.run {}` solves every step; the Results workspace comes up when a result appears.
|
||||
|
||||
@@ -53,8 +53,8 @@ same registry. `file.sample {name}` opens a sample (`parts`, `cantilever`, `impa
|
||||
| `ui.worldToScreen` | `points`: `[[x, y, z]…]` (at most 1000) | screen points in the viewport drawn last frame (null when not on screen) |
|
||||
| `ui.resize` | `width`, `height` | window inner size in points |
|
||||
| `ui.fullscreen` | `on?` (default true) | into or out of full screen; on macOS the title bar's left group moves into the traffic lights' room while there are none |
|
||||
| `ui.screenshot` | `path?` | PNG of the window, taken a few frames later; waits for a presented frame; when none comes within 8 seconds (a hidden window, a locked screen) it answers with `ui.capture`'s offscreen picture (`"offscreen": true`). Without `path`: `modelcraft-shot.png` in the temporary folder |
|
||||
| `ui.capture` | `path?`, `width?`, `height?` (points; default the window's), `scale?` (pixels per point, 0.5–4; default the window's) | PNG of the whole window (title bar, ribbon, open menus and search, panels, forms and the viewport) drawn offscreen, without fade-in animations: the UI pass runs in a separate egui context and is rasterised on the CPU, so it works with the window hidden, minimised or the screen locked. At most 8192 pixels a side and 16 megapixels. Without `path`: `modelcraft-shot.png` in the temporary folder |
|
||||
| `ui.screenshot` | `path?` | PNG of the window, taken a few frames later; waits for a presented frame; when none comes within 8 seconds (a hidden window, a locked screen) it answers with `ui.capture`'s offscreen picture (`"offscreen": true`). Without `path`: `fieldcraft-shot.png` in the temporary folder |
|
||||
| `ui.capture` | `path?`, `width?`, `height?` (points; default the window's), `scale?` (pixels per point, 0.5–4; default the window's) | PNG of the whole window (title bar, ribbon, open menus and search, panels, forms and the viewport) drawn offscreen, without fade-in animations: the UI pass runs in a separate egui context and is rasterised on the CPU, so it works with the window hidden, minimised or the screen locked. At most 8192 pixels a side and 16 megapixels. Without `path`: `fieldcraft-shot.png` in the temporary folder |
|
||||
| `ui.render` | `path`, `width?` (default 1280), `height?` (default 800): whole pixels, each 1–8192 and at most 16 megapixels in all | CPU render of the model with the current camera and view settings (no window or GPU needed). A size out of range, or a scene over 20 million primitives, is an error |
|
||||
| `app.quit` | — | closes the window |
|
||||
|
||||
|
||||
+3
-3
@@ -1,6 +1,6 @@
|
||||
# Element library
|
||||
|
||||
ModelCraft's finite element library (`crates/fem`), family by family, with status. The scope is
|
||||
FieldCraft's finite element library (`crates/fem`), family by family, with status. The scope is
|
||||
modelled on what a full CAE code offers (Abaqus's element library is the reference for breadth);
|
||||
names, formulations and tests are our own, written from the published literature. Deck writers map
|
||||
each of our elements to each solver's name (see `crates/decks`). Simple elements first: 1D and 2D,
|
||||
@@ -32,7 +32,7 @@ hex8/20/27 with first and second derivatives).
|
||||
|---|---|---|
|
||||
| Truss, 2-node (2D and 3D) | Axial members, cables (compression allowed) | done (rod2: implicit, in plane models with their two unknowns per node; explicit, corotational under nonlinear geometry; Abaqus T3D2 / T2D2, Nastran CROD, LS-DYNA truss beam (3D models)) |
|
||||
| Truss, 3-node (2D and 3D) | Curved axial members | done (rod3: implicit, plane models too; explicit with small displacements; Abaqus T3D3 / T2D3; no Nastran or LS-DYNA counterpart) |
|
||||
| Beam, 2-node Timoshenko, 3D | Frames, stiffeners; shear deformable | done (exact interdependent interpolation, profile properties, orientation vector; `modelcraft_fem::beam`) |
|
||||
| Beam, 2-node Timoshenko, 3D | Frames, stiffeners; shear deformable | done (exact interdependent interpolation, profile properties, orientation vector; `fieldcraft_fem::beam`) |
|
||||
| Beam, 2-node Euler–Bernoulli (cubic), 2D and 3D | Slender frames; exact for end-loaded prismatic members | planned (1D elements II) |
|
||||
| Beam, 3-node Timoshenko (quadratic), 2D and 3D | Curved and stocky beams | planned (1D elements II) |
|
||||
| Beam, 2D (planar frames) | In-plane frames with 3 DOFs per node | planned (1D elements II) |
|
||||
@@ -57,7 +57,7 @@ hex8/20/27 with first and second derivatives).
|
||||
|
||||
| Element | Use | Status |
|
||||
|---|---|---|
|
||||
| Shell quad4 (MITC4), triangle (locking-free) | Thin and thick shells | done (flat MITC4 and MITC3 with a Hughes–Brezzi drilling rotation; `modelcraft_fem::shell`) |
|
||||
| Shell quad4 (MITC4), triangle (locking-free) | Thin and thick shells | done (flat MITC4 and MITC3 with a Hughes–Brezzi drilling rotation; `fieldcraft_fem::shell`) |
|
||||
| Shell quad8 / tri6 | Curved thick shells | planned |
|
||||
| Continuum shells (8-node, on swept hex) | Thick-to-thin shells, composites through thickness | planned (M8) |
|
||||
| Membranes (tri3, quad4, quad8) | Fabrics, inflatables, skins without bending | planned |
|
||||
|
||||
+6
-6
@@ -1,7 +1,7 @@
|
||||
# Features
|
||||
|
||||
Generated from the capability catalogue (`crates/engine/src/catalogue.rs`) by
|
||||
`cargo run -p modelcraft-cli -- features > docs/features.md`; a test fails when it is out of date.
|
||||
`cargo run -p fieldcraft-cli -- features > docs/features.md`; a test fails when it is out of date.
|
||||
Every entry is a toolbar button. **Ready** entries run their command; **coming soon** entries are
|
||||
shown greyed with the roadmap milestone that brings them (ROADMAP.md). Scripts, the command line,
|
||||
the control channel and AI agents over MCP (docs/mcp.md) run the same commands.
|
||||
@@ -121,8 +121,8 @@ the control channel and AI agents over MCP (docs/mcp.md) run the same commands.
|
||||
| Decks | Abaqus Input — Write an Abaqus input file (.inp) | ready | `deck.write {"format":"abaqus"}` |
|
||||
| Decks | Nastran Deck — Write Nastran bulk data (SOL 101, 103) | ready | `deck.write {"format":"nastran"}` |
|
||||
| Decks | LS-DYNA Deck — Write an LS-DYNA keyword file | ready | `deck.write {"format":"lsdyna"}` |
|
||||
| Decks | Read Deck — Read a deck, keeping keywords ModelCraft does not know | coming soon (M9) | |
|
||||
| Implicit | Static — Linear static (or coupled temperature–displacement) solve of a step with ModelCraft's own solver; heat transfer in the drop-down | ready | `solve.static`, `solve.heat` |
|
||||
| Decks | Read Deck — Read a deck, keeping keywords FieldCraft does not know | coming soon (M9) | |
|
||||
| Implicit | Static — Linear static (or coupled temperature–displacement) solve of a step with FieldCraft's own solver; heat transfer in the drop-down | ready | `solve.static`, `solve.heat` |
|
||||
| Implicit | Frequency — Natural frequencies and mode shapes of a frequency step | ready | `solve.frequency` |
|
||||
| Explicit | Explicit — Transient dynamics of an explicit step by central differences (contact and erosion coming in M10) | ready | `solve.explicit` |
|
||||
| Explicit | Blast & Impact — EOS-driven fluids with fluid–structure contact (ALE or SPH) | coming soon (M14) | |
|
||||
@@ -153,10 +153,10 @@ the control channel and AI agents over MCP (docs/mcp.md) run the same commands.
|
||||
| Panel | Capability | Status | Command |
|
||||
|---|---|---|---|
|
||||
| Model | Model Info — Node and element counts and the model summary | ready | `model.info` |
|
||||
| File | Open Model — Open a .modelcraft model | ready | `file.open` |
|
||||
| File | Open Model — Open a .fieldcraft model | ready | `file.open` |
|
||||
| File | Samples — Open a sample model, ready to solve | ready | `file.sample` |
|
||||
| File | Save — Save the model to its .modelcraft file | ready | `file.save` |
|
||||
| File | Save As — Save the model to a new .modelcraft file | ready | `file.save_as` |
|
||||
| File | Save — Save the model to its .fieldcraft file | ready | `file.save` |
|
||||
| File | Save As — Save the model to a new .fieldcraft file | ready | `file.save_as` |
|
||||
| File | Recover — Open a model autosaved by an app that crashed or closed with unsaved changes | ready | `file.recover`, `file.recovery.list`, `file.recovery.discard` |
|
||||
| History | Undo — Undo the last command that changed the model | ready | `edit.undo` |
|
||||
| History | Redo — Redo the command undone last | ready | `edit.redo` |
|
||||
+4
-4
@@ -39,13 +39,13 @@ Lookups: `node(label)` / `slot(label)` (a slot is a position: mesh nodes `0..nod
|
||||
`point_slot(k)`), `dof(slot, kind)`, `range(slot)`, `kinds(slot)`, `locate(dof) -> (slot,
|
||||
kind)`, `element_dofs(slots, kinds)`, `describe(dof)`, `stride()` (uniform layouts).
|
||||
|
||||
Trusses declare `modelcraft_fem::truss::DOFS` (translations, on `Basis::Line2`/`Line3`).
|
||||
Trusses declare `fieldcraft_fem::truss::DOFS` (translations, on `Basis::Line2`/`Line3`).
|
||||
Point masses, springs and dashpots are not mesh elements: the implicit solver asks the layout
|
||||
for what each needs at its nodes (`modelcraft_solver::discrete::needs`: translations for a mass
|
||||
for what each needs at its nodes (`fieldcraft_solver::discrete::needs`: translations for a mass
|
||||
or a translational spring, rotations for an inertia or a torsional spring; a reference point
|
||||
they use is a point with six) and finds its unknowns with `discrete::dof_of`.
|
||||
|
||||
Solvers: `modelcraft_solver::system::Mesh::layout` numbers the implicit system (mesh nodes,
|
||||
Solvers: `fieldcraft_solver::system::Mesh::layout` numbers the implicit system (mesh nodes,
|
||||
then six per coupled reference point); assembly (`sparse::add_block(k, layout, slots, kinds,
|
||||
data)`, `add_scalar`, `add_diagonal`) works for any mix of kinds per node, so a solid sharing
|
||||
nodes with a shell adds its translation block into the shell nodes' six-unknown blocks.
|
||||
@@ -108,7 +108,7 @@ A heat conduction element carries one temperature per node (`heat::HEAT_DOFS`, k
|
||||
`heat::Conduction` gives the conductivity ∫ ∇Nᵀ k ∇N dV (full rule), the capacity ∫ ρc N Nᵀ dV
|
||||
and a source ∫ N Q dV (mass rule), and the heat flux −k∇T at the integration points;
|
||||
`heat::face_weights` and `face_film` integrate surface flux and convection on tri3/tri6/quad4/quad8
|
||||
faces. The solver (`modelcraft_solver::heat`) numbers the temperatures with
|
||||
faces. The solver (`fieldcraft_solver::heat`) numbers the temperatures with
|
||||
`DofLayout::uniform(…, DofSet::TEMPERATURE)` and assembles with the same `sparse::add_block`.
|
||||
|
||||
Thermal strain ε_th = α (T − T_ref) along the material axes enters a solid as the load
|
||||
|
||||
@@ -1,26 +1,26 @@
|
||||
# The `.modelcraft` file (format `modelcraft/1`)
|
||||
# The `.fieldcraft` file (format `fieldcraft/1`)
|
||||
|
||||
A `.modelcraft` file holds one model: its definition, its mesh, the geometry it is built on and
|
||||
the commands that built it. It is written and read by `modelcraft-io` (`write`, `read`; bytes in,
|
||||
A `.fieldcraft` file holds one model: its definition, its mesh, the geometry it is built on and
|
||||
the commands that built it. It is written and read by `fieldcraft-io` (`write`, `read`; bytes in,
|
||||
bytes out, so the browser build uses the same code) and by the commands `file.save`,
|
||||
`file.save_as` and `file.open`.
|
||||
|
||||
## Package
|
||||
|
||||
The file is a ZIP package with exactly four parts, in this order, all stored uncompressed (so any
|
||||
unzip tool reads them: `unzip -p bracket.modelcraft model.json`):
|
||||
unzip tool reads them: `unzip -p bracket.fieldcraft model.json`):
|
||||
|
||||
| Part | Content |
|
||||
|---|---|
|
||||
| `modelcraft.json` | Manifest: `format` (`"modelcraft/1"`), `generator` (`"ModelCraft 0.1.0"`), `geometry`, and `parts`: the byte size and SHA-256 of each other part. |
|
||||
| `fieldcraft.json` | Manifest: `format` (`"fieldcraft/1"`), `generator` (`"FieldCraft 0.1.0"`), `geometry`, and `parts`: the byte size and SHA-256 of each other part. |
|
||||
| `model.json` | The model definition: unit system, sets, materials, sections, reference points, couplings, boundary conditions, loads and steps. Pretty-printed JSON with a fixed key order (maps sorted by name), so a change shows as a line diff. Its form is the model's own JSON form, which commands take as parameters. |
|
||||
| `mesh.bin` | Nodes, elements and geometry tags, binary (below). |
|
||||
| `journal.json` | The commands that built the model, `[{"command": id, "params": {...}}, ...]`, one per line. It is a script `modelcraft-cli run` replays. |
|
||||
| `journal.json` | The commands that built the model, `[{"command": id, "params": {...}}, ...]`, one per line. It is a script `fieldcraft-cli run` replays. |
|
||||
|
||||
The same model gives the same bytes on every platform: entry times are fixed (1980-01-01),
|
||||
permissions are fixed, and every map is written in sorted order. To diff two versions with git,
|
||||
add `*.modelcraft diff=modelcraft` to `.gitattributes` and
|
||||
`git config diff.modelcraft.textconv "unzip -p"`; the definition and the journal show line by
|
||||
add `*.fieldcraft diff=fieldcraft` to `.gitattributes` and
|
||||
`git config diff.fieldcraft.textconv "unzip -p"`; the definition and the journal show line by
|
||||
line, the mesh part as binary.
|
||||
|
||||
## Geometry
|
||||
@@ -68,8 +68,8 @@ Every file is treated as hostile:
|
||||
allocation is larger than the input.
|
||||
- Only the four parts, each once. The ZIP CRC and the manifest's size and SHA-256 are checked for
|
||||
every part.
|
||||
- A `format` other than `modelcraft/1` is refused: a later `modelcraft/N` as a version error, any
|
||||
other value as not a ModelCraft file. Unknown fields are errors.
|
||||
- A `format` other than `fieldcraft/1` is refused: a later `fieldcraft/N` as a version error, any
|
||||
other value as not a FieldCraft file. Unknown fields are errors.
|
||||
- `mesh.bin`: counts are capped (50 million nodes and elements, one million entities) and checked
|
||||
against the bytes present before anything is read; labels must ascend; unknown kinds and
|
||||
trailing bytes are refused.
|
||||
@@ -87,8 +87,8 @@ refused.
|
||||
## Autosave and recovery
|
||||
|
||||
The desktop app autosaves every 30 seconds while there are unsaved changes, into the recovery
|
||||
folder (`MODELCRAFT_RECOVERY_DIR`, else `ModelCraft/recovery` in the per-user data folder):
|
||||
`<id>.modelcraft`, `<id>.json` (the model's own path, time, counts) and `<id>.lock`, held while
|
||||
folder (`FIELDCRAFT_RECOVERY_DIR`, else `FieldCraft/recovery` in the per-user data folder):
|
||||
`<id>.fieldcraft`, `<id>.json` (the model's own path, time, counts) and `<id>.lock`, held while
|
||||
the app runs. Saving (or undoing back to the saved state) drops the autosave. After a crash, the
|
||||
next launch reports the entries; `file.recovery.list` lists them, `file.recover` opens one as
|
||||
unsaved work under its original path, and `file.recovery.discard` deletes them.
|
||||
@@ -1,8 +1,8 @@
|
||||
# Face-tagged meshes (3MF with B-rep face tags)
|
||||
|
||||
Besides opening a `.solidcraft` design, geometry can enter ModelCraft as a triangulated boundary
|
||||
Besides opening a `.solidcraft` design, geometry can enter FieldCraft as a triangulated boundary
|
||||
surface written by another program, with each triangle tagged by the B-rep face it lies on.
|
||||
ModelCraft reads it into a `SurfaceMesh` (`modelcraft_geometry::tagged_mesh`, command
|
||||
FieldCraft reads it into a `SurfaceMesh` (`fieldcraft_geometry::tagged_mesh`, command
|
||||
`geometry.import.mesh`) without involving the kernel.
|
||||
|
||||
## The format is SolidCraft's
|
||||
@@ -20,10 +20,10 @@ in the SolidCraft repository. In short:
|
||||
- Coordinates are written in shortest round-trip `f64` form, so they read back exactly.
|
||||
- Within an object, either every triangle is tagged or none is.
|
||||
|
||||
ModelCraft follows that specification and does not extend it. Because the format is 3MF,
|
||||
FieldCraft follows that specification and does not extend it. Because the format is 3MF,
|
||||
untagged 3MF from any other program goes through the same reader, with one face per object.
|
||||
|
||||
## What ModelCraft's reader does
|
||||
## What FieldCraft's reader does
|
||||
|
||||
- **Surfaces.** Every build item becomes one `TaggedSurface`: a `SurfaceMesh` with its name and
|
||||
face count. Lengths are converted to millimetres from `unit`. The surface is named after its
|
||||
@@ -42,7 +42,7 @@ untagged 3MF from any other program goes through the same reader, with one face
|
||||
- Each part is at most 1 GB uncompressed, in at most 10 000 zip entries.
|
||||
- At most 20 million vertices and 20 million triangles, counted over every placement.
|
||||
- At most 10 000 build items, and XML nesting at most 256 deep.
|
||||
- Coordinates must be finite and within ±10⁹ mm (`modelcraft_model::MAX_COORD`), both as read
|
||||
- Coordinates must be finite and within ±10⁹ mm (`fieldcraft_model::MAX_COORD`), both as read
|
||||
and once placed.
|
||||
- Every vertex index must exist.
|
||||
- **Errors.** Any violation is an error that names the problem. Nothing panics.
|
||||
+17
-17
@@ -1,22 +1,22 @@
|
||||
# ModelCraft and AI agents (MCP)
|
||||
# FieldCraft and AI agents (MCP)
|
||||
|
||||
ModelCraft speaks the [Model Context Protocol](https://modelcontextprotocol.io) over stdio
|
||||
FieldCraft speaks the [Model Context Protocol](https://modelcontextprotocol.io) over stdio
|
||||
(JSON-RPC 2.0, one message per line; protocol revisions 2025-06-18, 2025-03-26 and 2024-11-05).
|
||||
An agent builds and solves models the way a person does: every tool runs engine commands, the
|
||||
same ones the UI, scripts, the command line and the control channel run, and never opens a
|
||||
dialog or a file picker. The server is `crates/mcp` (`modelcraft-mcp`); `modelcraft-cli mcp`
|
||||
dialog or a file picker. The server is `crates/mcp` (`fieldcraft-mcp`); `fieldcraft-cli mcp`
|
||||
runs it.
|
||||
|
||||
## Start it
|
||||
|
||||
```sh
|
||||
# Headless (the default): an in-process session, no window; screenshots are CPU renders.
|
||||
modelcraft-cli mcp
|
||||
modelcraft-cli mcp --headless
|
||||
fieldcraft-cli mcp
|
||||
fieldcraft-cli mcp --headless
|
||||
|
||||
# Bridged to the running app, so you can watch the agent work:
|
||||
modelcraft --control 7070 &
|
||||
modelcraft-cli mcp --connect 127.0.0.1:7070
|
||||
fieldcraft --control 7070 &
|
||||
fieldcraft-cli mcp --connect 127.0.0.1:7070
|
||||
```
|
||||
|
||||
With `--connect`, an app that cannot be reached when the server starts gives a headless session
|
||||
@@ -27,21 +27,21 @@ both must run on the same computer.
|
||||
### Claude Code
|
||||
|
||||
```sh
|
||||
claude mcp add modelcraft -- /path/to/modelcraft-cli mcp
|
||||
claude mcp add fieldcraft -- /path/to/fieldcraft-cli mcp
|
||||
# bridged to a running app:
|
||||
claude mcp add modelcraft -- /path/to/modelcraft-cli mcp --connect 127.0.0.1:7070
|
||||
claude mcp add fieldcraft -- /path/to/fieldcraft-cli mcp --connect 127.0.0.1:7070
|
||||
# kept to one project folder:
|
||||
claude mcp add modelcraft -- /path/to/modelcraft-cli mcp --automation-read-root /work/bracket --automation-write-root /work/bracket/out
|
||||
claude mcp add fieldcraft -- /path/to/fieldcraft-cli mcp --automation-read-root /work/bracket --automation-write-root /work/bracket/out
|
||||
```
|
||||
|
||||
Build the binary first (`cargo build --release -p modelcraft-cli`; it is
|
||||
`target/release/modelcraft-cli`). The same setup as a project `.mcp.json`, or in another client's
|
||||
Build the binary first (`cargo build --release -p fieldcraft-cli`; it is
|
||||
`target/release/fieldcraft-cli`). The same setup as a project `.mcp.json`, or in another client's
|
||||
configuration (Claude Desktop's `claude_desktop_config.json`):
|
||||
|
||||
```json
|
||||
{
|
||||
"mcpServers": {
|
||||
"modelcraft": { "command": "/path/to/modelcraft-cli", "args": ["mcp"] }
|
||||
"fieldcraft": { "command": "/path/to/fieldcraft-cli", "args": ["mcp"] }
|
||||
}
|
||||
}
|
||||
```
|
||||
@@ -49,13 +49,13 @@ configuration (Claude Desktop's `claude_desktop_config.json`):
|
||||
## Confining file access
|
||||
|
||||
```sh
|
||||
modelcraft-cli mcp --automation-read-root /work/bracket --automation-write-root /work/bracket/out
|
||||
fieldcraft-cli mcp --automation-read-root /work/bracket --automation-write-root /work/bracket/out
|
||||
```
|
||||
|
||||
The two flags keep the agent to the folders you give it:
|
||||
|
||||
- Every file a command reads must lie inside the **read root**: `open`, `file.open`,
|
||||
`geometry.open`, `geometry.import.mesh`, the design and meshes a `.modelcraft` file opens
|
||||
`geometry.open`, `geometry.import.mesh`, the design and meshes a `.fieldcraft` file opens
|
||||
again, `file.recovery.list` and `file.recover` with a `dir`.
|
||||
- Every file a command writes must lie inside the **write root**: `save`, `file.save` and
|
||||
`file.save_as` (also a save to the model's own file), `write_deck` and `deck.write`,
|
||||
@@ -96,7 +96,7 @@ software on the computer.
|
||||
| `batch` | `commands: [{command, params}]` | Run steps in order, stop at the first error; the reply has every result and the failing step (`failed.index`, `failed.command`, `failed.error`). Steps before it stay applied (`undo` takes them back). |
|
||||
| `inspect_model` | — | `model.info` (counts, units, definitions), `model.activity` (the step table) and `geometry.bodies` (bodies with measures and persistent face names, which sets name as `{body, face}`). |
|
||||
| `check_model` | — | `model.check`: errors and warnings, each naming its item. |
|
||||
| `open` | `path` | By extension: `.modelcraft` (`file.open`), `.solidcraft` (`geometry.open`), `.3mf` (`geometry.import.mesh`). |
|
||||
| `open` | `path` | By extension: `.fieldcraft` (`file.open`), `.solidcraft` (`geometry.open`), `.3mf` (`geometry.import.mesh`). |
|
||||
| `save` | `path?` | `file.save`: to `path` or the model's own file. |
|
||||
| `write_deck` | `format` (abaqus, nastran, lsdyna), `path`, `steps?` | `deck.write`. |
|
||||
| `mesh` | `method`, `params?` | Runs the mesher (`tet`: `mesh.tet.generate`; `planar`: `mesh.planar`; the hex and block meshers as they land) and replies with its result, `model.info` and `mesh.quality`. |
|
||||
@@ -107,7 +107,7 @@ software on the computer.
|
||||
| `screenshot` | `view?`, `source?` (window, model), `width?`, `height?`, `path?` | A PNG image content block and what it shows. Headless: a CPU render framing the model, the geometry and the results display (deformed shape, contour bands). Bridged: the whole app window drawn offscreen (`ui.capture`, the default) or a model render with the app's camera (`ui.render`); `view` turns the app's camera first. |
|
||||
| `undo`, `redo` | — | `edit.undo`, `edit.redo`. |
|
||||
|
||||
Resources: `modelcraft://model` (`model.info`) and `modelcraft://commands` (the command catalog).
|
||||
Resources: `fieldcraft://model` (`model.info`) and `fieldcraft://commands` (the command catalog).
|
||||
|
||||
Errors: an unknown tool, or arguments that do not match the tool's schema (a missing or unknown
|
||||
argument, a wrong type, a value outside an enum), are JSON-RPC `-32602` errors; an engine failure
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# Volume meshing literature survey for ModelCraft (tet → hex)
|
||||
# Volume meshing literature survey for FieldCraft (tet → hex)
|
||||
|
||||
Compiled 2026-10-13. Scope: watertight triangulated B-rep tessellation in, then (1) tetrahedral mesh by
|
||||
Delaunay methods with Voronoi/ODT improvement, then (2) all-hex and hex-dominant meshes.
|
||||
@@ -110,7 +110,7 @@ Delaunay methods with Voronoi/ODT improvement, then (2) all-hex and hex-dominant
|
||||
|
||||
---
|
||||
|
||||
**A0.5 Boundary surface preparation (implemented in `modelcraft-mesh::surface`).** **Verdict: BUILD ON.**
|
||||
**A0.5 Boundary surface preparation (implemented in `fieldcraft-mesh::surface`).** **Verdict: BUILD ON.**
|
||||
- **Guigue and Devillers 2003.** P. Guigue, O. Devillers. *Fast and Robust Triangle–Triangle Overlap Test Using
|
||||
Orientation Predicates.* Journal of Graphics Tools 8(1):25–32, 2003. Triangle overlap decided from `orient3d` /
|
||||
`orient2d` signs alone, so it is exact on the A0.1 predicates. We use the equivalent edge–triangle reduction (two
|
||||
@@ -151,7 +151,7 @@ Delaunay methods with Voronoi/ODT improvement, then (2) all-hex and hex-dominant
|
||||
- Hilbert index: J. Skilling, *Programming the Hilbert curve*, AIP Conf. Proc. 707:381–387, 2004, DOI
|
||||
[10.1063/1.1751381](https://doi.org/10.1063/1.1751381).
|
||||
- **Code.** For a permissive reference, see geogram `delaunay_3d.cpp` (BSD).
|
||||
- **Implemented** in `modelcraft-mesh::delaunay` (ghost vertex for the hull, Devillers–Teillaud perturbation for
|
||||
- **Implemented** in `fieldcraft-mesh::delaunay` (ghost vertex for the hull, Devillers–Teillaud perturbation for
|
||||
cospherical points, exact verifier).
|
||||
|
||||
**A1.2 Marot, Pellerin, Remacle 2019, "One machine, one minute, three billion tetrahedra".** **Verdict: reference (later).**
|
||||
@@ -238,7 +238,7 @@ Delaunay methods with Voronoi/ODT improvement, then (2) all-hex and hex-dominant
|
||||
- **Complexity.** High: about 8–12k lines of Rust including the predicate generator. It is the single most valuable
|
||||
investment in the tet pipeline.
|
||||
- **Code.** `MarcoAttene/CDT` is **GPL, or LGPL by build option** (README): FORBIDDEN.
|
||||
- **Implemented** in `modelcraft-mesh::cdt` from the paper only, with these choices:
|
||||
- **Implemented** in `fieldcraft-mesh::cdt` from the paper only, with these choices:
|
||||
- Steiner points are LNC points (§4.3) on the original segment, `a + t (b − a)` with `t` a double; the in-sphere test
|
||||
on them is exact (interval filter, then exact dyadic integers) and perturbed with the same lexicographic lift as
|
||||
the Delaunay step, so Bowyer–Watson insertion of Steiner points stays consistent with it.
|
||||
@@ -785,7 +785,7 @@ Delaunay methods with Voronoi/ODT improvement, then (2) all-hex and hex-dominant
|
||||
- **HexaLab** (MIT, https://github.com/mlivesu/HexaLab, https://www.hexalab.net) is READ OK. It is a hex quality
|
||||
viewer whose metrics match the literature's.
|
||||
|
||||
**B6.6 Element validity and quality metrics (implemented in `modelcraft-mesh::quality`).** **Verdict: BUILD ON.**
|
||||
**B6.6 Element validity and quality metrics (implemented in `fieldcraft-mesh::quality`).** **Verdict: BUILD ON.**
|
||||
- **Johnen, Remacle, Geuzaine 2013.** *Geometrical validity of curvilinear finite elements.* J. Comput. Phys.
|
||||
233:359–372, 2013. The Jacobian
|
||||
determinant in Bernstein form is bounded by its coefficients, equals them at the vertices and converges under
|
||||
@@ -803,7 +803,7 @@ Delaunay methods with Voronoi/ODT improvement, then (2) all-hex and hex-dominant
|
||||
|
||||
> Shell (curved-face) quad meshing — advancing front in (u,v) with a cross field, recombination and cleanup — is surveyed separately in [shell-quad-literature.md](shell-quad-literature.md).
|
||||
|
||||
(implemented in `modelcraft-mesh::quad`)
|
||||
(implemented in `fieldcraft-mesh::quad`)
|
||||
|
||||
The face meshers under mapped and swept hex meshing and shell meshing. All quads on prescribed
|
||||
boundary nodes, so faces sharing an edge share its nodes. DOIs below were checked through
|
||||
@@ -878,7 +878,7 @@ input points), Steiner points kept half the local spacing from the boundary.
|
||||
|
||||
---
|
||||
|
||||
### B8. Mapped and swept hexahedral meshing (implemented in `modelcraft-mesh::hex`)
|
||||
### B8. Mapped and swept hexahedral meshing (implemented in `fieldcraft-mesh::hex`)
|
||||
|
||||
`mesh.hex.generate` (and `mesh.hex.sweep`, `mesh.hex.mapped`). Every method below is implemented from
|
||||
its paper; no code was read. DOIs marked "checked" were confirmed on 2026-10-13 through a repository
|
||||
@@ -939,14 +939,14 @@ Collision Detection*, 2005, §5.1.5).
|
||||
|
||||
## Part C: Datasets and benchmarks
|
||||
|
||||
| Dataset | Content | Licence | Usable for ModelCraft? |
|
||||
| Dataset | Content | Licence | Usable for FieldCraft? |
|
||||
|---|---|---|---|
|
||||
| **Thingi10K**: Zhou & Jacobson 2016, arXiv https://arxiv.org/abs/1605.04797; site https://ten-thousand-models.appspot.com; tooling https://github.com/Thingi10K/Thingi10K | 10,000 STL meshes. 45% self-intersecting, 50% non-solid. The 4,408 "valid" subset is the standard tet-meshing robustness benchmark (fTetWild, Diazzi 2023). | Tooling Apache-2.0. **Each model has its own licence** (10 licences, including CC-BY-NC and GPL). Filter by the `license` field. | **Conditionally.** Use CC-BY / CC0 / public-domain models for robustness testing. **Provenance risk:** Thingiverse records no authoring tool, and many uploads were modelled in commercial CAD. Under the "no test data produced with commercial CAD products" rule this is an **owner decision**. |
|
||||
| **HexMe**: DOI 10.5281/zenodo.6642020, https://hexme.algohex.eu | 189 tet meshes from 63 CAD models, with feature tags. | Dataset **CC-BY-4.0**. The source models come from the **ABC dataset (Onshape terms), GrabCAD (GrabCAD terms)**, MAMBO (Apache-2.0), and models made with **Gmsh and Siemens NX** (the paper's own statement). | **Only a filtered subset.** The ABC/Onshape, GrabCAD and Siemens NX models are produced with commercial CAD: exclude them. Gmsh-authored ones are acceptable as data. |
|
||||
| **MAMBO**: https://gitlab.com/franck.ledoux/mambo | STEP models: basic, simple, medium. Designed for hex block-meshing evaluation. | **Apache-2.0** | **Risky.** The STEP headers I sampled say `'Spatial InterOp 3D'` as originating system and authors `'Cubit 15.2'` / `'MGX'`. These are commercial or closed tools. Treat as commercial-CAD-produced unless the owner rules otherwise. |
|
||||
| **ABC**: Koch et al., CVPR 2019, DOI [10.1109/CVPR.2019.00983](https://doi.org/10.1109/CVPR.2019.00983), arXiv https://arxiv.org/abs/1812.06216, https://deep-geometry.github.io/abc-dataset/ | 1M CAD models (B-rep and meshes). | "Copyright of the CAD models is owned by their creators", under **Onshape Terms of Use**. The models come from Onshape. | **No.** Produced with a commercial CAD product, and the licence is not open. Skip. |
|
||||
|
||||
**Recommendation for test data.** Build ModelCraft's own corpus:
|
||||
**Recommendation for test data.** Build FieldCraft's own corpus:
|
||||
- **Generated cases.** Parametric primitives plus booleans from our own kernel:
|
||||
- cubes and cylinders with holes;
|
||||
- fillets;
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
# Shell meshing literature survey for ModelCraft: quad and quad-dominant meshes of curved B-rep faces
|
||||
# Shell meshing literature survey for FieldCraft: quad and quad-dominant meshes of curved B-rep faces
|
||||
|
||||
Compiled 2026-10-13. Scope: all-quad and quad-dominant surface meshes of the curved faces (planes, cylinders,
|
||||
cones, spheres, tori, NURBS) of SolidCraft parts, meshed in each face's (u,v) parameter space with metric
|
||||
correction and conforming across shared B-rep edges, for shell analysis (MITC4-class shells now,
|
||||
continuum shells on swept hexes in M8). This extends `docs/meshing/literature.md` §B7, which compared
|
||||
paving, Q-Morph and Blossom-Quad for **planar** faces only and chose CDT → greedy recombination →
|
||||
Catmull–Clark split (`modelcraft-mesh::quad`).
|
||||
Catmull–Clark split (`fieldcraft-mesh::quad`).
|
||||
|
||||
Same format as `docs/meshing/literature.md`: per paper, citation, DOI/URL, method, problem solved,
|
||||
robustness/limits, complexity, code + licence, verdict. Part P is the opinionated plan.
|
||||
@@ -126,7 +126,7 @@ robustness/limits, complexity, code + licence, verdict. Part P is the opinionate
|
||||
**S2.2 Owen and Saigal 2000, Surface mesh sizing control.** **Verdict: build on (size field on faces).**
|
||||
- **Citation.** IJNME 47(1–3):497–511, 2000. DOI [10.1002/(SICI)1097-0207(20000110/30)47:1/3<497::AID-NME781>3.0.CO;2-H](https://doi.org/10.1002/(SICI)1097-0207(20000110/30)47:1/3%3C497::AID-NME781%3E3.0.CO;2-H). *Read:* metadata.
|
||||
- **Method.** Automatic sizing on CAD surfaces from curvature and proximity, stored on a background mesh.
|
||||
- **Use.** The curvature and proximity terms of ModelCraft's surface size field (P3.3).
|
||||
- **Use.** The curvature and proximity terms of FieldCraft's surface size field (P3.3).
|
||||
|
||||
**S2.3 Lo 1989; Lau, Lo, Lee 1997; Lo and Lau 1998: quadrilaterals over curved surfaces.** **Verdict: reference.**
|
||||
- **Citations.**
|
||||
@@ -193,7 +193,7 @@ robustness/limits, complexity, code + licence, verdict. Part P is the opinionate
|
||||
**S3.2 Borouchaki, George, Hecht, Laug, Saltel 1997, Delaunay mesh generation governed by metric specifications.** **Verdict: build on (only if non-conformal parametrizations need an anisotropic Delaunay kernel).**
|
||||
- **Citation.** Part I: FEAD 25(1–2):61–83, 1997, DOI [10.1016/S0168-874X(96)00057-1](https://doi.org/10.1016/S0168-874X(96)00057-1); Part II: FEAD 25:85–109, DOI [10.1016/S0168-874X(96)00065-0](https://doi.org/10.1016/S0168-874X(96)00065-0). *Read:* metadata.
|
||||
- **Method.** The Delaunay criterion evaluated in a local metric (anisotropic Bowyer–Watson cavity).
|
||||
- **Caveat for ModelCraft.** A metric in-circle test is not an exact predicate of the input coordinates; it
|
||||
- **Caveat for FieldCraft.** A metric in-circle test is not an exact predicate of the input coordinates; it
|
||||
may only decide *point placement* and *which flip to try*, never validity. Validity stays an exact `orient2d`
|
||||
sign in (u,v) (see P3.5).
|
||||
|
||||
@@ -315,7 +315,7 @@ robustness/limits, complexity, code + licence, verdict. Part P is the opinionate
|
||||
- **Complexity.** Same as frontal-Delaunay triangulation, O(n log n); "tens of thousands of elements a minute"
|
||||
(§1) in 2010-era hardware.
|
||||
- **Why it matters here.** It is a marching front, but one whose collisions cannot fail, and it is a small
|
||||
change to machinery ModelCraft already has (Bowyer–Watson, constrained recovery, recombination).
|
||||
change to machinery FieldCraft already has (Bowyer–Watson, constrained recovery, recombination).
|
||||
|
||||
**S5.2 Georgiadis, Beaufort, Lambrechts, Remacle 2017, High quality mesh generation using cross and asterisk fields.** **Verdict: reference.**
|
||||
- **Citation.** arXiv <https://arxiv.org/abs/1706.02236>, 2017. *Read:* abstract.
|
||||
@@ -346,7 +346,7 @@ robustness/limits, complexity, code + licence, verdict. Part P is the opinionate
|
||||
slow on faces over 100k vertices; acute corners (< 45°) need artificial singularities; size-map vs
|
||||
cross-field compatibility "still open".
|
||||
- **Why it matters here.** Strongest published evidence on CAD B-reps for any automatic all-quad method, and
|
||||
it uses **the same tri → recombine → split guarantee ModelCraft already ships**, with better point placement
|
||||
it uses **the same tri → recombine → split guarantee FieldCraft already ships**, with better point placement
|
||||
in front of it and cleanup behind it. It is the template for P.
|
||||
- **Data caveat.** Both datasets are excluded for our own tests (see `literature.md` Part C); we cite the numbers only.
|
||||
|
||||
@@ -372,7 +372,7 @@ robustness/limits, complexity, code + licence, verdict. Part P is the opinionate
|
||||
- **Citation.** IJNME 89(9):1102–1119, 2012. DOI [10.1002/nme.3279](https://doi.org/10.1002/nme.3279). *Read:* metadata.
|
||||
- **Note.** Reberol 2021 replaced Blossom with a greedy, alignment-weighted matching followed by the split, which
|
||||
removes the "perfect matching may not exist" failure and the cubic-time matching. That supports keeping
|
||||
ModelCraft's greedy matching.
|
||||
FieldCraft's greedy matching.
|
||||
|
||||
**S6.3 Ramaswami, Ramos, Toussaint 1998, Converting triangulations to quadrangulations.** **Verdict: reference (theory).**
|
||||
- **Citation.** CGTA 9(4):257–276, 1998. DOI [10.1016/S0925-7721(97)00019-9](https://doi.org/10.1016/S0925-7721(97)00019-9).
|
||||
@@ -619,14 +619,14 @@ cylinder displacement under the load 1.8248×10⁻⁵ (E = 3×10⁶, P = 1); pin
|
||||
|
||||
---
|
||||
|
||||
## Part P: Recommended plan for ModelCraft shell meshing (opinionated)
|
||||
## Part P: Recommended plan for FieldCraft shell meshing (opinionated)
|
||||
|
||||
### P1. Position
|
||||
|
||||
**I agree with a cross-field-guided advancing front in (u,v) with a metric and topological cleanup, with one
|
||||
change: the front advances *points over a Delaunay triangulation* (frontal-Delaunay in the cross-field L∞
|
||||
norm, Remacle 2013), not quads (paving) and not triangle-to-quad transformations (Q-Morph).** All-quad comes
|
||||
from the recombination + split ModelCraft already ships, and cleanup follows Reberol 2021.
|
||||
from the recombination + split FieldCraft already ships, and cleanup follows Reberol 2021.
|
||||
|
||||
Reasons:
|
||||
1. **Closure cannot fail.** A frontal-Delaunay front always sits inside a valid constrained triangulation, so
|
||||
@@ -668,13 +668,13 @@ For each B-rep face set to be shell-meshed (a sheet body, or chosen faces of a s
|
||||
|
||||
### P3. Components
|
||||
|
||||
**P3.1 Chart abstraction** (`modelcraft-mesh::surface_mesh::chart` or a new `shell` module; trait in `mesh`,
|
||||
**P3.1 Chart abstraction** (`fieldcraft-mesh::surface_mesh::chart` or a new `shell` module; trait in `mesh`,
|
||||
implementation in `geometry`, wired in `engine`, so `mesh` does not depend on `geometry`):
|
||||
`eval(u,v) → [f64;3]`, `derivs(u,v) → (S_u, S_v)` (second derivatives for curvature sizing), `project(p,
|
||||
hint) → (u,v)`, the face's loops as 3D node chains with their (u,v), periodicity and singular points. Native
|
||||
charts come from SolidCraft's kernel surfaces (truck's parametric surfaces already have parameter search, used
|
||||
in 5 SolidCraft kernel files); this needs a new **public** face-surface API in `solidcraft-kernel`, exposed
|
||||
through `modelcraft-geometry` without leaking SolidCraft types. Handling:
|
||||
through `fieldcraft-geometry` without leaking SolidCraft types. Handling:
|
||||
- **Periodic faces** (cylinder, torus, revolved): the seam edge appears twice in the loop; give its nodes
|
||||
u = 0 on one side and u = period on the other (unwrap by continuity along the loop). The domain becomes simply
|
||||
connected; seam nodes are the same 3D nodes, so conformity across the seam holds.
|
||||
@@ -772,7 +772,7 @@ ship.
|
||||
### P6. Order of work
|
||||
|
||||
1. **Chart API** in `solidcraft-kernel` (public face-surface evaluation and parameter search) and
|
||||
`modelcraft-geometry` (trait implementation, seams, poles). Done when the P5.1 tests pass.
|
||||
`fieldcraft-geometry` (trait implementation, seams, poles). Done when the P5.1 tests pass.
|
||||
2. **Port the shipped free mesher to (u,v) + metric**: half-resolution CDT and Ruppert refinement in the
|
||||
rescaled (u,v) with metric sizing, recombination, split, smoothing with 3D objective. This gives all-quad
|
||||
conforming meshes on curved faces early, and is the baseline.
|
||||
|
||||
+3
-3
@@ -1,12 +1,12 @@
|
||||
# Verification and validation oracle
|
||||
|
||||
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 ModelCraft 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.
|
||||
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.
|
||||
|
||||
**117 of 123 quantities pass** (6 known failure(s)) in 35 active cases: 26 theory, 9 published benchmark, 0 experiment; 9 pending cases wait for capabilities still being built.
|
||||
|
||||
## Theory: closed-form solutions, patch tests and mesh invariants
|
||||
|
||||
| Case | Quantity | Reference | ModelCraft | Error | Tolerance | Result | Fixture |
|
||||
| Case | Quantity | Reference | FieldCraft | Error | Tolerance | Result | Fixture |
|
||||
|---|---|---|---|---|---|---|---|
|
||||
| [bar-pressure-wave](../tests/oracle/bar-pressure-wave/) | displacement of the loaded end at t = 0.06 | -6.0000e-4 | -5.9980e-4 | 0.034% | 1% | pass | matches |
|
||||
| [bar-pressure-wave](../tests/oracle/bar-pressure-wave/) | particle velocity at x = 5, 20 elements behind the front, at t = 0.06 | -0.01 | -0.0098552 | 1.45% | 2% | pass | matches |
|
||||
@@ -108,7 +108,7 @@ Generated by `cargo xtask oracle` from [`tests/oracle/`](../tests/oracle/); the
|
||||
|
||||
## Published benchmarks
|
||||
|
||||
| Case | Quantity | Reference | ModelCraft | Error | Tolerance | Result | Fixture |
|
||||
| Case | Quantity | Reference | FieldCraft | Error | Tolerance | Result | Fixture |
|
||||
|---|---|---|---|---|---|---|---|
|
||||
| [mh-curved-cantilever](../tests/oracle/mh-curved-cantilever/) | tip displacement along the in-plane load | 0.08734 | 0.076833 | -12% | 2% | known failure: 0.880 of the theory, grade C: straight-sided hex8 on six elements over 90° (MacNeal–Harder's HEXA(8): 0.880, Table 9 p. 15) | — |
|
||||
| [mh-curved-cantilever](../tests/oracle/mh-curved-cantilever/) | tip displacement along the out-of-plane load | 0.5022 | 0.40095 | -20.2% | 2% | known failure: 0.798 of the theory, grade D: out-of-plane bending with torsion on one element across (MacNeal–Harder's HEXA(8): 0.849) | — |
|
||||
|
||||
+7
-7
@@ -1,6 +1,6 @@
|
||||
# Capability checklist (reference: Abaqus/CAE)
|
||||
|
||||
What an analyst does in a full CAE pre-processor, grouped by milestone, with ModelCraft's status.
|
||||
What an analyst does in a full CAE pre-processor, grouped by milestone, with FieldCraft's status.
|
||||
Scope comes from the public documentation of Abaqus/CAE and public analyst discussion,
|
||||
described in our own words; nothing was taken from the product itself (AGENTS.md: no commercial
|
||||
products are run, no documentation text is copied). Status: **done**, **started**, **planned**.
|
||||
@@ -8,7 +8,7 @@ products are run, no documentation text is copied). Status: **done**, **started*
|
||||
|
||||
## Where we aim to be better
|
||||
|
||||
| # | Opportunity | Why analysts want it | ModelCraft approach |
|
||||
| # | Opportunity | Why analysts want it | FieldCraft approach |
|
||||
|---|---|---|---|
|
||||
| 1 | Hex meshes without manual partitioning | Partitioning a part into sweepable cells by hand is the most cited chore | Sweep and mapped meshing with automatic decomposition that proposes SolidCraft splits (M5); octree all-hex for anything else (M6) |
|
||||
| 2 | Undo, redo, replay, crash recovery | No general undo; replay files are hard to reuse; corrupted model files | Every action is a journalled command with rollback, undo and redo; autosave with recovery after a crash |
|
||||
@@ -16,7 +16,7 @@ products are run, no documentation text is copied). Status: **done**, **started*
|
||||
| 4 | An API that is not a bundled scripting runtime | Version breakage, slow scripts, geometry picked by position | JSON commands over CLI, control channel and MCP |
|
||||
| 5 | Located diagnostics | Generic error messages | Errors name the element, face or keyword; `mesh.quality` lists failing elements |
|
||||
| 6 | Lossless deck round trip | Unsupported keywords dropped on import | Deck readers keep unknown keywords and write them back (M9) |
|
||||
| 7 | Safe, diffable model files | Binary model databases that corrupt or lock to a version | `.modelcraft`: text, line-diffable definition and journal, checksummed binary mesh, versioned format tag, atomic saves with backup, autosave (M3, done) |
|
||||
| 7 | Safe, diffable model files | Binary model databases that corrupt or lock to a version | `.fieldcraft`: text, line-diffable definition and journal, checksummed binary mesh, versioned format tag, atomic saves with backup, autosave (M3, done) |
|
||||
| 8 | Geometry checked before meshing | Slivers and tiny faces fail late | Surface preparation reports defects with their location (M1) |
|
||||
| 9 | No size caps, any solver | Node limits in learning editions; one solver per tool | Free, open source, three deck formats |
|
||||
| 10 | Clear step history | Loads and BCs propagate between steps implicitly | An explicit step × load/BC table (M3) |
|
||||
@@ -33,7 +33,7 @@ products are run, no documentation text is copied). Status: **done**, **started*
|
||||
| Mesh | Size field: global, per face and edge seeds, bias, curvature and proximity refinement | M2 | yes | planned |
|
||||
| Mesh | Free tet meshing (tet4, tet10 with mid-side nodes on the geometry) | M2 | | started |
|
||||
| Mesh | Quality metrics, certified validity, verify per set | M1–M2 | yes | done (metrics, gate) |
|
||||
| Mesh | 2D quad meshing of faces | M5 | yes | started (`modelcraft_mesh::quad`; `mesh.planar`: 2D models of a polygon or a planar face, quad4/quad8/tri3/tri6, edges tagged by their neighbouring face) |
|
||||
| Mesh | 2D quad meshing of faces | M5 | yes | started (`fieldcraft_mesh::quad`; `mesh.planar`: 2D models of a polygon or a planar face, quad4/quad8/tri3/tri6, edges tagged by their neighbouring face) |
|
||||
| Mesh | Mapped hex of six-sided regions | M5 | yes | done (`mesh.hex.mapped`) |
|
||||
| Mesh | Sweep hex (extrusions, revolutions) | M5 | yes | done (`mesh.hex.sweep`: multi-level extrusions, revolutions, one-to-one sweeps) |
|
||||
| Mesh | Automatic decomposition into sweepable and mappable regions | M5 | yes | planned |
|
||||
@@ -69,7 +69,7 @@ products are run, no documentation text is copied). Status: **done**, **started*
|
||||
| Results | Readers for public result formats (Nastran OP2, LS-DYNA d3plot, Abaqus `.fil`) | M9 | | planned |
|
||||
| Results | Mesh convergence studies | M9 | | planned |
|
||||
| App | Desktop viewport, model tree, commands, control channel | continuous | | done |
|
||||
| App | Undo/redo on the command journal, autosave, `.modelcraft` file | M3 | | done |
|
||||
| App | Undo/redo on the command journal, autosave, `.fieldcraft` file | M3 | | done |
|
||||
| App | MCP server, browser build | continuous | | planned |
|
||||
|
||||
## Deck notes for the writers
|
||||
@@ -84,14 +84,14 @@ products are run, no documentation text is copied). Status: **done**, **started*
|
||||
`crates/decks/src/abaqus.rs`). The step table is bridged to Abaqus's propagation: zero-valued
|
||||
boundary conditions active in every step go to the initial state, and steps restate their
|
||||
boundary conditions and loads with `OP=NEW` when the active set changes.
|
||||
- Nastran (`modelcraft_decks::nastran`): entries with a real use large (16-column) fields, the rest
|
||||
- Nastran (`fieldcraft_decks::nastran`): entries with a real use large (16-column) fields, the rest
|
||||
small fields; a real is exact when its shortest round-trip form fits 16 columns, else rounded to
|
||||
at least ten significant digits. Linear solids map full integration to `PSOLID` `TWO`/`THREE` +
|
||||
`FULL`, hex20 reduced to `TWO` + `FULL`, hex8 incompatible modes to `BUBBLE`; one-point reduced
|
||||
linear solids, hybrid solids, reduced-integration or one-point shells, body forces, gravity on part
|
||||
of the model, orthotropic beams and rods, and orthotropic shells off planes of constant Z are
|
||||
reported as unsupported. Static and frequency steps need separate decks (`deck.write` `steps`).
|
||||
- LS-DYNA (`modelcraft_decks::lsdyna`, `deck.write {"format": "lsdyna"}`): long format (20-column
|
||||
- LS-DYNA (`fieldcraft_decks::lsdyna`, `deck.write {"format": "lsdyna"}`): long format (20-column
|
||||
fields; every value with up to 13 significant digits, and 17-digit values from 0.01 to 1e17, are
|
||||
written exactly; the rest is rounded to at least 13 digits and counted). The 10-node tetrahedron
|
||||
follows the manual's figure: mid-side nodes 8, 9, 10 on edges 2-4, 3-4, 1-4 (the model has them
|
||||
|
||||
+21
-21
@@ -1,4 +1,4 @@
|
||||
# Solver literature survey for ModelCraft: explicit dynamics, equations of state, lattice Boltzmann, FSI
|
||||
# Solver literature survey for FieldCraft: explicit dynamics, equations of state, lattice Boltzmann, FSI
|
||||
|
||||
Compiled 2026-10-13. Scope: three new solver families on top of the planned implicit linear solver (M6):
|
||||
(A) an explicit Lagrangian finite element solver of the LS-DYNA / Abaqus-Explicit class, (B) equations of state for
|
||||
@@ -560,7 +560,7 @@ JCP 232(1):100–117, 2013, DOI [10.1016/j.jcp.2012.07.023](https://doi.org/10.1
|
||||
- **Method.** For each wall link, the fraction q ∈ (0, 1] of the link inside the fluid; linear or quadratic
|
||||
interpolation of the reflected population, second-order for curved walls.
|
||||
- **Needs from meshing.** q comes from ray–triangle intersection of the lattice link with the face-tagged boundary
|
||||
surface — robust predicates (modelcraft-mesh) give the inside/outside decision; q itself is a constructed value.
|
||||
surface — robust predicates (fieldcraft-mesh) give the inside/outside decision; q itself is a constructed value.
|
||||
- **Limits.** Not mass conservative; small q (< ~0.01) can destabilise: treat as q = 0 or use the Mei variant.
|
||||
- **Also.** R. Mei, L.-S. Luo, W. Shyy, JCP 155(2):307–330, 1999, DOI [10.1006/jcph.1999.6334](https://doi.org/10.1006/jcph.1999.6334) — the alternative curved-boundary scheme. **Reference.**
|
||||
|
||||
@@ -794,7 +794,7 @@ IB is simpler with a deforming FE surface; bounce-back is better for rigid or sl
|
||||
- S. W. Attaway, M. W. Heinstein, J. W. Swegle. *Coupling of smooth particle hydrodynamics with the finite element method.* Nucl. Eng. Des. 150:199–205, 1994. DOI [10.1016/0029-5493(94)90136-8](https://doi.org/10.1016/0029-5493(94)90136-8).
|
||||
- C. Antoci, M. Gallati, S. Sibilla. *Numerical simulation of fluid–structure interaction by SPH.* Comput. Struct. 85(11–14):879–890, 2007. DOI [10.1016/j.compstruc.2007.01.002](https://doi.org/10.1016/j.compstruc.2007.01.002).
|
||||
- **Assessment.** SPH shares the explicit solver's whole stack (time step, EOS, Johnson–Cook, artificial viscosity,
|
||||
contact via the same penalty), so it slots *into* `modelcraft-explicit` as another discretisation — the natural
|
||||
contact via the same penalty), so it slots *into* `fieldcraft-explicit` as another discretisation — the natural
|
||||
home for hypervelocity impact, fragmentation and blast with JWL, which LBM cannot do. As a general fluid solver it is
|
||||
noisy (pressure), needs many particles for accuracy and has the tensile instability; LBM beats it for viscous
|
||||
low-Mach flow. Code: SPHinXsys (Apache-2.0), SPlisHSPlasH (MIT), PySPH (BSD-3-style), Cabana (BSD-3): READ OK;
|
||||
@@ -812,7 +812,7 @@ IB is simpler with a deforming FE surface; bounce-back is better for rigid or sl
|
||||
codes) but coordinates/displacements over long runs need f64 accumulation; that rules out a naive GPU port.
|
||||
- **Layering.** `xtask/src/layers.rs` lists `wgpu` in `UI_CRATES`: nothing below L5 may depend on it. A GPU backend
|
||||
therefore needs either an owner decision to allow `wgpu` in a dedicated compute crate below L5 (headless compute is
|
||||
not UI), or a `modelcraft-gpu` crate at L5 that implements a backend trait the L1 solver crates define. I recommend
|
||||
not UI), or a `fieldcraft-gpu` crate at L5 that implements a backend trait the L1 solver crates define. I recommend
|
||||
the second (no rule change): the solver crate defines a `LatticeBackend` trait and a CPU implementation; the GPU
|
||||
implementation lives at L5. **Owner decision either way.**
|
||||
- **Determinism.** The project requires bit-identical output on every platform. GPU f32 results differ from CPU and
|
||||
@@ -859,25 +859,25 @@ Implicit and explicit share element kinematics (shape functions, quadrature, B-m
|
||||
|
||||
| Layer | Crate | Contents |
|
||||
|---|---|---|
|
||||
| L0 | `modelcraft-model` | + materials, EOS, sections/formulations, explicit and fluid steps, contact, fluid domains, coupling interfaces (F3) |
|
||||
| L1 | `modelcraft-fem` (new) | element kernels (shape functions, quadrature, B/B-bar, one-point hex with FB hourglass and Belytschko–Bindeman stabilisation, Bonet–Burton tet, BLT shell), constitutive updates (hypoelastic, objective rates, J2 radial return, Johnson–Cook, damage), EOS evaluation. Pure functions over `model` types; no solver loop. |
|
||||
| L2 | `modelcraft-lbm` (new) | lattices, collision operators, BCs, voxelisation from the face-tagged surface and the octree from `mesh`\*, stepping on CPU, momentum-exchange forces, IB kernels; a backend trait for GPU |
|
||||
| L2 | `modelcraft-solver` (moved up from L1) | implicit linear static/modal (M6), later nonlinear implicit; uses `fem` |
|
||||
| L2 | `modelcraft-explicit` (new) | central-difference driver, time step, mass scaling, q, contact (search + penalty), erosion, energy accounting, output; uses `fem` (and later SPH) |
|
||||
| L3 | `modelcraft-fsi` (new) | IB coupling, interface mapping, Aitken/IQN-ILS, subcycling, coupled step driver; uses `explicit`, `solver`, `lbm` |
|
||||
| L0 | `fieldcraft-model` | + materials, EOS, sections/formulations, explicit and fluid steps, contact, fluid domains, coupling interfaces (F3) |
|
||||
| L1 | `fieldcraft-fem` (new) | element kernels (shape functions, quadrature, B/B-bar, one-point hex with FB hourglass and Belytschko–Bindeman stabilisation, Bonet–Burton tet, BLT shell), constitutive updates (hypoelastic, objective rates, J2 radial return, Johnson–Cook, damage), EOS evaluation. Pure functions over `model` types; no solver loop. |
|
||||
| L2 | `fieldcraft-lbm` (new) | lattices, collision operators, BCs, voxelisation from the face-tagged surface and the octree from `mesh`\*, stepping on CPU, momentum-exchange forces, IB kernels; a backend trait for GPU |
|
||||
| L2 | `fieldcraft-solver` (moved up from L1) | implicit linear static/modal (M6), later nonlinear implicit; uses `fem` |
|
||||
| L2 | `fieldcraft-explicit` (new) | central-difference driver, time step, mass scaling, q, contact (search + penalty), erosion, energy accounting, output; uses `fem` (and later SPH) |
|
||||
| L3 | `fieldcraft-fsi` (new) | IB coupling, interface mapping, Aitken/IQN-ILS, subcycling, coupled step driver; uses `explicit`, `solver`, `lbm` |
|
||||
| L4… | `doc`, `io`, `engine`, then L5+ shifts up by two | results (time histories, field frames) in `doc`/`io` |
|
||||
| L5+ | `modelcraft-gpu` (new, with the UI layer or an owner-approved compute layer) | wgpu implementations of the solver backend traits |
|
||||
| L5+ | `fieldcraft-gpu` (new, with the UI layer or an owner-approved compute layer) | wgpu implementations of the solver backend traits |
|
||||
|
||||
\* `modelcraft-lbm` needs the octree and predicates from `modelcraft-mesh` (L1), so it sits at L2. **`lbm` at L2** next to `solver` and `explicit` (it may then use `mesh`'s octree and
|
||||
\* `fieldcraft-lbm` needs the octree and predicates from `fieldcraft-mesh` (L1), so it sits at L2. **`lbm` at L2** next to `solver` and `explicit` (it may then use `mesh`'s octree and
|
||||
predicates), and `fem` at L1. That is one coherent rule: L1 = geometry and math kernels, L2 = solvers, L3 = coupling.
|
||||
|
||||
Cost of this being wrong: renumbering the layer table is a mechanical edit to `xtask/src/layers.rs` and
|
||||
`docs/architecture.md`; the risk is churn, not breakage. The alternative (one `modelcraft-solver` crate with
|
||||
`docs/architecture.md`; the risk is churn, not breakage. The alternative (one `fieldcraft-solver` crate with
|
||||
`implicit`/`explicit`/`lbm`/`fsi` modules) needs no layer change, but a 50k-line crate compiles slowly and lets the
|
||||
LBM depend on FE internals by accident. If the owner prefers no renumbering, take the single-crate option and enforce
|
||||
module boundaries with `pub(crate)` discipline. This layout change is an owner decision.
|
||||
|
||||
### F3. Solver-neutral model extensions in `modelcraft-model`
|
||||
### F3. Solver-neutral model extensions in `fieldcraft-model`
|
||||
|
||||
- **Materials** (named, unit-consistent, no product numbering): density; isotropic elastic; J2 plasticity with
|
||||
isotropic/kinematic hardening (bilinear, power law, table); Johnson–Cook strength (A, B, n, C, m, ε̇₀, T_room,
|
||||
@@ -906,7 +906,7 @@ All of these must map to the LS-DYNA keyword and Abaqus input concepts M5 writes
|
||||
|
||||
| # | Milestone | Needs from meshing | Verification (analytic first) |
|
||||
|---|---|---|---|
|
||||
| X0 | `modelcraft-fem` extraction with M6: hex8/tet4 kinematics, elastic and J2 updates, shared with the implicit solver | M2 tets, generated boxes | patch tests, J2 uniaxial curve, rigid rotation |
|
||||
| X0 | `fieldcraft-fem` extraction with M6: hex8/tet4 kinematics, elastic and J2 updates, shared with the implicit solver | M2 tets, generated boxes | patch tests, J2 uniaxial curve, rigid rotation |
|
||||
| X1 | Explicit core: central difference, lumped mass, element Δt (FB 1984), one-point hex8 + FB hourglass, Bonet–Burton tet4, artificial viscosity, energy accounting, prescribed BCs, initial velocity, history output | structured hex8 boxes generated in code (no M3 needed), M2 tets | bar wave (front position and amplitude), bar–rigid wall contact time 2L/c, energy balance, cantilever period vs M6 modal |
|
||||
| X2 | Large deformation materials: Hughes–Winget Jaumann, Flanagan–Taylor Green–Naghdi, J2 radial return, Johnson–Cook strength + damage, erosion | same | Dienes simple shear (both rates, closed form), Taylor bar (Taylor 1948 analytic estimate; experimental comparison only if the owner allows) |
|
||||
| X3 | Contact: BVH global search, node-to-segment penalty two-pass + friction, pinball for eroding surfaces, rigid walls | surface extraction of volume meshes (have it) | two bars colliding (momentum exchange, analytic), block sliding with friction on a slope (analytic), Hertz sphere-on-plane at low speed (analytic contact time and force) |
|
||||
@@ -956,7 +956,7 @@ the better pairing — this is why FSI should support both structure solvers.
|
||||
|
||||
## Part G: Implicit solver (M4), as implemented
|
||||
|
||||
The papers and books `modelcraft-fem` and `modelcraft-solver` are written from (cited again in
|
||||
The papers and books `fieldcraft-fem` and `fieldcraft-solver` are written from (cited again in
|
||||
the module docs):
|
||||
|
||||
- Elements: O. C. Zienkiewicz, R. L. Taylor, J. Z. Zhu, *The Finite Element Method: Its Basis
|
||||
@@ -1031,7 +1031,7 @@ the module docs):
|
||||
|
||||
## Part H: Explicit solver core (X1), as implemented
|
||||
|
||||
The papers and books `modelcraft-explicit` and `modelcraft_fem::uniform` are written from (cited
|
||||
The papers and books `fieldcraft-explicit` and `fieldcraft_fem::uniform` are written from (cited
|
||||
again in the module docs):
|
||||
|
||||
- Time integration, energy balance, element eigenvalue inequality: T. Belytschko, W. K. Liu,
|
||||
@@ -1065,7 +1065,7 @@ again in the module docs):
|
||||
|
||||
## Part I: Lattice Boltzmann core (M12, plan L1), as implemented
|
||||
|
||||
`modelcraft-lbm` is written from these papers and the book (cited again in its module docs). No
|
||||
`fieldcraft-lbm` is written from these papers and the book (cited again in its module docs). No
|
||||
lattice Boltzmann package's code was opened.
|
||||
|
||||
- Lattice, equilibrium, units, stream–collide, bounce-back, forcing and boundary conditions:
|
||||
@@ -1082,7 +1082,7 @@ lattice Boltzmann package's code was opened.
|
||||
lattice Boltzmann simulations*, J. Stat. Mech. 2010, P01018 (DOI not checked).
|
||||
- Stability limits (Mach ≤ 0.3, τ⁺ ≥ 0.505, runtime speed ≤ 0.5): Sterling & Chen 1996 and
|
||||
Lallemand & Luo 2000 (C1.5) for the shrinking stable region as τ → ½.
|
||||
- Voxelisation: Shewchuk's exact `orient2d`/`orient3d` (`modelcraft_mesh::predicates`) with a
|
||||
- Voxelisation: Shewchuk's exact `orient2d`/`orient3d` (`fieldcraft_mesh::predicates`) with a
|
||||
symbolic perturbation after H. Edelsbrunner, E. P. Mücke, *Simulation of Simplicity*, ACM TOG
|
||||
9(1):66–104, 1990; link faces by nearest triangle, C. Ericson, *Real-Time Collision Detection*,
|
||||
Morgan Kaufmann 2005, §5.1.5.
|
||||
@@ -1095,7 +1095,7 @@ lattice Boltzmann package's code was opened.
|
||||
|
||||
## Part J: Large deformation and inelastic materials (X2), as implemented
|
||||
|
||||
The papers and books `modelcraft_fem::{rotation, plasticity}` and `modelcraft-explicit`'s X2
|
||||
The papers and books `fieldcraft_fem::{rotation, plasticity}` and `fieldcraft-explicit`'s X2
|
||||
update are written from (cited again in the module docs):
|
||||
|
||||
- Updated Lagrangian one-point elements, strain increments on the midpoint configuration:
|
||||
@@ -1128,7 +1128,7 @@ update are written from (cited again in the module docs):
|
||||
- **Conduction.** Galerkin form of ρc Ṫ = ∇·(k∇T) + Q with surface flux and convection:
|
||||
O. C. Zienkiewicz, R. L. Taylor, J. Z. Zhu, *The Finite Element Method: Its Basis and
|
||||
Fundamentals*, 7th ed., Butterworth-Heinemann 2013, §3.2; T. J. R. Hughes, *The Finite Element
|
||||
Method*, Dover 2000, ch. 1. Kernels in `modelcraft_fem::heat`, solver in `modelcraft_solver::heat`.
|
||||
Method*, Dover 2000, ch. 1. Kernels in `fieldcraft_fem::heat`, solver in `fieldcraft_solver::heat`.
|
||||
- **Time integration.** The generalized trapezoidal (θ) family, unconditionally stable for
|
||||
θ ≥ ½ (Hughes 2000, §8.2): backward Euler (θ = 1, the default) and Crank–Nicolson (θ = ½).
|
||||
- **Thermal strain.** Initial-strain load ∫ Bᵀ D ε_th dV and stress D(ε − ε_th)
|
||||
|
||||
@@ -14,11 +14,11 @@ Rules:
|
||||
material, loads, boundary conditions). We never run a commercial product and never copy its
|
||||
input files, manual text or figures; only the published numbers are used, with a citation.
|
||||
- Each case lives in `tests/oracle/<case>/`:
|
||||
- `recipe.json` — the model as ModelCraft commands (or a SolidCraft recipe for geometry);
|
||||
- `recipe.json` — the model as FieldCraft commands (or a SolidCraft recipe for geometry);
|
||||
- `expected.json` — the reference values with `kind` (theory | experiment | benchmark),
|
||||
`source` (citation: document, table or figure, page), `quantity`, `value`, `tolerance` and
|
||||
the reason for that tolerance (mesh, measurement scatter, model differences);
|
||||
- `fixture.json` — ModelCraft's accepted result, written by `cargo xtask oracle --bless <case>`
|
||||
- `fixture.json` — FieldCraft's accepted result, written by `cargo xtask oracle --bless <case>`
|
||||
only after the case passes against `expected.json`.
|
||||
- `cargo xtask oracle` runs every case, compares with `expected.json` (pass/fail with error) and
|
||||
with `fixture.json` (any change beyond the fixture tolerance fails CI, even if the reference
|
||||
@@ -30,7 +30,7 @@ Rules:
|
||||
|
||||
## The case format
|
||||
|
||||
`cargo xtask oracle` builds `modelcraft-testkit`'s `oracle` binary (release) once and runs every
|
||||
`cargo xtask oracle` builds `fieldcraft-testkit`'s `oracle` binary (release) once and runs every
|
||||
case through the command engine; the results are in [oracle.md](oracle.md).
|
||||
|
||||
```
|
||||
@@ -40,7 +40,7 @@ cargo xtask oracle --bless nafems-le1 # freeze a passing case's results (or --
|
||||
cargo xtask oracle --quick # skip cases marked "slow"
|
||||
```
|
||||
|
||||
- `recipe.json` is a script `modelcraft-cli run` also accepts: a JSON array of
|
||||
- `recipe.json` is a script `fieldcraft-cli run` also accepts: a JSON array of
|
||||
`{"command", "params"}`; a step may carry an `"id"` so a quantity can read its output. Meshes
|
||||
come from `mesh.block` (mapped hex, tet or wedge blocks with arcs and elliptical edges, named
|
||||
faces, edges and vertices that sets select), `mesh.tet.generate`, or nodes and elements written
|
||||
@@ -56,7 +56,7 @@ cargo xtask oracle --quick # skip cases marked "slow"
|
||||
"quantities": [{"id": "syy_D", "quantity": "σ_yy at D (2, 0)",
|
||||
"measure": {"command": "solve.probe", "params": {"step": "Load", "at": [[2, 0, 0]]}, "pointer": "/nodes/0/stress/1"},
|
||||
"value": 92.7, "tolerance": {"relative": 0.01}, "reason": "why this tolerance",
|
||||
"known_failure": "optional: why ModelCraft misses the reference today"}]}
|
||||
"known_failure": "optional: why FieldCraft misses the reference today"}]}
|
||||
```
|
||||
A measure reads a JSON pointer either from a recipe step's output (`"from": "<id>"`) or from a
|
||||
command run after the recipe (`"command"`, `"params"`); an optional `"scale"` multiplies it.
|
||||
|
||||
Reference in new issue
Block a user