- Pytorch
- Numpy
- Matplotlib
- Jupyter notebook
Ensure Python and PyTorch compatibility: Python 3.10.10 and PyTorch 2.7.1 are used here.
import torch
import torch.nn as nn
import torch.optim as optim
import numpy as np
import matplotlib.pyplot as plt
from torch.utils.data import DataLoader, TensorDataset
# Set random seeds for reproducibility
torch.manual_seed(42)
np.random.seed(42)- The analytical solution is calculated using the traveltime formula presented by Morris Miller Slotnick
# Analytical solution for reference traveltime field T0
def calculate_T0(x, z, xs, zs, v_ref):
r = torch.sqrt((x - xs)**2 + (z - zs)**2)
return r / v_ref
T0 = calculate_T0(X, Z, source_x, source_z, v_ref)
# Calculate analytical traveltime T_data
if vertgrad == 0 and horigrad == 0:
T_data = torch.sqrt((X - source_x)**2 + (Z - source_z)**2) / v0
else:
# Corrected analytical solution
r_sq = (X - source_x)**2 + (Z - source_z)**2
# Convert denominator to tensor
denom = torch.sqrt(torch.tensor(vertgrad**2 + horigrad**2, device=device))
term = 1.0 + 0.5 * (vertgrad**2 + horigrad**2) * r_sq / (v_ref * velmodel)
# Clamp to avoid numerical issues
term = torch.clamp(term, min=1.0 + 1e-8)
T_data = torch.arccosh(term) / denom- Collocation points are 25% of the gridpoints
- Compute autodifferentiation for traveltime within the 2D domain
- Uses a trainable slope parameter a that dynamically scales with the input frequency.
- Dual-ELM framework for both traveltime (u) and velocity (v); each has 2000 hidden units.
PIELM-EikoNet/PIELM/PIELM README.md
Lines 183 to 289 in c402671
Training time: 44.01 minutes
# Predict on entire domain
with torch.no_grad():
u_pred = elm_u(coords).reshape(nx, nz).cpu().numpy()
v_pred = elm_v(coords).reshape(nx, nz).cpu().numpy()
T_pred = T0.cpu().numpy() * u_pred# Analytical solutions for comparison
T0_np = T0.cpu().numpy()
T_data_np = T_data.cpu().numpy()
velmodel_np = velmodel.cpu().numpy()The full script to the quick tutorial is available here

