Skip to content

ElasticBorn

sweep.equations.ElasticBorn

ElasticBorn(spatial_order=4, device='cpu', backend='torch')

Bases: sweep.equations.base.FirstOrderEquation

Born modelling for the 2-D first-order elastic equation (velocity-stress, staggered grid).

Two coupled copies of :class:Elastic: the background field (vx, vz, sxx, szz, sxz) propagating through (vp, vs, rho), and the scattered field (svx, svz, ssxx, sszz, ssxz) driven by the perturbation (dvp, dvs, drho) acting on the background field. Each field has its own ten CPML memories. Defaults: source on the background stresses (explosion), receivers on the scattered velocities -- the layout of elastic least-squares RTM and reflection waveform inversion.

The perturbations are absolute (same units as the background). Their gradients are the elastic LSRTM images; the background gradients are the reflection-waveform-inversion (RWI) ones of Li et al. (2019).

With impl='c' the backward is the :class:Elastic one: the scattered field's adjoint imaged against the background field, which is exactly the gradient of (dvp, dvs, drho), in every memory mode. The gradients of the background (vp, vs, rho) and of the wavelet are impl='eager' only (autograd); the compiled path refuses them.

Reference: Y. Li, Q. Guo, Z. Li and T. Alkhalifah, 2019, Elastic reflection waveform inversion with variable density, Geophysics 84(4), R553-R567, 10.1190/geo2017-0722.1.

Models (constructor input order)

  • vp (m/s): Elastic P-wave velocity model.
  • vs (m/s): Elastic S-wave velocity model.
  • rho (kg/m^3): Density model.
  • dvp (m/s): P-wave velocity perturbation.
  • dvs (m/s): S-wave velocity perturbation.
  • drho (kg/m^3): Density perturbation.

Wavefields

  • vx (aliases: velocity_x): Particle velocity in the x direction.
  • vz (aliases: velocity_z): Particle velocity in the z direction.
  • sxx (aliases: stress_xx): Normal stress in the x direction; default source.
  • szz (aliases: stress_zz): Normal stress in the z direction; default source.
  • sxz (aliases: stress_xz, shear_xz): Shear stress component.
  • m_vxx: CPML memory variable for dvx/dx (internal).
  • m_vxz: CPML memory variable for dvx/dz (internal).
  • m_vzx: CPML memory variable for dvz/dx (internal).
  • m_vzz: CPML memory variable for dvz/dz (internal).
  • m_txxx: CPML memory variable for dsxx/dx (internal).
  • m_txxz: Reserved elastic auxiliary field (internal).
  • m_tzzx: Reserved elastic auxiliary field (internal).
  • m_tzzz: CPML memory variable for dszz/dz (internal).
  • m_txzx: CPML memory variable for dsxz/dx (internal).
  • m_txzz: CPML memory variable for dsxz/dz (internal).
  • svx (aliases: scattered_vx): Scattered particle velocity in the x direction; default receiver.
  • svz (aliases: scattered_vz): Scattered particle velocity in the z direction; default receiver.
  • ssxx (aliases: scattered_sxx): Scattered normal stress in the x direction.
  • sszz (aliases: scattered_szz): Scattered normal stress in the z direction.
  • ssxz (aliases: scattered_sxz): Scattered shear stress component.
  • sm_vxx: Scattered-field cPML memory variable for dvx/dx (internal).
  • sm_vxz: Scattered-field cPML memory variable for dvx/dz (internal).
  • sm_vzx: Scattered-field cPML memory variable for dvz/dx (internal).
  • sm_vzz: Scattered-field cPML memory variable for dvz/dz (internal).
  • sm_txxx: Scattered-field cPML memory variable for dsxx/dx (internal).
  • sm_txxz: Scattered-field reserved elastic auxiliary field (internal).
  • sm_tzzx: Scattered-field reserved elastic auxiliary field (internal).
  • sm_tzzz: Scattered-field cPML memory variable for dszz/dz (internal).
  • sm_txzx: Scattered-field cPML memory variable for dsxz/dx (internal).
  • sm_txzz: Scattered-field cPML memory variable for dsxz/dz (internal).

Defaults

  • source_type: ['sxx', 'szz']
  • receiver_type: ['svx', 'svz']
  • pml_type: 'cpmls'

Build the elastic Born equation operator.

Parameters:

  • spatial_order –

    FD accuracy order of the staggered first-derivative operator, as :class:Elastic. Defaults to 4.

  • device –

    Device for the operator's static gradient kernels. Defaults to 'cpu'.

  • backend –

    'torch' or 'jax'. Defaults to 'torch'.

C_NAME class-attribute

C_NAME = 'elastic_born2d'

str(object='') -> str str(bytes_or_buffer[, encoding[, errors]]) -> str

Create a new string object from the given object. If encoding or errors is specified, then the object must expose a data buffer that will be decoded using the given encoding and error handler. Otherwise, returns the result of object.str() (if defined) or repr(object). encoding defaults to sys.getdefaultencoding(). errors defaults to 'strict'.

cuda_layout property

cuda_layout

:class:Elastic's layout with the scattered field added to the forward: bind order [bg vx..sxz][sc vx..sxz][bg 10 memories][sc 10 memories] (csrc/cuda/equations/elastic_born2d/driver_traits.cuh). Everything the backward binds -- adjoint fields, checkpoint snapshots and replay state, boundary strips, last state, history -- is the background's, in Elastic's layout: the backward is elastic2d's.

supports_batched_models class-attribute

supports_batched_models = True

bool(x) -> bool

Returns True when the argument x is true, False otherwise. The builtins True and False are the only two instances of the class bool. The class bool is a subclass of the class int, and cannot be subclassed.

supports_bs_free_surface class-attribute

supports_bs_free_surface = True

bool(x) -> bool

Returns True when the argument x is true, False otherwise. The builtins True and False are the only two instances of the class bool. The class bool is a subclass of the class int, and cannot be subclassed.

supports_image_topography class-attribute

supports_image_topography = True

bool(x) -> bool

Returns True when the argument x is true, False otherwise. The builtins True and False are the only two instances of the class bool. The class bool is a subclass of the class int, and cannot be subclassed.

supports_image_topography_c class-attribute

supports_image_topography_c = True

bool(x) -> bool

Returns True when the argument x is true, False otherwise. The builtins True and False are the only two instances of the class bool. The class bool is a subclass of the class int, and cannot be subclassed.

supports_per_edge_free_surface class-attribute

supports_per_edge_free_surface = True

bool(x) -> bool

Returns True when the argument x is true, False otherwise. The builtins True and False are the only two instances of the class bool. The class bool is a subclass of the class int, and cannot be subclassed.

supports_per_edge_free_surface_c class-attribute

supports_per_edge_free_surface_c = True

bool(x) -> bool

Returns True when the argument x is true, False otherwise. The builtins True and False are the only two instances of the class bool. The class bool is a subclass of the class int, and cannot be subclassed.

c_refuse_grads

c_refuse_grads(
    wavelet_grad,
    model_grad_mask,
    boundary_saving=False,
    boundary_dtype=None,
    checkpoint=False,
)

impl='c' returns the (dvp, dvs, drho) gradients only.

interior_substeps

interior_substeps()

The two half-steps of :meth:func (background and scattered together) with pml zeroed and the free-surface BC kept, for the eager boundary-saving reverse driver: composed in reverse order at -dt they invert the step exactly.

Gradients

gradient of impl='eager' impl='c'
dvp, dvs, drho (elastic LSRTM) autograd every memory mode (Full, BoundarySaving, Ckpt)
vp, vs, rho (reflection waveform inversion) autograd refused
wavelet autograd refused

On impl='c' the backward is the Elastic one: the adjoint of the scattered field obeys the background elastic equation, and its imaging condition against the background field is exactly the gradient of the perturbation. A background receiver (vx, ..., recorded next to the scattered svx, ...) does not depend on the perturbation, so its residual adds nothing to these gradients.

from sweep.equations import ElasticBorn
from sweep.propagator.torch import PropTorch

eq = ElasticBorn(spatial_order=4, device="cuda")
prop = PropTorch(eq, shape=(nz, nx), dh=dh, dt=dt, abcn=40, free_surface=True)
dvp, dvs, drho = (torch.zeros_like(vp).requires_grad_() for _ in range(3))
d_sc = prop(wavelet, sources, receivers, models=[vp, vs, rho, dvp, dvs, drho])
loss = ((d_sc - d_obs) ** 2).sum()
loss.backward()   # dvp.grad, dvs.grad, drho.grad