Wellbore Genius

Downhole Simulator

Performance modeling

Sign in
Phase 6 inc. 3 · DFIT benchmarks

DFIT analytical benchmark suite ALL PASSED

Live view of the same suite that runs on every CI build. 3 benchmarks compared on a fixed log-spaced time grid (1 → 1024 s) with a 0.05 log-tolerance ceiling. Drift past tolerance = scoreboard flip required.

Phase 7 inc 1–5

Tip-kernel knobs

Osher–Sethian monotone upwind gradient on tipPropagationStep.

Dontsov–Peirce 2017 max-of-asymptotes blend of K-vertex Charles and M-vertex viscous V_M.

Level-set reinitialization

Sussman-Smereka-Osher 1994 — auto-call between front-motion steps so |∇φ| ≈ 1 stays put. Off by default.

Workspace presets

Saved per workspace. Apply restores the knobs above to the preset's snapshot.

No presets saved yet.

Local controls

Re-runs the suite locally — does not change CI defaults. Density applies to the long-time PKN + Carter grid; the KGD-Newton entry keeps its locked [1, 2] s window.

sparse (2)dense (12)
tighter (0.1×)looser (5×)

Phase 7 inc 16 — pick which kernel each benchmark exercises. Only KGD currently exposes both newton-kernel (fixed-tip Newton step) and live-kernel (MK moving-tip wrapper); PKN + Carter are live-kernel only today.

Applies to "Download tip diagnostics CSV" and "Download combined CSV". The two ID columns (benchmark_id, runner_label) are always included.

No saved presets yet. Save the current grid/tolerance settings with a label to switch back to them in one click.

Per-benchmark results

BenchmarkStatusRMS log-residualMax log-residualToleranceN samples
kgd-widthPASS7.02e-27.56e-21.15e-12
pkn-lengthPASS1.33e-11.80e-11.50e-12
carter-falloffPASS6.95e-89.82e-81.00e-52

Compare against a previous run

Upload a previously downloaded dfit-benchmarks-*.json to diff its PASS/FAIL + residuals against the current run above.

No baseline loaded yet.

Residuals over time

Shaded band = ±tolerance. Red markers = samples outside the band.

kgd-widthcoupledNewtonStep + MK moving-tip + reinit i=8 (Phase 7 inc 15) · live kernel
tol ±0.12 · max |log| = 7.56e-2ALL IN BAND
pkn-lengthcoupledNewtonStep (Phase 3.5 kernel, height-contained) · live kernel
tol ±0.15 · max |log| = 1.80e-11 OUT OF BAND
carter-falloffcoupledNewtonStep + Carter sink mass-balance recovery (Phase 7 inc 14) · live kernel
tol ±0.00 · max |log| = 9.82e-8ALL IN BAND

KGD fixed-tip vs moving-tip [m, log₁₀ residual]

Side-by-side widths on the canonical [1, 2] s window against the Spence–Sharp analytical reference. Moving-tip uses the MK-universal wrapper (Phase 7 inc 13); fixed-tip is the legacy strip Newton (Phase 6 inc 4). RMS is √(mean(log₁₀(w_run / w_ref)²)).

Toggle on to recompute both runners on the canonical inputs.

Window sweep (preview)

Compares the registry-locked window against a wider preview window per live-kernel entry. Doesn't touch the CI gate or the kernel.

Quick presets:

Mesh adapt & tip-BC are wired through to each runner: PKN uses adaptiveTipFocus + cohesiveTipBC, KGD uses bumped reinit iterations + cohesiveTipBC, Carter doubles cell count for tip-refined (no propagating tip — tip-BC echoed for traceability). Defaults preserve the registry rms byte-for-byte.

Registry: [1, 2] s·Preview: [1, 4] s, 3 pts

rms_log10 vs window

Sweeps t_end across the requested range with t_start fixed and plots the rms log10 residual returned by the active runner.

