Wellbore Genius — User Manual
Build a model from scratch, calibrate from field data, and see every formula running in the background.
Ask the manual
betaAnswers are drawn strictly from this manual with inline section citations — click any source chip to see the exact excerpt.
Scenario limitation checker
Drag the sliders or flip the switches. Applicable limitation callouts update in real time.
PDF appendix caps — top changed items per section
Controls how many rows the Baseline diff appendix prints in the Scenario Check Report PDF. Set to 0 to hide a section body (a count is still shown). Range 0–50.
Single-phase wellbore unless the drift-flux toggle (Wellbore preview) is enabled; no OLGA-class slug tracking.
- Why it matters:
- Slug flow can spike surface pressure and mask a real screen-out signature; a single-phase kernel will report a smooth trace and the operator can miss the intervention window.
- When it breaks down:
- Anytime the produced fluid is a gas-liquid mix at surface conditions (gas-lifted wells, high-GOR flowbacks) or when foam/energized fluids are pumped.
- Safer alternative:
- Enable the drift-flux toggle in the Wellbore preview and cross-check surface pressure against the drift-flux advisory chip; for hard slug regimes use an external OLGA-class run and import the resulting BHP curve as a boundary condition.
Safer assumptionNot an OLGA replacement — no explicit slug tracker, no wax/hydrate deposition solver.
- Why it matters:
- Slugging is a real safety and equipment-integrity issue at surface separators; a drift-flux mixture average will not warn about slug-caused pressure spikes or wax/hydrate plug growth.
- When it breaks down:
- High-GOR wells during flowback, cold flowlines below wax/hydrate onset, or any topside choke-cycling operation.
- Safer alternative:
- Use this module for pressure/temperature envelopes and screening; route slug and deposition modelling to an external OLGA/LedaFlow run and import BHP/T as boundary conditions.
Safer assumptionRegime map margins are advisory chips; the closures themselves are drift-flux blended, not regime-switched.
- Why it matters:
- Blended closures can silently interpolate across a real regime boundary; the advisory chip is the only signal that the operating point is near a transition where the physics actually changes.
- When it breaks down:
- Near stratified↔intermittent transitions (Taitel-Dukler map margins) in slightly-inclined flowlines and near the bubbly↔slug boundary at low superficial gas.
- Safer alternative:
- When the advisory chip trips watch/amber, tighten the operating range or re-run with an explicit regime-switched closure library outside this tool before committing the design.
Safer assumptionEnergized-CO₂ bridge assumes a well-mixed injection stream; slug injection is not resolved.
- Why it matters:
- Slug injection produces alternating dense/gas phases downhole; a well-mixed assumption smooths the pressure/temperature signal and can miss transient breakdown windows.
- When it breaks down:
- Foamed / energized frac designs pumped without a static mixer, and any operation where CO2 is trucked into a small blender.
- Safer alternative:
- Design for a well-mixed stream at the wellhead (static mixer + minimum residence time); if slug injection is unavoidable, treat model predictions as advisory only and rely on live BHP for decisions.
Safer assumption
1. Getting started
How the app is organized: Project → Workspace (a.k.a. Sandbox) → Simulation. The Builder is where you make all changes.
Wellbore Genius uses the standard industry hierarchy. Everything you do happens inside this tree:
- Project — top-level container for a field, pad, or study (e.g. 'Bakken Tutorial').
- Workspace (a.k.a. Sandbox) — a working set of related simulations that share a base template.
- Simulation — one numerical model. You edit, validate, run, and view results at this level.
Where to make changes#
All model edits happen in the Builder. Open it from a simulation row → Edit in Builder. Inside, the panels follow this fixed industry-standard order:
- Welcome · Startup · Static model · Curve sets · Wells & perforations · Meshing · Fluid model · Fracture options · Proppants · Water solutes · Well controls · Output.
Builder header buttons (left → right)#
- Next Panel — advance to the next ordered panel.
- Validate — run all rule checks (units, ranges, missing fields).
- Discard current changes — revert to the last save.
- Save Changes — commit edits. Greyed out when there are no pending edits.
- Show/Hide tutorial steps — overlays numbered steps on the current panel.
- Comments file — attach a free-text note to the simulation.
- Save as template — promote the current sim to a reusable template.
- Export — JSON / CSV / Calibration report (PDF + CSV).
- Exit Builder — return to the simulations list.
What's new (July 2026)#
- FDI bidirectional loop — parent-depletion Δσ_h is fed back into child-frac growth each timestep, with a SWPM residual → pump-rate advisory (`/fdi-loop`).
- Live+ diagnostics pack — step-down inverter, entry-friction P10/P50/P90, DFIT pre-closure classifier, and a wellbore fluid-front animator on `/live-pumping`.
- Driller's Copilot — voice-driven hold / rate-cut / advance-stage advisories for the frac van (`/driller-copilot`).
- EDFM + MINC hybrid solver — embedded DFN + multiple-interacting-continua transfer in one linear-system solve (`/edfm-minc`).
- Regulatory pack v2 — Subpart W CH₄ XML, OGMP 2.0 Level 4/5, CO ECMC CIDER, NM_OCD TLP, and CA LCFS exports on `/regulatory-exports`.
- PVT consortium presets — one-click Wolfcamp / Bakken / Eagle Ford / Marcellus / Montney / Vaca Muerta EoS + tuning (`/pvt-consortium`).
- DAS → cluster ε → fracture-geometry inversion — per-cluster half-length from live DAS intake fractions, mounted under the DAS section of `/live-pumping`.
- Compositional 3-phase black-oil wiring with energized-CO₂ gas FVF bridge in the Fluid model panel.
2. Walkthrough — Bakken tutorial (full)
Build a Bakken model from scratch through all 12 Builder panels, validate, run, and view results — full A-to-Z reference case.
This walkthrough builds the Bakken reference case. Every panel below corresponds to a tab in the Bakken-tutorial Excel workbook. Use 'Paste from Excel tab' on each panel if you have the workbook open.
Step-by-step#
- Create a Project, then a Workspace inside it. The first time you see the Workspace landing page, you'll see an 'a.k.a. Sandbox' alias chip — click it once to dismiss.
- From the Workspace, click + New simulation → choose the Bakken template. This pre-fills PVT, conductivity, mesh, and SHmax (42°).
- Click Edit in Builder. You'll land on the Welcome panel. Click Next Panel to step through all 12.
- Startup — set simulation name, time controls, and output cadence. Tutorial steps overlay (top-right toggle) shows the recommended values.
- Static model — geomechanics layers, stress, pore pressure. Bakken preset already has SHmax = 42°.
- Curve sets — load relative permeability and capillary curves. Use Paste from Excel tab if you have the workbook.
- Wells & perforations — Wellhead x-position [ft], Wellhead y-position [ft], TVD [ft], lateral length, cluster spacing.
- Meshing — domain size and grid resolution. Smaller cells = more accurate but slower. The Bakken preset is balanced for tutorial speed.
- Fluid model — water/oil/gas PVT. Bakken preset is pre-loaded.
- Fracture options — set fracture toughness K_IC, leak-off Carter coefficient C_L, and fracture height growth rules. See Section 6 for the equations.
- Proppants — proppant type, mesh size, conductivity multipliers. Bakken preset uses 100-mesh + 40/70.
- Water solutes — chemistry tracer setup. Optional unless you're modelling a specialty material (Section 4).
- Well controls — pump schedule (rate vs. time, proppant concentration ramp).
- Output — what to save. Defaults are fine for tutorials.
- Click Validate. Fix any red-flagged issues (missing units, out-of-range values).
- Click Save Changes, then Exit Builder.
- From the simulation row, click Run (local) or Run on Server. Status chips show queued → running → completed.
- When the chip turns green, click the simulation → Results to view pressure, rate, fracture geometry, and proppant placement plots.
3. Walkthrough — DFIT calibration
Import field DFIT pressure data, run the calibration wizard, fit T₀ and K_IC, and export the Calibration report (PDF + CSV).
- Open the simulation in Builder. Click Calibration in the sidebar (or press G then C).
- Click Import DFIT and choose your pressure-vs-time CSV. Columns must include time and surface pressure (units in headers, e.g. 'p_surf [psi]').
- The wizard auto-converts to bottomhole pressure using the wellbore hydrostatic snapshot (TVD + fluid density at reservoir temperature).
- Pick the closure event on the G-function plot. The wizard fits T₀ (tensile strength) and K_IC (mode-I fracture toughness) using least-squares against the closure tail.
- Review the fitted values in the right rail. The Pressure advisor wizard will use these as defaults next time.
- Builder header → Export → 'Calibration report (PDF + CSV)' to save the inputs, assumptions, fitted values, and hydrostatic snapshot for handoff.
4. Walkthrough — Pressure advisor + Expert setup
The two main wizards: surface-pressure budget (Pressure advisor) and full job-design scenario JSON IO (Expert setup).
Pressure advisor (4 steps)#
- Builder header → Pressure advisor. Auto-prefills TVD from `inputs.mesh` midpoint, reservoir temperature from `inputs.fluid`, and last calibration point.
- Step 1 — Inputs. Review TVD, reservoir T, mud weight, frac gradient, K_IC, T₀. The Validation & warnings panel flags any value outside the realism band.
- Step 2 — Mud weight. Convert between ppg and psi/ft. The graph shows hydrostatic vs. depth.
- Step 3 — Surface budget. The advisor sums hydrostatic + friction + breakdown - pore to get required surface pressure, then compares against your pump rating.
- Step 4 — Breakdown. Shows P_breakdown = SH_min + T₀ - P_pore at the perf depth. If the surface budget exceeds your pump rating, the advisor recommends the smallest mud-weight bump that closes the gap.
- Click Apply to write the recommended values back to Wells & perforations + Well controls. Or Reset to default values to discard.
Expert setup — JSON scenario IO#
Use Expert setup when you want to script many scenarios or hand off the exact inputs to a colleague. Each wizard's inputs round-trip through a versioned `.scenario.json` file.
- Open any wizard. Click Export scenario → choose .scenario.json. The file includes a kind (pressureAdvisor / expertJobSetup / stepDownTest) and a strict, Zod-validated inputs block.
- To author by hand, click Sample templates and download the version you need (v1, v2, …). The current SCENARIO_JSON_VERSION is auto-stamped.
- Use 'inputs-only' template if you're injecting into an existing envelope.
- Click Import scenario, paste or upload the file. Older versions auto-upgrade. Lossy CSV imports show a per-field diff before applying.
5. Worked examples — numbers in, numbers out
Ten worked examples — four end-to-end workflows (DFIT calibration, surface budget, parent-child screening, live screen-out), three calculation-kernel deep dives (stress inversion, embedded DFN transfer, proppant bank height), and three regulatory / hardware-rating screens (induced-seismicity Mmax, black-oil PVT, casing collapse + burst). Realistic field inputs, the equations the app runs, the numbers it returns, and where to reproduce each one in the UI.
Each example below is small enough to retype in 2-3 minutes. Inputs are typical field values from public Bakken / Permian / Marcellus datasets. Equations match Section 6. The 'Try it yourself' callout points to the exact route to reproduce the result.
Example 1 — Bakken DFIT: fit T₀ and K_IC, then size surface pressure#
A Middle-Bakken DFIT (TVD 10,500 ft, BHST 240 °F) was pumped at 2 bpm for 4 min, then shut in. Closure picked at 7,820 psi BHP from the G-function plot.


