ESP32-S3 Bench Guide
ESP32‑S3 N16R8 벤치 가이드: 실시간 핀아웃, 강의, 시뮬레이터 및 벤치 로그
Black-Oil Simulator with Analytical Comparison. Runs entirely in browser, powered by Rust compiled to WASM.
저장소 README에서 가져옴
README 전체를 불러오는 중입니다. 아래는 저장된 발췌입니다.
A reservoir simulator that runs entirely in the browser and draws every result against the
classical solution it is supposed to reproduce. Three-phase black-oil flow on a 3D Cartesian
grid — implicit-pressure (IMPES) or fully implicit — with Peaceman wells, gravity, capillarity
and correlation or tabular PVT, plotted live against Buckley–Leverett, Craig, Dykstra–Parsons,
Stiles, Dietz, Fetkovich, Arps, Havlena–Odeh and line-source well-test solutions, plus
precomputed OPM Flow runs where no closed form exists.README 전문 보기 ↗A reservoir simulator that runs entirely in the browser and draws every result against the classical solution it is supposed to reproduce. Three-phase black-oil flow on a 3D Cartesian grid — implicit-pressure (IMPES) or fully implicit — with Peaceman wells, gravity, capillarity and correlation or tabular PVT, plotted live against Buckley–Leverett, Craig, Dykstra–Parsons, Stiles, Dietz, Fetkovich, Arps, Havlena–Odeh and line-source well-test solutions, plus precomputed OPM Flow runs where no closed form exists. Seventeen scenarios ship as self-contained studies with sensitivity dimensions, scenario-appropriate charts and (where the case is spatial) a 3D view and saturation profile. Each states what its reference assumes and where the simulation is expected to leave it. Nothing is uploaded: the solver is WebAssembly running on the page, fonts are bundled with the app, and there are no analytics or cookies. The selected theme is stored locally in the browser.
Live app — No installation required. Hosted at the domain root on GitHub Pages. See deployment and rollback.
| Catalog group | Scenario | Key | Primary reference / purpose |
|---|---|---|---|
| 1D Displacement — Buckley–Leverett | 1D Waterflood | wf_bl1d | Buckley–Leverett + Welge analytical reference across mobility ratio, oil Corey exponent and residual oil |
| 1D Displacement — Buckley–Leverett | 1D Waterflood — Capillary Effects | wf_capillary | Departure from the zero-capillary BL limit; physical versus numerical front spreading; OPM Flow run of the identical model, capillary pressure included |
| 1D Displacement — Buckley–Leverett | Gravity-Stable vs Unstable Displacement | wf_gravity_stability | 1D vertical column flooded upward or downward; gravity along the flow path brackets the viscous BL curve instead of bounding it; OPM Flow run of the identical model |
| 1D Displacement — Buckley–Leverett | Numerical Dispersion & Convergence | wf_numerics | The case where no BL assumption is broken, so the whole gap is the grid: first-order convergence over a 40x cell-size range, the IMPES stability limit made visible, IMPES vs FIM, and OPM Flow runs at two resolutions |
| 1D Displacement — Buckley–Leverett | Gas Injection | gas_injection | Gas-oil fractional-flow breakthrough; OPM Flow run of the identical model |
| Sweep Efficiency | Areal Sweep | sweep_areal | Craig confined five-spot correlation; OPM Flow run of the identical model |
| Sweep Efficiency | Vertical Sweep | sweep_vertical | Dykstra–Parsons / Stiles layered sweep; OPM Flow run of the identical model |
| Sweep Efficiency | Layer Crossflow — Do the Layers Talk? | sweep_crossflow | Dykstra–Parsons' non-communicating assumption tested directly: a k_v/k_h ladder the correlation cannot see, a crossflow benefit that reverses sign with mobility ratio, and capillary crossflow that needs a path; OPM Flow run of the base case |
| Sweep Efficiency | Combined Sweep | sweep_combined | Combined areal and vertical contact with selectable layered correlation; OPM Flow run of the base case |
| Sweep Efficiency | Gravity Override (Dietz Tongue) | wf_gravity | Vertical sweep lost to a gravity tongue; gravity-off control returns to BL, rate/density/k_z/completion ladders leave it; OPM Flow cross-check of the base case |
What each reference is entitled to claim, and where it stops.
docs/THREE_PHASE_VALIDATION.md section 6.docs/BLACK_OIL_VALIDATION.md §3–4b.20 x P_entry. That cap is a stability safeguard, not a physical plateau.c_o in two-phase mode, and in three-phase mode an effective value from the bubble-point curve, blended over the last 5 bar above the bubble point. In both modes this is only the first guess. A volume-balance iteration then takes storage from the mass closure itself, so the approximation does not reach the conserved masses.Bo rises faster than Bg·dRs/dp below the bubble point is thermodynamically unstable. The run is allowed, with a pre-run warning that names the pressure range.pnpmwasm-packwasm32-unknown-unknown targetpnpm install
rustup target add wasm32-unknown-unknown
cargo install wasm-pack
pnpm run dev
src/lib/ressim/pkg/ (the wasm-bindgen output) is generated and not committed. pnpm run dev,
build, typecheck and the test* scripts all build it first; scripts/build-wasm.sh skips the
work when the output is already newer than the Rust sources, so the hook is close to free once
warm.
pnpm run validate # frontend: typecheck + lint + cycles + fast tests + build
pnpm run validate:product # + full vitest + Rust IMPES solver bucket
pnpm run validate:full # + all Rust solver buckets (shared + FIM + IMPES)
bash scripts/validate-solver-coverage.sh all # Rust solver test buckets on their own
cargo test --manifest-path src/lib/ressim/Cargo.toml benchmark_buckley # physics benchmark
Pull-request CI runs the same ground as validate:full, plus the Buckley-Leverett benchmarks, the
compositional thermodynamics gate and the two gates below. The #[ignore]d release replays and
the wasm control matrix stay out of PR CI and are run explicitly;
.claude/skills/ressim-validation/SKILL.md lists them and says when each applies.
Two gates sit outside validate:* because they need more than a Rust toolchain and Node:
bash scripts/validate-native-binding.sh # native (PyO3) vs browser bindings: a case matrix plus every black-oil catalog run
pnpm run test:deployed # Playwright, against `pnpm run preview`
Both run in PR CI. The first builds crates/ressim-py against the engine with its browser
bindings switched off and compares the two clients. They agree bit for bit: the engine's
transcendental math goes through one implementation on both targets (#62). The second is the only check that would catch an unstyled page, because a Tailwind
content-glob miss raises no error anywhere.
Builds default to /ressim/ in dist/ressim. Set RESIM_BASE_PATH=/ for a root build in
dist-root; use the same setting for preview, packaging, and browser tests. PR CI (also available
through manual dispatch) validates both layouts with exact commit checks before deployment.
See deployment and cutover for commands and archive formats.
One gate is local only, because CI has no OPM Flow. Run it after any change that can move an answer:
bash scripts/validate-cross-solver.sh # FIM and IMPES vs OPM Flow on the small-direct decks
Full cargo test is not used as a gate, because FIM diagnostic tests can dominate its runtime
(see .claude/skills/ressim-validation/SKILL.md).
comp_co2_1d) on the compositional engine.gas_injection, gas_drive, spe1_gas_injection, dep_gas_pz, dep_pvt,
wf_capillary). The
other oil/water cases run IMPES. wf_numerics runs the two side by side.crates/ressim-py, PyO3), with its browser
bindings switched off.Spe5FluidSystem. It is validated natively against OPM's
compositional simulator and not yet offered in the app.ScenarioPicker.svelte, with scenario-owned parameters,
sensitivity dimensions, per-variant run sweeps and references.Current scorecard: per area, the banded criterion closest to its band, the largest gap to a
reference solving the same discrete model, and the commit it was measured on. The table is generated from docs/benchmarks/benchmarks.json by
bash scripts/benchmarks.sh render; every row, its band and its replay command are in
docs/BENCHMARKS.md, which is the authoritative record.
| Area | Reference | Tightest criterion | Band | Band used | Largest same-model gap | Measured on |
|---|---|---|---|---|---|---|
| 1D waterflood breakthrough | Buckley-Leverett + Welge | BL-Case-A nx=24: breakthrough_rel_err 9.54 % | 15.0 % | 64% | — | ee2f6b5 |
| SPE1 Case 1, 10 years | Published SPE1 / Flow | 10x10x3: gor_rel_err 1.41 % | 12.0 % | 12% | 10x10x3: vs_flow.WGOR_rel_err -0.90 % (explained) | ee2f6b5 |
| Three-phase gas drive and injection | OPM Flow | gas_drive: gor_rel_err 0.56 % | 1.0 % | 56% | gas_drive: vs_jutul.FOPR_rel_err +4.49 % (explained) | ee2f6b5 |
| Black-oil depletion column | Grid self-convergence, Flow | FIM: sat_gas_finest_pair_gap 1.20 % | 1.5 % | 80% | — | ee2f6b5 |
| Generated decks, three solvers | OPM Flow, generated decks | no banded criterion | — | — | sweep-combined: sparse.cum.FWPT +0.45 % | ee2f6b5 |
| Native vs wasm bindings | Each other | buckley-impes (IMPES): cells_max_abs_diff 0 abs | 1e-09 abs | 0% | — | ee2f6b5 |
| FIM convergence, long horizons | Substeps per report step | no banded criterion | — | — | — | ee2f6b5 |
| Compositional, matched timestep | OPM flowexp_comp | 1D plain: worst_pressure_diff 1.68 bar | 2 bar | 84% | 1D plain: worst_pressure_diff 1.68 bar (explained) | ee2f6b5 |
| Second simulator on the same decks | JutulDarcy vs Flow and FIM | no banded criterion | — | — | dep-pvt-lab-report: fim_vs_jutul.final_FGPR_rel_err +1.31 % (explained) | ee2f6b5 |
Scenario tests (pnpm run test:scenarios) also grade each case in the picker against its own
reference, and analytical-contract tests check that every dimension marked affectsAnalytical
actually moves the analytical curve.
The next priorities follow standard reservoir-engineering practice:
That ordering aligns with the literature already used in the project: Buckley and Leverett, Welge, Craig, Dykstra and Parsons, Stiles, Dietz, Fetkovich, Arps, Havlena and Odeh, and the SPE comparative-solution tradition used for simulator validation.
src/
App.svelte # the application's page
app.css
main.ts
pages/ # additional entry points, built from the packages below
fractionalFlow/
lib/
analytical/ # @ressim/analytical - reference solutions
charts/ # @ressim/charts - Chart.js panels and chart models
primitives/ # @ressim/primitives - presentational controls, no domain vocabulary
quantities/ # @ressim/quantities - derived run series and in-place volumes
presets/ # @ressim/presets - the preset/scenario editability contract
catalog/ # scenario definitions and bundled OPM Flow artifacts
compositional/ # compositional run payloads, series and quantities
physics/
ressim/ # the Rust/WASM engine
scenario/
stores/
ui/
visualization/
workers/
crates/
ressim-py/ # PyO3 bindings: the engine without its browser bindings
parity/ # native/wasm cross-client gate
ressim_quantities/# run quantities for notebooks, from the shared contract
contracts/
run-quantities.json # GENERATED from the TypeScript registry; the shared data contract
docs/ # authoritative + active working docs (see DOCUMENTATION_INDEX.md)
BENCHMARKS.md # current benchmark scorecard
DOCUMENTATION_INDEX.md
...
opm/ # OPM Flow reference decks, the small-direct scorecard, compositional fixtures
tools/ # offline OPM Flow pipeline (Python, run with uv)
.archive/ # superseded experiments, closed plans, historical snapshots
docs/ # (git-tracked, reversible; see .archive/README.md)
ROADMAP.md
TODO.md
The five @ressim/* directories are pnpm workspace packages, imported by name rather than by
relative path. src/lib/packageBoundaries.test.ts enforces that: a relative import reaching into
a package from outside fails, because a package name without an enforced boundary is a naming
convention that decays the first time someone types a path out of habit.
fractional-flow.html is a second page built only from those packages — no store, no scenario
catalog, no worker, no WASM. It exists so that "the frontend can be composed into more than one
page" is demonstrated rather than asserted; see docs/ARCHITECTURE_SPLIT_PLAN_2026-09-19.md.
| Document | Purpose |
|---|---|
| GitHub Issues | Actionable work, priorities, acceptance criteria, and status |
ROADMAP.md | Strategic ordering and links to active issues |
docs/BENCHMARKS.md | Current benchmark scorecard: every reference, band, measured error and replay command |
docs/P4_TWO_PHASE_BENCHMARKS.md | Buckley-Leverett benchmark methodology and tolerance policy |
docs/BLACK_OIL_VALIDATION.md | SPE1 acceptance criteria, black-oil grid convergence, solver safeguards |
docs/THREE_PHASE_VALIDATION.md | Three-phase exit criteria, OPM Flow / SPE1 acceptance, phase-closure diagnostics |
docs/COMPOSITIONAL_VALIDATION.md | Compositional fluid dataset, oracles, acceptance contract and gate status |
docs/FIM_STATUS.md | FIM solver state, convergence history and source map |
docs/OPEN_ITEMS_2026-09-21.md | Deliberate deferrals and known gaps, each with why and what would close it |
docs/SCIENTIFIC_LIMITATIONS.md | What the software is not qualified for |
docs/THREE_PHASE_IMPLEMENTATION_NOTES.md | Three-phase implementation details and parameter reference |
docs/UNIT_SYSTEM.md | Unit conventions, equations, and PVT / solver notes |
docs/ARCHITECTURE_NOTES.md | Current architecture direction and unresolved design decisions |
docs/DOCUMENTATION_INDEX.md | Which documents are authoritative vs historical |
The limited public release is deployed. See ROADMAP.md for current ordering. The next
priorities are:
comp_co2_1d product path is complete
(#29), to SPE5 and then SPE3
(#52).ResSim is licensed under the GNU Affero General Public License v3.0 only. IBM Plex Sans and IBM Plex Mono are bundled through Fontsource and remain licensed under the SIL Open Font License 1.1; their license texts are included in the installed font packages.
| Flow Regimes & Decline | Transient Radial Flow (Theis) | dep_welltest | Line-source drawdown before boundaries are felt; permeability, skin, and near-well grid bias |
| Flow Regimes & Decline | Drainage Geometry & Productivity (Dietz) | dep_pss | Equal-area drainage geometries and well positions; C_A recovered from the measured PSS drawdown |
| Flow Regimes & Decline | Boundary-Dominated Decline (Fetkovich) | dep_decline | Finite-slab transient, boundary arrival, and asymptotic decline |
| Flow Regimes & Decline | Layered Depletion (Arps) | dep_arps | Spatial layered depletion approaching a late-time Dietz/Fetkovich superposition, plus a crossflow limitation study |
| Material Balance & Drive Mechanism | Gas Reserves from p/z | dep_gas_pz | Dry-gas depletion against the p/z material-balance straight line; pore compressibility, compartmentalisation and how much history you have each inflate the reserves estimate; OPM Flow cross-check at both ends of the compressibility ladder |
| Material Balance & Drive Mechanism | Solution Gas Drive | gas_drive | Saturated black-oil depletion — liberation, free-gas build-up and the GOR rise; graded against an OPM Flow reference (docs/THREE_PHASE_VALIDATION.md §2) |
| Material Balance & Drive Mechanism | PVT Model Risk — One Calibration Point | dep_pvt | Constant-rate black-oil blowdown; every PVT table shares the one point a flash test pins. Above it, unmeasured undersaturated compressibility doubles the time to the bubble point; below it, the published Rs(p) correlation spreads producing GOR by ±20% at matched pressure. OPM Flow on every rung |
| Published Benchmark Decks | SPE1 Black-Oil Benchmark | spe1_gas_injection | Published Eclipse and OPM Flow comparative-solution references |
| Published Benchmark Decks | 1D Compositional CO₂ Flood | comp_co2_1d | OPM's 1D_COMP deck on the Peng–Robinson compositional engine: components in place, net injected, vapour saturation and a conservation check per case, across grid and timestep ladders. No analytical overlay exists; validated against OPM flowexp_comp (docs/COMPOSITIONAL_VALIDATION.md §8) |