dsh-cae-plugin
Manifest valid★ 3Mochi 🐶 — natural-language CAE plugin for DeepSeek Harness: one sentence in, a full CAD → mesh → solve → post-process pipeline out (CalculiX FEA + OpenFOAM CFD). | 自然语言驱动的 CAE插件:一句话跑通 CAD → 网格 → 求解 →
Mochi (dsh-cae)
English | 中文
WeChat Official Account · plugin tutorials and usage articles, published every so often
Natural-language-driven CAE pipeline for DeepSeek Harness: the agent takes a plain-language simulation request and drives a complete CAD → mesh → solve → post-process chain over build123d, Gmsh, CalculiX, OpenFOAM, and PyVista. Five tools cover the chain end to end — geometry (scripted construction or external STEP import with validation/healing), solid and fluid meshing behind one mode switch, linear static solving plus steady or transient incompressible CFD behind another, result extraction/plotting, and automated mesh-independence verification — with receipts (paths, volumes, mesh quality, field extremes) fed back to the model after every stage.
Install
Recommended (Docker): install Docker, add the plugin, and point python at the prebuilt image — no conda, no apt CalculiX, no OpenFOAM install. The image is pulled automatically on first use (~3–4 GB):
python: docker://ghcr.io/daiyuhangsustc/dsh-cae:latest
Local interpreter (no Docker): the routes below.
Python stack first: pip install build123d gmsh pyvista ccx2paraview, plus a CalculiX solver — sudo apt install calculix-ccx on Debian/Ubuntu or conda install -c conda-forge calculix elsewhere (the ccx binary must be on PATH).
For the CFD modes, OpenFOAM (Foundation v11–13 or ESI) must be installed; its etc/bashrc is auto-detected ($FOAM_BASHRC, /opt/openfoam*, /usr/lib/openfoam*) or set via openfoamBashrc.
Then load the plugin into a profile — run dsh from a DeepSeek Harness checkout:
- Local checkout (plugin development):
dsh plugin --profile web add /path/to/dsh-cae— installs as alink:dependency; after changing the plugin,pnpm buildand restart the surface to pick it up. - Direct git checkout:
dsh plugin --profile web add https://github.com/DaiYuhangSustc/dsh-cae-plugin.git(git installs run thepreparebuild script; pnpm users may need to allow it viaallowBuilds). - npm registry (once published):
dsh plugin --profile web add dsh-cae.
Each profile holds its own plugin list — repeat the add for every profile you use (e.g. headless).
Launch and use
- Browser:
dsh webboots the web UI on http://127.0.0.1:3080 (--portto change; it opens the default browser automatically) — paste a plain-language request and watch the tool calls and receipts stream. - Terminal:
dsh --profile headless "20×20 mm square duct, 1 m long, water at 0.02 m/s inlet — steady laminar solve and a pressure contour"runs one task headlessly and prints the transcript. A surface started before the plugin was added cannot see it — restart the surface afteradd(or after a rebuild, forlink:installs).
Try it
See examples/cantilever.md: a single Chinese sentence produces a fixed-end cantilever under tip load via cae_geometry → cae_mesh → cae_solve → cae_post, with a von Mises contour and a cae_verify mesh-independence check.
And examples/duct-flow.md: one Chinese sentence produces a laminar duct-flow solution (cae_mesh fluid mode → cae_solve steady mode → cae_post) validated against the Shah–London friction constant.
The five tools
| Tool | Modes | Input | Output |
|---|---|---|---|
cae_geometry | mode: 'build' | 'import' | build: build123d script (defines part, optional NAMED_FACES) + name; import: external .step path (+ optional repair, nameFaces face naming) | build: .step path, volume, bounding box, named faces with areas/centroids; import: validated/healed .step path, face table (areas/centroids/normals) for BC anchors, optional faces.json sidecar |
cae_mesh | mode: 'solid' | 'fluid' | solid: .step path, elementSizeMm, elementType (tet4/tet10); fluid: duct lengthMm/widthMm/heightMm/cellSizeMm (+ wallGrading, full blockMeshDict text, name) | solid: .msh path, node/element counts, named groups, minimum scaled Jacobian; fluid: caseDir (SI bounds, cell count, checkMesh quality, checksPassed) |
cae_solve | mode: 'static' | 'steady' | 'transient' | static: .msh path, material (youngMPa, poisson), constraints/loads on named groups; steady/transient: caseDir, inletVelocityMS, kinematicViscosityM2S, densityKgM3, dict overrides (+ transient time controls endTimeS/writeIntervalS/maxCourant/deltaTS) | static: .frd/.vtu paths, exitCode, log tail; steady: converged + final residuals, VTK path; transient: time-step history, max Courant seen, VTK path |
cae_post | — | .vtu/.vtk/.frd path, maxima/probes/plots queries (+ densityKgM3 for CFD pressure) | field extremes with locations, probe values, contour PNG paths |
cae_verify | chain: 'structural' | 'cfd' | the corresponding chain's inputs plus a size list (elementSizesMm structural, cellSizesMm cfd), metric, gciThresholdPercent | mesh-independence study: per-level table, observed order (Richardson) + GCI (Celik 2008), verdict + recommendation |
cae_solve mode='steady' vs mode='transient': steady is the default recommendation for internal-flow requests; the transient branch (Euler/PIMPLE, Courant-limited adaptive step) is for genuinely time-dependent physics — the steady-vs-transient trade-off is spelled out in the tool description for the agent to recommend and the user to decide.
Migrating from v0.4
v0.5.0 is a breaking release: the nine v0.4 tool names are gone, and so are the v0.4 verify tool's flat boundary-condition shapes (a list of constrained group names; force vectors keyed by group). Boundary conditions are canonical everywhere — constraints: [{groupName, kind: 'fixed'}] and loads: [{groupName, vectorN: [fx, fy, fz]}] — used by cae_solve (mode='static') and cae_verify (chain='structural').
Every v0.4 tool maps onto one of the five v0.5 tools plus a mode/chain switch: the two geometry tools became cae_geometry (mode='build' scripted construction, mode='import' external STEP import); the solid mesher and the duct mesher became cae_mesh (mode='solid' / mode='fluid'); the structural solver and the two CFD solvers became cae_solve (mode='static' / 'steady' / 'transient'); the post-processor became cae_post; and the mesh-independence study became cae_verify (chain='structural' / 'cfd'). The v0.4 names and schemas remain available in the git history (the pre-refactor tree at commit 01fad90, where origin/master also sits).
Six-stage workflow mapping
The plugin covers the classic CFD/CAE six-stage workflow; stages 1–5 are automated, stage 6 is deliberately human.
| Fluent stage | dsh-cae coverage |
|---|---|
| 1 Pre-processing | cae_geometry (build script geometry · import external STEP: validate/heal/name faces) · cae_mesh (solid Gmsh tetrahedra · fluid blockMesh duct) |
| 2 Solver setup | parameters of cae_solve (materials, BCs, ν); steady vs transient is a recommendation the agent makes, the user decides |
| 3 Solution | cae_solve — static (CalculiX) · steady / transient (foamRun) |
| 4 Post-processing | cae_post (PyVista) |
| 5 Verification | cae_verify (mesh independence, Richardson + GCI); convergence receipts on every solve |
| 6 Validation | deliberately human — the plugin provides the numbers and plots, the engineer compares against reality |
Architecture
Five tools map onto five Python packages: src/tools/{geometry,mesh,solve,post,verify}.ts ↔ python/dsh_cae/{geometry,mesh,solve,post,verify} (+ python/dsh_cae/shared for receipt emission, the dependency self-check, and OpenFOAM case assembly). The TS layer owns orchestration only; each tool call is a one-shot python -m dsh_cae.<stage> subprocess coupled through argv plus the stdout receipt line after the <<<DSH_CAE_JSON>>> marker — nothing else crosses the boundary. Two contracts are deliberately mirrored on both sides: the override whitelist exists as the file enum of overrides in src/tools/solve.ts (OVERRIDES_PARAM) and as CASE_DICT_FILES in python/dsh_cae/shared/cfd_case.py — change both in one commit — and cae_verify's per-level loop (mesh + solve + post per size) runs in-process inside the single python -m dsh_cae.verify process, which is why its stage timeout is scaled by 3×levels.
Trust boundary
The script parameter is model-generated Python (and batch text) executed locally with trust level equal to the harness's own bash tool; treat it accordingly and use a profile permission layer (tools/pre-execute) for governance.
Units
Millimeters, newtons, megapascals everywhere: geometry in mm, forces in N, stresses in MPa, so deflections come out in mm and Young's modulus is entered as MPa (steel ≈ 210000).
The CFD branch takes geometry in mm at cae_mesh (mode='fluid', converted to m once) and is SI afterwards: m, m/s, Pa, Pa·s; cae_post converts kinematic pressure to Pa when given densityKgM3.
Configuration
| Field | Default | Meaning |
|---|---|---|
python | auto | 'auto' probes a conda env named dsh-cae ($CONDA_PREFIX, $CONDA_ENVS_PATH, ~/.conda, ~/miniconda3, ~/anaconda3, ~/mambaforge, /opt/conda), falling back to python3; or set an explicit interpreter path; or docker://<image-ref> to run every stage in a container — recommended image ghcr.io/daiyuhangsustc/dsh-cae (auto-pulled on first use) |
workdir | ./cae | Artifact directory (relative to agent cwd) for STEP/MSH/INP/FRD/VTU/PNG files |
stageTimeoutMs | 600000 | Per-stage wall-clock budget in ms; exceeded kills the stage process group |
openfoamBashrc | auto-detect | OpenFOAM etc/bashrc path; auto-detection checks $FOAM_BASHRC, /opt/openfoam*/etc/bashrc, /usr/lib/openfoam*/etc/bashrc |
Troubleshooting
If import build123d dies with pyexpat ... undefined symbol: XML_SetAllocTrackerActivationThreshold, an inherited LD_LIBRARY_PATH (e.g. OpenFOAM's bashrc listing /usr/lib dirs) is shadowing the interpreter's own newer libexpat. For a conda-style interpreter — python: auto or an explicit env path — the runner already prepends the env's lib to LD_LIBRARY_PATH and its bin to PATH at spawn time; for other layouts force the newer one first yourself: LD_PRELOAD=$CONDA_PREFIX/lib/libexpat.so.1.
Linux servers without a display need EGL or OSMesa for PyVista rendering — conda-forge's vtk ships X-only window classes (no EGL/OSMesa build), so use the pip wheel (pip install 'vtk==9.6.2', which bundles vtkEGLRenderWindow; install libegl1 for the EGL runtime it dlopens) and set PYVISTA_OFF_SCREEN=true with VTK_DEFAULT_OPENGL_WINDOW=vtkEGLRenderWindow; the Docker image does exactly this.
OpenFOAM 11+ (Foundation) replaced standalone solvers: this plugin runs foamRun (solver incompressibleFluid), the simpleFoam successor; ESI releases keep simpleFoam but the invoked names here are Foundation's. foamToVTK writes legacy .vtk, which cae_post reads directly.
Docker route errors are explicit: "Docker is not installed" → install Docker; "daemon is not running" → sudo systemctl start docker (using a rootless/remote daemon via DOCKER_HOST/DOCKER_CONTEXT? Export those in the shell that launches the harness — the runner passes a minimal environment to the docker CLI); "failed to pull" → run the printed docker pull by hand. A stale image behaves like stale dependencies — docker pull ghcr.io/daiyuhangsustc/dsh-cae:latest to refresh. On SELinux-enforcing hosts (Fedora/RHEL) the stage bind mounts may be denied — look at container-selinux if stage logs show permission errors. With python: docker://… leave openfoamBashrc unset: host paths don't exist inside the container, and the image's own OpenFOAM is used automatically.
Limitations
Structural: linear static analysis only, tetrahedral meshes only; CFD: incompressible laminar internal flow only (steady or transient), block-hex meshes only; POSIX only; single-machine.
Roadmap
CAE skill for prompt guidance, background jobs via ctx.jobs, modal/thermal analysis, turbulence (kOmegaSST + y+ treatment), snappyHexMesh/STL geometry, pluggable solver providers.
Contributing
PRs and issues are welcome — a natural-language CAE stack covers a lot of ground, and it needs many hands: more physics, more solvers, better examples and docs.
Development setup (TS side): pnpm install.
Note: @deepseek-ai/dsh-tools is at rc.1 and its runtime import chain pulls dsh-llm/dsh-scope/dsh-session/dsh-timeout; when installed out-of-tree into a profile, resolution normally comes from the in-profile dsh-base.
For a standalone dev checkout, pnpm install needs autoInstallPeers: false (already in pnpm-workspace.yaml) plus the declared extra devDeps — if peers still fail to resolve, install within a dsh profile rather than standalone.
Kernel environment, no sudo required (the route CI-equivalent validation uses locally):
conda create -n dsh-cae -c conda-forge python=3.11 calculix -y
conda run -n dsh-cae python -m ensurepip --upgrade
conda run -n dsh-cae pip install build123d gmsh pyvista ccx2paraview pytest
The env name matters: the default python: auto probes for a conda env named exactly dsh-cae, so this env needs no further configuration.
Run the suite that matches your change:
| Layer | Command | Notes |
|---|---|---|
| TS tools / runner | pnpm build && pnpm vitest run | keyless, runs everywhere |
| Python stages | pytest pytest -v | inside the kernel env; the pytest/ directory shadows the pytest package, so the console script is required — never python -m pytest from the repo root |
| Loader composition | DSH_COMPOSITION=1 pnpm vitest run tests/composition.e2e.ts | needs a dsh harness checkout; opt-in, CI does not gate it |
Contracts every change must keep:
- The TS layer owns orchestration only (tool schemas, subprocesses, timeouts, receipts); all domain knowledge lives in
python/dsh_cae/. The layers couple through argv and the stdout receipt line<<<DSH_CAE_JSON>>>— nothing else. - Solver outcomes are data: a non-zero ccx exit is a normal receipt carrying
exitCodeandlogTailfor the model to diagnose; only infrastructure failures (missing binary, timeout, unparseable output) raise. - Units are mm/N/MPa everywhere, with no conversion anywhere.
- Some solver realities are encoded deliberately, with comments: Gmsh tet10 mid-edge nodes 9/10 are swapped against Abaqus C3D10 in
solve.py; ccx exits 0 even on a singular (unconstrained) system, so the domain-failure test drives ccx with a*CLOADon a nonexistent node.
PR expectations: the tests covering your layer are green; kernel tests self-skip without kernels — say so in the PR and let CI run them for real; update README.md and README.zh.md together (the two files mirror each other); conventional commit subjects (feat:, fix:, docs:, test:).
Good first targets are the Roadmap items above: a new analysis type (*FREQUENCY, *HEAT TRANSFER), turbulence and snappyHexMesh extensions on top of the CFD branch, a cae skill teaching the model build123d/INP idioms, and more runnable examples in the style of examples/cantilever.md.
License
MIT
Comments
Loading…
Similar plugins
by yangbobo2021
Codex integration plugin for DeepSeek Harness, providing native Codex conversations powered by the Codex App Server, with workspace, terminal, approval, and DSH tool support.
★ 12
↓ 452/wk
MIT
JavaScript
Sep 19, 2026
dsh plugin --profile web add relay-dsh-plugin-codexby taikaikaikai-pixel
CodeBuddy (copilot.tencent.com) provider bundle for DeepSeek Harness: 18 models, web_search/web_fetch backends, image_generate, local streaming bridge with OAuth & multi-Key rotation, Web UI settings
★ 4
MIT
JavaScript
Sep 6, 2026
dsh plugin --profile web add dsh-codebuddy-pluginby zriyox
一句话大需求先别急着跑:拦一下问你要不要先规划,自动生成带验收清单的 plan.md 再开工 — DeepSeek Harness 插件 / Catches one-sentence mammoth tasks and scaffolds plan.md + a capped goal first
★ 3
MIT
TypeScript
Aug 15, 2026
dsh plugin --profile web add dsh-goal-scaffoldby HOWILLMAKEIT
DeepSeek Harness 插件:维护 llm-pi-ai 模型的准确上下文窗口,避免长会话被误判为上下文溢出。
★ 34
MIT
JavaScript
Sep 1, 2026
dsh plugin --profile web add dsh-model-context-catalogby wxkingstar
在 DeepSeek Harness / Claude Code / Cursor / Codex / Gemini CLI 里直接搜索 20 个中国开放平台的 65,600+ 篇 API 文档;零配置,支持 Skill 与 DSH 原生插件。
★ 67
↓ 43/wk
MIT
TypeScript
Sep 15, 2026
dsh plugin --profile web add @wxkingstar/specfusion-dshby AmethystLuna
Embedded C/C++ AI engineering plugin — firmware skills (FreeRTOS, Keil, HardFault, state machines) + 1% Rule / Plan Verification Gate discipline | 嵌入式 C/C++ 工程 AI 插件:固件技能与 agent 纪律。 For Claude Code, C
★ 12
↓ 270/wk
MIT
JavaScript
Sep 19, 2026
dsh plugin --profile web add dsh-embedded-workbench