Sensitivity sweep — Q · t-window · meshAdapt · tipBC
REGRESSIONS
Sweeps the registry-locked window plus a tighter / broader neighbour for each entry, across meshAdapt (uniform / tip-refined), tipBC (free / kic-clamped), and Carter Q sizing (constant / auto). Headroom (Δ = tolerance − rms) ≥ 0 ⇒ healthy. Default filter shows all 48 rows.
KGD width
4/12 pass
tol [log]: 1.150e-1
best Δ 4.477e-2 · worst Δ -1.282e-1
worst @ [1, 4]s · tip-refined · free
PKN length
2/12 pass
tol [log]: 1.500e-1
best Δ 1.657e-2 · worst Δ -3.846e-1
worst @ [0.25, 0.5]s · tip-refined · kic-clamped
Carter falloff (leak-off)
24/24 pass
tol [log]: 1.000e-5
best Δ 9.980e-6 · worst Δ 6.406e-6
worst @ [2, 10]s · tip-refined · kic-clamped · Q=auto
Filter:
meshAdapt:
tipBC:
Q (carter):
48 / 48 rows
EntryWindow [s]meshAdapttipBCQrms [log]tol [log]Δ [log]HeadroomStatus
kgd-width[1, 2] · n=2uniformfree7.023e-21.150e-1+4.477e-2
PASS
kgd-width[0.5, 1] · n=2uniformfree1.908e-11.150e-1-7.576e-2
FAIL
kgd-width[1, 4] · n=2uniformfree2.432e-11.150e-1-1.282e-1
FAIL
kgd-width[1, 2] · n=2uniformkic-clamped1.070e-11.150e-1+7.968e-3
PASS
kgd-width[0.5, 1] · n=2uniformkic-clamped1.999e-11.150e-1-8.489e-2
FAIL
kgd-width[1, 4] · n=2uniformkic-clamped2.427e-11.150e-1-1.277e-1
FAIL
kgd-width[1, 2] · n=2tip-refinedfree7.023e-21.150e-1+4.477e-2
PASS
kgd-width[0.5, 1] · n=2tip-refinedfree1.908e-11.150e-1-7.576e-2
FAIL
kgd-width[1, 4] · n=2tip-refinedfree2.432e-11.150e-1-1.282e-1
FAIL
kgd-width[1, 2] · n=2tip-refinedkic-clamped1.070e-11.150e-1+7.968e-3
PASS
kgd-width[0.5, 1] · n=2tip-refinedkic-clamped1.999e-11.150e-1-8.489e-2
FAIL
kgd-width[1, 4] · n=2tip-refinedkic-clamped2.427e-11.150e-1-1.277e-1
FAIL
pkn-length[0.5, 1] · n=2uniformfree1.334e-11.500e-1+1.657e-2
PASS
pkn-length[0.25, 0.5] · n=2uniformfree3.176e-11.500e-1-1.676e-1
FAIL
pkn-length[1, 2] · n=2uniformfree2.113e-11.500e-1-6.130e-2
FAIL
pkn-length[0.5, 1] · n=2uniformkic-clamped3.368e-11.500e-1-1.868e-1
FAIL
pkn-length[0.25, 0.5] · n=2uniformkic-clamped5.346e-11.500e-1-3.846e-1
FAIL
pkn-length[1, 2] · n=2uniformkic-clamped2.081e-11.500e-1-5.813e-2
FAIL
pkn-length[0.5, 1] · n=2tip-refinedfree1.334e-11.500e-1+1.657e-2
PASS
pkn-length[0.25, 0.5] · n=2tip-refinedfree3.176e-11.500e-1-1.676e-1
FAIL
pkn-length[1, 2] · n=2tip-refinedfree2.113e-11.500e-1-6.130e-2
FAIL
pkn-length[0.5, 1] · n=2tip-refinedkic-clamped3.368e-11.500e-1-1.868e-1
FAIL
pkn-length[0.25, 0.5] · n=2tip-refinedkic-clamped5.346e-11.500e-1-3.846e-1
FAIL
pkn-length[1, 2] · n=2tip-refinedkic-clamped2.081e-11.500e-1-5.813e-2
FAIL
carter-falloff[1, 2] · n=2uniformfreeconstant6.947e-81.000e-5+9.931e-6
PASS
carter-falloff[0.5, 1] · n=2uniformfreeconstant2.001e-81.000e-5+9.980e-6
PASS
carter-falloff[2, 10] · n=2uniformfreeconstant9.980e-71.000e-5+9.002e-6
PASS
carter-falloff[1, 2] · n=2uniformfreeauto6.947e-81.000e-5+9.931e-6
PASS
carter-falloff[0.5, 1] · n=2uniformfreeauto2.001e-81.000e-5+9.980e-6
PASS
carter-falloff[2, 10] · n=2uniformfreeauto9.980e-71.000e-5+9.002e-6
PASS
carter-falloff[1, 2] · n=2uniformkic-clampedconstant6.947e-81.000e-5+9.931e-6
PASS
carter-falloff[0.5, 1] · n=2uniformkic-clampedconstant2.001e-81.000e-5+9.980e-6
PASS
carter-falloff[2, 10] · n=2uniformkic-clampedconstant9.980e-71.000e-5+9.002e-6
PASS
carter-falloff[1, 2] · n=2uniformkic-clampedauto6.947e-81.000e-5+9.931e-6
PASS
carter-falloff[0.5, 1] · n=2uniformkic-clampedauto2.001e-81.000e-5+9.980e-6
PASS
carter-falloff[2, 10] · n=2uniformkic-clampedauto9.980e-71.000e-5+9.002e-6
PASS
carter-falloff[1, 2] · n=2tip-refinedfreeconstant2.482e-71.000e-5+9.752e-6
PASS
carter-falloff[0.5, 1] · n=2tip-refinedfreeconstant7.113e-81.000e-5+9.929e-6
PASS
carter-falloff[2, 10] · n=2tip-refinedfreeconstant3.594e-61.000e-5+6.406e-6
PASS
carter-falloff[1, 2] · n=2tip-refinedfreeauto2.482e-71.000e-5+9.752e-6
PASS
carter-falloff[0.5, 1] · n=2tip-refinedfreeauto7.113e-81.000e-5+9.929e-6
PASS
carter-falloff[2, 10] · n=2tip-refinedfreeauto3.594e-61.000e-5+6.406e-6
PASS
carter-falloff[1, 2] · n=2tip-refinedkic-clampedconstant2.482e-71.000e-5+9.752e-6
PASS
carter-falloff[0.5, 1] · n=2tip-refinedkic-clampedconstant7.113e-81.000e-5+9.929e-6
PASS
carter-falloff[2, 10] · n=2tip-refinedkic-clampedconstant3.594e-61.000e-5+6.406e-6
PASS
carter-falloff[1, 2] · n=2tip-refinedkic-clampedauto2.482e-71.000e-5+9.752e-6
PASS
carter-falloff[0.5, 1] · n=2tip-refinedkic-clampedauto7.113e-81.000e-5+9.929e-6
PASS
carter-falloff[2, 10] · n=2tip-refinedkic-clampedauto3.594e-61.000e-5+6.406e-6
PASS

