mcpField
S
simpeg

simpeg

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

About simpeg

simpeg is a Python skill for setting up geophysical simulations and inversions. It guides researchers through meshes, surveys, forward models, and inversion workflows across several geophysical methods.

Key features

  1. 01TensorMesh and TreeMesh discretization
  2. 02Survey and simulation setup
  3. 03Forward modeling
  4. 04Data misfit and regularization
  5. 05Inversion workflow guidance

Use cases

  1. 01Build a DC resistivity survey model
  2. 02Invert observed geophysical data
  3. 03Set up custom forward modeling
  4. 04Combine datasets for joint inversion

Install

Copy the command and run it in a terminal.

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

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

Bundled files

References and scripts installed along with SKILL.md.

references/
mesh_types.md
survey_types.md
scripts/
dc_inversion.py

Details

From the project README

SimPEG - Geophysical Simulation & Inversion

Quick Reference

from discretize import TensorMesh
from simpeg.electromagnetics.static import resistivity as dc
from simpeg import maps, data_misfit, regularization, optimization
from simpeg import inverse_problem, inversion, directives
import numpy as np

# Create mesh
hx, hz = np.ones(100) * 10, np.ones(50) * 5
mesh = TensorMesh([hx, hz], origin='CN')

# Forward model
simulation = dc.Simulation2DNodal(mesh, survey=survey, sigmaMap=maps.ExpMap(mesh))
dpred = simulation.dpred(model)

# Inversion
dmis = data_misfit.L2DataMisfit(data=data, simulation=simulation)
reg = regularization.WeightedLeastSquares(mesh)
opt = optimization.InexactGaussNewton(maxIter=20)
inv_prob = inverse_problem.BaseInvProblem(dmis, reg, opt)
inv = inversion.BaseInversion(inv_prob, directiveList=[...])
mrec = inv.run(m0)

Key Classes

ClassPurpose
TensorMesh, TreeMeshDiscretization (regular grid, adaptive octree)
SurveyData acquisition geometry
SimulationForward modeling engine
DataObserved/predicted data container
InvProblemCombines misfit, regularization, optimization

Essential Operations

Create Mesh
from discretize import TensorMesh

# 2D mesh (x, z) - centered in x, top at z=0
hx, hz = np.ones(100) * 20, np.ones(50) * 10
mesh = TensorMesh([hx, hz], origin='CN')

# 3D mesh
mesh = TensorMesh([np.ones(50)*25, np.ones(50)*25, np.ones(30)*10], origin='CCN')
DC Resistivity Survey
from simpeg.electromagnetics.static import resistivity as dc

elec_locs = np.c_[np.linspace(-95, 95, 20), np.zeros(20)]
source_list = []
for i in range(17):  # dipole-dipole
    rx = dc.receivers.Dipole(elec_locs[[i+2]], elec_locs[[i+3]])
    src = dc.sources.Dipole([rx], elec_locs[i], elec_locs[i+1])
    source_list.append(src)
survey = dc.Survey(source_list)
Forward Model
model = np.ones(mesh.nC) * 100  # 100 ohm-m
simulation = dc.Simulation2DNodal(mesh, survey=survey, sigmaMap=maps.ExpMap(mesh))
dpred = simulation.dpred(np.log(1/model))  # input: log(conductivity)
Inversion
from simpeg import data_misfit, regularization, optimization
from simpeg import inverse_problem, inversion, directives, data

obs_data = data.Data(survey, dobs=dobs, standard_deviation=0.05*np.abs(dobs))
dmis = data_misfit.L2DataMisfit(data=obs_data, simulation=simulation)
reg = regularization.WeightedLeastSquares(mesh, alpha_s=1e-4, alpha_x=1, alpha_z=1)
opt = optimization.InexactGaussNewton(maxIter=20)
inv_prob = inverse_problem.BaseInvProblem(dmis, reg, opt)
dir_list = [directives.BetaSchedule(coolingFactor=2), directives.TargetMisfit()]
inv = inversion.BaseInversion(inv_prob, directiveList=dir_list)
mrec = inv.run(m0)

Common Maps

MapDescriptionUse Case
IdentityMapNo transformationSusceptibility, density
ExpMapexp(m)Log-parameterized conductivity
ReciprocalMap1/mResistivity to conductivity
WiresSplit modelJoint inversion

Physical Property Ranges

PropertyTypical RangeUnits
Resistivity1 - 10000ohm-m
Conductivity0.0001 - 1S/m
Susceptibility0 - 0.1SI
Density contrast-1 to 1g/cc

When to Use vs Alternatives

ScenarioRecommendation
Multi-method geophysical inversion (DC, magnetics, gravity, EM)SimPEG - broadest method coverage
Near-surface ERT with standard arrayspyGIMLi - simpler API, built-in array support
ERT-focused inversion with GUI exportpyGIMLi - better ERT-specific tooling
Custom forward modelling with flexible physicsSimPEG - modular design, easy to extend
Joint inversion of multiple geophysical datasetsSimPEG - built-in support via Wires maps
Commercial ERT processingRes2DInv / Res3DInv - industry standard

Choose SimPEG when: You need a unified framework for multiple geophysical methods, custom forward operators, or research-grade flexibility. Its modular design (mesh + survey + simulation + inversion) suits complex and non-standard problems.

Avoid SimPEG when: You only need standard ERT inversion (pyGIMLi is faster to set up), or you need a turnkey commercial solution.

Common Workflows

Run DC resistivity inversion from survey data
  • Define electrode locations and build dipole-dipole (or other) survey geometry
  • Create TensorMesh or TreeMesh with appropriate cell sizes
  • Set up dc.Simulation2DNodal with mesh, survey, and ExpMap
  • Load observed data into data.Data with standard deviations
  • Configure L2DataMisfit, WeightedLeastSquares regularization, and optimizer
  • Set directives: BetaSchedule, TargetMisfit
  • Build BaseInvProblem and BaseInversion
  • Run inversion with inv.run(m0) using a homogeneous starting model
  • Plot recovered model and compare observed vs predicted data
  • Check data misfit convergence (target chi-squared ~ 1)

Tips

  1. Use log parameters for positive quantities (resistivity, susceptibility)
  2. Start with coarse mesh and refine after initial tests
  3. Check data fit by plotting observed vs predicted
  4. Tune regularization to balance data fit and model smoothness
  5. Use TreeMesh for 3D problems to improve efficiency

References

Scripts

Comments

Markdown supported