A brief tutorial on Gempy 3D structural geological modeling

Gempy is an open source Python library for generating complete 3D structural geological models. The library is a complete development for creating geological models from interfaces, faults, and layer orientations, and it also associates the order of geological layers to represent rock intrusions and fault sequences.

insert image description here

Recommendation: Use NSDT Designer to quickly build programmable 3D scenes.

The geological modeling algorithm is based on generalized co-kriging interpolation and supports high-end Python math libraries such as Numpy, PyMC3, and Theano.

Gempy creates a mesh model that can be visualized as a 2D section using Matplotlib, or as a VTK object as a 3D geometric object, allowing representation of geological models on Paraview for custom slicing, filtering, transparency and styling.

This tutorial provides a basic example of a layered geological setup with 5 layers and 1 fault. To make this tutorial fully accessible to most users, we have created a supplemental tutorial on how to install Gempy on Windows using the Anaconda repository distribution.

The input files for this tutorial can be downloaded from this link.

1. Set up the Python environment

In this part, we import the libraries needed for this tutorial. The script requires Gempy as well as Numpy and Matplotlib. We configure Jupyter options after script cells to interactively represent Matplotlib figures (%matplotlib inline).

Note that warnings are just messages that the user must remember when running the script, and do not mean that the code failed. Since this tutorial was conducted on Windows, some supplementary libraries could not be installed, but the overall performance of the geological modeling code is intact.

# Embedding matplotlib figures in the notebooks
%matplotlib inline

# Importing GemPy
import gempy as gp

# Importing auxiliary libraries
import numpy as np
import matplotlib.pyplot as plt

2. Creation of geological model objects and definition of geography

This tutorial creates a 100 column x 100 row x 100 layer grid over a 2km x 2km x 2km extension. Higher resolutions are possible but will take longer to compute. The coordinate system is a local coordinate system, and subsequent tutorials will use UTM coordinates to evaluate Gempy's performance.

Orientations and geological contacts were imported from CSV files and converted to Pandas dataframes. Geological series (faults/strata) and geological stratigraphic sequences are then defined.

It's worth mentioning that faults must be inserted independently, with the youngest being the first entry.

# Importing the data from CSV-files and setting extent and resolution
geo_data = gp.create_data([0,2000,0,2000,0,2000],[100,100,100],
                          path_o = "../Txt/simple_fault_model_orientations.csv", # importing orientation (foliation) data
                          path_i = "../Txt/simple_fault_model_points.csv") # importing point-positional interface data
gp.get_data(geo_data).loc[:,['X','Y','Z','formation']].head()
X	Y	Z	formation
interfaces	52	700.0	1000.0	900.0	Main_Fault
53	600.0	1000.0	600.0	Main_Fault
54	500.0	1000.0	300.0	Main_Fault
55	800.0	1000.0	1200.0	Main_Fault
56	900.0	1000.0	1500.0	Main_Fault
# Assigning series to formations as well as their order (timewise)
gp.set_series(geo_data, {"Fault_Series":'Main_Fault',
                      "Strat_Series": ('Sandstone_2','Siltstone', 'Shale', 'Sandstone_1')},
                       order_series = ["Fault_Series", 'Strat_Series'],
                       order_formations=['Main_Fault',
                                         'Sandstone_2','Siltstone', 'Shale', 'Sandstone_1',
                                         ], verbose=0)

3. Geological sequence map

Gempy has some useful features for representing defined geological series and stratigraphic sequences.

gp.get_sequential_pile(geo_data)
<gempy.plotting.sequential_pile.StratigraphicPile at 0x107149e8>

insert image description here

4. Review of input data

The different datasets used for geological model building can be accessed through Gempy's ".get_" function.

# Review of the centroid coordinates from the model grid
gp.get_grid(geo_data).values

array([[   10.,    10.,    10.],
       [   10.,    10.,    30.],
       [   10.,    10.,    50.],
       ..., 
       [ 1990.,  1990.,  1950.],
       [ 1990.,  1990.,  1970.],
       [ 1990.,  1990.,  1990.]], dtype=float32)