A/B comparison (preview)

Runs two solver settings on the same window range and plots rms_log10 / max_log10 deltas (B − A). Doesn't touch the CI gate.

A
B

Registry-window comparison

Scores every live-kernel entry on both registry windows ([1, 2] s and [0.5, 1] s) under the same solver settings. Use it to evaluate the meshAdapt / tipBC tightening work before flipping the scoreboard. Doesn't touch the CI gate or the kernel.

EntryRegistryrms [1, 2] srms [0.5, 1] sΔ rms (tight − wide)max [1, 2] smax [0.5, 1] s
KGD width[1, 2] s7.0234e-21.9076e-11.2052e-17.5640e-22.6220e-1
PKN length[0.5, 1] s2.1130e-11.3343e-1-7.7875e-22.9365e-11.8038e-1
Carter falloff[1, 2] s6.9466e-82.0013e-8-4.9453e-89.8172e-82.8212e-8

Compare saved runs

Pin the current density / tolerance configuration as a snapshot and view PASS/FAIL + residual charts side-by-side.

No saved runs yet. Adjust the controls above and hit Save current run.

CI log preview

DFIT benchmark suite @ 2026-05-24T14:33:06.036Z — PASS (3 benchmarks)
  [PASS] kgd-width        rms=7.02e-2 max=7.56e-2 tol=1.15e-1 n=2
  [PASS] pkn-length       rms=1.33e-1 max=1.80e-1 tol=1.50e-1 n=2
  [PASS] carter-falloff   rms=6.95e-8 max=9.82e-8 tol=1.00e-5 n=2

Truncation diagnostic — width & half-length over time

legacy vs mkTipFeedback vs reinit, per KGD benchmark
Benchmark curves (1/1)
Width w(t) [m]
Half-length a(t) [m]
Wellbore pressure p(t) [Pa]

