Fluid Propagation¶
This test is meant to demonstrate the Fluid Propagation algorithm
import gstlearn as gl
import gstlearn.plot as gp
import gstlearn.document as gdoc
import matplotlib.pyplot as plt
import pandas as pd
import numpy as np
Data Presentation¶
The block system is constituted of 50 by 50 cells. Each cell measures 1m by 1m. Therefore, the grid lies between 1m and 50m along each direction. All the cells can be reached by the fluid: they are considered as filled with a homogeneous facies (Facies #1). The only difference lies in the permeability values assigned to each cell. The permeability information is read from a CSV file. This permeability field is considered through its log transform, by integer classes. The permeability values vary between 1.086 and 26831.300. Its log transform varies between 0.083 and 10.197, and therefore in integer classes lying from 0 to 10.
datcsv = pd.read_csv(
gdoc.loadData("Fluid", "Permeability.csv", verbose=False), header=None
)
datnp = np.array(datcsv)
logdatnp = np.log(datnp)
grid = gl.DbGrid.create([50, 50])
nFacies = 1
nFluids = 1
iuid = grid.addColumnsByConstant(nFacies, 1.0, "Facies")
iuid = grid.addColumns(datnp, "Permeability")
iuid = grid.addColumns(logdatnp.astype(int), "LogPerm")
dbfmt = gl.DbStringFormat.createFromFlags(
False, False, False, True, names=["Permeability", "LogPerm"]
)
grid.display(dbfmt)
Data Base Grid Characteristics ============================== Data Base Statistics -------------------- 5 - Name Permeability - Locator NA Nb of data = 2500 Nb of active values = 2500 Minimum value = 1.086 Maximum value = 26831.300 Mean value = 551.502 Standard Deviation = 1528.406 Variance = 2336025.270 6 - Name LogPerm - Locator NA Nb of data = 2500 Nb of active values = 2500 Minimum value = 0.000 Maximum value = 10.000 Mean value = 4.496 Standard Deviation = 1.709 Variance = 2.920
The log-permeability field is presented in the next figure.
fig, ax = plt.subplots(1, 1)
ax.raster(grid, name="LogPerm", flagLegend=True)
plt.show()
The (single) fluid is provided by a single injection well, located in the center of the block system. For the Fluid Propagation procedure, we consider that the central cell (25,25) is filled with fluid.
iuid = grid.addColumnsByConstant(nFluids, gl.TEST, "Fluid")
center = grid.indiceToRank([25, 25])
grid.setValue("Fluid", center, 1.0)
Result¶
We let the fluid invade the whole block system using the Fluid Propagation algorithm. As the whole block system is constituted of a single facies and as a single fluid is considered, the invasion speed only relies upon the permeability field.
Then we let the Fluid Propagation algorithm run during several iterations (as one additional cell is populated in each iteration). At the end of the process, the (single) fluid invades the whole block system. Note that a cell with a zero log-permeability is still invaded, but very slowly...
So the only interesting map is the one corresponding to the date (rank of the iteration) when the cell is invaded by the fluid. This map is presented in the next figure:
sl = 1
sm = 3
speeds = [sm, sm, sm, sm, sl, sl]
err = gl.fluid_propagation(
grid, "Facies", "Fluid", "LogPerm", "", nFacies, nFluids, 1, speeds, verbose=True
)
Fluid propagation parameters
============================
Number of facies = 1
Number of fluids = 1
Facies=1 - Fluid=1 - Dir #1=3 Dir #2=3 Dir #3=3 Dir #4=3 Dir #5=1 Dir #6=1
Skin algorithm: Initial status
------------------------------
- Total number of cells = 2500
- Number of cells already filled = 1
- Number of cells active = 2481
- Number of cells to be processed = 2480
Final status (iteration 1)
--------------------------
- Seed Value = 321321
- Cells already filled
. Facies 1 - Fluid 1 : Number = 2481 - Volume = 2481.000000
Total Number = 2481.000000
Total Volume = 2481.000000
Skin algorithm: Final status
----------------------------
- Number of iterations = 2481
- Maximum skin length = 195
- Maximum energy = 4551.000000
We can check the consistency between the location of the permeability bareers and the slowliness of the invasion. This map can finally be used in order to derive the break through time at the four wells located in the corners of the block system.
ax = gp.raster(grid, "Eden.Date", flagLegend=True)