# Defined interfases from the input CSV data
gp.get_data(geo_data, 'interfaces').loc[:,['X','Y','Z','formation']].head()
X	Y	Z	formation
52	700.0	1000.0	900.0	Main_Fault
53	600.0	1000.0	600.0	Main_Fault
54	500.0	1000.0	300.0	Main_Fault
55	800.0	1000.0	1200.0	Main_Fault
56	900.0	1000.0	1500.0	Main_Fault
# Defined layer orientations from the input CSV data
gp.get_data(geo_data, 'orientations').loc[:,['X','Y','Z','formation','azimuth']]
X Y Z formation azimuth
2 500 1000 864.602 Main_Fault
1 400 1000 1400.000 Sandstone_2
0 1000 1000 950.000 Shale

5. Graphical representation of input data

In this section, 2D and 3D representations are used to present the interface and orientation.

gp.plot_data(geo_data, direction='y')

E:\Software\Anaconda3\lib\site-packages\gempy\gempy_front.py:927: FutureWarning: gempy plotting functionality will be moved in version 1.2, use gempy.plotting module instead
  warnings.warn("gempy plotting functionality will be moved in version 1.2, use gempy.plotting module instead", FutureWarning)

insert image description here

gp.plotting.plot_data_3D(geo_data)

insert image description here

6. Geological interpolation

After the input data is ready, we can define the interpolation data and parameters using the InterpolatonData method in the Gempy library.

Geological models are computed under the "compute_model" method. The result of the modeling process is lithology and faults with the same array dimensions as geo_data.

interp_data = gp.InterpolatorData(geo_data, u_grade=[1,1], output='geology', compile_theano=True, theano_optimizer='fast_compile')

Compiling theano function...
Compilation Done!
Level of Optimization:  fast_compile
Device:  cpu
Precision:  float32
Number of faults:  1

interp_data.geo_data_res.formations.as_matrix

<bound method NDFrame.as_matrix of              value  formation_number
Main_Fault       1                 1
Sandstone_2      2                 2
Siltstone        3                 3
Shale            4                 4
Sandstone_1      5                 5
basement         6                 6>

interp_data.geo_data_res.get_formations()

[Main_Fault, Sandstone_2, Siltstone, Shale, Sandstone_1]
Categories (5, object): [Main_Fault, Sandstone_2, Siltstone, Shale, Sandstone_1]

lith_block, fault_block = gp.compute_model(interp_data)

7. Lithology model exploration

A lithology block has two parts, the first part contains information about the lithology strata and the second part indicates the direction. In this section, the distribution of lithology and fault separation information is presented in the form of a histogram.

lith_block[0]

array([ 6.3131361 ,  6.24877167,  6.19397354, ...,  2.00398016,
        2.00626612,  2.00983   ], dtype=float32)

plt.hist(lith_block[0],bins=100)
plt.show()

insert image description here

plt.hist(fault_block[0],bins=10)
plt.show()

insert image description here

8. Geological model representation

The resulting lithology blocks can be represented on Matplotlib just like any other Numpy array. However, Gempy has a special way of representing cross sections. Using a Jupyter widget, an interactive representation of a geological cross-section along the Y direction can be performed using the handles to move along the row.

gp.plotting.plot_section(geo_data, lith_block[0], cell_number=50,  direction='y', plot_data=False)

insert image description here

import ipywidgets as widgets

def plotCrossSection(cell):
    gp.plotting.plot_section(geo_data, lith_block[0], cell_number=cell,  direction='y', plot_data=False)


widgets.interact(plotCrossSection, 
cell=widgets.IntSlider(min=0,max=99,step=1,value=50) )

insert image description here

gp.plotting.plot_scalar_field(geo_data, lith_block[1], cell_number=50, N=6,
                        direction='y', plot_data=False)
plt.colorbar()
plt.show()

insert image description here

ver_s, sim_s = gp.get_surfaces(interp_data,lith_block[1],
                               fault_block[1],
                               original_scale=True)

gp.plotting.plot_surfaces_3D(geo_data, ver_s, sim_s)

insert image description here


Original link: Gempy 3D structural geological modeling—BimAnt

Guess you like

Origin blog.csdn.net/shebao3333/article/details/131951329