peak |Δw| mk−legacy: 6.51e-4 m · peak |Δw| reinit−legacy: 6.51e-4 m · peak |Δp| mk−legacy: 3.54e+7 Pa · peak |Δp| reinit−legacy: 3.54e+7 Pa · rows: 2

Temperature T(t): —   KGD kernel is isothermal; row schema reserves T columns for future thermal-coupled kernels.

Registry

  • kgd-width · tol 0.115 (log10) · runner: coupledNewtonStep + MK moving-tip + reinit i=8 (Phase 7 inc 15) (live kernel)
  • pkn-length · tol 0.15 (log10) · runner: coupledNewtonStep (Phase 3.5 kernel, height-contained) (live kernel)
  • carter-falloff · tol 0.00001 (log10) · runner: coupledNewtonStep + Carter sink mass-balance recovery (Phase 7 inc 14) (live kernel)

Phase 6 inc 4 wired the kgd-width entry into the live coupledNewtonStep kernel (1D strip, 41 cells, [1, 2] s window). PKN + Carter still self-reference until their kernels land.

Timestamp: 2026-05-24T14:33:06.036Z

μ × dt solver diagnostics

Convergence status, residual trend, and failure-mode label for every (μ [cp], dt [d]) cell in the viscosity sweep grid.

Pass22Solver tol.0Transient0Both0Skipped (dt cap)2
Tuning presetsCaptures dt cap, dt levels, per-μ caps & metric — rerun with one click.
|
μ [cp] \ dt [d]0.20.51520100
0.5
Pass
Pass
Pass
Pass
Pass
Pass
1
Pass
Pass
Pass
Pass
Pass
Pass
2
Pass
Pass
Pass
Pass
Pass
Skipped (dt cap)
5
Pass
Pass
Pass
Pass
Pass
Skipped (dt cap)

Sparklines show per-step CG residual on a log scale. Failure-mode labels come from classifyFailureMode with default thresholds (residualTol = 1e-6, settleRatioTol = 0.05).

Drift-guard tolerance-margin heatmap [μ × dt]

Color = 1 − |Δ| / envelope. Green = envelope sits well above observed deviation; amber = tight; red = envelope violated.

Safe22Comfortable0Tight0Failing0Skipped2
μ [cp] \ dt [d]0.20.51520100
0.5
1.001.00e+3 psi
1.001.00e+3 psi
1.001.00e+3 psi
1.001.00e+3 psi
1.009.99e+2 psi
1.009.99e+2 psi
1
1.002.00e+3 psi
1.002.00e+3 psi
1.002.00e+3 psi
1.002.00e+3 psi
1.002.00e+3 psi
1.002.00e+3 psi
2
1.004.00e+3 psi
1.004.00e+3 psi
1.004.00e+3 psi
1.004.00e+3 psi
1.004.00e+3 psi
skip
5
1.001.00e+4 psi
1.001.00e+4 psi
1.001.00e+4 psi
1.001.00e+4 psi
1.001.00e+4 psi
skip

Envelope per μ comes from tolerancesFor({ viscosityCp: μ }).pInitEnvelopePsi. Observed |Δ| uses the synthetic probe'smaxAbsStepDelta from the diagnostics recorder — same quantity the failure classifier inspects.

Pass/fail matrices — capped vs uncapped (with headroom)

Tightens the analytical envelope to E / (1 + headroomFraction) and recolors both matrices live. Use it to ask: "what still fails if I require an extra X% buffer?"

Effective envelope per μ = tolerancesFor(μ).pInitEnvelopePsi / 1.00. Capped fails: 0 · Uncapped fails: 0.

Downloads

Wide / long / fail-frequency CSVs for both capped & uncapped grids at the current metric and headroom.

Capped (μ ≥ 2 ⇒ dt ≤ 20 d)

0 fail · 0 tight · 22 safe · 2 skip
μ \ dt0.20.51520100
0.5
1
2
5

Uncapped (full dt grid)

0 fail · 0 tight · 24 safe · 0 skip
μ \ dt0.20.51520100
0.5
1
2
5

✓ = pass / safe · ! = tight · ✗ = envelope violated · — = skipped by dt cap. Cell color follows the same diverging palette as the tolerance-margin heatmap above.

Failure-prone heatmap [μ × dt] — worst of all metrics

