Loading...
Loading...
Orchestrate multi-simulation campaigns — generate parameter sweep configurations (grid, linspace, or Latin Hypercube sampling), initialize and track batch job campaigns, monitor job completion status, and aggregate results with summary statistics across all runs. Use when running a parameter study across dt, kappa, or other simulation inputs, managing dozens or hundreds of simulation configurations, combining outputs from completed batch runs to find the best result, or automating the generate-run-collect workflow for systematic studies, even if the user only says "I need to try many parameter combinations" or "how do I organize a sweep."
npx skill4agent add heshamfs/materials-simulation-skills simulation-orchestrator| Input | Description | Example |
|---|---|---|
| Base config | Template simulation configuration | |
| Parameter ranges | Parameters to sweep with bounds | |
| Sweep method | How to sample parameter space | |
| Output directory | Where to store campaign files | |
| Simulation command | Command to run each simulation | |
Need every combination (full factorial)?
├── YES → Use grid (warning: exponential growth with parameters)
└── NO → Is space-filling coverage needed?
├── YES → Use lhs (Latin Hypercube Sampling)
└── NO → Use linspace for uniform sampling per parameter| Method | Best For | Sample Count |
|---|---|---|
| Low dimensions (1-3), need exact corners | n^d (exponential) |
| 1D sweeps, uniform spacing | n per parameter |
| High dimensions, space-filling | user-specified budget |
| Parameters | Grid Points Each | Total Runs | Recommendation |
|---|---|---|---|
| 1 | 10 | 10 | Grid is fine |
| 2 | 10 | 100 | Grid acceptable |
| 3 | 10 | 1,000 | Consider LHS |
| 4+ | 10 | 10,000+ | Use LHS or DOE |
| Script | Output Fields |
|---|---|
| |
| |
| |
| |
| |
| |
Note on swept parameter names:writes each swept value into the base config by key path. A bare name (e.g.sweep_generator.py) overwrites a top-level key; a dot-notation name (e.g.kappa) targets a nested key. The swept key path must match where the solver reads the value — sweepingparameters.kappaagainst a config that nestskappawould add an unused top-level key and silently leave the base value in place. Seeparameters.kappa.references/sweep_strategies.md
python3 scripts/sweep_generator.py \
--base-config base_config.json \
--params "dt:1e-4:1e-2:5,kappa:0.1:1.0:3" \
--method linspace \
--output-dir ./campaign_001 \
--jsonpython3 scripts/campaign_manager.py \
--action init \
--config-dir ./campaign_001 \
--command "python sim.py --config {config}" \
--jsonpython3 scripts/job_tracker.py \
--campaign-dir ./campaign_001 \
--update \
--jsonpython3 scripts/result_aggregator.py \
--campaign-dir ./campaign_001 \
--metric final_energy \
--jsonresult_aggregator.pybest_runsummary.minimizetrue--maximizebest_run# Higher is better -> select the maximum
python3 scripts/result_aggregator.py \
--campaign-dir ./campaign_001 \
--metric yield \
--maximize \
--jsonDecision guidance: If higher is better (yield, accuracy, throughput), pass; otherwise the reported--maximizeis the minimum.best_run
# Generate 5x3=15 runs varying dt (5 values) and kappa (3 values)
python3 scripts/sweep_generator.py \
--base-config sim.json \
--params "dt:1e-4:1e-2:5,kappa:0.1:1.0:3" \
--method linspace \
--output-dir ./sweep_001 \
--json
# Generate LHS samples for 4 parameters with budget of 20 runs
python3 scripts/sweep_generator.py \
--base-config sim.json \
--params "dt:1e-4:1e-2,kappa:0.1:1.0,M:1e-6:1e-4,W:0.5:2.0" \
--method lhs \
--samples 20 \
--output-dir ./lhs_001 \
--json
# Check campaign status
python3 scripts/campaign_manager.py \
--action status \
--config-dir ./sweep_001 \
--json
# List jobs (read-only), optionally filtered by status
python3 scripts/campaign_manager.py \
--action list \
--config-dir ./sweep_001 \
--status-filter failed \
--json
# Get summary statistics from completed runs (minimize: best = lowest)
python3 scripts/result_aggregator.py \
--campaign-dir ./sweep_001 \
--metric final_energy \
--json
# Maximization metric: best = highest value (yield, accuracy, throughput)
python3 scripts/result_aggregator.py \
--campaign-dir ./sweep_001 \
--metric yield \
--maximize \
--jsonpython3 scripts/sweep_generator.py \
--base-config simulation.json \
--params "dt:1e-4:1e-2:5,kappa:0.1:1.0:4" \
--method linspace \
--output-dir ./dt_kappa_sweep \
--jsonpython3 scripts/campaign_manager.py \
--action init \
--config-dir ./dt_kappa_sweep \
--command "python phase_field.py --config {config}" \
--jsonpython3 scripts/result_aggregator.py \
--campaign-dir ./dt_kappa_sweep \
--metric interface_width \
--json| Error | Cause | Resolution |
|---|---|---|
| Invalid file path | Verify base config file exists |
| Malformed param string | Use format |
| Would overwrite | Use |
| No results to aggregate | Wait for jobs to complete or check for failures |
| Result files missing field | Verify metric name in result JSON |
parameter-optimization simulation-orchestrator
│ │
│ DOE samples ────────────────>│ Generate configs
│ │
│ │ Run simulations
│ │
│<──────────────────────────── │ Aggregate results
│ │
│ Sensitivity analysis │
│ Optimizer selection │parameter-optimization/doe_generator.pysimulation-orchestrator/sweep_generator.pysimulation-orchestrator/result_aggregator.pyparameter-optimization/sensitivity_summary.pybest_runconfig_NNNN.jsonparameters.kappasweep_generator.pyresult_aggregator.py --jsonsummary.total_jobssummary.completedsummary.failedcompleted + failed == total_jobsextract_metricNonecompleted > 0summary.metricextract_metricNonesummary.minimize--maximizebest_runjob_tracker.pyexit_codereferences/aggregation_methods.mdbest_run.value--seedmanifest.jsontotal_runsparameter_space| Tempting shortcut | Why it's wrong / what to do |
|---|---|
| "The job tracker says completed, so the run succeeded." | |
" | Jobs with a missing result file or a metric that |
"Aggregation returned a | By default the aggregator minimizes. If higher is better you must pass |
"I swept | |
| "The metric name is close enough." | A misspelled or absent metric makes |
| "Grid covers everything, so use it for all my parameters." | Grid is |
| "LHS is random, so I don't need to record anything." | LHS is reproducible only with a fixed |
result_aggregator.py --metric[a-zA-Z_][a-zA-Z0-9_.]*sweep_generator.py --params[a-zA-Z_][a-zA-Z0-9_]*(.[a-zA-Z_][a-zA-Z0-9_]*)*campaign_manager.py;|&$--paramsname:min:max:countNaNInfmin < max--methodgridlinspacelhs--samples--actioninitstatuslistlist--status-filterpendingrunningcompletedfailedsweep_generator.py--base-config--output-dirresult_aggregator.pyboolNaNInfshlex.quote()allowed-toolsBasheval()exec()shell=Truereferences/campaign_patterns.mdreferences/sweep_strategies.mdreferences/aggregation_methods.mdCHANGELOG.mdsweep_generator.py--params--samples--maximizelist