Kratos MDPA Preview (VS Code extension)

📖 Read the full documentation »

Preview, organize, edit, and remesh Kratos Multiphysics .mdpa model-part files directly in VS Code: a 3D mesh viewer with a navigable ModelPart / SubModelPart outline whose entries are toggleable layers.
It is fully self-contained — a pure-TypeScript parser feeds a VTK.js viewer running in a webview. No Python or compiled Kratos is required.
More screenshots
| Mesh quality |
Field contour |
 |
 |
| Level-set split (MMG) |
Linear → Quadratic |
 |
 |
| Problemtype: build & run Kratos cases |
Sphere / particle elements (Advanced menu) |
 |
 |
| Additional mesh operations |
Face normals (Advanced menu) |
 |
 |
📖 See the full documentation for a screenshot-rich walkthrough of every feature.
Features
- Preview and navigate — open a mesh from the Kratos activity-bar sidebar and explore nodes, elements, conditions, geometries, and SubModelParts as independent 3D layers.
- Inspect and visualize — find entities by ID, inspect field values, measure distances, plot nodal data, and use contours, vectors, isosurfaces, thresholds, deformation, clipping, and split views.
- Assess mesh quality — inspect geometric quality metrics, size distributions, face orientation, topology defects, and very large files through a bounded header summary.
- Edit and remesh — reorganize SubModelParts, run undoable mesh operations, convert element order, repair or refine meshes, and remesh with MMG, all without Python or a native Kratos build.
- Build and run cases — generate Kratos problem files, configure built-in or custom problemtypes, track solver runs, and preview results as they are written.
- Read and write mesh formats — open native MDPA, VTK, STL, OBJ, and PLY files plus a broad meshio++ catalog, with format conversion and OpenFOAM case support.
- Capture and analyze — take screenshots, record viewport animations, inspect data tables, probe fields over time or along a line, and export results to CSV or XLSX.
- Automate from MCP — use the standalone MCP server to inspect, transform, compare, convert, split, probe, package, and run Kratos cases without VS Code.
Detailed feature reference
Open it from the sidebar, with no file open. A Kratos icon in VS Code's activity bar opens a panel offering Open Mesh File…, Open Empty Preview (the viewer itself, over an empty viewport) and Load Problem…, plus a Recent Meshes list of the last ten meshes you opened. Tracked solver runs (Kratos Runs) show up there too, alongside their usual place in the Explorer.
Read and write OpenFOAM cases. Open a case's .foam marker and its constant/polyMesh/ is loaded, with each boundary patch as a named SubModelPart (inlet, outlet, …) so boundary conditions can be assigned to it. Compressed (writeCompression on) cases are decompressed automatically, and the preview watches constant/polyMesh/ so re-running blockMesh refreshes it in place. Saving in place is refused — the marker is an empty file and the mesh is its siblings — so use Export or Save As to write a new case. See OpenFOAM Cases.
An experimental VTK-wasm renderer. Setting kratos.preview.renderer to vtkwasm draws the preview with the VTK C++ rendering engine compiled to WebAssembly and shipped inside the extension, instead of vtk.js. It covers the same features. If the host cannot run it (no WebAssembly JSPI, no WebGL2, or the runtime failed to load), the preview falls back to vtk.js and says why. It needs one scoped CSP relaxation ('wasm-unsafe-eval'), and only when selected. vtk.js remains the default renderer. See Rendering Backend.
A header summary for a mesh too large to open. Above kratos.preview.summaryThresholdMb (default 250 MB, 0 disables it) the preview reports what is in the file — counts, entity blocks, variable names, regions, time steps — with one Open full mesh anyway button, instead of parsing a file that would hang the window. It works for every supported format, and says what the answer cost: a bounded header read for VTK XML, PLY, binary STL and .vtm; a single allocation-free stream for .mdpa, .obj and ASCII STL (.mdpa declares no counts, so it has no header to read); a whole read for the meshio++ formats. See Header Summary.
3D preview of nodes, elements, conditions, and geometries. Volume elements (tet/hex/wedge/pyramid) are shown as their boundary surface; quadratic elements are approximated by their corner nodes.
Outline tree of the entity blocks and the full SubModelPart hierarchy, with per-row visibility checkboxes (activate/deactivate a layer) and click-to-frame; View ▾ ▸ Flat SubModelPart list flattens nested parts into one list labelled with full paths (view-only, remembered per mesh). Drag the divider between the sidebar and the 3D view to resize the sidebar.
Reorganize the SubModelPart tree — every SubModelPart row carries an organize button offering New child, Move under, Merge into and Edit membership (add/remove node, element, condition or geometry ids by a comma/range list, e.g. 1,2,5-10), beside the existing rename and delete. The parent/child subset rule Kratos requires is maintained, not merely checked: adding an entity to a part also adds it to every ancestor and removing one also removes it from every descendant, which is exactly what ModelPart::AddNode / RemoveNode do upstream — so the tree you build is always one Kratos loads. Each is an undoable operation in the history and reachable from mesh_transform.
SubModelParts as layers — each SubModelPart is an independently toggleable overlay so you can isolate inlets/outlets/boundaries.
Stats panel: node/element/condition/geometry counts, bounding box, detected 2D/3D, and any element type names that could not be mapped.
Mesh quality (Quality toolbar button / Compute Mesh Quality command): purely geometric metrics inspired by Kratos' ComputeMeshQualityProcess — aspect/edge ratio, min/max angle (dihedral for volume cells, interior corner angles for surface cells), and per-node size gradation. Results are shown in a panel with per-metric histograms, a Good/Acceptable/Bad/Unacceptable breakdown, and an overall verdict. Bad elements can be highlighted in red and framed in the 3D view.
Mesh size (Advanced ▸ Mesh Size): compute per-node and per-element size and inspect the distribution.
- Nodal size (
NODAL_H) — a faithful port of Kratos' FindNodalHProcess: for each node, the minimum distance to any other node that shares an element.
- Element size — the element characteristic length (mean edge length).
- Color the mesh field-like by either measure, and read a floating box-and-whisker plot of the element-size distribution. Highlight the smallest and largest elements (statistical IQR outliers) — small in blue, large in red — and frame them in the 3D view.
- Write to mesh appends
NODAL_H / ELEMENT_H to the mesh (an undoable operation) so they show in the Field panel and are saved with the file; the values are also cached for reuse by future operations.
Field visualization (Field toolbar button / Field Visualization command): plot the NodalData, ElementalData, and ConditionalData fields stored in the file. Pick a variable and switch on any combination of the five modes:
- Contour — color the mesh by a scalar (smooth point-data for nodal fields, flat per-cell for elemental/conditional). Vector fields default to magnitude, or pick a single X/Y/Z component.
- Quiver — arrow glyphs oriented and scaled by a vector field (at nodes, or at cell centroids for elemental/conditional data), colored by magnitude, with an adjustable arrow-scale slider.
- Isosurface — extract the surface where a scalar equals one or more slider-driven iso values (a count spinner adds evenly-spaced sliders; marching tetrahedra over volume cells, 2D / surface meshes fall back to iso-lines).
- Threshold — show only the Elements/Conditions whose value falls in an editable
[min, max] window; for nodal fields, choose whether a cell needs all or any of its nodes in range.
- Deformed shape — warp the geometry by a vector field × an adjustable scale (its own "Deform by" selector, independent of the coloring field), the canonical FE post-processing view. The deformation is global, so every other active mode renders on the deformed geometry.
Contour/Isosurface/Threshold share a color range that's editable and lockable (min/max inputs + reset-to-data button), an optional log scale, and discrete color banding (5/10/20 bands). A colormap dropdown (Rainbow/jet by default, plus Viridis, Plasma, Inferno, Magma, Cividis, Turbo, Cool-warm, Blue-Orange, Spectral, HSV, and Grayscale) drives the 3D coloring, a live panel legend, and an optional in-scene scalar bar that (unlike the panel legend) is captured by the Screenshot button; when the scalar bar is off, screenshots instead composite the legend onto the captured image.
Screenshot (View ▾ → Screenshot… / Screenshot to PNG… command / Ctrl+Alt+P): captures the current viewport as a PNG and opens a Save dialog pre-filled with the source file's name (e.g. mesh.png next to mesh.mdpa). Uses VTK.js's captureNextImage() for correct WebGL swap-chain timing. SVG export is not possible — the viewport is a rasterised WebGL canvas.
Find entity by ID (Find toolbar button / Find Entity by ID command): type a Node, Element, Condition, or Geometry ID to locate it instantly. The entity is highlighted in yellow and the camera zooms to it; all other layers switch to wireframe so the result stands out clearly. Closing the bar restores the previous display state.
Inspect (Inspect toolbar button): click any node, element, or condition on the mesh — no id needed up front, unlike Find — to see its id, block, SubModelPart membership, and every field value defined at it, in a floating panel. A Measure sub-mode inside the panel: click two nodes to draw a line between them and read the distance and Δx/Δy/Δz.
Run manager (Kratos Runs in the Explorer): running a case now tracks it. Live runs show elapsed time and the latest step written; finished ones show their exit code. Stop actually stops the solver, and results already written are kept. Runs survive the preview that started them.
Record a video (View ▾ ▸ Record…): capture the viewport as a WebM video or a numbered PNG sequence — either a playthrough of a mesh time series, or a camera turntable for a static mesh.
Split view (View ▾ ▸ Layout): show the mesh in 1, 2 or 4 viewports, each with its own camera, field settings and clip plane — DISPLACEMENT beside VELOCITY, or a clipped section beside the whole model. Orbit, pan and zoom act on whichever pane the pointer is in, and the focused pane (the one Reset/Frame, the Field panel and the Clip controls act on) is outlined.
Plot over time (Inspect panel, mesh previews with a time series): click a node or element, then Plot over time to chart one of its field values across every step of the series — one line per component, gaps where the value is missing rather than a line drawn through them. Click a point to jump the 3D view to that step, and export the series as CSV.
Integrated FEM plots: Plots / Advanced ▸ Plot builder… opens a resizable read-only pane inside the mesh editor, with simple point/quantity/component controls and hidden Advanced settings. Append displacement/pressure histories by clicking points; locate full-resolution peaks. Analyze / Plot on a SubModelPart provides current-frame/history reductions, pressure means/integrals/forces/moments, supplied reaction sums/moments and boundary vector flux, with explicit conventions, units and coverage. Batched histories share one frame scan, publish partials and retain them on cancellation. The standalone Kratos Mesh: Scientific Plot Builder remains available for CSV/TSV without a mesh. A visual icon picker exposes twelve families: line/step/area, pure scatter, bubble, grouped/stacked/horizontal bars, pie/doughnut, histogram/box and heatmap/contour. Pie aggregation and bubble sizes are explicit; numerical analysis, recipes and PNG/SVG/full-resolution CSV share the MCP backend. Saved run… discovers existing records and pins terminal isolated results by run/source/companion hashes; physical-time cursors use supplied units and explicit matching, without redirecting other previews. See the guide with packaged-UI screenshots and verification record. Roadmap item 19 remains open for the remaining run-ownership, workflow and scale acceptance work.
Timeline-following profiles: choose Follow timeline on an embedded spatial profile, or Fix frame to retain it for comparison. Only followed probes resample; fixed curves and disk histories retain their collected samples within a bounded session budget. Changing timeline/rank/resampling or cancelling pauses following until explicitly resumed. Saved live profiles are captured tables, while MCP evaluates their explicit frame index.
Probe line (Inspect panel): toggle Probe line, click two nodes, and the extension samples a nodal field along the line between them and charts distance-versus-value — the quantitative half of Clip, which answers the same question visually. The line breaks wherever the path leaves the mesh or the field is unwritten, the plot follows the timeline step in mesh series, and CSV export rides the same save dialog as the other panels. Also available headlessly as the mesh_probe MCP tool, whose numbers the panel's equal by construction.
Virtual wind tunnel (Advanced ▾ ▸ Virtual wind tunnel…): five steps from a body surface (STL, OBJ, PLY) to a meshed tunnel and a prepared Fluid case — tunnel box from multiples of the body, ground mode and half model, flat-plate boundary-layer estimate for a target y+, a body-fitted mesh (level-set carve, wake refinement, stretched-tetrahedron wall layer with a measured wall fit) or an embedded one (signed DISTANCE), and the case with inlet, outlet, walls, wall law, time stepping and force/coefficient monitors. A live plan shows the estimated cells, memory and time before anything runs. Also wind_tunnel_plan / wind_tunnel_generate headlessly. See Virtual Wind Tunnel.
Streamlines (Advanced ▾ ▸ Streamlines…): trace steady streamlines of a nodal vector field (VELOCITY, DISPLACEMENT…) from seed points, a line, a plane lattice or the nodes of a SubModelPart, forward, backward or both. They are drawn over the mesh coloured by speed — as lines or tubes, view-only — follow the timeline (a new frame re-traces), and Export… writes them as line cells with the speed, velocity, arc length, seed and termination reason on them. The trace runs in a worker thread with per-seed progress and a Cancel that keeps the partial result. Every line ends for a stated reason and a seed that yields no line is reported, never dropped. Also available headlessly as mesh_derive with kind: "streamlines".
Flow balance (Advanced ▾ ▸ Flow balance…): the signed volumetric flux ∫u·n dA through named SubModelParts of Conditions (inlets, outlets, walls), the area-weighted mean of a nodal pressure on each, the net flux and imbalance across them, an optional mass flux from an explicit density and the pressure drop between two sections. Flux is positive out of the domain; normals are flipped away from the Element each facet belongs to (or trusted as wound, on request), and a facet that cannot be oriented, an internal facet or a corner with no value is excluded and reported, never guessed or read as zero. A higher-order facet integrates as its linear skeleton and says so. With an explicit P density, a kinematic pressure is additionally reported in Pa. 2D meshes give flux per unit depth and say so. Follows the timeline, All steps balances the whole series with clickable rows, and Export CSV saves the table. Also available headlessly as mesh_flow_balance, including over every step of a series.
Export report and provenance: Show report opens a graphical status-grouped panel (also Advanced ▸ Export report…) for retained/transformed/omitted/unverified data, companions, warnings and verification contradictions, with a file selector and Copy JSON. Four reference meshes measure hex/quad and simplicial topology, including Conditional scalar/vector fields; untested cases stay unverified. Native MDPA/VTK XML/OBJ/PLY embed safe comments, legacy VTK uses a bounded title, and STL uses a sidecar. kratos.export.provenance controls embedding and <output>.kratosexport.json; none adds no provenance. Partition/split manifests and batch entries retain per-file reports, packing/resampling return per-step roll-ups, and structured VTI/temporal XDMF paths disclose unverified fidelity. Problem archives embed a source/recipe/hash record without altering pristine mesh bytes. MCP mirrors these reports and single-mesh verify; mesh_capabilities.exportFidelity publishes per-reference measurements. Details.
Data table (Advanced ▾ ▸ Data table…): the same values Inspect shows for one entity, for every entity at once — a scrollable table of nodes, elements, conditions or geometries with their coordinates or connectivity, optional SubModelPart membership, and every field defined there. Click a row to highlight and frame that entity in the scene; export the whole table as CSV or XLSX.
Clip (Clip toolbar button): an interactive clipping plane — pick the X / Y / Z axis or Free for an oblique cut (type a normal vector's X/Y/Z components), flip the direction, and drag the position slider — capped with a filled, field-colorable section and its element intersection edges rather than a hollow clip.
Layer opacity: hover any outline row for a small button that opens a live 0–100% opacity slider for that layer.
Rendering quality: the nav dock's ⋯ popover holds the scene-theme picker and a global model-opacity slider, and the dock itself a Persp/Ortho flip button that toggles perspective vs. orthographic camera projection; Lighting… exposes global specular / ambient / diffuse sliders and a backface-culling toggle; Camera Bookmarks… saves/restores named views (kept in the mesh's <stem>.kratosview.json), with a JSON textarea for copying a view out or pasting one in. Standard axis views are one keypress away — 1–6 for ±X/±Y/±Z, i for an isometric corner.
Orientation cube + axis arrows — an always-visible labeled cube in the top-left corner of the viewport (RIGHT / LEFT / TOP / BOTTOM / FRONT / BACK) that follows the camera as you orbit. Prominent X (red), Y (green), and Z (blue) axis arrows with letter labels radiate from the cube. Clicking a face snaps the camera to that canonical axis direction.
Navigation dock — a floating one-row dock at the bottom-centre of the viewport that appears once a model loads (wraps to two rows in a narrow window; the chevron at its end collapses it):
- Reset view (default front view, framed), Fit (frames all visible geometry, same as the Reset Camera command), Zoom out / in (dolly ×0.8 / ×1.25; press-and-hold for continuous zoom).
- Shaded | Wire, the Clip group (Off/On, X/Y/Z/Free, position slider, live readout) and the Persp/Ortho flip.
- ⋯ popover (closes on an outside click or
Esc): Rotate compass with a 15°/45°/90° step picker, Pan compass (step proportional to the current zoom level), clip Flip and the Free-normal inputs, scene theme + model opacity, Edges, and Center (re-centers the focal point on the visible bounds without changing the orbit angle or zoom).
Background grid (View ▾ → Grid) — toggles a CubeAxesActor bounding box with labeled X/Y/Z axes and tick marks around the mesh. Colors adapt to the active scene theme.
Variables — the sidebar's named field registry, kept in sync with the Field panel (both list the same inventory; the panel badges fields that have a row, with a reveal jump). Every field on the mesh gets a row: file fields and computed ones alike. Add a variable by hand (+ Add variable), name it (e.g. d), pick how to compute it — a formula over coordinates and existing fields at any location (Nodal/Elemental/Conditional, like the Field calculator), the signed distance to a surface (an imported file, or a SubModelPart already in this mesh; same sign/band options as the Signed-distance form), any other Fields operation (average, gradient, Hessian, error estimate, transfer — same options as their forms, each with its form's icon), or a global reduction (min/max/minAbs/maxAbs/mean/std/median/sum/count/q1/q3/iqr of any field, e.g. maxAbs_TEMP; vectors reduce over magnitude) — then hit its own Play button. Computing a field from any Field form instead auto-creates the row for you, prefilled with that form's inputs. Once computed it is an ordinary field: the Field panel opens automatically, coloring the mesh by that variable, and it is immediately usable anywhere else a formula is accepted — the Field calculator, or the Remesh size = ƒ(h) formula — so d computed here can drive clamp(0.85*mean_h*(abs(d)/maxabs_d), 0.85*min_h, 1.15*max_h) in the Remesh form with no separate wiring. Variables combine freely: define one from a distance, then a second as a formula referencing the first, and so on. A row tracks the field it produced: if a timeline step replays without the async ops that computed it, the row says so and offers recompute instead of keeping a stale "Computed." — and if the computation itself produces nothing, the row reports the failure rather than hanging on "Computing…". Fields with no reconstructible definition (file fields and the like) render as locked rows — name, kind and origin, show-on-mesh, delete — and deleting any row removes only the row, never the field.
Mesh modification — the Mesh Modification sidebar section hosts in-place operations on the loaded mesh. Convert Linear → Quadratic inserts mid-edge nodes to raise every linear cell to its quadratic ("serendipity") counterpart — Triangle2D3→Triangle2D6, Quadrilateral2D4→Quadrilateral2D8, Tetrahedra3D4→ Tetrahedra3D10, Hexahedra3D8→Hexahedra3D20, Prism3D6→Prism3D15, Pyramid3D5→Pyramid3D13, Line2→Line3. Adjacent cells that share an edge get a single welded mid-edge node, nodal fields are interpolated at the new nodes, and SubModelParts are extended. The newly inserted mid-edge nodes are shown as a semitransparent Quadratic mid-nodes point overlay (a toggleable layer) so you can see exactly what was added. The preview updates in place; save or export the modified mesh from the File menu.
Remeshing (MMG) — the Mesh Modification section embeds the MMG remeshers via @loumalouomega/mmg-wasm (WebAssembly — no native binaries). Remesh (MMG) adapts the whole mesh with five modes: size × factor (per-node metric = local edge size × your factor, the one-knob refine/coarsen), uniform target size (hsiz), optimize only (size-preserving quality pass), size = ƒ(h) — a flexible formula that sets each node's target size from the current nodal size h (Kratos NODAL_H), the whole-mesh size statistics (mean, std, min, max, median, q1, q3, iqr) and the node coordinates x, y, z, with functions like min/max/clamp/sqrt/sin/pow. For example 0.5*h halves the mesh, clamp(0.5*h, mean-1.5*std, mean+1.5*std) refines while keeping sizes within one-and-a-half standard deviations of the mean, and clamp(0.6 - 0.45*x, 0.1, 0.6) grades density across space. A preset dropdown fills the box with a starting point — a uniform half-size formula, or a boundary-layer grading template (clamp(0.85*mean_h*(abs(d)/maxabs_d), 0.85*min_h, 1.15*max_h): finest 0.85*min_h at the wall, growing to 0.85*mean_h at the farthest node, since abs(d)/maxabs_d runs from 0 to 1; 1.15*max_h is only a safety cap) that assumes a distance variable d plus mean_h/min_h/max_h globals of the mesh size and a maxabs_d global (the largest |d|) already exist — picking it adds any missing ones to the Variables section automatically and computes them (writing NODAL_H first when absent; only d's surface stays your call — pick a part or file on its row, then Play — and picking it also switches the mode to size = ƒ(h)). The formula sees every existing nodal field on the mesh by name — including one computed via the Variables panel or the Field calculator/Distance-to-surface forms directly — so define d as a distance-to-surface variable there first (no file/SubModelPart picker lives in the Remesh form itself any more), and it becomes usable in the sizing formula with no separate wiring; referencing a name nothing has computed yet is flagged as an unknown variable rather than silently doing nothing (for d the message says where to compute one — the Variables section) — and anisotropic, which differentiates a scalar nodal field twice inline and adapts to its curvature (fine across a boundary layer, coarse along it). A collapsible Per-part sizing block assigns different formulas to individual SubModelParts (everything else uses the global one; the statistics stay whole-mesh). A Frozen entities & local sizes block names whole EntityBlocks or SubModelPart subtrees MMG must leave bit-identical (e.g. an interface another code owns), and assigns per-block / per-part hmin/hmax/hausd bounds — "nothing smaller than 2 mm in the boundary layer, whatever the formula says". The Advanced block exposes the MMG tuning surface — hmin/hmax size bounds, hausd Hausdorff distance, hgrad gradation, sharp-angle detection threshold, keep surface / no insert / no swap / no move toggles, and a module override (auto-detected otherwise: tetrahedral volumes → mmg3d, non-planar triangulated surfaces → mmgs, planar triangulations → mmg2d). Level-set split (MMG) discretizes an isovalue of any nodal field as an explicit, conforming boundary — pick the field and isovalue and the mesh is split into MMG_Domain_Inside / MMG_Domain_Outside with an MMG_Interface boundary layer, each also generated as a SubModelPart of the same name (exportable/deletable from the outline, saved as real Begin SubModelPart blocks). Level-set has its own Advanced block with the same hmin/hmax/hausd/hgrad/module controls as Remesh, for manually tuning the split (e.g. a tighter hausd for a sharper interface) when the automatic defaults aren't right, plus rmc — delete split components below a volume fraction of the mesh, for the small detached blobs a Signed distance → level-set chain leaves behind. A Materials & base references block adds keep materials, which puts each split cell back into its original block and SubModelParts and carries the side on the generated MMG_Domain_Inside/_Outside parts instead (off by default, since it changes the shape of the output); no-split blocks/parts, naming materials the level set must leave uncut; and base references, boundary entities a split domain must touch to survive. Element blocks and SubModelParts survive remeshing (each cell is tagged with its block + SubModelPart signature as an MMG reference and regrouped afterwards); data fields are mapped onto the remeshed mesh — Nodal values are barycentric-interpolated (exact for linear fields), Elemental/Conditional values come from the containing source cell — and the result message names what landed and what (if anything) was dropped with its reason. Hexahedral, pyramid and quadratic meshes are not remeshable (MMG is tet/triangle-based). Remeshes join the same operation history — undo is instant (the result is snapshotted), and remesh steps in a saved JSON recipe re-run MMG deterministically when replayed. MMG runs in a worker thread, so the editor stays responsive; while it runs, an inline loading bar under the form streams MMG's live phase output (analysis, meshing, split/collapse/swap counters) and the form's play button becomes a stop button that cancels the run immediately, leaving the mesh unchanged.
More mesh operations — the Mesh Modification section also surfaces the extension's bundled meshio++ as an oracle (it computes something we apply to your own mesh — SubModelParts, ids and material assignments are never lost the way a raw meshio++ round-trip would lose them) plus several operations implemented natively. The section is organized into seven collapsible categories so it reads as a short list of groups rather than a long scroll of forms:
| Category |
Operations |
| Element order & topology |
Convert Linear → Quadratic · Quadratic → Linear (the inverse: drops mid-edge nodes) · Refine (uniform subdivision — triangles/quads/tets/hexahedra/wedges split into 4 or 8 children, lines into 2, up to 4 levels, with shared edges/faces deduplicated to a single new node and nodal fields interpolated exactly) · Simplexify (hexahedra/wedges/pyramids/quads → tetrahedra/triangles) · Tessellate curved cells (meshio++ ≥ 16.42.0: 6-node triangles, 8/9-node quads, 10-node tetrahedra and 27-node hexahedra become straight linear triangles/tetrahedra sampled through their own shape functions, up to 5 levels; ids, properties, SubModelParts and fields carry onto the children) · Remesh surface (redistribute) (ACVD: a new triangulation with exactly N vertices, isotropic / curvature-aware / anisotropic; every face inherits block, property, SubModelPart membership and cell fields from the nearest original face, and the message reports the deviation from the original surface) · Generate volume mesh (retetrahedralize) (a tetrahedral mesh of a closed surface or volume on a lattice, with the boundary as Conditions inheriting the surface's parts — and an honest report of its quality caveats) · Optimize tetrahedra (2-3 / 3-2 flips and vertex relocation with fixed nodes: untouched tetrahedra keep their ids, blocks, properties and parts) · Repair surface (fix winding, orient closed components outward, fill bounded holes, split non-manifold vertices, weld — adopted in place; filled faces join the source block and are listed in a Repair_Fill SubModelPart, with no element field values invented) |
| Remeshing (MMG) |
Remesh (MMG) · Level-set split (MMG) — described under Remeshing (MMG) above |
| Smoothing & renumbering |
Smooth (Taubin — shrink-free — Laplacian, or ODT (optimal-Delaunay-triangulation, tetrahedra only, which targets element quality rather than surface fairness and is the one to run before a solve), with boundary pinning, feature-edge preservation and an inversion guard; only coordinates move) · Reorder (RCM bandwidth reduction, or Morton/Hilbert space-filling curves for cache locality — a pure reordering of storage order; every node keeps its own id) · Project onto CAD (move the nodes of a CAD-tagged surface mesh back onto the B-rep of a .cad.json, from its CAD_FACE field — projectToCad), Shrinkwrap (project the nodes onto a triangle surface — a file, a SubModelPart of this mesh, or its own skin — with offset, maximum distance, blend, and move-only / keep-fixed parts; a projection rather than a collision-free fit, so folded cells are counted) · Sobolev deformation (apply a smoothed, optionally pinned displacement field through the mesh's own finite-element operators; a constant displacement is preserved exactly) · Mark connected components (each Element's connected-body index as a field, with isolated fragments flagged) · Renumber (compact ids into a gapless run, each entity kind numbered independently as Kratos does — pair it with Reorder for a full RCM renumbering) · Partition (space-filling-curve domain decomposition into N balanced parts, attached as a real Kratos PARTITION_INDEX field, optionally with one SubModelPart per part) |
| Selection & combination |
Crop (keep only the cells inside a bounding box or on one side of a plane, "all nodes" or "any node") · Merge mesh (append one or several mesh files' nodes and cells in a single operation, offsetting ids per kind, wrapping each source in its own SubModelPart, automatically suffixing conflicting part names and preserving incompatible same-name fields under suffixed variable names, with an optional weld of coincident nodes run once across every seam) |
| Fields |
Field calculator (a new nodal/elemental/conditional field from a formula over coordinates and existing fields — the same safe expression evaluator as the MMG size = ƒ(h) mode, never eval) · Average field (nodal ↔ elemental averaging) · Manage fields (rename, drop, keep only — lossless, and a global reduction follows a renamed source) · Condition field (clamp, normalize or standardize a field's values, per component or by magnitude, with an explicit NaN policy) · Kinematic pressure → Pa (an OpenFOAM kinematic p in m²/s² to a new Pa field with an explicit density you supply — only a field whose recorded dimensions are m²/s² converts, the original is kept, a conflicting density is refused) · Field gradient (gradient / divergence / curl of a nodal field, Green-Gauss or least-squares) · Surface curvature (mean, Gaussian and principal curvature of a surface mesh as nodal fields — a sphere of radius R reads 1/R and 1/R², a wrong-way winding flips the sign of the mean curvature and says so, and a closed surface reports the Gauss–Bonnet check; usable in remesh size formulas, with a Curvature-adaptive preset) · Field Hessian (the second derivative of a scalar nodal field, as its 9 flattened components — a field that is at most linear has an exactly zero Hessian, which is the guarantee to sanity-check against) · Error estimate (Zienkiewicz-Zhu recovery-based indicator, per cell, optionally marking the worst cells for refinement by threshold, fraction or Dörfler bulk — a field the mesh represents exactly has zero error) · Distance to surface (the signed distance from every node to a surface — an imported file, or a SubModelPart already in this mesh, no file needed — negative inside; feed it straight to Level-set split (MMG) to cut the mesh along that surface) · Compare with another mesh (a field against the same field of another file, by entity id or by spatial point sampling, written as signed / absolute / relative difference fields with uncovered entities left as gaps — never compared as 0) · Transfer fields (mass-preserving transfer of another mesh's fields onto this one — the measure-weighted total is what is conserved; nodal data is smoothed through a cell round trip rather than resampled) |
| Sphere elements |
Set element radius — see Sphere / particle elements |
| Mesh analysis |
Feature-edge preview/export · sampled Hausdorff comparison · structured quality gates · periodic-node pairing by original IDs · SubModelPart union/intersection/difference · transient resampling in the timeline or export to PVD |
Smooth / Reorder / Partition / Merge mesh / Field gradient / Field Hessian / Error estimate / Distance to surface / Transfer fields (and the other meshio++ operations) run asynchronously off the host thread with the same inline progress bar and cancel button as MMG — Cancel stops the running operation and leaves the mesh untouched; the rest apply instantly. Every one joins the same undoable operation history and JSON recipe as the operations above, and is reachable from mesh_transform for scripting. The Mesh Editing guide has a worked before/after screenshot for each one.
Editing & operation history — the Edit sidebar section records every applied edit and mesh modification into an undoable history: undo / redo / clear plus a clickable list of operations (click any step to partially revert to it). Edit operations are driven by interactive controls in the sidebar: remove orphan nodes, merge coincident nodes (tolerance), and separate scale, translate, and rotate transforms (values entered inline). Deleting a SubModelPart is done from its ✕ button in the outline tree. Every edit and mesh modification joins the same history, and the applied operations can be saved to / loaded from a JSON recipe and replayed on the mesh (Save operations… / Load operations…). Check "Queue operations for one apply" to combine several operations — from any sidebar form — into one sequence: each still lands as its own undoable step, but it's one click of Apply queued steps instead of N.
Reload from disk — File ▸ Reload from disk (Ctrl+Alt+R) re-reads the file, and so does an external change to it or saving it in a text editor. Applied operations survive a reload: the history is re-applied to the new contents instead of being discarded, an op that no longer applies is kept and marked rather than dropped, and the same holds when you step a VTK time series — except that the expensive remeshing operations are marked skipped instead of re-running on every frame, with a Re-apply button to run them deliberately.
Save / Load problem (zip) — File ▸ Save problem… bundles the whole setup into a single portable zip: the original mesh file, the applied edit operations as a recipe, the problemtype case state (<name>.kratoscase.json) and the generated case files (ProjectParameters.json, the materials JSON, MainKratos.py, <name>_case.mdpa) — whichever exist. File ▸ Load problem… extracts such an archive into a folder of your choice, opens the mesh in the preview, replays the bundled edits automatically and restores the case setup — share a .kratosproblem.zip and the recipient gets the exact same problem. Also available as the Save Problem (zip)… / Load Problem (zip)… palette commands.
Command line — a one-row input above the status bar (focus it with /, or Kratos MDPA: Focus Command Line) that runs every mesh operation, view toggle, panel, export and case action as text: translate dx=1, smooth method=taubin iterations=10, view top, export vtu, fieldCalc … ; remesh … for several steps in order. Tab completes commands, parameters and the mesh's own field/SubModelPart names, ↑/↓ recalls history, help <command> shows usage. Arguments are checked before anything is sent; the host's reason is shown if it refuses one. See the Command Line guide.
Keyboard shortcuts, scoped to the preview tab (they never clobber the global VS Code bindings): Ctrl+O Open, Ctrl+S Save, Ctrl+Shift+S Save As, Ctrl+E Export, Ctrl+Alt+R Reload from disk, Ctrl+Alt+S / Ctrl+Alt+O Save/Load problem, Ctrl+Alt+P Screenshot (⌘ variants on macOS) — plus the in-viewport view snaps 1–6 (±X / ±Y / ±Z) and i (isometric).
Editor integration: mdpa language id with // comments, Begin/End folding, and syntax highlighting. The raw text editor stays the default; open the preview from the editor-title button, the explorer context menu, the Open MDPA Preview command, or the Kratos activity-bar sidebar (see above), which works with nothing open at all.
Problemtypes — build & run Kratos cases: the Problemtype sidebar section generates everything a Kratos run needs from the previewed mesh: pick a problemtype (built in: Structural, Fluid, Compressible Fluid, Embedded Fluid, Turbulent Flow (RANS), Two Fluids, Free Surface, Potential Flow, Shallow Water, Convection-Diffusion and the coupled Buoyancy, Conjugate Heat Transfer, Fluid-Structure Interaction and Generic Coupling (CoSimulation) — weak or strong, several interface pairs, optional ALE —, aligned with GiDInterface; plus Structural Optimization for the OptimizationApplication, with an Optimization progress panel and per-iteration design fields, and reduced-order model variants of Structural, Convection-Diffusion, Fluid and Potential Flow for the RomApplication's RomManager), fill the grouped, collapsible solver cards, assign conditions/loads and materials to SubModelParts, and Generate case files writes ProjectParameters.json, the materials JSON and MainKratos.py next to the mesh — which need not be an .mdpa: any previewed mesh format works, and a non-.mdpa mesh is always converted to a <name>_case.mdpa case mesh first, since the solver reads .mdpa. Element/condition block names are adapted to the solver automatically: when the mesh's typology differs from what the chosen physics expects (e.g. SmallDisplacementElement3D4N for structural, generic Element3D4N for fluid), a renamed <name>_case.mdpa copy is generated and the case points at it — the original mesh stays untouched. Output always goes through Kratos' vtk_output_process, so Run case (an integrated terminal with the configured Kratos environment — pip-installed Kratos works with zero setup, and a custom-compiled Kratos is configured with the Select Kratos Installation Folder… command, which auto-detects a source checkout's bin/Release build) produces a vtk_output/ folder the extension previews directly, timeline growing live as steps are written (Open results). The case setup auto-saves to <name>.kratoscase.json and is restored on reopen. Custom problemtypes are plain .js / .py files in .kratos/problemtypes/ (Python runs in bundled Pyodide); faithful Python ports of the five original built-ins and of FSI and CoSimulation ship as copyable examples in example/problemtypes/. Before a run starts, the extension checks that the configured Python can import every Kratos application the case needs and names any that are missing. See the documentation site for the user guide and the authoring API.
- Material presets, with provenance. The Materials form carries a searchable catalog of parameter values, each with its units, reference conditions and source. About sixty-five rows ship — fluids (water at several temperatures, seawater, glycerol, air…), structural solids (steel, stainless steel, aluminium alloys, titanium, concrete grades, timber, glass… with
E, ν and ρ quoted from Eurocodes and handbooks), thermal properties, Manning roughness, and the defaults of the Kratos GiD interface — each with a citation, so a material is one pick rather than three typed numbers. For example: picking water fills DENSITY 998.2 kg/m³ and derives μ = ρ·ν (the status line shows the multiplication), which happens exactly once per application however often you re-apply it. A preset is values, not a law — it names the constitutive laws it fits, and one applied to a law it does not name is refused rather than half-filled. Your own rows are JSON files in the workspace (.kratos/materials/*.json, kratos.materials.extraPaths to move them), importable from a file, savable from a case row, and exportable to share; units convert both ways (g/cm³, cP, cSt, GPa, psi, …) and any pair that is not the same physical quantity is refused with a reason instead of guessed. Each case keeps a snapshot of the values it was given plus the source, version and reference conditions they came from: editing the material changes the case, editing the library never rewrites a case, and a row the library has since changed offers an explicit re-apply. Save problem… and problem_pack carry the snapshot with the case. A material the generator cannot use — an undeclared law, a mismatched preset, a non-positive density — is reported by the case check and refused by Generate rather than written out for Kratos to fail on.
Flowgraph node editor (visual case setup): a sixth built-in problemtype, Flowgraph (node editor), embeds the Kratos Flowgraph visual editor directly in the preview. Selecting it splits the view in half and opens Flowgraph in a resizable pane — horizontal (below the mesh) by default, toggleable to vertical (beside it) from the pane header or the kratos.flowgraph.splitOrientation setting. It runs as a bundled local server embedded in an iframe, so the full node editor works unchanged. The bridge is two-way: opening Flowgraph seeds the graph with the current case's ProjectParameters.json, and Flowgraph's Generate writes the resulting ProjectParameters.json back next to the .mdpa, ready for Run case. Flowgraph is AGPL-3.0 — see License.
VTK / mesh file preview
The same viewer handles native MDPA, VTK-family, and surface-mesh files, with additional formats provided by meshio++. It also includes selection and Properties authoring, timeline playback, analysis panels, mesh export tools, and specialized renderers for particles and beams.
Supported format details
The viewer opens all common VTK-family and surface-mesh formats, plus many more through meshio++:
| Format |
Extensions |
Notes |
| Legacy VTK |
.vtk |
ASCII and binary (big-endian) |
| VTK XML |
.vtu, .vtp, .vti, .vts, .vtr |
ascii, inline base64, appended raw/base64, zlib-compressed |
| VTK multiblock |
.vtm |
referenced blocks merge into one scene; each block becomes a layer; writes back as an index plus one .vtu per top-level part |
| ParaView collections |
.pvd (time series), .pvtu/.pvtp (partitioned) |
a .pvd is read natively from its index, each step's .vtu/.vtp merged and its time values driving the timeline; a .pvtu/.pvtp reads every piece it names as one dataset, dropping ghost cells at the seams (read-only, via meshio++) |
| Surface meshes |
.stl (ascii+binary), .obj, .ply (ascii+binary) |
STL vertices are welded; PLY vertex properties become fields |
| Extended (meshio++) |
.msh (Gmsh), .inp (Abaqus), .bdf/.nas/.fem (Nastran), .unv, .mesh (Medit), .vol (Netgen), .su2, .xdmf/.xmf, .off, .dat/.tec (Tecplot), .avs, .f3grid, .pf3, .mfm, .mphtxt (COMSOL), .post/.dato (PERMAS), .ugrid, .wkt, .xml (DOLFIN), .case/.geo (EnSight Gold), .node/.ele (TetGen), .poly (Triangle), .foam (OpenFOAM case: polyMesh plus time-directory fields; multi-region and decomposed cases too), .vtkhdf/.hdf, .pcd, .xyz/.xyzn/.xyzrgb, .k/.key/.dyn (LS-DYNA), .frd (CalculiX results), .fil (Abaqus results), .rst/.rth (MAPDL results), .d3plot (LS-DYNA animation), .t19 (MSC Marc post), .h5 (MSC Nastran result database, retried after .h5m), .op2 (Nastran bulk results), .xplt (FEBio plot), .meshb (Medit binary) |
via @meshioplusplus/wasm 17.13.0. Kratos CAD JSON (.cad.json, meshio++ ≥ 16.42.0) reads and writes quadrilaterals as bilinear NURBS faces and lines as edges (the compound extension is claimed because a bare .json is too generic; reach a plain .json with an explicit inputFormat), and .fil (Abaqus results), .op2 (Nastran results), .t19 (MSC Marc post), .xplt (FEBio plot) and .rst (MAPDL results) are export targets besides readable files (meshio++ ≥ 17.3.0 gave all three a writer). The step/iges readers need OpenCASCADE, so they run on the full artifact (which the extension ships beside the lean one) and are routed. Ambiguous extensions are resolved by content (.msh tries Gmsh then ANSYS/FreeFem; .inp tries Abaqus then ANSYS). The solver-result formats above are routed as ordinary single-step reads — their metadata read falls back to a full read, so none drives an in-file timeline (the same rule that keeps .frd a filename series); a run written as one file per step still groups through the usual filename timeline. Four further result readers are reachable only with an explicit format argument, because upstream identifies them by file name rather than by extension: ansys_rst_cyclic (a cyclic model’s full rotor), lsdyna_binout, radioss_anim and radioss_th. Gmsh MSH 4.1 needs ≥ 9.7.0 — earlier builds couldn't read a real-world 4.1 file at all (every such file starts with a $Entities section the reader used to reject on sight), which is also what carries 4.1's physical-group membership, so upgrading also means 4.1 files now get their named regions as SubModelParts. Since 11.5.0 a .msh export also declares $PhysicalNames (untagged groups get freshly allocated tags) instead of dropping them. Export also offers write-only SVG/TikZ figures. OpenFOAM export (meshio++ ≥ 9.20.0) is the one format that writes a directory: picking .foam leaves a 0-byte marker there and puts the mesh in constant/polyMesh/ beside it, with patch names recovered from the model's SubModelParts afterwards (a patch-less mesh still gets the single synthesized defaultFaces). OpenFOAM zones and patch types now survive too: cellZones/faceZones/pointZones are read as named SubModelParts (alongside the writer's own block-derived zone — the same block-name-survives pattern Exodus and FLAC3D already have), and a recovered patch type that needs no extra dictionary key (wall/empty/symmetry/symmetryPlane) round-trips instead of always writing patch; a type needing extra keys (cyclic and similar) is still downgraded, named in the diagnostic. Multi-region and decomposed (processor*/) cases are still read as a single constant/polyMesh only. DOLFIN/TetGen/EnSight are now export targets too: DOLFIN needs at least one triangle/tetrahedron (each field becomes its own <stem>_<field>.xml sibling file), TetGen needs 3D points and at least one tetrahedron (.ele + a .node companion, geometry only), EnSight Gold writes .case + a .geo companion (geometry only) — an ineligible mesh is refused with the actual reason before the write runs, rather than an upstream error partway through. .pcd/.xyz have no cell concept, so exporting to either drops all connectivity and keeps only nodes and Nodal fields. .f3grid (FLAC3D) named ZONE/FACE groups become clean SubModelParts — zone:Inlet:Default reads back as plain Inlet, and its 2D FACE-section blocks read back as Conditions rather than Elements, since FLAC3D's own file structure separates the two (unlike Gmsh, where dimensions carry no such meaning). Named groups on a .msh export only survive a re-read when they claim no cell any other named group already claims — Gmsh tags one physical group per element, and every EntityBlock already gets its own block-named group covering its full cell set, so an overlapping SubModelPart loses to it; a node-only SubModelPart has no cell to carry a tag on at all and is refused with a named reason rather than silently dropped (.med/.inp keep point-only groups, if that matters) |
| GiD postprocess (meshio++) |
.post.msh + .post.res (ascii pair), .post.bin (deflated), .post.h5 (HDF5) |
Kratos's reference pre/post-processor, readable and writable since meshio++ ≥ 10.19.0 / 10.18.0. Multi-step: the steps live in the .post.res headers and drive the timeline bar, like Exodus. These are compound extensions — case.post.msh resolves to GiD, not to .msh/Gmsh, and a bare .post is PERMAS as before. Opening either half of the ascii pair finds the other. Export offers the ascii flavour, which writes both files |
| HDF5 / netCDF containers (meshio++) |
.cgns, .h5m (MOAB), .hmf, .med (Salome), .e/.exo/.ex2 (Exodus II) |
needs a meshio++ ≥ 8.0.0 build (Exodus ≥ 8.6.0, for real SEACAS/Cubit/Sierra files — earlier builds threw on the qa_records every such file carries). MED's named groups (*FAS/*GRO families) become SubModelParts too, since meshio++ ≥ 9.6.0, and a real Salome/Code_Aster file that the strict reader refuses is retried leniently (meshio++ ≥ 9.9.0) instead of failing to open. .med can now be written (meshio++ ≥ 9.9.0, which fixed the vector-field shape bug that made every earlier writer fail on the common case): fields survive scalar and vector alike, and SubModelParts arrive as MED families. CGNS now carries point and cell data (meshio++ ≥ 9.9.0 — earlier it silently dropped every field), and has been a genuine CGNS/SIDS-compliant writer since ≥ 9.8.0 (before that it wrote only the first tetra block it found, so any other mesh — every surface mesh included — produced a file nothing could read). Exodus can be written (meshio++ ≥ 9.3.0) but lossily, so pick it knowingly: element blocks, point_data and per-element data all survive (vectors included since ≥ 9.9.0), and block names now round-trip as SubModelParts, but a genuine SubModelPart does not — the writer emits no node sets or side sets — a time series is flattened to one step, and the output is NetCDF-4/HDF5 rather than classic netCDF-3. Export to .mdpa/.vtu/.med if the grouping matters. Exodus carries its own in-file time series — see Timeline animation — and its element blocks/node sets/side sets become SubModelParts like every other format's named groups. .xdmf written from the extension now emits a companion <stem>.h5 beside the XML — both files are needed to re-open it |
Named groups become SubModelParts. Gmsh physical groups, Abaqus *NSET/*ELSET/*SURFACE, and every other named group meshio++ recognizes arrive as SubModelParts in the outline tree, with the usual frame / export / rename / delete / organize actions. A surface group (a set of cell facets rather than whole cells) is materialized into real boundary-facet Conditions, so it is a visible layer — and exporting to .mdpa yields genuine Kratos Conditions.
Filename-based playback supports VTK, STL, OBJ, PLY and the extended meshio++ formats that do not already have an in-file timeline. Open a file named <prefix>_<rank>_<step>.<ext> (for example Main_0_2.ply) to discover its sibling steps. Groups stay separate by extension; the selected frame uses the usual reader and companion files. Existing root-file groups survive subpart merging.
Point/cell data arrays from any format appear in the Field panel; mesh quality, find-by-ID, and screenshots work everywhere.
Structural CAE routes also cover Code_Aster (.mail), FEBio (.feb), Femap (.neu), libMesh (.xda/.xdr, including gzip and bzip2), COMSOL binary (.mphbin), Patran (.pat), and Z88 (.z88, plus the exact z88i1.txt and z88structure.txt basenames). Elmer cases open from an .elmer marker beside their mesh files or from mesh.header, including binary and partitioned layouts. Marc retries after Tecplot on .dat, while MFEM retries after Medit on .mesh; MFEM rank files such as .mesh.000000 collect their sibling ranks, and MFEM writing is an explicit .mesh flavour. Marc and Radioss mesh-only exports are available through MCP outputFormat.
Selection, layers, and timeline workflows
Selection sets and Properties authoring
The Selection toolbar button opens named selection sets over Elements, Conditions and Geometries (each kind its own id space). While the panel is open, Ctrl+click toggles the picked entity in the active set, Box select turns a left-drag into a rubber-band batch add, and Lasso places vertices one click at a time (click the first point or press Enter to close, Escape cancels). A set carries a seed — explicit picks, a SubModelPart, a field range (with the same "all/any" rule the viewer's Threshold mode uses), a quality metric (bad / unacceptable elements), or a property id — and re-resolves it against every new model: a field seed follows the timeline step by step, explicit picks keep exactly the ids that still exist and prune the rest, so a selection never silently survives onto unrelated ids.
From a set: New SubModelPart (an ordinary, undoable operation — the selected cells' nodes ride with them so the Kratos parent/child subset rule holds), Export (the selection as its own file, original ids preserved), Delete entities (one undoable edit — the complement of the export: conditions on the surviving region stay, constraints vanish with their nodes, fields and SubModelParts follow, orphan nodes are cleaned up), Isolate / Hide / Restore (whole block layers, per each button's stated granularity), Frame and Clear.
Hanging-node constraints — a hexahedral octree (or any hexahedral/quadrilateral mesh with a refined patch) has nodes in the middle of a coarse neighbour's edge or face. Mesh Modification ▸ Tie hanging nodes (command addHangingNodeConstraints) finds them from the geometry and writes one LinearMasterSlaveConstraint per node and variable, with 0.5/0.5 weights on an edge and bilinear weights on a face, so a linear field is reproduced exactly; chains of hanging nodes resolve to end masters and everything lands in a HangingNodes SubModelPart that a re-run replaces. createConstraint/deleteConstraint edit single constraints, View ▸ Constraint links draws the slave→master segments, Inspect lists the constraints of the picked node, and the Data table has a Constraints kind. Headless: mesh_transform takes the three ops, mesh_derive with kind: "octreeMesh" takes hangingConstraints, and mesh_export_table accepts kind: "Constraints".
Advanced ▸ Properties editor… lists every Begin Properties <id> block: edit any variable in place (Enter commits — number, True/False, vector, or verbatim text), create/clone/delete sets, and assign a set to a SubModelPart by rewriting its blocks' propertyIds rows. Both authoring shapes are exposed: editing a shared set in place, or clone-and-reassign to point selected blocks at a fresh id. A beam's CROSS_AREA resolves through these sets, so an edit re-renders the beam tubes immediately. Headless, mesh_select evaluates the same predicates per kind and mesh_transform takes setProperty/createProperty/cloneProperty/assignProperty/deleteProperty/createSubModelPartFromSelection (a seed there resolves against the rolling model at apply time) and deleteEntities (the selection as one undoable delete). See the documentation site's Selection & Properties page for details.
View layers (view-only, never solver data)
The sidebar's Layers section lists the mesh itself — blocks and SubModelParts. View Layers, right below it, lists named view-only groups (walls, a probe region, compared results) built from checked blocks, parts and a selection snapshot. Show/hide suppresses members underneath without rewriting your outline checkboxes (a base layer hides only when every containing view layer is hidden), the topmost visible layer lends its colour, and explicit picks draw as one overlay each. Locked layers refuse rename/reorder/delete/promote; deleting one never deletes entities, parts or fields. Layers prune by definition on every new model and persist in <stem>.kratosview.json, so reopening restores them in order. The same file remembers how you left the viewer — camera bookmarks, pane layout, each pane's camera, Field and Clip settings, and which layers are shown and how opaque — and restores it on reopening (a variable or layer the mesh no longer has is skipped with a note; nothing is written until you change something). Promote is the only way one reaches the solver: it resolves the layer to explicit ids and posts an ordinary undoable createSubModelPartFromSelection. See the documentation site's View Layers page for details.
Submodelpart tree
The sidebar shows the same layer tree as the MDPA preview. The root model-part file provides the full mesh; each submodelpart file (e.g. FixedEdgeNodes, MovingNodes) appears as a hidden-by-default overlay layer that you can toggle independently. Point-cloud submodelparts (node-only files) are rendered as vertex cells.
Timeline animation
When multiple time steps are found in the directory, a timeline bar appears at the bottom of the viewport:
◀ ▶ ▶▶ ══════●══════════ Step 4 (2/3) 2 fps
- ◀ / ▶▶ step backward / forward one frame
- ▶ / ⏸ play / pause (at the configured fps rate)
- Scrubber — drag to jump to any step instantly
- fps input — controls playback speed (1–30 fps)
Camera position, layer visibility, active field variable, and colormap are all preserved when switching frames. A single file with no timestep siblings opens as a static preview with no timeline bar. Filename-based grouping covers VTK, STL/OBJ/PLY and meshio formats without an in-file timeline.
Exodus, GiD postprocess, MED, CGNS, Tecplot and XDMF carry their own steps, while OpenFOAM lists numeric time directories. These drive the same timeline bar without a filename grammar, and newly appended steps extend the timeline live. MED, CGNS and Tecplot enumerate their steps since meshio++ 11.3.0 (native metadata readers); Gmsh selects steps but cannot enumerate untagged sections, so it stays on filename grouping.
Advanced tools
The Advanced toolbar button holds operations that are useful but not everyday, so the toolbar does not grow a button per niche feature.
Mesh size
Opens the Mesh Size panel — per-node and per-element size statistics, a box-and-whisker plot, and smallest/largest highlighting. See Mesh Size above for the full details.
Face normals

Draws an arrow on every surface face and every boundary face of a volume mesh. This is the standard way to find an inverted element: the winding of a cell decides both the arrow direction and the sign of its Jacobian, so a flipped cell points against its neighbours — obvious on screen, invisible in the numbers, and a hard error for the solver.
Hole rims are outlined in orange and non-manifold edges in violet, so a defect has a place and not just a count. Faces wound against a neighbour are also counted and highlighted in red, and the status line reports whether the orientation is consistent. Note this is a relative test: a mesh that is uniformly inside-out is self-consistent and reports none, so the arrows themselves remain the check for global orientation.
Run manager
Running a case used to be fire-and-forget: the extension launched a terminal and said "running" forever, whatever actually happened. Now every run is tracked in a Kratos Runs view in the Explorer, with its status, elapsed time, the latest step written to vtk_output/, and — when it ends — a real exit code.
The solver runs as a child process with its output in an Output channel, which is what makes the exit code, the live progress and a working Stop possible; it also fixes a launch failure being reported properly, so a wrong kratos.pythonPath now names itself instead of scrolling past in a terminal. Set kratos.run.launchMode to terminal if you need an interactive shell instead — such a run is still listed, but marked detached, because a terminal cannot report when the solver exits and the extension will not claim otherwise. Set kratos.run.isolate to give every run a workspace of its own (<case folder>/<runs folder>/<stem>-<run id>/), with the generated inputs and vtk_output/ inside it, so runs of different cases sharing a folder never overwrite each other; each keeps a preparation record and an execution receipt, which case_compare reads after a reload.
Stopping asks the solver to finish its current step and finalize — through a stop file the generated MainKratos.py watches, so it works on Windows too — and only escalates to an interrupt or terminate if that does not answer within 10 seconds; anything already in vtk_output/ is kept. Because the last step of an interrupted run may be half-written, Open results for a run that did not finish cleanly opens the last complete step.
Runs outlive the preview that started them. If the window is closed or reloaded they are stopped by default (kratos.run.stopOnWindowClose), and whatever is found afterwards is reported honestly: a run whose process is gone reads orphaned, and one whose process may still be alive reads detached — never running, because process ids get reused and the extension will not claim a liveness it cannot verify. Agents drive the same runs through the case_run, case_status and case_stop MCP tools, which meet the editor on the same sidecar file — so a run started on either side is visible from both.
Record a video

View ▾ ▸ Record… turns the viewport into an animation. Two sources: a turntable that spins the camera through one full revolution (available for any mesh, including .mdpa files with no time dimension), and a time series playthrough that steps through every frame of a mesh series.
The result is a WebM video, or a numbered PNG sequence if you would rather encode it yourself — the extension prints the exact ffmpeg -i <stem>_%04d.png out.mp4 line when it saves them. mp4 is not offered directly because the browser engine VS Code is built on cannot reliably encode H.264; the PNG route is the honest answer rather than a format that sometimes fails.
Each frame is captured only once the frame it depends on is genuinely on screen, so a recording of a time series is a faithful playthrough rather than whatever happened to be drawn when a timer fired — worth knowing because every step of a series is a full re-read from disk, so a long recording takes real time. The progress bar counts frames, and Cancel keeps whatever was captured.
In a split view the recording includes every pane, with the pane separators drawn in so it matches what is on screen. A turntable spins the focused pane.
Split view

View ▾ ▸ Layout splits the viewport into 1, 2 or 4 panes. Each pane has its own camera over the same mesh, so you can look at the front and the top at the same time, or keep an overview beside a zoomed-in detail, without reloading anything.
Orbit, pan and zoom apply to the pane under the pointer. The pane you last pressed in is outlined, and that is the one Reset, Frame, the navigation dock and the keyboard view shortcuts act on — the orientation cube also turns to match it.

The Field panel and the Clip controls also act on the focused pane, so each pane can show a different variable, colormap, component, range, isosurface, threshold or deformation, and its own clip plane — the panel names the pane it is editing and offers Copy to all panes when you want them to agree. Click into a pane to point the panel at it.
Everything else stays shared: the same layers, visibility, colours, opacity and display mode appear in every pane, so a split is a second viewpoint rather than a second document. A screenshot captures the whole grid; in a split, switch on Show scalar bar in scene so each pane's legend is part of the picture.
Node IDs are shown in the single-pane layout only: they are drawn as HTML labels projected through one camera, so in a split they would land over the wrong panes.
Comparing two meshes or runs: open each in its own preview and use Advanced ▸ Link previews… to link them, so the camera, coloured field, colour map and range, clip plane and physical time of one drive the other (each its own switch). Time is matched by physical time — exact, or nearest within a tolerance — never by frame number, and a time or field the other mesh cannot honour is reported rather than guessed. The compared runs are remembered with the view.
Plot over time
Inspect ▸ Plot over time and Plot beside a field value now append a history to the embedded Plots pane. Use Add points from mesh for several points on the same chart, components or magnitude, and Locate peak to find the full-resolution maximum. Advanced settings support statistics, XY relationships and saved configurations. The scientific plotting guide also covers regional analysis, standalone table imports and line-probe shortcuts. The image below shows the earlier single-history panel, whose extraction core is retained.

Reading one number at one step is what Inspect does. This answers the other half: what that number did across the whole run. Pick a node or element, choose a variable, and the extension reads every step of the time series and charts it.
The scan runs in the extension host, not in the preview — the viewer only ever holds one frame, so charting from it would mean stepping the whole timeline and watching the viewport flicker through every frame to read one value. Progress is shown per step and the scan can be cancelled; a partial series is still plotted.
What it will not do is quietly make the data look tidier than it is. A step where the variable is not written, or where the entity does not exist, leaves a break in the line rather than a segment drawn through it, and the panel says how many steps were missing and which of the two reasons applied. If the mesh changes size partway through the series, it says that too — the id still resolves, but it may no longer be the same entity. Edit operations from the sidebar are not replayed per step (that would cost as much as scrubbing the timeline by hand), so if any are applied the panel tells you the values are the ones on disk.
Clicking a point jumps the 3D view to that step. CSV saves the series. Also available headlessly as the mesh_field_series MCP tool.
Line probe
Inspect answers "what is the value at a point" (a click) and Plot over time answers "what did one entity do across the run"; the Probe line answers the third combination — what the field does along a line, at one step. Toggle Probe line next to Measure, click two nodes, and a profile chart opens: distance along the line on the x-axis, the chosen nodal field on the y-axis, one line per component.
The sampling runs in the extension host through one meshAnalysis round trip, so the plot's numbers are exactly mesh_probe's for the same endpoints. A sample the mesh cannot answer — the line leaving the domain, or a region the field was never written to — is a break in the line, never a bridged segment, and the panel counts how many samples were uncovered. In a mesh series the plot follows the timeline step: stepping or playing re-samples the same two endpoints on each frame, and a reply that arrives late (a step whose sampling straggles behind the newer one during playback) is dropped rather than allowed to overwrite the newer profile. CSV saves the current profile. Works in both previews, including filename MDPA series; without a series it is a single-frame profile. Plot builder… opens the embedded workspace with a fixed captured profile and an explicit Follow timeline option.
Streamlines
Open Advanced ▾ ▸ Streamlines…, pick a Nodal vector field (2 or 3 components; a cell field must be moved to the nodes first with Average field) and say where the lines start: typed Points (one x y z per line, or Pick seeds and click nodes in the scene), a Line of equidistant seeds, a Plane lattice origin + i/(nu−1)·U + j/(nv−1)·V, or the nodes of a SubModelPart and its children. Trace draws the lines over the mesh coloured by speed; Both directions gives two lines per seed, one each way.
The integration is a fourth-order Runge–Kutta in arc length through a point locator built on the mesh's own cells, so a step is a distance — a fraction (default 0.25) of the cell it is in — and does not shrink where the flow is slow. Three caps bound a line: Max steps (default 2000), Max length (default five bounding-box diagonals) and at most 1000 seeds (more are refused, not truncated). Every line ends for a reason the export records: it reached a cap, left the domain, ran into a stagnation point (speed below 10⁻⁶ of the field's largest magnitude), or met a node that carries no value — the field is never extrapolated. A seed outside the mesh, or at zero speed, gives no line and is counted in the summary instead of disappearing.
These are steady streamlines of the frame on screen — the field frozen at one instant. They are not the paths particles would take in a changing flow (pathlines), and edit operations applied in the sidebar are honoured. Stepping the timeline re-traces the same seeds on the new frame. A plane lattice can be taken from the focused pane's clip plane (Use clip plane), and orange markers preview the seeds while the panel is open. The overlay draws lines or tubes, both coloured by speed; tubes are generated surfaces (view-only) and the export is line cells either way. Export… writes one node per vertex and one Line2D2N per segment, with nodal STREAM_SPEED, STREAM_VELOCITY and STREAM_ARCLENGTH and per-segment STREAM_LINE, STREAM_SEED (0-based), STREAM_DIRECTION (+1 forward, −1 backward) and STREAM_TERMINATION (0 max length, 1 max steps, 2 left the domain, 3 stagnation, 4 missing data); .vtu keeps all of them. Also available headlessly as mesh_derive with kind: "streamlines", which shares the numerical core.
Data table

Every node, element, condition or geometry as a row of plain values — the id, the coordinates (nodes) or the block and connectivity (entities), optionally the SubModelParts it belongs to, and every field defined at it. A vector field splits into NAME_X/NAME_Y/NAME_Z columns (a wider one, such as a Hessian, into NAME_0…NAME_n), and a field that does not cover a row leaves the cell blank rather than showing a zero the mesh does not carry.
Clicking a row highlights and frames that entity in the 3D view, so a number in the table can be found in the mesh without leaving the panel. The table paginates at 100 000 rows and renders only the visible window, so it opens on a multi-million-entity mesh as quickly as on a small one.
CSV and XLSX export always write the whole table, not the visible page. CSV is streamed, so it has no size limit beyond your disk; XLSX is capped by Excel's own worksheet limit (1 048 576 rows) and tells you when it had to leave rows out. Coordinates export at their true float32 precision rather than the 0.10000000149011612-style expansion a naive conversion produces. Also reachable from the Command Palette (Kratos Mesh: Export Data Table) and from the mesh_export_table MCP tool.
Export skin
Extracts the boundary of the mesh's volume cells (plus any pre-existing surface cells) as a standalone surface mesh and writes it to a file of your choice, via the same format picker as File ▸ Export. Unlike meshio++'s own surface/skin extractors, this is a native boundary-face walk — a face seen by exactly one cell is boundary — so SubModelParts survive the extraction, narrowed to node membership (element/condition membership cannot follow, since the skin's faces get fresh entity ids with no correspondence to the source mesh). Also reachable from the mesh_extract_skin MCP tool.
Simplify surface and Level of detail
Advanced ▸ Tessellate curved cells… writes a linear copy of the mesh's quadratic cells (6-node triangles, 8/9-node quads, 10-node tetrahedra, 27-node hexahedra, 0–5 levels): the open mesh keeps its curved cells and every cell of the copy carries SOURCE_ENTITY_ID; mesh_derive (kind: "tessellate") is the headless route. A .vtu or meshio++ polyhedron is still drawn as the tetrahedra it is decomposed into, but its original faces are remembered and the .vtu writer emits the real polyhedron again until an edit changes the mesh. Advanced ▸ Simplify surface… writes a decimated copy of a triangle surface (quadric-error edge collapse): boundary and crease vertices are pinned, surviving faces keep their entity ids, property ids and cell-field values, and the report gives the reduction and the largest collapse error as a share of the bounding-box diagonal. View ▸ Level of detail draws a decimated surface in place of the full layers to keep a huge mesh navigable — the mesh is untouched and picking is off while it shows. mesh_derive (kind: "decimate") is the headless route.
Sample to grid
Advanced ▸ Sample to grid… (or Kratos Mesh: Sample to Grid) samples the surface — or the boundary skin of a solid — onto a regular lattice and writes it as a new file: a voxel occupancy (cells whose centre is inside the surface, with a VOXEL_OCCUPANCY 0/1 field) or a signed-distance volume (the distance to the surface at every lattice point, negative inside, as SDF_DISTANCE). It asks for the cell size, shows the cell count and memory it implies before anything is allocated, confirms above five million cells and refuses beyond twenty million. A complete lattice can be written as .vti — the only container that keeps the sdf:* header (origin, spacing, dimensions) — while a partial voxelization or an octree goes to .vtu or another cell format. This complements the Signed distance operation, which samples only the open mesh's own nodes. The same builders are the grid, voxelize and sdfVolume kinds of mesh_derive.
Octree volume mesh, CAD face meshing and generated meshes
Advanced ▸ Sweep, mirror and layers… runs one of the meshio++ 17.23.0 kernels on the open mesh and writes a new one: extrude and revolve sweep a line or surface mesh into hexahedra or wedges, mirror reflects it in a plane, boundaryLayer grows prism layers of a chosen first height from a closed skin, tetrahedralize fills a skin with tetrahedra (the native octree mesher here, as Netgen is not built in), errorSize turns an error array into a size field and checkConformity counts hanging nodes and T-junctions. Options are the kernel's own, edited as JSON; the same kinds are in mesh_derive. meshio++ 18.1.0 adds convexHull (a closed hull surface, or a loop in 2-D, with each vertex's input node in SOURCE_NODE_INDEX), delaunay2d, reconstructSurface (a surface through an oriented point cloud), estimateNormals and parameterize (a UV atlas, kept as the 2-component nodal field UV because the model has no texture-coordinate slot). meshio++ 18.3.0 adds cutLevelSet (keep the part a level-set point field selects, e.g. phi < 0, cutting cells exactly) and cutQuadrature (that part's quadrature rules as a point cloud with QUADRATURE_WEIGHT and friends); both need the full meshio++ artifact. For a STEP/IGES input, mesh_info and mesh_convert take cadRead (deflection, angularDeflection, heal, sewTolerance) to control the triangulation and heal the shape before it is read.

The seven in-place operations of 18.1.0 — Untangle, Morph, Register (rigid ICP), Geodesic distance, Surface eigenmodes, Cylindrical / spherical components and Prepare MMG metric — are forms in the Mesh Modification sidebar (Fields), commands in the command line and ops of mesh_transform; they keep node and entity ids, Properties, SubModelParts and fields. Compressed .gz and single-file .zip meshes are read by the headless readers (mesh_info, mesh_convert, …), and a length unit a file states (STEP/IGES: mm; UNV, CGNS, MED) becomes the model's coordinate unit.
Advanced ▸ Octree volume mesh… meshes the inside of the surface (or of a solid's skin) on a balanced octree as tetrahedra, hexahedra or castellated hexahedra (meshio++ 17.13.0), Mesh CAD faces… triangulates the faces of an open .cad.json/STEP B-rep into one conforming surface with a SubModelPart per face (an optional JSON prompt adds meshio++ 17.21.0's minimum-angle refinement and smoothing, curved order: 2 elements, curvature / gap / per-face / per-edge / background sizing and a report of what each did), and Generate mesh… writes a procedural mesh (rectangle, box, disk, spheres, cylinder, annulus, L-shape, plate with a hole, honeycomb…) from nothing. All three are exports, never edits of the open mesh, and mesh_derive reaches them as octreeMesh, octree, cadSurface and generate. Segment surface patches and Refine patches (Mesh modification) label the smooth patches of a surface as a SEGMENT_PATCH field and refine them until a plane, sphere, cylinder, cone or torus explains each. The .step export's fit also accepts meshio++ 17.13.0's freeform options (freeformMode, extraordinaryVertex, …) and the report states the freeform census. See the guide.
Export partitions and Split mesh
Advanced ▸ Export partitions… writes the mesh as N per-part files plus a manifest, with optional ghost layers: every cell is owned by exactly one part, each part is rebuilt natively from the source cell ids so ids, kinds, Properties, SubModelParts and fields all survive, ghosts are flagged (PARTITION_GHOST, a Ghost SubModelPart, PARTITION_INDEX = the owner), and the manifest lists interface nodes and imbalance. Split mesh… writes one file per connected body, element type or field value. The cut is a space-filling curve by default, or KaHIP (minimizes the edge cut; offered in the prompt and as method: "kahip" in MCP). Both are the mesh_split MCP tool.
Sphere / particle elements

Peridynamics and DEM meshes are made of one-node elements — Exodus writes them as SPHERE, Kratos DEM as spherical particles. They have no extent, so by default they draw as fixed-size screen points, which tells you nothing about how big the particles actually are.
The Spheres toolbar button renders them as real spheres instead, scaled in model space so they behave like geometry under zoom:
- RADIUS field — when the mesh carries one (an Exodus per-element
RADIUS attribute arrives as an Elemental field of that name), every particle is drawn at its own radius, and the rendering turns on automatically.
- Constant radius — most particle files carry no radius at all. The panel suggests one (half the median nearest-neighbour spacing, so touching particles read as touching) and you can override it.
- Scale, detail (sphere tessellation) and optional colour by radius.
- Write to mesh turns the constant into a real
RADIUS field. It is a normal, undoable mesh operation, so it saves, exports and appears in a saved recipe — also reachable from the Set element radius form in the Mesh Modification sidebar (which can also scale existing radii, and can target a single SubModelPart), and from the mesh_transform MCP tool.
Exporting such a mesh to .exo writes the radius back as an Exodus element attribute; exporting to .mdpa writes a Begin ElementalData RADIUS block.
Beam / line elements

A frame or a truss is made of line elements with a cross-section. They have no extent either, so by default they draw as fixed-width screen polylines — a 6 mm tie rod and a 600 mm girder look identical at every zoom.
Advanced ▸ Beams… draws them as real tubes, scaled in model space:
CROSS_AREA from the Properties block — where Kratos actually keeps a member's section. The drawn radius is the circular-equivalent sqrt(A / π), resolved per cell (repeated Begin Elements blocks merge into one layer, so a single layer routinely holds members on several properties). An ElementalData CROSS_AREA field is used when Properties carry none.
- Constant radius — a twentieth of the median element length, for a mesh that declares no section.
- Thickness multiplies the radius only, never the length, so a member never detaches from its end nodes. Plus tessellation and optional colour by section.
Volume view
A mesh that is a dense regular lattice (a .vti file, or a grid from Advanced ▸ Sample to grid…) can be shown as a volume with an editable opacity curve, three orthogonal slices or marching-cubes iso surfaces from Advanced ▸ Volume view…. It is display only; Surface brings back the ordinary view. See the Volume View guide.
A line cell is also the shape a 2D boundary takes, so the rendering only turns itself on when the mesh gives it a reason to: the section must be a real CROSS_AREA, and only Elements count towards enabling it — a LineCondition2D2N skin that happens to share a structural part's property id never flips it on. Draw such conditions deliberately with Line conditions.
The section is read, not written: it belongs in Properties, which a Save emits from the model. mesh_info reports a properties section with the parsed values, and a beams section describing the line cells. See example/MDPA/portal_frame.mdpa.
Known limitations
- MPI rank > 0 files are not merged in this release (rank-0 files are loaded).
- Submodelpart merging uses coordinate matching (
toFixed(6)); if the root and subpart files were written at different float precision the merge may miss nodes (a diagnostic is emitted in the sidebar stats).
MCP server
The extension ships a standalone MCP server (dist/mcpServer.js) that exposes its mesh and simulation-setup engine to any MCP client (Claude Code, Claude Desktop, …) — no VS Code needed. Build it once with npm run compile, then register it, e.g. with Claude Code:
claude mcp add kratos-mdpa -- node /abs/path/to/VSCode-MDPA-Preview/dist/mcpServer.js
or in a generic client config:
{ "mcpServers": { "kratos-mdpa": { "command": "node", "args": ["/abs/path/to/dist/mcpServer.js"] } } }
Complete MCP tool reference
Export reporting: single-mesh write tools, including mesh_compare with outputPath, return report and accept provenance / verify. mesh_split manifests contain per-file reports; mesh_batch_transform entries persist their report across resume. mesh_pack_series / mesh_resample return compact per-step reports, with one collection sidecar when requested. Structured VTI and temporal XDMF do not borrow unstructured/single-mesh fidelity claims. problem_pack embeds a provenance/recipe/hash record (none opts out). See Export Report & Provenance.
| Tool |
What it does |
mesh_info |
Parse any supported mesh (.mdpa, VTK family, .stl/.obj/.ply, and the extended meshio++ formats) and summarize nodes, blocks, SubModelParts, fields (each with its true min/max value and the entity id holding it), diagnostics. Named groups from formats that carry them (gmsh physical groups, Abaqus sets, Exodus blocks/node sets/side sets) appear as SubModelParts. inputFormat forces a reader no extension defaults to (ansys, freefem, ansysinp). timeStep selects a step of a multi-step mesh (Exodus, MED since meshio++ 9.9.0, GiD postprocess, CGNS/Tecplot since 11.3.0, XDMF, VTKHDF, ParaView .pvd, OpenFOAM time directories); the response then includes timeStep/timeValues (Exodus, GiD, MED, CGNS, Tecplot, XDMF and OpenFOAM list theirs). metadataOnly skips parsing and reports the file header (counts, block shapes, data-array names, regions, bbox) for the formats whose reader stays header-only (.xdmf/.xmf, .msh, .med, .cgns, .dat/.tec, the GiD .post.* set) — anything else is refused rather than served at header price. An OpenFOAM case is opened through its .foam marker, like any other path. piece reads one piece of a .pvtu/.pvtp and dropGhosts (default true for those two) drops cells duplicated at partition seams; region reads one region of a multi-region OpenFOAM case instead of merging them all. fields reads only the named point/cell data arrays of a meshio++ format (honoured by XDMF and Gmsh; other readers return everything and say so). summary is the universal counterpart: it reports the file shape for every supported format, including .mdpa and the natively-parsed VTK/STL/OBJ/PLY, and never refuses for ineligibility — it reports cost instead (header a bounded read, scan a whole-file stream that builds nothing, buffered/read the meshio++ paths that hold or parse the file), with bytesRead saying what it actually took and unknown naming what the format cannot report so a blank is not read as a zero. A mesh with one-node (sphere/particle) elements also reports a spheres section — how many, whether they carry a RADIUS, and a suggested radius if not. An .mdpa that declares Begin Properties also reports a properties section with the parsed values, one that declares Begin Constraints a constraints section (per block: name, variables, row count and id range, plus undefinedIds — constraint ids a SubModelPart lists that no block defines), and a mesh with line cells a beams section (how many carry a CROSS_AREA, and how many of those are Elements rather than boundary conditions). A .med file also reports a source section with its own mesh name, description and units — coordinate, time and per-field — when the file actually sets them |
mesh_quality |
Geometric quality metrics (edge ratio, angles, gradation) with Kratos thresholds and worst-element ids, plus a watertight section: how many boundary edges (holes), non-manifold edges, inconsistently wound face pairs and zero-area faces — the counts rather than a bare flag, since three boundary edges is a pinhole and three thousand is a surface that was never closed |
mesh_size |
Nodal size (NODAL_H, a port of Kratos FindNodalHProcess) + element size (mean edge length), with box-whisker statistics and the IQR-outlier smallest/largest element ids |
mesh_field_integrate |
Cell-measure-weighted total and mean of the cell fields — a density field's total mass, a flux field's total power, an occupied volume — for the whole mesh and per named region, which here means one row per entity block and one per SubModelPart. Regions overlap rather than partition, so their totals need not sum to the domain total. revolveAbout (x/y, explicit, planar xy meshes only) weights each cell by 2πr for axisymmetric results (a Nodal field is accepted too, with exact lumped nodal weights that stay positive on the axis) and labels the answer "revolved about …"; without it the integral is the plain r-z plane one |
mesh_curvature |
Discrete mean / Gaussian / principal curvature statistics of a surface mesh, the Gauss–Bonnet check (angle-defect sum vs 2πχ), boundary / isolated / degenerate node counts and orientation warnings — read-only; mesh_transform's curvature op writes the fields |
mesh_graph |
The connectivity graph of a mesh (meshio++ 18.1.0): kind node (nodes joined by a cell edge), clique (nodes sharing a cell — the FEM sparsity pattern) or cell (cells sharing a facet). Returns vertex and edge counts, the degree range and the bandwidth of the current numbering; with outputPath writes a METIS (.graph) or Scotch (.grf) file for a partitioner. Read-only. |
mesh_intersections |
Where a surface mesh intersects itself, or with otherPath where two surfaces interpenetrate or touch (exact triangle–triangle tests, meshio++ 18.0.0): clean, pair / coplanar / segment counts and the entity ids of the facets involved (capped by idLimit) — read-only; mesh_derive kind findIntersections writes the intersection curve as a line mesh |
mesh_fit_primitives |
Names the boundaries of a surface mesh by shape: segments it into patches (unless SEGMENT_PATCH exists) and reports per patch the plane / sphere / cylinder / cone / torus it matches, its radius and axis, and the fit residual; outputPath writes the integer FIT_PRIMITIVE field. |
mesh_ale_quality |
Mesh validity over a moving-mesh (ALE/FSI) series: per frame, every Element on its deformed coordinates (default MESH_DISPLACEMENT) against the same element at the first frame — signed measure ratio, shape ratio, inverted count and ids, and the worst frame. .csv output. |
mesh_recover_flux |
Per-area traction / heat flux recovered on a SubModelPart's faces from nodal reactions (consistent boundary-mass projection, CG); its integral equals the reaction sum. Derived field <VAR>_RECOVERED; outputPath writes it. |
mesh_compare |
Compare two meshes and their fields by entity id: a verdict (identical / equal within tolerance / different), moved nodes with the worst id, entities only in one mesh or with changed connectivity or type per kind, block-name and SubModelPart-membership differences, and per-field max / mean / RMS / relative error with coverage gaps counted (never compared as 0). With variable it also compares one field — by id, or by spatial point sampling of the other mesh's nodal field — and with outputPath writes the difference mesh (<name>_DIFF, _ABS, _REL). A field read from an OpenFOAM case carries its dimensions vector: mesh_info reports dimensions and unit per field, and the series, probe and table CSV headers gain [unit] only for such fields. When both fields state their dimensions and they differ the comparison is refused (naming convertFieldUnits); if one side is unknown it proceeds and says so. |
mesh_derive |
Write a new mesh derived from the opened one (nothing is written back to the input): a slice through a plane, the isosurface of a nodal field, a threshold region where a field lies in an absolute or normalized window, a decimated copy of a triangle surface, a linear tessellated copy of the curved cells (kind: "tessellate", levels 0–5, children tagged with SOURCE_ENTITY_ID), or a regular sampling of it — grid (a lattice from nothing, no input mesh needed), voxelize (occupancy) and sdfVolume (signed distance, dense or octree), sized by cellSize or resolution with a memory estimate and a 20-million-cell refusal before anything runs; a complete lattice can be written as .vti. Slices and isosurfaces carry the interpolated fields and tag every cell with the cell it was cut from (SOURCE_ENTITY_ID / SOURCE_ENTITY_KIND); a threshold region keeps original ids, groups, fields, Properties and the conditions still on it, or returns its boundary surface. Normalized windows need an explicit fixed reference range — rescaling per frame is opt-in kind: "streamlines" traces STEADY streamlines of a Nodal vector field variable (RK4 in arc length through a pure-JS locator, no meshio++) from seedPoints, seedLine, seedPlane or seedPart (exactly one), forward/backward/both, bounded by maxSteps/maxLength/maxSeeds (more seeds are refused, not truncated), in the frame timeStep selects, and writes line cells with STREAM_SPEED/VELOCITY/ARCLENGTH and per-segment STREAM_LINE/SEED/DIRECTION/TERMINATION; every line ends for a stated reason and the reply lists the seeds that gave no line. kind: "cadSurface" triangulates a .cad.json (or STEP/IGES read) B-rep into one surface mesh of edge length targetSize, and cadOptions (meshio++ 17.21.0) adds minAngle refinement with smoothIterations/lopCorners, order: 2 curved triangle6/line3 elements (order 3 is refused), curvatureDeviation/cellsAcrossGaps/grading sizing, faceSizes/edgeSizes, a backgroundPath size field, and the reply carries a structured cadSurface report (angle histogram, the bound met or the corners that prevent it, edges limiting the size, merged/reparametrised faces, lopped corners). Since meshio++ 17.23.0: kinds extrude, revolve, mirror, boundaryLayer, tetrahedralize, errorSize and checkConformity (kernel options in options), 21 more generate shapes with a complete flag, voxelize plane, and cadOptions untangle/quads/quadPairs/metricBackgroundPath. |
mesh_select |
Evaluate a selection predicate over a mesh and return the entity ids per kind (Elements, Conditions, Geometries each keep their own id space): seed by SubModelPart subtree, by a field's [lo, hi] window (the viewer's Threshold cells, with the same all/any rule), by a quality metric (bad / unacceptable elements) or by property id — the feed for mesh_transform's assignProperty / createSubModelPartFromSelection / deleteEntities; outputPath writes the uncapped ids as JSON |
mesh_periodic |
Match periodic SubModelPart nodes under an affine transform: every node of the slave part is mapped into the master part's frame and paired with its nearest match within atol. Exactly one of matrix, translate or rotate. Reports original node ids with residuals; requireComplete refuses partial sets; CSV export. Same core as Advanced ▸ Mesh analysis and region tools |
mesh_probe |
Sample a nodal field along a polyline — distance-versus-value rows with a gap (null) wherever the path leaves the mesh or crosses a region the field was never written, never a fabricated 0 — optionally across every step of a time series, with CSV output |
plot_table_read |
Inspect CSV/TSV with delimiter/header correction, numeric-column mapping, supplied units, missing-value diagnostics and source revision; paginated JSON, without a mesh |
plot_runs |
Discover saved/tracked run records from explicit paths/directories without adopting unresolved shared outputs or consulting the active case |
plot_run_bind |
Pin a terminal isolated result by existing run/study/request identity and SHA-256 source-mesh/rank/timeline/recursive-companion revisions; OpenFOAM/Elmer/MFEM directory sources also require a frozen complete inventory revision; changed or unresolved ownership is refused |
plot_time_cursor |
Resolve supplied physical time in the verified owning run using exact or tolerance-bound nearest matching; no equal-distance choice, invented unit/entity correspondence or preview redirection |
plot_run_target |
Resolve the exact verified owning source/rank/frame and original-association entity or SubModelPart; no active-preview fallback or cross-mesh correspondence |
plot_preset |
Build (and optionally evaluate) a named plot recipe: section comparison over time, measure-weighted Elemental total, tensor components / invariants (from a supplied layout), heat-flux balance, table-column relationship; optional user-supplied threshold check and from − to section differences |
plot_dataset |
Evaluate a version-1 plot recipe with shared extraction, statistics, ordered transformations, reference alignment and masked gridding; bounded JSON samples or full-resolution CSV plus .kratosplot.json provenance; cancellable worker |
mesh_flow_balance |
Signed boundary flow balance: the flux ∫u·n dA through each named SubModelPart of Conditions (positive = out of the domain, so an inlet reads negative), the area-weighted mean of a nodal pressure on each, net flux, imbalance = net / max(inflow, outflow) (null with a reason when there is no flow) and an optional pressureDrop between two sections in the field's own units. orientation outward (default) flips each facet away from the Element it belongs to and excludes facets it cannot orient or that are internal; winding trusts the file. A corner with no value is a gap, reported as uncovered area, never 0; higher-order facets integrate as their linear skeleton and say so; 2D meshes give flux per unit depth; mass flux needs an explicit density. pressureDensity additionally reports means/drop in Pa for a kinematic-pressure field only. allSteps repeats over the whole series; outputPath writes a .csv |
mesh_split |
Split one mesh into several files that keep the source's ids, kinds, Properties, SubModelParts and fields: partition writes N per-part meshes with optional ghost layers (every cell owned by exactly one part, ghosts flagged, weights by an elemental field, interface nodes and imbalance in the manifest — method: space-filling curve by default, kahip to minimize the edge cut, auto for KaHIP when available), or component / type / field split into connected bodies, element types or field values |
mesh_transform |
Honours the client's request cancellation and sends notifications/progress when a progress token is supplied (as do mesh_batch_transform and mesh_derive). Apply a sequence of mesh operations (scale/translate/rotate, merge nodes, remove orphans, linear→quadratic, delete/rename SubModelPart, reorganize the SubModelPart tree (create / move / merge / add / remove entities), write mesh-size fields, set/scale the sphere-element RADIUS, MMG remesh & level-set split, smooth, reorder, partition, refine, simplexify, linear→linear-only (quadratic→linear), crop, field calculator + nodal/elemental averaging, field gradient/divergence/curl, field Hessian, Zienkiewicz-Zhu error estimate, signed distance to a surface (an imported file, or a SubModelPart already in the mesh), mass-preserving field transfer from another mesh, merge another mesh file, Properties authoring (setProperty / createProperty / cloneProperty / assignProperty / deleteProperty), and selection-driven edits (a SubModelPart built from a selection — explicit per-kind id lists or a seed resolved against the mesh at apply time — or deleteEntities, the same ids as one undoable delete)) inline or from a saved Edit-sidebar recipe — returns an export report (what each kind of data did: retained / transformed / omitted / unverified); provenance (auto / sidecar / none) and verify (re-read and grade the report) |
mesh_batch_transform |
Apply one recipe to many meshes — explicit paths or a filename series (seriesOf). Sequential and explicit; the output plan (deterministic naming template) is refused whole if any output would overwrite an input, another output or an existing file; a failing file is recorded and the rest continue; <outputDir>/kkss-batch.json is a resumable manifest (resume skips files already done with an unchanged input); dryRun returns the plan only |
mesh_convert |
Convert between formats — ours (.mdpa, .vtk, .vtu, .vtp, .stl, .obj, .ply) plus ~45 written by meshio++ (.msh, .inp, .bdf, .unv, .mesh, .vol, .su2, .xdmf, .off, .poly (Triangle), .xml (DOLFIN), .ele (TetGen), .case (EnSight Gold), .vtkhdf, .pcd, .xyz, .k (LS-DYNA), the HDF5 containers .cgns/.h5m/.hmf/.med, plus the field-only .dex/.ip/.mff and write-only .svg/.tikz figures, …); plus .e/.exo/.ex2 (Exodus, lossy — see the format table). inputFormat/outputFormat override the extension defaults; timeStep selects a step of a multi-step input (Exodus, MED, GiD postprocess, CGNS/Tecplot, XDMF, OpenFOAM time directories). piece, dropGhosts, region and fields select the input as for mesh_info. Writing .xdmf also emits a companion <stem>.h5; writing .xml/.ele/.case refuses with a named reason when the mesh has no representable cells (see the format table) — returns an export report (what each kind of data did: retained / transformed / omitted / unverified); provenance (auto / sidecar / none) and verify (re-read and grade the report) |
mesh_extract_submodelpart |
Slice one SubModelPart (+ subtree) into a standalone file — returns an export report (what each kind of data did: retained / transformed / omitted / unverified); provenance (auto / sidecar / none) and verify (re-read and grade the report) |
mesh_extract_skin |
Extract the boundary skin of a mesh's volume cells (+ any pre-existing surface cells) as a standalone surface mesh — a native boundary-face walk, so SubModelParts survive (narrowed to node membership) — returns an export report (what each kind of data did: retained / transformed / omitted / unverified); provenance (auto / sidecar / none) and verify (re-read and grade the report) |
mesh_field_series |
One entity's value for one variable across every step of a time series — the headless mirror of the viewer's Plot over time, and the only tool that reads a value across steps. Steps are discovered from a single path exactly as the preview does (a sibling <prefix>_<rank>_<step> series (VTK, STL/OBJ/PLY and meshio formats without an in-file timeline), an in-file series such as Exodus/GiD/XDMF/OpenFOAM, or a lone file), and source reports which was found. A gap is null, never 0, with missingField and missingId counted apart; topologyChangedAt warns that the mesh changed size mid-series. Writes a .csv when outputPath is given |
mesh_export_table |
Tabulate every node/element/condition/geometry as rows of plain values — id, coordinates or block+connectivity, optional SubModelPart membership, and every field defined there. The only tool that reports field values (mesh_info reports field metadata; mesh_find_entity answers for one id). With outputPath it writes the whole table as .csv/.xlsx; without one it returns limit rows from offset as JSON (default 100, max 10 000). submodelpart restricts rows to one part and its subtree |
mesh_pack_series |
Packs a solver run's per-step mesh files into one time-series container. path is the vtk_output directory or any one step file; steps are found the same way the preview finds them (<prefix>_<rank>_<step>), and the step label becomes the time, so the axis carries the Kratos step numbers rather than 0..N-1. Not mesh_convert with outputFormat: xdmf — that writes ONE mesh, this writes every step. target picks the container and the choice is semantic: "xdmf" (default) writes one .xdmf plus its sibling .h5 (part of the output, not an extra) and therefore refuses a series whose mesh changes between steps, because a time series carries one grid for all steps; "pvd" writes a .pvd index plus a directory of one file per step, each with its own mesh, which is the container for a remeshed or adaptive run — it needs no mesh-format kernel, copies a step's bytes when they are already VTK XML, and can also repack a source that already carries its own steps (Exodus, GiD, a packed XDMF or .pvd). It will not overwrite an existing .pvd or its directory. Both containers stream one step at a time, and the result re-opens in the preview as a timeline. |
mesh_resample |
Export a resampled timeline as .pvd (plus one .vtu per new step) or a single .vtu: explicit times or a range, linear / previous / nearest methods (linear needs matching topology), integer fields never blended, unknown fields named in continuousFields, extrapolate: "error" by default. Sources never modified; per-frame export reports |
mesh_find_entity |
Locate a node/element/condition/geometry by id (coordinates, connectivity, owning SubModelParts) |
mesh_capabilities |
meshio++ capability inventory: the installed WASM build's readers/writers, per-reader options-awareness, backend and cgnslib — next to the extension's routing (read candidates, write targets, in-file vs filename timelines, header-only metadata set, unrouted keys with reasons) and a fidelity section (the carry/adopt adapter's carrier keys, SubModelPart region prefix, and which model slots it retains). Takes no arguments and an exportFidelity section (what each writer was measured to keep), plus a runtime section reporting how THIS server process was wired — where the kernel tree was resolved (node_modules vs the bundled copy) and, per MMG/oracle/derived/read/write, worker or in-process — so a packaged distribution that lost a file shows up instead of silently falling back (npm run check:staged runs the server from a staged copy and asserts it) |
problemtype_list / problemtype_describe |
Enumerate built-in + workspace problemtypes (with their family, domains and collections); get the full form/condition/material/collection spec plus a default case skeleton |
case_run |
Start a Kratos solve (generating the case files first unless told not to). The solver is always spawned detached, with its output appended to <stem>.kratosrun.log, so it outlives the MCP server — which cannot own a run, since its stdout is the protocol channel. Optional threads is applied and read back through Kratos ParallelUtilities before MainKratos.py starts; a mismatch fails before analysis construction and the execution receipt records requested/effective counts. Owned queue runs also retain revisioned outputs and configured-output findings. waitSeconds (default 10, 0 = don't wait) blocks for the exit; expiry is not an error but a handoff, returning running with the pid and log path, since the only applicable timeout belongs to the client and the server cannot observe it. Refuses to start over a run that may still be active unless forced. python / installPath / extraEnv are arguments, defaulting to a pip-installed Kratos. Before starting, it asks python whether every Kratos application the case needs (recorded in kkss-preparation-v1.json) can be imported and refuses naming the missing ones; when that probe cannot answer, the run starts and the generated driver's own check (exit code 3) stands behind it. requestId + ownerId + runDirectory snapshots the mesh and case state into that fresh directory and writes the durable receipt a retry resolves; isolate: true plans <case folder>/runs/<stem>-<requestId> itself, the default layout kratos.run.isolate uses. |
case_compare |
Compare two saved isolated runs by their own evidence — execution receipt and kkss-preparation-v1.json — never by matching file names, so cases sharing a source folder cannot be confused. Reports both identities, whether they share source-mesh revision / problemtype / settings / CAD export revision, each differing setting as a dotted path with both values, per-role artifact counts, artifacts only one side has, outputs whose frozen revision differs, and paired outputs neither side pinned a revision for (unverified, never reported as unchanged). comparable: false names why (not terminal, no receipt, same directory); it never upgrades a legacy receipt by hashing today's bytes. |
case_run_quantity |
One monitor evaluated once per isolated run: a row per run with the case settings that differ between runs as columns and the monitor's final value — a parameter sweep as a table. .csv output. |
case_stop |
Stop the latest run by the pid in its sidecar. First writes the cooperative stop file (<stem>.kratosstop) that a case generated by this extension watches between solution steps, so the solver finalizes and closes its last result file on every platform, Windows included; if it does not answer within the grace period (or the script predates the file) it escalates SIGINT → SIGTERM → SIGKILL (Windows: immediate terminate — signals are not real there). Reports which rung worked (outcome / stopRung) — SIGINT is what lets python close its last result file rather than truncate it. Records the stop before signalling so it reads cancelled, not failed. A run that already ended is never signalled, since pids get reused |
wind_tunnel_plan |
Plan a virtual wind tunnel around a body surface without meshing anything: the body as measured (size, frontal area, whether it is closed), the tunnel extents and blockage, the flat-plate boundary layer (Reynolds number, friction velocity, first-cell height for a target y+, layers), the cell sizes, an estimate of tetrahedra, memory and time, the ordered steps, warnings and errors (a plan with errors cannot run). Read-only. |
wind_tunnel_generate |
Build the tunnel: a graded background lattice, distance-driven refinement with a wake box, a level-set carve of the body, the named parts (Fluid, Body, Inlet, Outlet, Floor, Ceiling, SideLow/SideHigh or Symmetry), a stretched-tetrahedron wall layer (remesh mode wall), hard mesh checks and a measured wall fit — or, in embedded mode, the unfitted lattice with the signed DISTANCE. Writes <stem>.mdpa, the placed <stem>_body.stl, <stem>.kratosvwt.json (parameters, report) and the prepared Fluid (or Embedded Fluid) case <stem>.kratoscase.json; with generateCase also the solver files. Refuses to overwrite unless overwrite; reports progress and stops between steps on cancellation. |
case_convergence |
The solver convergence history of a case, read from the kkss-convergence-v2.jsonl the generated MainKratos.py writes: per-step residual norm, convergence ratio, nonlinear iteration count and the solver's own converged flag, with CSV output. Progress, completion, per-step convergence and the verdict are reported apart; the verdict is conservative — converged needs a completed run, a run with no end record is incomplete, a solve-hook exception is solver-error (an unknown outcome, never proof of divergence), and a residual the solver did not publish is null, never 0. case_status carries a compact copy |
case_export_results |
Convert a case's solver output (vtk_output/) to other meshio++ formats: one file for .xdmf/.pvd, one per step otherwise; defaults to the case's saved exportFormats. |
case_optimization |
The progress of a Structural Optimization case, read from the per-iteration summary the OptimizationApplication's ascii output process writes (the file optimization_parameters.json names, summary.csv by default): the formulation, the objective's current value and change since the first iteration, each constraint's value and standardized value (satisfied when ≤ 0, unknown when the column is absent), and a verdict — finished, stopped (a cooperative stop finalizes the run), running, incomplete (no end-of-file marker: killed or crashed) or no-data. Columns are classified by the case's own response names. Bounded rows (limit, default 200) or every row as .csv. case_status carries a compact copy |
case_optimization_cad |
The optimized geometry of a Structural Optimization case as STEP: the latest finished design-field frame through the .step pipeline (shape writes the frame mesh; topology contours densityField at threshold, default 0.5, averaging an Elemental field to the nodes). fitCad as in mesh_convert, outputPath defaulting to <case>_optimized.step, excludeNewest dropping a possibly half-written newest frame |
case_rom |
The results of a reduced-order model case: modes from rom_data/RomParameters.json, the singular-value decay, the HROM element and condition ids (Kratos entity ids), the sampled parameters from RomSamples.json, the per-analysis progress the generated driver records and its end summary. A stopped run is reported as a partial database. Lists bounded by limit. case_status carries a compact copy |
case_monitors |
Saved post-run monitors of a case, stored in <stem>.kratosmonitors.json: a point value of a field at one entity or a regional quantity (min, max, mean, sum, boundary mean or integral, pressure force or moment, flux, reaction moment) over a SubModelPart. Actions list, set, remove and evaluate; evaluation reads the case's current saved result frames with the plotting library's extraction, supports stride thinning and a unit label, returns bounded rows or a full .csv, and reports a missing field, entity or frame as a null gap, never 0. A point source interpolates a Nodal field at fixed coordinates. Not a live solver monitor; it makes no run-ownership claim unless a run binding from plot_run_bind is passed with resultPath, which is then verified. |
case_status |
The latest Kratos run for a mesh: status, exit code, command, pid and a summary discovered from ProjectParameters.json output-process settings. Reports VTK, XDMF/HDF5 and GiD result entrypoints, companions, missing files, unknown output processes and unsafe destinations; legacy cases without output settings retain the documented vtk_output/ fallback. Reads the <stem>.kratosrun.json sidecar, so either side can see what the other started — and reconciles it against the OS rather than repeating it, so a stale record whose process is gone reads orphaned and one whose pid is alive reads detached, never running |
case_validate / case_write_state |
Preflight a case setup against mesh + problemtype as structured findings (severity error/warning/info, a stable code, a target naming the SubModelPart / condition / law / Properties id); write <stem>.kratoscase.json (picked up by the sidebar). The check is a dry run of generation, so ok: true means the case generates — including unusable material values, bad fluid time-stepping values and coupled-domain interface problems. It adds computing parts with no material, empty / wrong-kind / unused SubModelParts, dangling or unused Properties ids and mesh-wide quality concerns (quality: false skips those). With checkInstall: true (and optional python / installPath / extraEnv) it also reports install.missingApplications, the Kratos applications the case needs that the given Python cannot import; applications lists what the case needs either way. solver reports the linear solver (resolved, estimated dofs, why) — automatic writes nothing to the JSON — and a solver-direct-large warning flags a direct solver on a large 3D case. For coupled problemtypes the interface sides must pair one-to-one, carry boundary cells of the right dimension and overlap. With wavelength (or frequency + waveSpeed, optional pointsPerWavelength) it returns wavelengthAdvice, the largest element size h ≤ λ/n that resolves the wave; nothing is inferred from the case. |
case_estimate_timestep |
Read-only convective time-step guidance dt = safety × Courant × h / \|U\| for a mesh: the length basis used (a thin smallest element switches to its shortest edge and says so; a mesh with no measurable elements falls back to bounding-box volume/diagonal per node and says so), flow-through time and, with endTime/outputInterval, step count, output frames and a rough storage range. Guidance, not a stability guarantee; zero velocity or no usable bounds is reported as unavailable. Apply a chosen step with case_write_state |
case_material_assign |
Fill one SubModelPart's material from a catalog preset or explicit values and write the case file. A preset is applied as a snapshot (resolved values + source + reference conditions), so editing the library never rewrites the case; μ = ρ·ν is derived exactly once and the conversions/derivations are reported |
material_preset_list / material_preset_import |
The material catalog — the rows shipped with the extension plus every workspace library file — listable, inspectable and filterable by law, and writable as an importable JSON file; import validates a preset file and installs it into the workspace library |
case_generate |
Write ProjectParameters.json, the materials JSON and MainKratos.py next to the mesh — same output as the sidebar's Generate button, including solver mesh-name adaptation (a non-.mdpa mesh is always converted to <stem>_case.mdpa first) |
problem_pack / problem_unpack |
Bundle the whole problem (mesh + edit recipe + case state + generated case files) into one zip, or extract such an archive — the same format as the File menu's Save problem… / Load problem… |
MMG operations run in-process and block the server while they run; progress is streamed as MCP log messages.
Develop
npm install
npm run compile # bundle extension (dist/) and webview (media/) via esbuild
npm run watch # rebuild on change
npm test # parser unit tests (node:test) against repo fixtures
npm run typecheck # tsc --noEmit
Press F5 in VS Code to launch an Extension Development Host, then open any .mdpa file (e.g. those under applications/*/tests/).
Layout
Project structure
| Path |
Purpose |
src/extension.ts |
Activation, command + custom-editor registration |
src/mdpaEditorProvider.ts |
Custom editor for .mdpa: parses the document, hosts the webview |
src/vtkEditorProvider.ts |
Custom editor for VTK/mesh files: discovers sibling files, manages timeline, merges subparts |
src/parser/ |
mdpaParser, meshFileParser (format dispatcher), vtkLegacyParser (ASCII+binary legacy VTK), vtkXmlCore/vtkXmlParser (VTK XML), vtkMultiblock (.vtm read), writers/vtmWriter (.vtm write), stlParser, objParser, plyParser, vtkFileGroup (filename grammar → timeline tree), geometryMap, meshQuality, isoSurface, dataTable (the data-table rows + CSV), paneLayout (split-view viewport rects), runCore/runFile/runProcess (tracked solver runs), recordPlan (video frame plans), fieldSeries/fieldSeriesScan (one entity's value across a time series), types |
webview/ |
main.ts (VTK scene), meshBuilder.ts, outline.ts, timeline.ts (VTK playback bar), qualityPanel.ts, fieldPanel.ts, fieldData.ts, fieldRender.ts, quiver.ts, colormaps.ts, orientationCube.ts (cube + axis arrows), navControls.ts (orbit/pan/zoom/fit/center panel), gridAxes.ts, dataTablePanel.ts, seriesPanel.ts, videoRecord.ts, recordPanel.ts, style.css |
src/mcp/, src/mcpServer.ts |
Standalone stdio MCP server (tool handlers over the pure modules + SDK wiring) |
syntaxes/ |
TextMate grammar for highlighting |
The Kratos name → VTK cell-type table mirrors the core kratos/input_output/vtk_definition.cpp and kratos/sources/kratos_application.cpp.
Third-party notices
Third-party components
Remeshing is powered by MMG through the unmodified @loumalouomega/mmg-wasm npm package (MMG v5.8.0 compiled to WebAssembly). MMG and mmg-wasm are licensed under LGPL-3.0-or-later and are consumed as a replaceable package dependency. If you use the remeshing features in academic work, please cite the MMG papers.
The experimental VTK-wasm renderer ships the VTK rendering engine compiled to WebAssembly, from Kitware's VTK-wasm distribution (VTK 9.7.20260920, fetched by commit and verified file by file). VTK is licensed under BSD-3-Clause; the notices of the third-party libraries compiled into the binary and of the Emscripten runtime are reproduced in media/vtk-wasm/THIRD_PARTY_NOTICES.md.
The Flowgraph node editor is provided by the @kratos-flowgraph/flowgraph npm package, licensed under AGPL-3.0-or-later. Its assets are bundled and served locally, embedded in the preview via an iframe. Because it is distributed as part of this extension, the combined work is licensed under the AGPL (see License).
License
This extension is licensed under the GNU Affero General Public License, version 3 or later (AGPL-3.0-or-later) — see LICENSE. It previously shipped under MIT; the change is required because it now bundles the AGPL-3.0 Flowgraph editor, and an AGPL component makes the combined work AGPL.
Under the AGPL's network-use clause (§13), users who interact with the software must be able to obtain its complete corresponding source. This is satisfied by the public repository at https://github.com/loumalouomega/VSCode-MDPA-Preview.
Extended mesh-format support (reading 82 and writing 83 formats) comes from @meshioplusplus/wasm 18.1.0 — meshio++'s C++ core compiled to WebAssembly, shipped verbatim under dist/meshio/ in two artifact pairs. The lean pair is licensed MIT AND MPL-2.0 — meshio++ 17.13.0 compiles Eigen into the lean build for the MED transpose, and Eigen's MPL-2.0 is file-level copyleft, so its own source stays available under that licence. The full pair (the one the CAD reads, the fitted STEP export and the codec fallbacks use) adds OpenCASCADE, Netgen and MMG (meshio++ 18.0.0 links the last two statically for tetrahedralize and the kernel's MMG operations) and is licensed MIT AND (LGPL-2.1-only WITH OCCT-exception-1.0) AND LGPL-2.1-only AND LGPL-3.0-or-later, the expression the package itself carries; MMG is linked without its GPL-3.0 ELAS library, so the kernel's move is unavailable. The extension's own in-place remeshing keeps using the separate @loumalouomega/mmg-wasm package. Both pairs' exact component list, versions and licences are reproduced in dist/meshio/THIRD_PARTY_NOTICES.md. New structural routes cover Code_Aster, Elmer, FEBio, Femap, libMesh, Marc reads, MFEM, COMSOL binary, Patran, Radioss reads, and Z88; bzip2 libMesh files are decoded in the host because the lean WASM build does not link bzip2.
Copyright © 2026 Vicente Mataix Ferrándiz and contributors.
KKSS preparation and convergence reports
Report contents and validation notes
Case generation writes kkss-preparation-v1.json beside the solver inputs. It
records effective parameters, case settings, source/solver mesh hashes, generated
input hashes, generator script identity and generation warnings. Paths are file
names relative to the report; undeclared units stay explicitly undeclared.
Unknown report versions are not overwritten.
Structural scripts write kkss-convergence-v2.jsonl from the AnalysisStage solve
hook verified against Kratos 10.4.3. Each record carries step/time, the actual
solve outcome, final nonlinear iteration, solver criterion, and ProcessInfo
RESIDUAL_NORM/CONVERGENCE_RATIO when published. The norm is criterion-dependent
and has no inferred unit. Exceptions are unknown outcomes, not proof of numerical
divergence. Successful finalization appends an end record; interrupted streams
have no completion claim. Older v1 consumers must upgrade before reading v2.
The built-in case generators are exercised by KKSS's geometry-to-results tutorials
against Kratos 10.4.3, including stationary heat conduction, uniform potential
flow, slip-wall channel flow and still water. Material numbers preserve Kratos'
real-valued JSON representation when their declarations require it.
| |