forked from 1b-agent/fieldcraft-upstream
MCP: the partition, cell and mirror commands in the instructions and docs
The mesh tool runs mesh.cells (method cells) and mesh.mirror (method mirror). The server instructions and docs/mcp.md list the partition, per-cell, mirror and symmetry commands and point to the crank-mirror sample. Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01UhhZMBTviDQxZvwnyP89fo
This commit is contained in:
1 parent
860707efa6
commit
794122a302
3 files changed
+38
-3
No files matched your search
@@ -31,8 +31,12 @@ then `execute` the model definition commands (model.set.create {name, geometry:
|
||||
model.material.create, model.section.create, model.boundary_condition.create, model.load.create, model.step.create \
|
||||
— list_commands shows each one's parameters); `check_model`; `solve` (static, frequency, explicit, fluid); \
|
||||
`show_results` (field: displacement, von_mises…; its reply has the field's range) and `probe` / `reactions` for \
|
||||
numbers; `screenshot` to look; `save` or `write_deck` (abaqus, nastran, lsdyna). Failures leave the model unchanged \
|
||||
and name what to fix.";
|
||||
numbers; `screenshot` to look; `save` or `write_deck` (abaqus, nastran, lsdyna). Partitions: geometry.datum makes a \
|
||||
datum plane, geometry.partition cuts the design's bodies into cells by it (cut faces partition:<name>:a|b; kept in \
|
||||
the model and applied again when the design opens); `mesh` method cells meshes the cells each with its own method, \
|
||||
method mirror reflects a meshed half across a datum plane into one conforming mesh; \
|
||||
model.boundary_condition.symmetry holds a half model on its symmetry plane (file.sample crank-mirror shows the \
|
||||
partition, half-mesh and mirror sequence). Failures leave the model unchanged and name what to fix.";
|
||||
|
||||
pub struct Server {
|
||||
backend: Box<dyn Backend>,
|
||||
|
||||
@@ -19,6 +19,12 @@ const MESHERS: &[(&str, &str, &str)] = &[
|
||||
("hex_sweep", "mesh.hex.sweep", "swept all-hex mesh"),
|
||||
("hex_mapped", "mesh.hex.mapped", "mapped all-hex mesh"),
|
||||
("hex_blocks", "mesh.hex.blocks", "one conforming all-hex mesh of a design split into six-sided blocks {bodies, size, order}"),
|
||||
(
|
||||
"cells",
|
||||
"mesh.cells",
|
||||
"one mesh of a partitioned part, each cell with its own method {methods: {cell: method}, default, size, order}; cells joined across partitions (merged or tied)",
|
||||
),
|
||||
("mirror", "mesh.mirror", "reflect meshed bodies across a datum plane and join them on it {plane, bodies}"),
|
||||
("block", "mesh.block", "structured hex block"),
|
||||
("planar", "mesh.planar", "2D elements of a polygon or a planar face"),
|
||||
];
|
||||
|
||||
+26
-1
@@ -99,7 +99,7 @@ software on the computer.
|
||||
| `open` | `path`, `model?` | By extension: `.fieldcraft` (`file.open`), `.solidcraft` (`geometry.open`), `.3mf` (`geometry.import.mesh`). For a design, `model` is `keep` (default: the mesh and definitions stay, as a reopen after an edit wants) or `new` (a new model with the design); the reply's `related` is false when the design has none of the bodies the model refers to, and `stale` lists the mesh bodies and sets that no longer resolve. |
|
||||
| `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`. |
|
||||
| `mesh` | `method`, `params?` | Runs the mesher (`tet`: `mesh.tet.generate`; `hex`, `hex_sweep`, `hex_mapped`, `hex_blocks`: the structured hex meshers; `cells`: `mesh.cells`, a partitioned part cell by cell; `mirror`: `mesh.mirror`, a meshed half reflected across a plane; `block`: `mesh.block`; `planar`: `mesh.planar`) and replies with its result, `model.info` and `mesh.quality`. |
|
||||
| `solve` | `analysis` (static, frequency, explicit, fluid; heat as it lands), `step?`, `options?` | `solve.<analysis>` with the step and the solver's caps and settings. |
|
||||
| `show_results` | `step?`, `field?`, `bands?`, `deformed?`, `scale?`, `mode?`, `frame?`, `time?` | The `results.*` commands its arguments ask for (`deformed: false` draws the undeformed mesh; `scale` is a factor, 0 for the undeformed shape so a sequence from 0 swings the deformation out, or `"auto"`); the reply has the contour range (smallest and largest value and their nodes: `field: "displacement"` gives the largest displacement), modes or frames. |
|
||||
| `probe` | `step?`, `nodes?`, `elements?`, `points?`, `forces?`, `mode?`, `frame?` | `solve.probe`: stored results at nodes, elements (explicit) or points (fluid). |
|
||||
@@ -115,6 +115,31 @@ Errors: an unknown tool, or arguments that do not match the tool's schema (a mis
|
||||
argument, a wrong type, a value outside an enum), are JSON-RPC `-32602` errors; an engine failure
|
||||
is a tool result with `isError: true` and the engine's message.
|
||||
|
||||
## Partition, mesh half, mirror
|
||||
|
||||
The commands that cut a part into cells and build its mesh from a half, all through `execute`
|
||||
and `mesh` (each one's parameters: `list_commands`):
|
||||
|
||||
1. `geometry.datum {name, by}`: a datum plane — a principal plane moved along its normal
|
||||
(`{"type": "offset", "plane": "zx", "offset": 0}`), three points, or a point and a normal.
|
||||
`geometry.datum.axis` makes axes.
|
||||
2. `geometry.partition {name, datum, bodies?}`: cuts the open design's bodies by the plane into
|
||||
cells `<body>/a` (negative side) and `<body>/b`. The two faces of the cut are
|
||||
`partition:<name>:a` and `partition:<name>:b`; every other face keeps the name of the face it
|
||||
is a piece of. The partition is part of the model: saving and opening it, or opening the
|
||||
design again after an edit, cuts the design again. `inspect_model` lists the cells.
|
||||
3. `mesh` with method `hex`, `hex_sweep`, `hex_mapped` or `tet` on one cell (`{"body":
|
||||
"Part/b"}`), or method `cells` for all cells with a method each (`{"methods": {"Part/a":
|
||||
"tet"}, "default": "auto"}`): cells whose faces match on a partition are merged, others are
|
||||
tied (the reply lists each interface).
|
||||
4. `mesh` with method `mirror` (`{"plane": "<datum>", "bodies": ["Part/b"]}`): the meshed half
|
||||
reflected across the plane, right-handed, joined on it, its elements and faces tagged as the
|
||||
other half's, so sets by face name (`{body, face}` on either half) reach both.
|
||||
5. Or keep the half: `model.boundary_condition.symmetry {name, datum}` holds it on the plane
|
||||
(zero normal displacement), with half the load.
|
||||
|
||||
`file.sample {"name": "crank-mirror"}` opens the crank arm built this way (docs/examples.md).
|
||||
|
||||
## Limits
|
||||
|
||||
The server treats its input as hostile. A message line may be at most 16 MiB (the control
|
||||
|
||||
Reference in new issue
Block a user