Quick Start#
This page walks through a minimal end-to-end workflow: generate a geological model, compute elastic properties, simulate seismic data, and run a deterministic inversion.
1. Generate a Geological Model#
import torch
from geobrain.geomodel import Simulator, SimulationConfig
config = SimulationConfig(
shape=(100, 200),
lh=15, lv=5,
mean=0.25, std=0.05,
seed=2025,
)
sim = Simulator.create("fft_ma")
porosity = sim.simulate(config)
print(f"Porosity: shape={porosity.shape}, range=[{porosity.min():.3f}, {porosity.max():.3f}]")
Fig. 7 Porosity field generated by FFT-MA.#
2. Rock Physics Forward Model#
Convert porosity to elastic velocities using the rock physics module:
from geobrain.physics.rock import SoftSand, Gassmann, DensityModel, v_from_moduli
soft_sand = SoftSand()
gassmann = Gassmann()
K_m, G_m = 36.6, 44.0 # Mineral moduli (GPa)
K_fl, rho_fl = 3.06, 1.08 # Fluid properties
rho_m = 2.65 # Mineral density (g/cm3)
pressure = torch.ones_like(porosity) * 20
k_dry, g_dry = soft_sand(K_m, G_m, porosity, 0.4, 7, pressure)
k_sat, g_sat = gassmann(k_dry, g_dry, K_m, K_fl, porosity)
rho = DensityModel()(porosity, rho_m, rho_fl)
vp, vs = v_from_moduli(k_sat, g_sat, rho)
Fig. 8 Rock physics: porosity to elastic velocities.#
3. Seismic Forward Modeling#
Generate a synthetic seismic section using AVO reflectivity and wavelet convolution:
from geobrain.physics.wave import (
RickerWavelet, compute_reflectivity, create_conv_matrix,
)
# Reflectivity from layer contrasts
vp1, vp2 = vp[:-1], vp[1:]
vs1, vs2 = vs[:-1], vs[1:]
rho1, rho2 = rho[:-1], rho[1:]
refl = compute_reflectivity(vp1, vs1, rho1, vp2, vs2, rho2,
theta=[0], method='shuey')
# Wavelet convolution
ricker = RickerWavelet()
wavelet, _ = ricker(f0=25.0, dt=0.001)
W = create_conv_matrix(wavelet, refl.shape[-1])
nsW = len(wavelet) // 2
W = W[nsW:-nsW].T
seismic = refl @ W.T
Fig. 9 Synthetic seismic angle gathers.#
4. Deterministic Inversion#
Recover the velocity model from the synthetic seismic data:
from geobrain import InverseProblem
problem = InverseProblem(
forward_fn=my_forward, # Your forward operator
observed=seismic,
noise_std=0.01,
)
inverter = problem.create_inverter(initial_model=vp_init)
result = inverter.run(problem.observed, max_epochs=200, lr=0.01)
print(f"Final loss: {result.loss_history[-1]:.6f}")
5. Bayesian Uncertainty Quantification#
Quantify uncertainty using SVGD:
from geobrain import SVGD
posterior = problem.as_posterior(log_prior=my_prior)
svgd = SVGD(target=posterior, lr=0.005)
result = svgd.run(n_samples=50, n_steps=500)
print(f"Ensemble mean shape: {result.samples.mean(dim=0).shape}")
print(f"Ensemble std shape: {result.samples.std(dim=0).shape}")
Fig. 10 Bayesian inversion posterior comparison.#
Next Steps#
Explore detailed module documentation
Work through the 15 tutorials covering geomodeling, wave physics, flow simulation, and inversion
Read the Architecture page for design principles