Application sweepable
sweepable is a lightweight command-line tool for simulation parameter sweeps.
It reads a script file and generates a tree of input files — one per parameter
combination — ready to be launched in parallel with the companion script
batchable.sh.
Both tools ship as a single self-contained file:
simuFileManips.hpp— header-only C++ library (the engine)sweepable.cpp— the script interpreter (build withmake)
No external dependencies. Requires C++17.
Quick Start
Build
make
Generate the batch runner
Running sweepable without arguments writes batchable.sh to the current
directory:
./sweepable
# → File 'batchable.sh' has been created
chmod +x batchable.sh
Write a sweep script
sweep.txt:
.foreach solver cg gmres
.foreach dt 0.1 0.5 1.0
.read input.txt
.findLineStartingWith solver
.replaceBy "solver $solver"
.findLineStartingWith dt
.replaceBy "dt $dt"
.createFolder "output/${solver}_dt_$dt"
.saveInFolder
.endforeach
.endforeach
.saveCollection generated.txt
Run the sweep
./sweepable sweep.txt
This produces:
output/cg_dt_0.1/input.txt
output/cg_dt_0.5/input.txt
output/cg_dt_1.0/input.txt
output/gmres_dt_0.1/input.txt
output/gmres_dt_0.5/input.txt
output/gmres_dt_1.0/input.txt
generated.txt
Launch all runs in parallel
./batchable.sh generated.txt mysim 4
batchable.sh reads generated.txt (produced by .saveCollection),
runs mysim input.txt inside each folder, and uses up to 4 parallel
processes. Output from each run is captured in run.log inside its folder.
Argument |
Description |
|---|---|
|
File produced by |
|
Executable to run (receives the input filename as argument) |
|
Maximum number of parallel jobs |
Script Language
General syntax
Commands start with a dot. Arguments are space-separated. Use quotes to
preserve spaces. Comments start with #.
# This is a comment
.read input.txt
.appendLine "# generated automatically"
Variables
Define a variable with .set:
.set name value
Use it with $name or ${name} (braces avoid ambiguity in composite strings):
.set dt 0.5
.createFolder "output/dt_$dt"
.createFolder "output/${dt}_run"
Loops
.foreach variable value1 value2 ...
...
.endforeach
Loops are fully nestable. The loop variable is restored to its previous value after the loop exits.
Verbosity
.verbose # enable output (default)
.mute # suppress output
.quiet # same as .mute
Command Reference
File I/O
Command |
Description |
|---|---|
|
Load a file into memory |
|
Change output filename (default: |
|
Save to the current folder |
|
Save to a specific folder (creates it if needed) |
Line Selection and Editing
Command |
Description |
|---|---|
|
Select the first matching line |
|
Replace the selected line |
|
Replace all matching lines |
|
Replace a substring in the selected line |
|
Insert a line after the first match |
|
Append a line at the end of the file |
Folders
Command |
Description |
|---|---|
|
Create a directory and remember it for |
Collection
Command |
Description |
|---|---|
|
Clear the list of generated files |
|
Write the list of generated files to disk |
Error Handling
Command |
Description |
|---|---|
|
Ignore missing matches instead of throwing |
|
Re-enable errors for missing matches |
C++ API
SFManip can also be used directly in C++ without the script interpreter.
Basic example
#include "simuFileManips.hpp"
int main() {
SFManip sf;
sf.read("input.txt")
.findLineStartingWith("dt")
.replaceBy("dt %.3f", 0.5)
.createFolder("output/run1")
.saveInFolder();
}
Full sweep example
#include "simuFileManips.hpp"
int main() {
SFManip::clearCollection();
for (const auto& solver : {"cg", "gmres"}) {
for (double dt : {0.1, 0.5, 1.0}) {
SFManip()
.read("input.txt")
.findLineStartingWith("solver")
.replaceBy("solver %s", solver)
.findLineStartingWith("dt")
.replaceBy("dt %.3f", dt)
.createFolder("output/%s_dt_%.3f", solver, dt)
.saveInFolder();
}
}
SFManip::saveCollection("generated.txt");
}
Method summary
All methods return SFManip& for chaining.
Method |
Description |
|---|---|
|
Load file into memory |
|
Set output filename |
|
Select first matching line |
|
Replace selected line (printf-style) |
|
Replace all matching lines |
|
Replace substring in selected line |
|
Insert line after match |
|
Append line at end |
|
Create directory and store it |
|
Save to stored directory |
|
Save to explicit directory |
|
Suppress errors for missing matches |
Static collection API
SFManip::Collection // std::vector<std::string> of generated paths
SFManip::clearCollection() // clear the list
SFManip::saveCollection(path) // write list to file