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:
- Loading an MSX-enabled engine.
- Writing the INP file and the MSX configuration file into the workspace virtual filesystem.
- Running a full hydraulic + multi-species water-quality simulation.
- 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.
Writing the INP and MSX files
Section titled “Writing the INP and MSX files”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);Running the simulation
Section titled “Running the simulation”// 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();Stepping through the simulation
Section titled “Stepping through the simulation”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.