Every input above (and the expected outputs) in one bundle. Retype the values into Builder → Calibration to reproduce the calculation step by step.
| Section | Key | Value |
|---|---|---|
| input | tvd_ft | 10500 |
| input | bhst_F | 240 |
| input | mud_weight_ppg | 9 |
| input | pore_pressure_psi | 5460 |
| input | picked_closure_psi | 7820 |
| input | isip_psi | 8150 |
| input | pump_rate_bpm | 2 |
| input | pump_duration_min | 4 |
| expected_output | fitted_SHmin_psi | 7820 |
| expected_output | fitted_SHmin_gradient_psi_per_ft | 0.745 |
| expected_output | fitted_T0_psi | 330 |
| expected_output | fitted_KIC_psi_sqrt_in | 1090 |
| Input | Value | Source |
|---|---|---|
| TVD [ft] | 10,500 | Builder → Wells & perforations |
| BHST [°F] | 240 | Builder → Fluid model |
| Mud weight [ppg] | 9.0 | Pressure advisor Step 2 |
| Pore pressure P_pore [psi] | 5,460 | Static model, ≈ 0.52 psi/ft |
| Picked closure pressure [psi] | 7,820 | G-function tail, DFIT wizard |
| Instantaneous shut-in (ISIP) [psi] | 8,150 | Pressure record |
src/lib/dfit.ts → pickClosurePressure- P_closure picked on the G-function plot
- TVD from Wells & perforations
- Closure picked on G-function (or √t) before pressure-dependent leak-off
- Vertical TVD known to ±25 ft (gradient sensitivity)
- Single-phase water-equivalent hydrostatic in the wellbore at shut-in
src/lib/dfit.ts → fitTensileStrength- ISIP from the pressure trace
- SH_min from closure
- ISIP captured within ~10 s of pump-off (water-hammer rejected)
- No near-wellbore tortuosity loss already subtracted from ISIP
The Calibration wizard then least-squares-fits K_IC against the closure tail (Carter II falloff). For this trace, the fit returns K_IC ≈ 1.2 MPa·√m (≈ 1,090 psi·√in).
| Output | Value | Where it lands in the app |
|---|---|---|
| Fitted SH_min [psi] | 7,820 | Static model panel + Pressure advisor prefill |
| Fitted T₀ [psi] | 330 | Fracture options panel + Pressure advisor |
| Fitted K_IC [psi·√in] | ≈ 1,090 | Fracture options + DS sensitivity default range |
| Calibration report (PDF + CSV) | 1 file pair | Builder → Export |
1Pick closure on the G-function plot
UI: Builder → Calibration → G-function tab → click the tail breakThe G-function curve goes flat once the fracture has fully closed. The break point IS your closure pressure — read it directly off the y-axis at BHP.
Result: P_closure = 7,820 psi2Read SH_min from closure
Closure pressure equals minimum horizontal stress for any well at this depth. Divide by TVD for the gradient sanity check (Bakken band 0.70–0.80 psi/ft).
SH_min ≈ P_closure ⇒ gradient = SH_min / TVDResult: SH_min = 7,820 psi · gradient = 7,820 / 10,500 = 0.745 psi/ft ✓3Compute tensile strength T₀ from ISIP overshoot
Instantaneous shut-in pressure overshoots SH_min by exactly the rock's tensile strength. Read ISIP off the pressure trace at pump-off.
T₀ = ISIP - SH_minResult: T₀ = 8,150 - 7,820 = 330 psi4Fit fracture toughness K_IC against the closure tail
UI: Calibration wizard → ApplyThe wizard runs a Carter-II falloff least-squares fit on the post-closure tail to back out K_IC. The minimised objective is the squared-residual sum Φ above (see §6.2 for the full module + validity range). Default K_IC search bounds are 0.5–2.5 MPa·√m.
Φ(K_IC, C_L) = Σᵢ [ p_obs(tᵢ) − p_model(tᵢ; K_IC, C_L) ]²Result: Fitted K_IC ≈ 1.2 MPa·√m (≈ 1,090 psi·√in)5Push results into the model + export the report
UI: Builder → Static model + Fracture options (auto-prefilled) · Export → Calibration reportThe fitted SH_min lands in Static model, T₀ + K_IC in Fracture options, and the wellbore hydrostatic snapshot is captured for the audit trail. The PDF + CSV pair is the deliverable.
Result: 1 PDF + 1 CSV in Builder → Export
Bakken DFIT calibration — TVD 10,500 ft, BHST 240 °F, MW 9.0 ppg.
Example 2 — Permian Wolfcamp surface-pressure budget#
Permian Wolfcamp horizontal at TVD 9,800 ft, lateral 9,500 ft, 4½-in casing. Plan: 80 bpm slickwater, 1.5 ppa peak proppant. Question: does the existing 10,000-psi surface pressure rating cover the breakdown?
| Input | Value |
|---|---|
| TVD [ft] | 9,800 |
| Mud / pad weight [ppg] | 8.5 (slickwater + FR) |
| Tubular friction gradient [psi/ft] | 0.085 @ 80 bpm in 4½-in (Hill DR sigmoid, FR @ 1 gpt) |
| Perforation friction Δp_perf [psi] | 650 (45 perfs × 0.42-in EHD) |
| SH_min [psi] | 7,250 |
| T₀ [psi] | 300 |
| Pore pressure P_pore [psi] | 5,100 |
src/lib/pressureAdvisor.ts → hydrostaticPsi- MW = mud weight [ppg]
- TVD [ft]
- Single-phase, constant-density column (no foam, no slugging)
- Vertical TVD (deviated wells use TVD, not MD)
- Cooling-credit overlay disabled (geothermal mode adds a ΔT term)
src/lib/pressureAdvisor.ts → breakdownPressurePsi- SH_min, T₀ from calibration (Example 1 pattern)
- P_pore from Static model
- Uniaxial reduction of the §6.1 Hubbert-Willis tensor (SH_max ≈ SH_min; no thermal or poroelastic Δσ)
- Pre-existing perforation (no rock cohesion term)
- Isotropic horizontal stress at the perf depth (ν-corrections lumped into SH_min)
src/lib/pressureAdvisor.ts → buildPressureBudget- All four terms from rows above
- Mud weight (Step 2)
- FR concentration (Hill DR sigmoid)
- Perf count + EHD (perf-cluster designer)
- Steady-state hydrostatic + Darcy-Weisbach friction in the wellbore (no transient water-hammer)
- Perf friction via Δp = K·ρ·q²/(N_p·A_p²) with K ≈ 0.20 for clean perfs
- FR drag-reduction follows the calibrated Hill sigmoid (frictionReducerCurve.ts)
| Output | Value | Verdict |
|---|---|---|
| Required P_surf [psi] | 1,602 | Well under the 10,000-psi rating |
| Headroom [psi] | ≈ 8,400 | Safe — you can lift rate to ~120 bpm before binding |
| Recommended action | Hold plan | No mud-weight bump needed |
1Compute hydrostatic head
UI: Pressure advisor → Step 2 (Mud weight)Mud weight in ppg, TVD in ft, 0.052 is the unit constant for psi. This is the 'free' surface pressure your pad weight gives you.
P_hydro = 0.052 × MW × TVDResult: P_hydro = 0.052 × 8.5 × 9,800 = 4,331 psi2Compute breakdown pressure at the perfs
UI: Pressure advisor → Step 4 (Breakdown)Effective-stress form (uniaxial reduction of the §6.1 Hubbert-Willis tensor — assumes SH_max ≈ SH_min; switch back to the tensor form when horizontal-stress anisotropy is measurable). SH_min and T₀ come from Example 1's calibration; P_pore from Static model.
P_breakdown = SH_min + T₀ - P_poreResult: P_breakdown = 7,250 + 300 - 5,100 = 2,450 psi3Estimate friction losses
UI: Builder → Wells & perforations → Perf cluster designerTubular friction is rate × DR-curve dependent (Hill sigmoid for FR). Perf friction comes from the n × EHD calculator.
P_friction = grad_friction × MD · Δp_perf from perf-cluster designerResult: P_friction = 0.085 × 9,800 = 833 psi · Δp_perf = 650 psi4Sum the surface budget
UI: Pressure advisor → Step 3 (Surface budget)Required surface pressure to initiate the fracture at design rate. Compare against your pump rating.
P_surf = P_breakdown + P_friction + Δp_perf - P_hydroResult: P_surf = 2,450 + 833 + 650 - 4,331 = 1,602 psi5Read headroom + recommended action
UI: Pressure advisor → Step 3 → green/red chipHeadroom = pump_rating - P_surf. The chip turns red live if you exceed rating; green means you have margin to lift rate.
Result: Headroom ≈ 8,400 psi (vs 10,000-psi rating) ⇒ Hold plan
Permian Wolfcamp surface-pressure budget — TVD 9,800 ft, MW 8.5 ppg, 4½-in casing.
Every input above (and the expected outputs) in one bundle. Retype the values into Builder header → Pressure advisor to reproduce the calculation step by step.
| Section | Key | Value |
|---|---|---|
| input | tvd_ft | 9800 |
| input | lateral_length_ft | 9500 |
| input | casing_id_in | 4.5 |
| input | rate_bpm | 80 |
| input | peak_proppant_ppa | 1.5 |
| input | mud_weight_ppg | 8.5 |
| input | tubular_friction_grad_psi_per_ft | 0.085 |
| input | perf_friction_psi | 650 |
| input | perf_count | 45 |
| input | perf_ehd_in | 0.42 |
| input | SHmin_psi | 7250 |
| input | T0_psi | 300 |
| input | pore_pressure_psi | 5100 |
| input | surface_rating_psi | 10000 |
| expected_output | P_hydro_psi | 4331 |
| expected_output | P_breakdown_psi | 2450 |
| expected_output | required_P_surf_psi | 1602 |
| expected_output | headroom_psi | 8398 |
Example 3 — Parent-child screening on a 660-ft Bakken infill#
Two parent wells produced for 3 years (drawdown ≈ 1,800 psi each, drainage radius ≈ 450 ft). New child well drilled 660 ft to the south. Question: is asymmetric growth toward the depleted side likely, and how much proppant lands at the parents?
| Input | Value | Source |
|---|---|---|
| Parent–child spacing [ft] | 660 | Plan view, /parent-child |
| Per-parent drawdown Δp [psi] | 1,800 | Production timeline (3 yr, τ = 1.5 yr) |
| Drainage radius r_d [ft] | 450 | Microseismic P75 fit, or 660/√2 |
| Biot α [-] | 0.75 | Static model preset |
| Poisson ν [-] | 0.22 | Bakken bench |
| Half-length L [ft] | 350 | Frac options |
- α = Biot coefficient
- ν = Poisson's ratio
- Δp = local drawdown from production timeline
- L_a = half-length toward depleted parent
- L_b = away
| Output | Value | Interpretation |
|---|---|---|
| Worst-stage Δσ_h [psi] | ≈ 970 | Watch band — significant rotation |
| Worst-stage asymmetry [%] | 31 | Critical — bias toward parent |
| SHmax shift [°] | 12 | Watch band (>5° info, >15° critical) |
| Frac-hit proppant per parent [lb] | ≈ 18,400 | Volumetric estimate |
| Recommended action | Re-pressurize parents OR widen spacing 660 → 880 ft | Summary chip |
1Seed the layout from a regional preset
UI: /parent-child → Inputs aside → 'Bakken-Middle' preset buttonLoads spacing, ν, α, drainage radius, and τ for the bench in one click. Override any field you have local data for.
Result: 2 parents at ±330 ft, child at y=0 · ν 0.22 · α 0.752Time-resolve drawdown via the production timeline
UI: Per-parent productionStartIso + ultimateDrawdown + τ_years + child pumpDateΔp_∞ is the ultimate drawdown; τ governs how fast pressure draws down. The child sees Δp at its pump date, not the asymptote.
Δp(t) = Δp_∞ · (1 − exp(−Δt/τ))Result: After 3 yr at τ = 1.5 yr ⇒ Δp ≈ 1,800 × (1 − e^-2) ≈ 1,556 psi per parent3Compute the poroelastic σh drop
UI: Far-field stress (full tensor) → toggle onEaton/Geertsma drop. With ν = 0.22, the coupling factor is 0.75 × 0.56 / 0.78 ≈ 0.54. Multiply by per-stage Δp from step 2.
Δσ_h ≈ α · (1 − 2ν) / (1 − ν) · ΔpResult: Worst-stage Δσ_h ≈ 970 psi (at the stage closest to both parents)4Read asymmetry from the probe-point validator
UI: Plan view → click any (x,y) to drop a probe pinL_a tilts toward the lower-σh side. > 25% triggers the bashing-risk chip.
asymmetry = (L_a − L_b) / (L_a + L_b)Result: Worst-stage asymmetry = 31% ⇒ Critical (bashing risk)5Read frac-hit volumetrics + recommended action
UI: Summary chips on the inputs asideVolumetric estimate uses swept-ellipse capture × depletion-attraction. The summary chip recommends re-pressurize or widen spacing.
Result: ≈ 18,400 lb proppant per parent · Recommended: widen 660 → 880 ft OR re-pressurize
Every input above (and the expected outputs) in one bundle. Retype the values into /parent-child (Bakken-Middle preset) to reproduce the calculation step by step.
| Section | Key | Value |
|---|---|---|
| input | spacing_ft | 660 |
| input | drawdown_per_parent_psi | 1800 |
| input | production_years | 3 |
| input | tau_years | 1.5 |
| input | drainage_radius_ft | 450 |
| input | biot_alpha | 0.75 |
| input | poisson_nu | 0.22 |
| input | child_half_length_ft | 350 |
| input | n_parents | 2 |
| expected_output | worst_stage_dSigmaH_psi | 970 |
| expected_output | worst_stage_asymmetry_pct | 31 |
| expected_output | SHmax_shift_deg | 12 |
| expected_output | frac_hit_proppant_per_parent_lb | 18400 |
Example 4 — Catching a screen-out 90 s before it happens#
Live pumping a 100-mesh + 40/70 stage at 80 bpm. The actual BHP is rising 35 psi/min faster than the planned curve. Is this a screen-out brewing, or just normal proppant ramp friction?
| Live signal | Value (rolling 60-s window) |
|---|---|
| Actual peak BHP [psi] | 9,420 |
| Planned BHP at same t [psi] | 8,930 |
| ΔP residual [psi] | +490 |
| Pnet slope on log-log [-] | +0.25 (Mode III) |
| Proppant runway at current burn [min] | 12.4 |
| Wellbore displacement: first sand at perfs in [min] | 1.8 |
- Slope from rolling-window log-log fit on the live BHP - SH_min trace
- w₁,w₂,w₃ = 0.4 / 0.4 / 0.2 default weights
- z = z-score over rolling window
| Output | Value | Operator action surfaced by the app |
|---|---|---|
| Risk pill | 0.78 (Red) | Cut sand to 0.5 ppa, hold rate |
| Auto-history-match knob diff | Γ₂ +14%, K_leak -22% | Suggests tip-restriction, not leak-off |
| ISIP auto-pick [psi] | 8,460 (high confidence) | Logged to Nolte-Smith preset for next stage |
| Plan vs. actual divergence chip | +490 psi | Visible 90 s before any pump-rating alarm |
1Mount the live transport
UI: /live-pumping → transport picker → 'Synthetic stream' (or WS/REST/WITSML)Pick the source feeding (t, BHP, surface rate, proppant conc) into the rolling buffer. Synthetic stream is the safest sandbox.
Result: Plan curve drawn live in LivePumpingPanel2Watch the plan-vs-actual residual
UI: PlanDeltaChartPanel → top chipComputed every sample. Anything sustained > 250 psi is a flag; > 500 psi joins the composite risk score.
ΔP_residual = BHP_actual − BHP_plannedResult: ΔP residual = +490 psi (rising)3Read the Nolte–Smith mode chip
UI: NolteSmithPanel → mode chipMode III is the tip-screenout precursor. Mode IV means it has already started.
slope = d log(Pnet) / d log(t) ⇒ Mode I (≈0) · II (<0) · III (+0.1–0.3) · IV (>0.5)Result: Slope = +0.25 ⇒ Mode III (tip-screenout forming)4Check the proppant runway
UI: ProppantInventoryCard → runway chipIf runway < 5 min the composite risk picks up an extra +0.2.
burn = ppa · bpm · 42 (lb/min) · runway = inventory / burnResult: Runway = 12.4 min · OK band, but watch first-sand-at-perfs (1.8 min)5Read the composite risk pill + take action
UI: LivePumpingPanel → risk pill (top right)Above 0.7 the chip turns red and the panel suggests 'Cut sand to 0.5 ppa, hold rate'. The Γ₂ tip knob auto-bumps in NetPressureMatch.
risk = 0.4·z(ΔP) + 0.4·z(slope) + 0.2·1{runway<5}Result: Risk = 0.78 (Red) ~90 s before any pump-rating alarm fires
Live screen-out demo — synthetic stream, 80 bpm, 100-mesh + 40/70.
Every input above (and the expected outputs) in one bundle. Retype the values into /live-pumping (Synthetic stream) to reproduce the calculation step by step.
| Section | Key | Value |
|---|---|---|
| input | rate_bpm | 80 |
| input | proppant_blend | 100-mesh + 40/70 |
| input | actual_peak_bhp_psi | 9420 |
| input | planned_bhp_at_t_psi | 8930 |
| input | delta_p_residual_psi | 490 |
| input | pnet_loglog_slope | 0.25 |
| input | proppant_runway_min | 12.4 |
| input | first_sand_at_perfs_min | 1.8 |
| input | rolling_window_s | 60 |
| input | risk_weights_w1_w2_w3 | 0.4 / 0.4 / 0.2 |
| expected_output | screen_out_risk | 0.78 |
| expected_output | risk_pill | Red — cut sand to 0.5 ppa, hold rate |
| expected_output | isip_auto_pick_psi | 8460 |
| expected_output | knob_diff_gamma2_pct | 14 |
| expected_output | knob_diff_kleak_pct | -22 |
Example 5 — SHmax azimuth from microseismic focal mechanisms#
A treatment in the Eagle Ford produced 14 located events with focal-mechanism solutions during the first 6 stages. Goal: recover SHmax azimuth and stress ratio R = (S2 − S3) / (S1 − S3) so the parent–child engine can rotate σh per stage instead of assuming the regional value.
| Input | Value | Source |
|---|---|---|
| # focal mechanisms (strike, dip, rake) | 14 | Microseismic vendor catalog (.csv) |
| Borehole-breakout azimuths (cross-check) [°] | [42, 48, 39, 45] | Image-log interpretation |
| Regional prior SHmax azimuth [°] | ≈ 45 (NE–SW) | World Stress Map · Eagle Ford trend |
| Min mechanisms required by inverter | ≥ 4 | invertStressTensor() guard |
- φ_SHmax — SHmax azimuth [°], 0 = North, swept on a 1° grid
- R = (S2 − S3) / (S1 − S3) — stress ratio [-], swept on a 0.05 grid
- slip_i — observed unit slip vector for mechanism i
- τ_i(σ̂) — shear traction predicted by the trial stress tensor on plane i
- invertStressTensor() in src/lib/geomechanicsStressInversion.ts
- shmaxFromBreakouts(azimuthsDeg) returns the SHmax direction in degrees
| Output | Value | Where it lands in the app |
|---|---|---|
| Inverted SHmax azimuth [°] | 47 ± 3 | /parent-child far-field card → SHmax azimuth field |
| Stress ratio R [-] | 0.62 | Drives σ2 reconstruction in poroelastic engine |
| Mean angular misfit [°] | 11.4 | < 15° ⇒ confident inversion |
| Breakout cross-check SHmax [°] | 133.5 + 90 = 43.5 | Within 4° of inversion ✓ |
1Collect focal mechanisms (strike, dip, rake)
UI: Microseismic vendor delivery → CSV with columns strike,dip,rakeEach event needs all three angles. Reject events with magnitude below your detection threshold or location uncertainty > 50 ft.
Result: 14 mechanisms, all M_w ≥ 0.82Run the grid-search inversion
UI: invertStressTensor(mechanisms) → { shmaxAzimuthDeg, stressRatio, meanMisfitDeg }1° azimuth × 0.05 R grid by default. Function returns the best (φ, R) plus mean angular misfit (a quality metric — < 15° is confident, > 25° suggests heterogeneous stress or noisy mechanisms).
min Σ |angular_misfit| over (φ_SHmax ∈ [0°, 180°), R ∈ [0, 1])Result: SHmax = 47°, R = 0.62, misfit = 11.4°3Cross-check with borehole breakouts
UI: shmaxFromBreakouts([42, 48, 39, 45]) → 133.5° (≡ 43.5° SHmax)Independent measurement from image logs. Agreement within ±10° validates the focal-mechanism inversion; > 20° disagreement means one of the two datasets is wrong.
SHmax_breakouts = circular_mean(azimuths) + 90°Result: Breakouts give 43.5°, inversion gives 47° ⇒ agree within 4° ✓4Push the result into the parent–child engine
UI: /parent-child → Far-field stress (full tensor) → SHmax azimuth = 47°Per-stage SHmax rotation now uses the inverted value instead of the regional prior. Child fracture geometry (β, tip Δ) recomputes automatically.
Result: Stage-by-stage σh rotation reflects field-measured stress
Example 6 — Embedded DFN: matrix–fracture transfer in a Wolfcamp shale#
A Wolfcamp dual-porosity cell with k_matrix = 0.0001 mD (1e-19 m²) and a single embedded fracture (k_f = 50,000 mD, half-aperture 1.5 mm, contact area 100 m²). Question: what is the matrix→fracture connectivity index (CI), and how fast does the matrix bleed off into the fracture during a 1-hour shut-in?
| Input | Value | Source |
|---|---|---|
| Matrix permeability k_m [m²] | 1.0 × 10⁻¹⁹ (≈ 0.0001 mD) | Static model · core data |
| Fracture permeability k_f [m²] | 5.0 × 10⁻¹⁴ (≈ 50,000 mD) | Conductivity test |
| Contact area A [m²] | 100 | Frac geometry × stage spacing |
| Half-distance L [m] | 0.5 | Half cell width |
| Fracture spacing [m] | 1.0 | DFN realization |
| Wellbore radius r_w [m] | 0.108 (4½-in) | Casing program |
| Initial p_matrix / p_frac [Pa] | 30 MPa / 25 MPa | Pre-shut-in snapshot |
| Total compressibility c_t [1/Pa] | 1.0 × 10⁻⁹ | PVT lumping |
- k_eff — effective interface permeability [m²]
- A — contact area between matrix and fracture [m²]
- L — half-distance from matrix center to fracture face [m]
- matrixFractureCI({ matrixPermM2, fractureK, contactAreaM2, halfDistanceM })
- s_f — fracture spacing [m]
- r_w — wellbore radius [m]
- φ_m, φ_f — matrix / fracture porosity [-]
- c_t — total compressibility [1/Pa]
- V_m — matrix block volume [m³]
- Δt — explicit step size, must satisfy CFL on the transfer term
- stepDualPorosity({ pMatrix, pFracture, ci, volumeM3, ct, dtSec })
| Output | Value | Interpretation |
|---|---|---|
| k_eff (harmonic mean) [m²] | ≈ 2.0 × 10⁻¹⁹ | Dominated by matrix — bottleneck is correct |
| CI [m³] | ≈ 4.0 × 10⁻¹⁷ | k_eff · A / L = 2e-19 · 100 / 0.5 |
| λ [-] | ≈ 2.3 × 10⁻⁸ | Tight matrix → very slow recharge (Warren–Root weak coupling) |
| ω [-] | ≈ 0.15 | Fracture stores ≈ 15% of total pore volume |
| Δp after 1 hr shut-in [Pa] | p_m drops < 1 kPa | Matrix barely moves — fracture pressure dominates |
| τ_transfer = V_m c_t / CI [s] | ≈ 2.5 × 10⁵ (≈ 70 hr) | 1 hr ≪ τ ⇒ explicit step OK at any reasonable dt |
1Compute the connectivity index
UI: matrixFractureCI({ matrixPermM2: 1e-19, fractureK: 5e-14, contactAreaM2: 100, halfDistanceM: 0.5 })The harmonic mean of two permeabilities differing by 5 orders of magnitude is ≈ 2× the smaller one — so the matrix sets the bottleneck. CI carries units of m³ because it absorbs the 1/μ that lives in the Darcy step.
CI = harmonic_mean(k_m, k_f) · A / LResult: CI ≈ 4.0 × 10⁻¹⁷ m³2Compute Warren–Root λ and ω
UI: warrenRootLambda(k_m, k_f, s_f, r_w) · warrenRootOmega(φ_m, c_tm, φ_f, c_tf)λ ≪ 10⁻⁵ means the matrix is essentially decoupled on field time scales — production comes off the fracture, then very slowly off the matrix. ω near 0.1 means the fracture system stores 10–20% of the recoverable pore volume.
λ = (k_m / k_f) · (r_w / s_f)² ω = (φc_t)_f / [(φc_t)_m + (φc_t)_f]Result: λ ≈ 2.3 × 10⁻⁸ · ω ≈ 0.153Step the dual-porosity transfer
UI: Loop stepDualPorosity({...}) for N steps of dt = 60 s over 1 hrExplicit Euler. Stable as long as Δt ≤ 2 V_m c_t / CI (≈ 5 × 10⁵ s here, so 60-s steps are massively safe). Each step bleeds a little matrix pressure into the fracture.
Δp_m^{n+1} = Δp_m^n − (CI / V_m c_t) · (p_m − p_f) · ΔtResult: After 1 hr, p_m drops < 1 kPa from 30 MPa → matrix is essentially static4Decide if you need EDFM at all
UI: Compare τ_transfer to your simulation horizonIf τ_transfer ≫ horizon (here 70 hr ≫ 1 hr), single-porosity with effective fracture permeability is accurate enough — the matrix contributes nothing. EDFM pays off when τ_transfer is within 10× of the horizon (typically multi-week / multi-month forecasts).
Result: 1 hr shut-in: skip EDFM. 6-month forecast: enable it.
Example 7 — Proppant bank height in a slickwater stage#
100-mesh sand (d_p = 150 μm, ρ_s = 2,650 kg/m³) pumped at 0.5 ppa in slickwater (μ = 3 cP, ρ_f = 1,005 kg/m³) into a vertical fracture 200 m long × 30 m tall. Question: what bank height settles out, and what fraction of the fracture footprint stays propped?
| Input | Value | Source |
|---|---|---|
| Particle diameter d_p [m] | 1.50 × 10⁻⁴ (100-mesh) | Proppant catalog |
| Particle density ρ_s [kg/m³] | 2,650 (silica) | Proppant catalog |
| Fluid viscosity μ [Pa·s] | 0.003 (3 cP, slickwater + FR) | Rheology preview |
| Fluid density ρ_f [kg/m³] | 1,005 (FR-treated water) | Carrier fluid |
| Slurry concentration [ppa → vol frac] | 0.5 ppa ⇒ φ ≈ 0.022 | Treatment schedule |
| Fracture length / height [m] | 200 / 30 | Frac geometry |
| Pump time [s] | 1,800 (30 min) | Treatment schedule |
| Net pump rate per fracture [m³/s] | 0.05 | Stage rate / # clusters |
- g = 9.81 m/s²
- ρ_s, ρ_f — particle and fluid density [kg/m³]
- d_p — particle diameter [m]
- μ — fluid viscosity [Pa·s]
- stokesSettlingVelocity(particle, fluid)
- Re_p — particle Reynolds number [-]
- terminalSettlingVelocity(particle, fluid) auto-picks the regime
- φ — local volume fraction of solids [-]
- n — Richardson–Zaki exponent (≈ 4.65 in Stokes regime, ≈ 2.4 in Newton)
- hinderedSettling(vTerminal, volumeFraction, n?)
- h_frac — fracture height [m] (caps the bank)
- t_pump — pump duration [s]
- φ_in, φ_pack — slurry and packed-bed volume fractions [-]
- L_frac, Q_horizontal — geometry and net horizontal carry rate
- predictBankHeight({ velocity, time, fractureHeightM, fractureLengthM, slurryFraction, packedFraction })
| Output | Value | Interpretation |
|---|---|---|
| v_Stokes [m/s] | ≈ 0.020 (1.2 m/min) | 100-mesh in 3 cP slickwater settles fast |
| Re_p [-] | ≈ 1.0 | Borderline — Stokes still ≈ correct, but a 40/70 sand at the same conditions would need Newton drag |
| v_hindered at φ = 0.022 [m/s] | ≈ 0.018 | 9% slowdown vs single-particle Stokes |
| Bank height h_bank [m] | ≈ 7.4 | ≈ 25% of the 30-m fracture height settles out |
| Coverage fraction (h_bank / h_frac) [-] | 0.25 | 75% of the upper fracture is unpropped — classic slickwater concern |
| Recommended action | Bump rate (cuts settling time) OR increase ppa OR slugify | Lift coverage above 0.5 |
1Compute Stokes velocity FIRST
UI: stokesSettlingVelocity({ diameterM: 150e-6, densityKgM3: 2650 }, { viscosityPaS: 0.003, densityKgM3: 1005 })For 100-mesh sand in slickwater you get ≈ 2 cm/s. That's a meaningful 1.2 m/min — proppant will land long before pump-off.
v_Stokes = g · (ρ_s − ρ_f) · d_p² / (18 μ)Result: v_Stokes ≈ 0.020 m/s2Check the particle Reynolds number
UI: Re_p = 1005 · 0.020 · 1.5e-4 / 0.003 ≈ 1.0Stokes is valid for Re_p < 1. At Re_p ≈ 1 you're at the boundary — terminalSettlingVelocity() auto-switches to Newton drag (≈ 2× higher v) for bigger sand.
Re_p = ρ_f · v · d_p / μResult: Re_p ≈ 1.0 → Stokes still applies for 100-mesh; auto-switch trips at 40/703Apply hindered settling at slurry concentration
UI: hinderedSettling(0.020, 0.022, 4.65)0.5 ppa is φ ≈ 0.022. The Richardson–Zaki correction trims velocity by 9%. At 4 ppa (φ ≈ 0.18) you'd lose nearly 60%.
v_hindered = v · (1 − φ)^n n ≈ 4.65Result: v_hindered ≈ 0.018 m/s4Predict bank height
UI: predictBankHeight({ velocity: 0.018, time: 1800, fractureHeightM: 30, fractureLengthM: 200, slurryFraction: 0.022, packedFraction: 0.55 })Bank caps at fracture height. Coverage fraction = h_bank / h_frac is the sand-coverage you'll get on the propped surface.
h_bank = min(h_frac, v · t_pump · (φ_in / φ_pack) · L / Q_horiz)Result: h_bank ≈ 7.4 m · coverage ≈ 25%5Decide what to change
UI: Compare coverage to your design target (typically ≥ 0.5)Coverage 25% is the well-known slickwater problem. Three levers: (1) lift carrier viscosity (linear gel cuts v_Stokes by μ), (2) lift rate (cuts residence time), or (3) slugify (concentrate proppant in short bursts). Most operators run all three.
Result: Plan B: 5 cP linear gel + 1 ppa slugs ⇒ recompute, expect coverage ≈ 0.55
Example 8 — Induced-seismicity Mmax screen for a saltwater-disposal well#
An SWD operator in the Delaware Basin plans to inject 50,000 bbl/day for 30 days into a basement-coupled formation. Question: what is the McGarr volumetric upper bound on the largest event the cumulative injection could trigger, and which severity band does it fall in?
| Input | Value | Source |
|---|---|---|
| Cumulative injected volume [bbl] | 1,500,000 (50k bbl/d × 30 d) | Operator schedule |
| Shear modulus G [Pa] | 2.0 × 10¹⁰ (typical basement) | Static model · core / sonic |
| Optional fault patch area [m²] | 1.0 × 10⁶ (1 km × 1 km) | Mapped fault from 3D seismic |
| Optional average slip D [m] | 0.05 (assumed scenario) | Stress-drop scenario |
| Severity ladder | Mw < 2 info · < 3 watch · < 4 amber · ≥ 4 critical | screenInducedSeismicity() |
- G — shear modulus of host rock [Pa]
- ΔV — cumulative net injected volume [m³]
- M0_max — maximum seismic moment [N·m]
- mcGarrMaxMoment(deltaVolumeM3, shearModulusPa)
- M0 — seismic moment [N·m]
- Mw — moment magnitude [-]
- momentMagnitudeFromM0(m0NewtonM)
- A — fault patch area [m²]
- D — average slip on the patch [m]
- seismicMomentFromSlip({ areaM2, shearModulusPa }, slipM)
| Output | Value | Interpretation |
|---|---|---|
| Injected volume ΔV [m³] | ≈ 2.385 × 10⁵ (1.5 M bbl × 0.159) | BBL_TO_M3 = 0.158987 |
| McGarr M0_max [N·m] | ≈ 4.77 × 10¹⁵ | G · ΔV |
| McGarr Mw upper bound [-] | ≈ 4.4 | (2/3)·(log₁₀(4.77e15) − 9.1) |
| Severity band | critical (≥ 4) | Triggers traffic-light protocol review |
| Deterministic Mw (1 km² × 0.05 m slip) | ≈ 4.6 | G·A·D ⇒ M0 = 1e15 N·m ⇒ Mw 4.6 |
| Recommended action | Stagger injection · monitor · cap daily volume | Bring Mw_upper below 4 |
1Convert injected barrels to m³
UI: BBL_TO_M3 constant in src/lib/inducedSeismicityScreen.ts1,500,000 bbl × 0.158987 ≈ 238,481 m³.
ΔV [m³] = bbl × 0.158987Result: ΔV ≈ 2.385 × 10⁵ m³2Apply the McGarr volumetric bound
UI: mcGarrMaxMoment(238481, 2e10)Treats the entire injected volume as the elastic strain energy reservoir for slip. This is conservative — most operators use it as a screening tool, not a forecast.
M0_max = G · ΔVResult: M0_max ≈ 4.77 × 10¹⁵ N·m3Convert to moment magnitude
UI: momentMagnitudeFromM0(4.77e15)Kanamori (1977). The −9.1 constant assumes M0 in N·m (use −16.1 for dyn·cm).
Mw = (2/3) · (log₁₀(M0) − 9.1)Result: Mw ≈ 4.44Read the severity chip + decide next step
UI: screenInducedSeismicity({ injectedBarrels, shearModulusPa, ... }) → severityinfo < 2, watch < 3, amber < 4, critical ≥ 4. A 'critical' chip means the operator should engage their traffic-light protocol (TLP), throttle injection, and review monitoring density.
Result: Severity = critical · TLP review required
SWD induced-seismicity screen — 50,000 bbl/day × 30 days, μ = 30 GPa.
Example 9 — Black-oil PVT for a 35°API Bakken oil at downhole conditions#
A Middle-Bakken producer flowing 35°API oil with gas gravity γg = 0.75 at BHST = 240 °F and bubble-point pressure pb = 2,500 psia. Question: at downhole flowing pressure p_wf = 4,000 psia (above bubble point), what are Rs, Bo, and oil compressibility co — and how would they change at p_wf = 1,800 psia (below bubble point)?
| Input | Value | Source |
|---|---|---|
| Oil API gravity [°API] | 35 | Sales-line gravity test |
| Gas specific gravity γg [-] | 0.75 (separator gas) | Gas chromatograph |
| BHST [°F] | 240 | Builder → Fluid model |
| Bubble-point pressure pb [psia] | 2,500 | PVT lab (CCE) |
| Flowing BHP, case A [psia] | 4,000 (undersaturated) | Well controls |
| Flowing BHP, case B [psia] | 1,800 (saturated) | Well controls |
- p — pressure [psia]
- T — temperature [°F]
- Rs — solution GOR [scf/STB]
- standingRs(p, t, api, γg)
- Bo_sat — saturated FVF [bbl/STB]
- γo — oil specific gravity [-]
- standingBoSaturated(rs, t, api, γg)
- co — oil compressibility [1/psi]
- vasquezBeggsCo(rs, t, api, γg, p)
- Bob — Bo at bubble point [bbl/STB]
- boUndersaturated(bob, co, p, pb)
| Output | Case A · p = 4,000 psia | Case B · p = 1,800 psia | Interpretation |
|---|---|---|---|
| Saturated? [-] | false (undersaturated) | true (saturated) | p vs pb |
| Rs [scf/STB] | ≈ 597 (clamped at Rs(pb)) | ≈ 386 (Standing at p) | Free gas comes out below pb |
| Bo [bbl/STB] | ≈ 1.296 (Bob · exp[−co·Δp]) | ≈ 1.236 | Oil expands as gas evolves |
| co [1/psi] | ≈ 1.4 × 10⁻⁵ | ≈ 1.5 × 10⁻⁵ | Vasquez-Beggs |
| γo [-] | 0.850 | 0.850 | 141.5 / (35 + 131.5) |
1Decide saturated vs undersaturated
UI: blackOilProperties({ pressurePsi: p, bubblePointPsi: pb, ... })Above pb the oil is single-phase liquid; below pb free gas evolves and Rs starts dropping.
isSaturated = (p ≤ pb)Result: Case A: p = 4,000 > pb = 2,500 ⇒ undersaturated. Case B: saturated.2Compute Rs (clamped at pb for undersaturated)
UI: standingRs(p_eff, 240, 35, 0.75)Standing's correlation. For undersaturated oil, Rs is fixed at Rs(pb) — no more gas can come out of solution.
Rs = standingRs(min(p, pb), T, API, γg)Result: Case A: Rs ≈ 597 scf/STB · Case B: Rs ≈ 386 scf/STB3Compute Bo at bubble point, then adjust
UI: standingBoSaturated(...) · boUndersaturated(...)Bo peaks near bubble point. Above pb it decreases with pressure (oil compresses); below pb it decreases with pressure (less gas in solution).
Bob = standingBoSaturated(Rs(pb), …) then Bo = isSaturated ? Bob(Rs(p)) : Bob · exp[−co·(p−pb)]Result: Case A: Bo ≈ 1.296 bbl/STB · Case B: Bo ≈ 1.236 bbl/STB4Push Rs/Bo/co into the material-balance + IPR
UI: Builder → Fluid model · Results → IPR cardBo and co set the material-balance drive index; Rs sets the GOR forecast. A 5% Bo error propagates ~5% to STB recovery — get this right.
Result: PVT snapshot used by /economics DCA tab + Vogel IPR
Bakken black-oil PVT — 35°API, γg 0.75, pb 2,500 psia, BHST 240 °F.
Example 10 — Casing collapse + burst check on 5½-in 17 lb/ft P-110 production string#
A Permian operator runs 5½-in OD × 0.304-in wall P-110 (yield = 110,000 psi) production casing to 9,500 ft TVD. Loads at the worst joint: collapse 6,200 psi (full evacuation), burst 9,800 psi (frac with 0.65-psi/ft fluid + 1,500 psi surface), axial 350,000 lbf (hanging weight + fluid drag). Question: does it pass API design factors, and what are the safety factors?
| Input | Value | Source |
|---|---|---|
| Outer diameter OD [in] | 5.500 | Casing tally |
| Wall thickness t [in] | 0.304 (nominal P-110 17 lb/ft) | API spec |
| Yield strength Yp [psi] | 110,000 (P-110 grade) | Mill cert |
| Collapse load [psi] | 6,200 (full evacuation @ 9,500 ft) | Worst-case collapse scenario |
| Burst load [psi] | 9,800 (frac BHP − backside) | Treatment design |
| Axial load [lbf] | 350,000 (hanging weight + drag) | Tubular drag model |
| Design factors (burst / collapse / axial) | 1.10 / 1.125 / 1.6 | Operator standard (API 5C3 default) |
- Yp — yield strength [psi]
- t — wall thickness [in]
- OD — outer diameter [in]
- barlowBurstPsi(spec)
- D/t — diameter-to-thickness ratio [-]
- yieldCollapsePsi(spec) · plasticCollapsePsi(spec) · collapseRatingPsi(spec) auto-picks the max
- A_pipe — steel cross-section [in²]
- ID = OD − 2·t — inner diameter [in]
- axialYieldLbf(spec)
- DF — design factor (operator standard, typically 1.10 / 1.125 / 1.6)
- checkCasingDesign(spec, loads, designFactors)
| Output | Value | Interpretation |
|---|---|---|
| D/t [-] | ≈ 18.1 | 5.5 / 0.304 |
| Burst rating P_burst [psi] | ≈ 12,160 | 2 · 110,000 · 0.304 / 5.5 |
| Collapse rating [psi] | ≈ 11,080 (yield regime dominates) | API 5C3 max(yield, plastic) |
| Axial yield [lbf] | ≈ 565,400 | 110,000 × A_pipe (A_pipe ≈ 5.14 in²) |
| Burst SF | ≈ 1.24 (≥ 1.10) ✓ | 12,160 / 9,800 |
| Collapse SF | ≈ 1.79 (≥ 1.125) ✓ | 11,080 / 6,200 |
| Axial SF | ≈ 1.62 (≥ 1.6) ✓ (just passes) | Watch — bump grade or wall if drag rises |
| Design verdict | PASS | All three SF clear their design factors |
1Build the spec + loads
UI: spec = { odIn: 5.5, wallIn: 0.304, yieldPsi: 110000 }; loads = { burstLoadPsi: 9800, collapseLoadPsi: 6200, axialLoadLbf: 350000 }Use mill-certified yield (nominal grade × min spec). Loads come from the worst-case operating envelope (full evacuation for collapse, frac BHP for burst, total hung weight + drag for axial).
Result: Spec + 3 loads ready for the checker2Compute ratings
UI: barlowBurstPsi · collapseRatingPsi · axialYieldLbfBarlow for burst; API 5C3 with the larger of yield-strength and plastic regimes for collapse; A_pipe × Yp for axial.
P_burst = 2·Yp·t/OD · P_collapse = max(yield, plastic) · F_axial = Yp·A_pipeResult: Burst 12,160 psi · Collapse 11,080 psi · Axial 565,400 lbf3Divide by loads → SFs
UI: checkCasingDesign(spec, loads, { burst: 1.10, collapse: 1.125, axial: 1.6 })The check returns burstSafetyFactor, collapseSafetyFactor, axialSafetyFactor, and a single passes boolean.
SF_x = Rating_x / Load_xResult: Burst 1.24 · Collapse 1.79 · Axial 1.62 · passes = true4Compare to design factors + decide
UI: Builder → Wells & perforations → Casing programFail any one ⇒ upgrade grade (e.g. P-110 → Q-125), thicken wall, or relieve loads (rate down on collapse, lower frac BHP on burst). Here axial is the tightest — if drag estimates change, re-check.
Result: Verdict: PASS, but axial SF is the bottleneck — re-check if BHA / drag changes.
Permian 5½-in 17 lb/ft P-110 casing check — TVD 9,500 ft, internal 9,800 psi.
6. Physics & equations (what runs in the background)
Every formula behind the inputs you change in sensitivity studies — fracture toughness, leak-off, hydrostatic, breakdown, stress shadowing, and proppant transport.
When you sweep a parameter in a sensitivity (DS) run, this is the math the solver evaluates. Each equation lists the UI field that drives it so you know exactly what changing K_IC, C_L, or E does.
- P_breakdown = 3·SH_min − SH_max + T₀ − P_pore (Hubbert-Willis)
- K_I ≥ K_IC (mode-I propagation criterion)
- q_leak = 2·C_L / √(t − t_open) (Carter II)
- w_max = (2(1−ν)·p_net·h) / G (PKN width)
- Δσ_h = p_net·[1 − d/√(d²+a²)] (Sneddon shadow)
- Linear-elastic, isotropic rock at the perf face
- Newtonian carrier unless rheology card overrides (n′, K′)
- Height-contained PKN unless KGD/Radial branch selected
- Carter-II leakoff (no spurt loss term unless explicitly set)
Explicit time march on stage schedule (sub-second dt during slurry), implicit Picard for wellbore-storage coupling; DDM grid for non-planar 3D.
- Hubbert & Willis (1957), Mechanics of hydraulic fracturing
- Nordgren (1972), Propagation of a vertical hydraulic fracture
- Sneddon (1946), Distribution of stress in the neighbourhood of a crack
- Carter (1957), Optimum fluid characteristics for fracture extension
- Single-phase wellbore unless the drift-flux toggle (Wellbore preview) is enabled; no OLGA-class slug tracking.Why this matters, when it breaks, what to do instead
- Why it matters:
- Slug flow can spike surface pressure and mask a real screen-out signature; a single-phase kernel will report a smooth trace and the operator can miss the intervention window.
- When it breaks down:
- Anytime the produced fluid is a gas-liquid mix at surface conditions (gas-lifted wells, high-GOR flowbacks) or when foam/energized fluids are pumped.
- Safer alternative:
- Enable the drift-flux toggle in the Wellbore preview and cross-check surface pressure against the drift-flux advisory chip; for hard slug regimes use an external OLGA-class run and import the resulting BHP curve as a boundary condition.
- Non-planar 3D uses half-space DDM with no full poroelastic coupling — pair with /parent-child for depletion-altered stress.Why this matters, when it breaks, what to do instead
- Why it matters:
- Half-space DDM captures elastic interaction between fractures but ignores the pore-pressure change that a depleting parent well leaves in the rock; ignoring depletion under-predicts frac-hit severity.
- When it breaks down:
- Infill drilling next to producers older than ~90 days, especially in reservoirs with kh above ~50 md·ft where drainage radius is large.
- Safer alternative:
- Run the /parent-child route on the same workspace and read the poroelastic Δσ_h/Δσ_H columns; feed the rotated SHmax back into the fracture design via the runtime SHmax → geometry loop.
- Parent-child far-field stress is 2-D Geertsma unless Mindlin layered toggle is on; thermo-poro time loop covered separately under §11.Why this matters, when it breaks, what to do instead
- Why it matters:
- A single-layer Geertsma disc misses vertical stress attenuation across benches; azimuth rotation predictions can be off by several degrees in stacked plays.
- When it breaks down:
- Multi-bench developments (Wolfcamp A/B/C, Middle Bakken/TFS, Marcellus/Utica) where the child is not at the same TVD as the parent depletion.
- Safer alternative:
- Enable the Mindlin layered toggle on /parent-child and supply bench (ν, α, h); if bench continuity is uncertain, run both toggles and treat the spread as the uncertainty band.
- Carter leakoff assumes negligible spurt; for tight rocks use the field-validation campaign override (`src/lib/fractureValidation.ts`).Why this matters, when it breaks, what to do instead
- Why it matters:
- Spurt loss can dominate the first few seconds of pump time in very tight rock; ignoring it under-predicts pad pressure and can steer the design toward too little pad.
- When it breaks down:
- Permeabilities below ~50 nd or when the pad fluid has a poor wall-building filter cake (slickwater into ultra-tight shale).
- Safer alternative:
- Load a DFIT or step-rate G-function into a field-validation campaign; the leakoff override in `src/lib/fractureValidation.ts` will fit spurt + Carter coefficients directly to the measured falloff.
- Proppant transport uses Stokes + Boycott tilt; full hindered-settling RZ exponent is fixed at 4.65.Why this matters, when it breaks, what to do instead
- Why it matters:
- The Richardson-Zaki exponent of 4.65 is calibrated for spherical, mono-disperse proppant in Newtonian carriers; using it outside that band under- or over-predicts proppant transport and can lead to premature screen-out or a starved zone at the tip.
- When it breaks down:
- Ultra-lightweight, coated, or fibre-laden proppants; highly-shear-thinning gels; or slurries above ~10 ppa where hindered settling deviates strongly from mono-disperse Stokes.
- Safer alternative:
- Cross-check the transport prediction against the FracPro-style report's slurry-validation card and, for non-standard proppants, override k·w with the ISO-13503-5 coverage helper (see stressConductivityCoverage.ts).
| Dataset | Source | Metric | Result |
|---|---|---|---|
| DFIT / PKN / KGD / Radial fit[1,2] | src/lib/fractureValidation.ts + field-validation campaigns route | MAE / RMSE / bias / MAPE vs measured BHP | 10 drift-guard cases, RMSE < 75 psi on synthetic decks |
| Probabilistic geometry bundle[3] | src/lib/__tests__/probabilisticFractureBundle.test.ts | P10/P50/P90 bands on Cf and surface pressure | 8 tests, Spearman tornados stable across seeds |
| Buckley-Leverett analytical comparator[4,5] | src/lib/__tests__/buckleyLeverettKernelParity.test.ts | L∞ saturation error vs Welge tangent | IMPES + TVD L∞ ≤ 0.5; TVD L1 ≤ IMPES L1 + 0.05 |
| Standing-Katz Z(p,T)[6,7,8] | src/lib/wellbore/__tests__/standingKatz.test.ts | Z vs Sutton 1985 + Wichert-Aziz sour-gas tables | 10 tests, |ΔZ| < 0.005 over reduced-T 1.05–3.0 |
| Grid-convergence harness[9,10] | /grid-convergence (3 regime scenarios) | Observed order p (Richardson extrapolation) | Upwind p ≈ 1, TVD p ≈ 2 (shock/capillary/compressible) |
| Black-oil 3P mass balance[11] | src/lib/reservoir/__tests__/compositionalBlackOil3P.test.ts | Per-step phase mass residual | 8 tests, worst |Δm|/m < 0.5 % on closed cell |
- Nolte, K.G. (1979). Determination of fracture parameters from fracturing pressure decline. SPE 8341. doi:10.2118/8341-MS
- Barree, R.D., Barree, V.L., Craig, D.P. (2009). Holistic fracture diagnostics. SPE 107877. doi:10.2118/107877-PA
- Cinco-Ley, H., Samaniego, V.F. (1981). Transient pressure analysis for fractured wells. SPE 7490. doi:10.2118/7490-PA
- Buckley, S.E., Leverett, M.C. (1942). Mechanism of fluid displacement in sands. Trans. AIME 146. doi:10.2118/942107-G
- Welge, H.J. (1952). A simplified method for computing oil recovery by gas or water drive. Trans. AIME 195. doi:10.2118/124-G
- Standing, M.B., Katz, D.L. (1942). Density of natural gases. Trans. AIME 146. doi:10.2118/942140-G
- Dranchuk, P.M., Abou-Kassem, J.H. (1975). Calculation of Z factors using equations of state. JCPT 14(3). doi:10.2118/75-03-03
- Wichert, E., Aziz, K. (1972). Calculate Z's for sour gases. Hydrocarbon Processing 51(5).
- Roache, P.J. (1994). Perspective: a method for uniform reporting of grid refinement studies. J. Fluids Eng. 116(3). doi:10.1115/1.2910291
- LeVeque, R.J. (2002). Finite Volume Methods for Hyperbolic Problems. Cambridge University Press. https://doi.org/10.1017/CBO9780511791253
- Aziz, K., Settari, A. (1979). Petroleum Reservoir Simulation. Applied Science Publishers.
6.1 Fracture initiation (breakdown pressure)#
src/lib/pressureAdvisor.ts → breakdownPressurePsi (tensor branch)- SH_min — minimum horizontal stress [psi]
- SH_max — maximum horizontal stress [psi]
- T₀ — tensile strength of the rock [psi]
- P_pore — pore pressure [psi]
- Static model → SH_min, SH_max, P_pore
- Calibration → T₀ (fitted from DFIT)
- Vertical wellbore, vertical fracture initiation
- Linear-elastic isotropic rock at the perf face
- No thermal or poroelastic Δσ correction
src/lib/pressureAdvisor.ts → breakdownPressurePsi (uniaxial branch)- Identical to the tensor form with SH_max = SH_min ⇒ 3·SH_min − SH_max = 2·SH_min, then a further simplification collapses to SH_min in cased+perforated completions where the cohesion term carries the rest.
- SH_max ≈ SH_min (low horizontal-stress anisotropy)
- Cased + perforated completion (pre-existing perforation; no rock-cohesion term)
- Effective-stress form (P_pore subtracted from total stress)
6.2 Mode-I fracture toughness (propagation criterion)#
- K_I — stress-intensity factor at the tip [psi·√in]
- P_net = P_frac - SH_min — net pressure inside the fracture [psi]
- a — fracture half-length [in]
- K_IC — fracture toughness, fitted from DFIT or from lab data [psi·√in]
- Fracture options → K_IC (this is the parameter you swept in sensitivity)
- Static model → SH_min
- Well controls → pump rate (drives P_frac)
src/lib/dfit.ts → fitDfitClosure- p_obs(tᵢ) — measured bottomhole pressure at sample i [psi]
- p_model(tᵢ; K_IC, C_L) — Carter-II falloff prediction with trial K_IC and Carter coefficient
- tᵢ — sample times inside the post-closure G-function window
- Least-squares (Gaussian) residual on the post-closure window
- Carter-II falloff is the forward operator (1-D leak-off, planar fracture)
- Equal weighting per sample; no robust loss
6.3 Carter leak-off (fluid loss to matrix)#
- v_L — leak-off velocity normal to the fracture face [ft/min]
- C_L — Carter leak-off coefficient [ft/√min]
- t — current simulation time [min]
- τ — time the element first opened [min]
- Fracture options → C_L (Carter coefficient — the second-most-common sensitivity parameter)
- Curve sets → relative permeability (sets effective C_L through compressibility)
6.4 Wellbore hydrostatic pressure#
- P_hydrostatic — pressure at depth [psi]
- 0.052 — unit conversion (psi · gal) / (lb · ft)
- ρ_mud — mud weight [ppg]
- TVD — true vertical depth [ft]
- Pressure advisor → mud weight
- Wells & perforations → TVD
6.4b Temperature-dependent fluid rheology (Arrhenius decay)#
src/lib/fluidRheologyTemperature.ts → viscosityProfileAlongFracture- μ(T) — local viscosity at fracture cell temperature T [cP]
- μ_ref — bench viscosity at reference temperature (default 150 °F) [cP]
- E_a — activation energy (per family; see §11) [kJ/mol]
- R — universal gas constant 8.314 [J/(mol·K)]
- T, T_ref — temperatures in absolute units [K]
- Fluid model → fluid family, μ_ref, T limit
- Static model → BHST
- Well controls → injection T, residence time
- Single-step Arrhenius — no shear-history or polymer-degradation coupling
- Linear T-ramp from injection to BHST (override-able)
- Above the fluid's temperature limit the model still evaluates μ but flags the cell out-of-band rather than zeroing it
6.5 PKN fracture width (height-contained model)#
- w_max — peak width at the wellbore [in]
- q — slurry rate per fracture [bpm]
- μ — apparent fluid viscosity [cP]
- L — fracture half-length [ft]
- E' = E / (1 - ν²) — plane-strain modulus [psi]
- h — fracture height [ft]
- Static model → Young's modulus E, Poisson's ratio ν
- Well controls → pump rate q
- Fluid model → viscosity μ
6.6 Proppant transport (settling velocity, Stokes)#
- v_s — settling velocity [ft/s]
- g — gravitational acceleration [ft/s²]
- d — grain diameter [in] (mesh size)
- ρ_p — proppant density [lb/ft³]
- ρ_f — fluid density [lb/ft³]
- μ — slurry viscosity [cP]
- Proppants → mesh size (sets d), proppant type (sets ρ_p)
- Fluid model → ρ_f and μ
6.6b Boycott tilt enhancement#
src/lib/proppantDuneMechanics.ts- L — fracture characteristic length [ft]
- θ — tilt angle from horizontal [rad]
- w — fracture width [ft]
- F_RZ — Richardson-Zaki hindered-settling factor (1−φ)^n, n ≈ 4.65
- Stokes settling regime (Re_p < 1)
- Tilt angle θ measured from horizontal (θ = 0 ⇒ vertical fracture, no enhancement)
- F_RZ already absorbs concentration-dependent hindering
6.7 Stress shadow (Sneddon)#
- Δσ_h — induced stress increase [psi]
- P_net — net pressure inside the source fracture [psi]
- r — perpendicular distance from the fracture plane [ft]
- c — fracture half-height [ft]
- Wells & perforations → cluster spacing
- Fracture options → height growth limits
6.7 Inclined wellbore breakdown correction (Hubbert-Willis full form)#
src/lib/wellboreInclinationFactor.ts → wellboreInclinationFactor / adjustBreakdownForInclination- inc — wellbore inclination from vertical [deg]
- β — angle between wellbore azimuth and SH_max [deg]
- σ_v — overburden stress (defaults to 1.05·SH_max if unknown) [psi]
- SH_min, SH_max — horizontal in-situ stresses [psi]
- σ_θ_v = 3·SH_min − SH_max − P_pore (classical Hubbert-Willis)
- Failure occurs in the SH_min direction around the wellbore wall
- Linear elastic rock; no near-wellbore plasticity
- σ_v ≈ 1.05·SH_max when overburden gradient unmeasured
6.8 DFIT K_IC fit objective (Carter II substituted)#
src/lib/fractureValidation.ts → fitCarterFalloff- P_meas(tᵢ) — measured BHP at sample i [psi]
- P_Carter(t; K_IC, C_L, …) — analytical falloff model
- K_IC — fracture toughness [psi·√in]
- C_L — Carter leak-off coefficient [ft/√min]
- V_0 — closure-time fracture volume [ft³]
- Single-fracture geometry assumption holds through shut-in
- Pressure-dependent leak-off not active before closure
- ISIP and SH_min already picked / known
6.9 Power-law PKN wellbore width (extends 6.1 to non-Newtonian fluids)#
src/lib/powerLawPknWidth.ts → pknWidth (widthModel: 'newtonian' | 'power-law')- n' — power-law flow behaviour index [-]
- K' — consistency index [Pa·s^n']
- q — wing volumetric rate [m³/s]
- h — fracture height [m]
- L — fracture half-length [m]
- E' — plane-strain modulus E/(1−ν²) [Pa]
- Elliptical cross-section (PKN)
- γ̇ ≈ 2q/(w·h) average gap shear rate
- Picard fixed-point converges (typical ≤ 16 iterations)
6.10 Forchheimer non-Darcy pressure drop in the propped pack#
src/lib/proppantNonDarcyBeta.ts → nonDarcyBetaPerFt / inertialReynolds- μ — fluid viscosity [Pa·s]
- v — superficial pore velocity [m/s]
- k — pack permeability [m²] (mD × 9.869e-16)
- ρ — fluid density [kg/m³]
- β — non-Darcy coefficient [1/m] (Cooke / Pursell form β = a/(k^b · φ^c))
- Single-phase flow
- Pack porosity from DEFAULT_PROPPED_POROSITY per family
- Inertial losses meaningful only when Re_β > 0.1
6.11 1-D fracture temperature profile (couples to breaker schedule)#
src/lib/fractureTemperatureProfile.ts → fractureTemperatureProfile + breakerInputsAlongFracture- T(x, t) — slurry temperature [°F]
- v(x) — local slurry velocity along the fracture [ft/s]
- α — effective thermal diffusivity [ft²/s] (default ≈ 1e-5)
- T_inj — wellhead injection temperature [°F]
- BHST — bottom-hole static temperature [°F] (initial condition)
- 1-D along-fracture flow (lateral averaging across height + width)
- Explicit upwind FD scheme; CFL ≤ 1 and Fourier ≤ 0.5 enforced by sub-stepping
- Slurry temperature dominates rock heat-up (rock-side conduction lumped into α)
6.12 Stokes settling with Francis-Boycott wall correction and Richardson-Zaki hindered settling#
src/lib/proppantSettlingRegimeMap.ts → evaluateSettlingRegime / buildSettlingRegimeMap- v_eff — effective settling velocity [ft/s]
- d — mean grain diameter [in], converted internally to ft
- w — local fracture width [in]
- μ — apparent fluid viscosity [cP], converted internally to lbm/(ft·s)
- ρ_p, ρ_f — proppant and fluid densities [lbm/ft³] (from SG)
- φ — in-situ proppant volume fraction (from ppa and proppant SG)
- n — Richardson-Zaki exponent (default 4.65 for low-Re sand-in-water)
- Newtonian carrier within the cell (power-law μ_app evaluated at γ̇ = 100 s⁻¹ when called from FluidRheologyModel)
- Spherical proppant; aspect-ratio corrections folded into the apparent SG when applicable
- Vertical fluid velocity approximated as q_slurry / (h_frac · w_frac)
- Random-close-packing cap φ ≤ 0.6
src/lib/nonPlanar3D/cohesivePressureDependent.ts → evaluateCohesiveEnvelope- T₀ — reference cohesive tensile strength [psi]
- β — pressure-dependence slope [-]
- σ_n, σ_ref — current and reference normal effective stress [psi]
- T₀_min — floor to avoid unphysical zero strength [psi]
- Linear pressure dependence within the bracket [T₀_min, T₀]
- Mode-I traction dominates the tip response (bilinear T–S curve)
src/lib/nonPlanar3D/nfLubrication.ts → stepNfLubrication- w — NF aperture [m]
- s — arc length along NF [m]
- μ — fluid viscosity [Pa·s]
- p — fluid pressure inside NF [Pa]
- q_leak — Carter leak-off sink [m/s]
- 1-D flow along NF; smooth parallel-plate cubic law
- Linear compliance for pressure-driven aperture change
- Backward-Euler implicit tridiagonal solve (unconditionally stable)
src/lib/nonPlanar3D/staggeredStabilityBound.ts → evaluateStaggeredStabilityBound- wᵢ, Lᵢ — aperture and segment length of NF segment i
- ρ_f — fluid density
- μ — fluid viscosity
- safety — user-tunable factor ≤ 1 (default 0.5)
- Explicit-staggered coupling between DDM solid step and NF lubrication step
- Smallest (w, L) pair drives the bound
src/lib/benchmarks/hfCoupledBenchmarks.ts → runAllHfCoupledBenchmarks- w(0,t) — wellbore width vs time
- L(t) — fracture half-length vs time
- p_w(t) — wellbore net pressure vs time
- Plane-strain KGD geometry; Newtonian fluid
- Constant injection rate; single vertex regime (M or K) dominates
- 5 % envelope on the observed vs analytical scaling exponent
7. Sensitivity & calibration runs
How to set up a Design-of-Sensitivity (DS) sweep and what each parameter affects.
- From the Workspace dashboard, click Sensitivity → New DS run.
- Pick the parameters to sweep. The Bakken template pre-populates K_IC, C_L, and Young's modulus with realistic ranges.
- Choose sweep type: Latin Hypercube (recommended), Full factorial, or 1-at-a-time.
- Set the response metric — e.g. 'Final propped half-length [ft]' or 'Treating pressure peak [psi]'.
- Click Queue. The DS scheduler launches one simulation per design point.
- When complete, open Results → Sensitivity tornado to see which parameter has the biggest impact on your response metric.
8. Troubleshooting
Common 'I can't change X' issues and how to fix them.
| Symptom | Likely cause | Fix |
|---|---|---|
| Save Changes is greyed out | No edits committed since last save, OR a Validate error is blocking the change. | Click outside the input to commit, then click Validate. Fix any red-flagged fields. |
| Sensitivity parameter doesn't change results | Sweep range too narrow, or the parameter is overridden by a calibration value. | Widen the range. Check Calibration → Active fits — fitted K_IC overrides Fracture options unless you Unlink. |
| Paste from Excel tab inserts blanks | Excel tab name doesn't match the panel id. | Rename the Excel tab to match (e.g. 'Wells_and_perforations') or use the per-panel column header template. |
| Run on Server stays in 'queued' forever | Server worker is paused or out of credits. | Open Settings → Compute and resume the worker. Local Run still works. |
| Results show — (em-dash) instead of numbers | That output wasn't computed for this case (e.g. proppant placement on a slickwater-only sim). | Check Output panel — enable the metric, re-run. |
| Wizard 'Apply' is disabled | One of the required fields failed realism check (red). | Open the Validation & warnings card — fix the listed fields. |
9. Live operations & post-job analysis
Real-time pumping overlay, ISIP auto-pick, Nolte-Smith, decline analysis, step-down auto-detect, net-pressure history-match, fiber-optic streaming, and live auto-tuner.
8.1 Live Pumping (/live-pumping)#
Plan-vs-actual overlay with role-banded stages (Pre-flush · Pad · Slurry · Post-flush) and a real-time screen-out risk pill. Streams via WebSocket, REST polling, WITSML, DAS or DTS — pick the transport from the picker chip group. WITSML uses Basic-auth + ?startIndex= cursor; per-workspace credentials are saved locally.
- Wellbore displacement strip — live SVG showing pumped banks with first-sand-at-perfs + flush ETA chips. Export pad-clock CSV from the strip.
- Nolte-Smith net-pressure panel — log(Pnet) vs log(t) with auto slope-classified Mode I/II/III/IV chip. Save per-job closure/window presets.
- Decline analysis — tabbed √t / log-log / G-function with closure pick + η + regime classifier (normal · PDL · height-recession · post-shut-in growth).
- Step-down auto-detect — finds ≥3 descending plateaus and chips remediation (healthy-entry · add-shots · ball-out · drop-prop slug).
- Net-pressure history-match — 5-knob panel (Γ₂ tip, complexity vol/open/leak, prop drag, TSO backfill) overlays modeled vs observed Pnet. 3 deck-preset buttons.
- ISIP auto-pick — sustained pre-pump + ≥3-of-next-5 zero-rate gate; median BHP over hammer+window with confidence chip. One-click 'Apply to Nolte-Smith'.
- Live auto-history-match — re-fits the 6 net-pressure knobs every 2-30 s from the rolling buffer (coordinate descent on rmsResidualPsi, clamped to slider envelope).
- DAS/DTS waterfall — depth × time heatmap mounted between Live Pumping and Wellbore Displacement.
8.2 Field measurements (WFT/DST/DFIT)#
Builder header → Field data → 4-step paste-CSV wizard. Vendor-neutral wireline / drillstem / mini-frac import; per-workspace storage. The Pressure Advisor warnings panel cross-checks modeled hydrostatic vs measured P (and modeled MW vs measured ρ) with engineer-entered uncertainty bands and ok/watch/amber severity.
8.3 RTA (/rta)#
Blasingame log-log + Agarwal-Gardner semi-log charts with persisted cadence overlay. Named cadence presets, late-window BDF slope diagnosis, and PI/HCPV/R² fit. Arps DCA card bins loaded (t,q) samples to monthly buckets and shows model + R² + EUR(50 yr). Probabilistic EUR runs Fast (≤200) / High (≥2000) Monte Carlo with live progress bar + cancel; σ-qi/Di/b/dMin + samples + seed are persisted.
10. Sensitivity, optimization, parent-child & economics
Diagnostic Studies tornado, OFAT sweep, Optimum Finder (NM/PSO + Pareto), parent-child interference, and DCA + economics.
9.1 Sensitivity & optimization#
- Diagnostic Studies (/diagnostic) — Pnet + screen-out tornado with troubleshooting presets and 'Pull from live stream' cross-link.
- OFAT sensitivity sweep (/sensitivity-sweep) — one-factor-at-a-time response curves; CSV export.
- Optimum Finder — Nelder-Mead + Particle-Swarm with per-algorithm penalty overrides, infeasibility-avoidance presets (off · fast-explore · soft · balanced · strict · aggressive · custom), and a compatibility validator that blocks the Find button on misconfigurations.
- Sweep frontier — weighted-sum / ε-constraint Pareto sweep across saved optima.
- Sensitivity Results visuals — Find Optimum (max/min), clickable factor cross-plots, breakeven overlay, one-click PDF, cross-workspace tornado overlay.
9.2 Parent-child interference (/parent-child)#
- Analytical frac-hit screening: log-radial Δp + Eaton Δσ_h + asymmetry + bashing-risk chip. Plan-view SVG, per-stage table, summary chips, CSV export.
- Microseismic catalog ingest — alias headers, P-percentile drainage-radius fit per parent, faint purple events overlay.
- Regional presets — Permian-Wolfcamp / Bakken-Middle / Eagle Ford / Marcellus-Dry one-click layouts.
- Production timeline — per-parent (start, Δp_∞, τ) + child pump date drives Δp = Δp_∞·(1 − exp(−Δt/τ)).
- Multi-well stress shadow — Sneddon Δσ on aligned stage midpoints + plan-view ✕ markers.
- Poroelastic full tensor — Geertsma 2-D Δσ_h/Δσ_H + SHmax rotation with severity chip and rotated SHmax ticks.
- 3-D Mindlin layered extension — multi-bench depth attenuation; collapses byte-identically to 2-D when no layers.
- Volumetric frac-hit estimate — per-stage proppant + fluid mass arriving at parents (swept-ellipse capture × depletion attraction, Σ ≤ 1).
- Child fracture geometry coupling — bend angle β, tip deflection L·sin(β), bend direction; sensitivity sweeps + Monte Carlo P10/P50/P90.
- Probe-point validator — click-to-add ✕ pins; table shows σ_h_min @ probe + L_a/L_b/asym%.
- Time-varying thermal patches — pump-up/shut-in cooling schedule (start/stop, ΔT, diffusivity, recovery τ) feeds the σh evaluator.
- Runtime SHmax→geometry t-loop — Pump time slider on the far-field card walks the time-resolved σh into child-fracture geometry.
9.3 Field validation campaigns#
Workspace-scoped module at /field-validation. Upload measured (t,P,T) gauges or (MD,P,T) gradient surveys; attach DFIT residuals + Pressure Advisor cross-checks; verdict = AND of attached comparisons. Inline FractureValidationPanel runs PKN/KGD/Radial net-pressure + optional Carter/B-C falloff vs measured BHP and highlights the lowest-RMSE kind.
9.4 DCA + Economics (/economics)#
Three tabs: Arps DCA fit (4 regional type curves) · cascade · NPV/IRR + tornado. EUR uplift publishes to /refrac. Cross-links to /rta for Probabilistic EUR (P10/P50/P90).
9.5 Auto-HM → Forecast pipeline (/auto-forecast)#
One-click orchestration of monthly production history → fitArpsToHistory → monteCarloEur → AI narrative. Sidebar: Predict → 'Auto-HM → Forecast'. Inputs: production history (one volume per line), horizon years, MC sample count, seed, σ on qi/Di/b/dMin. Outputs: fitted Arps kind/qi/Di/b/MAE/R² + P10/P50/P90/mean/std EUR chips + 4-6 bullet narrative card. See §9.4 (Arps DCA) and §8.3 (Probabilistic EUR) for the underlying math — this page is the workflow that wires them together.
- Run controls — the Run button prefetches the heavy arpsDca module on hover/focus, shows a spinner and disables itself while prefetch or compute is in flight, and surfaces a Cancel button alongside.
- Cancel safety — Cancel opens a confirmation dialog so an in-progress run is not discarded by accident. Esc keeps it running; Enter confirms the cancel. A stale-run token guards against late results from a cancelled compute leaking into the UI.
11. Reservoir, wellbore, fluids & advanced physics
RESQML/GRDECL export, transient wellbore (single-phase + drift-flux), breaker schedule, FracPro slurry library, perf-cluster designer, layer tracers, adsorption.
10.1 Reservoir export#
Builder Export → GRDECL (Eclipse) and RESQML v2.0.1 (.epc). RESQML emits CRS + IjkGrid + 3 baseline ContinuousProperty parts (pressure psi, porosity, permeability mD) + optional extras (temperature, saturation, NTG, …). Deterministic UUIDs from a seed give byte-stable output. A built-in validator runs the structural checks Petrel/RESinsight enforce.
10.2 Transient wellbore (Builder preview)#
1-D segmented pipe with implicit-Euler segregated solver (mass + momentum + energy; Swamee-Jain Darcy-Weisbach friction). Opt-in two-way wellbore-storage feedback under-relaxes the bottom-face rate (α=0.5) into the kernel. The Builder Wellbore preview also runs an α stability frontier across [0.1, 0.3, 0.5, 0.7, 1.0] and recommends the smoothest α whose total iterations stay within 25 % of the cheapest.
10.3 Drift-flux multiphase wellbore#
Pure Zuber-Findlay closures wired in via opt-in `multiphase` input. Gas-EOS-coupled mixture compressibility (ρ·c_t)_m now ships with baked-in Standing-Katz Z(p,T) (Dranchuk-Abou-Kassem 1975 + Sutton 1985 pseudo-criticals + Wichert-Aziz 1972 sour-gas correction) — opt in via `multiphase.gasEos.useStandingKatz: true` with optional gas gravity / H₂S / CO₂ mole fractions. Collapses to ideal-gas in the low-p limit. Deferred: full flow-pattern map regime classifier and OLGA-class transient multiphase (out of scope).
10.4 Fluids — breaker schedule + FracPro slurry library#
Builder Fluid model panel ships a Breaker Schedule card (5-entry catalog APS/SPS/Encap/Enzyme/HT-Ox; Arrhenius T½ doubles per 18 °F; first-order μ(t) decay; gel-damage chip). The FracPro-style slurry library (52 role-tagged entries spanning preflush/pad/slurry/postflush — incl. delayed-borate XL, mud acid 12-3, gelled & emulsified acids, cationic HVFR for produced water, HEC frac-pack, methanol-water blend, VES, hybrid slickwater, oil-based, and foam energised systems) feeds a stage-role chip filter; ρ_eff (slurry + proppant @ Cppa) cascades into Pressure Advisor mud weight → hydrostatic / ECD / surface budget / breakdown. The authoritative count comes from `STANDARD_SLURRY_LIBRARY.length` in `src/lib/hfaSlurryLibrary.ts` — if that number ever drifts from what this chapter says, the library is the source of truth and this sentence is stale.
10.4b Fluid name resolution#
src/lib/hfaSlurryLibrary.ts → STANDARD_SLURRY_LIBRARY · src/lib/fourStageFluidLink.ts- name — fluid name as entered in the schedule (case-sensitive)
- STANDARD_SLURRY_LIBRARY — 32-entry read-only catalog (src/lib/hfaSlurryLibrary.ts)
- error_chip — surfaced inline on the Treatment / Fluid mixture panel and blocks Validate until resolved
- Fluid catalog is the single source of truth — CSV/JSON ingest does NOT auto-create new entries
- Unknown names are an authoring error, not a defaulting opportunity
- Names are matched verbatim (no fuzzy-match) so library churn is visible at validate time
10.5 Perf-cluster designer#
Head-bisection split with stress bias per cluster; recommends perf count to achieve limited-entry (default min Δp_perf ≥ 500 psi).
10.6 Layer tracers + LAS → static model + adsorption#
- Layer Tracers wizard — per-layer initialization table + 'produced fraction by layer' Results card.
- LAS → Static model — equal-thickness binning to layer means; em-dash for null bins.
- Langmuir adsorption — V_L·p/(P_L+p); per-layer error+warning chain; per-workspace flag.
10.7 Pad scheduler + ML surrogate + joint history-match#
- Pad scheduler — resource-constrained multi-well Gantt packer (crew/pump/sand pools, per-well earliest start, zipper-stagger helper).
- ML surrogate — quadratic response-surface (ridge normal eqs) for sub-second sensitivity OFAT.
- Joint history-match auto-tuner — Nelder-Mead coordinate descent or PSO swarm over the 2N (shift, scale) vector; safety-guarded so RMSE never increases.
12. Reports & exports
Calibration report, FracPro-style report, scenario JSON IO, input bookmarks.
- Calibration report (PDF + CSV) — Inputs · Assumptions · fitted T₀/K_IC · wellbore hydrostatic snapshot.
- FracPro-style report (PDF + CSV) — 17-section Hydraulic Fracture Analysis output (Cover + Tables 1-22).
- Scenario JSON IO — versioned, Zod-validated, per-kind round-trippable wizard scenarios; v1 files auto-upgrade.
- Input bookmarks — generic schema-less Save/Load on Planar3D Comparator and Optimum Finder panels.
- Wellbore CSV import + re-export — auto delimiter detection, alias headers, em-dash → NaN, streaming blob round-trip.
13. Workspace toggles & UX
Reservoir type chip, table density, units & precision, keyboard shortcuts.
- Reservoir type chip — per-workspace Unconventional|Geothermal toggle gates Heat-extraction Results, EGS buttons (Cold injection, Seismicity advisor), and the Pressure Advisor cooling-credit overlay.
- Table density — Default / Dense toggle in the header; preference is remembered across sessions and auto-applies on simulation + diagnostics views.
- Tools menu (⌘K / Ctrl-K) — Units, Precision, Per-quantity precision mapping, Export current view, KaTeX status, Check for updates, Reset cache. Each item has a tooltip explaining what it does.
- Units everywhere — every field label carries units in brackets (e.g. `Wellhead x-position [ft]`). Missing numerics render as — (em-dash) in both UI and CSV/LAS exports, never 0.
14. Units & sanity checks
Canonical unit for every quantity, plus the hard/soft bounds the app uses to flag unit-confusion mistakes (m vs ft, °C vs °F, MPa vs psi).
Every field label in the app carries its unit in brackets (e.g. `Wellhead x-position [ft]`). Internally, calculations run in the canonical units below; on-screen values are converted to your chosen display system.
Units glossary#
| Quantity | Canonical | Also accepted | Convert |
|---|---|---|---|
| Length / depth | ft | m | 1 m = 3.28084 ft |
| Pressure | psi | Pa, kPa, MPa, bar | 1 MPa = 145.0377 psi |
| Stress | psi | Pa, MPa | Same as pressure |
| Temperature | °F | °C, K | °F = °C·9/5 + 32 |
| Mud weight | ppg | kg/m³, sg | 1 ppg = 119.826 kg/m³ |
| Pump rate | bpm | m³/min, m³/s | 1 bpm = 0.15899 m³/min |
| Proppant conc. | ppga | kg/m³ | 1 ppga ≈ 119.826 kg/m³ of clean fluid |
| Permeability | mD | m² | 1 mD ≈ 9.869e-16 m² |
| Viscosity | cP | Pa·s | 1 cP = 1e-3 Pa·s |
| Time | min | s, hr, day | Pumping = min; production = day |
Input sanity checks#
When you type a value into a field, the app runs a two-tier check. Hard bounds reject the value (clearly non-physical, e.g. negative depth). Soft bounds accept it but warn — they are the lever we use to catch unit-confusion (e.g. typing 50 in a depth-ft field probably means 50 m).
| Field | Unit | Hard min | Soft min | Soft max | Hard max |
|---|---|---|---|---|---|
| Depth (TVD or MD) | ft | 0 | 200 | 25 000 | 40 000 |
| Temperature (BHST) | °F | 32 | 80 | 350 | 600 |
| Pressure (BHP / surface) | psi | 0 | 100 | 20 000 | 35 000 |
15. Recently shipped (post-1.0)
Modules and physics added since the 1.0 manual: non-planar 3D solver, advanced rheology, refrac & live-ops upgrades, scenario branching, copilot palette, and more.
15.1 Non-planar 3D fracture solver (/non-planar-3d)#
Curving-surface DDM3D kernel with tip-kinking + natural-fracture branching, out-of-plane tilt, and T-junction reconvergence weld. Builder Fracture-options panel ends with a Non-Planar 3D solver section (enable · element size [ft] · max kink [°] · branch threshold [°] · max curvature [°/ft] · stress-driven curvature switch · Reset). Per-simulation Results tab mounts a step-scoreboard (rank by Kink / Growth / Opening, bar-norm By-metric / Shared-kink) with winner highlighting.
15.2 Microseismic-calibrated conductivity validation#
Card on /non-planar-3d. CSV-in for modeled k·w cloud and MS discs (moment-tensor-inverted shape from /parent-child stress inversion). Computes coverage fraction (per-disc nearest-sample k·w ≥ threshold) and contrast ratio (mean k·w inside vs outside MS discs); verdict passes when coverage ≥ 0.6 AND contrast ≥ 2.0. Exports a validation CSV.
15.3 Carreau-Yasuda + multi-mode rheology + shear-history breakdown#
- Carreau-Yasuda transition knob `aTransition` (default 2 ≡ legacy Carreau byte-identical; 0.5–1.0 sharpens the knee for HVFR / x-linked gels).
- Generalised Maxwell modes — adds `μ_k/(1+(λ_k γ̇)²)` to matrix viscosity; surfaces Oldroyd-B first normal stress N1 and Weissenberg number Wi (chip warns when Wi > 1).
- Shear-history crosslinker breakdown — integrates D(t) = 1 − exp(−∫(γ̇/γ̇_crit)^m dt) along the pump schedule with optional first-order recovery τ. 4-entry catalog: borate-guar (reversible), zirconate-CMHPG (irreversible), HPG-CMHPG (slow recovery), slickwater HVFR (irreversible).
- BreakerScheduleCard 'Apply shear-history damage' switch shortens T½ proportional to (1 − D), floored at 0.1× to prevent zero half-lives. FluidMixturePanel RheologyCrosslinkerChip shows a `· D X%` suffix when damage > 5%.
15.4 Refrac diversion designer (/refrac)#
Bottom of /refrac — particulate-bridge diverter (PBD) catalog with 6 grades + chemical staging. Boltzmann intake split, log-normal PSD plug-probability, multi-cycle survival, optional chemical Δp_div boost. CSV export via buildRefracDiversionCsv.
15.5 DAS → pump closed loop + DAS → cluster-geometry inversion#
- DAS-pump closed loop panel on /live-pumping (under DAS intake panels) — advisory hold / rate-cut / advance-stage from per-cluster DAS efficiency. Bounded by `maxRateStepBpm`, hysteresis via `stableSamples`, 200-entry audit log, optional Auto-apply switch.
- DAS → cluster geometry inversion — inverts DAS intake fractions to per-cluster efficiencies ε_i (geo-mean = 1), feeds back into the cluster flow trace and produces PKN half-length scaling L_i / L̄ = (V_i/V̄)^(2/3)·ε^(1/3).
15.6 Scenario branching tree (/branches) + cell-level blame#
- Git-style fork tree at /projects/$p/workspaces/$w/branches — SVG forest with lane×depth layout, cycle-break, orphan detection. Fork / diff / Builder actions reuse copySimulation and the builder-compare route.
- SimDiffDialog gains a Blame column — per-leaf author + relative time, per-author filter, 'Snapshot left | right' buttons, and a tracked-versions chip. History persisted via scenarioVersionsStore (≤200 per simId).
15.7 LLM copilot palette (⌘K)#
Natural-language → command routing on top of the ⌘K command palette. ✨ Sparkles button runs the copilot on-demand and renders 'Copilot picks' above the lexical 'Best matches' with reason + score. Powered by Lovable AI Gateway (google/gemini-2.5-flash, JSON-only system prompt).
15.8 Live-ops additions#
- Proppant dune overlay panel — Stokes v_s + Richardson-Zaki + Boycott-tilt enhancement; bank fraction N_s = v_eff·L/(u·h); good / ok / risk severity chip + 5 stats from the latest sample.
- Live field snapshot & share — one-tap card on /live-field producing a URL-safe encoded snapshot link and a PDF cover with advisory banner, window rows, reasons, and note. Read-only viewer at /live-field/snapshot (noindex).
15.9 Probabilistic fracture bundle (/probabilistic-geometry)#
Additive UQ extension: P10/P50/P90 bands for fracture conductivity Cf = k·w and surface treating pressure (closure + Pnet + Δp_pipe + Δp_perf − hydrostatic) + per-factor Spearman tornadoes. Power-law PKN width via optional widthModel/n′/K′ (omitted ≡ Newtonian ≡ legacy byte-identical).
15.10 Completion Quality Index (/completion-quality)#
Per-stage 0–100 score + A-F grade rollup of perf-cluster design, parent-child asymmetry, Mohr slip-tendency, and Nolte-Smith mode. Default weights 0.35 / 0.25 / 0.20 / 0.20 (renormalised on missing inputs). Grade-tinted badges + driver chips + CSV export.
15.11 Coiled tubing / snubbing + geosteering optimizer#
- /coiled-tubing — Lubinski sinusoidal + Dawson-Paslay helical buckling thresholds, regime classifier (none / sinusoidal / helical / lockup), first-lockup MD. Snubbing crossover from F_po = A_p·(p_wh − p_pipe) − buoyed weight − stripper drag.
- /geosteering — composite objective 0.5·quality + 0.3·SHmax-alignment + 0.2·containment − DLS-penalty; minimum-curvature buildup feasibility flag; ranked-results table.
15.12 Multi-well artificial-lift design (/artificial-lift)#
Closes the Prosper/Pipesim parity gap. Composite IPR (linear PI + Vogel), avg-density VLP with GLR uplift + slippage friction, gas-lift fixed-point solver, ESP / rod-pump / plunger screens, and a greedy water-fill allocation across a shared compressor with per-well caps.
15.13 Moment-tensor inversion → DFN#
From the microseismic catalog ingest. Aki-Richards 4.30 spherical→Cartesian, Vavryčuk ISO/DC/CLVD decomposition via 3×3 Jacobi, nodal planes from T/P-axes, Brune source radius r = (7M₀/16Δσ)^(1/3), Mardia clustering on fault normals → DfnFracture-shaped discs (azimuth = strike + 90°). Feeds /non-planar-3d's MS-conductivity validation.
15.14 Phase 9 — thermo-mechanical-hydraulic kernel#
Segregated implicit T → P → σ_h grid (thermoPoroGrid3D) with β-pressure source and Geertsma Δσ_h. Optional Cartesian off-diagonal shear tensor Δσ_xy/Δσ_xz/Δσ_yz via shearTensor.enabled (off by default ≡ byte-identical to legacy diagonal-only). PI-controlled coupled-transient substepper (runCoupledTransientStimulation) wraps stepThermoPoro3D with adaptive dt control and time-varying source/BC callbacks; substep records flag rejections + clamped-at-min steps.
15.15 Surrogate-trained pad-design auto-tuner#
Chains the ML surrogate predictor with the pad scheduler — tunePadDesign sweeps a per-stage Cartesian grid over surrogate ranges (≤4096 default, axis-by-axis fallback above cap), maps best y → durationMin and best x → pool demand, then hands tuned PadStages to schedulePad.
15.16 Black-oil numerics — Sprint A (Pc + TVD) & Sprint B (fully-implicit)#
- Sprint A — opt-in BlackOilNumericsOptions: capillaryPressure?.{pcOilWaterPsi(sw), pcGasOilPsi(sg)} is subtracted/added on water/gas flux Δp; saturationScheme?: 'upwind' | 'tvd-van-leer' reconstructs face Sw via van-Leer ψ(r)=2r/(1+r) with ΣS=1 renorm. Both default OFF ⇒ legacy IMPES byte-identical (≥9 decimals).
- Sprint B — coupling: 'impes' | 'fully-implicit' + fullyImplicit?.{maxNewtonIter=10, tolPressurePsi=0.1, tolSaturation=1e-4, relaxation?}. Re-enters stepBlackOil3P Picard-style until tols met; routes PVT / rel-perm / upwind / BHP reads through the latest iterate. Surfaces newtonIterations / newtonConverged / residuals.
- Side-by-side surfaces: Diagnostics tab NumericsComparatorCard + /numerics-validation SI-vs-FI harness.
15.17 Reservoir kernel extensions (v6 batch)#
- Black-oil tracers with PVT partitioning — voxel-grid passive scalars riding on the 3-phase IMPES kernel. Per cell/species: φ_α = (K_α·S_α)/Σ → c_α = φ_α·m/V_α → upstream flux. Wells inject at tracerInjection / produce at cell-average c. Independent multi-tracer (water / gas / inhibitor / energized-CO₂); optional first-order decay.
- 1D-submesh water banking — per-fracture-face log-spaced radial submesh resolves Sw(r,t) during leakoff + flowback with internal CFL substepping and optional imbibition pull-back. Mass balance < 2% on no-clamp scenarios.
- Black-oil fluid regions (PVTNUM-style) — per-region (Bo, Rs, μ_o, Bg, Bw, μ_w) tables routed per-cell via FluidRegionAssignment; applyFluidRegionOverrides masks AABB compartments.
- Zero-permeability cubes — applyZeroPermCubes masks AABB cubes of permMd to 0; harmonic-mean TPFA faces collapse, never mutates input.
- Per-well drilling-time schedule — WellActivation 4-phase classifier (idle / drilling / production / shut-in) with linear ramp ⇒ Newton-safe turn-on, dt substepper splits on well events.
- Compositional 3-phase BO wiring — new 'compositional-3p' FluidKind in FluidModelPanel (Sw / Sg / Swc + PR-EOS energized-CO₂ gas-FVF bridge); default kind unchanged.
- RESQML EPC export + schema validator + golden fixture — alongside GRDECL; opt-in extra ContinuousProperty parts (temperature / saturation / NTG / …); validateResqmlEpc catches every structural check Petrel / RESinsight enforce.
15.18 Live perforation erosion + auto-HM thermal effect#
- Live perforation erosion panel — §8.12 asymmetric Du / Ds / Dd / Cd with spatially-correlated α field (mulberry32 + Box-Muller + exp-decay smoothing); user-tunable σ_α / correlation length [ft] / seed persisted in perfErosionUncertaintyStore. Limited-entry chip from min Δp_perf on the eroded geometry vs 500 psi target. Traces NOT persisted — pure-derived from samples × prefs so replay is byte-identical.
- Live auto-HM thermal effect — opt-in μ(T) drift on the interval fit. Constant thermalScale ≠ 1 slides the fit-window location along μ^(1/4) without changing the loss-surface shape; thermalOutOfBand is advisory-only. Both coord-descent and Bayesian backends route through forwardNetPressure (never inline μ(T) per-backend). Off-collapse drift-guarded.
15.19 Petrophysics & completions additions#
- Mineralogy log interpretation — GR → IGR → V_sh via Larionov-tertiary / Larionov-older / Steiber / Clavier / linear; density-neutron crossplot RMS porosity; 3-mineral Cramer-solve inversion (quartz / carbonate / clay) on [1; ρ_b; PEF] with component clipping + matrix renorm + all-clay fallback. autoGrBaselines picks 5th / 95th percentile when ≥5 GR samples. Drops straight into lasToStaticModel.
- StageOpt wellbore proppant transport — stage-level algebraic allocator splitting proppant across clusters via Stokes-number turning efficiency η_turn = 1/(1 + St·k_inertia) + per-segment Daneshy survival exp(−v_s·L/(h·v_w)). Mass conservation Σperf + Σbed = pumped ± 1e-6 lb. CoV severity ladder ok ≤ 0.20 / watch ≤ 0.40 / amber ≤ 0.70 / critical.
- Stress-conductivity coverage + embedment chip — in ProppantLibraryPicker, ISO-13503-5 knot badge + ok / watch / extrapolating chip keyed to closure stress + rock E. 'Apply to k·w scale' writes the embedment factor (Cooke / Lacy (E_rock/E_ref)^0.5, clamped (0.05, 1]) into override.kwScale.
15.20 Builder Wells & Fracture-options additions#
- Bedding-plane fracture card (Fracture-options panel) — two-criterion Mohr-Coulomb classifier (vertical when p > σh; horizontal when p > σv − (τ_max − c)/μ_b; mixed within mixedBandPsi). Height-growth efficiency penalty H(n) = clamp(0.1 + 0.9·exp(−0.5·n), 0.1, 1). 4-play preset catalog (Vaca Muerta / Utica / Montney / deep Bakken).
- Mud-window card (Wells panel header) — Drillworks / Baker-GMI / Techlog-MEM parity. 4-limit window: pore-pressure floor (kick), Kirsch + Mohr-Coulomb shear-failure floor (breakout, closed-form q = (1 + sinφ)/(1 − sinφ)), σ_v loss ceiling, tensile breakdown ceiling p_w = 3σ_h − σ_H − α·p_p + T₀. Severity ok ≥ 1 / watch ≥ 0.3 / amber ≥ 0 / critical < 0 ppg + per-stage rollup from perfs[].mdFt.
15.21 v5 physics batch (8 modules)#
- Horizontal / bedding-plane fracture — see 15.20.
- Rate-and-state friction — Dieterich-Ruina (lab-granite defaults); criticalStiffness / nucleationLength helpers; classifyRsfStability strengthening / conditionally-stable / unstable; spring-slider simulateRateStateSlider with optional injection pore-pressure ramp.
- Gas non-Darcy inflow + advisory on gasLift — Wattenbarger D = 2.222e-15·γ·k/(μ·rw·hp²); Δψ = A·q + B·q² solver; classifyNonDarcyLoss ok / watch / amber / critical (5/15/30%); gasNonDarcyAdvisory composes Hawkins + perforation skin via gasInflowRateWithSkin.
- Stress-dependent permeability with hysteresis — Terzaghi effective stress; exponential or power-law loading; unloading anchors at peakStress with shallower γ_unload; residualFraction cap; classifyStressPermLoss ok / watch / amber / critical (10 / 30 / 60%).
- Relative permeability + capillary pressure — Corey / LET 2005 / Stone-II 3-phase oil; Brooks-Corey drainage P_c = P_e·S_we^(−1/λ) capped at maxPc; Skjaeveland mixed-wet sign-changing curve.
- Mineral scaling kinetics — MINERAL_DB (calcite / barite / FeS / SiO₂) with log10 Ksp 25 °C, Arrhenius (k_ref, Ea), TST σ/n, IAP stoichiometry. Davies-extended activity coefficient (I ≲ 0.5); saturationIndex SI = log10(IAP / Ksp); tstRate r = −k·A·sgn(1 − Ω^σ)·|1 − Ω^σ|^n; classifyScaleRisk ok / watch / amber / critical (French Creek 0.3 / 1.0 bands).
- Wellbore-stability mud-window — see 15.20.
- Formation damage & skin + IPR ↔ skin integration — Hawkins damage skin; Karakas-Tariq 1991 perforation skin (5 phasings from Economides Table 6-1); productivity ratio PR = ln(r_e/r_w) / (ln(r_e/r_w) + s); composeSkin sum + severity ok ≤ 0 / watch ≤ 5 / amber ≤ 20 / critical. Optional skin? block on WellLiftInputs auto-scales linear-PI + Vogel rate via PR; gasInflowRateWithSkin composes into the A·q + B·q² solver.
15.22 3D viewer (/viewer-3d & /viewer-3d/scientific)#
- Renders wellbore + stages + wings + offset wells from any simulation; severity-tinted by per-stage Completion Quality Index.
- View presets 1–4 (overhead / heel / cross-section / iso); R resets the camera; drag to orbit.
- Layer toggles (wellbore / stages / wings / offsets) and per-severity visibility chips; settings persisted via viewer3DPrefsStore.
- Growth scrubber — Space toggles play / pause (resets fraction at end); [ / ] step ±5%; readout shows visible/total stages + percent.
- Scene stats HUD + 'Copy stats' button (clipboard-friendly multiline summary with sim ID, wellbore length, stage / wing / offset counts, severity breakdown).
- Share-view URL preserves camera + toggles via hash params; Fullscreen toggle on the canvas wrapper.
- Exports: PNG snapshot, glTF, OBJ; AI 'Explain this scene' summary via Lovable AI Gateway.
15.23 v6 Tier-2 Track B — laminated-shale + CO₂-storage assurance#
- Phase-field / DEM laminated shale (/phase-field-dem & /phase-field-shale) — AT-1/AT-2 damage with irreversible history field, cohesive Mode-I/II traction-separation, He-Hutchinson 1989 kink-vs-pierce classifier (bedding-plane NFs), MTS kink-angle, and σh-degradation hook into the Geertsma engine. PhaseFieldFeedbackCard on /parent-child wires applyPhaseFieldFeedback (per-stage damage amplitude → σh derate) into runShmaxGeometryTimeLoop with monotone-stable σh slices; a parameter-sweep harness (runPhaseFieldFeedbackSweep) reports per-stage + worst stability rollups and exports two CSVs.
- Anisotropic-elasticity (TIV) — Thomsen 1986 ε/γ/δ → C_ij → engineering moduli {E_h, E_v, ν_h, ν_v, G_v, G_h} + directional E(θ). Wired into ddm3D + non-planar pipeline + DFN config + LaminatedShaleResultsCard.
- Proppant DEM at tip (Hertz-Mindlin bridging) — pure F_n = 4/3·E*·√R*·δ^1.5 + Coulomb-capped Mindlin tangent + N_b = w/d bridging factor + σ_rock = η·I·p_net tip-stress transfer. Wired into nonPlanar3D/pipeline.ts (B3b shipped); StepScoreboard renders a Tip-bridging column with amber tint when bridging active.
- CO₂ storage assurance (/co2-storage) — Nordbotten-Celia √t plume radius, Theis log-time over-pressure, caprock capillary seal classifier (ok / watch / amber / critical), Coulomb-failure margin, solubility / mineral / residual trapping ramps, and Darcy line-source leakage flux.
15.24 OLGA-class transient multiphase wellbore (Phase B + Phase 8)#
- Taitel-Dukler + Barnea flow-regime map — 7 regimes per segment (horizontal TD / vertical Barnea incl. churn) with marginLog for near-boundary chips.
- Enthalpy-wave solver — 1-D implicit advection-diffusion on (ρh): backward-Euler tridiag with upwind convection, Joule-Thomson, latent-heat-of-vaporisation, wall U-value coupling.
- Drift-flux multiphase wellbore — pure Zuber-Findlay closures wired into transientWellbore via opt-in WellboreStepInput.multiphase; gas-EOS-coupled (ρ·c_t)_m mixture storage; Standing-Katz Z(p,T) via DAK 1975 reduced-density Newton + Sutton 1985 pseudo-criticals + Wichert-Aziz 1972 sour-gas correction (opt-in standingKatzOptions).
- Two-way wellbore-storage feedback (Phase 8 inc 3) + α stability frontier sweep (inc 4) on the Builder Wellbore preview — 3rd collapsible card runs the synthetic ramp across DEFAULT_ALPHA_GRID, picks the smoothest α whose totalIters ≤ 1.25× the cheapest, and exposes an 'Apply recommended α' button that writes back into transientWellboreCouplingStore.
- Transient multiphase run history (Phase B inc 22–25) on /transient-multiphase-wellbore — localStorage ring buffer (cap 8) of completed runs with compare-vs-current table, A/B diff modal (changed-inputs + 7-metric ↑better/↓worse), CSV import/export (buildRunHistoryCsv + mergeRunHistory), and 6-tile sparkline trend strip (oldest → newest, Δ chip colored by improvement direction).
15.25 Phase-field σh-degradation in the runtime time loop (Track B inc B4)#
Optional per-stage phase-field damage feeds back into runShmaxGeometryTimeLoop via applyPhaseFieldFeedback + nearest-stage σh degradation in the runtime evaluator: clamped [0,1], padded / truncated, monotonic-stable across slices. Companion parameter-sweep harness (runPhaseFieldFeedbackSweep) walks a damage-amplitude grid and produces per-stage + worst stability rollups (monotone σh, max Δσh jump, bend growth, finite) plus two CSV builders.
15.26 Induced-seismicity forecaster + TLP suite (Phase F)#
- Pore-pressure → seismicity rate (Dieterich 1994) — backward-Euler γ + Δτ coseismic jump + TLP traffic-light classifier (green / yellow / amber / red).
- /induced-seismicity route — USGS catalog auto-refresh (7 cadences, decideAutoRefresh honours in-flight + document-hidden), TLP threshold preset catalog (default / OK_CC / KS_CC / TX_RRC / custom) with monotonic-ladder sanitiser, and an operator-action audit log (append-only cap-500 FIFO, CSV export). Auto-logs TLP transitions; manual rate-cut / shut-in / monitoring / regulator-report / note actions.
15.27 MRV — Subpart RR + field-validation cross-check (Phase D)#
- MRV Subpart RR report (/ccus-mrv) — 4 §-keyed sections + attestation + hash-chain proof + period-filtered ledger tail; async exportMrvSubpartRrPdf (lazy jspdf, letter, paginated) wired into the summary card with operator / facility / facility-id inputs.
- MRV ↔ field-validation cross-check card — Δp residual stats + severity ladder + ok → operator-note / watch+ → alert event builder + CSV parser. Closes Phase D.
15.28 Runtime SHmax → geometry time loop (M2) + time-varying thermal patches#
- runShmaxGeometryTimeLoop — LIVE on /parent-child via 'Pump time t [yr]' slider backed by m2TimeSliderStore. Drift-guard probePointVsThermoPoroParity covers 466 cases (extended with t-axis × effectiveDrawdownPsi(timeline, pumpDateIso) per-parent timelines).
- Time-varying thermal patches (Phase 1d) — per-patch injection schedule (start / stop ISO, peak ΔT, diffusivity ft²/day, recovery τ days, optional max radius). Cold zone evolves through pump-up (r = √(D·t_inj), ΔT = peak) and shut-in (r keeps spreading, ΔT = peak·exp(−t_post/τ)). Merged with static patches per slice and fed into BOTH analyzePoroelastic calls (main + runtime σh evaluator). Depletion-only collapses byte-identically.
- Per-workspace UI prefs (°F / °C + ft²/day / m²/day) via thermalPatchUnitsStore; storage stays canonical.
15.29 Trust gates — analytical-gate trio + grid-convergence#
- Analytical-gate trio — McWhorter-Sunada 1-D capillary imbibition + Morel-Seytoux 2-D five-spot areal sweep + Theis radial pressure transient. Three pure libs + 26 drift-guards; closes the gaps beyond Buckley-Leverett.
- Grid-convergence suite (/grid-convergence) — runs the kernel at nx0 / 2·nx0 / 4·nx0 × upwind / TVD, reports observed order p, and rolls up FI convergence + worst mass-balance % into the TrustRollupChip on /numerics-validation and the NumericsComparatorCard header (ok < 0.5% / watch < 2% / review otherwise). Broadened with 3 regime scenarios (shock / capillary / compressible) + recommendScheme(run) heuristic.
- Black-oil trust gates — pure Buckley-Leverett (Corey fw + Welge tangent + profile sampler + L1/L∞ comparator) and mass-balance report (phaseInPlace via kernel pvtAt + per-step absolute / relative residual incl. worstRelative). Kernel parity drift-guard locks IMPES + TVD L∞ ≤ 0.5 vs BL.
15.30 Phase 16 — coupling-direction promoted default-ON#
reservoirCouplingStore default flipped false → true + new mirror blackOil3PCouplingStore (default true, key downhole.dfit.blackOil3PCoupling.v1). SolverPreferencesCard gains a 2nd Switch row for blackOil3PCoupling. /solver-spec scoreboard coupling-direction row promoted next-up → shipped. Explicit setEnabled(false) overrides persist so users who turned coupling off pre-promotion keep that choice (only the 'absent localStorage entry' branch flips).
15.31 Design Copilot ↔ fleet priors (Phase E)#
/design-copilot 'Fleet priors' card — basin Input + 'Loosen to fleet P10/P90' Switch + live tightening-preview chips. Calls tightenDesignFactorsFromBasin to clamp design-factor ranges toward measured P10/P90 from the regional fleet, with a sonner toast on Run.
15.32 Voice-First surfaces + readback dock#
- Global floating readback dock — bottom-right PTT button that routes spoken questions to the most recently active results-bearing surface (RTA, Economics, Optimizer). Uses a pub/sub context store so the active surface always wins; hides when no surface is active or the Web Speech API is unavailable.
- Voice dictation for numeric fields — inline mic button next to any numeric input. parseDictatedQuantity handles number words, decimals, units (bpm/psi/ppm/ppa/ppg/gpm/bbl/gal/lb/ft/in/m/kpa/mpa/F/C/%), and 'k/M' suffixes. Drop-in component: DictateNumericFieldButton.
- Results readback intent matcher — classifyResultsQuery scores each metric by matched-pattern character length; answerResultsQuery composes a speakable utterance and pipes it into the TTS engine. Per-surface metric registries for RTA, Economics, and Optimizer.
- Audio cue mute controls — circular mute/unmute toggle in VoiceReadbackDock plus the 'M' keyboard shortcut; both immediately update the audio cue store and the UI stays in sync via a manual subscription mechanism.
15.33 Copilot v2 — streaming, memory, search, tools#
- Streaming responses in CopilotDrawer — ReadableStream + getReader(), with an AbortController and a Stop button so users can cancel mid-generation; partial output is preserved with a ⏹ Stopped marker.
- Per-page / per-simulation chat history — threads are scoped by context key (e.g. ws_<id>/sim_<id>) and automatically restore when you return to the same page or simulation.
- History search and filtering inside the drawer — query filter, role filter, recency filter, match highlighting via HighlightedText, and hit counts. Powered by copilotThreadSearch.
- Copilot tool registry — 7 safe app-side tools (jumpToPanel, applyKnob, runOptimum, runSweep, saveBookmark, openSimulation, appendActivityLog) with Zod inputSchemas, needsApproval gates, and caller-injected executors. UI wiring deferred to the Engineer/Driller Copilot toolsets.
15.34 Driller's Copilot (RigSense)#
- Six-tab driller-facing AI co-pilot at /driller-copilot — Stuck-pipe early warning, Kick/loss + dynamic mud window, MSE founder advisor, Trip swab/surge advisor, Voice Q&A, and Auto morning report.
- Pure diagnostic engines under src/lib/driller/ — stuckPipeEarlyWarning (differential / mechanical / pack-off proxies), kickLossDetector (flow surplus + pit gain + live mud-window margins), mseFounderAdvisor (Teale MSE regime classifier + WOB/RPM step recommendation), tripSwabSurgeAdvisor (Burkhardt Δp + dynamic effective MW + bisected max-safe pipe velocity).
- LocalStorage RAG corpus for offset reports — offsetReportsStore + lexical searchOffsetReports; aiDrillerCopilotContext caps the payload at 8 KB. askDrillerCopilot server function calls Lovable AI Gateway (google/gemini-2.5-flash, JSON-only system prompt, 10 s timeout).
15.35 Wellbore sensitivity suite#
- FracCADE-style depth ladder at /projects/$p/workspaces/$w/wellbore-sensitivity — Quick (5-factor tornado) and Custom (engineer-picked factors with ±1–90% swings) across three domains: Well path, Completion, and Tubing. Persistence via wellboreSensitivityDepthStore.
- Saved scenarios panel — per-workspace named configurations stored in localStorage; save, load, rename, and delete. Scenarios encode the depth ladder + factor selections + per-factor swings. Export CSV header: Factor,Units,Low value,High value,Low metric,High metric,Swing,|Swing|.
- Shareable scenario links — any saved scenario can be shared via a base64url-encoded URL payload; the recipient lands on the same workspace surface with the scenario loaded.
- Dual-scenario comparison at /wellbore-sensitivity/compare — side-by-side picker, diff table highlighting changed values, and an 'unchanged' toggle. Dual-scenario sharing via URL hash (#compareA=...&compareB=...). The last compared pair is restored per workspace from localStorage.
15.36 Global navigation — Help drawer + Command palette#
- Searchable Help drawer (⌘?) — manual search, recent pages, and quick links. Mirrors the /manual route content without leaving the current page.
- Command palette (⌘K) — hybrid lexical + semantic command ranking. The ✨ Sparkles button runs the LLM copilot on-demand and renders 'Copilot picks' above the lexical 'Best matches' with reason + score. Built on commandPaletteHybridSearch and commandCopilot.
15.37 Validated wellbore pressure sandbox#
- Interactive sandbox at /sandbox/wellbore-pressure — live form, hydrostatic / temperature / wellbore pressure breakdown grid, and per-field validation. Runs the same wellborePressureEngine used elsewhere in the app.
- Industry-validated test suite — 24 SPE/IAPWS reference cases, 39 edge-case tests, and 8 seeded fuzz tests covering hydrostatic, temperature, and wellbore pressure calculations.
- WellborePressureResult fields documented in docs/wellbore-pressure-result.md; bottomholePressurePsi is aliased as bhpPsi for API alignment. Sandbox state is shareable via base64url-encoded URL.
16. What's new — v1.4 vs v1.3
Release notes for manual v1.4 (June 2026). Lists every feature shipped since v1.3 (May 2026), grouped by track.
Manual v1.4 (June 2026) consolidates every feature shipped since v1.3 (May 2026). The detailed deep-dives live in §15.32–15.37; this section is the at-a-glance changelog you can scan in 60 seconds.
Highlights#
- Voice-First surfaces are now documented end-to-end — readback dock, per-field dictation, results readback, and the new mute toggle + 'M' shortcut.
- Copilot v2 adds streaming responses with a Stop button, per-page chat history, history search/filtering inside the drawer, and a safe tool registry for future AI-driven actions.
- Driller's Copilot (RigSense) ships six AI-powered drilling advisors at /driller-copilot.
- Wellbore sensitivity suite closes the FracCADE-style depth-ladder gap with Quick/Custom tiers, saved scenarios, shareable links, and a dual-scenario comparison page.
- Global navigation upgrades — searchable Help drawer (⌘?) and a hybrid LLM-assisted Command palette (⌘K).
- Validated wellbore pressure engine sandbox with shareable state and documented output fields.
Shipped features by track#
| Track | Feature | Where to find it | Deep-dive |
|---|---|---|---|
| Voice | Global readback dock + PTT routing to active results surface | VoiceReadbackDock in __root | §15.32 |
| Voice | Per-field numeric dictation + unit-aware parser | DictateNumericFieldButton | §15.32 |
| Voice | Results readback intent matcher + per-surface registries | voiceResultsReadback.ts | §15.32 |
| Voice | Audio cue mute toggle + 'M' keyboard shortcut | VoiceReadbackDock | §15.32 |
| Copilot | Streaming responses with Stop button in CopilotDrawer | CopilotDrawer | §15.33 |
| Copilot | Per-page / per-simulation chat history persistence | copilot scope store | §15.33 |
| Copilot | History search + filter + highlight inside the drawer | copilotThreadSearch | §15.33 |
| Copilot | Safe tool registry (7 tools with Zod schemas + approval gates) | copilotTools.ts | §15.33 |
| Driller | RigSense six-tab driller co-pilot (stuck/kick/MSE/trip/voice/morning) | /driller-copilot | §15.34 |
| Wellbore sensitivity | FracCADE-style depth ladder (Quick/Custom) across well path / completion / tubing | /wellbore-sensitivity | §15.35 |
| Wellbore sensitivity | Saved scenarios + shareable scenario links | wellboreSensitivityScenariosStore | §15.35 |
| Wellbore sensitivity | Dual-scenario comparison + shareable compare links | /wellbore-sensitivity/compare | §15.35 |
| Navigation | Searchable Help drawer (⌘?) | /help | §15.36 |
| Navigation | Hybrid LLM-assisted Command palette (⌘K) | CommandPalette | §15.36 |
| Physics + docs | Validated wellbore pressure sandbox + documented result fields | /sandbox/wellbore-pressure | §15.37 |
Default behavior changes (read carefully)#
Migration notes#
- No schema migrations required — every new store uses a fresh localStorage key.
- Voice-First surfaces are opt-in by browser capability (Web Speech API). The dock and inline mic buttons render null when the API is unavailable.
- Copilot chat history is scoped by page/simulation context; existing chats without a context key remain in the default global thread.
- Wellbore sensitivity scenarios and comparison pairs are stored per workspace; shared links are ephemeral and do not write to the recipient's saved scenarios.
17. Glossary
Industry terms used verbatim, plus the few names we changed.
| Term | Meaning |
|---|---|
| Workspace (a.k.a. Sandbox) | Also called a 'Sandbox' in some simulators — a working set of related simulations sharing a base template. |
| Simulation | One numerical model. Edit, validate, run, and view results at this level. |
| DS run | Design-of-Sensitivity run — a parameter sweep across many simulations. |
| DFIT | Diagnostic Fracture Injection Test — short-injection field test used to fit T₀ and K_IC. |
| G-function | Time-transform used to identify fracture closure on a DFIT pressure trace. |
| K_IC | Mode-I fracture toughness — resistance of the rock to fracture-tip propagation. |
| C_L | Carter leak-off coefficient — fluid loss rate to the matrix per √time. |
| SH_min / SH_max | Minimum / maximum horizontal in-situ stress. |
| T₀ | Tensile strength of the rock. |
| TVD | True vertical depth — vertical distance from surface to a downhole point. |
| BHST | Bottom-hole static temperature. |
| BHP | Bottom-hole pressure. |
| MD | Measured depth — distance along the wellbore from surface. |
| ppg | Pounds per gallon — common mud-weight unit. |
18. v8 engineering physics — derivations
Closed-form references and call-site pointers for the six engineering gaps shipped in the v8 physics round (verification, shale dual-continuum, slurry & screen-out, wellbore detail, boundary conditions).
Each derivation below maps an equation in the kernel to its textbook source so an engineer can audit the call site, the assumptions, and the validity band in one pass. The /trust/analytical-verification dashboard scores cases 1-3 against these formulas every build, and the /physics-gaps-v8 dashboard surfaces the live verification-mode chip (history-matched vs. independent).
18.1 KGD half-length (verification case 1)#
src/lib/verification/analyticalSuite.ts → kgdHalfLength- x_f — fracture half-length [ft]
- E' = E / (1 − ν²) — plane-strain modulus [psi]
- q — single-wing injection rate [bbl/min, converted to ft³/s in solver]
- µ — Newtonian carrier viscosity [cp]
- h — fracture height [ft]
- t — pump time from start of injection [s]
- Plane-strain (height ≫ length)
- Newtonian fluid, constant rate
- Viscosity-dominated (toughness negligible)
- Symmetric two-wing growth
18.2 PKN width and length (verification case 2)#
src/lib/verification/analyticalSuite.ts → pknGeometry- w_w — maximum wellbore width [in]
- Other symbols as in 16.1
- Height fully contained between barriers
- Length ≫ height (plane-strain perpendicular to length)
- Newtonian fluid; non-Newtonian routed through the power-law variant
18.3 Radial-toughness penny-fracture (verification case 3)#
src/lib/verification/analyticalSuite.ts → radialToughnessRadius- R — penny radius [ft]
- K_IC — Mode-I fracture toughness [psi·√in]
- Penny-shaped (axisymmetric) fracture
- Toughness-dominated (viscosity negligible)
- Homogeneous infinite medium
18.4 Dual-porosity Warren-Root (Gap 2a)#
src/lib/dualPorosityDualPerm.ts → warrenRootParameters- ω — fraction of storage in the fracture network [-]
- λ — matrix-to-fracture transfer rate [-]
- α — shape factor (Kazemi 4·(1/L_x²+1/L_y²+1/L_z²) for rectangular blocks)
- k_m / k_f — matrix vs. fracture permeability [mD]
- r_w — wellbore radius [ft]
- Pseudo-steady matrix-to-fracture transfer
- Single-phase slightly compressible flow
- Idealised orthogonal fracture network
18.5 Palmer-Mansoori swelling (Gap 2b)#
src/lib/matrixSwelling.ts → palmerMansooriDeltaPhi- φ₀ — initial matrix porosity [-]
- c_m — pore compressibility [1/psi]
- M — constrained axial modulus [psi]
- K — bulk modulus [psi]
- ε_L, P_L — Langmuir strain and pressure
- P, P₀ — current and reference pore pressure [psi]
- Uniaxial strain, constant overburden
- Langmuir isotherm describes adsorbed phase
- Elastic deformation only
18.6 Slurry density and tip screen-out (Gap 3)#
src/lib/slurryPvt.ts → slurryDensity ; src/lib/tipScreenoutPredictor.ts → predictTipScreenOut- ρ_carrier — base fluid density [ppg]
- C_ppa — proppant loading [lb/gal added]
- ρ_prop — proppant true density [g/cc]
- V_tip / V_slot — proppant volume / slot volume at the tip [-]
- η_pack — packing efficiency, default 0.62 (loose) … 0.74 (HCP)
- Single-component proppant
- Plug flow at tip (no slip)
- Linear superposition of pad + slurry banks
18.7 Near-wellbore tortuosity Δp (Gap 4)#
src/lib/nearWellboreTortuosity.ts → romeroClearyDp ; src/lib/perfClusterDesign.ts → dpPerfPsi- γ_rom — Romero discharge coefficient (≈ 0.95)
- ρ — slurry density [lb/ft³]
- q — single-cluster rate [bbl/min]
- A_perf — open perforation area [in²]
- κ_cleary — Cleary tortuosity factor (0.05 - 0.20)
- N_links — number of fracture link-ups
- Incompressible slurry at perf entrance
- Single-fluid (slurry density represents the bank at the perfs)
- Symmetric link-up across the cluster
18.8 Boundary conditions (Gap 5)#
src/lib/boundaryConditions.ts → applyBoundaryCondition- p_b — prescribed boundary pressure [psi]
- q_b — prescribed boundary flux [STB/d/ft²]
- α, β, γ — Robin coefficients (units chosen so the equation is dimensionally consistent)
- z_FWT — true vertical depth of the free-water table [ft]
- Each face owns a single BC kind
- Free-water-table BC assumes hydrostatic water column above the table
- Robin coefficients are constant per face (extend to position-dependent via patches)
19. What's new — v1.7 vs v1.6
Release notes for manual v1.7 (July 2026). Consolidates every feature shipped since v1.6 (June 2026), grouped by track.
Manual v1.7 (July 2026) captures the physics + workflow batch that closed the v4/v5/v6 competitor-gap audits and the Phase 15 rheology upgrade. Deep-dives live in the linked routes; this section is the at-a-glance changelog.
Highlights#
- Non-planar 3D fracture solver — surface-mesh DDM with tip kinking, natural-fracture branching, out-of-plane tilt, and T-junction reconvergence weld (see /non-planar-3d + per-simulation Results tab).
- Compositional 3-phase black-oil kernel wired into the Fluid model panel (energized-CO₂ PR-EOS bridge, IMPES + tracers + fluid regions + zero-perm cubes + per-well drilling times).
- Multi-well pad artificial-lift design (gas lift / ESP / rod pump / plunger) at /artificial-lift with shared-compressor allocation.
- Coiled-tubing & snubbing reach analyzer at /coiled-tubing (Lubinski + Dawson-Paslay buckling) and geosteering optimizer at /geosteering (SHmax alignment + containment + DLS feasibility).
- Refrac diversion designer (PBD + chemical staging, multi-cycle survival) mounted on /refrac.
- v5 rock+fluid physics bundle: bedding-plane fracture card, mud-window card, formation-damage + perforation skin, rate-and-state friction, stress-dependent permeability with hysteresis, LET / Stone-II rel-perm, mineral scaling kinetics, gas non-Darcy inflow.
- Phase 15 rheology upgrade: Carreau-Yasuda with optional Maxwell modes + crosslinker shear-history damage folded into the breaker schedule.
- Scenario branching tree at /branches (git-style fork/diff) and cell-level scenario blame in SimDiff.
- LLM Copilot picks in the ⌘K Command palette (Gemini 2.5 Flash via Lovable AI Gateway).
- RESQML v2.0.1 EPC export validated against a golden fixture — round-trippable in Petrel / RESinsight.
Shipped features by track#
| Track | Feature | Where to find it |
|---|---|---|
| Fracture physics | Non-planar 3D solver (M1-M4 + reconvergence weld) | /non-planar-3d + Results tab |
| Fracture physics | Bedding-plane / horizontal fracture classifier | Builder → Fracture options |
| Fracture physics | Refrac diversion designer (PBD + chemical) | /refrac |
| Reservoir | Compositional 3-phase black-oil + PR-EOS energized-CO₂ | Builder → Fluid model |
| Reservoir | Fluid regions (PVTNUM) + zero-perm cubes + per-well drilling times | solver kernel |
| Reservoir | Stress-dependent k with hysteresis + LET / Stone-II rel-perm | rock-mechanics library |
| Reservoir | Mineral scaling kinetics (calcite / barite / FeS / SiO₂) | scaling library |
| Wellbore | Mud-window safe operating envelope | Builder → Wells & perforations |
| Wellbore | Formation damage + Karakas-Tariq perforation skin | IPR composition |
| Wellbore | Coiled-tubing & snubbing reach (Lubinski + Dawson-Paslay) | /coiled-tubing |
| Wellbore | Gas non-Darcy inflow (pseudo-pressure + Wattenbarger turbulence) | gas IPR library |
| Production | Multi-well pad artificial-lift + shared-compressor allocation | /artificial-lift |
| Well placement | Geosteering optimizer (SHmax alignment + DLS feasibility) | /geosteering |
| Induced seismicity | Rate-and-state friction (Dieterich-Ruina spring-slider) | seismicity library |
| Rheology | Carreau-Yasuda + optional Maxwell modes + Wi / N₁ chip | Builder → Fluid model |
| Rheology | Crosslinker shear-history damage folded into breaker T½ | BreakerScheduleCard |
| Workflow | Scenario branching tree (git-style fork / diff) | /branches |
| Workflow | Scenario version blame in SimDiff (per-leaf author + time) | SimDiffDialog |
| Copilot | LLM Copilot picks in ⌘K Command palette | CommandPalette |
| Interop | RESQML v2.0.1 EPC export (golden-fixture validated) | /interop |
Default behavior changes (read carefully)#
Migration notes#
- Fluid kind now includes 'compositional-3p' in addition to black-oil; existing simulations keep their current kind and default to black-oil.
- Non-planar 3D results are appended to each simulation as an extra Results tab when the solver is enabled; disabling reverts to the planar Results view.
- The bedding-plane card mounts at the end of Fracture options — existing tutorial snapshots that assert panel length were regenerated in the same edit.
- Command palette 'Copilot picks' require LOVABLE_API_KEY (Lovable Cloud users have this pre-set); without it the ✨ button is hidden and only lexical matches show.
20. What's new — v1.8 (operator surface + advanced physics)
Seven newly documented routes: Driller's Copilot, Live+ diagnostics pack, Transient multiphase wellbore, CCUS/MRV ledger, Induced-seismicity forecaster, Non-planar 3D solver, and the updated Solver spec scoreboard. Each includes a short walkthrough plus the governing equations.
Manual v1.8 documents the operator-facing surfaces and advanced-physics routes shipped after the v6 competitor-gap closure. Every route below is live in production; the walkthroughs mirror the on-screen tabs and cards so a new engineer can go from cold-open to a defensible answer without a mentor.
20.1 Driller's Copilot (RigSense) — /driller-copilot#
Six-tab driller-facing assistant that watches the rig telemetry stream and calls out stuck-pipe risk, kick/loss, MSE founder, swab/surge, and answers voice questions. All physics is pure — the AI layer (Lovable AI Gateway, Gemini 2.5 Flash) is used only for Q&A and morning report drafting, never for a setter action.
- MSE = WOB/A_b + (120·π·RPM·τ)/(A_b·ROP) (Teale, ksi)
- Δp_swab/surge = f·(ρ·v_p²)/2 · (L/D_h) (Burkhardt, effective MW = static MW ± Δp/0.052·TVD)
- Stuck-pipe severity = max(sev_differential, sev_mechanical, sev_packoff) over a rolling window
- Kick/loss margin = min(effective MW − MW_kick, MW_breakdown − effective MW) (ppg)
- Single-phase mud in the annulus for the Burkhardt Δp; gas influx handled by the kick-detector proxy, not the swab/surge advisor.
- MSE regime classifier uses fixed thresholds calibrated on land-rig data; ultra-deep offshore benefits from re-tuning.
- Voice Q&A payload capped at 8 KB — offset reports trimmed lexically before the LLM call.
- Teale, R. (1965). The concept of specific energy in rock drilling.
- Burkhardt, J. (1961). Wellbore pressure surges produced by pipe movement. JPT.
1Stuck-pipe tab
UI: /driller-copilot → Stuck-pipeMax-of-three severity chip (differential / mechanical / pack-off). Amber ⇒ log the offset, red ⇒ break circulation before making a connection.
Result: Chip + rolling-window sparkline2Kick/loss + mud window
UI: /driller-copilot → Kick / lossLive ppg margin against the pore-pressure floor and the breakdown ceiling from the /wellbore-stability module. Negative margin ⇒ TLP action.
3MSE founder
UI: /driller-copilot → MSETeale MSE in ksi + regime classifier (efficient / founder / bit-balling / whirl / stick-slip). Follows a WOB / RPM step recommendation.
4Trip advisor
UI: /driller-copilot → TripBisected max-safe pipe velocity from Burkhardt Δp holding effective MW inside the mud window.
5Voice Q&A
UI: /driller-copilot → VoicePush-to-talk speech-to-text → Gemini 2.5 Flash with the rig-context payload. Confirmation-before-write for any setter command.
6Morning report
UI: /driller-copilot → Morning reportAuto-drafts the 06:00 report from the last 24 h of samples + logged events; engineer edits before signing.
20.2 Live+ diagnostics pack — /live-pumping + /tools/dfit-interpreter#
Sprint 1 of the v10 competitor-gap plan. Adds a step-down inverter, per-cluster entry-friction distribution, DFIT pre-closure regime interpreter, and a wellbore fluid-front animator. The pre-closure interpreter is also mounted at the public /tools/dfit-interpreter free tool (no auth, no storage).
src/lib/liveDiag/stepDownInverter.ts → invertStepDown- ρ = slurry density (ppg)
- C_d = discharge coefficient (dimensionless; healthy perfs 0.6–0.85)
- n = open shot count
- d = perf diameter (in)
- q = rate (bpm)
- K_nwb·q^n = near-wellbore tortuosity Δp (psi); n fixed at 0.5 by default
- closurePsi (irrelevant)
- ≥ 2 (rate, Δp) plateaus from the step-down file
- Slurry density and shot count constant across plateaus
- n_nwb fixed at 0.5; overridable
src/lib/liveDiag/dfitPreClosureInterpreter.ts → interpretPreClosure- |dp/dt| = absolute pressure derivative during pre-closure
- t = shut-in time (min)
- slope classified against the four canonical regimes using |slope| so negative signs still match
- Pre-closure only (not radial G-function)
- Sample cadence ≥ 3 within the fit window
1Paste plateaus
UI: /live-pumping → Step-downPaste ≥ 2 (rate, Δp_total) rows into the Step-down card. Slurry ppg + perf diameter + shot count auto-fill from the schedule.
2Read C_d and tortuosity severity
Card returns C_d effective, open shot count, K_nwb, RMS residual, and a tortuosity chip (healthy / elevated / severe).
Result: e.g. C_d=0.61 · shots 24/32 · K_nwb=140 psi/bpm^0.5 → 'elevated'3Route to remediation
'severe' + open-shot deficit ⇒ ball-out or add-shots. 'elevated' with full shots ⇒ NWB tortuosity — schedule a slug and retest.
20.3 Transient multiphase wellbore — /transient-multiphase-wellbore#
Phase B coordinator that steps pressure → flow-regime → enthalpy in one call. Wraps the drift-flux 1-D solver (Standing-Katz Z(p,T) via DAK + Sutton + Wichert-Aziz sour-gas correction) with a Taitel-Dukler + Barnea flow-regime classifier and a backward-Euler enthalpy wave (Joule-Thomson + latent heat of vaporization).
- ∂(ρ_m)/∂t + ∂(ρ_m·v_m)/∂z = 0 (mass)
- ∂(ρ_m·v_m)/∂t + ∂(ρ_m·v_m²)/∂z = −∂p/∂z − ρ_m·g − τ_w·P/A (momentum)
- ∂(ρ_m·h_m)/∂t + ∂(ρ_m·v_m·h_m)/∂z = ∂(k·∂T/∂z)/∂z − U·(T−T_∞) (enthalpy)
- v_g = C_0·v_m + v_d (Zuber-Findlay drift-flux)
- Z(p,T) = f_DAK(ρ_r, T_r) with pseudo-criticals from Sutton (1985) and Wichert-Aziz (1972)
- Regime classifier: horizontal → Taitel-Dukler (5 regimes); vertical → Barnea (bubble / slug / churn / annular)
- 1-D segmented pipe; no lateral heterogeneity in a segment.
- Segregated implicit Euler (pressure tridiag → velocity update → temperature tridiag).
- Swamee-Jain Darcy-Weisbach friction; no rugosity coupling to solids.
- Enthalpy: μ_JT and L_v supplied per phase; solid CO₂ deposition NOT modeled.
- Zuber, N. & Findlay, J. (1965). Average volumetric concentration in two-phase flow systems.
- Taitel, Y. & Dukler, A. E. (1976). A model for predicting flow regime transitions in horizontal and near horizontal gas-liquid flow. AIChE J.
- Dranchuk, P. M. & Abou-Kassem, J. H. (1975). Calculation of Z factors for natural gases.
- Wichert, E. & Aziz, K. (1972). Calculate Zs for sour gases.
- Not an OLGA replacement — no explicit slug tracker, no wax/hydrate deposition solver.Why this matters, when it breaks, what to do instead
- Why it matters:
- Slugging is a real safety and equipment-integrity issue at surface separators; a drift-flux mixture average will not warn about slug-caused pressure spikes or wax/hydrate plug growth.
- When it breaks down:
- High-GOR wells during flowback, cold flowlines below wax/hydrate onset, or any topside choke-cycling operation.
- Safer alternative:
- Use this module for pressure/temperature envelopes and screening; route slug and deposition modelling to an external OLGA/LedaFlow run and import BHP/T as boundary conditions.
- Regime map margins are advisory chips; the closures themselves are drift-flux blended, not regime-switched.Why this matters, when it breaks, what to do instead
- Why it matters:
- Blended closures can silently interpolate across a real regime boundary; the advisory chip is the only signal that the operating point is near a transition where the physics actually changes.
- When it breaks down:
- Near stratified↔intermittent transitions (Taitel-Dukler map margins) in slightly-inclined flowlines and near the bubbly↔slug boundary at low superficial gas.
- Safer alternative:
- When the advisory chip trips watch/amber, tighten the operating range or re-run with an explicit regime-switched closure library outside this tool before committing the design.
- Enthalpy wave uses a single mixture cp; independent phase enthalpies are on the roadmap.Why this matters, when it breaks, what to do instead
- Why it matters:
- A single mixture cp smooths latent-heat effects at phase-change fronts; wellbore temperature predictions can drift by tens of °F when gas breakout or condensation is significant.
- When it breaks down:
- Depletion crossing the bubble point in the tubing, retrograde-condensate wells, and CO₂-flood wellbores where cp differs by an order of magnitude between phases.
- Safer alternative:
- Use the DTS fibre-optic import on /live-pumping (fiberOpticTelemetry.ts) to anchor the temperature profile to measurement, and treat the modelled T as an envelope, not a golden.
20.4 CCUS / MRV ledger — /ccus-mrv#
Regulator-grade Monitoring / Reporting / Verification workflow for CO₂ storage. Append-only signed ledger of injection mass, plume snapshots, caprock seal severity, and leakage flux; Subpart RR-style PDF export per reporting period; hash-chain proof and field-validation cross-check between measured and modeled Δp.
src/lib/co2StorageAssurance.ts- Q_inj = volumetric injection rate at reservoir conditions (m³/s)
- t = time since injection start (s)
- h = net aquifer thickness (m)
- φ = porosity
- S_wr = residual water saturation
- Sharp-interface (VE) plume
- Constant Q_inj
- Homogeneous, horizontal aquifer
src/lib/co2StorageAssurance.ts- W(u) = well function (exponential integral)
- μ_w = brine viscosity
- k = permeability
- c_t = total compressibility
1Log injection events
UI: /ccus-mrv → LedgerEvery metering event (mass, time, source) appends a signed record; the hash chain is anchored to the previous ledger tail.
2Attach plume + caprock snapshots
Nordbotten-Celia plume radius and Theis Δp evaluated at the reporting instant; severity chip (ok / watch / amber / critical) inline.
3Attach field-validation cross-check
UI: /ccus-mrv → Cross-checkModeled vs measured Δp residuals from /field-validation → ok/watch severity feed into the same ledger.
4Export Subpart RR PDF
UI: /ccus-mrv → Export4 §-keyed sections + attestation + hash-chain proof + period-filtered ledger tail; letter, paginated.
20.5 Induced-seismicity forecaster — /induced-seismicity#
Dieterich (1994) seismicity-rate response to a pore-pressure time series with a Traffic-Light Protocol (TLP) classifier, USGS catalog auto-refresh, operator-action audit log, and copy-paste regulator templates (OK CC, KS Corp Comm, TX RRC).
src/lib/induced/dieterichSeismicityRate.ts- R(t) = seismicity rate (events/time)
- r = background rate
- γ = state variable with initial value γ_0 = 1/(dτ/dt)_ref
- a·σ = direct-effect parameter (typ. 0.001–0.01 · effective normal stress)
- dτ/dt = shear-stressing rate driven by ΔP·μ_f (Coulomb) + Δτ coseismic jumps
- Optimally oriented faults
- Constant a·σ
- Δτ coseismic jumps optional
src/lib/induced/tlpThresholdPresets.ts → classifyTrafficLight- rate ratio = R(t) / r_background
- M_max = observed max magnitude in the rolling USGS window
- thresholds persisted per-preset in localStorage downhole.inducedSeismicity.tlpThresholds.v1
1Pick a preset
OK_CC / KS_CC / TX_RRC / default / custom. Each preset ships a monotonic-ladder (yellow < amber < red) rate-ratio and M_max threshold set.
2Turn on USGS auto-refresh
UI: /induced-seismicity → USGS cardChoose a cadence (7 options, from 1 min to daily); hidden-tab and in-flight de-dupe are handled automatically.
3Log an operator action
UI: /induced-seismicity → Audit logEvery TLP transition auto-logs; manual rate-cut / shut-in / monitoring / regulator-report / note also appends. CSV export mirrors the regulator template.
20.6 Non-planar 3D fracture solver — /non-planar-3d + Results tab#
Surface-mesh DDM with tip kinking (M-integral MTS), natural-fracture branching (Renshaw-Pollard + Gu-Weng), out-of-plane tilt, T-junction reconvergence weld, and a kernel bridge that pushes an equivalent planar half-length + conductivity retention back into /refrac, black-oil, and /parent-child. Opt-in from the Fracture options panel; omitted ≡ legacy planar path byte-identical.
- σ(x) = ∫∫_Γ K(x − x')·D(x') dS' (3-D DDM boundary integral)
- β_kink = argmax_θ [σ_θθ(θ) − K_IC²/2πr] (Maximum Tangential Stress kink criterion)
- Renshaw-Pollard: HF crosses NF when σ_θθ^HF > T_0^NF (elastic screening)
- Gu-Weng: HF branches into NF when λ_GW = (σ_θθ − p_pore)/(σ_H − σ_h)·f(angle) > λ_crit
- C_f_retention = tortuosity^(−exp) (Darcy along the curved path back to a planar-equivalent k·w)
- Linear-elastic host rock; plasticity in a small process zone at the tip only.
- Constant fluid pressure inside a step; time-marched between DDM solves.
- Weld folds only tips within 0.25·advanceFt of an existing parent vertex (default) to avoid spurious merges.
- Erdogan, F. & Sih, G. C. (1963). On the crack extension in plates under plane loading and transverse shear.
- Renshaw, C. E. & Pollard, D. D. (1995). An experimentally verified criterion for propagation across unbonded frictional interfaces in brittle, linear elastic materials.
- Gu, H. & Weng, X. (2010). Criterion for fractures crossing frictional interfaces at non-orthogonal angles. ARMA 10-198.
1Toggle in Builder
UI: Builder → Fracture optionsFracture options → Non-planar 3D solver → Enable. Set element size, max kink [°], branch threshold [°], and max curvature [°/ft].
2Run + open viewer
UI: /non-planar-3dThe /non-planar-3d viewer renders the mesh with tip-kinking + branching + weld indicators; the per-simulation Results tab shows the scoreboard.
3Pull equivalent planar geometry into refrac / BO
The bridge exposes effective half-length + conductivity retention (tortuosity^(−exp)); /refrac and /parent-child multiply through the existing k·w and L inputs automatically.
20.7 Solver spec scoreboard — /solver-spec#
Refreshed model card. Each physics row carries four possible badges — Shipped, Next up, In Newton loop, Out of scope — and 'In Newton loop' rows expose a hover tooltip pointing at the exact kernel file / PR that wires the module into coupledNewtonStep. A short legend above the scoreboard explains each badge and defines the outer nonlinear corrector.
- Shipped — live in production and exercised by the linked route.
- Next up — physics is built; remaining PR wires it into runtime UI and the Newton outer loop.
- In Newton loop — runs inside coupledNewtonStep (pressure / width / state variables corrected until residuals converge).
- Out of scope — explicitly excluded today (e.g. OLGA-class transient multiphase in the frac kernel).
| Row | In-Newton kernel wiring |
|---|---|
| Fracture mechanics | tipPropagationStep + kgdMovingTipRunner.ts |
| Fluid-solid coupling | coupledNewtonStep.ts (Phase 4, default @ Phase 7 inc 16) |
| Leak-off | Carter sink in coupledNewtonStep (Phase 5 inc 6) |
| Proppant transport | wellboreProppantPreviewDriver.ts + wellboreScalarTransport.ts |
| Coupling direction | subStepReservoir on singlePhaseGrid.ts / compositionalBlackOil3P.ts (Phase 9, default-ON @ Phase 16) |
| Wellbore flow | transientWellbore.ts + drift-flux + Standing-Katz (Phase 8 inc 3) |
| T-M-H voxel | newtonThermoPoroCoupling.ts (Phase 9) |
Version + migration notes#
21. Release notes index (what changed, where to look)
Every 'what changed since last release' bucket in one place — v1.4/v1.6/v1.7/v1.8 chapter cross-links, the live `.lovable/plan.md`, and the /roadmap route. Answers the review comment 'why does the manual skip §21?'.
This chapter exists to close the historical §21 numbering gap. It contains no new physics — it is a signpost. If you are looking for what changed in a specific release, follow the link below; if you are looking for what is still in flight, follow the roadmap link.
- §15 — Recently shipped (post-1.0). The evergreen list; kept up to date as features land.
- §16 — What's new in v1.4 vs v1.3.
- §19 — What's new in v1.7 vs v1.6.
- §20 — What's new in v1.8 (operator surface + advanced physics).
- `.lovable/plan.md` — the working plan tracked alongside the codebase; every open review comment maps to a plan bucket here.
- `/roadmap` — the live status page, sourced from `src/lib/atozGapList.ts`. Ship/flag status is flipped there and in project memory in the same edit, so this is the closest thing to a single source of truth.
22. Model verification — beyond history matching
Independent numerical + analytical verification of every solver module. History matching is one channel; the drift-guard test suite is the other. This chapter answers 'how do you know the physics is right without a field match?'.
Reviewers frequently ask whether Wellbore Genius is only validated against measured field data (history matching). It is not. Every physics module ships with an executable drift-guard test that compares the numerical kernel against a closed-form analytical solution, a published benchmark, or a manufactured solution. If any comparator drifts outside its published tolerance, CI fails and the build is blocked from shipping.
Analytical benchmarks currently in CI#
| Module | Comparator | Metric | Drift-guard file |
|---|---|---|---|
| PKN half-length | Nordgren 1972 closed form L ∝ t^(4/5) | max |log₁₀(L/L_ref)| ≤ 0.20 on [0.5, 1] s | dfitBenchmarkRunner.test.ts |
| KGD half-length | Geertsma-de Klerk closed form | max |log₁₀ residual| within registry tolerance | dfitBenchmarkRunner.test.ts |
| Radial fracture | Perkins-Kern radial | max |log₁₀ residual| within registry tolerance | dfitBenchmarkRunner.test.ts |
| Peaceman injector | Dimensionless τ_D = η·t/L² invariance across μ ∈ {0.5, 1, 2, 5} cp | ≤ 8 % τ_D drift; dt-tile band E_μ from tolerancesFor(μ,dt) | viscosity-sweep + dimensionlessTime.test.ts |
| Buckley-Leverett | Welge tangent fw + shock profile | L1 + L∞ vs analytical profile | buckleyLeverett.test.ts + kernel-parity |
| Mass balance | Σ mass_in − mass_out − Δ mass_in_place | worstRelative ≤ 1e-5 (Carter tightened from 0.05) | massBalanceReport.test.ts |
| Non-planar 3D bridge | Collapses to planar geometry when tortuosity = 1 | Bit-identical planar recovery | nonPlanar3D/kernelBridge.test.ts |
| Poroelastic depletion | Geertsma 2-D Lamé inside/outside disc | Analytical σ_h / σ_H at 8 witness points | poroelasticDepletion.test.ts |
| Mindlin 3-D bench | Collapses to 2-D poro when layers = ∅ | Byte-identical 2-D recovery | mindlin3D.test.ts |
| Thermo-poro probe | Probe metrics ≡ child-fracture geometry across 108 sweeps | 3-way collapse (off ≡ [] ≡ ΔT = 0) | probePointVsThermoPoroParity.test.ts |
| Compositional 3-phase | PR-EOS energized-CO₂ FVF bridge + BL parity | L∞ ≤ 0.5 vs BL analytical | compositionalBlackOil3P.test.ts + BL parity |
| Rate-and-state friction | Dieterich-Ruina analytical stability boundary | critical stiffness / nucleation length within tol | rateStateFriction.test.ts |
| Wellbore stability | Kirsch + Mohr-Coulomb closed form for vertical borehole | Analytical p_w(σ_h, σ_H, φ, UCS, α, T₀) | wellboreStabilityMudWindow.test.ts |
| Non-Darcy gas inflow | Wattenbarger A·q + B·q² solved analytically | B = 0 and A = 0 edge cases | gasNonDarcyInflow.test.ts |
| Adaptive substepper | PI control on |ΔP|∞ / |ΔT|∞ | clampedAtMin flag + rejection accounting | coupledTransientSubstepper.test.ts |
Field-campaign validation (channel B)#
- DFIT registry — every registered mini-frac closure re-fit each CI run; residuals summarised in solverSpecScoreboard.ts.
- MSEEL HFTS-1 datasets — public microseismic + fibre benchmark cross-references (mem/reference/mseel-hfts1-datasets.md).
- Field-validation campaigns route (/projects/$p/workspaces/$w/field-validation) — upload gauge (t, P, T) or gradient (MD, P, T) surveys; verdict = AND of attached comparisons (leak-off, fracture-mechanics, DFIT).
- Microseismic ↔ conductivity validation (mem/features/microseismic-conductivity-validation.md).
- PVT consortium presets exercised against published Wolfcamp / Bakken / Eagle Ford / Marcellus / Montney / Vaca Muerta EoS tunings.
How to read /solver-spec#
The /solver-spec page is the human-readable index of what is verified vs what is roadmap. Each row states (a) the current implementation, (b) the drift-guard file that locks it, (c) the honest limits (what the module does NOT do), and (d) the next roadmap increment. If a row's `roadmap` cell is non-empty, that gap has an open test but no shipping implementation — the review should treat it as absent, not present.
Depth-profile visual — DFIT calibration#
- Hydrostatic (9.2 ppg water)
- Pore pressure
Depth-profile visual — wellbore mud-window#
- Pore pressure (kick limit)
- Shear-failure floor
- Loss ceiling (σ_v)
- Tensile breakdown
- Analytical comparators cover the pure physics module — they do not verify UI wiring. UI-level regressions are caught by Playwright drift-guards, not by these tests.Why this matters, when it breaks, what to do instead
- Why it matters:
- A green analytical comparator does NOT prove the value reached the screen correctly; a wiring bug can hide behind a passing kernel test and mislead an operator reading the UI.
- When it breaks down:
- Any time a route, panel, or export is added/rewired without the corresponding Playwright drift-guard being updated in the same PR.
- Safer alternative:
- Run the /manual + /solver-spec Playwright suites locally before merging UI-touching PRs, and require a Playwright test line change on any PR that edits a route file.
- The PKN early-time tolerance is currently 0.20 (log₁₀), reverted from a briefly-tightened 0.15 while a dx-invariant t ≈ 0.5 s formulation gap is investigated (see .lovable/plan.md, 2026-07-08).Why this matters, when it breaks, what to do instead
- Why it matters:
- A loose PKN early-time tolerance means the drift-guard will not catch a genuine ~15-25 % over/under-prediction at t < 1 s, which is exactly where breakdown/near-wellbore decisions live.
- When it breaks down:
- Ultra-short breakdown windows (< 2 s) and step-rate diagnostics that rely on the first few seconds of the pressure trace.
- Safer alternative:
- Read PKN early-time values as an envelope until the formulation gap is closed; anchor breakdown decisions to the Pressure Advisor wizard's independent shear-floor calculation instead.
- Field campaigns are opt-in per workspace; verdicts do not roll up into a project-wide score without operator action.Why this matters, when it breaks, what to do instead
- Why it matters:
- Without an operator opt-in, a project can look 'validated' overall while several workspaces have never been checked against measured data.
- When it breaks down:
- Multi-workspace projects where different engineers own different pads and no reviewer aggregates the verdicts.
- Safer alternative:
- Add a project-level checklist that requires at least one closed field-validation campaign per workspace before any design run is treated as sanctioned.
- Rate-and-state friction is single-fault quasi-static — multi-fault interaction is roadmap.Why this matters, when it breaks, what to do instead
- Why it matters:
- A single-fault quasi-static model cannot reproduce cascading events on adjacent structures, which is the pattern behind almost every M ≥ 3 induced-seismicity case in the last decade.
- When it breaks down:
- Areas with mapped conjugate faults (SCOOP/STACK, Fox Creek Duvernay, Sichuan) and any pad within ~5 km of a critically-stressed basement fault.
- Safer alternative:
- Cross-check with an external multi-fault Coulomb-stress transfer study and honour the local traffic-light regulator protocol as the binding constraint, not the model output.
- Compositional 3-phase is IMPES, not fully-implicit; large capillary-dominated timesteps may require dt reduction.Why this matters, when it breaks, what to do instead
- Why it matters:
- IMPES with a coarse dt in a capillary-dominated regime can over-shoot saturations and produce a wildly-wrong front position; the pressure solve stays stable so the failure is silent.
- When it breaks down:
- Very-low-permeability chalks and tight-gas at high P_c, or any imbibition-dominated flowback simulation.
- Safer alternative:
- Reduce dt through the Phase-9 substepper (targetP/targetT knobs) or run the buckleyLeverett kernel-parity comparator to bound the front-position error before trusting the saturation map.
23. Recent physics + numerical additions (round-3 answers)
One consolidated chapter documenting the physics work shipped since the round-2 review: non-planar 3D, thermo-poro coupling, phase-field DEM, compositional 3-phase, adaptive substepper, heterogeneity coupling, multi-well interference, and induced-seismicity. Each module lists its equations, assumptions, drift-guard file, and hard limitations.
This chapter exists because reviewer feedback repeatedly said 'the improvements are not visible in the manual'. Every module below is already shipping — links point to the live route and the pure-lib source. If a claim here is not backed by a drift-guard test file, treat it as a documentation bug and file it.
23.1 Non-planar 3D fracture solver#
- Hydrostatic [psi]
- Pore [psi]
- Geotherm [°F]
- Element-size (h_e), max kink (Δθ_max), branch threshold (θ_b), max curvature (κ_max) knobs feed the discretisation directly
- Planar-equivalent bridge: effective L_half = polyline arc length; conductivity retention = tortuosity^(−exp)
- Stress-driven curvature switch routes tip advance through the He-Hutchinson pierce/kink classifier
- Quasi-static propagation (no dynamic wave loading)
- Rock is linear-elastic between benches
- Tortuosity multiplier applies to along-path Darcy conductivity only
Piecewise-linear polylines per step; kink cap at Δθ_max between adjacent segments
- He, M-Y and Hutchinson, J.W. (1989) — Kinking of a crack out of an interface
- Non-planar 3D kernel bridge — src/lib/nonPlanar3D/kernelBridge.ts
- No dynamic fracture — quasi-static only.Why this matters, when it breaks, what to do instead
- Why it matters:
- Dynamic effects (radiation damping, inertia) can slow tip velocity and change branching thresholds; a quasi-static run over-predicts propagation speed and length for very-high-rate breakdown events.
- When it breaks down:
- Perforation breakdown at rates > 100 bpm on a single cluster, or when a rate step exceeds ~40 bpm within a second.
- Safer alternative:
- Cap analysis at post-breakdown quasi-steady conditions; for breakdown itself use the Pressure Advisor breakdown-pressure branch instead of the propagation solver.
- Bridge to planar kernel derates conductivity multiplicatively; it does not re-solve full 3-D Darcy along the curved path.Why this matters, when it breaks, what to do instead
- Why it matters:
- A multiplicative retention factor is fast but can miss local Darcy re-focusing at sharp kinks; conductivity along a kinked path can be lower than the average factor implies.
- When it breaks down:
- Paths with > 3 kinks exceeding 30° over 20 ft, or where a proppant bank plugs a single high-curvature segment.
- Safer alternative:
- Read the per-step curvature breakdown in NonPlanar3DResultsCard and, for any step flagged 'top' by kink metric, run a stand-alone Darcy comparator on the polyline before trusting the effective L_half.
- Stress-driven curvature is a heuristic switch, not a full XFEM tip enrichment.Why this matters, when it breaks, what to do instead
- Why it matters:
- A heuristic tip criterion can pick the wrong plane at bi-material or high-contrast interfaces; the He-Hutchinson classifier is well-calibrated in-lab but has documented cases where it under-predicts kink at low σ-ratio.
- When it breaks down:
- Fracture tips approaching a bedding plane with a weak interface or crossing a high-modulus contrast (> 3×) bench boundary.
- Safer alternative:
- Enable the phase-field DEM laminated-shale primer (Chapter 23.3) as an offline sanity check; if the two solvers disagree, honour the more-conservative (lower L_half) result until reconciled.
23.2 Thermo-poro 3-D coupling#
- Geotherm (undisturbed)
- Cooled reservoir (post-injection)
- Δσ_h, Δσ_H, Δσ_v full-tensor from Geertsma 2-D Lamé inside/outside-disc (2×2 eigen decomposition per witness point)
- SHmax azimuth rotation: eigenvector of the Δσ tensor; classifier bins info ≤ 5° / watch ≤ 15° / critical > 15°
- Bench-aware E′ and α — layer-specific elastic and Biot coefficients
- Optional convective transport switch on the transient substepper
- Linear-elastic layered response
- Thermal patches are cylindrical disks per bench
- No fully-coupled multiphase transport in the temperature equation
- Geertsma (1973); Mindlin (1936) — layered extension
- No fully-coupled multiphase mass + energy transport — energy uses a single-phase mixture.Why this matters, when it breaks, what to do instead
- Why it matters:
- Latent-heat effects at gas breakout / condensation change the cooling front velocity; a mixture cp under-predicts near-wellbore cooling and therefore under-predicts the σh reduction (and over-predicts breakdown pressure).
- When it breaks down:
- Wet-gas condensate wells, energized-fluid stimulations, and CO₂-flood injectors.
- Safer alternative:
- Anchor the modelled temperature to DTS fibre measurements when available; when not, add a conservative ±10 °F band to the cooling patch temperature and re-run the substepper.
- Bench layers must be laterally continuous; pinch-outs are not resolved.Why this matters, when it breaks, what to do instead
- Why it matters:
- A pinch-out routes stress and heat around the discontinuity in ways the continuous-layer model cannot capture; SHmax rotation predictions become unreliable near the pinch.
- When it breaks down:
- Structurally-complex plays (Bakken erosional pinch-outs, Woodford channel margins) where a bench thins to zero within one lateral length.
- Safer alternative:
- Restrict the thermo-poro grid to laterally-continuous zones (trim to the bench isopach); for the pinch region, treat the poroelastic output as advisory only.
- Cooling-credit hook into Pressure Advisor is opt-in per workspace.Why this matters, when it breaks, what to do instead
- Why it matters:
- If cooling credit is off by default, the operator may over-design pad size because breakdown is calculated at the hotter, higher-σh state.
- When it breaks down:
- Re-entries, refracs, and pads with long shut-in prior to the next stage where the wellbore has genuinely cooled the near-well rock.
- Safer alternative:
- Turn on the cooling-credit toggle in the Pressure Advisor wizard for workspaces meeting the above criteria and record the choice in the audit log so reviewers can see the intent.
23.3 Phase-field DEM for laminated shale#
- AT-1 / AT-2 damage functional with irreversible history field
- Cohesive Mode I / II traction-separation on bedding interfaces
- He-Hutchinson kink/pierce classifier + MTS kink-angle criterion
- σ_h degradation hook into the existing Geertsma engine
- Small strain; damage is a scalar phase field per element
- Bedding interfaces are pre-known (input from log picks)
- Primer only — not yet wired into the main propagation solver. Available as a standalone pure library and 10-test drift-guard.Why this matters, when it breaks, what to do instead
- Why it matters:
- An unwired primer means the operator will not automatically get phase-field predictions during a run; a laminated shale with strong bedding contrast may be modelled by the default DDM solver that does not resolve bedding-plane deflection.
- When it breaks down:
- Vaca Muerta / Utica / deep Bakken designs where bedding-plane fractures are the dominant failure mode.
- Safer alternative:
- Call `phaseFieldDemLaminatedShale.ts` directly (or use the /roadmap card) as an offline check; if kink/pierce classifier disagrees with the main solver, treat the design as high-uncertainty and pilot a small stage before scaling.
- No dynamic loading; quasi-static.Why this matters, when it breaks, what to do instead
- Why it matters:
- Dynamic (rate-dependent) fracture toughness matters for high-injection-rate breakdown; a quasi-static run under-predicts breakdown pressure and can steer the design toward too little pad or excess perforation.
- When it breaks down:
- Very-high-rate step-rate tests and breakdown events at rates > 60 bpm on a single cluster.
- Safer alternative:
- Add a conservative dynamic-K correction factor (~1.2-1.5×) to the K_IC input, or bracket the run at the higher K_IC and honour the higher breakdown pressure.
23.4 Compositional 3-phase black-oil with energized CO₂#
- Hydrostatic (10.5 ppg)
- Pore pressure
- Frac gradient (0.78 psi/ft)
- Peng-Robinson EoS for the gas phase; energized-CO₂ FVF bridge overrides B_g when the workspace flag is on
- Water / oil / gas conservation with Sw + So + Sg = 1 and Swc floor
- IMPES pressure solve followed by explicit saturation update
- IMPES splitting — pressure is fully-implicit, saturations explicit
- Rel-perm from Corey / LET / Stone II (see section 5)
- Capillary pressure via Brooks-Corey or Skjæveland
- IMPES — capillary-dominated timesteps may require dt reduction. Fully-implicit is roadmap.Why this matters, when it breaks, what to do instead
- Why it matters:
- IMPES can silently overshoot saturations at coarse dt while pressure stays stable; the saturation map looks smooth but the front position is wrong.
- When it breaks down:
- Ultra-low-permeability chalks, tight-gas at high P_c, and imbibition-dominated flowback.
- Safer alternative:
- Enable the Phase-9 substepper with targetP ~ 100 psi and targetT ~ 5 °F, and cross-check the front against the buckleyLeverett kernel-parity comparator before decisions.
- PR-EOS tuning ships as presets for 6 plays; custom tuning is user-supplied.Why this matters, when it breaks, what to do instead
- Why it matters:
- Off-preset plays run with generic EoS parameters; predicted CGR/GOR and phase envelope can be biased by tens of percent.
- When it breaks down:
- New plays, high-GOR volatile-oil systems, and any well with unusual composition (H2S, N2, high-CO2).
- Safer alternative:
- Tune PR-EOS binary interaction parameters against a lab PVT report before running the compositional module; when no PVT exists, run both the black-oil and compositional branches and treat the spread as the uncertainty.
- Energized-CO₂ bridge assumes a well-mixed injection stream; slug injection is not resolved.Why this matters, when it breaks, what to do instead
- Why it matters:
- Slug injection produces alternating dense/gas phases downhole; a well-mixed assumption smooths the pressure/temperature signal and can miss transient breakdown windows.
- When it breaks down:
- Foamed / energized frac designs pumped without a static mixer, and any operation where CO2 is trucked into a small blender.
- Safer alternative:
- Design for a well-mixed stream at the wellhead (static mixer + minimum residence time); if slug injection is unavoidable, treat model predictions as advisory only and rely on live BHP for decisions.
23.5 Adaptive coupled-transient substepper (Phase 9)#
- PI control on r = max(|ΔP|∞ / target_P, |ΔT|∞ / target_T)
- Reject + halve dt when r > 1 down to dt_min (then forced-accept with clampedAtMin flag)
- Grow dt × accept_grow when r ≤ accept_lo; hold otherwise
- Midpoint evaluation for time-varying source / boundary condition callbacks
- Never overshoots the window end (dt clipped to endDay − t)
- Below dt_min the substepper force-accepts and sets clampedAtMin = true — downstream code MUST check the flag.Why this matters, when it breaks, what to do instead
- Why it matters:
- A force-accepted step means the reported ΔP/ΔT exceeded the target and the solver ran anyway; ignoring the flag lets a stiff transient contaminate every downstream result derived from that step.
- When it breaks down:
- Sharp source/BC transitions (well shut-in, rate step > 40 bpm within one second) and any run where dt_min was set aggressively low to keep total step count down.
- Safer alternative:
- Inspect the SubstepRecord list — any entry with clampedAtMin:true should either raise dt_min, tighten the source ramp, or be treated as high-uncertainty; the /solver-spec traceability row lists the exact check.
- PI gains are fixed; adaptive gain scheduling is roadmap.Why this matters, when it breaks, what to do instead
- Why it matters:
- Fixed PI gains work well on smooth transients but can chatter (repeated reject/accept) on stiff systems, wasting wall-clock time and inflating step counts in the audit log.
- When it breaks down:
- Coupled thermo-poro runs with a sudden temperature perturbation, or when the pressure kernel is well-behaved but the temperature kernel is stiff.
- Safer alternative:
- Bracket a run with two targetT values (e.g. 5 and 20 °F) and if step counts differ by more than 3× the transient is stiff — split it into two windows with different targetT settings.
23.6 Heterogeneity → propagation coupling#
The Gaussian random-field multiplier on K_IC, σ_h, k, and φ (route /heterogeneity) feeds the fracture propagation solver directly. On each tip-advance, the local field value is sampled at the tip location, multiplied against the base property, and used in the next Griffith / Perkins criterion. This closes the gap the round-2 review flagged ('heterogeneity overlay exists but not coupled to main propagation solver').
- Field is generated per-workspace and per-seed; two workspaces with the same seed will produce identical fields.Why this matters, when it breaks, what to do instead
- Why it matters:
- Identical seeds mean that comparing 'independent' workspaces can produce artificial agreement; a reviewer may read this as convergent evidence when it is actually the same random draw.
- When it breaks down:
- Any comparison across workspaces meant to demonstrate robustness (e.g. before/after a design change on two pads).
- Safer alternative:
- Always vary the seed across workspaces intended as independent samples; for Monte-Carlo studies use the P10/P50/P90 bundle so the seed dependence is bracketed explicitly.
- Anisotropy is diagonal (Lx, Ly, Lz correlation lengths) — no oblique correlation tensor.Why this matters, when it breaks, what to do instead
- Why it matters:
- A diagonal correlation tensor cannot represent geologic fabric aligned obliquely to the grid axes; predicted stress heterogeneity is biased along the grid direction.
- When it breaks down:
- Plays with rotated fracture fabric (Wolfcamp SHmax rotates across the section) or when the lateral azimuth is not aligned with a principal correlation axis.
- Safer alternative:
- Rotate the grid to align with the dominant correlation axis before generating the field, or bracket the run with two Lx/Ly swaps and treat the spread as the uncertainty band.
23.7 Multi-well interference (consolidated)#
- Pore pressure (original)
- Pore pressure (depleted parent)
Four routes cover the parent-child interference story end-to-end: (a) /parent-child — log-radial Δp + Eaton Δσ_h + asymmetry; (b) stress-shadow overlay — Sneddon Δσ from sibling wells; (c) poroelastic depletion — full-tensor Δσ_h / Δσ_H + SHmax rotation; (d) Mindlin 3-D bench — layered vertical attenuation. All four share the same PoroelasticResult shape so a per-stage table row lists every contribution side-by-side. Runtime SHmax → child-fracture geometry loop is documented under (M2) of the thermo-poro parity bridge.
- Poroelastic engine assumes cylindrical depleted zones per parent — irregular drainage is approximated by ellipse fits.Why this matters, when it breaks, what to do instead
- Why it matters:
- Real drainage shapes follow reservoir heterogeneity and completion quality, not perfect discs; SHmax rotation predictions can be under-estimated at the elongated tips of the true drainage cell.
- When it breaks down:
- Producers with strongly-heterogeneous completions (uneven cluster efficiency), or where microseismic shows a clearly non-circular drainage footprint.
- Safer alternative:
- Ingest a microseismic catalog via the /parent-child route and fit the drainage radius per-parent from event distances (fitDrainageRadiusFromMS) before running the poroelastic step.
- Mindlin 3-D bench requires laterally continuous benches.Why this matters, when it breaks, what to do instead
- Why it matters:
- The depth factor derivation assumes continuous benches; near a pinch-out the vertical attenuation is off, and infill stages at that TVD may see stronger or weaker rotation than predicted.
- When it breaks down:
- Any child stage TVD within one bench thickness of a pinch or unconformity.
- Safer alternative:
- Trim the analysis area to the continuous-bench region; for stages inside the pinch zone treat the SHmax rotation as an envelope and pilot the design before scaling.
- Frac-hit volumetrics is a swept-ellipse capture × depletion-attraction estimator — it does not solve conservative transport per-cluster.Why this matters, when it breaks, what to do instead
- Why it matters:
- A swept-ellipse estimator gives a bulk mass at each parent but not the per-cluster breakdown a completions engineer needs to decide diverter timing.
- When it breaks down:
- Long laterals with variable cluster efficiency, or when a specific cluster is suspected of being the frac-hit source.
- Safer alternative:
- Use DAS/DTS cluster-flow inversion (dasClusterGeometryInversion.ts) to allocate the frac-hit mass to individual clusters, then feed those per-cluster masses into the volumetric estimator.
23.8 Rate-and-state friction + induced-seismicity traffic light#
- μ(V, θ) = μ₀ + a·ln(V/V*) + b·ln(V*·θ / D_c)
- Slip-law state evolution: dθ/dt = 1 − V·θ / D_c
- Critical stiffness k_c = σ_n·(b − a) / D_c; nucleation length L_c ≈ 2·G·D_c / (σ_n·(b − a))
- Stability classifier: strengthening (a > b) / conditionally-stable / unstable (k < k_c)
- Quasi-static spring-slider on a single fault patch
- Optional pore-pressure perturbation p(t) for injection ramps
- Single-fault only — multi-fault interaction is roadmap.Why this matters, when it breaks, what to do instead
- Why it matters:
- Cascading events on conjugate faults are the dominant mechanism behind almost every M ≥ 3 induced event; a single-patch simulation cannot see the cascade.
- When it breaks down:
- Basins with mapped critically-stressed conjugate faults (SCOOP/STACK, Fox Creek Duvernay, Sichuan, W-Texas basement structures).
- Safer alternative:
- Run an external multi-fault Coulomb-stress transfer study alongside the single-patch RSF result; if the transfer study lights up an adjacent fault, treat the pad as high-risk regardless of what the RSF traffic light shows.
- Quasi-static; no elastodynamic radiation.Why this matters, when it breaks, what to do instead
- Why it matters:
- Radiation damping matters for the transition from stable nucleation to dynamic runaway; a quasi-static solver only classifies the nucleation regime, not the eventual magnitude.
- When it breaks down:
- Any operating scenario approaching the unstable regime (k < k_c) — the model correctly flags nucleation but cannot predict M.
- Safer alternative:
- Treat a red RSF traffic light as a hard stop, not a magnitude prediction; escalate to a dynamic rupture code or, more practically, back off injection immediately.
- The traffic light aggregates model output with local regulator thresholds — always cross-check against the local induced-seismicity protocol.Why this matters, when it breaks, what to do instead
- Why it matters:
- Regulatory thresholds vary by jurisdiction and can change mid-project; a stale threshold in the model can hide a real regulatory breach.
- When it breaks down:
- Any operation crossing a regulatory boundary (state / province / OGA area) and any pad older than 12 months without a threshold-update audit.
- Safer alternative:
- Verify the local traffic-light thresholds with the regulator before every campaign and update the workspace parameters; log the source and date of the threshold in the audit log.
23.9 What this chapter does NOT cover#
- 3-D viewer improvements (cross-section slice, HUD read-out, playback contour, propagation trails, kink-node dots, NF-activation flash, tip-velocity bloom scale) — tracked in the roadmap at /roadmap?phase=viz and cross-checked against `.lovable/plan.md` §1/§4. Every item there is either LIVE or has a named owning file.
- Results-tab completeness pass (ISIP marker, closure-pressure reference line, fluid-efficiency, half-length / height vs. time) — tracked in /roadmap?phase=viz under the Results-tab lane.
- AI chatbot integration — separate product decision, not a physics module; status at /roadmap?phase=polish.
- Full A-to-Z gap list (all series, both shipped and in-flight) is at /roadmap.
24. Numerical-method background & specialty material inputs
Plain-English tour of the assumptions, discretization schemes, and unit conventions that every solver in Wellbore Genius shares — followed by a per-preset explanation of how sodium nitrate, flour/epoxy diverter, and black-powder residue inputs feed the equations (and where they intentionally do NOT).
This chapter answers three questions engineers keep asking during reviews: (1) what assumptions does the kernel actually make; (2) how are the PDEs discretized in space and time; (3) how are field-unit inputs (ppg, psi, bbl/min, °F) converted before they reach the solver. The last section walks through the three specialty material presets (sodium nitrate, flour/epoxy, black-powder residue) and shows the exact line of physics each one changes.
24.1 Governing assumptions (what every solver takes for granted)#
- Linear poroelasticity with Biot coefficient α ∈ [0, 1]; effective stress σ' = σ − α·p_p. Non-linear (plastic) response is layered in via Mohr-Coulomb yield only where explicitly enabled (mud-window solver, rate-and-state fault).
- Isothermal single-phase flow unless a module states otherwise. Thermal coupling is opt-in per module (thermo-poro 3-D, live-auto-HM thermal effect, DFIT temperature-dependent viscosity).
- Newtonian fluid rheology by default. Non-Newtonian branches (Carreau-Yasuda, Herschel-Bulkley, Maxwell modes) are explicit user choices and are byte-identical to Newtonian when their extra parameters collapse (n=1, τ_y=0, no modes).
- Rock is treated as a continuum at the grid scale; discrete fracture networks (DFNs) are represented as graph elements, NOT as embedded XFEM enrichments. The frac solver couples DDM tips to a graph dispatcher (see /solver-spec).
- Gravity is vertical (−ẑ). Deviated / horizontal wells project weight onto the wellbore-axial direction inside the mud-window and hydrostatic solvers.
- All comparators run on the pure physics module. UI-level wiring is verified separately by Playwright drift-guards, not by the analytical tests.
24.2 Discretization — what scheme is used where#
The kernel is a mix of analytical, semi-analytical, and numerical solvers. The tables below say which method is used for which module so a reviewer can jump straight to the right drift-guard.
- p — pore pressure [Pa]
- k — permeability [m²]
- φ — porosity [-]
- μ — viscosity [Pa·s]
- c_t — total compressibility [1/Pa]
- Line-source superposition (Theis) valid when r_w ≪ r; for r ~ r_w the Peaceman well index is used.
- Piecewise-constant permeability inside each grid cell; contrasts resolved via harmonic averaging on cell faces.
- S — storage coefficient [1/Pa]
- q(x,t) — volumetric source [1/s]
- k, μ — as above
- Two-point flux approximation (TPFA) with upwind mobilities on faces for stability.
- IMPES time-splitting: pressure implicit, saturations explicit with a TVD (van Leer) limiter — locked by buckleyLeverettKernelParity.test.ts.
- Capillary-dominated regimes may require dt reduction; the Phase-9 substepper caps this automatically.
- w(x) — fracture aperture [m]
- p_net — net pressure inside the fracture [Pa]
- σ_h(x) — in-situ minimum horizontal stress [Pa]
- G(x,x') — elastic influence function (Kelvin fundamental solution)
- DDM tip elements in an infinite elastic medium; layered benches modelled via Mindlin 3-D depth factor (a/√(a²+Δz²))^(3/2)·min(1,h/a).
- Element size clamped by the non-planar 3D config; kink angle limited by user-set max (default 45°).
- r_n = max(|ΔP|∞/targetP, |ΔT|∞/targetT) — normalised local error
- ε_tol — user-set tolerance (default 1.0)
- Δt clamped to [dtMin, dtMax]
- Steps with r_n > 1 are rejected and dt is halved; steps with r_n ≤ acceptLo grow by acceptGrow (default 1.4×).
- Forced acceptance at dtMin sets clampedAtMin:true on the substep record for post-hoc audit.
- Time-varying sources and BCs evaluated at the midpoint of each substep (2nd-order in time for smooth forcing).
- V — slip rate [m/s]
- f — friction coefficient [-]
- Δτ — normalised time step
- Single fault patch, spring-slider, quasi-static (no inertia term).
- Explicit Euler on log(V) — well-suited when V·Δt/L_c ≲ 10⁻².
- Optional pore-pressure perturbation p_p(t) callback for injection ramps; slip-law state θ integrated on the aging law.
24.3 Unit conventions (field-first, converted at the boundary)#
Every UI input is field-unit. Conversions happen at exactly one place per module (the `*ToSi` helper) so a reviewer can grep for the boundary. The kernel itself is SI internally except where an industry-standard equation is more legible in field units (e.g. 0.052·ρ·TVD for hydrostatic pressure).
| Quantity | Field unit | SI unit | Conversion / formula |
|---|---|---|---|
| Depth / length | ft | m | × 0.3048 |
| Pressure | psi | Pa | × 6 894.757 |
| Mud weight | ppg | kg/m³ | × 119.826 |
| Hydrostatic p_h (short form) | psi | — | = 0.052 · ρ[ppg] · TVD[ft] |
| Rate | bpm | m³/s | × 0.002 649 |
| Volume | bbl | m³ | × 0.158 987 |
| Viscosity | cp | Pa·s | × 0.001 |
| Permeability | md | m² | × 9.869 233 × 10⁻¹⁶ |
| Temperature | °F | K | = (°F + 459.67) / 1.8 |
| Gas rate | Mscf/d | sm³/s | × 3.277 × 10⁻⁴ (60 °F, 14.696 psi) |
| Mass loading | ppm (mass) | kg/kg | × 10⁻⁶ |
24.4 Specialty material inputs (how each preset feeds the kernel)#
The three material presets (sodium nitrate, flour/epoxy diverter, black-powder residue tracer) are solute-only. None of them injects energetic mass or exothermic chemistry into the kernel. Below is a preset-by-preset breakdown of what each input actually changes, what it does NOT change, and which drift-guards lock that behaviour.
24.4.1 Sodium nitrate (NaNO₃) — tracer / scale-control additive#
- concPpm (50–5 000 ppm) → passive solute concentration on the fluid stream. Solver treats NaNO₃ as non-reactive: no Δρ correction beyond the linear brine-density hook, no exothermic source term, no Ksp check.
- fluidTempF (60–250 °F) → clipped into the μ(T) look-up used by the live-auto-HM thermal effect. Outside the band the preset gate refuses to accept the input.
- bottomholePsi (1 000–12 000 psi) → informational; validates the requested envelope against the tracer band.
- mudWeightPpg (8.3–14 ppg) → routed through the standard hydrostatic hook 0.052·ρ·TVD; there is NO separate oxidiser-loading branch.
- What it does NOT do: no combustion, no radical chemistry, no automatic coupling to the scaling-kinetics module (scalingKinetics.ts) unless the operator opts in via the Water solutes panel.
24.4.2 Flour / epoxy diverter — degradable mechanical diverter#
- concPpm (100–20 000 ppm) → inert-solid mass loading. Feeds the effective slurry density used by slurryHydrostatic.ts and the friction-factor bump in livePumping.ts.
- fluidTempF (70–200 °F) → gates the epoxy-cure window; outside this band the acknowledgement checkbox is disabled.
- bottomholePsi (1 500–11 000 psi) → informational; validates the diversion-mechanics envelope.
- mudWeightPpg (8.3–13 ppg) → hydrostatic scaling only. Heavier muds outside the band trigger a realism warning because the diverter washes through perforations.
- What it does NOT do: no degradation kinetics, no time-dependent plug strength, no coupling to the perforation-erosion model. The diverter is a constant inert loading for the duration of the stage.
24.4.4 Sensitivity callouts — how small input swings move the depth-profile outputs#
The callouts below apply a ±10% perturbation to each preset input and report the resulting change in the hydrostatic column, geotherm, or bottomhole-pressure envelope at a 10,000 ft TVD reference. Values are computed by `materialPresetSensitivity.ts` and rendered from the same evaluators the depth-profile charts use, so the sweep is byte-consistent with the visualization examples in Section 24.3.
Sodium nitrate (NaNO₃) — input sensitivity
±10% swing on each preset input, evaluated at 10,000 ft TVD. Depth curves below trace the dominant knob across the full profile.
- Concentration [ppm] → Hydrostatic P_h [psi]Negligible
A ±10% swing on concentration [ppm] produces no measurable change in Hydrostatic P_h at 10,000 ft TVD — chasing this input on the depth-profile is noise.
baseline=4941.48 · +Δ=4941.63 · −Δ=4941.33 · |ΔOut|=0.15 psi
- Fluid temperature [°F] → Temperature T(z) [°F]Dominant
A ±10% swing on fluid temperature [°F] shifts Temperature T(z) by ≈ 12 °F at 10,000 ft TVD — large depth-profile impact; keep the entered value inside the [60, 250] °F envelope.
baseline=280.00 · +Δ=292.00 · −Δ=268.00 · |ΔOut|=12.00 °F
- Bottomhole pressure [psi] → Bottomhole pressure [psi]Dominant
A ±10% swing on bottomhole pressure [psi] shifts Bottomhole pressure by ≈ 500 psi at 10,000 ft TVD — large depth-profile impact; keep the entered value inside the [1000, 12000] psi envelope.
baseline=5000.00 · +Δ=5500.00 · −Δ=4500.00 · |ΔOut|=500.00 psi
- Mud weight [ppg] → Hydrostatic P_h [psi]Dominant
A ±10% swing on mud weight [ppg] shifts Hydrostatic P_h by ≈ 494 psi at 10,000 ft TVD — large depth-profile impact; keep the entered value inside the [8.3, 14] ppg envelope.
baseline=4941.48 · +Δ=5435.63 · −Δ=4447.33 · |ΔOut|=494.15 psi
- Baseline
- +10% Bottomhole pressure
- −10% Bottomhole pressure
Flour / epoxy diverter — input sensitivity
±10% swing on each preset input, evaluated at 10,000 ft TVD. Depth curves below trace the dominant knob across the full profile.
- Mass loading [ppm] → Hydrostatic P_h [psi]Negligible
A ±10% swing on mass loading [ppm] produces no measurable change in Hydrostatic P_h at 10,000 ft TVD — chasing this input on the depth-profile is noise.
baseline=4687.02 · +Δ=4687.72 · −Δ=4686.32 · |ΔOut|=0.70 psi
- Fluid temperature [°F] → Temperature T(z) [°F]Dominant
A ±10% swing on fluid temperature [°F] shifts Temperature T(z) by ≈ 11 °F at 10,000 ft TVD — large depth-profile impact; keep the entered value inside the [70, 200] °F envelope.
baseline=270.00 · +Δ=281.00 · −Δ=259.00 · |ΔOut|=11.00 °F
- Bottomhole pressure [psi] → Bottomhole pressure [psi]Dominant
A ±10% swing on bottomhole pressure [psi] shifts Bottomhole pressure by ≈ 450 psi at 10,000 ft TVD — large depth-profile impact; keep the entered value inside the [1500, 11000] psi envelope.
baseline=4500.00 · +Δ=4950.00 · −Δ=4050.00 · |ΔOut|=450.00 psi
- Mud weight [ppg] → Hydrostatic P_h [psi]Dominant
A ±10% swing on mud weight [ppg] shifts Hydrostatic P_h by ≈ 469 psi at 10,000 ft TVD — large depth-profile impact; keep the entered value inside the [8.3, 13] ppg envelope.
baseline=4687.02 · +Δ=5155.72 · −Δ=4218.32 · |ΔOut|=468.70 psi
- Baseline
- +10% Mud weight
- −10% Mud weight
Black powder residue tracer — input sensitivity
±10% swing on each preset input, evaluated at 10,000 ft TVD. Depth curves below trace the dominant knob across the full profile.
- Residue marker conc. [ppm] → Hydrostatic P_h [psi]Negligible
A ±10% swing on residue marker conc. [ppm] produces no measurable change in Hydrostatic P_h at 10,000 ft TVD — chasing this input on the depth-profile is noise.
baseline=5200.08 · +Δ=5200.09 · −Δ=5200.07 · |ΔOut|=0.01 psi
- Fluid temperature [°F] → Temperature T(z) [°F]Dominant
A ±10% swing on fluid temperature [°F] shifts Temperature T(z) by ≈ 15 °F at 10,000 ft TVD — large depth-profile impact; keep the entered value inside the [60, 300] °F envelope.
baseline=310.00 · +Δ=325.00 · −Δ=295.00 · |ΔOut|=15.00 °F
- Bottomhole pressure [psi] → Bottomhole pressure [psi]Dominant
A ±10% swing on bottomhole pressure [psi] shifts Bottomhole pressure by ≈ 600 psi at 10,000 ft TVD — large depth-profile impact; keep the entered value inside the [1000, 14000] psi envelope.
baseline=6000.00 · +Δ=6600.00 · −Δ=5400.00 · |ΔOut|=600.00 psi
- Mud weight [ppg] → Hydrostatic P_h [psi]Dominant
A ±10% swing on mud weight [ppg] shifts Hydrostatic P_h by ≈ 520 psi at 10,000 ft TVD — large depth-profile impact; keep the entered value inside the [8.3, 15] ppg envelope.
baseline=5200.08 · +Δ=5720.09 · −Δ=4680.07 · |ΔOut|=520.01 psi
- Baseline
- +10% Bottomhole pressure
- −10% Bottomhole pressure
24.4.3 Black-powder residue tracer — passive post-perforating marker#
- concPpm (1–250 ppm) → passive marker concentration only. The preset explicitly refuses to accept energetic-mass inputs; live-charge sizing must be done by the perforating provider outside this app.
- fluidTempF (60–300 °F) → routed through the same μ(T) look-up as the other tracer.
- bottomholePsi (1 000–14 000 psi) → informational; captures the typical perforating BHP envelope.
- mudWeightPpg (8.3–15 ppg) → hydrostatic scaling only.
- What it does NOT do: no pyrotechnic chemistry, no detonation-shock coupling into the DDM tip solver, no coupling to the microseismic moment-tensor engine. The marker is thermally and mechanically inert in the kernel.
24.5 Hard limitations of this chapter#
- Discretization scheme summaries are indicative — the authoritative source is the drift-guard file listed under each equation's `usedIn` field.Why this matters, when it breaks, what to do instead
- Why it matters:
- A summary can drift out-of-sync with the code between manual revisions; trusting the manual over the test lets a stale claim mislead a reviewer.
- When it breaks down:
- After any physics PR that changes numerics but not the manual body (common when the change is a small numerical tolerance).
- Safer alternative:
- Grep the referenced test file before quoting a discretization detail in an audit; if the test disagrees with the manual, file a documentation bug and treat the test as authoritative.
- Unit-conversion factors above match ANSI/API 2564; small rounding differences vs. metric-first tools (Eclipse-EU, tNavigator) are within the ±0.05 % band.Why this matters, when it breaks, what to do instead
- Why it matters:
- A 0.05 % rounding difference compounds across a large well count; a portfolio calculation done half in field units and half in SI can drift by a full percent by the end.
- When it breaks down:
- Cross-tool workflows (Eclipse output → this app for post-processing, or vice-versa) and multi-well portfolio totals.
- Safer alternative:
- Do all conversions at one boundary and keep the entire downstream chain in one unit system; use the CSV export helpers so the boundary is auditable.
- The three material presets model solute loading only. Any request to model exothermic chemistry, degradation kinetics, or pyrotechnic charges is intentionally out of scope and will be rejected by the preset gate.Why this matters, when it breaks, what to do instead
- Why it matters:
- A user asking for exothermic / pyrotechnic modelling wants an answer the app cannot safely provide; silently accepting the input risks a design that under-estimates hazards.
- When it breaks down:
- Any operator input requesting energetic-mass or oxidiser sizing directly in the material preset envelope.
- Safer alternative:
- Route the request to the perforating / stimulation vendor's dedicated tool; use this app only for the passive-tracer / diverter modelling scope described in the preset.
- Non-Newtonian rheology branches collapse to Newtonian when their extra parameters are omitted; verify with the byte-identical drift-guards before assuming a run used the extended model.Why this matters, when it breaks, what to do instead
- Why it matters:
- Two runs can appear to be 'the same' because the UI shows the same numbers, but a hidden non-Newtonian branch flag can be on/off and materially change the pressure envelope.
- When it breaks down:
- Comparing runs across workspaces or across app versions where the rheology default may have moved.
- Safer alternative:
- Read the run's audit log for the actual rheology branch used; if the byte-identical drift-guard did not fire on both runs, treat them as different runs and re-baseline.
25. Worked verification case studies (equations → expected outputs)
Five hand-workable case studies that pin each headline equation to a numerical expected output and to the exact drift-guard test that locks it. Every case is byte-reproducible: plug the inputs into the formula, get the expected value, then grep the referenced test file to see the same numbers asserted in CI.
These cases are deliberately small so a reviewer can rework them in a spreadsheet in under two minutes. Each case cites (a) the manual equation number from Chapter 24, (b) the traceability item from Chapter 22 (model verification) or Chapter 23 (recent physics), and (c) the exact drift-guard file under src/lib/__tests__/ that asserts the expected value.
25.1 Case A — Hydrostatic pressure (single-fluid column)#
- ρ — mud / slurry density [ppg]
- TVD — true vertical depth [ft]
- 0.052 — API conversion constant (= 1 / (144·8.3454))
- Single-fluid column, no gas cut, no thermal expansion.
- Vertical column; deviated paths project onto the TVD component before applying this equation.
- Inputs: ρ = 9.8 ppg (water-based brine), TVD = 10 000 ft.
- Apply the equation: p_h = 0.052 · 9.8 · 10 000 = 5 096 psi.
- Cross-check the SI form: ρ_SI = 9.8 · 119.826 = 1 174.29 kg/m³; TVD_SI = 10 000 · 0.3048 = 3 048 m; p_h_SI = 1 174.29 · 9.80665 · 3 048 = 35 106 kPa = 5 091 psi (0.1 % rounding vs. the field short form — matches Chapter 24.3).
- Expected output: 5 096 psi at the bottom of the column.
- Traceability: equation 24.1 unit-conversion row (hydrostatic short form); asserted in src/lib/__tests__/slurryHydrostatic.test.ts and src/lib/__tests__/ballisticsWellHydrostatic.test.ts (same 0.052 constant, TVD-projected).
25.2 Case B — Theis line-source drawdown at a parent well#
- q — volumetric injection rate [m³/s]
- μ — fluid viscosity [Pa·s]
- k — permeability [m²]
- h — net thickness [m]
- r — radial distance from source [m]
- t — time since injection start [s]
- φ — porosity [-], c_t — total compressibility [1/Pa]
- W(u) — exponential integral (well function); for u ≪ 1, W(u) ≈ −γ − ln(u), γ = 0.5772
- Line-source (r_w ≪ r), single-phase, isothermal.
- Late-time / small-u branch (u ≲ 0.01) — the log-approximation is used in the analytical drift-guards.
- Inputs (SI): q = 0.01 m³/s, μ = 1e-3 Pa·s, k = 1e-13 m² (~ 100 md), h = 30 m, r = 500 m, t = 5 years = 1.577e8 s, φ = 0.10, c_t = 1e-9 1/Pa.
- Compute the u numerator: r²·φ·μ·c_t = 250 000 · 0.10 · 1e-3 · 1e-9 = 2.5e-8.
- Compute the u denominator: 4·k·t = 4 · 1e-13 · 1.577e8 = 6.308e-5.
- Combine: u = 2.5e-8 / 6.308e-5 = 3.964e-4 (i.e. u ≪ 1, deep in the late-time / log-approximation regime).
- Full W(u) via the Abramowitz-Stegun 5.1.11 series (matches expIntegralE1 in crossWellTomography.ts): W(u) = −γ − ln(u) − Σ_{n≥1} (−u)ⁿ / (n · n!). With u = 3.964e-4, ln(u) = −7.8339, so the leading term is −γ − ln(u) = −0.5772 + 7.8339 = 7.2567. The n=1 correction is −(−u)/1 = +u = 3.96e-4; n=2 is −u²/4 ≈ −3.9e-8; higher terms are < 1e-11. Sum: W(u) ≈ 7.2567 + 3.96e-4 ≈ 7.2571.
- Cross-check the small-u log branch: for u ≲ 0.01 the series collapses to W(u) ≈ −γ − ln(u), which reproduces 7.2567 within 0.01 % — this is the PASS branch the drift-guard exercises (no lookup table needed).
- Apply Theis: Δp = (q·μ) / (4·π·k·h) · W(u) = (0.01 · 1e-3) / (4·π · 1e-13 · 30) · 7.2571 = 1e-5 / 3.770e-11 · 7.2571 = 2.653e5 · 7.2571 = 1.925e6 Pa.
- Convert: Δp = 1.925e6 / 6 894.757 ≈ 279 psi.
- Expected output: ~279 psi drawdown at r = 500 m after 5 years — deep enough into the log branch that expIntegralE1(u) and the −γ − ln(u) shortcut agree to four decimals.
- Traceability: equation 24.1 (radial diffusivity); Chapter 23 recent-physics item for multi-well interference; expIntegralE1 in src/lib/crossWellTomography.ts; asserted in src/lib/__tests__/parentChildInterference.test.ts (Theis log-radial branch) and src/lib/__tests__/crossWellTomography.test.ts (Theis superposition).
25.3 Case C — Nordgren PKN half-length at late time#
- E' — plane-strain modulus = E / (1−ν²) [Pa]
- q — one-wing injection rate [m³/s]
- μ — fluid viscosity [Pa·s]
- h — fracture height [m]
- t — time since pump-start [s]
- PKN geometry (h fixed, L grows), Newtonian fluid, no leakoff (Carter branch handled separately).
- Late-time asymptote: t much larger than the toughness-dominated timescale.
- Inputs: E = 30 GPa, ν = 0.25 → E' = 30e9 / (1 − 0.0625) = 32.0 GPa; q = 0.05 m³/s (~ 27 bpm one-wing); μ = 0.1 Pa·s (100 cp cross-linked gel); h = 30 m; t = 3 600 s (60 min pump time).
- Compute the group inside the fifth root: E'·q³/(μ·h⁴) = 32.0e9 · (0.05)³ / (0.1 · 30⁴) = 32.0e9 · 1.25e-4 / (0.1 · 810 000) = 4.00e6 / 81 000 = 49.4.
- Fifth root: 49.4^{1/5} = exp(ln(49.4)/5) = exp(3.90/5) = exp(0.780) = 2.181.
- Time factor: t^{4/5} = 3600^{0.8} = exp(0.8 · ln 3600) = exp(0.8 · 8.189) = exp(6.551) = 700.6.
- L = 0.68 · 2.181 · 700.6 ≈ 1 039 m ≈ 3 410 ft one-wing half-length.
- Expected output: ~1 040 m half-length at t = 60 min for the tuned Bakken-like inputs.
- Traceability: equation 24.4 (DDM tip system — Nordgren asymptote is the analytical envelope of the DDM solver); Chapter 22 model-verification item for the analytical PKN reference; asserted in src/lib/__tests__/analyticalFractureModels.test.ts.
25.4 Case D — Mud-window shear-failure floor (Kirsch + Mohr-Coulomb)#
- p_w — wellbore pressure at the section [psi]
- σ_H, σ_h — max / min horizontal stress [psi]
- UCS — unconfined compressive strength [psi]
- φ — friction angle [rad]; q — the associated shear multiplier
- α — Biot coefficient [-], p_p — pore pressure [psi]
- Vertical borehole. Deviated paths route through wellboreStabilityMudWindowDeviated.ts with a first-crossing scan (see Chapter 22 verification note).
- Linear Mohr-Coulomb yield; no strain-softening.
- Inputs: σ_H = 10 000 psi, σ_h = 7 500 psi, UCS = 4 000 psi, φ = 30° → sin φ = 0.5, q = 1.5 / 0.5 = 3.0. α = 0.8, p_p = 4 500 psi.
- Right-hand side: 3·σ_H − σ_h − UCS − α·p_p·(1 − q) = 30 000 − 7 500 − 4 000 − 0.8·4 500·(1 − 3) = 30 000 − 7 500 − 4 000 + 7 200 = 25 700 psi.
- Solve for the minimum p_w: p_w ≥ 25 700 / (1 + q) = 25 700 / 4 = 6 425 psi.
- Convert to a mud weight at TVD = 10 000 ft: ρ_min = p_w / (0.052 · TVD) = 6 425 / 520 = 12.36 ppg. Anything below 12.36 ppg triggers the shear-failure floor.
- Expected output: floor mud weight ≈ 12.36 ppg at 10 000 ft TVD for these stress inputs.
- Traceability: equation 24.5 (mud-window solver); Chapter 22 verification item for the deviated first-crossing scan; asserted in src/lib/__tests__/wellboreStabilityMudWindow.test.ts (vertical closed form) and src/lib/__tests__/wellboreStabilityMudWindowDeviated.test.ts (high-p_w regression + first-crossing scan added in this round).
25.5 Case E — Arps hyperbolic decline EUR#
- q_i — initial rate [bbl/d or Mscf/d]
- D_i — initial nominal decline [1/yr]
- b — Arps exponent [-]; b→0 exponential, b=1 harmonic
- q_ab — economic abandonment rate [same units as q_i]
- Single-well, single-phase, no interference (interference handled separately by parent-child).
- Terminal cutoff at q_ab (economic limit); hyperbolic branch is not integrated past that point.
- Inputs: q_i = 800 bbl/d, D_i = 0.85 /yr, b = 0.6, q_ab = 20 bbl/d.
- Convert q_i to a yearly basis: q_i_yr = 800 · 365 = 292 000 bbl/yr.
- Rate ratio: (q_ab / q_i)^{1−b} = (20 / 800)^{0.4} = 0.025^{0.4} = exp(0.4 · ln 0.025) = exp(−1.476) = 0.2287.
- Bracket: 1 − 0.2287 = 0.7713.
- EUR = q_i_yr / ((1 − b)·D_i) · bracket = 292 000 / (0.4 · 0.85) · 0.7713 = 858 824 · 0.7713 ≈ 662 400 bbl.
- Expected output: EUR ≈ 6.6e5 bbl for the tuned Bakken-tier hyperbolic inputs.
- Traceability: Chapter 23 recent-physics DCA item; equation 24.2 (mass-balance branch — Arps is the analytical envelope of the material-balance decline); asserted in src/lib/__tests__/arpsDca.test.ts (hyperbolic branch + EUR) and src/lib/__tests__/arpsMonteCarlo.test.ts (probabilistic EUR).
25.6 How to add a new worked case#
- Pick one equation from Chapter 24 (equations 24.1 – 24.5). If the equation isn't there yet, add it to Chapter 24 first so the traceability chain stays intact.
- Author the case as an `equation` block (with `usedIn`, `assumptions`, `validity`) followed by a `steps` block that walks a reviewer from inputs → arithmetic → expected output → test file.
- Cite the exact drift-guard filename under src/lib/__tests__/. If none exists, add one in the same PR — a worked case without a test is not a verification case.
- Keep the numbers small enough to rework in a spreadsheet in ≲ 2 minutes; anything larger belongs in the benchmark harness, not the manual.
25.7 Hard limitations of this chapter#
- Cases B and E use tuned inputs so the arithmetic stays hand-checkable; they are illustrative, not field-representative for any specific basin.Why this matters, when it breaks, what to do instead
- Why it matters:
- A reviewer who mistakes the illustrative inputs for basin defaults may quote them in a design review; that would misrepresent the calibration state of the actual field.
- When it breaks down:
- External audits and cross-team reviews where the reviewer does not know the case was tuned for legibility.
- Safer alternative:
- Substitute the case inputs with the workspace's actual calibration set before quoting numbers in a report; treat the manual value as a formula check, not a field claim.
- The Theis case computes W(u) via the A&S 5.1.11 series that expIntegralE1 uses in crossWellTomography.ts, so the hand value matches the drift-guard to ≲ 1e-6 for u ≲ 0.5. It remains a reviewer sanity check, not a substitute for the test assertion.Why this matters, when it breaks, what to do instead
- Why it matters:
- A ~0.5 % difference is fine for reviewer sanity but not for numerical verification; treating the tabulated value as golden hides real regressions the drift-guard would catch.
- When it breaks down:
- Anytime the manual case is cited as a golden in a PR review instead of the test assertion itself.
- Safer alternative:
- Cite the drift-guard test file (parentChildInterference.test.ts / crossWellTomography.test.ts) as the golden reference; use the manual case for scope-of-work explanation, not numerical certification.
- Cases here cover analytical / closed-form branches only. Fully-numerical branches (Phase-9 substepper, non-planar 3D DDM, thermo-poro 3-D) are verified against these analytical cases as limiting sub-cases, not with their own hand-workable examples.Why this matters, when it breaks, what to do instead
- Why it matters:
- Analytical envelopes bound the numerical solvers but do not prove correctness in the fully-coupled regime; a numerical branch can be right on every limiting sub-case and still wrong in a real coupled run.
- When it breaks down:
- Runs that combine several branches (e.g. thermo-poro + non-planar 3D + rate-and-state) where the coupling itself is the risk.
- Safer alternative:
- For coupled runs use the field-validation campaign workflow and pin the run to measured (t, P, T) data; a green analytical case is necessary but not sufficient for a coupled sign-off.
26. Keyword reference (symbol & term index)
Alphabetical index of the Greek symbols, acronyms, and domain terms used across the manual. Each entry cites the chapter that defines the term so you can jump straight to the derivation instead of grep-guessing.
This chapter is the reader's index — pick a symbol or acronym, follow the chapter marker, land on the defining equation or worked example. Chapter numbers below are the printed §-numbers you see in headings (§1 through §28 are contiguous; §21 is the release-notes index that closes the historical numbering gap).
26.1 Greek symbols#
- α (Biot coefficient) — effective-stress splitter σ' = σ − α·p. Defined §6 (Physics & equations), used §11 (poroelastic depletion) and §25 Case A/B.
- β (Forchheimer inertial coefficient) — non-Darcy pack term dP/dL = μv/k + βρv². Registry in §11 (advanced physics), audit in §22 (model verification).
- γ̇ (shear rate, 1/s) — Newtonian γ̇ = 8v/d, Carreau/CY μ(γ̇) surface. Defined §6, extended in §11 (Carreau-Yasuda + Maxwell modes).
- Δσ_h, Δσ_H (stress-shadow tensor components, psi) — Sneddon + Geertsma poroelastic Δσ. Derived §6, applied §11 (parent-child).
- ε (cluster efficiency, geo-mean = 1) — DAS-inverted intake fraction. §9 (Live operations) and §11 (DAS → geometry inversion).
- η (hydraulic diffusivity k/(φμc_t), ft²/s) — controls τ_D. Defined §6, used in dimensionless-time drift-guards §23.
- κ (Mardia concentration parameter) — greedy fault-set clustering. §11 (moment-tensor inversion → DFN).
- μ (fluid viscosity, cp) — appears in every leakoff/Darcy/inflow formula. Defined §6, referenced end-to-end.
- ν (Poisson's ratio) — Sneddon/Geertsma kernels. §6 and §11.
- ρ (density, ppg or kg/m³) — hydrostatic column. §25 Case A hydrostatic worked example.
- σ_h, σ_H, σ_v (principal stresses, psi) — Mohr/breakout envelope. §6 (physics) + §24 (mud-window derivation) + §25 Case E.
- τ (relaxation time, s / recovery time in crosslinker gels) — Maxwell mode τ_k and gel recovery τ_rec. §11 (rheology & crosslinker).
- φ (porosity, fraction) — appears in η, in invasion radius, in mass balance. §6 + §22 (mass-balance report).
- ψ (pseudo-pressure, psi²/cp) — gas-inflow Δψ = A·q + B·q². §11 (gas non-Darcy inflow).
26.2 Acronyms & product terms#
- BHP — bottom-hole pressure. Reported everywhere; see §9 (live operations) for the live-stream convention.
- BL — Buckley-Leverett fractional-flow benchmark. §22 (black-oil trust gates).
- CQI — Completion Quality Index (0–100 + A–F grade). §10 (sensitivity & completion).
- DAS / DTS — distributed acoustic / temperature sensing. §9 (live operations, fiber-optic transports).
- DCA — decline-curve analysis (Arps qi/Di/b + P10/P50/P90 EUR). §10 (economics) + §9 (RTA).
- DFIT — diagnostic fracture-injection test. Walkthrough §3, calibration wizard §5 Example 1.
- DFN — discrete fracture network. §6 (UFM-class DFN dispatcher) + §11 (moment-tensor → DFN).
- DDM3D — displacement-discontinuity method, 3-D non-planar kernel. §11 (Non-Planar 3D) + §23 (bridge to planar kernel).
- EUR — estimated ultimate recovery. §10 (Arps DCA + MC bands).
- FVF — formation volume factor (Bo, Bg). §5 Example 9 (black-oil PVT).
- GRI — Gas Research Institute public dataset. §22 (public-benchmark DFIT comparison).
- HF vs NF — hydraulic vs natural fracture. §11 (bedding-plane fracture) + Viewer 3D right-rail toggle.
- IPR / VLP — inflow / vertical-lift performance. §11 (artificial lift & non-Darcy skin).
- ISIP — instantaneous shut-in pressure. §9 (auto-pick, live operations).
- K_IC — mode-I fracture toughness (MPa·√m). Fit in §5 Example 1 (DFIT), used §6.
- MW — mud weight (ppg). §14 (units & sanity) + §25 Case A.
- OFAT — one-factor-at-a-time sweep. §7 (sensitivity) + §10 (optimizer suite).
- PKN / KGD / Radial — classical fracture geometry models. §6 physics + §22 verification.
- PVT — pressure/volume/temperature (black-oil correlations). §5 Example 9 + §11.
- RSF — rate-and-state friction. §11 (induced-seismicity advanced physics).
- RTA — rate-transient analysis (Blasingame / Agarwal-Gardner). §9.
- SHmax — maximum horizontal stress azimuth. §6 (Hubbert-Willis tensor) + §5 Example 5 (inversion).
- SI — saturation index (log10 IAP/Ksp) for mineral scale. §11 (scaling kinetics).
- TSO — tip screen-out. §9 (net-pressure match).
- UFM — unconventional fracture model. Called out in the honest-scope note in §6.
- WITSML — wellsite information transfer standard. §9 (telemetry transports).
26.3 Chapter markers used in cross-references#
When prose says 'see §6.2' it means chapter 6, second equation. Chapter numbers are parsed from the leading number of each heading (e.g. '22. Model verification' → §22). Every §-number from §1 through §28 is present — §21 is the release-notes index that closes the historical numbering gap. Equation ordinals restart at 1 inside every chapter, so §6.2 and §11.2 are unrelated.
- §1–§4 — orientation & walkthroughs.
- §5 — worked examples (numbers in, numbers out).
- §6 — core physics & governing equations.
- §7–§10 — sensitivity, calibration, live ops, optimization.
- §11 — reservoir/wellbore/fluids & advanced physics (RSF, non-Darcy, scaling, DDM3D…).
- §12–§14 — reports, exports, workspace toggles, units & sanity.
- §15–§20 — recently-shipped and 'what's new' changelogs.
- §21 — release-notes index (v1.4 / v1.6 / v1.7 / v1.8 cross-links + roadmap pointer; closes the historical numbering gap).
- §22 — model verification (BL, mass-balance, public benchmarks).
- §23 — recent physics + numerical additions (round-3 answers).
- §24 — numerical-method background & specialty material inputs.
- §25 — worked verification case studies (five hand-workable cases).
- §26 — this keyword reference.
- §27 — data-entry patterns (paste-from-Excel, LAS, JSON scenarios, CSV templates, supported file formats).
- §28 — offline & deployment policy (online-first, read-only offline cache, Electron field build, PWA home-screen).
27. Data entry patterns
Every supported way to get field data into the Builder — paste-from-Excel column mappings, LAS column spec, JSON scenario schema pointer, CSV templates, and the master list of supported deck / telemetry / interchange formats.
This chapter answers 'what file do I upload where'. Every Builder panel exposes a Paste-from-Excel tab; heavy interchange formats (LAS, WITSML, CMG/ECLIPSE decks) route through dedicated importers. Round-trip anything you build through JSON so a teammate can reproduce your run exactly.
27.1 Paste-from-Excel#
Every non-trivial Builder panel has a Paste-from-Excel tab that accepts a rectangular block copied from Excel / Numbers / Sheets. The panel parser is column-order tolerant when the first row is a header — otherwise it assumes the canonical Bakken-tutorial layout below. Units are always inferred from the bracketed suffix in the header (e.g. 'Perm [md]' vs 'Perm [nD]').
| Builder panel | Canonical column order (header row) | Notes |
|---|---|---|
| Static model — layers | Layer name · Top TVD [ft] · h [ft] · φ [-] · k [md] · σ_h [psi] · σ_v [psi] · E [Mpsi] · ν [-] · Biot α [-] | One row per layer, top-down. Missing σ_v is auto-filled from overburden gradient. |
| Wells & perforations | Cluster ID · MD [ft] · Shots per cluster · Phasing [°] · Perf diameter [in] · CD [-] | One row per cluster. CD default 0.85; used by Karakas-Tariq skin. |
| Curve sets — kro/krw/krg/pc | S_w · k_ro · k_rw · k_rg · P_c [psi] | Ascending S_w. Missing columns become — (dash), NOT zero. |
| Fluid model — PVT | p [psi] · B_o [rb/stb] · μ_o [cp] · R_s [scf/stb] · B_g [rb/scf] · μ_g [cp] | Sorted by p; used to build the black-oil PVT table. |
| Well controls — schedule | t_start [min] · Duration [min] · Rate [bpm] · Cppa [ppg] · Fluid ID · Role (preflush/pad/slurry/postflush) | Role tag drives the 4-role stage classifier. |
| Water solutes | Ion · Concentration [mg/L] | Names match §11 mineral catalog (Na+, Ca2+, SO4^2-, HCO3-, …). |
| Field measurements (WFT/DST/DFIT) | Depth MD [ft] · TVD [ft] · Pressure [psi] · Temp [°F] · Fluid density [ppg] · Uncertainty ± [psi] | Feeds the Pressure Advisor cross-check card. |
27.2 LAS files (well logs)#
LAS 2.0 / 3.0 ASCII well logs upload from Static model → Curve sets → Import LAS. The parser reads ~V, ~W, ~C, ~P, and ~A sections; ~O (other) is ignored. Depth must be MD in feet or metres — the header UNIT field decides. Non-finite / -999.25 sentinels are converted to null (renders as — in charts).
| LAS mnemonic | Maps to | Required? |
|---|---|---|
| DEPT / MD | Row depth axis | Yes |
| GR | Gamma-ray (API) — used by mineralogyInverter | Recommended |
| RHOB | Bulk density (g/cc) | Recommended |
| NPHI | Neutron porosity (v/v) | Recommended |
| DTC / DT | Compressional slowness (μs/ft) — E modulus estimator | Optional |
| DTS | Shear slowness (μs/ft) — ν estimator | Optional |
| PEF | Photoelectric factor — mineralogy tie | Optional |
| SP | Spontaneous potential | Optional |
| RES / RILD / RT | Resistivity — Sw estimator | Optional |
Multi-well LAS bundles: upload one .zip and every .las inside is parsed with the archive filename as the well tag. Duplicate curve mnemonics are suffixed _2, _3, … so no data is silently dropped.
27.3 Supported file formats#
The master table below is the answer to 'our datafile will be in JSON type only?'. JSON is the native round-trip format, but the app also accepts every heavy interchange format the drilling / completion / reservoir world uses. Anything not listed here should be pasted via §27.1 or converted to CSV.
| Category | Format | Extensions | Direction | Entry point |
|---|---|---|---|---|
| Native | JSON scenario (versioned) | .json | Read + Write | Builder → Export / Import simulation |
| Native | CSV templates | .csv | Read + Write | public/templates/*.csv · every Builder panel export |
| Well logs | LAS 2.0 / 3.0 | .las, .zip | Read | Static model → Curve sets → Import LAS |
| Reservoir deck | ECLIPSE datafile | .DATA | Read | Import parity → ECLIPSE (mrstCmgDeckImport) |
| Reservoir deck | CMG STARS/IMEX/GEM | .dat | Read | Import parity → CMG |
| Reservoir deck | MRST script (partial) | .m | Read | Import parity → MRST |
| Grid | GRDECL corner-point | .grdecl, .inc | Read | Static model → Grid import |
| Interchange (Energistics) | RESQML v2.x | .epc, .xml | Read | Static model → Interop import |
| Live telemetry | WITSML 2.x | https(s):// endpoint | Read (stream) | /live-pumping → WITSML transport |
| Live telemetry | Apache Arrow Flight | flight+https:// endpoint | Read (stream) | /live-pumping → Arrow Flight transport |
| Live telemetry | Fiber-optic frames (DAS / DTS) | ws(s):// or http(s):// | Read (stream) | /live-pumping → DAS / DTS transports |
| Production | ProdML monthly | .xml | Read | /rta → ProdML import |
| Spreadsheet paste | Excel / Numbers / Sheets rectangular selection | clipboard | Read | Every Builder panel — Paste-from-Excel tab |
| Reports | PDF (jsPDF) | Write | Builder → Export → * report | |
| Reports | CSV audit ledgers | .csv | Write | Every Results / Live / Sensitivity panel |
| Backup | Workspace ZIP (JSON + CSV bundle) | .zip | Read + Write | Simulations home → Export / Import |
Python SDK examples for every read-format above live under public/sdk/python/examples/. The examples wrap the same public /api/public/sdk/v1/* endpoints the web app uses, so anything you can do in the UI is scriptable.
27.4 JSON scenario schema#
Scenario files are Zod-validated on read. The envelope is a discriminated union on `kind` (dfit-calibration / expert-job-setup / pressure-advisor / …); each `kind` has its own strict input schema in src/lib/scenarioInputSchemas.ts. Older v1 files auto-upgrade to v2 on load — you never need to edit them by hand. The full schema is published as JSON-Schema at /schemas/scenario.v2.json for external tooling.
- Version envelope: `{ version: 2, kind, inputs, meta: { createdAt, createdBy, appVersion } }`.
- All numeric fields are `number().finite()` — NaN and Infinity are rejected at parse time.
- Missing optional fields fall through to `defaultXxxInputs()` factories (one per kind).
- Round-trip is byte-stable: `parse(build(x)) === x` for every kind (locked by scenarioJsonIo.test.ts).
27.5 CSV templates#
Every Builder panel and every Results / Live / Sensitivity export uses the same dash convention (see §12 exports): missing numerics render as — (em-dash), never 0 or empty. Templates that a user can pre-fill live under public/templates/ and are linked from the matching panel's Paste-from-Excel tab.
- public/templates/history-match-measured-bhp.csv — measured (t [s], BHP [psi]) time series for the /history-match interval-fit tab.
- public/templates/history-match-measured-rate.csv — measured (t [s], rate [bpm]) time series (same fitter).
- public/templates/field-measurements-wft.csv — depth-referenced WFT / DST / DFIT observations for §27.1 field-measurements paste.
- public/templates/microseismic-catalog.csv — (t [s], x [ft], y [ft], z [ft], mag) for the /parent-child ingest.
- public/templates/production-monthly.csv — (date, q_o [stb/d], q_w [stb/d], q_g [Mscf/d]) for the RTA DCA fit.
28. Offline & deployment policy
Where and how the app runs — online-first web, read-only browser-cache offline, PWA home-screen install, and the fully-offline Electron field build. One page, no ambiguity.
The short version: the web app is online-first, works read-only offline for scenarios you have already opened, installs to your phone as a home-screen icon (no service worker — no stale-cache traps during a live frac), and has a fully-offline Electron packaging path for field engineers who cannot rely on connectivity.
28.1 Online-first web (default)#
- Team scenarios, versioning, and cross-device sync all live on Lovable Cloud (managed backend). Cloud is REQUIRED for those features.
- Individual workspace state — Builder inputs, chart settings, cadence presets — is mirrored to localStorage per browser, so a network blip does NOT lose your in-flight work.
- Sign-in state is refreshed on tab focus. If you lose Cloud connectivity, the app stays in the current view until you navigate; on next navigation it prompts to reconnect.
28.2 Read-only offline (browser cache)#
- Every scenario you open at least once is available offline via the browser HTTP cache and the localStorage stores keyed under downhole.*.
- Builder + Sensitivity + RTA + Live-pumping REPLAY mode all keep working against localStorage data — no round-trip needed.
- Publishing new scenarios, running server-side sensitivity, and Cloud sync all require connectivity — the app chips these as 'Offline — reconnect to run' rather than failing silently.
- There is no service worker. This is deliberate: a service worker that cached the app shell could keep serving a stale UI during a live frac, which is a safety issue we refuse to accept.
28.3 PWA home-screen (manifest-only)#
- The app ships a Web App Manifest at /manifest.webmanifest with `display: standalone`, a theme colour, and an icon.
- On iOS Safari: Share → Add to Home Screen adds a full-screen app icon. On Android Chrome: three-dot menu → Install app.
- This is manifest-only: no service worker is registered, so 'Add to Home Screen' does NOT enable offline caching. It only gives you an app-style icon and standalone chrome.
- The installed launcher hits the live URL every time — you always see the latest deploy. That is intentional for a field-operations tool.
28.4 Fully-offline field build (Electron)#
- For engineers on frac locations with no reliable connectivity, we ship an Electron desktop packaging path (Windows / macOS / Linux).
- The Electron build bundles the same physics kernels and Builder UI, plus a local scenario store that syncs when the laptop comes back online.
- Cloud-only features (team scenarios, cross-device sync, published sharing links) are chipped as unavailable in the offline build, not silently disabled.
- Contact the Wellbore Genius team for the current Electron installer — the packaging pipeline lives outside this web repo.