Skip to content

MSX multi-species simulation

EPANET-MSX models the transport and reaction of multiple chemical species through a water network. With epanet-js 0.9.0 you can run MSX simulations directly in the browser by loading the default workspace, or by loading any of the *-msx engine variants through the slim Workspace.

This example walks through:

  1. Loading an MSX-enabled engine.
  2. Writing the INP file and the MSX configuration file into the workspace virtual filesystem.
  3. Running a full hydraulic + multi-species water-quality simulation.
  4. Reading the species concentrations back out.
import { Workspace } from "epanet-js/slim";
import { Project } from "epanet-js";
import { MsxConstant } from "epanet-js/engines/v2.3.5-msx";
const ws = new Workspace();
await ws.loadModuleVersion(() => import("epanet-js/engines/v2.3.5-msx"));
const project = new Project(ws);

The chosen engine variant has the -msx suffix, which exposes MSX functions in the Project. Loading a non-MSX engine and calling msxOpen would throw an exception.

You need both:

  • The EPANET INP file that defines the network (nodes, links, demands…).
  • The MSX configuration file that defines species, reaction equations, sources, and patterns.
ws.writeFile("network.inp", inpText);
ws.writeFile("network.msx", msxText);
// 1. Open the EPANET project.
project.open("network.inp", "network.rpt", "network.bin");
// 2. Bind the MSX configuration to the project.
project.msxOpen("network.msx");
// 3. Run hydraulics + multi-species quality in one shot.
project.msxSolveH();
project.msxSolveQ();
// 4. Read species concentrations.
const speciesCount = project.msxGetCount(MsxConstant.MSX_SPECIES);
const nodeCount = project.getCount(CountType.Node);
for (let s = 1; s <= speciesCount; s++) {
const { type, units } = project.msxGetSpecies(s);
for (let n = 1; n <= nodeCount; n++) {
const value = project.msxGetQual(MsxConstant.MSX_NODE, n, s);
console.log(`species ${s} at node ${n}: ${value} ${units}`);
}
}
// 5. Write a formatted report and read it back.
project.msxReport();
const report = ws.readFile("network.rpt");
// 6. Tear down.
project.msxClose();
project.close();

If you need intermediate results (e.g. to drive an animation), use the step-based form:

project.msxSolveH();
project.msxInit(/* saveFlag */ 0);
let { t, tleft } = project.msxStep();
while (tleft > 0) {
// …inspect species concentrations at simulation time `t`…
({ t, tleft } = project.msxStep());
}
project.msxClose();
project.close();

See the MSX functions reference for the full list of MSX methods.