Skip to content

Repository files navigation

pestpp-wasm

PEST++ 5.2.27 compiled to WebAssembly, plus the one adapter it needs to drive a forward model that is not a child process. pestpp-ies and pestpp-glm run in Node or in a browser Worker and hand every forward run to a host callback.

This repository publishes an artifact. It contains no application and no user interface. That separation is deliberate, see Licence boundary.

Status

Built and gated. The build emits dist/pestpp.js, dist/pestpp.wasm, dist/pestpp-glm.js and dist/pestpp-glm.wasm from the pinned PEST++ 5.2.27 sources and a numbered patch set applied at build time.

npm ci
npm run build
npm test              # Node, Chromium and Firefox gates
npm run test:parity   # the same cases against native PEST++ 5.2.27

The parity gate hides the conductivity multipliers [3, 1, 0.3] of the pyEMU Freyberg MODFLOW 6 case, generates the observations by running the model with them, and requires the optimiser to find them back. It then repeats both runs with the pinned official macOS binaries and compares. Last run, 2026-08-11:

WASM Native 5.2.27
pestpp-ies recovered [2.9655, 1, 0.3005] [2.9568, 1, 0.3005]
pestpp-glm recovered [2.9999, 1, 0.3000] [3.0000, 1, 0.3000]

The largest parameter difference is 0.295% against a stated 0.5% tolerance, and the WASM forward model reproduces native MODFLOW 6.7.0 heads byte for byte. The gate downloads both native archives and verifies their SHA-256 hashes before use. ROADMAP.md section 8 records the full evidence.

Why this exists

PEST++ already implements the algorithms. They are the thing being ported, not something to be rewritten. What PEST++ cannot do in a browser is run the model: its run managers either fork/exec a child process or coordinate workers over TCP sockets, and a page can do neither. The whole port reduces to that one seam.

The seam

Every PEST++ algorithm talks to one abstract class, and that class has exactly one pure virtual method:

// src/libs/run_managers/abstract_base/RunManagerAbstract.h
virtual void run() = 0;

Queueing runs, retrieving results, storage and serialisation are all concrete and shared. IterEnsembleSmoother and its siblings receive a RunManagerAbstract * and never learn what is behind it.

This repository adds one subclass whose run() hands the queued parameter sets to a host callback instead of spawning processes, and compiles the suite with Emscripten. The callback is documented in docs/host-contract.md and is the artifact's entire public interface.

Licence boundary

PEST++ is GPL-3.0. Everything produced here is therefore GPL-3.0, and this repository is the corresponding source for the artifact it builds.

The boundary is what keeps a consuming application off that licence, and it is structural rather than a matter of intent:

Inside this repository, GPL-3.0 Outside, any licence
PEST++ sources and patches The application and its interface
The run manager adapter The MODFLOW worker that runs a model
Build recipe and artifact Anything that only exchanges messages

Never compile consumer code into the module. The host implements the narrow, documented callback and nothing more. Native PEST++ already invokes arbitrary model executables without making them derivative works, and the adapter preserves exactly that relationship.

That reasoning is an engineering judgement, not legal advice, and how GPL linking doctrine applies to WebAssembly modules is untested. Take counsel before shipping commercially.

Layout

  • src/ holds the browser run manager, shaped like src/libs/run_managers/external so it reads as part of PEST++.
  • build/ holds the numbered patches, the Dockerfile and the build recipe. BUILD.md is the patch audit trail with measured evidence.
  • docs/ holds the host contract and the blocking bridge decision.
  • fixtures/ holds the pinned Freyberg case and the native reference outputs the gates compare against.
  • ROADMAP.md records the investigation and the implementation evidence, written to be picked up by someone with no prior context.

About

PEST++ compiled to WebAssembly, with a browser run manager and native parity gates

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages