Skip to content

v0.3.6 — Spectral elements, poroelastic waves, elastic Born

Latest

Choose a tag to compare

@GeophyAI GeophyAI released this 29 Oct 07:08
· 113 commits to dev since this release

sweep-solver 0.3.6

A spectral-element solver, poroelastic waves, elastic Born modelling, the pure-qP anisotropic equations on the CUDA core, and elastic topography rebuilt on a stable scheme. Upgrade with pip install -U sweep-solver; pip install -U sweepx brings it too (sweepx 0.4.1 requires it).

Breaking changes

  • The Born equations are named Born, not LSRTM, with no aliases: AcousticLSRTM / AcousticLSRTM3D / AcousticVTILSRTM / AcousticTTILSRTM are now AcousticBorn / AcousticBorn3D / AcousticVTIBorn / AcousticTTIBorn (modules acoustic_born, acoustic_born3d, qP_born; core entries acoustic_born2d, acoustic_born3d, qp_vti_born2d, qp_tti_born2d). A sweepx task that names equation: AcousticLSRTM must name AcousticBorn; sweepx 0.4.1 ships its LSRTM template that way.
  • The APM free surface is removed (topo_method='apm', ElasticAPM). Elastic topography is now ElasticCurvilinear (2-D) or the image-method staircase, which is also what topo_method='auto' resolves to for Elastic and Elastic3D. topo_method='apm' raises, and so does any name other than 'auto' and 'image'. 3-D elastic topography no longer has an impl='c' path.
  • ElasticCurvilinear works on the physical grid. Sources, receivers and topography= are physical grid indices, fractional rows allowed; they used to be the boundary-fitted grid's own rows. Models are sampled at the depth of the grid's rows and snapshots come back on the physical grid (snapshot_grid='computational' for the grid's own rows). spatial_order defaults to 16.
  • Records and gradients of the second-order acoustic family on impl='c' change (Acoustic, Acoustic3D, AcousticVRZ, AcousticVRZ3D, AcousticBorn, AcousticBorn3D, ViscoAcoustic): the compiled backward is now the exact transpose of the compiled forward, CPML band included.
  • The default eager gradient of AcousticVTI / AcousticTTI is s_gradient='adjoint' (it was the exact derivative, now 'exact').
  • New refusals where a gradient used to come back silently wrong or empty: the wavelet gradient of AcousticBorn(3D) and AcousticVRZ(3D) on impl='c'; the RWI vp gradient of LSRTM under memory=Ckpt(...); a wavelet that requires grad under ModelParallel; eager boundary saving for ViscoAcoustic, AcousticVTI and AcousticTTI; storage='disk' for LSRTM under ModelParallel. An eager source off the grid raises ValueError.
  • SWEEP_VRZ_GRAD_SPLIT is removed; setting it raises.
  • The core's C ABI is 3. A core built from an older tree (SWEEP_CORE, a cached local build) is refused at load; rebuild it. The cores in the wheel are rebuilt.

Added

  • ElasticBorn: Born modelling for the 2-D first-order elastic equation (Li, Guo, Li & Alkhalifah, 2019). The scattered field is the exact derivative of the Elastic step, free surface and topography included. Eager returns every gradient, the background ones being the elastic RWI gradient; impl='c' returns the dvp, dvs and drho gradients in every memory mode.
  • sweep.sem: a spectral-element solver for irregular topography. PropSEM takes PropTorch's constructor and call on Quad9 / Hex27 meshes fitted to the free surface: the acoustic potential, elastic and coupled fluid-solid equations in 2-D, acoustic and elastic in 3-D, and Biot poroelastic waves in 2-D (BiotVSSEM2DDeformed). C-PML, boundary saving, shot batching, per-shot models, local-window FWI and an x-strip domain decomposition; impl='c' CUDA kernels for eight of the classes. sweep list equations lists them next to the finite-difference equations, and sweep show <Class> describes one.
  • Biot: 2-D low-frequency Biot poroelastic waves (eager), fast P, slow P and S in one wavefield, with gradients. The viscous drag is integrated exactly, so any permeability runs at the fast-P time step; biot_from_rock builds the coefficients from rock properties.
  • AcousticVTI / AcousticTTI on impl='c' (Liang et al., 2023): forward, full-storage and boundary-saving backward, orders 2-8. s_gradient= chooses 'adjoint', 'frozen' or 'exact'.
  • AcousticVTIBorn / AcousticTTIBorn: the Born forms of the qP pair, eager and impl='c'.
  • sweep.datasets: chevron-fwi-2014, the SEG 2014 Chevron FWI synthetic (data, starting model, wavelet, well log).
  • Eager boundary saving for Elastic3D, DASMu, DASMu3D and ElasticVRR; eager storage='disk' and an asynchronous storage='cpu'; EagerOptions(cpml_strips=True).

Faster

  • Acoustic3D and AcousticVRZ3D on impl='c': 1.2-1.8x per step. Acoustic and AcousticVRZ (2-D): 1.05-1.55x.
  • The compiled eager step: derivatives fuse into the step kernel (1.2-4.5x on 2-D forwards, 1.1-7.3x on 2-D gradients, 2.5-10x at 128³) and a rollout compiles one graph instead of 3-6.
  • ElasticCurvilinear on compiled eager: 1.8-5.5x per step forward and 3-3.5x for gradients (order 16, 1024²-2048² grids, RTX 6000 Ada); EagerOptions(cpml_strips=True) now applies to it and halves its gradient memory. Receiver footprints (ElasticCurvilinear, ElasticTTI) are gathered in one index_select per step.

Fixed

  • PropSEM on a topography mesh no longer spends seconds per call locating its sources and receivers: the points are located in one batched Newton solve and kept per point (37 receivers: 4.7 s to 0.12 s a call). On float32 meshes the locations are now exact, which moves records by ~3e-5.
  • CPU results no longer depend on a first-call race in oneMKL's VML: on AVX-512 Intel CPUs the first multi-threaded sqrt / exp / log of a process could run a low-precision kernel in one thread's chunk (sqrt up to 3e-4 off). Importing sweep now settles it.
  • sweep.datasets downloads work again: the SEG S3 bucket stopped serving them, and the files now come from Zenodo and Hugging Face, checked by sha256.
  • 3-D boundary saving with storage_dtype='int8' / 'fp16': a race in the restore made the gradient change from run to run.
  • AcousticBorn(3D) under ModelParallel with storage='cpu': the gradient changed from run to run.
  • Boundary-saving gradients on a physical box thinner than two restore strips; registered gradients under a free surface; ViscoAcoustic with per-shot models; GPU memory kept by a dropped eager propagator under torch.compile.

Documentation

New notebooks: 33 (eager vs c), 34 (qP RTM / LSRTM), 38-40 (poroelastic kernels, radiation patterns, wavefields), 41-44 (SEM: FD against SEM on topography, Marmousi FWI, forward and gradient, batched local-window FWI), 45 (elastic Born, LSRTM and the RWI gradient). The API reference gains the SEM pages.

The CUDA cores are rebuilt (manylinux_2_28, ABI 3): cu12 601552de, cu13 191c054d. They add 16 entries for the qP equations, 5 for ElasticBorn and 43 for the SEM, rename the LSRTM entries to Born, and retire the two APM entries (65, 71); the finite-difference input structs are unchanged.

Full changelog: v0.3.5...v0.3.6 (details in CHANGELOG.md)