Modeling Well Transient Flow with Python
Reservoir engineers can draw some information from their reservoir by analyzing a well-test result. Well-test is an activity of opening a well to flow fluids from and into the reservoir (or production and injection, respectively) and shutting-in for several hours or days. The objective is not to produce the fluid to be considered as the economic value but to acquire data for understanding the reservoir.
Simulation or modeling a well-test is useful to observe how the well-flowing pressure and rate behave (we can call it transient response) when we do the actual test. Through this article, we will perform a simulation of a well-test using a program that I have prepared in Python. Let us now discuss the general idea of modeling well transient flow.
Single-Phase Fluid Flow in Porous Media
Our simulation is based on the Radial Darcy's flow, which is a flow of fluid directing radially from a cylindrical reservoir into the wellbore, or vice versa.
Several assumptions for Darcy's flow is that: the flow is single-phase, the flow is behaving laminar, the reservoir is homogeneous, several properties (reservoir permeability, porosity, fluid viscosity, and fluid compressibility) are constant over time, and the fluid is slightly compressible. The last two assumptions are approximately applicable to oil and water under an isothermal condition, and gases under high-pressure.
The flow is formulated as a partial differential equation (PDE) such that the pressure p derivative of the radial distance r to the wellbore and the time t.
When the flow is not yet reaching the outer reservoir boundary, the flow is called to behave infinite-acting. When the flow approaches the boundary, the flow is called to behave finite-acting. We can estimate the time when the flow starts to behave finite-acting using the following,
In 1949, van Everdingen and Hurst derived the analytical solutions of the above flow PDE for various boundary conditions. Two of their solutions are presented here because they are the most used solution for well-test practical applications, namely the constant terminal rate and constant terminal pressure with no-flow boundary. The analytical solution is not enough easy to implement because it contains what in maths called the Bessel function. Therefore, several approximations are made such as by Lee (1982).
During a well-test, if the flowing rate (q) or the flowing pressure (BHFP or pwf) is varied over time passage, it's called a multi-rate test or multiple-pressure test, respectively. The above flow solutions are implemented to do a simulation of this test. In a simulation of a multi-rate test, we acquire pressure results; likewise, a simulation of a multiple-pressure test produces rate results.
In addition, because the tests contain a series of rates and pressures, a principle known as the Principle of Superposition is applied. This is done by analogizing the change of rate or pressure of a well over time is similar to adding new wells with different rates or pressures over time.
The following is a tutorial to do modeling and simulation of multi-rate test and multiple-pressure well-tests with Python using a program called "wellflo" that I created through the implementation of the flow solution approximations and superposition principle.
Modeling Well Transient Flow with Python
You could get the wellflo program here. Unlike previous tutorials, there are no datasets used because we will purely do simulation on a mock case of multi-rate and multipressure test.
>>> See the full Python script for this tutorial here <<<
We do our usual routine of importing Numpy, Pandas, and Matplotlib. In this tutorial, we would like to make our plots to look different from the previous tutorials; we use the ggplot style of Matplotlib. Also, we import our wellflo program.
import numpy as np import matplotlib.pyplot as plt import pandas as pd plt.style.use('ggplot') from wellflo import *
There are two parts in this tutorial, simulation of well transient flow in a multi-rate test and a multiple pressure test.
Part 1. Multi-rate Test
In this part, we will simulate the transient flow of a well during a well test. The well is flowed over 5 series of different flow rates, first from the start of the test to hour-10, the well is let to flow 1,000 barrels a day. The flow is gradually increased by step until in hour-30, the flow is reduced and shut-in. The shut-in is done for 20 hours, and let to flow again until hour-70. The table below is the rate history.
Before we do the simulation, we need to specify some details of the well, the reservoir, and the fluid.
# known poro = 0.15 # Porosity ct = 12E-6 # Total formation + oil compressibility, sip perm = 600 # Permeability, md rw = 4 * .08333 # Radius of wellbore, convert inch to ft h = 32 # Reservoir thickness, ft mu = 2 # Oil viscosity, cp re = 3000 # Distance from centre of wellbore to outer reservoir boundary, ft Bo = 1.333 # Oil FVF, RB/STB
Then, define the initial pressure of the wellbore.
# define initial conditions p_initial = 2500 # Initial pressure, psia
Specify the time step of our simulation. A smaller number will produce a more accurate and narrower spaced result, however, will take more computational time. A time step of 0.1 hours is more than enough to produce an excellent result, so we will use this timestep.
# define time step (simulation starts from 0 hour) t_step = .1
Next, we specify the time and rate series based on the earlier table shown. There are five series of rate changes in our multi-rate test, so we specify five numbers in an array.
# define rate steps t_change = np.array([10, 20, 30, 45, 65, 70]) q_change = np.array([1000, 2000, 3000, 1500, 0, 1000])
We are done with the inputs. Now, we need to know what time when the flow starts to behave finitely acting. We can calculate the finite-acting time by running this script.
# calculate time at flow start to behave finite-acting t_finite_acting = time_finite_acting(perm, poro, mu, ct, rw, re) print(t_finite_acting)
This will print us a result of finite-acting time starting from about hour-51. Hence, we will have around 20 hours of finite-acting time until the end of our simulation. Next, we do the simulation. It's as simple as running the following one-line script because all algorithms have been packed inside. Simulate!
# simulate! simulate_multirate_test(p_initial, t_step, t_change, q_change, re, rw, perm, poro, mu, ct, Bo, h)
The simulation produces two profiles, the first is our well rate and the second is the simulated well flowing pressure, as follows,
Now, let's tweak some inputs we have. We can reduce the reservoir size to 1,000 ft. As we may guess, the finite-acting time will be shorter. Here's the result.
We can also simulate an injection (or build-up) test. Let's suppose we do an injection test with a similar rate as our earlier multi-rate production test. We need to invert the rates as follows,
q_change = np.array([1000, 2000, 3000, 1500, 0, 1000]) * -1
The rate becomes negative as the injection is simply the opposite of production. After we run a simulation, we'll see the following result.
Part 2. Multiple-Pressure Test
Now, we turn into a simulation of a multiple-pressure test. We will use the same timestep, reservoir, and fluid properties as before, but now we increase the reservoir size from 3,000 to 5,000 ft. The effect of increasing the reservoir size is to extend the finite-acting time. And also we reduce the initial pressure to 1,700 psia.
# known poro = 0.15 # Porosity ct = 12E-6 # Total compressibility, sip perm = 600 # Permeability, md rw = 4 * .08333 # Radius of wellbore, convert inch to ft h = 32 # Reservoir thickness, ft mu = 2 # Oil viscosity, cp re = 5000 # Distance from centre of wellbore to outer reservoir boundary, ft Bo = 1.333 # Oil FVF, RB/STB # define initial conditions p_initial = 1700 # Initial pressure, psia # define time step (simulation starts from 0 hour) t_step = .1
We will simulate a multiple-pressure test with a series of 6 varied pressures over 120 hours. The table below shows the pressure history of our simulated well-test.
Next, we define the time and pressure steps.
# define rate steps t_change = np.array([20, 40, 60, 80, 100, 120]) p_change = np.array([1500, 1200, 1000, 1400, 1600, 1000])
We'll now calculate the finite-acting time.
# calculate time at flow start to behave finite-acting t_finite_acting = time_finite_acting(perm, poro, mu, ct, rw, re) print(t_finite_acting)
The finite-acting time of the flow in this reservoir is around 142 hours, which means the flow in our simulation is behaving infinitely-acting until the 120 hours. Finally, we do the simulation.
# simulate! simulate_multipressure_test(p_initial, t_step, t_change, p_change, re, rw, perm, poro, mu, ct, Bo, h)
The simulation result is as follows,
Conclusion
Simulation of well-test is a very useful approach to study the pressure and rate transient response of a well in a multiple flow and shut-in condition. We could perform any simulation on any reservoir and fluid properties, and also varied rate-pressure steps, and help us understand more when we analyze a well-test result.
Reference
Lee, W. J. (1982). Well Testing: SPE Textbook Series Vol. 1. Society of Petroleum Engineers
Towler, B. F. (2002). Fundamental Principles of Reservoir Engineering: SPE Textbook Series Vol. 8. Society of Petroleum Engineers
Consultant RSE et ESG / Industries Extractives in SSA - Fluids SME w/ Law Firms / Legal Departments
4 年Olivier Malinur
Technical Sales WEATHERFORD | X-SPRINT CT Account Engineer | Petroleum Engineer | 2020 President at SPE NED Student Chapter | Intern at OGDCL and UEP | Projects Freelancer
4 年I developed it yohanes using linesr regressionand machine learning. Its easy and handy.
Support Consultant at Quorum Software
4 年Hello Yohanes Nuwara an student of Petroleum Engineering. Can i do project using this platform on well testing and on Reservoir
Senior Reservoir Engineering Consultant
4 年Very nice, and insightful simulation indeed :-). Just for fun I took it a step further and implemented it with a few lines of code in Mathematica, but I rather took the exact analytical solution of Van Everdingen – Hurst. The great advantage of the exact solution is, that one can follow the pressure evolution/distribution of the reservoir anywhere, and anytime. Below is a figure, which shows how the pressure evolves at certain dimensionless distances. On can easily see, that the pressure at the external boundary of the ( huge, reD ~ 9000 ) reservoir “feels” nearly nothing from the rate variations of the tiny well in the center. On the other hand as one moves closer, the pressure profile resembles more and more to that one of the well. In the shut in period all pressure locations build up to an equilibrium pressure. I just took the constant terminal rate solution, the constant terminal pressure solution would follow a similar logic. What a great achievement of Mr.Van Everdingen and Mr.William Hurst nearly 70 years ago, in times when nearly no computers and software existed! The very first steps in reservoir simulation. Their work was really a quantum leap in reservoir engineering. Tribute!
Petroleum Engineer
4 年May I ask how to install wellflo in Python?