Variograms in 3-D¶

This file is meant to demonstrate the use of gstlearn for calculating variograms on 3-D Data.

In [1]:
import numpy as np
import sys
import os
import gstlearn as gl
import gstlearn.plot as gp
import gstlearn.document as gdoc
import gstlearn.plot3D as gop
import matplotlib.pyplot as plt
import plotly.graph_objects as go

gdoc.setNoScroll()

We define the space dimension

In [2]:
ndim = 3
gl.defineDefaultSpace(gl.ESpaceType.RN, ndim)
np.random.seed(3131)

Defining the 2D location of well headers

In [3]:
nwells = 10
nvert = 15
nsamples = nwells * nvert
colar = np.random.uniform(size = (nwells,2))
z = np.random.uniform(size=nvert)
z = np.cumsum(z) / 10
a = np.zeros(shape=(nsamples,4))
for i in range(nwells):
    ind = np.arange(nvert)+nvert*i
    a[ind,0:2] = colar[i,:]
    a[ind,2] = z
for i in range(nsamples):
    a[i,3] = np.random.uniform()

Loading this array of values in a Data Base

In [4]:
db = gl.Db.createFromSamples(nsamples, tab=a.flatten(), names=["X","Y","Z","value"],
                             locatorNames=["x1","x2","x3","z1"])
db
Out[4]:
Data Base Characteristics
=========================

Data Base Summary
-----------------
File is organized as a set of isolated points
Space dimension              = 3
Number of Columns            = 5
Total number of samples      = 150

Variables
---------
Column = 0 - Name = rank - Locator = NA
Column = 1 - Name = X - Locator = x1
Column = 2 - Name = Y - Locator = x2
Column = 3 - Name = Z - Locator = x3
Column = 4 - Name = value - Locator = z1
In [5]:
db.getExtremas()
Out[5]:
array([[0.2003584 , 0.97446612],
       [0.10611527, 0.9628635 ],
       [0.05598033, 1.03142542]])

Defining a omnidirectional variogram¶

In [6]:
varioparam = gl.VarioParam.createOmniDirection(npas=10, dpas=0.1)
vario = gl.Vario.computeFromDb(varioparam, db)
In [7]:
vario
Out[7]:
Variogram characteristics
=========================
Number of variable(s)       = 1
Number of direction(s)      = 1
Space dimension             = 3
Variance-Covariance Matrix     0.083

Direction #1
------------
Number of lags              = 10
Direction coefficients      =      1.000     0.000     0.000
Direction angles (degrees)  =      0.000     0.000     0.000
Tolerance on direction      =     90.000 (degrees)
Calculation lag             =      0.100
Tolerance on distance       =     50.000 (Percent of the lag value)

For variable 1
      Rank    Npairs  Distance     Value
         0    73.000     0.029     0.074
         1   383.000     0.096     0.088
         2   309.000     0.200     0.072
         3   956.000     0.307     0.079
         4   844.000     0.410     0.080
         5  1783.000     0.501     0.082
         6  1361.000     0.599     0.084
         7  1516.000     0.700     0.082
         8  1401.000     0.795     0.088
         9   871.000     0.894     0.087
In [8]:
ax = gp.variogram(vario)
ax.decoration(title="OmniDirectional variogram")

Directional variogram¶

Vertical and omnidirectional in horizontal plane¶

We create a vertical direction and one horizontal direction. Note that:

  • we use a fine angular tolerance for calulation of the vertical direction
  • we use a bench selection for the horizontal calculation to avoid mixing information from samples to far away vertically.
In [9]:
varioparam = gl.VarioParam()

# Omnidirection in horizontal plane
dirhor = gl.DirParam.create(npas=10, dpas=0.1, tolang=90, bench=1)
varioparam.addDir(dirhor)

# Vertical direction
dirvert = gl.DirParam.create(npas=10, dpas=0.1, tolang=0.001, codir=[0,0,1])
varioparam.addDir(dirvert)

# Calculate the variogram in several directions
vario = gl.Vario.computeFromDb(varioparam, db)
In [10]:
vario
Out[10]:
Variogram characteristics
=========================
Number of variable(s)       = 1
Number of direction(s)      = 2
Space dimension             = 3
Variance-Covariance Matrix     0.083

Direction #1
------------
Number of lags              = 10
Direction coefficients      =      1.000     0.000     0.000
Direction angles (degrees)  =      0.000     0.000     0.000
Tolerance on direction      =     90.000 (degrees)
Slice bench                 =      1.000
Calculation lag             =      0.100
Tolerance on distance       =     50.000 (Percent of the lag value)

For variable 1
      Rank    Npairs  Distance     Value
         0    73.000     0.029     0.074
         1   383.000     0.096     0.088
         2   309.000     0.200     0.072
         3   956.000     0.307     0.079
         4   844.000     0.410     0.080
         5  1783.000     0.501     0.082
         6  1361.000     0.599     0.084
         7  1516.000     0.700     0.082
         8  1401.000     0.795     0.088
         9   871.000     0.894     0.087

Direction #2
------------
Number of lags              = 10
Direction coefficients      =      0.000     0.000     1.000
Direction angles (degrees)  =      0.000     0.000    90.000
Tolerance on direction      =      0.001 (degrees)
Calculation lag             =      0.100
Tolerance on distance       =     50.000 (Percent of the lag value)

For variable 1
      Rank    Npairs  Distance     Value
         0    20.000     0.022     0.094
         1   210.000     0.098     0.088
         2   140.000     0.195     0.071
         3   180.000     0.298     0.083
         4   150.000     0.411     0.080
         5   100.000     0.512     0.090
         6    80.000     0.603     0.077
         7    60.000     0.695     0.084
         8    70.000     0.801     0.096
         9    30.000     0.905     0.097
In [11]:
ax = gp.variogram(vario, idir=-1, flagLegend=True)
ax.decoration(title="Directional variogram")

Vertical and several directions in horizontal plane¶

In [12]:
varioparam = gl.VarioParam()

# First direction in horizontal plane
dirhor1 = gl.DirParam.create(npas=10, dpas=0.1, tolang=45, bench=1, codir=[1,0,0])
varioparam.addDir(dirhor1)

# Second direction in horizontal plane
dirhor2 = gl.DirParam.create(npas=10, dpas=0.1, tolang=45, bench=1, codir=[0,1,0])
varioparam.addDir(dirhor2)

# Vertical direction
dirvert = gl.DirParam.create(npas=10, dpas=0.1, tolang=0.001, codir=[0,0,1])
varioparam.addDir(dirvert)

# Calculate the variogram in several directions
vario = gl.Vario.computeFromDb(varioparam, db)
In [13]:
ax = gp.variogram(vario, idir=-1, flagLegend=True)
ax.decoration(title="Directional variogram")