Color = failed metrics ÷ ran metrics at this (μ, dt) acrossp_wf·p_cell·p_probe. Top-N most failure-prone cells get a ranked ring.

Pass66Fail0Skip6
μ [cp] \ dt [d]0.20.51520100
0.5
1
2
5

Sweep results summary — what changed

Diffs current settings against the baseline (capped grid, headroom = 0). Lists re-enabled cells, newly failing cells, recoveries, and outstanding regressions, plus the drift-guard tests they gate.

Re-enabled2Newly failing0Recovered0Still failing0
Changeμ [cp]dt [d]BaselineCurrentΔ headroom [psi]
Re-enabled2100skippedsafe
Re-enabled5100skippedsafe

Drift-guard tests affected by the visco sweep

Re-run these vitest files before merging any envelope or sweep change. Each one snapshots a piece of the (μ, dt) plumbing surfaced on this page.

  • src/lib/reservoir/__tests__/viscoSweepMatrixCsv.test.tsWIDE / LONG / fail-frequency CSV builders.
  • src/lib/reservoir/__tests__/viscoToleranceMargin.test.tsEnvelope vs deviation status bucketing.
  • src/lib/reservoir/__tests__/viscoDiagCsv.test.tsPer-(μ, dt) diagnostics grid CSV.
  • src/lib/reservoir/__tests__/viscoDiagFailingCsv.test.tsFailing-only CSV (rank by worst headroom).
  • src/lib/reservoir/__tests__/viscoSolverDiagnosticsDemo.test.tsSynthetic μ × dt grid that drives the page.
  • src/lib/__tests__/adaptiveEnvelopeCalibration.test.tsPer-μ envelope re-calibration from observed deviations.
  • src/lib/__tests__/perPointMultiplierSearch.test.tsPer-(μ, dt) multiplier lift search.

Quick command: bunx vitest run src/lib/reservoir/__tests__/viscoSweepMatrixCsv.test.ts src/lib/reservoir/__tests__/viscoToleranceMargin.test.ts src/lib/reservoir/__tests__/viscoDiagCsv.test.ts src/lib/reservoir/__tests__/viscoDiagFailingCsv.test.ts src/lib/reservoir/__tests__/viscoSolverDiagnosticsDemo.test.ts src/lib/__tests__/adaptiveEnvelopeCalibration.test.ts src/lib/__tests__/perPointMultiplierSearch.test.ts

Per-(μ, dt) adaptive multiplier search

Lifts envelope ONLY at failing cells until |Δ| · (1 + headroomFraction) ≤ E_μ · m. Increase headroom to push failing cells under the cap; capped cells remain genuine envelope blow-outs.

Pass16Lifted (m > 1)2Capped (fail)0Min headroom for 0 fails0 %
μ [cp]dt [d]|Δ| [psi]E_μ [psi]mE·m [psi]headroom [psi]status
0.50.20.0001.2501.00×1.2501.250pass
0.510.1001.2501.00×1.2501.145pass
0.550.2001.2501.00×1.2501.040pass
0.51000.6001.2501.00×1.2500.620pass
10.20.0002.5001.00×2.5002.500pass
110.1002.5001.00×2.5002.395pass
150.3002.5001.00×2.5002.185pass
11001.2002.5001.00×2.5001.240pass
20.20.0005.0001.00×5.0005.000pass
210.1005.0001.00×5.0004.895pass
250.4005.0001.00×5.0004.580pass
210012.0005.0002.53×12.6500.050lifted
50.20.00012.5001.00×12.50012.500pass
510.10012.5001.00×12.50012.395pass
550.60012.5001.00×12.50011.870pass
510032.00012.5002.69×33.6250.025lifted

Pilot grid: 4 viscosities × 4 dt levels (synthetic). Base envelope per μ comes from tolerancesFor({ viscosityCp: μ }).spreadAcrossSweepPsi with the tight preset.

μ × dt pass/fail matrix chart

Interactive view of the chart-ready LONG CSV (buildViscoSweepMatrixLongCsv). Paste your export or load the demo dataset; click a cell to pin its numbers.

Pass24Fail0Skipped0
μ [cp] \ dt [d]0.20.51520100
0.5
1
2
5

Color intensity scales with |headroom| (deeper green = more headroom; deeper red = larger overshoot vs envelope). Multi-metric inputs collapse to the worst status per (μ, dt) across the selected metric chips.