Multi-event deconvolution
Multi-rate well-test deconvolution recovers a single equivalent constant-rate response from any number of buildups and drawdowns, dramatically extending the radius of investigation and revealing late-time boundaries that no individual buildup is long enough to see.
Mathematical framework
The convolution problem for a variable-rate well test is
where:
\(p_i\) is the initial reservoir pressure,
\(p_{wf}(t)\) is the measured flowing/shut-in pressure,
\(q(\tau)\) is the (piecewise-constant) rate history,
\(p_u(t)\) is the unit-rate constant-rate response — the unknown — and \(p'_u = dp_u/dt\) is its derivative.
Direct deconvolution (recovering \(p_u\) by deconvolving the rate history) is famously ill-posed: tiny noise in \(p_{wf}\) produces unbounded errors in \(p_u\). Regularisation is mandatory.
The vSH04 encoded formulation
We follow von Schroeter, Hollaender and Gringarten (2004), encoding the unknown as
Two crucial properties follow:
Positivity by construction. \(p'_u(t) = e^{z(\ln t)}/t \geq 0\), so the recovered derivative cannot become negative — even when noise would otherwise drive it below zero.
Logarithmic regularisation. The flow-regime signatures (WBS, IARF, linear, bilinear, …) appear as straight lines on a log–log plot. Smoothness on the \(\sigma = \ln t\) axis is the physically meaningful notion of smoothness for a Bourdet derivative.
The objective is
where:
\(\mathbf{y}\) is the observed pressure vector,
\(C(q, \mathbf{z})\) is the convolution operator applied to the rate history \(q\) and the encoded response \(\mathbf{z}\),
\(D\) is a centred second-difference matrix on the log-spaced \(\sigma\)-grid, so \(\| D\mathbf{z}\|^2 \approx \int |z''(\sigma)|^2 d\sigma\),
\(\nu\) is the user-set regularisation weight.
Both \(\mathbf{z}\) and \(p_i\) are recovered jointly (set
fit_p_initial=False to fix \(p_i\) instead).
Choosing \(\nu\)
The regularisation weight \(\nu\) controls the bias–variance trade-off:
\(\nu\) |
Effect |
|---|---|
small (≤ 1e−3) |
Low bias, high variance — derivative may oscillate. Use for low-noise tests with abundant late-time data. |
moderate (1e−2) |
Default. Typical balance for clean DSTs. |
large (≥ 1e−1) |
High bias, low variance — derivative is very smooth. Use for noisy mechanical-gauge data. |
A practical strategy: start at \(\nu = 10^{-2}\), then L-curve or GCV to refine if needed (not yet implemented in this package — contributions welcome).
API
The entry point is welltest_pta.deconvolve():
from welltest_pta import deconvolve
res = deconvolve(
events=wt.events, # iterable of Event
default_q=850, # STB/D for DDs without ev.rate
nu=1e-2, # regularisation weight
n_response_nodes=60, # log-spaced grid points
t_response_min=1e-3, # smallest Δt of recovered response (hr)
t_response_max=None, # default: max observation time
p_initial=None, # solve jointly with z (default)
fit_p_initial=True,
max_iter=200,
verbose=False,
)
The return type is welltest_pta.DeconvolutionResult, which
carries:
Attribute |
Meaning |
|---|---|
|
Recovered response grid (hr), log-spaced |
|
Unit-rate cumulative response (psi per unit \(q\)) |
|
Bourdet log-derivative |
|
Encoded variable \(z = \ln(dp_u/d\ln t)\) |
|
Recovered (or fixed) \(p_i\) (psi) |
|
Reconstructed \(p(t_{\text{obs}})\) |
|
\(\|\mathbf{y} - \mathbf{p}_{\text{fit}}\|_2\) |
Convenience methods:
plot()— log–log of recovered \(p_u\) and its derivative.export()— write CSV / Excel / JSON.to_dataframe()— long-form Pandas DataFrame.
Implementation notes
The non-linear least-squares problem is solved with Levenberg– Marquardt via
scipy.optimize.least_squares()(method="lm").Default residual tolerances are \(10^{-9}\).
The convolution operator uses piecewise-linear log-time interpolation of \(p_u\) on the response grid; this preserves the slopes of the various flow regimes when sampled.
Initial guess for \(\mathbf{z}\) is a constant level chosen so that \(p_u(t_{\max}) \approx \max p - \min p\) at the dominant rate.
Best-practice checklist
For a successful deconvolution:
Include both the immediately-preceding drawdown(s) and the buildup(s) you care about. Drawdowns provide the late-time constraint that buildups alone cannot.
Clean the buildup tails before deconvolving (the V8.1 detector does this automatically, but for manually-split events check that \(p_{\text{end}}\) is a true plateau, not a pull-spike).
Use consistent rate units throughout (typically STB/D for oil). The recovered \(p_u\) will be in psi per unit \(q\).
If \(\nu = 10^{-2}\) produces a wiggly derivative, increase by \(\times 10\). If it over-smooths a known flow regime, decrease by \(\times 10\).
References
von Schroeter, T., Hollaender, F., & Gringarten, A. C. (2004). Deconvolution of well-test data as a nonlinear total least-squares problem. SPE Journal 9 (4), 375–390.
Levitan, M. M. (2005). Practical application of pressure/rate deconvolution to analysis of real well tests. SPE 84290.
Gringarten, A. C. (2008). From straight lines to deconvolution: the evolution of the state of the art in well test analysis. SPE Reservoir Evaluation & Engineering 11 (1), 41–62.