Overview
Naturally-fractured reservoirs are modeled with two co-located continua — a
fast-flowing fracture system and a matrix storage system — that exchange
fluid through a transfer function. BirSim reads a dual-porosity grid
(DUALPORO / DUALPERM), pairs each matrix cell with its fracture cell at equal
depth, and drives matrix↔fracture exchange with the Kazemi shape-factor
transmissibility T = σ·V_b·k_matrix.
The transfer is a regular flux connection, so it goes through the same mobility·ΔΦ kernel as any face and enters the Newton Jacobian fully implicitly. This report validates all three physical drives of that transfer:
- Pressure — depletion/support between the two continua.
- Gravity drainage — gas–oil counter-current segregation.
- Capillary imbibition — water–oil counter-current exchange.
Because OPM Flow does not support dual porosity, validation is by physics: counter-current direction, closed-system mass conservation, and equilibration to the analytically-known steady state.
The counter-current problem
Both gravity drainage and capillary imbibition are counter-current: one phase enters the matrix while another is expelled. With co-located cells at equal pressure, a naive single-connection transfer stalls — the expelled phase has no potential gradient to leave, so the imbibing phase cannot enter either. BirSim resolves this by giving each phase its own transfer potential:
- Gravity: a per-phase segregation half-height
gseg = ½·DZ_matrix— gas uses the block top (−gseg), oil/water the bottom (+gseg). - Capillary: the non-wetting (oil) phase gets an equal-and-opposite capillary
drive
+(Pcow_frac − Pcow_matrix), so oil is expelled as water imbibes.
Both live in the shared residual/Jacobian bodies, so the coupling stays fully implicit and Newton-consistent, and both are inert on ordinary faces — every non-dual-porosity benchmark is byte-for-byte unchanged.
1. Gravity drainage
Setup. A closed, single matrix–fracture block. The fracture holds a gas cap (Sg = 0.78); the matrix is oil-filled (Sg = 0.01). Both start at 250 bar — so the only drive is gravity segregation. Expected: gas invades the matrix from the top, oil drains into the fracture from the bottom, at constant pressure.
Saturations (start → 630 days)
| Cell | Phase | Start | Final | Direction |
|---|---|---|---|---|
| Fracture | Sg | 0.780 | 0.750 | gas leaves ↓ |
| Fracture | So | 0.020 | 0.050 | oil drains in ↑ |
| Matrix | Sg | 0.010 | 0.020 | gas invades ↑ |
| Matrix | So | 0.790 | 0.780 | oil drains out ↓ |
Gas moves fracture → matrix and oil moves matrix → fracture — textbook counter-current gravity drainage, at an essentially constant ~250 bar.
Mass conservation & stability
| Quantity | Result |
|---|---|
| Gas in place (reservoir vol) | 4050.0 → 4050.5 (+0.01%) |
| Oil in place (reservoir vol) | 11950 → 11949.5 (−0.004%) |
| Field pressure | 250.0 → 250.0 bar (constant) |
| Convergence | 0 rejected steps, 1 Newton iteration / step |
Surface volumes are conserved exactly (the transfer is a conservative connection flux); the sub-0.02% reservoir-volume wiggle is just the FVF response to a ~0.08 bar cell-to-cell pressure difference.
On / off control
| Configuration | Matrix Sg (final) | Result |
|---|---|---|
| Gravity on | 0.020 | drains as above |
Gravity off (BIRSIM_DUALPORO_GRAVITY=0) | 0.010 | inert — nothing moves |
At equal pressure the equal-pressure transfer does nothing; the segregation term is the sole driver.
2. Capillary imbibition
Setup. A closed water–oil block, no gravity. The fracture is water-filled
(Sw = 0.8), the matrix oil-filled (Sw = 0.2). Both start at equal pressure, so the
only drive is the matrix capillary pressure (from the SWOF Pcow column). Expected:
water imbibes into the matrix, oil is expelled, until the capillary pressures
balance — i.e. equal Sw (same rock curve), at the pore-volume-weighted mean
Sw = (0.05·0.8 + 0.15·0.2) / 0.20 = 0.35.
Equilibrium (20,000 days)
| Cell | Sw start | Sw final | Target |
|---|---|---|---|
| Fracture | 0.800 | 0.352 | 0.35 |
| Matrix | 0.200 | 0.349 | 0.35 |
Both continua converge to the analytic capillary equilibrium; water in place is conserved (7000 → 7000 reservoir·m³).
The stall it fixes
The naive transfer (capillary counter-current off) is a well-known failure mode: water cannot imbibe because oil cannot leave, so the solver thrashes and the saturations never move.
| Configuration | Matrix Sw (final) | Rejected steps | Newton iters |
|---|---|---|---|
| Capillary on (default) | 0.349 | 0 | 1,340 |
| Capillary off | 0.200 (locked) | 2,569 | 46,120 |
Cross-check. Running the naive transfer with 100× rock compressibility unlocks it and reaches the same 0.35/0.35 equilibrium — confirming the counter- current term reproduces the correct physics, not an artifact, while remaining well-conditioned at realistic compressibility.
Fully implicit & zero regression
Both mechanisms are implemented as per-connection offsets inside the shared
flux/Jacobian kernels (ResidualKernel.inl, JacobianKernel.inl), used
identically by the CPU and GPU backends. Two properties follow:
- Newton-consistent. Convergence is 1 iteration/step on the closed cases — the Jacobian linearization predicts the counter-current update exactly.
- No regression. The offsets vanish on ordinary faces (and when the two continua share the same Pcow), so SPE-1, SPE-9, the aquifer, VFP, MSW, and hysteresis benchmarks reproduce byte-identical Newton counts.
Validation summary
| Mechanism | Metric | Result |
|---|---|---|
| Gravity drainage | Counter-current direction | ✓ gas in / oil out |
| Gravity drainage | Mass conservation | under 0.02% (reservoir vol) |
| Gravity drainage | Stability | 0 rejects, constant pressure |
| Capillary imbibition | Equilibrium Sw | 0.35 (analytic mean) |
| Capillary imbibition | Conditioning | 0 rejects vs. locked-and-thrashing |
| Both | Implicit coupling | 1 Newton iteration / step |
| Both | Non-DP regression | byte-identical |
Open follow-ups: the stock Eclipse 2·N property-array layout (to ingest
unmodified dual-porosity decks) and a gas–oil capillary (Pcog) counter-current
term to mirror the water–oil one.