Skip to main content
Glama

Verify stress of a run

verify_run
Destructive

Verifies a finished run's final STL by meshing with quadratic tets and solving von Mises stress per load case, with optional stress-limit gate and mesh/memory estimates.

Instructions

Check the final STL of a finished run with quadratic tets (P2): von Mises stress per load case.

It is independent of the voxel optimizer: it meshes result/final.stl (part_only.stl with part_only) with tets (gmsh), clamps each fixed region (a joint or spring holds the part too), loads each load region with a traction (uniform per area, the resultant is the YAML force), and solves each load case alone (no case weights). Units: mm, N, MPa.

estimate_only: default True. It returns the estimates for each mesh size (memory in bytes, time in s per measured solver), the solver that would run, the extras and the RAM, and meshes nothing. Tell the user the numbers, then call again with estimate_only=false. A real run starts in the background and returns at once; verify_status shows it and gives the result. One verify job or optimizer run at a time: a second start is refused. allowable_mpa, percentile: your allowable stress, no default (ranges: topopt://materials/reference). It adds a limit block. exit_code is 3 if the percentile value (by volume, default 99.9) of a case is above it. With gate it replaces the YAML stress limits (a larger value loosens them: the user's consent). run_dir: the run folder (default: the last run that this server started). It needs run.json and result/final.stl. gate: true adds the key gate (met per check and case; exit_code 3 if it fails); limits: the YAML's, see topopt://levers/verify_run:gate max_gb: refuse above this memory estimate in GB; it also refuses above the available RAM. force: run anyway. On a wrong input or a run that cannot go on: {"ok": false, "error": ..., "exit_code": 1 or 2, "facts": ...} (exit_code 1: bad input, an unsolvable part, no usable solver; exit_code 2: a missing gmsh or scikit-fem, a meshing failure, a memory refusal, an empty region). p99.9 is the main number; the peak can move with the mesh at sharp features. A load patch can hold a large part of the top volume: read near_regions and load_band_sensitivity. mesh_size_mm: one mesh size. Default: the tet mesher size, about 1.3 to 2.2 voxels for an sdf STL. levels_mm: several sizes; the finest is the reference level; the result gets a levels block. region_band_mm: a mesh node belongs to a region when it is inside the region STL or within this band of its surface. Default: 0.5 voxel (counts_by_band: the counts at 0, 0.5 and 1 band). solver: auto (default: cholesky on macOS arm64, pardiso, cholespy, superlu) or a factor name. The result names the one that ran and those auto passed. yaml_path: the problem YAML, if the one that run.json names is gone (moved folder). near_region_mm: distance from a fixed or load region for the stress numbers without the region patches. load_sensitivity: also solve the load at bands of 0 and 2 times the band. part_only: mesh result/part_only.stl (the run needs regions.not_printed); a removed body becomes a boundary condition at its contact face, see topopt://levers/verify_run:part_only. Key: part_only.

Result keys (verify_status, when done): ok, exit_code (0 done, 3 limit failed), cases..von_mises.p99_9_by_volume_MPa. All other keys, and the keys that YAML blocks add (buckling.check, limits rows, bore_checks): topopt://levers/verify_run

Input Schema

NameRequiredDescriptionDefault
gateNo
forceNo
max_gbNo
solverNo
run_dirNo
levels_mmNo
part_onlyNo
yaml_pathNo
percentileNo
mesh_size_mmNo
allowable_mpaNo
estimate_onlyNo
near_region_mmNo
region_band_mmNo
load_sensitivityNo

Schema Changelog

Changes observed during successful MCP inspections.

  1. First observedv0.5.0

TDQS

A4.9/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Goes well beyond the annotations: discloses background execution returning immediately, exit-code semantics (0/3 done-or-limit, 1 bad input/no solver, 2 missing gmsh/meshing failure/memory refusal), a structured error envelope with a facts field, memory refusal via max_gb and force override, and that estimate_only meshes nothing. This is exactly the mutation/concurrency/resource context annotations alone cannot convey.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with purpose and the estimate-only workflow, and each block maps to a parameter or result concern, so little is wasted. It is however dense and telegraphic in places ('With gate it replaces the YAML stress limits'), which costs a little readability for an otherwise well-organized text.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a 15-parameter, no-output-schema, destructive-capable tool, the description supplies error shapes, result keys, exit codes, resource references (topopt://levers/verify_run) and caveats about p99.9 vs peak. No output schema exists, and the description compensates by naming the return keys the agent must read.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 0% across 15 parameters, so the description carries the full burden — and it does, explaining estimate_only, allowable_mpa/percentile semantics and the limit block, run_dir defaults, gate vs YAML limits, max_gb/force interaction, mesh_size_mm defaults, levels_mm reference level, region_band_mm membership rule, solver auto-passing, yaml_path fallback, near_region_mm, load_sensitivity bands and part_only's boundary-condition effect.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource (von Mises stress per load case on the final STL with quadratic tets) and explicitly distinguishes itself from the optimizer path ('independent of the voxel optimizer'). An agent can tell this apart from run_topopt and run_result without opening any schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives an explicit two-step workflow (call with estimate_only=true, report numbers, re-call with false), names verify_status as the follow-up for results, and states the exclusion 'one verify job or optimizer run at a time: a second start is refused'. Defaults for run_dir and prerequisites (run.json, result/final.stl) are also spelled out.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.