mcpField
G
gempy

gempy

github.com/steadfastasartData & databases7366 installsUpdated 6w ago
Repository

About gempy

GemPy is a Python skill for implicit 3D geological modelling from surface points and orientations, for geoscientists building subsurface models. It represents structural relationships such as faults and unconformities and supports model visualization and export.

Key features

  1. 01Create 3D geological models
  2. 02Map surfaces into structural groups
  3. 03Represent faults and unconformities
  4. 04Compute lithology and scalar fields
  5. 05Visualize models in 2D and 3D
  6. 06Export models to VTK, NumPy, or CSV

Use cases

  1. 01Build a 3D model from contact points and orientations
  2. 02Represent fault offsets and erosion relationships
  3. 03Inspect model cross-sections and surfaces
  4. 04Export computed geology for downstream analysis

Install

Copy the command and run it in a terminal.

$npx skills add https://github.com/steadfastasart/geoscience-skills --skill gempy

After installing, type/gempyin Claude Code to confirm it loaded.

Bundled files

References and scripts installed along with SKILL.md.

references/
data_requirements.md
structural_relations.md
troubleshooting.md
scripts/
export_model.py
validate_input.py

Details

From the project README

GemPy - 3D Geological Modelling

Quick Reference

import gempy as gp

# Create model
geo_model = gp.create_geomodel(
    project_name='Model',
    extent=[0, 1000, 0, 1000, 0, 500],  # [xmin, xmax, ymin, ymax, zmin, zmax]
    resolution=[50, 50, 25]
)

# Add surface points and orientations
gp.add_surface_points(geo_model, x=[100, 500, 900], y=[500, 500, 500],
                      z=[400, 350, 400], surface='TopFormation')
gp.add_orientations(geo_model, x=[500], y=[500], z=[375],
                    pole_vector=[0, 0, 1], surface='TopFormation')

# Compute and visualize
gp.set_interpolator(geo_model)
sol = gp.compute_model(geo_model)
gp.plot_2d(geo_model, cell_number=[25], direction='y')

Key Classes

ClassPurpose
GeoModelMain container - holds all model data
StructuralFrameManages geological relationships
GridComputation mesh for interpolation
SolutionsModel results (lithology, scalar fields)

Essential Operations

Define Geological Relationships
gp.map_stack_to_surfaces(geo_model, mapping={
    'Strata1': ['TopFormation', 'BaseFormation'],
    'Basement': ['Basement']
})
geo_model.structural_frame.structural_groups[0].structural_relation = \
    gp.data.StackRelationType.ERODE
Add Faults
gp.add_surface_points(geo_model, x=[300, 300, 300], y=[200, 500, 800],
                      z=[100, 250, 400], surface='Fault1')
gp.add_orientations(geo_model, x=[300], y=[500], z=[250],
                    pole_vector=[1, 0, 0.5], surface='Fault1')
gp.map_stack_to_surfaces(geo_model, mapping={
    'Fault_Series': ['Fault1'],
    'Strata1': ['Layer1', 'Layer2'],
})
geo_model.structural_frame.structural_groups[0].structural_relation = \
    gp.data.StackRelationType.FAULT
Load Data from Files
import pandas as pd

points_df = pd.read_csv('surface_points.csv')  # Columns: X, Y, Z, surface
gp.add_surface_points(geo_model, x=points_df['X'], y=points_df['Y'],
                      z=points_df['Z'], surface=points_df['surface'])

ori_df = pd.read_csv('orientations.csv')  # Columns: X, Y, Z, dip, azimuth, surface
gp.add_orientations(geo_model, x=ori_df['X'], y=ori_df['Y'], z=ori_df['Z'],
                    dip=ori_df['dip'], azimuth=ori_df['azimuth'],
                    surface=ori_df['surface'])
Visualization
gp.plot_2d(geo_model, cell_number=[25], direction='y', show_data=True)
gp.plot_3d(geo_model, show_data=True, show_surfaces=True)  # Requires PyVista
Access Results
sol = gp.compute_model(geo_model)
lithology = sol.raw_arrays.lith_block
lith_3d = lithology.reshape(geo_model.grid.regular_grid.resolution)

Structural Relation Types

TypeDescription
ERODEYounger surface erodes older (unconformity)
ONLAPYounger onlaps onto older
FAULTSurface is a fault plane
INTRUSIONIntrusive body

When to Use vs Alternatives

ScenarioRecommendation
3D implicit geological modelling from surface dataGemPy - purpose-built, Python-native
Complex fold modelling with structural framesLoopStructural - better fold support
Commercial-grade subsurface modellingSKUA-GOCAD - industry standard, proprietary
Quick 2D cross-sections onlyGemPy works but may be overkill; consider manual interpolation
Need gravity/magnetics forward model from geologyGemPy - has built-in potential field support

Choose GemPy when: You need implicit 3D geological modelling from surface contacts and orientations with fault/unconformity relationships, especially when integrated with Python workflows. It has a gentler learning curve than LoopStructural for standard cases.

Avoid GemPy when: Your geology is dominated by complex folding (use LoopStructural), or you need production-grade reservoir modelling (use commercial tools).

Common Workflows

Build 3D geological model from surface data
  • Load or define surface contact points (min 2 per surface) and orientations (min 1 per surface)
  • Create GeoModel with appropriate extent and resolution
  • Add surface points with gp.add_surface_points()
  • Add orientations with gp.add_orientations()
  • Map geological stack with gp.map_stack_to_surfaces()
  • Set structural relations (ERODE, ONLAP, FAULT)
  • Set interpolator with gp.set_interpolator()
  • Compute model with gp.compute_model()
  • Validate with 2D cross-sections using gp.plot_2d()
  • Visualize 3D result with gp.plot_3d() or export to VTK

Common Issues

IssueSolution
Model not computingCheck min 2 points + 1 orientation per surface
Artifacts at edgesExtend model extent beyond data
Wrong fault offsetCheck pole_vector direction
Memory errorsReduce grid resolution

References

Scripts

Comments

Markdown supported