Acoustic propagator reference

The variable-density acoustic propagators – acoustic, acoustic_born, viscoacoustic and acoustic_vti – in both their Module class and functional forms. Usage covers the conventions they share with every other propagator, and Acoustic Wave Equation, Born Modelling with the Variable-Density Acoustic Wave Equation, Viscoacoustic (attenuating) wave equation and Pseudo-acoustic VTI wave equation cover the physics.

Acoustic Class

class deepwave.Acoustic(v: Tensor, rho: Tensor, grid_spacing: float | Sequence[float], *, requires_grad: bool | Sequence[str] | None = None, v_requires_grad: bool | None = None, rho_requires_grad: bool | None = None, storage: str | Storage | None = None, storage_mode: Literal['device', 'cpu', 'disk', 'none'] | None = None, storage_path: str | PathLike[str] | None = None, storage_compression: bool | None = None)

Convenience nn.Module wrapper for acoustic wave propagation.

Stability: stable (see Stability policy).

Stores v, rho and grid_spacing once, so that each forward() call needs only the arguments that vary between calls.

Deepwave orders spatial dimensions from slowest-varying to fastest-varying and attaches no physical meaning to any of them; the component suffixes count from the fastest axis, so a 2-D run uses _y and _x and a 3-D run uses _z, _y and _x. See Dimension order and the axis convention.

Parameters:
  • v – The wavespeed model, of shape [*model_shape] or, for a batched model, [n_shots, *model_shape], where model_shape has ndim entries. See Batched models.

  • rho – The density model, of shape [*model_shape] or, for a batched model, [n_shots, *model_shape], where model_shape has ndim entries. See Batched models.

  • grid_spacing – The spatial grid cell size. It can be a single number that will be used for all dimensions, or a number for each dimension.

  • requires_grad – Which of this module’s models require a gradient. None (the default) defers entirely to the individual <model>_requires_grad flags below, each of which is unset (None) by default and then means False. True selects every model this module owns, False selects none, and a sequence of model names selects exactly those. Passing it together with an individual flag that was given explicitly raises ValueError rather than letting one silently win – whichever way the two point, and even when they agree, so that there is one rule rather than a direction-dependent one.

  • v_requires_grad – A bool specifying whether gradients will be computed for v. Unset by default, which means False. Cannot be combined with requires_grad.

  • rho_requires_grad – A bool specifying whether gradients will be computed for rho. Unset by default, which means False. Cannot be combined with requires_grad.

  • storage – The storage policy for the wavefield history that the model gradient is computed from, as one object: either a mode string (“device”, “cpu”, “disk” or “none”) or a deepwave.Storage, which also carries the path and the lossy-compression flag. Defaults to “device”. This is an alternative spelling for the four individual storage_* arguments below, which remain permanently supported and are not deprecated; passing storage together with any of them raises DeepwaveValueError, because there is no honest way to merge two policies.

  • storage_mode – A string specifying the storage mode for intermediate data. One of “device”, “cpu”, “disk”, or “none”. Defaults to “device”. A permanent alias for Storage.mode; not deprecated.

  • storage_path – The directory that storage_mode=”disk” writes to. A string or any os.PathLike (such as a pathlib.Path). Defaults to the system temporary directory, resolved when you call rather than when Deepwave is imported, so TMPDIR set at any point before the call is honoured. Using the default with storage_mode=”disk” emits a one-time warning naming the directory, because on many systems it is a RAM-backed tmpfs far smaller than the disk. A permanent alias for Storage.path; not deprecated.

  • storage_compression – Lossy – changes the model gradient by about 0.2-4% in 2-D and 0.2-8% in 3-D. See deepwave.elastic().

Model ownership and gradients

Every model tensor given to the constructor is wrapped in a new torch.nn.Parameter that this module owns. The Parameter is a distinct leaf tensor that shares storage with the tensor you passed in: it is not a copy, so an in-place edit of one is visible in the other, but it is not the same object. Gradients therefore accumulate on the module’s own attribute (module.<model>.grad) and never on the tensor you passed in. A model requires a gradient only if you ask for one, through the constructor’s requires_grad argument or by calling module.<model>.requires_grad_(True) afterwards; hand module.parameters() to a torch.optim optimiser as usual. An optional model left as None is not a Parameter at all, so it appears in neither parameters() nor state_dict(); assigning a tensor to that attribute later stores a plain tensor rather than registering a Parameter, so it stays out of parameters() and state_dict() (and out of any checkpoint) – give the model to the constructor, or wrap it yourself in torch.nn.Parameter. Because the module owns a leaf Parameter, it cannot carry an upstream autograd graph: if the model is itself produced by another operation – a network mapping a latent vector to a wavespeed, a reparameterisation, a smoothing filter – wrapping it in a module severs that graph and no gradient reaches the producer. Use the functional interface for anything graph-producing; it takes the model as an ordinary tensor argument and backpropagates through it.

Initialises the Module.

forward(dt: float, *, sources: Mapping[str, tuple[Tensor, Tensor | Hicks] | tuple[Tensor, Tensor | Hicks, Tensor | None]] | None = None, receivers: Mapping[str, Tensor | Hicks | tuple[Tensor | Hicks, Tensor | None]] | None = None, source_amplitudes_volume_rate: Tensor | None = None, source_amplitudes_p: Tensor | None = None, source_amplitudes_z: Tensor | None = None, source_amplitudes_y: Tensor | None = None, source_amplitudes_x: Tensor | None = None, source_locations_volume_rate: Tensor | Hicks | None = None, source_locations_p: Tensor | Hicks | None = None, source_locations_z: Tensor | Hicks | None = None, source_locations_y: Tensor | Hicks | None = None, source_locations_x: Tensor | Hicks | None = None, source_mask_volume_rate: Tensor | None = None, source_mask_z: Tensor | None = None, source_mask_y: Tensor | None = None, source_mask_x: Tensor | None = None, receiver_locations_p: Tensor | Hicks | None = None, receiver_locations_z: Tensor | Hicks | None = None, receiver_locations_y: Tensor | Hicks | None = None, receiver_locations_x: Tensor | Hicks | None = None, receiver_mask_p: Tensor | None = None, receiver_mask_z: Tensor | None = None, receiver_mask_y: Tensor | None = None, receiver_mask_x: Tensor | None = None, pressure_0: Tensor | None = None, vz_0: Tensor | None = None, vy_0: Tensor | None = None, vx_0: Tensor | None = None, initial_state: PropagatorOutput | Mapping[str, Tensor | AuxiliaryState] | None = None, accuracy: Literal[2, 4, 6, 8] = 4, pml_width: int | Sequence[int] = 20, boundary: str | Sequence[str] | None = None, pml_freq: float | None = None, max_vel: float | None = None, courant_number: float | None = None, survey_pad: int | Sequence[int | None] | None = None, origin: Sequence[int] | None = None, nt: int | None = None, model_gradient_sampling_interval: int = 1, checkpoint_segments: int | None = None, freq_taper_frac: float = 0.0, time_pad_frac: float = 0.0, time_taper: bool = False, check_output_finite: bool = True, forward_callback: Callback | None = None, backward_callback: Callback | None = None, callback_frequency: int = 1, backend: str = 'auto', python_backend: Literal['eager', 'jit', 'compile'] | bool | None = None, storage: str | Storage | None = None, storage_mode: Literal['device', 'cpu', 'disk', 'none'] | None = None, storage_path: str | PathLike[str] | None = None, storage_compression: bool | None = None, location_interpolation: Literal['auto', 'hicks', 'none'] = 'auto', location_interpolation_halfwidth: int = 4) → PropagatorOutput

Perform forward propagation/modelling.

See acoustic() for details (the constructor-owned v/rho/ grid_spacing and the storage settings are supplied from the stored module state).

Parameters:
  • dt – Time step interval. Deepwave is unit-agnostic: choose any single consistent system of units for v, rho, grid_spacing, and dt; see Units and source conventions.

  • sources – This simulation’s sources, keyed by channel. This is the canonical way to specify a survey. Each value is (amplitudes, locations), or (amplitudes, locations, mask) to include an activity mask. The channels are volume_rate, z, y, x (z only in 3-D, y only in 2-D and 3-D); p is a deprecated spelling of volume_rate here. Exactly equivalent to the flat source_amplitudes_*/source_locations_* keywords, which remain permanently supported; giving one channel in both forms raises. Optional.

  • receivers – This simulation’s receivers, keyed by channel, as the canonical alternative to the flat receiver_locations* keywords. Each value is a locations object, or (locations, mask) to include an activity mask. The channels are p, z, y, x (z only in 3-D, y only in 2-D and 3-D). Giving one channel in both forms raises. Optional.

  • source_amplitudes_volume_rate – Source amplitudes s: an injected volume per unit volume per unit time, so units of 1/time. This differs from the elastic family, whose source_amplitudes_pressure_rate is a pressure rate; see Units and source conventions for the conversion. Each sample acts at (t+0.5)*dt, half a step after the pressure receiver of the same index is recorded. To drive the propagation with a volumetric (extended) source instead of hand-placed point sources, build the amplitudes and integer locations with deepwave.wavefields.source_field_to_sources().

  • source_amplitudes_p – Deprecated spelling of source_amplitudes_volume_rate, which means exactly the same thing. It warns deepwave.DeepwaveFutureWarning and will be removed in Deepwave 0.4.0: the letter p names a volume rate here and a pressure rate on the elastic family, two quantities that differ by roughly the bulk modulus, so a source channel says which one it injects; see Units and source conventions. p remains the receiver channel’s name. Passing both raises. Optional.

  • source_locations_volume_rate – Source locations. A point whose coordinates are all deepwave.IGNORE_LOCATION is ignored: it injects nothing. A point with only some coordinates set to the sentinel raises. Compare against deepwave.IGNORE_LOCATION; do not hard-code its value.

  • source_locations_p – Deprecated spelling of source_locations_volume_rate, as source_amplitudes_p is of source_amplitudes_volume_rate. Passing both raises. Optional.

  • source_amplitudes_z – Source amplitudes f_z: a body-force density in the z direction, with units of force/volume in both 2-D and 3-D. Each sample acts at t*dt. This channel exists only in 3-D.

  • source_locations_z – Source locations (z-force). This channel exists only in 3-D. A point whose coordinates are all deepwave.IGNORE_LOCATION is ignored: it injects nothing. A point with only some coordinates set to the sentinel raises. Compare against deepwave.IGNORE_LOCATION; do not hard-code its value.

  • source_amplitudes_y – Source amplitudes (y-force density), as source_amplitudes_z.

  • source_locations_y – Source locations (y-force). A point whose coordinates are all deepwave.IGNORE_LOCATION is ignored: it injects nothing. A point with only some coordinates set to the sentinel raises. Compare against deepwave.IGNORE_LOCATION; do not hard-code its value.

  • source_amplitudes_x – Source amplitudes (x-force density), as source_amplitudes_z.

  • source_locations_x – Source locations (x-force). A point whose coordinates are all deepwave.IGNORE_LOCATION is ignored: it injects nothing. A point with only some coordinates set to the sentinel raises. Compare against deepwave.IGNORE_LOCATION; do not hard-code its value.

  • source_mask_volume_rate – A boolean torch.Tensor with dimensions [shot, source] selecting which sources of the volume_rate channel are active. True means active; False means that point injects nothing, and its coordinates in source_locations_volume_rate are then ignored entirely (they need not be valid, in range, or unique). The shape must match the leading dimensions of source_locations_volume_rate, which must be given. This is the modern spelling of the deepwave.IGNORE_LOCATION sentinel and produces bit-identical results; supplying both a mask and a sentinel-containing locations tensor for the same component raises, as does combining a mask with a deepwave.Hicks object: a Hicks carries its own already-resolved points, so disable points inside it by setting all of their coordinates to deepwave.IGNORE_LOCATION in the locations it was built from. Optional.

  • source_mask_z – A boolean torch.Tensor with dimensions [shot, source] selecting which sources of the z channel (3-D only) are active. True means active; False means that point injects nothing, and its coordinates in source_locations_z are then ignored entirely (they need not be valid, in range, or unique). The shape must match the leading dimensions of source_locations_z, which must be given. This is the modern spelling of the deepwave.IGNORE_LOCATION sentinel and produces bit-identical results; supplying both a mask and a sentinel-containing locations tensor for the same component raises, as does combining a mask with a deepwave.Hicks object: a Hicks carries its own already-resolved points, so disable points inside it by setting all of their coordinates to deepwave.IGNORE_LOCATION in the locations it was built from. Optional.

  • source_mask_y – A boolean torch.Tensor with dimensions [shot, source] selecting which sources of the y channel are active. True means active; False means that point injects nothing, and its coordinates in source_locations_y are then ignored entirely (they need not be valid, in range, or unique). The shape must match the leading dimensions of source_locations_y, which must be given. This is the modern spelling of the deepwave.IGNORE_LOCATION sentinel and produces bit-identical results; supplying both a mask and a sentinel-containing locations tensor for the same component raises, as does combining a mask with a deepwave.Hicks object: a Hicks carries its own already-resolved points, so disable points inside it by setting all of their coordinates to deepwave.IGNORE_LOCATION in the locations it was built from. Optional.

  • source_mask_x – A boolean torch.Tensor with dimensions [shot, source] selecting which sources of the x channel are active. True means active; False means that point injects nothing, and its coordinates in source_locations_x are then ignored entirely (they need not be valid, in range, or unique). The shape must match the leading dimensions of source_locations_x, which must be given. This is the modern spelling of the deepwave.IGNORE_LOCATION sentinel and produces bit-identical results; supplying both a mask and a sentinel-containing locations tensor for the same component raises, as does combining a mask with a deepwave.Hicks object: a Hicks carries its own already-resolved points, so disable points inside it by setting all of their coordinates to deepwave.IGNORE_LOCATION in the locations it was built from. Optional.

  • receiver_locations_p – Pressure receiver locations. A point whose coordinates are all deepwave.IGNORE_LOCATION is ignored: it records zeros. A point with only some coordinates set to the sentinel raises. Compare against deepwave.IGNORE_LOCATION; do not hard-code its value.

  • receiver_locations_z – Z-component velocity receiver locations. This channel exists only in 3-D. A point whose coordinates are all deepwave.IGNORE_LOCATION is ignored: it records zeros. A point with only some coordinates set to the sentinel raises. Compare against deepwave.IGNORE_LOCATION; do not hard-code its value.

  • receiver_locations_y – Y-component velocity receiver locations. A point whose coordinates are all deepwave.IGNORE_LOCATION is ignored: it records zeros. A point with only some coordinates set to the sentinel raises. Compare against deepwave.IGNORE_LOCATION; do not hard-code its value.

  • receiver_locations_x – X-component velocity receiver locations. A point whose coordinates are all deepwave.IGNORE_LOCATION is ignored: it records zeros. A point with only some coordinates set to the sentinel raises. Compare against deepwave.IGNORE_LOCATION; do not hard-code its value.

  • receiver_mask_p – A boolean torch.Tensor with dimensions [shot, receiver] selecting which receivers of the p channel are active. True means active; False means that point records zeros, and its coordinates in receiver_locations_p are then ignored entirely (they need not be valid, in range, or unique). The shape must match the leading dimensions of receiver_locations_p, which must be given. This is the modern spelling of the deepwave.IGNORE_LOCATION sentinel and produces bit-identical results; supplying both a mask and a sentinel-containing locations tensor for the same component raises, as does combining a mask with a deepwave.Hicks object: a Hicks carries its own already-resolved points, so disable points inside it by setting all of their coordinates to deepwave.IGNORE_LOCATION in the locations it was built from. Optional.

  • receiver_mask_z – A boolean torch.Tensor with dimensions [shot, receiver] selecting which receivers of the z channel (3-D only) are active. True means active; False means that point records zeros, and its coordinates in receiver_locations_z are then ignored entirely (they need not be valid, in range, or unique). The shape must match the leading dimensions of receiver_locations_z, which must be given. This is the modern spelling of the deepwave.IGNORE_LOCATION sentinel and produces bit-identical results; supplying both a mask and a sentinel-containing locations tensor for the same component raises, as does combining a mask with a deepwave.Hicks object: a Hicks carries its own already-resolved points, so disable points inside it by setting all of their coordinates to deepwave.IGNORE_LOCATION in the locations it was built from. Optional.

  • receiver_mask_y – A boolean torch.Tensor with dimensions [shot, receiver] selecting which receivers of the y channel are active. True means active; False means that point records zeros, and its coordinates in receiver_locations_y are then ignored entirely (they need not be valid, in range, or unique). The shape must match the leading dimensions of receiver_locations_y, which must be given. This is the modern spelling of the deepwave.IGNORE_LOCATION sentinel and produces bit-identical results; supplying both a mask and a sentinel-containing locations tensor for the same component raises, as does combining a mask with a deepwave.Hicks object: a Hicks carries its own already-resolved points, so disable points inside it by setting all of their coordinates to deepwave.IGNORE_LOCATION in the locations it was built from. Optional.

  • receiver_mask_x – A boolean torch.Tensor with dimensions [shot, receiver] selecting which receivers of the x channel are active. True means active; False means that point records zeros, and its coordinates in receiver_locations_x are then ignored entirely (they need not be valid, in range, or unique). The shape must match the leading dimensions of receiver_locations_x, which must be given. This is the modern spelling of the deepwave.IGNORE_LOCATION sentinel and produces bit-identical results; supplying both a mask and a sentinel-containing locations tensor for the same component raises, as does combining a mask with a deepwave.Hicks object: a Hicks carries its own already-resolved points, so disable points inside it by setting all of their coordinates to deepwave.IGNORE_LOCATION in the locations it was built from. Optional.

  • accuracy – See deepwave.elastic().

  • pml_width – See deepwave.elastic(). Unlike the scalar propagator, whose zero-width edge is a free surface, here (as for any staggered-grid propagator) it is a rigid surface for pressure (reflection coefficient approximately +1). A face whose pml_width is zero does not absorb: it becomes an implicit reflecting boundary whose type depends on the propagator and the field component. See Reflecting edges for the per-propagator reflection coefficient and surface location, and prefer naming the condition with boundary (or deepwave.boundaries()), which also uses the exact image rather than this approximate one.

  • boundary – An optional single string, applying to every face, or a list of 2 * ndim strings selecting a first-class boundary condition per face, in the same order as pml_width. Each entry is one of “pml” (absorbing, using pml_width; boundary=”pml” is the spelled-out default, and behaves in every respect – including the warnings it emits – as omitting boundary does), “free” (a pressure-release surface: pressure is held to zero on the surface and reflects with inverted polarity, reflection coefficient -1), “rigid” (a rigid wall: the boundary-normal velocity is held to zero and pressure reflects with preserved polarity, +1), or “periodic” (the face wraps around to the opposite face). A “free”, “rigid”, or “periodic” face requires pml_width to be zero on that face, and “periodic” must be set on both faces of a dimension. Unlike a bare zero-pml_width face (an approximate reflector at accuracy above 2), a “free”/”rigid” face refills the guard ring with the exact staggered image every step, so the reflection coefficient is met to better than 1% at all accuracy orders. Supported in both the compiled and the pure-PyTorch (backend=”eager”) backends, which agree to machine precision in the forward fields and the gradients. See the boundary-conditions documentation for the ghost-plane conventions. Availability: “pml” and “rigid” are accepted on every face at every accuracy, and “free” on the beginning of a dimension at every accuracy and on the end of a dimension at accuracy=2. “free” on the end of a dimension with accuracy >= 4, and “periodic” on any face, raise deepwave.DeepwaveNotImplementedError: those guard-ring fills do not conserve a discrete energy, so the solution can grow without bound. Put such a face at the beginning of the dimension instead (flip the model along that axis), or use accuracy=2. Faces may be accepted in a later release; none is removed.

  • pml_freq – See deepwave.elastic().

  • max_vel – See deepwave.elastic().

  • courant_number – See deepwave.elastic(), which documents the staggered-grid critical Courant number used here.

  • survey_pad – See deepwave.scalar().

  • pressure_0 – Initial pressure (time t=0). Like every initial wavefield, it may be provided either at the shape of the simulation domain (the extracted model region plus the PML), which is the shape a previous call returns, or at the shape of the extracted model region itself, which Deepwave zero-pads for you; see the wavefield_0 entry of deepwave.scalar().

  • vz_0 – Initial z-velocity (time t=-0.5).

  • vy_0 – Initial y-velocity (time t=-0.5).

  • vx_0 – Initial x-velocity (time t=-0.5).

  • initial_state – See deepwave.elastic(). The mapping keys are this propagator’s own public state field names (pressure_0, vz_0, …) and auxiliary_state. The individual absorbing-boundary field names (phi_z_0, …, psi_x_0) are still accepted as keys, with a FutureWarning; they will stop being accepted in Deepwave 0.4.0.

  • origin – See deepwave.scalar().

  • nt – See deepwave.elastic().

  • model_gradient_sampling_interval – See deepwave.elastic().

  • checkpoint_segments –

    If given, split the time axis into this many segments and run each of them under torch.utils.checkpoint, which is the memory lever for a run whose wavefield history does not fit: peak backward memory falls to roughly one segment’s history plus the states held at the segment boundaries, at the cost of running the forward pass of each segment a second time during the backward pass. None (the default) runs the whole time axis in one piece, exactly as before. It is the same thing as calling deepwave.checkpointing.run_segments() with n_segments= and checkpoint=True, and returns the same combined output – the same fields, the same info and the same auxiliary_state a direct call gives. initial_state, the storage arguments and every physics option are supported; nt may pad or truncate supplied source amplitudes for the whole run. Source-free nt calls, individual initial-wavefield arguments and per-step callbacks are not supported, and say so.

    Take the gradient with loss.backward(). The checkpointing is reentrant, and torch.utils.checkpoint does not support torch.autograd.grad() (or an inputs= argument to .backward()) in that mode: it raises. If you need torch.autograd.grad, call deepwave.checkpointing.run_segments() directly with use_reentrant=False.

  • freq_taper_frac – See deepwave.elastic().

  • time_pad_frac – See deepwave.elastic().

  • time_taper – See deepwave.elastic().

  • check_output_finite – See deepwave.elastic().

  • forward_callback – See deepwave.elastic().

  • backward_callback – See deepwave.elastic().

  • callback_frequency – See deepwave.elastic().

  • backend – Which execution backend to use: "auto" (the default), "compiled", "eager" or "torch_compile". See Backends for what each value selects, what "auto" resolves to, and how the backends agree numerically. "auto" resolves to the compiled C/CUDA kernel.

  • python_backend – See deepwave.scalar().

  • storage – The storage policy for the wavefield history that the model gradient is computed from, as one object: either a mode string (“device”, “cpu”, “disk” or “none”) or a deepwave.Storage, which also carries the path and the lossy-compression flag. Defaults to “device”. This is an alternative spelling for the four individual storage_* arguments below, which remain permanently supported and are not deprecated; passing storage together with any of them raises DeepwaveValueError, because there is no honest way to merge two policies.

  • storage_mode – A string specifying the storage mode for intermediate data. One of “device”, “cpu”, “disk”, or “none”. Defaults to “device”. A permanent alias for Storage.mode; not deprecated.

  • storage_path – The directory that storage_mode=”disk” writes to. A string or any os.PathLike (such as a pathlib.Path). Defaults to the system temporary directory, resolved when you call rather than when Deepwave is imported, so TMPDIR set at any point before the call is honoured. Using the default with storage_mode=”disk” emits a one-time warning naming the directory, because on many systems it is a RAM-backed tmpfs far smaller than the disk. A permanent alias for Storage.path; not deprecated.

  • storage_compression – Lossy – changes the model gradient by about 0.2-4% in 2-D and 0.2-8% in 3-D. See deepwave.elastic().

  • location_interpolation – See deepwave.elastic(). This propagator has a single pressure node and one velocity component per axis (no stress tensor), but the same staggered-grid N + 0.5 convention applies. "auto" interpolates a floating-point locations Tensor only when at least one non-ignored coordinate lies more than deepwave.ON_NODE_TOLERANCE cells off its component’s grid node – except that a floating-point Tensor with requires_grad=True is always interpolated, even when every coordinate is on-node, because only the interpolated path carries gradients back to the positions. That changes the forward values for an on-node requires_grad locations Tensor relative to the same Tensor without requires_grad. Pass location_interpolation="none" for the exact path (positions are then not differentiable), or accept the band-limited values. RunInfo.location_interpolation_used records which path was taken: "none" or "hicks", or "mixed" if this propagator has several channels of one kind (several source components, say) and they did not all take the same path.

  • location_interpolation_halfwidth – See deepwave.elastic().

Acoustic Function

deepwave.acoustic(v: Tensor, rho: Tensor, grid_spacing: float | Sequence[float], dt: float, *, sources: Mapping[str, tuple[Tensor, Tensor | Hicks] | tuple[Tensor, Tensor | Hicks, Tensor | None]] | None = None, receivers: Mapping[str, Tensor | Hicks | tuple[Tensor | Hicks, Tensor | None]] | None = None, source_amplitudes_volume_rate: Tensor | None = None, source_amplitudes_p: Tensor | None = None, source_amplitudes_z: Tensor | None = None, source_amplitudes_y: Tensor | None = None, source_amplitudes_x: Tensor | None = None, source_locations_volume_rate: Tensor | Hicks | None = None, source_locations_p: Tensor | Hicks | None = None, source_locations_z: Tensor | Hicks | None = None, source_locations_y: Tensor | Hicks | None = None, source_locations_x: Tensor | Hicks | None = None, source_mask_volume_rate: Tensor | None = None, source_mask_z: Tensor | None = None, source_mask_y: Tensor | None = None, source_mask_x: Tensor | None = None, receiver_locations_p: Tensor | Hicks | None = None, receiver_locations_z: Tensor | Hicks | None = None, receiver_locations_y: Tensor | Hicks | None = None, receiver_locations_x: Tensor | Hicks | None = None, receiver_mask_p: Tensor | None = None, receiver_mask_z: Tensor | None = None, receiver_mask_y: Tensor | None = None, receiver_mask_x: Tensor | None = None, pressure_0: Tensor | None = None, vz_0: Tensor | None = None, vy_0: Tensor | None = None, vx_0: Tensor | None = None, initial_state: PropagatorOutput | Mapping[str, Tensor | AuxiliaryState] | None = None, accuracy: Literal[2, 4, 6, 8] = 4, pml_width: int | Sequence[int] = 20, boundary: str | Sequence[str] | None = None, pml_freq: float | None = None, max_vel: float | None = None, courant_number: float | None = None, survey_pad: int | Sequence[int | None] | None = None, origin: Sequence[int] | None = None, nt: int | None = None, model_gradient_sampling_interval: int = 1, checkpoint_segments: int | None = None, freq_taper_frac: float = 0.0, time_pad_frac: float = 0.0, time_taper: bool = False, check_output_finite: bool = True, forward_callback: Callback | None = None, backward_callback: Callback | None = None, callback_frequency: int = 1, backend: str = 'auto', python_backend: Literal['eager', 'jit', 'compile'] | bool | None = None, storage: str | Storage | None = None, storage_mode: Literal['device', 'cpu', 'disk', 'none'] | None = None, storage_path: str | PathLike[str] | None = None, storage_compression: bool | None = None, location_interpolation: Literal['auto', 'hicks', 'none'] = 'auto', location_interpolation_halfwidth: int = 4) → PropagatorOutput

Acoustic wave propagation (functional interface).

Stability: stable (see Stability policy).

This function performs forward modelling with the variable-density acoustic wave equation on a staggered grid.

Deepwave orders spatial dimensions from slowest-varying to fastest-varying and attaches no physical meaning to any of them; the component suffixes count from the fastest axis, so a 2-D run uses _y and _x and a 3-D run uses _z, _y and _x. See Dimension order and the axis convention.

Parameters:
  • v – The wavespeed model, of shape [*model_shape] or, for a batched model, [n_shots, *model_shape], where model_shape has ndim entries. See Batched models.

  • rho – The density model, of shape [*model_shape] or, for a batched model, [n_shots, *model_shape], where model_shape has ndim entries. See Batched models.

  • grid_spacing – Spatial grid cell size.

  • dt – Time step interval. Deepwave is unit-agnostic: choose any single consistent system of units for v, rho, grid_spacing, and dt; see Units and source conventions.

  • sources – This simulation’s sources, keyed by channel. This is the canonical way to specify a survey. Each value is (amplitudes, locations), or (amplitudes, locations, mask) to include an activity mask. The channels are volume_rate, z, y, x (z only in 3-D, y only in 2-D and 3-D); p is a deprecated spelling of volume_rate here. Exactly equivalent to the flat source_amplitudes_*/source_locations_* keywords, which remain permanently supported; giving one channel in both forms raises. Optional.

  • receivers – This simulation’s receivers, keyed by channel, as the canonical alternative to the flat receiver_locations* keywords. Each value is a locations object, or (locations, mask) to include an activity mask. The channels are p, z, y, x (z only in 3-D, y only in 2-D and 3-D). Giving one channel in both forms raises. Optional.

  • source_amplitudes_volume_rate – Source amplitudes s: an injected volume per unit volume per unit time, so units of 1/time. This differs from the elastic family, whose source_amplitudes_pressure_rate is a pressure rate; see Units and source conventions for the conversion. Each sample acts at (t+0.5)*dt, half a step after the pressure receiver of the same index is recorded. To drive the propagation with a volumetric (extended) source instead of hand-placed point sources, build the amplitudes and integer locations with deepwave.wavefields.source_field_to_sources().

  • source_amplitudes_p – Deprecated spelling of source_amplitudes_volume_rate, which means exactly the same thing. It warns deepwave.DeepwaveFutureWarning and will be removed in Deepwave 0.4.0: the letter p names a volume rate here and a pressure rate on the elastic family, two quantities that differ by roughly the bulk modulus, so a source channel says which one it injects; see Units and source conventions. p remains the receiver channel’s name. Passing both raises. Optional.

  • source_locations_volume_rate – Source locations. A point whose coordinates are all deepwave.IGNORE_LOCATION is ignored: it injects nothing. A point with only some coordinates set to the sentinel raises. Compare against deepwave.IGNORE_LOCATION; do not hard-code its value.

  • source_locations_p – Deprecated spelling of source_locations_volume_rate, as source_amplitudes_p is of source_amplitudes_volume_rate. Passing both raises. Optional.

  • source_amplitudes_z – Source amplitudes f_z: a body-force density in the z direction, with units of force/volume in both 2-D and 3-D. Each sample acts at t*dt. This channel exists only in 3-D.

  • source_locations_z – Source locations (z-force). This channel exists only in 3-D. A point whose coordinates are all deepwave.IGNORE_LOCATION is ignored: it injects nothing. A point with only some coordinates set to the sentinel raises. Compare against deepwave.IGNORE_LOCATION; do not hard-code its value.

  • source_amplitudes_y – Source amplitudes (y-force density), as source_amplitudes_z.

  • source_locations_y – Source locations (y-force). A point whose coordinates are all deepwave.IGNORE_LOCATION is ignored: it injects nothing. A point with only some coordinates set to the sentinel raises. Compare against deepwave.IGNORE_LOCATION; do not hard-code its value.

  • source_amplitudes_x – Source amplitudes (x-force density), as source_amplitudes_z.

  • source_locations_x – Source locations (x-force). A point whose coordinates are all deepwave.IGNORE_LOCATION is ignored: it injects nothing. A point with only some coordinates set to the sentinel raises. Compare against deepwave.IGNORE_LOCATION; do not hard-code its value.

  • source_mask_volume_rate – A boolean torch.Tensor with dimensions [shot, source] selecting which sources of the volume_rate channel are active. True means active; False means that point injects nothing, and its coordinates in source_locations_volume_rate are then ignored entirely (they need not be valid, in range, or unique). The shape must match the leading dimensions of source_locations_volume_rate, which must be given. This is the modern spelling of the deepwave.IGNORE_LOCATION sentinel and produces bit-identical results; supplying both a mask and a sentinel-containing locations tensor for the same component raises, as does combining a mask with a deepwave.Hicks object: a Hicks carries its own already-resolved points, so disable points inside it by setting all of their coordinates to deepwave.IGNORE_LOCATION in the locations it was built from. Optional.

  • source_mask_z – A boolean torch.Tensor with dimensions [shot, source] selecting which sources of the z channel (3-D only) are active. True means active; False means that point injects nothing, and its coordinates in source_locations_z are then ignored entirely (they need not be valid, in range, or unique). The shape must match the leading dimensions of source_locations_z, which must be given. This is the modern spelling of the deepwave.IGNORE_LOCATION sentinel and produces bit-identical results; supplying both a mask and a sentinel-containing locations tensor for the same component raises, as does combining a mask with a deepwave.Hicks object: a Hicks carries its own already-resolved points, so disable points inside it by setting all of their coordinates to deepwave.IGNORE_LOCATION in the locations it was built from. Optional.

  • source_mask_y – A boolean torch.Tensor with dimensions [shot, source] selecting which sources of the y channel are active. True means active; False means that point injects nothing, and its coordinates in source_locations_y are then ignored entirely (they need not be valid, in range, or unique). The shape must match the leading dimensions of source_locations_y, which must be given. This is the modern spelling of the deepwave.IGNORE_LOCATION sentinel and produces bit-identical results; supplying both a mask and a sentinel-containing locations tensor for the same component raises, as does combining a mask with a deepwave.Hicks object: a Hicks carries its own already-resolved points, so disable points inside it by setting all of their coordinates to deepwave.IGNORE_LOCATION in the locations it was built from. Optional.

  • source_mask_x – A boolean torch.Tensor with dimensions [shot, source] selecting which sources of the x channel are active. True means active; False means that point injects nothing, and its coordinates in source_locations_x are then ignored entirely (they need not be valid, in range, or unique). The shape must match the leading dimensions of source_locations_x, which must be given. This is the modern spelling of the deepwave.IGNORE_LOCATION sentinel and produces bit-identical results; supplying both a mask and a sentinel-containing locations tensor for the same component raises, as does combining a mask with a deepwave.Hicks object: a Hicks carries its own already-resolved points, so disable points inside it by setting all of their coordinates to deepwave.IGNORE_LOCATION in the locations it was built from. Optional.

  • receiver_locations_p – Pressure receiver locations. A point whose coordinates are all deepwave.IGNORE_LOCATION is ignored: it records zeros. A point with only some coordinates set to the sentinel raises. Compare against deepwave.IGNORE_LOCATION; do not hard-code its value.

  • receiver_locations_z – Z-component velocity receiver locations. This channel exists only in 3-D. A point whose coordinates are all deepwave.IGNORE_LOCATION is ignored: it records zeros. A point with only some coordinates set to the sentinel raises. Compare against deepwave.IGNORE_LOCATION; do not hard-code its value.

  • receiver_locations_y – Y-component velocity receiver locations. A point whose coordinates are all deepwave.IGNORE_LOCATION is ignored: it records zeros. A point with only some coordinates set to the sentinel raises. Compare against deepwave.IGNORE_LOCATION; do not hard-code its value.

  • receiver_locations_x – X-component velocity receiver locations. A point whose coordinates are all deepwave.IGNORE_LOCATION is ignored: it records zeros. A point with only some coordinates set to the sentinel raises. Compare against deepwave.IGNORE_LOCATION; do not hard-code its value.

  • receiver_mask_p – A boolean torch.Tensor with dimensions [shot, receiver] selecting which receivers of the p channel are active. True means active; False means that point records zeros, and its coordinates in receiver_locations_p are then ignored entirely (they need not be valid, in range, or unique). The shape must match the leading dimensions of receiver_locations_p, which must be given. This is the modern spelling of the deepwave.IGNORE_LOCATION sentinel and produces bit-identical results; supplying both a mask and a sentinel-containing locations tensor for the same component raises, as does combining a mask with a deepwave.Hicks object: a Hicks carries its own already-resolved points, so disable points inside it by setting all of their coordinates to deepwave.IGNORE_LOCATION in the locations it was built from. Optional.

  • receiver_mask_z – A boolean torch.Tensor with dimensions [shot, receiver] selecting which receivers of the z channel (3-D only) are active. True means active; False means that point records zeros, and its coordinates in receiver_locations_z are then ignored entirely (they need not be valid, in range, or unique). The shape must match the leading dimensions of receiver_locations_z, which must be given. This is the modern spelling of the deepwave.IGNORE_LOCATION sentinel and produces bit-identical results; supplying both a mask and a sentinel-containing locations tensor for the same component raises, as does combining a mask with a deepwave.Hicks object: a Hicks carries its own already-resolved points, so disable points inside it by setting all of their coordinates to deepwave.IGNORE_LOCATION in the locations it was built from. Optional.

  • receiver_mask_y – A boolean torch.Tensor with dimensions [shot, receiver] selecting which receivers of the y channel are active. True means active; False means that point records zeros, and its coordinates in receiver_locations_y are then ignored entirely (they need not be valid, in range, or unique). The shape must match the leading dimensions of receiver_locations_y, which must be given. This is the modern spelling of the deepwave.IGNORE_LOCATION sentinel and produces bit-identical results; supplying both a mask and a sentinel-containing locations tensor for the same component raises, as does combining a mask with a deepwave.Hicks object: a Hicks carries its own already-resolved points, so disable points inside it by setting all of their coordinates to deepwave.IGNORE_LOCATION in the locations it was built from. Optional.

  • receiver_mask_x – A boolean torch.Tensor with dimensions [shot, receiver] selecting which receivers of the x channel are active. True means active; False means that point records zeros, and its coordinates in receiver_locations_x are then ignored entirely (they need not be valid, in range, or unique). The shape must match the leading dimensions of receiver_locations_x, which must be given. This is the modern spelling of the deepwave.IGNORE_LOCATION sentinel and produces bit-identical results; supplying both a mask and a sentinel-containing locations tensor for the same component raises, as does combining a mask with a deepwave.Hicks object: a Hicks carries its own already-resolved points, so disable points inside it by setting all of their coordinates to deepwave.IGNORE_LOCATION in the locations it was built from. Optional.

  • accuracy – See deepwave.elastic().

  • pml_width – See deepwave.elastic(). Unlike the scalar propagator, whose zero-width edge is a free surface, here (as for any staggered-grid propagator) it is a rigid surface for pressure (reflection coefficient approximately +1). A face whose pml_width is zero does not absorb: it becomes an implicit reflecting boundary whose type depends on the propagator and the field component. See Reflecting edges for the per-propagator reflection coefficient and surface location, and prefer naming the condition with boundary (or deepwave.boundaries()), which also uses the exact image rather than this approximate one.

  • boundary – An optional single string, applying to every face, or a list of 2 * ndim strings selecting a first-class boundary condition per face, in the same order as pml_width. Each entry is one of “pml” (absorbing, using pml_width; boundary=”pml” is the spelled-out default, and behaves in every respect – including the warnings it emits – as omitting boundary does), “free” (a pressure-release surface: pressure is held to zero on the surface and reflects with inverted polarity, reflection coefficient -1), “rigid” (a rigid wall: the boundary-normal velocity is held to zero and pressure reflects with preserved polarity, +1), or “periodic” (the face wraps around to the opposite face). A “free”, “rigid”, or “periodic” face requires pml_width to be zero on that face, and “periodic” must be set on both faces of a dimension. Unlike a bare zero-pml_width face (an approximate reflector at accuracy above 2), a “free”/”rigid” face refills the guard ring with the exact staggered image every step, so the reflection coefficient is met to better than 1% at all accuracy orders. Supported in both the compiled and the pure-PyTorch (backend=”eager”) backends, which agree to machine precision in the forward fields and the gradients. See the boundary-conditions documentation for the ghost-plane conventions. Availability: “pml” and “rigid” are accepted on every face at every accuracy, and “free” on the beginning of a dimension at every accuracy and on the end of a dimension at accuracy=2. “free” on the end of a dimension with accuracy >= 4, and “periodic” on any face, raise deepwave.DeepwaveNotImplementedError: those guard-ring fills do not conserve a discrete energy, so the solution can grow without bound. Put such a face at the beginning of the dimension instead (flip the model along that axis), or use accuracy=2. Faces may be accepted in a later release; none is removed.

  • pml_freq – See deepwave.elastic().

  • max_vel – See deepwave.elastic().

  • courant_number – See deepwave.elastic(), which documents the staggered-grid critical Courant number used here.

  • survey_pad – See deepwave.scalar().

  • pressure_0 – Initial pressure (time t=0). Like every initial wavefield, it may be provided either at the shape of the simulation domain (the extracted model region plus the PML), which is the shape a previous call returns, or at the shape of the extracted model region itself, which Deepwave zero-pads for you; see the wavefield_0 entry of deepwave.scalar().

  • vz_0 – Initial z-velocity (time t=-0.5).

  • vy_0 – Initial y-velocity (time t=-0.5).

  • vx_0 – Initial x-velocity (time t=-0.5).

  • initial_state – See deepwave.elastic(). The mapping keys are this propagator’s own public state field names (pressure_0, vz_0, …) and auxiliary_state. The individual absorbing-boundary field names (phi_z_0, …, psi_x_0) are still accepted as keys, with a FutureWarning; they will stop being accepted in Deepwave 0.4.0.

  • origin – See deepwave.scalar().

  • nt – See deepwave.elastic().

  • model_gradient_sampling_interval – See deepwave.elastic().

  • checkpoint_segments –

    If given, split the time axis into this many segments and run each of them under torch.utils.checkpoint, which is the memory lever for a run whose wavefield history does not fit: peak backward memory falls to roughly one segment’s history plus the states held at the segment boundaries, at the cost of running the forward pass of each segment a second time during the backward pass. None (the default) runs the whole time axis in one piece, exactly as before. It is the same thing as calling deepwave.checkpointing.run_segments() with n_segments= and checkpoint=True, and returns the same combined output – the same fields, the same info and the same auxiliary_state a direct call gives. initial_state, the storage arguments and every physics option are supported; nt may pad or truncate supplied source amplitudes for the whole run. Source-free nt calls, individual initial-wavefield arguments and per-step callbacks are not supported, and say so.

    Take the gradient with loss.backward(). The checkpointing is reentrant, and torch.utils.checkpoint does not support torch.autograd.grad() (or an inputs= argument to .backward()) in that mode: it raises. If you need torch.autograd.grad, call deepwave.checkpointing.run_segments() directly with use_reentrant=False.

  • freq_taper_frac – See deepwave.elastic().

  • time_pad_frac – See deepwave.elastic().

  • time_taper – See deepwave.elastic().

  • check_output_finite – See deepwave.elastic().

  • forward_callback – See deepwave.elastic().

  • backward_callback – See deepwave.elastic().

  • callback_frequency – See deepwave.elastic().

  • backend – Which execution backend to use: "auto" (the default), "compiled", "eager" or "torch_compile". See Backends for what each value selects, what "auto" resolves to, and how the backends agree numerically. "auto" resolves to the compiled C/CUDA kernel.

  • python_backend – See deepwave.scalar().

  • storage – The storage policy for the wavefield history that the model gradient is computed from, as one object: either a mode string (“device”, “cpu”, “disk” or “none”) or a deepwave.Storage, which also carries the path and the lossy-compression flag. Defaults to “device”. This is an alternative spelling for the four individual storage_* arguments below, which remain permanently supported and are not deprecated; passing storage together with any of them raises DeepwaveValueError, because there is no honest way to merge two policies.

  • storage_mode – A string specifying the storage mode for intermediate data. One of “device”, “cpu”, “disk”, or “none”. Defaults to “device”. A permanent alias for Storage.mode; not deprecated.

  • storage_path – The directory that storage_mode=”disk” writes to. A string or any os.PathLike (such as a pathlib.Path). Defaults to the system temporary directory, resolved when you call rather than when Deepwave is imported, so TMPDIR set at any point before the call is honoured. Using the default with storage_mode=”disk” emits a one-time warning naming the directory, because on many systems it is a RAM-backed tmpfs far smaller than the disk. A permanent alias for Storage.path; not deprecated.

  • storage_compression – Lossy – changes the model gradient by about 0.2-4% in 2-D and 0.2-8% in 3-D. See deepwave.elastic().

  • location_interpolation – See deepwave.elastic(). This propagator has a single pressure node and one velocity component per axis (no stress tensor), but the same staggered-grid N + 0.5 convention applies. "auto" interpolates a floating-point locations Tensor only when at least one non-ignored coordinate lies more than deepwave.ON_NODE_TOLERANCE cells off its component’s grid node – except that a floating-point Tensor with requires_grad=True is always interpolated, even when every coordinate is on-node, because only the interpolated path carries gradients back to the positions. That changes the forward values for an on-node requires_grad locations Tensor relative to the same Tensor without requires_grad. Pass location_interpolation="none" for the exact path (positions are then not differentiable), or accept the band-limited values. RunInfo.location_interpolation_used records which path was taken: "none" or "hicks", or "mixed" if this propagator has several channels of one kind (several source components, say) and they did not all take the same path.

  • location_interpolation_halfwidth – See deepwave.elastic().

Returns:

a tuple subclass whose fields, in order, are:

  • pressure_0: Final pressure wavefield.

  • vz_0: Final z-velocity wavefield (if ndim == 3).

  • vy_0: Final y-velocity wavefield (if ndim >= 2).

  • vx_0: Final x-velocity wavefield.

  • auxiliary_state: A deepwave.AuxiliaryState holding the absorbing boundary’s memory variables. Opaque: pass it back (as part of initial_state) to continue the simulation; its contents are implementation state rather than physics.

  • receiver_amplitudes_p: Recorded pressure data.

  • receiver_amplitudes_z: Recorded z-velocity data (if ndim == 3).

  • receiver_amplitudes_y: Recorded y-velocity data (if ndim >= 2).

  • receiver_amplitudes_x: Recorded x-velocity data.

This positional order is easy to index incorrectly (out[-1] is the x-component velocity receiver amplitudes, not the pressure data); prefer accessing the fields by name instead.

Return type:

deepwave.PropagatorOutput

AcousticBorn Class

Born (linearised) modelling for the variable-density acoustic wave equation. It propagates a background field through v/rho and, alongside it, the scattered field: the exact first-order linearisation of the response to the model perturbations dv/drho. This is the basis of LSRTM and the linear map differentiated in FWI. The scattered receiver data is linear in that (dv, drho) scattering. See Born Modelling with the Variable-Density Acoustic Wave Equation for the physics (and Born Modelling with the Scalar Wave Equation for the background theory of Born modelling in general) and Derivation: variable-density acoustic Born (linearised) propagator for this propagator’s discrete derivation and its adjoint. The compiled backend – what backend="auto" (the default) resolves to here – supports forward_callback/backward_callback/callback_frequency and the storage_mode options; backend="eager" selects a pure-PyTorch coupled Born driver that runs under native autograd and composes with torch.func transforms (see the backend argument below).

class deepwave.AcousticBorn(v: Tensor, rho: Tensor, grid_spacing: float | Sequence[float], *, dv: Tensor | None = None, drho: Tensor | None = None, requires_grad: bool | Sequence[str] | None = None, v_requires_grad: bool | None = None, rho_requires_grad: bool | None = None, dv_requires_grad: bool | None = None, drho_requires_grad: bool | None = None, storage: str | Storage | None = None, storage_mode: Literal['device', 'cpu', 'disk', 'none'] | None = None, storage_path: str | PathLike[str] | None = None, storage_compression: bool | None = None)

A Module wrapper around acoustic_born().

Stability: experimental (see Stability policy).

Stores v, rho, grid_spacing (and, if desired, dv/drho) once, so that each forward() call needs only the arguments that vary between calls. As in the functional acoustic_born(), at least one of dv/drho must be provided (the other defaults to None, treated as a zero perturbation); the module defers this validation to acoustic_born() itself, which is called on every forward().

Deepwave orders spatial dimensions from slowest-varying to fastest-varying and attaches no physical meaning to any of them; the component suffixes count from the fastest axis, so a 2-D run uses _y and _x and a 3-D run uses _z, _y and _x. See Dimension order and the axis convention.

Parameters:
  • v – The background wavespeed model, of shape [*model_shape] or, for a batched model, [n_shots, *model_shape], where model_shape has ndim entries. See Batched models.

  • rho – The background density model, of shape [*model_shape] or, for a batched model, [n_shots, *model_shape], where model_shape has ndim entries. See Batched models.

  • grid_spacing – The spatial grid cell size. It can be a single number that will be used for all dimensions, or a number for each dimension.

  • dv – The wavespeed perturbation model, of shape [*model_shape] or, for a batched model, [n_shots, *model_shape], where model_shape has ndim entries. See Batched models. At least one of dv/drho must be provided.

  • drho – The density perturbation model, of shape [*model_shape] or, for a batched model, [n_shots, *model_shape], where model_shape has ndim entries. See Batched models. At least one of dv/drho must be provided.

  • requires_grad – Which of this module’s models require a gradient. None (the default) and False select none, True selects every model this module owns, and a sequence of model names selects exactly those. Naming a model this class does not have, or an optional model that was not supplied, raises ValueError. It is an alternative spelling for the <model>_requires_grad flags below, each of which is unset (None) by default and then means False. Passing it together with an individual flag that was given explicitly raises ValueError rather than letting one silently win – whichever way the two point, and even when they agree, so that there is one rule rather than a direction-dependent one.

  • v_requires_grad – A bool specifying whether gradients will be computed for v. Unset by default, which means False. Cannot be combined with requires_grad.

  • rho_requires_grad – A bool specifying whether gradients will be computed for rho. Unset by default, which means False. Cannot be combined with requires_grad.

  • dv_requires_grad – A bool specifying whether gradients will be computed for dv. Unset by default, which means False. Cannot be combined with requires_grad.

  • drho_requires_grad – A bool specifying whether gradients will be computed for drho. Unset by default, which means False. Cannot be combined with requires_grad.

  • storage – The storage policy for the wavefield history that the model gradient is computed from, as one object: either a mode string (“device”, “cpu”, “disk” or “none”) or a deepwave.Storage, which also carries the path and the lossy-compression flag. Defaults to “device”. This is an alternative spelling for the four individual storage_* arguments below, which remain permanently supported and are not deprecated; passing storage together with any of them raises DeepwaveValueError, because there is no honest way to merge two policies.

  • storage_mode – A string specifying the storage mode for intermediate data. One of “device”, “cpu”, “disk”, or “none”. Defaults to “device”. A permanent alias for Storage.mode; not deprecated. Only “device” is permitted with backend=”eager” (the eager backend does not use the engine’s storage manager).

  • storage_path – The directory that storage_mode=”disk” writes to. A string or any os.PathLike (such as a pathlib.Path). Defaults to the system temporary directory, resolved when you call rather than when Deepwave is imported, so TMPDIR set at any point before the call is honoured. Using the default with storage_mode=”disk” emits a one-time warning naming the directory, because on many systems it is a RAM-backed tmpfs far smaller than the disk. A permanent alias for Storage.path; not deprecated.

  • storage_compression – Lossy – changes the model gradient by about 0.2-4% in 2-D and 0.2-8% in 3-D. See deepwave.elastic(). Not supported with backend=”eager”.

Model ownership and gradients

Every model tensor given to the constructor is wrapped in a new torch.nn.Parameter that this module owns. The Parameter is a distinct leaf tensor that shares storage with the tensor you passed in: it is not a copy, so an in-place edit of one is visible in the other, but it is not the same object. Gradients therefore accumulate on the module’s own attribute (module.<model>.grad) and never on the tensor you passed in. A model requires a gradient only if you ask for one, through the constructor’s requires_grad argument or by calling module.<model>.requires_grad_(True) afterwards; hand module.parameters() to a torch.optim optimiser as usual. An optional model left as None is not a Parameter at all, so it appears in neither parameters() nor state_dict(); assigning a tensor to that attribute later stores a plain tensor rather than registering a Parameter, so it stays out of parameters() and state_dict() (and out of any checkpoint) – give the model to the constructor, or wrap it yourself in torch.nn.Parameter. Because the module owns a leaf Parameter, it cannot carry an upstream autograd graph: if the model is itself produced by another operation – a network mapping a latent vector to a wavespeed, a reparameterisation, a smoothing filter – wrapping it in a module severs that graph and no gradient reaches the producer. Use the functional interface for anything graph-producing; it takes the model as an ordinary tensor argument and backpropagates through it.

Initialises the Module.

forward(dt: float, *, sources: Mapping[str, tuple[Tensor, Tensor | Hicks] | tuple[Tensor, Tensor | Hicks, Tensor | None]] | None = None, receivers: Mapping[str, Tensor | Hicks | tuple[Tensor | Hicks, Tensor | None]] | None = None, bg_receivers: Mapping[str, Tensor | Hicks | tuple[Tensor | Hicks, Tensor | None]] | None = None, source_amplitudes_volume_rate: Tensor | None = None, source_amplitudes_z: Tensor | None = None, source_amplitudes_y: Tensor | None = None, source_amplitudes_x: Tensor | None = None, source_locations_volume_rate: Tensor | Hicks | None = None, source_locations_z: Tensor | Hicks | None = None, source_locations_y: Tensor | Hicks | None = None, source_locations_x: Tensor | Hicks | None = None, source_mask_volume_rate: Tensor | None = None, source_mask_z: Tensor | None = None, source_mask_y: Tensor | None = None, source_mask_x: Tensor | None = None, bg_receiver_locations_p: Tensor | Hicks | None = None, bg_receiver_locations_z: Tensor | Hicks | None = None, bg_receiver_locations_y: Tensor | Hicks | None = None, bg_receiver_locations_x: Tensor | Hicks | None = None, bg_receiver_mask_p: Tensor | None = None, bg_receiver_mask_z: Tensor | None = None, bg_receiver_mask_y: Tensor | None = None, bg_receiver_mask_x: Tensor | None = None, sc_receiver_locations_p: Tensor | Hicks | None = None, sc_receiver_locations_z: Tensor | Hicks | None = None, sc_receiver_locations_y: Tensor | Hicks | None = None, sc_receiver_locations_x: Tensor | Hicks | None = None, sc_receiver_mask_p: Tensor | None = None, sc_receiver_mask_z: Tensor | None = None, sc_receiver_mask_y: Tensor | None = None, sc_receiver_mask_x: Tensor | None = None, pressure_0: Tensor | None = None, vz_0: Tensor | None = None, vy_0: Tensor | None = None, vx_0: Tensor | None = None, pressure_sc_0: Tensor | None = None, vz_sc_0: Tensor | None = None, vy_sc_0: Tensor | None = None, vx_sc_0: Tensor | None = None, initial_state: PropagatorOutput | Mapping[str, Tensor | AuxiliaryState] | None = None, accuracy: Literal[2, 4, 6, 8] = 4, pml_width: int | Sequence[int] = 20, boundary: str | Sequence[str] | None = None, pml_freq: float | None = None, max_vel: float | None = None, courant_number: float | None = None, survey_pad: int | Sequence[int | None] | None = None, origin: Sequence[int] | None = None, nt: int | None = None, model_gradient_sampling_interval: int = 1, checkpoint_segments: int | None = None, freq_taper_frac: float = 0.0, time_pad_frac: float = 0.0, time_taper: bool = False, check_output_finite: bool = True, forward_callback: Callback | None = None, backward_callback: Callback | None = None, callback_frequency: int = 1, backend: str = 'auto', storage: str | Storage | None = None, storage_mode: Literal['device', 'cpu', 'disk', 'none'] | None = None, storage_path: str | PathLike[str] | None = None, storage_compression: bool | None = None, location_interpolation: Literal['auto', 'hicks', 'none'] = 'auto', location_interpolation_halfwidth: int = 4) → PropagatorOutput

Perform forward propagation/modelling.

See acoustic_born() for the meaning of every argument (the constructor-owned v/rho/dv/drho/grid_spacing and the storage settings are supplied from the stored module state).

Parameters:
  • dt – Time step interval. See deepwave.acoustic() for the unit-consistency requirement across v/rho/grid_spacing/ dt.

  • sources – This simulation’s sources, keyed by channel. This is the canonical way to specify a survey. Each value is (amplitudes, locations), or (amplitudes, locations, mask) to include an activity mask. The channels are volume_rate, z, y, x (z only in 3-D, y only in 2-D and 3-D); these are equivalent to the flat source_amplitudes_*/source_locations_* keywords, which remain permanently supported; giving one channel in both forms raises. Optional.

  • receivers – This simulation’s receivers, keyed by channel, as the canonical alternative to the flat sc_receiver_locations* keywords. Each value is a locations object, or (locations, mask) to include an activity mask. The channels are p, z, y, x (z only in 3-D, y only in 2-D and 3-D). Giving one channel in both forms raises. Optional.

  • bg_receivers – The receivers that record the background wavefield, keyed by channel, as the canonical alternative to the flat bg_receiver_locations* keywords. Values take the same forms as receivers’. Giving one channel in both forms raises. Optional.

  • source_amplitudes_volume_rate – Source amplitudes (a volume-injection rate per unit volume, with units of 1/time), as in deepwave.acoustic(); see Units and source conventions. To drive the propagation with a volumetric (extended) source instead of hand-placed point sources, build the amplitudes and integer locations with deepwave.wavefields.source_field_to_sources().

  • source_locations_volume_rate – Source locations, as in deepwave.acoustic(). A point whose coordinates are all deepwave.IGNORE_LOCATION is ignored: it injects nothing. A point with only some coordinates set to the sentinel raises. Compare against deepwave.IGNORE_LOCATION; do not hard-code its value.

  • source_amplitudes_z – Source amplitudes (a z-direction body-force density, with units of force/volume), as in deepwave.acoustic(). This channel exists only in 3-D.

  • source_locations_z – Source locations (z-force), as in deepwave.acoustic(). This channel exists only in 3-D. A point whose coordinates are all deepwave.IGNORE_LOCATION is ignored: it injects nothing. A point with only some coordinates set to the sentinel raises. Compare against deepwave.IGNORE_LOCATION; do not hard-code its value.

  • source_amplitudes_y – Source amplitudes (y-force), as in deepwave.acoustic().

  • source_locations_y – Source locations (y-force), as in deepwave.acoustic(). A point whose coordinates are all deepwave.IGNORE_LOCATION is ignored: it injects nothing. A point with only some coordinates set to the sentinel raises. Compare against deepwave.IGNORE_LOCATION; do not hard-code its value.

  • source_amplitudes_x – Source amplitudes (x-force), as in deepwave.acoustic().

  • source_locations_x – Source locations (x-force), as in deepwave.acoustic(). A point whose coordinates are all deepwave.IGNORE_LOCATION is ignored: it injects nothing. A point with only some coordinates set to the sentinel raises. Compare against deepwave.IGNORE_LOCATION; do not hard-code its value.

  • source_mask_volume_rate – A boolean torch.Tensor with dimensions [shot, source] selecting which sources of the volume_rate channel are active. True means active; False means that point injects nothing, and its coordinates in source_locations_volume_rate are then ignored entirely (they need not be valid, in range, or unique). The shape must match the leading dimensions of source_locations_volume_rate, which must be given. This is the modern spelling of the deepwave.IGNORE_LOCATION sentinel and produces bit-identical results; supplying both a mask and a sentinel-containing locations tensor for the same component raises, as does combining a mask with a deepwave.Hicks object: a Hicks carries its own already-resolved points, so disable points inside it by setting all of their coordinates to deepwave.IGNORE_LOCATION in the locations it was built from. Optional.

  • source_mask_z – A boolean torch.Tensor with dimensions [shot, source] selecting which sources of the z channel (3-D only) are active. True means active; False means that point injects nothing, and its coordinates in source_locations_z are then ignored entirely (they need not be valid, in range, or unique). The shape must match the leading dimensions of source_locations_z, which must be given. This is the modern spelling of the deepwave.IGNORE_LOCATION sentinel and produces bit-identical results; supplying both a mask and a sentinel-containing locations tensor for the same component raises, as does combining a mask with a deepwave.Hicks object: a Hicks carries its own already-resolved points, so disable points inside it by setting all of their coordinates to deepwave.IGNORE_LOCATION in the locations it was built from. Optional.

  • source_mask_y – A boolean torch.Tensor with dimensions [shot, source] selecting which sources of the y channel are active. True means active; False means that point injects nothing, and its coordinates in source_locations_y are then ignored entirely (they need not be valid, in range, or unique). The shape must match the leading dimensions of source_locations_y, which must be given. This is the modern spelling of the deepwave.IGNORE_LOCATION sentinel and produces bit-identical results; supplying both a mask and a sentinel-containing locations tensor for the same component raises, as does combining a mask with a deepwave.Hicks object: a Hicks carries its own already-resolved points, so disable points inside it by setting all of their coordinates to deepwave.IGNORE_LOCATION in the locations it was built from. Optional.

  • source_mask_x – A boolean torch.Tensor with dimensions [shot, source] selecting which sources of the x channel are active. True means active; False means that point injects nothing, and its coordinates in source_locations_x are then ignored entirely (they need not be valid, in range, or unique). The shape must match the leading dimensions of source_locations_x, which must be given. This is the modern spelling of the deepwave.IGNORE_LOCATION sentinel and produces bit-identical results; supplying both a mask and a sentinel-containing locations tensor for the same component raises, as does combining a mask with a deepwave.Hicks object: a Hicks carries its own already-resolved points, so disable points inside it by setting all of their coordinates to deepwave.IGNORE_LOCATION in the locations it was built from. Optional.

  • sc_receiver_locations_p – Pressure receiver locations for the scattered receiver amplitudes (the Born data). A point whose coordinates are all deepwave.IGNORE_LOCATION is ignored: it records zeros. A point with only some coordinates set to the sentinel raises. Compare against deepwave.IGNORE_LOCATION; do not hard-code its value.

  • sc_receiver_locations_z – Z-component velocity receiver locations for the scattered receiver amplitudes. This channel exists only in 3-D. A point whose coordinates are all deepwave.IGNORE_LOCATION is ignored: it records zeros. A point with only some coordinates set to the sentinel raises. Compare against deepwave.IGNORE_LOCATION; do not hard-code its value.

  • sc_receiver_locations_y – Y-component velocity receiver locations for the scattered receiver amplitudes. A point whose coordinates are all deepwave.IGNORE_LOCATION is ignored: it records zeros. A point with only some coordinates set to the sentinel raises. Compare against deepwave.IGNORE_LOCATION; do not hard-code its value.

  • sc_receiver_locations_x – X-component velocity receiver locations for the scattered receiver amplitudes. A point whose coordinates are all deepwave.IGNORE_LOCATION is ignored: it records zeros. A point with only some coordinates set to the sentinel raises. Compare against deepwave.IGNORE_LOCATION; do not hard-code its value.

  • sc_receiver_mask_p – A boolean torch.Tensor with dimensions [shot, receiver] selecting which receivers of the p channel are active. True means active; False means that point records zeros, and its coordinates in sc_receiver_locations_p are then ignored entirely (they need not be valid, in range, or unique). The shape must match the leading dimensions of sc_receiver_locations_p, which must be given. This is the modern spelling of the deepwave.IGNORE_LOCATION sentinel and produces bit-identical results; supplying both a mask and a sentinel-containing locations tensor for the same component raises, as does combining a mask with a deepwave.Hicks object: a Hicks carries its own already-resolved points, so disable points inside it by setting all of their coordinates to deepwave.IGNORE_LOCATION in the locations it was built from. Optional.

  • sc_receiver_mask_z – A boolean torch.Tensor with dimensions [shot, receiver] selecting which receivers of the z channel (3-D only) are active. True means active; False means that point records zeros, and its coordinates in sc_receiver_locations_z are then ignored entirely (they need not be valid, in range, or unique). The shape must match the leading dimensions of sc_receiver_locations_z, which must be given. This is the modern spelling of the deepwave.IGNORE_LOCATION sentinel and produces bit-identical results; supplying both a mask and a sentinel-containing locations tensor for the same component raises, as does combining a mask with a deepwave.Hicks object: a Hicks carries its own already-resolved points, so disable points inside it by setting all of their coordinates to deepwave.IGNORE_LOCATION in the locations it was built from. Optional.

  • sc_receiver_mask_y – A boolean torch.Tensor with dimensions [shot, receiver] selecting which receivers of the y channel are active. True means active; False means that point records zeros, and its coordinates in sc_receiver_locations_y are then ignored entirely (they need not be valid, in range, or unique). The shape must match the leading dimensions of sc_receiver_locations_y, which must be given. This is the modern spelling of the deepwave.IGNORE_LOCATION sentinel and produces bit-identical results; supplying both a mask and a sentinel-containing locations tensor for the same component raises, as does combining a mask with a deepwave.Hicks object: a Hicks carries its own already-resolved points, so disable points inside it by setting all of their coordinates to deepwave.IGNORE_LOCATION in the locations it was built from. Optional.

  • sc_receiver_mask_x – A boolean torch.Tensor with dimensions [shot, receiver] selecting which receivers of the x channel are active. True means active; False means that point records zeros, and its coordinates in sc_receiver_locations_x are then ignored entirely (they need not be valid, in range, or unique). The shape must match the leading dimensions of sc_receiver_locations_x, which must be given. This is the modern spelling of the deepwave.IGNORE_LOCATION sentinel and produces bit-identical results; supplying both a mask and a sentinel-containing locations tensor for the same component raises, as does combining a mask with a deepwave.Hicks object: a Hicks carries its own already-resolved points, so disable points inside it by setting all of their coordinates to deepwave.IGNORE_LOCATION in the locations it was built from. Optional.

  • bg_receiver_locations_p – Optional pressure receiver locations for the background receiver amplitudes. A point whose coordinates are all deepwave.IGNORE_LOCATION is ignored: it records zeros. A point with only some coordinates set to the sentinel raises. Compare against deepwave.IGNORE_LOCATION; do not hard-code its value.

  • bg_receiver_locations_z – Optional z-component velocity receiver locations for the background receiver amplitudes. This channel exists only in 3-D. A point whose coordinates are all deepwave.IGNORE_LOCATION is ignored: it records zeros. A point with only some coordinates set to the sentinel raises. Compare against deepwave.IGNORE_LOCATION; do not hard-code its value.

  • bg_receiver_locations_y – Optional y-component velocity receiver locations for the background receiver amplitudes. A point whose coordinates are all deepwave.IGNORE_LOCATION is ignored: it records zeros. A point with only some coordinates set to the sentinel raises. Compare against deepwave.IGNORE_LOCATION; do not hard-code its value.

  • bg_receiver_locations_x – Optional x-component velocity receiver locations for the background receiver amplitudes. A point whose coordinates are all deepwave.IGNORE_LOCATION is ignored: it records zeros. A point with only some coordinates set to the sentinel raises. Compare against deepwave.IGNORE_LOCATION; do not hard-code its value.

  • bg_receiver_mask_p – A boolean torch.Tensor with dimensions [shot, receiver] selecting which receivers of the p channel recording the background wavefield are active. True means active; False means that point records zeros, and its coordinates in bg_receiver_locations_p are then ignored entirely (they need not be valid, in range, or unique). The shape must match the leading dimensions of bg_receiver_locations_p, which must be given. This is the modern spelling of the deepwave.IGNORE_LOCATION sentinel and produces bit-identical results; supplying both a mask and a sentinel-containing locations tensor for the same component raises, as does combining a mask with a deepwave.Hicks object: a Hicks carries its own already-resolved points, so disable points inside it by setting all of their coordinates to deepwave.IGNORE_LOCATION in the locations it was built from. Optional.

  • bg_receiver_mask_z – A boolean torch.Tensor with dimensions [shot, receiver] selecting which receivers of the z channel (3-D only) recording the background wavefield are active. True means active; False means that point records zeros, and its coordinates in bg_receiver_locations_z are then ignored entirely (they need not be valid, in range, or unique). The shape must match the leading dimensions of bg_receiver_locations_z, which must be given. This is the modern spelling of the deepwave.IGNORE_LOCATION sentinel and produces bit-identical results; supplying both a mask and a sentinel-containing locations tensor for the same component raises, as does combining a mask with a deepwave.Hicks object: a Hicks carries its own already-resolved points, so disable points inside it by setting all of their coordinates to deepwave.IGNORE_LOCATION in the locations it was built from. Optional.

  • bg_receiver_mask_y – A boolean torch.Tensor with dimensions [shot, receiver] selecting which receivers of the y channel recording the background wavefield are active. True means active; False means that point records zeros, and its coordinates in bg_receiver_locations_y are then ignored entirely (they need not be valid, in range, or unique). The shape must match the leading dimensions of bg_receiver_locations_y, which must be given. This is the modern spelling of the deepwave.IGNORE_LOCATION sentinel and produces bit-identical results; supplying both a mask and a sentinel-containing locations tensor for the same component raises, as does combining a mask with a deepwave.Hicks object: a Hicks carries its own already-resolved points, so disable points inside it by setting all of their coordinates to deepwave.IGNORE_LOCATION in the locations it was built from. Optional.

  • bg_receiver_mask_x – A boolean torch.Tensor with dimensions [shot, receiver] selecting which receivers of the x channel recording the background wavefield are active. True means active; False means that point records zeros, and its coordinates in bg_receiver_locations_x are then ignored entirely (they need not be valid, in range, or unique). The shape must match the leading dimensions of bg_receiver_locations_x, which must be given. This is the modern spelling of the deepwave.IGNORE_LOCATION sentinel and produces bit-identical results; supplying both a mask and a sentinel-containing locations tensor for the same component raises, as does combining a mask with a deepwave.Hicks object: a Hicks carries its own already-resolved points, so disable points inside it by setting all of their coordinates to deepwave.IGNORE_LOCATION in the locations it was built from. Optional.

  • pressure_0 – Initial background pressure, as in deepwave.acoustic().

  • vz_0 – Initial background z-velocity.

  • vy_0 – Initial background y-velocity.

  • vx_0 – Initial background x-velocity.

  • pressure_sc_0 – Initial scattered pressure.

  • vz_sc_0 – Initial scattered z-velocity.

  • vy_sc_0 – Initial scattered y-velocity.

  • vx_sc_0 – Initial scattered x-velocity.

  • accuracy – See deepwave.elastic().

  • pml_width – See deepwave.elastic(). A face whose pml_width is zero does not absorb: it becomes an implicit reflecting boundary whose type depends on the propagator and the field component. See Reflecting edges for the per-propagator reflection coefficient and surface location, and prefer naming the condition with boundary (or deepwave.boundaries()), which also uses the exact image rather than this approximate one.

  • boundary – An optional single string, applying to every face, or a list of 2 * ndim strings selecting a first-class boundary condition per face, in the same order as pml_width and with the same semantics as deepwave.acoustic()’s boundary (“pml”, “free”, “rigid”, or “periodic”; a non-“pml” face requires pml_width == 0 on that face). Applied independently to the background field (p, v_d) and the scattered field (dp, dv_d): both are an ordinary acoustic staggered-grid field on the same grid (see the module docstring), so the same acoustic per-axis image rule (pressure odd/even, normal velocity even/odd, tangential velocity untouched – see docs/boundaries.rst) applies to each independently, with no new physics beyond what deepwave.acoustic() already validates. Validated on the eager (backend=”eager”) and the default compiled C/CUDA backends; the “torch_compile” Python mode shares the eager guard-fill code path but is not separately validated for boundary=. Availability: “pml” and “rigid” are accepted on every face at every accuracy, and “free” on the beginning of a dimension at every accuracy and on the end of a dimension at accuracy=2. “free” on the end of a dimension with accuracy >= 4, and “periodic” on any face, raise deepwave.DeepwaveNotImplementedError: those guard-ring fills do not conserve a discrete energy, so the solution can grow without bound. Put such a face at the beginning of the dimension instead (flip the model along that axis), or use accuracy=2. Faces may be accepted in a later release; none is removed.

  • pml_freq – See deepwave.elastic().

  • max_vel – See deepwave.elastic().

  • courant_number – See deepwave.elastic().

  • survey_pad – See deepwave.scalar().

  • initial_state – See deepwave.elastic(). The mapping keys are this propagator’s own public state field names – the background names of deepwave.acoustic() (e.g. pressure_0) and the scattered names, which carry sc before the time index (e.g. pressure_sc_0) – plus auxiliary_state. The individual absorbing-boundary field names (phi_z_0, …, psi_x_0 and their scattered counterparts) are not accepted as keys: pass initial_state=out (or initial_state=out.final_state) to carry them across.

  • origin – See deepwave.scalar().

  • nt – See deepwave.elastic().

  • model_gradient_sampling_interval – See deepwave.elastic().

  • checkpoint_segments –

    If given, split the time axis into this many segments and run each of them under torch.utils.checkpoint, which is the memory lever for a run whose wavefield history does not fit: peak backward memory falls to roughly one segment’s history plus the states held at the segment boundaries, at the cost of running the forward pass of each segment a second time during the backward pass. None (the default) runs the whole time axis in one piece, exactly as before. It is the same thing as calling deepwave.checkpointing.run_segments() with n_segments= and checkpoint=True, and returns the same combined output – the same fields, the same info and the same auxiliary_state a direct call gives. initial_state, the storage arguments and every physics option are supported; nt may pad or truncate supplied source amplitudes for the whole run. Source-free nt calls, individual initial-wavefield arguments and per-step callbacks are not supported, and say so.

    Take the gradient with loss.backward(). The checkpointing is reentrant, and torch.utils.checkpoint does not support torch.autograd.grad() (or an inputs= argument to .backward()) in that mode: it raises. If you need torch.autograd.grad, call deepwave.checkpointing.run_segments() directly with use_reentrant=False.

  • freq_taper_frac – See deepwave.elastic().

  • time_pad_frac – See deepwave.elastic().

  • time_taper – See deepwave.elastic().

  • check_output_finite – See deepwave.elastic().

  • forward_callback – See deepwave.elastic(). Supported on both the default compiled backend and the eager backend (backend=”eager”).

  • backward_callback – See deepwave.elastic(). Supported only on the default compiled backend; the eager backend rejects it.

  • callback_frequency – See deepwave.elastic().

  • backend – Which execution backend to use: "auto" (the default), "compiled", "eager" or "torch_compile". See Backends for what each value selects, what "auto" resolves to, and how the backends agree numerically. "auto" resolves to the compiled C/CUDA forward paired with the compiled adjoint kernels, and supports callbacks and the "cpu"/"disk"/"none" storage modes. "eager" and "torch_compile" run the pure-PyTorch coupled Born driver, whose two step functions are compiled in the latter.

  • storage – The storage policy for the wavefield history that the model gradient is computed from, as one object: either a mode string (“device”, “cpu”, “disk” or “none”) or a deepwave.Storage, which also carries the path and the lossy-compression flag. Defaults to “device”. This is an alternative spelling for the four individual storage_* arguments below, which remain permanently supported and are not deprecated; passing storage together with any of them raises DeepwaveValueError, because there is no honest way to merge two policies.

  • storage_mode – A string specifying the storage mode for intermediate data. One of “device”, “cpu”, “disk”, or “none”. Defaults to “device”. A permanent alias for Storage.mode; not deprecated. Only “device” is permitted with backend=”eager” (the eager backend does not use the engine’s storage manager).

  • storage_path – The directory that storage_mode=”disk” writes to. A string or any os.PathLike (such as a pathlib.Path). Defaults to the system temporary directory, resolved when you call rather than when Deepwave is imported, so TMPDIR set at any point before the call is honoured. Using the default with storage_mode=”disk” emits a one-time warning naming the directory, because on many systems it is a RAM-backed tmpfs far smaller than the disk. A permanent alias for Storage.path; not deprecated.

  • storage_compression – Lossy – changes the model gradient by about 0.2-4% in 2-D and 0.2-8% in 3-D. See deepwave.elastic(). Not supported with backend=”eager”.

  • location_interpolation – See deepwave.elastic(). A single source interpolator is built from the shared source locations and its spread applied once, then shared by the background and the (internally derived) scattered source – both drive the same physical locations (see the module docstring’s source-cell paragraph). The background and scattered receivers have independent interpolators. "auto" interpolates a floating-point locations Tensor only when at least one non-ignored coordinate lies more than deepwave.ON_NODE_TOLERANCE cells off its component’s grid node – except that a floating-point Tensor with requires_grad=True is always interpolated, even when every coordinate is on-node, because only the interpolated path carries gradients back to the positions. That changes the forward values for an on-node requires_grad locations Tensor relative to the same Tensor without requires_grad. Pass location_interpolation="none" for the exact path (positions are then not differentiable), or accept the band-limited values. RunInfo.location_interpolation_used records which path was taken: "none" or "hicks", or "mixed" if this propagator has several channels of one kind (several source components, say) and they did not all take the same path.

  • location_interpolation_halfwidth – See deepwave.elastic().

AcousticBorn Function

deepwave.acoustic_born(v: Tensor, rho: Tensor, grid_spacing: float | Sequence[float], dt: float, *, dv: Tensor | None = None, drho: Tensor | None = None, sources: Mapping[str, tuple[Tensor, Tensor | Hicks] | tuple[Tensor, Tensor | Hicks, Tensor | None]] | None = None, receivers: Mapping[str, Tensor | Hicks | tuple[Tensor | Hicks, Tensor | None]] | None = None, bg_receivers: Mapping[str, Tensor | Hicks | tuple[Tensor | Hicks, Tensor | None]] | None = None, source_amplitudes_volume_rate: Tensor | None = None, source_amplitudes_z: Tensor | None = None, source_amplitudes_y: Tensor | None = None, source_amplitudes_x: Tensor | None = None, source_locations_volume_rate: Tensor | Hicks | None = None, source_locations_z: Tensor | Hicks | None = None, source_locations_y: Tensor | Hicks | None = None, source_locations_x: Tensor | Hicks | None = None, source_mask_volume_rate: Tensor | None = None, source_mask_z: Tensor | None = None, source_mask_y: Tensor | None = None, source_mask_x: Tensor | None = None, bg_receiver_locations_p: Tensor | Hicks | None = None, bg_receiver_locations_z: Tensor | Hicks | None = None, bg_receiver_locations_y: Tensor | Hicks | None = None, bg_receiver_locations_x: Tensor | Hicks | None = None, bg_receiver_mask_p: Tensor | None = None, bg_receiver_mask_z: Tensor | None = None, bg_receiver_mask_y: Tensor | None = None, bg_receiver_mask_x: Tensor | None = None, sc_receiver_locations_p: Tensor | Hicks | None = None, sc_receiver_locations_z: Tensor | Hicks | None = None, sc_receiver_locations_y: Tensor | Hicks | None = None, sc_receiver_locations_x: Tensor | Hicks | None = None, sc_receiver_mask_p: Tensor | None = None, sc_receiver_mask_z: Tensor | None = None, sc_receiver_mask_y: Tensor | None = None, sc_receiver_mask_x: Tensor | None = None, pressure_0: Tensor | None = None, vz_0: Tensor | None = None, vy_0: Tensor | None = None, vx_0: Tensor | None = None, pressure_sc_0: Tensor | None = None, vz_sc_0: Tensor | None = None, vy_sc_0: Tensor | None = None, vx_sc_0: Tensor | None = None, initial_state: PropagatorOutput | Mapping[str, Tensor | AuxiliaryState] | None = None, accuracy: Literal[2, 4, 6, 8] = 4, pml_width: int | Sequence[int] = 20, boundary: str | Sequence[str] | None = None, pml_freq: float | None = None, max_vel: float | None = None, courant_number: float | None = None, survey_pad: int | Sequence[int | None] | None = None, origin: Sequence[int] | None = None, nt: int | None = None, model_gradient_sampling_interval: int = 1, checkpoint_segments: int | None = None, freq_taper_frac: float = 0.0, time_pad_frac: float = 0.0, time_taper: bool = False, check_output_finite: bool = True, forward_callback: Callback | None = None, backward_callback: Callback | None = None, callback_frequency: int = 1, backend: str = 'auto', storage: str | Storage | None = None, storage_mode: Literal['device', 'cpu', 'disk', 'none'] | None = None, storage_path: str | PathLike[str] | None = None, storage_compression: bool | None = None, location_interpolation: Literal['auto', 'hicks', 'none'] = 'auto', location_interpolation_halfwidth: int = 4) → PropagatorOutput

Acoustic Born (linearised) wave propagation (functional interface).

Stability: experimental (see Stability policy).

Performs first-order Born forward modelling with the variable-density acoustic wave equation: the background field solves the ordinary (nonlinear) acoustic system for v, rho; the scattered field is the exact linearisation for perturbations dv, drho, driven by virtual sources built from the constitutive perturbations dK = 2 rho v dv + v**2 drho and dB_d = -d(rho_avg_d)/rho_avg_d**2 (see docs/acoustic_born_derivation.md).

A single set of source amplitudes per component drives both fields: the background field is driven as in deepwave.acoustic() (scaled by dt*K/dt*B_d); the scattered field is automatically driven by the same amplitudes scaled by dt*dK/dt*dB_d – the “source-cell” term that arises because that scaling is itself model-dependent (mirrors deepwave.scalar_born()’s single shared source_amplitudes). No separate scattered-source argument is needed or accepted.

Backend note. torch.func transforms (vmap, forward-mode jvp) and higher-order derivatives are not available on the default compiled backend, but the pure-PyTorch backend="eager" driver runs under native autograd and composes with them (vmap over the velocity model, jvp).

Deepwave orders spatial dimensions from slowest-varying to fastest-varying and attaches no physical meaning to any of them; the component suffixes count from the fastest axis, so a 2-D run uses _y and _x and a 3-D run uses _z, _y and _x. See Dimension order and the axis convention.

Parameters:
  • v – The background wavespeed model, of shape [*model_shape] or, for a batched model, [n_shots, *model_shape], where model_shape has ndim entries. See Batched models.

  • rho – The background density model, of shape [*model_shape] or, for a batched model, [n_shots, *model_shape], where model_shape has ndim entries. See Batched models.

  • grid_spacing – Spatial grid cell size.

  • dt – Time step interval. See deepwave.acoustic() for the unit-consistency requirement across v/rho/grid_spacing/ dt.

  • dv – The wavespeed scattering perturbation model (None -> zero), of shape [*model_shape] or, for a batched model, [n_shots, *model_shape], where model_shape has ndim entries. See Batched models. At least one of dv/drho must be provided.

  • drho – The density scattering perturbation model (None -> zero), of shape [*model_shape] or, for a batched model, [n_shots, *model_shape], where model_shape has ndim entries. See Batched models.

  • sources – This simulation’s sources, keyed by channel. This is the canonical way to specify a survey. Each value is (amplitudes, locations), or (amplitudes, locations, mask) to include an activity mask. The channels are volume_rate, z, y, x (z only in 3-D, y only in 2-D and 3-D); these are equivalent to the flat source_amplitudes_*/source_locations_* keywords, which remain permanently supported; giving one channel in both forms raises. Optional.

  • receivers – This simulation’s receivers, keyed by channel, as the canonical alternative to the flat sc_receiver_locations* keywords. Each value is a locations object, or (locations, mask) to include an activity mask. The channels are p, z, y, x (z only in 3-D, y only in 2-D and 3-D). Giving one channel in both forms raises. Optional.

  • bg_receivers – The receivers that record the background wavefield, keyed by channel, as the canonical alternative to the flat bg_receiver_locations* keywords. Values take the same forms as receivers’. Giving one channel in both forms raises. Optional.

  • source_amplitudes_volume_rate – Source amplitudes (a volume-injection rate per unit volume, with units of 1/time), as in deepwave.acoustic(); see Units and source conventions. To drive the propagation with a volumetric (extended) source instead of hand-placed point sources, build the amplitudes and integer locations with deepwave.wavefields.source_field_to_sources().

  • source_locations_volume_rate – Source locations, as in deepwave.acoustic(). A point whose coordinates are all deepwave.IGNORE_LOCATION is ignored: it injects nothing. A point with only some coordinates set to the sentinel raises. Compare against deepwave.IGNORE_LOCATION; do not hard-code its value.

  • source_amplitudes_z – Source amplitudes (a z-direction body-force density, with units of force/volume), as in deepwave.acoustic(). This channel exists only in 3-D.

  • source_locations_z – Source locations (z-force), as in deepwave.acoustic(). This channel exists only in 3-D. A point whose coordinates are all deepwave.IGNORE_LOCATION is ignored: it injects nothing. A point with only some coordinates set to the sentinel raises. Compare against deepwave.IGNORE_LOCATION; do not hard-code its value.

  • source_amplitudes_y – Source amplitudes (y-force), as in deepwave.acoustic().

  • source_locations_y – Source locations (y-force), as in deepwave.acoustic(). A point whose coordinates are all deepwave.IGNORE_LOCATION is ignored: it injects nothing. A point with only some coordinates set to the sentinel raises. Compare against deepwave.IGNORE_LOCATION; do not hard-code its value.

  • source_amplitudes_x – Source amplitudes (x-force), as in deepwave.acoustic().

  • source_locations_x – Source locations (x-force), as in deepwave.acoustic(). A point whose coordinates are all deepwave.IGNORE_LOCATION is ignored: it injects nothing. A point with only some coordinates set to the sentinel raises. Compare against deepwave.IGNORE_LOCATION; do not hard-code its value.

  • source_mask_volume_rate – A boolean torch.Tensor with dimensions [shot, source] selecting which sources of the volume_rate channel are active. True means active; False means that point injects nothing, and its coordinates in source_locations_volume_rate are then ignored entirely (they need not be valid, in range, or unique). The shape must match the leading dimensions of source_locations_volume_rate, which must be given. This is the modern spelling of the deepwave.IGNORE_LOCATION sentinel and produces bit-identical results; supplying both a mask and a sentinel-containing locations tensor for the same component raises, as does combining a mask with a deepwave.Hicks object: a Hicks carries its own already-resolved points, so disable points inside it by setting all of their coordinates to deepwave.IGNORE_LOCATION in the locations it was built from. Optional.

  • source_mask_z – A boolean torch.Tensor with dimensions [shot, source] selecting which sources of the z channel (3-D only) are active. True means active; False means that point injects nothing, and its coordinates in source_locations_z are then ignored entirely (they need not be valid, in range, or unique). The shape must match the leading dimensions of source_locations_z, which must be given. This is the modern spelling of the deepwave.IGNORE_LOCATION sentinel and produces bit-identical results; supplying both a mask and a sentinel-containing locations tensor for the same component raises, as does combining a mask with a deepwave.Hicks object: a Hicks carries its own already-resolved points, so disable points inside it by setting all of their coordinates to deepwave.IGNORE_LOCATION in the locations it was built from. Optional.

  • source_mask_y – A boolean torch.Tensor with dimensions [shot, source] selecting which sources of the y channel are active. True means active; False means that point injects nothing, and its coordinates in source_locations_y are then ignored entirely (they need not be valid, in range, or unique). The shape must match the leading dimensions of source_locations_y, which must be given. This is the modern spelling of the deepwave.IGNORE_LOCATION sentinel and produces bit-identical results; supplying both a mask and a sentinel-containing locations tensor for the same component raises, as does combining a mask with a deepwave.Hicks object: a Hicks carries its own already-resolved points, so disable points inside it by setting all of their coordinates to deepwave.IGNORE_LOCATION in the locations it was built from. Optional.

  • source_mask_x – A boolean torch.Tensor with dimensions [shot, source] selecting which sources of the x channel are active. True means active; False means that point injects nothing, and its coordinates in source_locations_x are then ignored entirely (they need not be valid, in range, or unique). The shape must match the leading dimensions of source_locations_x, which must be given. This is the modern spelling of the deepwave.IGNORE_LOCATION sentinel and produces bit-identical results; supplying both a mask and a sentinel-containing locations tensor for the same component raises, as does combining a mask with a deepwave.Hicks object: a Hicks carries its own already-resolved points, so disable points inside it by setting all of their coordinates to deepwave.IGNORE_LOCATION in the locations it was built from. Optional.

  • sc_receiver_locations_p – Pressure receiver locations for the scattered receiver amplitudes (the Born data). A point whose coordinates are all deepwave.IGNORE_LOCATION is ignored: it records zeros. A point with only some coordinates set to the sentinel raises. Compare against deepwave.IGNORE_LOCATION; do not hard-code its value.

  • sc_receiver_locations_z – Z-component velocity receiver locations for the scattered receiver amplitudes. This channel exists only in 3-D. A point whose coordinates are all deepwave.IGNORE_LOCATION is ignored: it records zeros. A point with only some coordinates set to the sentinel raises. Compare against deepwave.IGNORE_LOCATION; do not hard-code its value.

  • sc_receiver_locations_y – Y-component velocity receiver locations for the scattered receiver amplitudes. A point whose coordinates are all deepwave.IGNORE_LOCATION is ignored: it records zeros. A point with only some coordinates set to the sentinel raises. Compare against deepwave.IGNORE_LOCATION; do not hard-code its value.

  • sc_receiver_locations_x – X-component velocity receiver locations for the scattered receiver amplitudes. A point whose coordinates are all deepwave.IGNORE_LOCATION is ignored: it records zeros. A point with only some coordinates set to the sentinel raises. Compare against deepwave.IGNORE_LOCATION; do not hard-code its value.

  • sc_receiver_mask_p – A boolean torch.Tensor with dimensions [shot, receiver] selecting which receivers of the p channel are active. True means active; False means that point records zeros, and its coordinates in sc_receiver_locations_p are then ignored entirely (they need not be valid, in range, or unique). The shape must match the leading dimensions of sc_receiver_locations_p, which must be given. This is the modern spelling of the deepwave.IGNORE_LOCATION sentinel and produces bit-identical results; supplying both a mask and a sentinel-containing locations tensor for the same component raises, as does combining a mask with a deepwave.Hicks object: a Hicks carries its own already-resolved points, so disable points inside it by setting all of their coordinates to deepwave.IGNORE_LOCATION in the locations it was built from. Optional.

  • sc_receiver_mask_z – A boolean torch.Tensor with dimensions [shot, receiver] selecting which receivers of the z channel (3-D only) are active. True means active; False means that point records zeros, and its coordinates in sc_receiver_locations_z are then ignored entirely (they need not be valid, in range, or unique). The shape must match the leading dimensions of sc_receiver_locations_z, which must be given. This is the modern spelling of the deepwave.IGNORE_LOCATION sentinel and produces bit-identical results; supplying both a mask and a sentinel-containing locations tensor for the same component raises, as does combining a mask with a deepwave.Hicks object: a Hicks carries its own already-resolved points, so disable points inside it by setting all of their coordinates to deepwave.IGNORE_LOCATION in the locations it was built from. Optional.

  • sc_receiver_mask_y – A boolean torch.Tensor with dimensions [shot, receiver] selecting which receivers of the y channel are active. True means active; False means that point records zeros, and its coordinates in sc_receiver_locations_y are then ignored entirely (they need not be valid, in range, or unique). The shape must match the leading dimensions of sc_receiver_locations_y, which must be given. This is the modern spelling of the deepwave.IGNORE_LOCATION sentinel and produces bit-identical results; supplying both a mask and a sentinel-containing locations tensor for the same component raises, as does combining a mask with a deepwave.Hicks object: a Hicks carries its own already-resolved points, so disable points inside it by setting all of their coordinates to deepwave.IGNORE_LOCATION in the locations it was built from. Optional.

  • sc_receiver_mask_x – A boolean torch.Tensor with dimensions [shot, receiver] selecting which receivers of the x channel are active. True means active; False means that point records zeros, and its coordinates in sc_receiver_locations_x are then ignored entirely (they need not be valid, in range, or unique). The shape must match the leading dimensions of sc_receiver_locations_x, which must be given. This is the modern spelling of the deepwave.IGNORE_LOCATION sentinel and produces bit-identical results; supplying both a mask and a sentinel-containing locations tensor for the same component raises, as does combining a mask with a deepwave.Hicks object: a Hicks carries its own already-resolved points, so disable points inside it by setting all of their coordinates to deepwave.IGNORE_LOCATION in the locations it was built from. Optional.

  • bg_receiver_locations_p – Optional pressure receiver locations for the background receiver amplitudes. A point whose coordinates are all deepwave.IGNORE_LOCATION is ignored: it records zeros. A point with only some coordinates set to the sentinel raises. Compare against deepwave.IGNORE_LOCATION; do not hard-code its value.

  • bg_receiver_locations_z – Optional z-component velocity receiver locations for the background receiver amplitudes. This channel exists only in 3-D. A point whose coordinates are all deepwave.IGNORE_LOCATION is ignored: it records zeros. A point with only some coordinates set to the sentinel raises. Compare against deepwave.IGNORE_LOCATION; do not hard-code its value.

  • bg_receiver_locations_y – Optional y-component velocity receiver locations for the background receiver amplitudes. A point whose coordinates are all deepwave.IGNORE_LOCATION is ignored: it records zeros. A point with only some coordinates set to the sentinel raises. Compare against deepwave.IGNORE_LOCATION; do not hard-code its value.

  • bg_receiver_locations_x – Optional x-component velocity receiver locations for the background receiver amplitudes. A point whose coordinates are all deepwave.IGNORE_LOCATION is ignored: it records zeros. A point with only some coordinates set to the sentinel raises. Compare against deepwave.IGNORE_LOCATION; do not hard-code its value.

  • bg_receiver_mask_p – A boolean torch.Tensor with dimensions [shot, receiver] selecting which receivers of the p channel recording the background wavefield are active. True means active; False means that point records zeros, and its coordinates in bg_receiver_locations_p are then ignored entirely (they need not be valid, in range, or unique). The shape must match the leading dimensions of bg_receiver_locations_p, which must be given. This is the modern spelling of the deepwave.IGNORE_LOCATION sentinel and produces bit-identical results; supplying both a mask and a sentinel-containing locations tensor for the same component raises, as does combining a mask with a deepwave.Hicks object: a Hicks carries its own already-resolved points, so disable points inside it by setting all of their coordinates to deepwave.IGNORE_LOCATION in the locations it was built from. Optional.

  • bg_receiver_mask_z – A boolean torch.Tensor with dimensions [shot, receiver] selecting which receivers of the z channel (3-D only) recording the background wavefield are active. True means active; False means that point records zeros, and its coordinates in bg_receiver_locations_z are then ignored entirely (they need not be valid, in range, or unique). The shape must match the leading dimensions of bg_receiver_locations_z, which must be given. This is the modern spelling of the deepwave.IGNORE_LOCATION sentinel and produces bit-identical results; supplying both a mask and a sentinel-containing locations tensor for the same component raises, as does combining a mask with a deepwave.Hicks object: a Hicks carries its own already-resolved points, so disable points inside it by setting all of their coordinates to deepwave.IGNORE_LOCATION in the locations it was built from. Optional.

  • bg_receiver_mask_y – A boolean torch.Tensor with dimensions [shot, receiver] selecting which receivers of the y channel recording the background wavefield are active. True means active; False means that point records zeros, and its coordinates in bg_receiver_locations_y are then ignored entirely (they need not be valid, in range, or unique). The shape must match the leading dimensions of bg_receiver_locations_y, which must be given. This is the modern spelling of the deepwave.IGNORE_LOCATION sentinel and produces bit-identical results; supplying both a mask and a sentinel-containing locations tensor for the same component raises, as does combining a mask with a deepwave.Hicks object: a Hicks carries its own already-resolved points, so disable points inside it by setting all of their coordinates to deepwave.IGNORE_LOCATION in the locations it was built from. Optional.

  • bg_receiver_mask_x – A boolean torch.Tensor with dimensions [shot, receiver] selecting which receivers of the x channel recording the background wavefield are active. True means active; False means that point records zeros, and its coordinates in bg_receiver_locations_x are then ignored entirely (they need not be valid, in range, or unique). The shape must match the leading dimensions of bg_receiver_locations_x, which must be given. This is the modern spelling of the deepwave.IGNORE_LOCATION sentinel and produces bit-identical results; supplying both a mask and a sentinel-containing locations tensor for the same component raises, as does combining a mask with a deepwave.Hicks object: a Hicks carries its own already-resolved points, so disable points inside it by setting all of their coordinates to deepwave.IGNORE_LOCATION in the locations it was built from. Optional.

  • pressure_0 – Initial background pressure, as in deepwave.acoustic().

  • vz_0 – Initial background z-velocity.

  • vy_0 – Initial background y-velocity.

  • vx_0 – Initial background x-velocity.

  • pressure_sc_0 – Initial scattered pressure.

  • vz_sc_0 – Initial scattered z-velocity.

  • vy_sc_0 – Initial scattered y-velocity.

  • vx_sc_0 – Initial scattered x-velocity.

  • accuracy – See deepwave.elastic().

  • pml_width – See deepwave.elastic(). A face whose pml_width is zero does not absorb: it becomes an implicit reflecting boundary whose type depends on the propagator and the field component. See Reflecting edges for the per-propagator reflection coefficient and surface location, and prefer naming the condition with boundary (or deepwave.boundaries()), which also uses the exact image rather than this approximate one.

  • boundary – An optional single string, applying to every face, or a list of 2 * ndim strings selecting a first-class boundary condition per face, in the same order as pml_width and with the same semantics as deepwave.acoustic()’s boundary (“pml”, “free”, “rigid”, or “periodic”; a non-“pml” face requires pml_width == 0 on that face). Applied independently to the background field (p, v_d) and the scattered field (dp, dv_d): both are an ordinary acoustic staggered-grid field on the same grid (see the module docstring), so the same acoustic per-axis image rule (pressure odd/even, normal velocity even/odd, tangential velocity untouched – see docs/boundaries.rst) applies to each independently, with no new physics beyond what deepwave.acoustic() already validates. Validated on the eager (backend=”eager”) and the default compiled C/CUDA backends; the “torch_compile” Python mode shares the eager guard-fill code path but is not separately validated for boundary=. Availability: “pml” and “rigid” are accepted on every face at every accuracy, and “free” on the beginning of a dimension at every accuracy and on the end of a dimension at accuracy=2. “free” on the end of a dimension with accuracy >= 4, and “periodic” on any face, raise deepwave.DeepwaveNotImplementedError: those guard-ring fills do not conserve a discrete energy, so the solution can grow without bound. Put such a face at the beginning of the dimension instead (flip the model along that axis), or use accuracy=2. Faces may be accepted in a later release; none is removed.

  • pml_freq – See deepwave.elastic().

  • max_vel – See deepwave.elastic().

  • courant_number – See deepwave.elastic().

  • survey_pad – See deepwave.scalar().

  • initial_state – See deepwave.elastic(). The mapping keys are this propagator’s own public state field names – the background names of deepwave.acoustic() (e.g. pressure_0) and the scattered names, which carry sc before the time index (e.g. pressure_sc_0) – plus auxiliary_state. The individual absorbing-boundary field names (phi_z_0, …, psi_x_0 and their scattered counterparts) are not accepted as keys: pass initial_state=out (or initial_state=out.final_state) to carry them across.

  • origin – See deepwave.scalar().

  • nt – See deepwave.elastic().

  • model_gradient_sampling_interval – See deepwave.elastic().

  • checkpoint_segments –

    If given, split the time axis into this many segments and run each of them under torch.utils.checkpoint, which is the memory lever for a run whose wavefield history does not fit: peak backward memory falls to roughly one segment’s history plus the states held at the segment boundaries, at the cost of running the forward pass of each segment a second time during the backward pass. None (the default) runs the whole time axis in one piece, exactly as before. It is the same thing as calling deepwave.checkpointing.run_segments() with n_segments= and checkpoint=True, and returns the same combined output – the same fields, the same info and the same auxiliary_state a direct call gives. initial_state, the storage arguments and every physics option are supported; nt may pad or truncate supplied source amplitudes for the whole run. Source-free nt calls, individual initial-wavefield arguments and per-step callbacks are not supported, and say so.

    Take the gradient with loss.backward(). The checkpointing is reentrant, and torch.utils.checkpoint does not support torch.autograd.grad() (or an inputs= argument to .backward()) in that mode: it raises. If you need torch.autograd.grad, call deepwave.checkpointing.run_segments() directly with use_reentrant=False.

  • freq_taper_frac – See deepwave.elastic().

  • time_pad_frac – See deepwave.elastic().

  • time_taper – See deepwave.elastic().

  • check_output_finite – See deepwave.elastic().

  • forward_callback – See deepwave.elastic(). Supported on both the default compiled backend and the eager backend (backend=”eager”).

  • backward_callback – See deepwave.elastic(). Supported only on the default compiled backend; the eager backend rejects it.

  • callback_frequency – See deepwave.elastic().

  • backend – Which execution backend to use: "auto" (the default), "compiled", "eager" or "torch_compile". See Backends for what each value selects, what "auto" resolves to, and how the backends agree numerically. "auto" resolves to the compiled C/CUDA forward paired with the compiled adjoint kernels, and supports callbacks and the "cpu"/"disk"/"none" storage modes. "eager" and "torch_compile" run the pure-PyTorch coupled Born driver, whose two step functions are compiled in the latter.

  • storage – The storage policy for the wavefield history that the model gradient is computed from, as one object: either a mode string (“device”, “cpu”, “disk” or “none”) or a deepwave.Storage, which also carries the path and the lossy-compression flag. Defaults to “device”. This is an alternative spelling for the four individual storage_* arguments below, which remain permanently supported and are not deprecated; passing storage together with any of them raises DeepwaveValueError, because there is no honest way to merge two policies.

  • storage_mode – A string specifying the storage mode for intermediate data. One of “device”, “cpu”, “disk”, or “none”. Defaults to “device”. A permanent alias for Storage.mode; not deprecated. Only “device” is permitted with backend=”eager” (the eager backend does not use the engine’s storage manager).

  • storage_path – The directory that storage_mode=”disk” writes to. A string or any os.PathLike (such as a pathlib.Path). Defaults to the system temporary directory, resolved when you call rather than when Deepwave is imported, so TMPDIR set at any point before the call is honoured. Using the default with storage_mode=”disk” emits a one-time warning naming the directory, because on many systems it is a RAM-backed tmpfs far smaller than the disk. A permanent alias for Storage.path; not deprecated.

  • storage_compression – Lossy – changes the model gradient by about 0.2-4% in 2-D and 0.2-8% in 3-D. See deepwave.elastic(). Not supported with backend=”eager”.

  • location_interpolation – See deepwave.elastic(). A single source interpolator is built from the shared source locations and its spread applied once, then shared by the background and the (internally derived) scattered source – both drive the same physical locations (see the module docstring’s source-cell paragraph). The background and scattered receivers have independent interpolators. "auto" interpolates a floating-point locations Tensor only when at least one non-ignored coordinate lies more than deepwave.ON_NODE_TOLERANCE cells off its component’s grid node – except that a floating-point Tensor with requires_grad=True is always interpolated, even when every coordinate is on-node, because only the interpolated path carries gradients back to the positions. That changes the forward values for an on-node requires_grad locations Tensor relative to the same Tensor without requires_grad. Pass location_interpolation="none" for the exact path (positions are then not differentiable), or accept the band-limited values. RunInfo.location_interpolation_used records which path was taken: "none" or "hicks", or "mixed" if this propagator has several channels of one kind (several source components, say) and they did not all take the same path.

  • location_interpolation_halfwidth – See deepwave.elastic().

Returns:

a tuple subclass whose fields, in order, are:

  • pressure_0: Final background pressure wavefield.

  • vz_0: Final background z-velocity wavefield (if ndim == 3).

  • vy_0: Final background y-velocity wavefield (if ndim >= 2).

  • vx_0: Final background x-velocity wavefield.

  • auxiliary_state: A deepwave.AuxiliaryState holding the absorbing boundary’s memory variables, of both the background and the scattered field. Opaque: pass it back (as part of initial_state) to continue the simulation; its contents are implementation state rather than physics.

  • pressure_sc_0: Final scattered pressure wavefield.

  • vz_sc_0: Final scattered z-velocity wavefield (if ndim == 3).

  • vy_sc_0: Final scattered y-velocity wavefield (if ndim >= 2).

  • vx_sc_0: Final scattered x-velocity wavefield.

  • bg_receiver_amplitudes_p: Recorded background pressure data.

  • bg_receiver_amplitudes_z: Recorded background z-velocity data (if ndim == 3).

  • bg_receiver_amplitudes_y: Recorded background y-velocity data (if ndim >= 2).

  • bg_receiver_amplitudes_x: Recorded background x-velocity data.

  • sc_receiver_amplitudes_p: Recorded scattered pressure data.

  • sc_receiver_amplitudes_z: Recorded scattered z-velocity data (if ndim == 3).

  • sc_receiver_amplitudes_y: Recorded scattered y-velocity data (if ndim >= 2).

  • sc_receiver_amplitudes_x: Recorded scattered x-velocity data.

This positional order is easy to index incorrectly (out[-1] is the scattered x-component velocity receiver amplitudes, not the pressure data); prefer accessing the receiver fields by name instead.

Return type:

deepwave.PropagatorOutput

Viscoacoustic Class

class deepwave.Viscoacoustic(v: Tensor, rho: Tensor, q: Tensor, grid_spacing: float | Sequence[float], *, requires_grad: bool | Sequence[str] | None = None, v_requires_grad: bool | None = None, rho_requires_grad: bool | None = None, q_requires_grad: bool | None = None, storage: str | Storage | None = None, storage_mode: Literal['device', 'cpu', 'disk', 'none'] | None = None, storage_path: str | PathLike[str] | None = None, storage_compression: bool | None = None)

Convenience nn.Module wrapper for viscoacoustic wave propagation.

Stability: experimental (see Stability policy).

Stores v, rho, q and grid_spacing once, so that each forward() call needs only the arguments that vary between calls.

Deepwave orders spatial dimensions from slowest-varying to fastest-varying and attaches no physical meaning to any of them; the component suffixes count from the fastest axis, so a 2-D run uses _y and _x and a 3-D run uses _z, _y and _x. See Dimension order and the axis convention.

Parameters:
  • v – The wavespeed (low-frequency phase velocity) model, of shape [*model_shape] or, for a batched model, [n_shots, *model_shape], where model_shape has ndim entries. See Batched models.

  • rho – The density model, of shape [*model_shape] or, for a batched model, [n_shots, *model_shape], where model_shape has ndim entries. See Batched models.

  • q – The quality factor model at the reference frequency, of shape [*model_shape] or, for a batched model, [n_shots, *model_shape], where model_shape has ndim entries. See Batched models.

  • grid_spacing – The spatial grid cell size (a single number, or one per dimension).

  • requires_grad – Which of this module’s models require a gradient. None (the default) and False select none, True selects every model this module owns, and a sequence of model names selects exactly those. Naming a model this class does not have, or an optional model that was not supplied, raises ValueError. It is an alternative spelling for the <model>_requires_grad flags below, each of which is unset (None) by default and then means False. Passing it together with an individual flag that was given explicitly raises ValueError rather than letting one silently win – whichever way the two point, and even when they agree, so that there is one rule rather than a direction-dependent one.

  • v_requires_grad – A bool specifying whether gradients will be computed for v. Unset by default, which means False. Cannot be combined with requires_grad.

  • rho_requires_grad – A bool specifying whether gradients will be computed for rho. Unset by default, which means False. Cannot be combined with requires_grad.

  • q_requires_grad – A bool specifying whether gradients will be computed for q. Unset by default, which means False. Cannot be combined with requires_grad.

  • storage – The storage policy for the wavefield history that the model gradient is computed from, as one object: either a mode string (“device”, “cpu”, “disk” or “none”) or a deepwave.Storage, which also carries the path and the lossy-compression flag. Defaults to “device”. This is an alternative spelling for the four individual storage_* arguments below, which remain permanently supported and are not deprecated; passing storage together with any of them raises DeepwaveValueError, because there is no honest way to merge two policies.

  • storage_mode – A string specifying the storage mode for intermediate data. One of “device”, “cpu”, “disk”, or “none”. Defaults to “device”. A permanent alias for Storage.mode; not deprecated.

  • storage_path – The directory that storage_mode=”disk” writes to. A string or any os.PathLike (such as a pathlib.Path). Defaults to the system temporary directory, resolved when you call rather than when Deepwave is imported, so TMPDIR set at any point before the call is honoured. Using the default with storage_mode=”disk” emits a one-time warning naming the directory, because on many systems it is a RAM-backed tmpfs far smaller than the disk. A permanent alias for Storage.path; not deprecated.

  • storage_compression – Lossy – changes the model gradient by about 0.2-4% in 2-D and 0.2-8% in 3-D. See deepwave.elastic().

Model ownership and gradients

Every model tensor given to the constructor is wrapped in a new torch.nn.Parameter that this module owns. The Parameter is a distinct leaf tensor that shares storage with the tensor you passed in: it is not a copy, so an in-place edit of one is visible in the other, but it is not the same object. Gradients therefore accumulate on the module’s own attribute (module.<model>.grad) and never on the tensor you passed in. A model requires a gradient only if you ask for one, through the constructor’s requires_grad argument or by calling module.<model>.requires_grad_(True) afterwards; hand module.parameters() to a torch.optim optimiser as usual. An optional model left as None is not a Parameter at all, so it appears in neither parameters() nor state_dict(); assigning a tensor to that attribute later stores a plain tensor rather than registering a Parameter, so it stays out of parameters() and state_dict() (and out of any checkpoint) – give the model to the constructor, or wrap it yourself in torch.nn.Parameter. Because the module owns a leaf Parameter, it cannot carry an upstream autograd graph: if the model is itself produced by another operation – a network mapping a latent vector to a wavespeed, a reparameterisation, a smoothing filter – wrapping it in a module severs that graph and no gradient reaches the producer. Use the functional interface for anything graph-producing; it takes the model as an ordinary tensor argument and backpropagates through it.

Initialises the Module.

forward(dt: float, *, sources: Mapping[str, tuple[Tensor, Tensor | Hicks] | tuple[Tensor, Tensor | Hicks, Tensor | None]] | None = None, receivers: Mapping[str, Tensor | Hicks | tuple[Tensor | Hicks, Tensor | None]] | None = None, source_amplitudes_pressure_rate: Tensor | None = None, source_amplitudes_z: Tensor | None = None, source_amplitudes_y: Tensor | None = None, source_amplitudes_x: Tensor | None = None, source_locations_pressure_rate: Tensor | Hicks | None = None, source_locations_z: Tensor | Hicks | None = None, source_locations_y: Tensor | Hicks | None = None, source_locations_x: Tensor | Hicks | None = None, source_mask_pressure_rate: Tensor | None = None, source_mask_z: Tensor | None = None, source_mask_y: Tensor | None = None, source_mask_x: Tensor | None = None, receiver_locations_p: Tensor | Hicks | None = None, receiver_locations_z: Tensor | Hicks | None = None, receiver_locations_y: Tensor | Hicks | None = None, receiver_locations_x: Tensor | Hicks | None = None, receiver_mask_p: Tensor | None = None, receiver_mask_z: Tensor | None = None, receiver_mask_y: Tensor | None = None, receiver_mask_x: Tensor | None = None, pressure_0: Tensor | None = None, vz_0: Tensor | None = None, vy_0: Tensor | None = None, vx_0: Tensor | None = None, initial_state: PropagatorOutput | Mapping[str, Tensor | AuxiliaryState] | None = None, accuracy: Literal[2, 4, 6, 8] = 4, pml_width: int | Sequence[int] = 20, boundary: str | Sequence[str] | None = None, pml_freq: float | None = None, q_freq: float | None = None, q_n_mechanisms: int = 1, q_band: tuple[float, float] | None = None, max_vel: float | None = None, courant_number: float | None = None, survey_pad: int | Sequence[int | None] | None = None, origin: Sequence[int] | None = None, nt: int | None = None, model_gradient_sampling_interval: int = 1, checkpoint_segments: int | None = None, freq_taper_frac: float = 0.0, time_pad_frac: float = 0.0, time_taper: bool = False, check_output_finite: bool = True, forward_callback: Callback | None = None, backward_callback: Callback | None = None, callback_frequency: int = 1, backend: str = 'auto', storage: str | Storage | None = None, storage_mode: Literal['device', 'cpu', 'disk', 'none'] | None = None, storage_path: str | PathLike[str] | None = None, storage_compression: bool | None = None, location_interpolation: Literal['auto', 'hicks', 'none'] = 'auto', location_interpolation_halfwidth: int = 4) → PropagatorOutput

Perform forward propagation/modelling.

See viscoacoustic() for details (the constructor-owned v/ rho/q/grid_spacing and the storage settings are supplied from the stored module state).

Parameters:
  • dt – Time step interval. Deepwave is unit-agnostic: choose any single consistent system of units for v, rho, grid_spacing, and dt (q/q_freq have their own units documented above); see Units and source conventions.

  • sources – This simulation’s sources, keyed by channel. This is the canonical way to specify a survey. Each value is (amplitudes, locations), or (amplitudes, locations, mask) to include an activity mask. The channels are pressure_rate, z, y, x (z only in 3-D, y only in 2-D and 3-D); these are equivalent to the flat source_amplitudes_*/source_locations_* keywords, which remain permanently supported; giving one channel in both forms raises. Optional.

  • receivers – This simulation’s receivers, keyed by channel, as the canonical alternative to the flat receiver_locations* keywords. Each value is a locations object, or (locations, mask) to include an activity mask. The channels are p, z, y, x (z only in 3-D, y only in 2-D and 3-D). Giving one channel in both forms raises. Optional.

  • source_amplitudes_pressure_rate – External pressure-equation source rate, in pressure per unit time (Pa/s in SI). Each internal step adds dt_internal * amplitude directly to pressure; no source is added to the relaxation memories. This is not a constitutive volume-injection rate. In the lossless limit, compare with the acoustic source source_amplitudes_volume_rate by multiplying it by K = rho * v**2.

  • source_amplitudes_z – Z-force-density source amplitudes (units of force/volume), as in deepwave.acoustic(). This channel exists only in 3-D.

  • source_amplitudes_y – Y-force-density source amplitudes.

  • source_amplitudes_x – X-force-density source amplitudes.

  • source_locations_pressure_rate – Pressure-rate source locations. A point whose coordinates are all deepwave.IGNORE_LOCATION is ignored: it injects nothing. A point with only some coordinates set to the sentinel raises. Compare against deepwave.IGNORE_LOCATION; do not hard-code its value.

  • source_locations_z – Z-force source locations. This channel exists only in 3-D. A point whose coordinates are all deepwave.IGNORE_LOCATION is ignored: it injects nothing. A point with only some coordinates set to the sentinel raises. Compare against deepwave.IGNORE_LOCATION; do not hard-code its value.

  • source_locations_y – Y-force source locations. A point whose coordinates are all deepwave.IGNORE_LOCATION is ignored: it injects nothing. A point with only some coordinates set to the sentinel raises. Compare against deepwave.IGNORE_LOCATION; do not hard-code its value.

  • source_locations_x – X-force source locations. A point whose coordinates are all deepwave.IGNORE_LOCATION is ignored: it injects nothing. A point with only some coordinates set to the sentinel raises. Compare against deepwave.IGNORE_LOCATION; do not hard-code its value.

  • source_mask_pressure_rate – A boolean torch.Tensor with dimensions [shot, source] selecting which sources of the pressure_rate channel are active. True means active; False means that point injects nothing, and its coordinates in source_locations_pressure_rate are then ignored entirely (they need not be valid, in range, or unique). The shape must match the leading dimensions of source_locations_pressure_rate, which must be given. This is the modern spelling of the deepwave.IGNORE_LOCATION sentinel and produces bit-identical results; supplying both a mask and a sentinel-containing locations tensor for the same component raises, as does combining a mask with a deepwave.Hicks object: a Hicks carries its own already-resolved points, so disable points inside it by setting all of their coordinates to deepwave.IGNORE_LOCATION in the locations it was built from. Optional.

  • source_mask_z – A boolean torch.Tensor with dimensions [shot, source] selecting which sources of the z channel (3-D only) are active. True means active; False means that point injects nothing, and its coordinates in source_locations_z are then ignored entirely (they need not be valid, in range, or unique). The shape must match the leading dimensions of source_locations_z, which must be given. This is the modern spelling of the deepwave.IGNORE_LOCATION sentinel and produces bit-identical results; supplying both a mask and a sentinel-containing locations tensor for the same component raises, as does combining a mask with a deepwave.Hicks object: a Hicks carries its own already-resolved points, so disable points inside it by setting all of their coordinates to deepwave.IGNORE_LOCATION in the locations it was built from. Optional.

  • source_mask_y – A boolean torch.Tensor with dimensions [shot, source] selecting which sources of the y channel are active. True means active; False means that point injects nothing, and its coordinates in source_locations_y are then ignored entirely (they need not be valid, in range, or unique). The shape must match the leading dimensions of source_locations_y, which must be given. This is the modern spelling of the deepwave.IGNORE_LOCATION sentinel and produces bit-identical results; supplying both a mask and a sentinel-containing locations tensor for the same component raises, as does combining a mask with a deepwave.Hicks object: a Hicks carries its own already-resolved points, so disable points inside it by setting all of their coordinates to deepwave.IGNORE_LOCATION in the locations it was built from. Optional.

  • source_mask_x – A boolean torch.Tensor with dimensions [shot, source] selecting which sources of the x channel are active. True means active; False means that point injects nothing, and its coordinates in source_locations_x are then ignored entirely (they need not be valid, in range, or unique). The shape must match the leading dimensions of source_locations_x, which must be given. This is the modern spelling of the deepwave.IGNORE_LOCATION sentinel and produces bit-identical results; supplying both a mask and a sentinel-containing locations tensor for the same component raises, as does combining a mask with a deepwave.Hicks object: a Hicks carries its own already-resolved points, so disable points inside it by setting all of their coordinates to deepwave.IGNORE_LOCATION in the locations it was built from. Optional.

  • receiver_locations_p – Pressure receiver locations. A point whose coordinates are all deepwave.IGNORE_LOCATION is ignored: it records zeros. A point with only some coordinates set to the sentinel raises. Compare against deepwave.IGNORE_LOCATION; do not hard-code its value.

  • receiver_locations_z – Z-velocity receiver locations. This channel exists only in 3-D. A point whose coordinates are all deepwave.IGNORE_LOCATION is ignored: it records zeros. A point with only some coordinates set to the sentinel raises. Compare against deepwave.IGNORE_LOCATION; do not hard-code its value.

  • receiver_locations_y – Y-velocity receiver locations. A point whose coordinates are all deepwave.IGNORE_LOCATION is ignored: it records zeros. A point with only some coordinates set to the sentinel raises. Compare against deepwave.IGNORE_LOCATION; do not hard-code its value.

  • receiver_locations_x – X-velocity receiver locations. A point whose coordinates are all deepwave.IGNORE_LOCATION is ignored: it records zeros. A point with only some coordinates set to the sentinel raises. Compare against deepwave.IGNORE_LOCATION; do not hard-code its value.

  • receiver_mask_p – A boolean torch.Tensor with dimensions [shot, receiver] selecting which receivers of the p channel are active. True means active; False means that point records zeros, and its coordinates in receiver_locations_p are then ignored entirely (they need not be valid, in range, or unique). The shape must match the leading dimensions of receiver_locations_p, which must be given. This is the modern spelling of the deepwave.IGNORE_LOCATION sentinel and produces bit-identical results; supplying both a mask and a sentinel-containing locations tensor for the same component raises, as does combining a mask with a deepwave.Hicks object: a Hicks carries its own already-resolved points, so disable points inside it by setting all of their coordinates to deepwave.IGNORE_LOCATION in the locations it was built from. Optional.

  • receiver_mask_z – A boolean torch.Tensor with dimensions [shot, receiver] selecting which receivers of the z channel (3-D only) are active. True means active; False means that point records zeros, and its coordinates in receiver_locations_z are then ignored entirely (they need not be valid, in range, or unique). The shape must match the leading dimensions of receiver_locations_z, which must be given. This is the modern spelling of the deepwave.IGNORE_LOCATION sentinel and produces bit-identical results; supplying both a mask and a sentinel-containing locations tensor for the same component raises, as does combining a mask with a deepwave.Hicks object: a Hicks carries its own already-resolved points, so disable points inside it by setting all of their coordinates to deepwave.IGNORE_LOCATION in the locations it was built from. Optional.

  • receiver_mask_y – A boolean torch.Tensor with dimensions [shot, receiver] selecting which receivers of the y channel are active. True means active; False means that point records zeros, and its coordinates in receiver_locations_y are then ignored entirely (they need not be valid, in range, or unique). The shape must match the leading dimensions of receiver_locations_y, which must be given. This is the modern spelling of the deepwave.IGNORE_LOCATION sentinel and produces bit-identical results; supplying both a mask and a sentinel-containing locations tensor for the same component raises, as does combining a mask with a deepwave.Hicks object: a Hicks carries its own already-resolved points, so disable points inside it by setting all of their coordinates to deepwave.IGNORE_LOCATION in the locations it was built from. Optional.

  • receiver_mask_x – A boolean torch.Tensor with dimensions [shot, receiver] selecting which receivers of the x channel are active. True means active; False means that point records zeros, and its coordinates in receiver_locations_x are then ignored entirely (they need not be valid, in range, or unique). The shape must match the leading dimensions of receiver_locations_x, which must be given. This is the modern spelling of the deepwave.IGNORE_LOCATION sentinel and produces bit-identical results; supplying both a mask and a sentinel-containing locations tensor for the same component raises, as does combining a mask with a deepwave.Hicks object: a Hicks carries its own already-resolved points, so disable points inside it by setting all of their coordinates to deepwave.IGNORE_LOCATION in the locations it was built from. Optional.

  • pressure_0 – Initial pressure (time t=0). Like every initial wavefield, it may be provided either at the shape of the simulation domain (the extracted model region plus the PML), which is the shape a previous call returns, or at the shape of the extracted model region itself, which Deepwave zero-pads for you; see the wavefield_0 entry of deepwave.scalar().

  • vz_0 – Initial z-velocity (time t=-0.5).

  • vy_0 – Initial y-velocity (time t=-0.5).

  • vx_0 – Initial x-velocity (time t=-0.5).

  • initial_state – See deepwave.elastic(). The mapping keys are this propagator’s own public state field names (pressure_0, vz_0, …) and auxiliary_state. The GSLS memory variables are carried inside auxiliary_state, because how many there are depends on q_n_mechanisms, so an initial relaxation state is supplied by passing a previous call’s state back, most simply as initial_state=out. Neither they (r_mech0, …) nor the individual absorbing-boundary field names (phi_y_0, …, psi_x_0) are accepted as keys.

  • accuracy – See deepwave.elastic().

  • pml_width – See deepwave.elastic(). A face whose pml_width is zero does not absorb: it becomes an implicit reflecting boundary whose type depends on the propagator and the field component. See Reflecting edges for the per-propagator reflection coefficient and surface location, and prefer naming the condition with boundary (or deepwave.boundaries()), which also uses the exact image rather than this approximate one.

  • boundary – An optional single string, applying to every face, or a list of 2 * ndim strings selecting a first-class boundary condition per face, in the same order as pml_width and with the same semantics as deepwave.acoustic()’s boundary (“pml”, “free”, “rigid”, or “periodic”; a non-“pml” face requires pml_width == 0 on that face). The pressure image rule is identical to acoustic’s (pressure odd about the surface for “free”, even about the half-cell wall for “rigid”); the SLS memory variable r is filled with the exact same image (no separate physics derivation is needed – see docs/boundaries.rst, and Robertsson (1996) for the free-surface treatment these image rules follow). Validated on the eager (backend=”eager”) and the default compiled C/CUDA backends, against analytic reflection coefficients and by gradient checking; the “torch_compile” mode shares the eager guard-fill code path but is not separately validated for boundary=. Availability: “pml” and “rigid” are accepted on every face at every accuracy, and “free” on the beginning of a dimension at every accuracy and on the end of a dimension at accuracy=2. “free” on the end of a dimension with accuracy >= 4, and “periodic” on any face, raise deepwave.DeepwaveNotImplementedError: those guard-ring fills do not conserve a discrete energy, so the solution can grow without bound. Put such a face at the beginning of the dimension instead (flip the model along that axis), or use accuracy=2. Faces may be accepted in a later release; none is removed.

  • pml_freq – See deepwave.elastic().

  • q_freq – Reference frequency at which Q is specified, in the same units as 1 / dt. Required when q_n_mechanisms == 1 (the default), and must be None when q_n_mechanisms > 1, where the constant-Q fit spans q_band instead and no single reference frequency applies. There is no default: Q has no meaning without the frequency it was measured at, and it is never taken from pml_freq, which tunes the absorbing boundary and is a different physical quantity (it is also inferred from the wavelet, which would have made the attenuation model depend on the source). omega0 = 2*pi*q_freq. It must be a positive, finite number (a one-element tensor or a NumPy scalar is accepted); anything else raises.

  • q_n_mechanisms – Number of generalised-standard-linear-solid (GSLS) relaxation mechanisms. Defaults to 1 (a single SLS mechanism; q_band must be None). For q_n_mechanisms > 1, q_band=(f1, f2) is required: q_n_mechanisms relaxation frequencies are chosen log-spaced across the band and their per-mechanism nonnegative weights are fit once in float64, independently of q, to the weak-loss band target. Their scaling by 1/q remains differentiable. The resulting passive modulus can have an actual effective Q different from q; inspect it with deepwave.attenuation.response(). More mechanisms do not guarantee a better fit. Each mechanism gets its own memory variable, carried in auxiliary_state, each with its own Crank-Nicolson update, summed into the pressure update. q_n_mechanisms > 1 is supported on the eager backend (backend="eager") and the default compiled C/CUDA backend (a DW_GSLS kernel variant; not combinable there with storage_compression=True or per-shot batched models – those combinations raise NotImplementedError and work on the eager backend); the "torch_compile" mode raises NotImplementedError.

  • q_band – (f1, f2) frequency band for the GSLS constant-Q fit; required when q_n_mechanisms > 1, must be None when q_n_mechanisms == 1.

  • max_vel – See deepwave.elastic().

  • courant_number – See deepwave.elastic().

  • survey_pad – See deepwave.scalar().

  • origin – See deepwave.scalar().

  • nt – See deepwave.elastic().

  • model_gradient_sampling_interval – See deepwave.elastic().

  • checkpoint_segments –

    If given, split the time axis into this many segments and run each of them under torch.utils.checkpoint, which is the memory lever for a run whose wavefield history does not fit: peak backward memory falls to roughly one segment’s history plus the states held at the segment boundaries, at the cost of running the forward pass of each segment a second time during the backward pass. None (the default) runs the whole time axis in one piece, exactly as before. It is the same thing as calling deepwave.checkpointing.run_segments() with n_segments= and checkpoint=True, and returns the same combined output – the same fields, the same info and the same auxiliary_state a direct call gives. initial_state, the storage arguments and every physics option are supported; nt may pad or truncate supplied source amplitudes for the whole run. Source-free nt calls, individual initial-wavefield arguments and per-step callbacks are not supported, and say so.

    Take the gradient with loss.backward(). The checkpointing is reentrant, and torch.utils.checkpoint does not support torch.autograd.grad() (or an inputs= argument to .backward()) in that mode: it raises. If you need torch.autograd.grad, call deepwave.checkpointing.run_segments() directly with use_reentrant=False.

  • freq_taper_frac – See deepwave.elastic().

  • time_pad_frac – See deepwave.elastic().

  • time_taper – See deepwave.elastic().

  • check_output_finite – See deepwave.elastic().

  • forward_callback – See deepwave.elastic().

  • backward_callback – See deepwave.elastic().

  • callback_frequency – See deepwave.elastic().

  • backend – Which execution backend to use: "auto" (the default), "compiled", "eager" or "torch_compile". See Backends for what each value selects, what "auto" resolves to, and how the backends agree numerically. "auto" resolves to the compiled C/CUDA kernel.

  • storage – The storage policy for the wavefield history that the model gradient is computed from, as one object: either a mode string (“device”, “cpu”, “disk” or “none”) or a deepwave.Storage, which also carries the path and the lossy-compression flag. Defaults to “device”. This is an alternative spelling for the four individual storage_* arguments below, which remain permanently supported and are not deprecated; passing storage together with any of them raises DeepwaveValueError, because there is no honest way to merge two policies.

  • storage_mode – A string specifying the storage mode for intermediate data. One of “device”, “cpu”, “disk”, or “none”. Defaults to “device”. A permanent alias for Storage.mode; not deprecated.

  • storage_path – The directory that storage_mode=”disk” writes to. A string or any os.PathLike (such as a pathlib.Path). Defaults to the system temporary directory, resolved when you call rather than when Deepwave is imported, so TMPDIR set at any point before the call is honoured. Using the default with storage_mode=”disk” emits a one-time warning naming the directory, because on many systems it is a RAM-backed tmpfs far smaller than the disk. A permanent alias for Storage.path; not deprecated.

  • storage_compression – Lossy – changes the model gradient by about 0.2-4% in 2-D and 0.2-8% in 3-D. See deepwave.elastic().

  • location_interpolation – See deepwave.elastic(). "auto" interpolates a floating-point locations Tensor only when at least one non-ignored coordinate lies more than deepwave.ON_NODE_TOLERANCE cells off its component’s grid node – except that a floating-point Tensor with requires_grad=True is always interpolated, even when every coordinate is on-node, because only the interpolated path carries gradients back to the positions. That changes the forward values for an on-node requires_grad locations Tensor relative to the same Tensor without requires_grad. Pass location_interpolation="none" for the exact path (positions are then not differentiable), or accept the band-limited values. RunInfo.location_interpolation_used records which path was taken: "none" or "hicks", or "mixed" if this propagator has several channels of one kind (several source components, say) and they did not all take the same path.

  • location_interpolation_halfwidth – See deepwave.elastic().

Viscoacoustic Function

deepwave.viscoacoustic(v: Tensor, rho: Tensor, q: Tensor, grid_spacing: float | Sequence[float], dt: float, *, sources: Mapping[str, tuple[Tensor, Tensor | Hicks] | tuple[Tensor, Tensor | Hicks, Tensor | None]] | None = None, receivers: Mapping[str, Tensor | Hicks | tuple[Tensor | Hicks, Tensor | None]] | None = None, source_amplitudes_pressure_rate: Tensor | None = None, source_amplitudes_z: Tensor | None = None, source_amplitudes_y: Tensor | None = None, source_amplitudes_x: Tensor | None = None, source_locations_pressure_rate: Tensor | Hicks | None = None, source_locations_z: Tensor | Hicks | None = None, source_locations_y: Tensor | Hicks | None = None, source_locations_x: Tensor | Hicks | None = None, source_mask_pressure_rate: Tensor | None = None, source_mask_z: Tensor | None = None, source_mask_y: Tensor | None = None, source_mask_x: Tensor | None = None, receiver_locations_p: Tensor | Hicks | None = None, receiver_locations_z: Tensor | Hicks | None = None, receiver_locations_y: Tensor | Hicks | None = None, receiver_locations_x: Tensor | Hicks | None = None, receiver_mask_p: Tensor | None = None, receiver_mask_z: Tensor | None = None, receiver_mask_y: Tensor | None = None, receiver_mask_x: Tensor | None = None, pressure_0: Tensor | None = None, vz_0: Tensor | None = None, vy_0: Tensor | None = None, vx_0: Tensor | None = None, initial_state: PropagatorOutput | Mapping[str, Tensor | AuxiliaryState] | None = None, accuracy: Literal[2, 4, 6, 8] = 4, pml_width: int | Sequence[int] = 20, boundary: str | Sequence[str] | None = None, pml_freq: float | None = None, q_freq: float | None = None, q_n_mechanisms: int = 1, q_band: tuple[float, float] | None = None, max_vel: float | None = None, courant_number: float | None = None, survey_pad: int | Sequence[int | None] | None = None, origin: Sequence[int] | None = None, nt: int | None = None, model_gradient_sampling_interval: int = 1, checkpoint_segments: int | None = None, freq_taper_frac: float = 0.0, time_pad_frac: float = 0.0, time_taper: bool = False, check_output_finite: bool = True, forward_callback: Callback | None = None, backward_callback: Callback | None = None, callback_frequency: int = 1, backend: str = 'auto', storage: str | Storage | None = None, storage_mode: Literal['device', 'cpu', 'disk', 'none'] | None = None, storage_path: str | PathLike[str] | None = None, storage_compression: bool | None = None, location_interpolation: Literal['auto', 'hicks', 'none'] = 'auto', location_interpolation_halfwidth: int = 4) → PropagatorOutput

Viscoacoustic (single-SLS) wave propagation (functional interface).

Stability: experimental (see Stability policy).

Forward modelling with the variable-density acoustic wave equation plus one standard-linear-solid relaxation mechanism (constant-Q attenuation) on a staggered grid. See the module docstring for the equations and the Q -> (taueps, tausig) mapping.

Deepwave orders spatial dimensions from slowest-varying to fastest-varying and attaches no physical meaning to any of them; the component suffixes count from the fastest axis, so a 2-D run uses _y and _x and a 3-D run uses _z, _y and _x. See Dimension order and the axis convention.

Parameters:
  • v – The wavespeed model (the low-frequency / relaxed phase velocity; K = rho v**2 is the relaxed modulus), of shape [*model_shape] or, for a batched model, [n_shots, *model_shape], where model_shape has ndim entries. See Batched models.

  • rho – The density model, of shape [*model_shape] or, for a batched model, [n_shots, *model_shape], where model_shape has ndim entries. See Batched models.

  • q – The quality factor Q model at the reference angular frequency omega0 = 2*pi*q_freq, of shape [*model_shape] or, for a batched model, [n_shots, *model_shape], where model_shape has ndim entries. See Batched models. A differentiable model input. Larger Q means weaker attenuation; Q = +inf gives the exact lossless acoustic equation, including in selected cells of an otherwise attenuating model.

  • grid_spacing – Spatial grid cell size.

  • dt – Time step interval. Deepwave is unit-agnostic: choose any single consistent system of units for v, rho, grid_spacing, and dt (q/q_freq have their own units documented above); see Units and source conventions.

  • sources – This simulation’s sources, keyed by channel. This is the canonical way to specify a survey. Each value is (amplitudes, locations), or (amplitudes, locations, mask) to include an activity mask. The channels are pressure_rate, z, y, x (z only in 3-D, y only in 2-D and 3-D); these are equivalent to the flat source_amplitudes_*/source_locations_* keywords, which remain permanently supported; giving one channel in both forms raises. Optional.

  • receivers – This simulation’s receivers, keyed by channel, as the canonical alternative to the flat receiver_locations* keywords. Each value is a locations object, or (locations, mask) to include an activity mask. The channels are p, z, y, x (z only in 3-D, y only in 2-D and 3-D). Giving one channel in both forms raises. Optional.

  • source_amplitudes_pressure_rate – External pressure-equation source rate, in pressure per unit time (Pa/s in SI). Each internal step adds dt_internal * amplitude directly to pressure; no source is added to the relaxation memories. This is not a constitutive volume-injection rate. In the lossless limit, compare with the acoustic source source_amplitudes_volume_rate by multiplying it by K = rho * v**2.

  • source_amplitudes_z – Z-force-density source amplitudes (units of force/volume), as in deepwave.acoustic(). This channel exists only in 3-D.

  • source_amplitudes_y – Y-force-density source amplitudes.

  • source_amplitudes_x – X-force-density source amplitudes.

  • source_locations_pressure_rate – Pressure-rate source locations. A point whose coordinates are all deepwave.IGNORE_LOCATION is ignored: it injects nothing. A point with only some coordinates set to the sentinel raises. Compare against deepwave.IGNORE_LOCATION; do not hard-code its value.

  • source_locations_z – Z-force source locations. This channel exists only in 3-D. A point whose coordinates are all deepwave.IGNORE_LOCATION is ignored: it injects nothing. A point with only some coordinates set to the sentinel raises. Compare against deepwave.IGNORE_LOCATION; do not hard-code its value.

  • source_locations_y – Y-force source locations. A point whose coordinates are all deepwave.IGNORE_LOCATION is ignored: it injects nothing. A point with only some coordinates set to the sentinel raises. Compare against deepwave.IGNORE_LOCATION; do not hard-code its value.

  • source_locations_x – X-force source locations. A point whose coordinates are all deepwave.IGNORE_LOCATION is ignored: it injects nothing. A point with only some coordinates set to the sentinel raises. Compare against deepwave.IGNORE_LOCATION; do not hard-code its value.

  • source_mask_pressure_rate – A boolean torch.Tensor with dimensions [shot, source] selecting which sources of the pressure_rate channel are active. True means active; False means that point injects nothing, and its coordinates in source_locations_pressure_rate are then ignored entirely (they need not be valid, in range, or unique). The shape must match the leading dimensions of source_locations_pressure_rate, which must be given. This is the modern spelling of the deepwave.IGNORE_LOCATION sentinel and produces bit-identical results; supplying both a mask and a sentinel-containing locations tensor for the same component raises, as does combining a mask with a deepwave.Hicks object: a Hicks carries its own already-resolved points, so disable points inside it by setting all of their coordinates to deepwave.IGNORE_LOCATION in the locations it was built from. Optional.

  • source_mask_z – A boolean torch.Tensor with dimensions [shot, source] selecting which sources of the z channel (3-D only) are active. True means active; False means that point injects nothing, and its coordinates in source_locations_z are then ignored entirely (they need not be valid, in range, or unique). The shape must match the leading dimensions of source_locations_z, which must be given. This is the modern spelling of the deepwave.IGNORE_LOCATION sentinel and produces bit-identical results; supplying both a mask and a sentinel-containing locations tensor for the same component raises, as does combining a mask with a deepwave.Hicks object: a Hicks carries its own already-resolved points, so disable points inside it by setting all of their coordinates to deepwave.IGNORE_LOCATION in the locations it was built from. Optional.

  • source_mask_y – A boolean torch.Tensor with dimensions [shot, source] selecting which sources of the y channel are active. True means active; False means that point injects nothing, and its coordinates in source_locations_y are then ignored entirely (they need not be valid, in range, or unique). The shape must match the leading dimensions of source_locations_y, which must be given. This is the modern spelling of the deepwave.IGNORE_LOCATION sentinel and produces bit-identical results; supplying both a mask and a sentinel-containing locations tensor for the same component raises, as does combining a mask with a deepwave.Hicks object: a Hicks carries its own already-resolved points, so disable points inside it by setting all of their coordinates to deepwave.IGNORE_LOCATION in the locations it was built from. Optional.

  • source_mask_x – A boolean torch.Tensor with dimensions [shot, source] selecting which sources of the x channel are active. True means active; False means that point injects nothing, and its coordinates in source_locations_x are then ignored entirely (they need not be valid, in range, or unique). The shape must match the leading dimensions of source_locations_x, which must be given. This is the modern spelling of the deepwave.IGNORE_LOCATION sentinel and produces bit-identical results; supplying both a mask and a sentinel-containing locations tensor for the same component raises, as does combining a mask with a deepwave.Hicks object: a Hicks carries its own already-resolved points, so disable points inside it by setting all of their coordinates to deepwave.IGNORE_LOCATION in the locations it was built from. Optional.

  • receiver_locations_p – Pressure receiver locations. A point whose coordinates are all deepwave.IGNORE_LOCATION is ignored: it records zeros. A point with only some coordinates set to the sentinel raises. Compare against deepwave.IGNORE_LOCATION; do not hard-code its value.

  • receiver_locations_z – Z-velocity receiver locations. This channel exists only in 3-D. A point whose coordinates are all deepwave.IGNORE_LOCATION is ignored: it records zeros. A point with only some coordinates set to the sentinel raises. Compare against deepwave.IGNORE_LOCATION; do not hard-code its value.

  • receiver_locations_y – Y-velocity receiver locations. A point whose coordinates are all deepwave.IGNORE_LOCATION is ignored: it records zeros. A point with only some coordinates set to the sentinel raises. Compare against deepwave.IGNORE_LOCATION; do not hard-code its value.

  • receiver_locations_x – X-velocity receiver locations. A point whose coordinates are all deepwave.IGNORE_LOCATION is ignored: it records zeros. A point with only some coordinates set to the sentinel raises. Compare against deepwave.IGNORE_LOCATION; do not hard-code its value.

  • receiver_mask_p – A boolean torch.Tensor with dimensions [shot, receiver] selecting which receivers of the p channel are active. True means active; False means that point records zeros, and its coordinates in receiver_locations_p are then ignored entirely (they need not be valid, in range, or unique). The shape must match the leading dimensions of receiver_locations_p, which must be given. This is the modern spelling of the deepwave.IGNORE_LOCATION sentinel and produces bit-identical results; supplying both a mask and a sentinel-containing locations tensor for the same component raises, as does combining a mask with a deepwave.Hicks object: a Hicks carries its own already-resolved points, so disable points inside it by setting all of their coordinates to deepwave.IGNORE_LOCATION in the locations it was built from. Optional.

  • receiver_mask_z – A boolean torch.Tensor with dimensions [shot, receiver] selecting which receivers of the z channel (3-D only) are active. True means active; False means that point records zeros, and its coordinates in receiver_locations_z are then ignored entirely (they need not be valid, in range, or unique). The shape must match the leading dimensions of receiver_locations_z, which must be given. This is the modern spelling of the deepwave.IGNORE_LOCATION sentinel and produces bit-identical results; supplying both a mask and a sentinel-containing locations tensor for the same component raises, as does combining a mask with a deepwave.Hicks object: a Hicks carries its own already-resolved points, so disable points inside it by setting all of their coordinates to deepwave.IGNORE_LOCATION in the locations it was built from. Optional.

  • receiver_mask_y – A boolean torch.Tensor with dimensions [shot, receiver] selecting which receivers of the y channel are active. True means active; False means that point records zeros, and its coordinates in receiver_locations_y are then ignored entirely (they need not be valid, in range, or unique). The shape must match the leading dimensions of receiver_locations_y, which must be given. This is the modern spelling of the deepwave.IGNORE_LOCATION sentinel and produces bit-identical results; supplying both a mask and a sentinel-containing locations tensor for the same component raises, as does combining a mask with a deepwave.Hicks object: a Hicks carries its own already-resolved points, so disable points inside it by setting all of their coordinates to deepwave.IGNORE_LOCATION in the locations it was built from. Optional.

  • receiver_mask_x – A boolean torch.Tensor with dimensions [shot, receiver] selecting which receivers of the x channel are active. True means active; False means that point records zeros, and its coordinates in receiver_locations_x are then ignored entirely (they need not be valid, in range, or unique). The shape must match the leading dimensions of receiver_locations_x, which must be given. This is the modern spelling of the deepwave.IGNORE_LOCATION sentinel and produces bit-identical results; supplying both a mask and a sentinel-containing locations tensor for the same component raises, as does combining a mask with a deepwave.Hicks object: a Hicks carries its own already-resolved points, so disable points inside it by setting all of their coordinates to deepwave.IGNORE_LOCATION in the locations it was built from. Optional.

  • pressure_0 – Initial pressure (time t=0). Like every initial wavefield, it may be provided either at the shape of the simulation domain (the extracted model region plus the PML), which is the shape a previous call returns, or at the shape of the extracted model region itself, which Deepwave zero-pads for you; see the wavefield_0 entry of deepwave.scalar().

  • vz_0 – Initial z-velocity (time t=-0.5).

  • vy_0 – Initial y-velocity (time t=-0.5).

  • vx_0 – Initial x-velocity (time t=-0.5).

  • initial_state – See deepwave.elastic(). The mapping keys are this propagator’s own public state field names (pressure_0, vz_0, …) and auxiliary_state. The GSLS memory variables are carried inside auxiliary_state, because how many there are depends on q_n_mechanisms, so an initial relaxation state is supplied by passing a previous call’s state back, most simply as initial_state=out. Neither they (r_mech0, …) nor the individual absorbing-boundary field names (phi_y_0, …, psi_x_0) are accepted as keys.

  • accuracy – See deepwave.elastic().

  • pml_width – See deepwave.elastic(). A face whose pml_width is zero does not absorb: it becomes an implicit reflecting boundary whose type depends on the propagator and the field component. See Reflecting edges for the per-propagator reflection coefficient and surface location, and prefer naming the condition with boundary (or deepwave.boundaries()), which also uses the exact image rather than this approximate one.

  • boundary – An optional single string, applying to every face, or a list of 2 * ndim strings selecting a first-class boundary condition per face, in the same order as pml_width and with the same semantics as deepwave.acoustic()’s boundary (“pml”, “free”, “rigid”, or “periodic”; a non-“pml” face requires pml_width == 0 on that face). The pressure image rule is identical to acoustic’s (pressure odd about the surface for “free”, even about the half-cell wall for “rigid”); the SLS memory variable r is filled with the exact same image (no separate physics derivation is needed – see docs/boundaries.rst, and Robertsson (1996) for the free-surface treatment these image rules follow). Validated on the eager (backend=”eager”) and the default compiled C/CUDA backends, against analytic reflection coefficients and by gradient checking; the “torch_compile” mode shares the eager guard-fill code path but is not separately validated for boundary=. Availability: “pml” and “rigid” are accepted on every face at every accuracy, and “free” on the beginning of a dimension at every accuracy and on the end of a dimension at accuracy=2. “free” on the end of a dimension with accuracy >= 4, and “periodic” on any face, raise deepwave.DeepwaveNotImplementedError: those guard-ring fills do not conserve a discrete energy, so the solution can grow without bound. Put such a face at the beginning of the dimension instead (flip the model along that axis), or use accuracy=2. Faces may be accepted in a later release; none is removed.

  • pml_freq – See deepwave.elastic().

  • q_freq – Reference frequency at which Q is specified, in the same units as 1 / dt. Required when q_n_mechanisms == 1 (the default), and must be None when q_n_mechanisms > 1, where the constant-Q fit spans q_band instead and no single reference frequency applies. There is no default: Q has no meaning without the frequency it was measured at, and it is never taken from pml_freq, which tunes the absorbing boundary and is a different physical quantity (it is also inferred from the wavelet, which would have made the attenuation model depend on the source). omega0 = 2*pi*q_freq. It must be a positive, finite number (a one-element tensor or a NumPy scalar is accepted); anything else raises.

  • q_n_mechanisms – Number of generalised-standard-linear-solid (GSLS) relaxation mechanisms. Defaults to 1 (a single SLS mechanism; q_band must be None). For q_n_mechanisms > 1, q_band=(f1, f2) is required: q_n_mechanisms relaxation frequencies are chosen log-spaced across the band and their per-mechanism nonnegative weights are fit once in float64, independently of q, to the weak-loss band target. Their scaling by 1/q remains differentiable. The resulting passive modulus can have an actual effective Q different from q; inspect it with deepwave.attenuation.response(). More mechanisms do not guarantee a better fit. Each mechanism gets its own memory variable, carried in auxiliary_state, each with its own Crank-Nicolson update, summed into the pressure update. q_n_mechanisms > 1 is supported on the eager backend (backend="eager") and the default compiled C/CUDA backend (a DW_GSLS kernel variant; not combinable there with storage_compression=True or per-shot batched models – those combinations raise NotImplementedError and work on the eager backend); the "torch_compile" mode raises NotImplementedError.

  • q_band – (f1, f2) frequency band for the GSLS constant-Q fit; required when q_n_mechanisms > 1, must be None when q_n_mechanisms == 1.

  • max_vel – See deepwave.elastic().

  • courant_number – See deepwave.elastic().

  • survey_pad – See deepwave.scalar().

  • origin – See deepwave.scalar().

  • nt – See deepwave.elastic().

  • model_gradient_sampling_interval – See deepwave.elastic().

  • checkpoint_segments –

    If given, split the time axis into this many segments and run each of them under torch.utils.checkpoint, which is the memory lever for a run whose wavefield history does not fit: peak backward memory falls to roughly one segment’s history plus the states held at the segment boundaries, at the cost of running the forward pass of each segment a second time during the backward pass. None (the default) runs the whole time axis in one piece, exactly as before. It is the same thing as calling deepwave.checkpointing.run_segments() with n_segments= and checkpoint=True, and returns the same combined output – the same fields, the same info and the same auxiliary_state a direct call gives. initial_state, the storage arguments and every physics option are supported; nt may pad or truncate supplied source amplitudes for the whole run. Source-free nt calls, individual initial-wavefield arguments and per-step callbacks are not supported, and say so.

    Take the gradient with loss.backward(). The checkpointing is reentrant, and torch.utils.checkpoint does not support torch.autograd.grad() (or an inputs= argument to .backward()) in that mode: it raises. If you need torch.autograd.grad, call deepwave.checkpointing.run_segments() directly with use_reentrant=False.

  • freq_taper_frac – See deepwave.elastic().

  • time_pad_frac – See deepwave.elastic().

  • time_taper – See deepwave.elastic().

  • check_output_finite – See deepwave.elastic().

  • forward_callback – See deepwave.elastic().

  • backward_callback – See deepwave.elastic().

  • callback_frequency – See deepwave.elastic().

  • backend – Which execution backend to use: "auto" (the default), "compiled", "eager" or "torch_compile". See Backends for what each value selects, what "auto" resolves to, and how the backends agree numerically. "auto" resolves to the compiled C/CUDA kernel.

  • storage – The storage policy for the wavefield history that the model gradient is computed from, as one object: either a mode string (“device”, “cpu”, “disk” or “none”) or a deepwave.Storage, which also carries the path and the lossy-compression flag. Defaults to “device”. This is an alternative spelling for the four individual storage_* arguments below, which remain permanently supported and are not deprecated; passing storage together with any of them raises DeepwaveValueError, because there is no honest way to merge two policies.

  • storage_mode – A string specifying the storage mode for intermediate data. One of “device”, “cpu”, “disk”, or “none”. Defaults to “device”. A permanent alias for Storage.mode; not deprecated.

  • storage_path – The directory that storage_mode=”disk” writes to. A string or any os.PathLike (such as a pathlib.Path). Defaults to the system temporary directory, resolved when you call rather than when Deepwave is imported, so TMPDIR set at any point before the call is honoured. Using the default with storage_mode=”disk” emits a one-time warning naming the directory, because on many systems it is a RAM-backed tmpfs far smaller than the disk. A permanent alias for Storage.path; not deprecated.

  • storage_compression – Lossy – changes the model gradient by about 0.2-4% in 2-D and 0.2-8% in 3-D. See deepwave.elastic().

  • location_interpolation – See deepwave.elastic(). "auto" interpolates a floating-point locations Tensor only when at least one non-ignored coordinate lies more than deepwave.ON_NODE_TOLERANCE cells off its component’s grid node – except that a floating-point Tensor with requires_grad=True is always interpolated, even when every coordinate is on-node, because only the interpolated path carries gradients back to the positions. That changes the forward values for an on-node requires_grad locations Tensor relative to the same Tensor without requires_grad. Pass location_interpolation="none" for the exact path (positions are then not differentiable), or accept the band-limited values. RunInfo.location_interpolation_used records which path was taken: "none" or "hicks", or "mixed" if this propagator has several channels of one kind (several source components, say) and they did not all take the same path.

  • location_interpolation_halfwidth – See deepwave.elastic().

Returns:

a tuple subclass whose fields, in order, are:

  • pressure_0: Final pressure wavefield.

  • vz_0: Final z-velocity wavefield (if ndim == 3).

  • vy_0: Final y-velocity wavefield (if ndim >= 2).

  • vx_0: Final x-velocity wavefield.

  • auxiliary_state: A deepwave.AuxiliaryState holding the absorbing boundary’s memory variables and the GSLS relaxation memory variables (one per mechanism). Opaque: pass it back (as part of initial_state) to continue the simulation; its contents are implementation state rather than physics. The field list therefore does not change with q_n_mechanisms.

  • receiver_amplitudes_p: Recorded pressure data.

  • receiver_amplitudes_z: Recorded z-velocity data (if ndim == 3).

  • receiver_amplitudes_y: Recorded y-velocity data (if ndim >= 2).

  • receiver_amplitudes_x: Recorded x-velocity data.

This positional order is easy to index incorrectly (out[-1] is the x-component velocity receiver amplitudes, not the pressure data); prefer accessing the fields by name instead.

Return type:

deepwave.PropagatorOutput

Acoustic VTI

class deepwave.AcousticVti(c11: Tensor, c13: Tensor, c33: Tensor, buoyancy: Tensor, grid_spacing: float | Sequence[float], *, requires_grad: bool | Sequence[str] | None = None, c11_requires_grad: bool | None = None, c13_requires_grad: bool | None = None, c33_requires_grad: bool | None = None, buoyancy_requires_grad: bool | None = None, storage: str | Storage | None = None, storage_mode: Literal['device', 'cpu', 'disk', 'none'] | None = None, storage_path: str | PathLike[str] | None = None, storage_compression: bool | None = None)

A PyTorch Module for pseudo-acoustic VTI wave propagation.

Stability: experimental (see Stability policy).

This Module stores the VTI stiffnesses (c11, c13, c33) and the buoyancy as torch.nn.Parameter objects, allowing gradients to be computed with respect to them if desired. See acoustic_vti() for a description of the physics, arguments, and outputs.

Deepwave orders spatial dimensions from slowest-varying to fastest-varying and attaches no physical meaning to any of them; the component suffixes count from the fastest axis, so a 2-D run uses _y and _x and a 3-D run uses _z, _y and _x. See Dimension order and the axis convention. The one exception to that freedom is this family: its symmetry axis is dimension 0 by construction, so here the axis order is a physics constraint rather than a documentation convention.

Parameters:
  • c11 – The c11 stiffness model (horizontal P modulus), of shape [*model_shape] or, for a batched model, [n_shots, *model_shape], where model_shape has ndim entries. See Batched models.

  • c13 – The c13 stiffness model, of shape [*model_shape] or, for a batched model, [n_shots, *model_shape], where model_shape has ndim entries. See Batched models.

  • c33 – The c33 stiffness model (vertical P modulus), of shape [*model_shape] or, for a batched model, [n_shots, *model_shape], where model_shape has ndim entries. See Batched models.

  • buoyancy – The buoyancy (1/density) model. A cell with buoyancy = 0 is a vacuum, not an infinitely dense cell; see the vacuum sentinel in Boundary conditions, which also explains how the sentinel is averaged onto the staggered nodes. It is of shape [*model_shape] or, for a batched model, [n_shots, *model_shape], where model_shape has ndim entries. See Batched models.

  • grid_spacing – The spatial grid cell size (a single number or one per dimension).

  • requires_grad – Which of this module’s models require a gradient. None (the default) and False select none, True selects every model this module owns, and a sequence of model names selects exactly those. Naming a model this class does not have, or an optional model that was not supplied, raises ValueError. It is an alternative spelling for the <model>_requires_grad flags below, each of which is unset (None) by default and then means False. Passing it together with an individual flag that was given explicitly raises ValueError rather than letting one silently win – whichever way the two point, and even when they agree, so that there is one rule rather than a direction-dependent one.

  • c11_requires_grad – A bool specifying whether gradients will be computed for c11. Unset by default, which means False. Cannot be combined with requires_grad.

  • c13_requires_grad – A bool specifying whether gradients will be computed for c13. Unset by default, which means False. Cannot be combined with requires_grad.

  • c33_requires_grad – A bool specifying whether gradients will be computed for c33. Unset by default, which means False. Cannot be combined with requires_grad.

  • buoyancy_requires_grad – A bool specifying whether gradients will be computed for buoyancy. Unset by default, which means False. Cannot be combined with requires_grad.

  • storage – The storage policy for the wavefield history that the model gradient is computed from, as one object: either a mode string (“device”, “cpu”, “disk” or “none”) or a deepwave.Storage, which also carries the path and the lossy-compression flag. Defaults to “device”. This is an alternative spelling for the four individual storage_* arguments below, which remain permanently supported and are not deprecated; passing storage together with any of them raises DeepwaveValueError, because there is no honest way to merge two policies.

  • storage_mode – A string specifying the storage mode for intermediate data. One of “device”, “cpu”, “disk”, or “none”. Defaults to “device”. A permanent alias for Storage.mode; not deprecated. Compiled backend only (the eager backend requires “device”).

  • storage_path – The directory that storage_mode=”disk” writes to. A string or any os.PathLike (such as a pathlib.Path). Defaults to the system temporary directory, resolved when you call rather than when Deepwave is imported, so TMPDIR set at any point before the call is honoured. Using the default with storage_mode=”disk” emits a one-time warning naming the directory, because on many systems it is a RAM-backed tmpfs far smaller than the disk. A permanent alias for Storage.path; not deprecated.

  • storage_compression – Lossy – changes the model gradient by about 0.2-4% in 2-D and 0.2-8% in 3-D. See deepwave.elastic().

Model ownership and gradients

Every model tensor given to the constructor is wrapped in a new torch.nn.Parameter that this module owns. The Parameter is a distinct leaf tensor that shares storage with the tensor you passed in: it is not a copy, so an in-place edit of one is visible in the other, but it is not the same object. Gradients therefore accumulate on the module’s own attribute (module.<model>.grad) and never on the tensor you passed in. A model requires a gradient only if you ask for one, through the constructor’s requires_grad argument or by calling module.<model>.requires_grad_(True) afterwards; hand module.parameters() to a torch.optim optimiser as usual. An optional model left as None is not a Parameter at all, so it appears in neither parameters() nor state_dict(); assigning a tensor to that attribute later stores a plain tensor rather than registering a Parameter, so it stays out of parameters() and state_dict() (and out of any checkpoint) – give the model to the constructor, or wrap it yourself in torch.nn.Parameter. Because the module owns a leaf Parameter, it cannot carry an upstream autograd graph: if the model is itself produced by another operation – a network mapping a latent vector to a wavespeed, a reparameterisation, a smoothing filter – wrapping it in a module severs that graph and no gradient reaches the producer. Use the functional interface for anything graph-producing; it takes the model as an ordinary tensor argument and backpropagates through it.

Initialises the Module.

forward(dt: float, *, sources: Mapping[str, tuple[Tensor, Tensor | Hicks] | tuple[Tensor, Tensor | Hicks, Tensor | None]] | None = None, receivers: Mapping[str, Tensor | Hicks | tuple[Tensor | Hicks, Tensor | None]] | None = None, source_amplitudes_pressure_rate: Tensor | None = None, source_amplitudes_z: Tensor | None = None, source_amplitudes_y: Tensor | None = None, source_amplitudes_x: Tensor | None = None, source_amplitudes_sigma_v: Tensor | None = None, source_amplitudes_sigma_h: Tensor | None = None, source_locations_pressure_rate: Tensor | Hicks | None = None, source_locations_z: Tensor | Hicks | None = None, source_locations_y: Tensor | Hicks | None = None, source_locations_x: Tensor | Hicks | None = None, source_locations_sigma_v: Tensor | Hicks | None = None, source_locations_sigma_h: Tensor | Hicks | None = None, source_mask_pressure_rate: Tensor | None = None, source_mask_z: Tensor | None = None, source_mask_y: Tensor | None = None, source_mask_x: Tensor | None = None, source_mask_sigma_v: Tensor | None = None, source_mask_sigma_h: Tensor | None = None, receiver_locations_p: Tensor | Hicks | None = None, receiver_locations_z: Tensor | Hicks | None = None, receiver_locations_y: Tensor | Hicks | None = None, receiver_locations_x: Tensor | Hicks | None = None, receiver_locations_sigma_v: Tensor | Hicks | None = None, receiver_locations_sigma_h: Tensor | Hicks | None = None, receiver_mask_p: Tensor | None = None, receiver_mask_z: Tensor | None = None, receiver_mask_y: Tensor | None = None, receiver_mask_x: Tensor | None = None, receiver_mask_sigma_v: Tensor | None = None, receiver_mask_sigma_h: Tensor | None = None, vz_0: Tensor | None = None, vy_0: Tensor | None = None, vx_0: Tensor | None = None, sigma_v_0: Tensor | None = None, sigma_h_0: Tensor | None = None, initial_state: PropagatorOutput | Mapping[str, Tensor | AuxiliaryState] | None = None, accuracy: Literal[2, 4, 6, 8] = 4, pml_width: int | Sequence[int] = 20, boundary: str | Sequence[str] | None = None, pml_freq: float | None = None, mpml_fraction: float = 0.0, max_vel: float | None = None, courant_number: float | None = None, survey_pad: int | Sequence[int | None] | None = None, origin: Sequence[int] | None = None, nt: int | None = None, model_gradient_sampling_interval: int = 1, checkpoint_segments: int | None = None, freq_taper_frac: float = 0.0, time_pad_frac: float = 0.0, time_taper: bool = False, check_output_finite: bool = True, forward_callback: Callback | None = None, backward_callback: Callback | None = None, callback_frequency: int = 1, backend: str = 'auto', storage: str | Storage | None = None, storage_mode: Literal['device', 'cpu', 'disk', 'none'] | None = None, storage_path: str | PathLike[str] | None = None, storage_compression: bool | None = None, location_interpolation: Literal['auto', 'hicks', 'none'] = 'auto', location_interpolation_halfwidth: int = 4) → PropagatorOutput

Perform forward propagation/modelling.

The inputs are the same as for acoustic_vti() except that the stiffnesses, buoyancy, grid_spacing, and the storage settings (storage_mode/storage_path/storage_compression) do not need to be provided again – they are supplied from the stored module state. See acoustic_vti() for a description of the inputs and outputs.

Parameters:
  • dt – The time step interval of the input and output. Deepwave is unit-agnostic: choose any single consistent system of units for the stiffnesses, buoyancy, grid_spacing, and dt; see Units and source conventions.

  • source_amplitudes_z – Source amplitudes for the z velocity component (3-D only). See deepwave.elastic(). This channel exists only in 3-D.

  • source_amplitudes_y – Source amplitudes for the y velocity component: a body-force density, as source_amplitudes_z.

  • source_amplitudes_x – Source amplitudes for the x velocity component: a body-force density, as source_amplitudes_z.

  • source_amplitudes_sigma_h – Source amplitudes for sigma_h, the normal stress across the symmetry axis (a stress-rate source term s_h, with units of pressure/time).

  • sources – This simulation’s sources, keyed by channel. This is the canonical way to specify a survey. Each value is (amplitudes, locations), or (amplitudes, locations, mask) to include an activity mask. The channels are pressure_rate, z, y, x, sigma_v, sigma_h (z only in 3-D); these are equivalent to the flat source_amplitudes_*/source_locations_* keywords, which remain permanently supported; giving one channel in both forms raises. Optional.

  • receivers – This simulation’s receivers, keyed by channel, as the canonical alternative to the flat receiver_locations* keywords. Each value is a locations object, or (locations, mask) to include an activity mask. The channels are p, z, y, x, sigma_v, sigma_h (z only in 3-D). Giving one channel in both forms raises. Optional.

  • source_amplitudes_pressure_rate – The amplitudes of a compression-positive pressure-rate source, with dimensions [shot, source, time]. This propagator has no pressure variable and no volume-injection term: its only scalar sources are the two normal-stress rates, so source_amplitudes_pressure_rate is a convenience that drives both of them at once. It is exactly equivalent to passing source_amplitudes_sigma_v = -source_amplitudes_pressure_rate and source_amplitudes_sigma_h = -source_amplitudes_pressure_rate at source_locations_pressure_rate on both stress channels – the sign flip is because stress here is tension-positive while a pressure is compression-positive – and is bit-identical to writing that out by hand. The quantity is therefore a pressure rate (units of pressure/time), the same quantity as the elastic family’s source_amplitudes_pressure_rate, not the acoustic family’s volume rate; see Units and source conventions. If the sigma_v/sigma_h channels also have their own sources, these are concatenated with them along the source axis. The matching p receiver channel records the pressure this drives; see receiver_locations_p. Optional; if given, source_locations_pressure_rate must also be given.

  • source_amplitudes_sigma_v – Source amplitudes for sigma_v, the normal stress along the symmetry axis (a stress-rate source term s_v, with units of pressure/time). The same wavelet on both stress channels is an explosive/pressure source. Stress is tension-positive, so a positive amplitude is dilatational, the opposite sign to the elastic family’s compression-positive source_amplitudes_pressure_rate; see Units and source conventions.

  • source_locations_z – See deepwave.elastic() (and similarly for the other source/receiver location arguments). This channel exists only in 3-D. A point whose coordinates are all deepwave.IGNORE_LOCATION is ignored: it injects nothing. A point with only some coordinates set to the sentinel raises. Compare against deepwave.IGNORE_LOCATION; do not hard-code its value.

  • source_locations_y – See source_locations_z. A point whose coordinates are all deepwave.IGNORE_LOCATION is ignored: it injects nothing. A point with only some coordinates set to the sentinel raises. Compare against deepwave.IGNORE_LOCATION; do not hard-code its value.

  • source_locations_x – See source_locations_z. A point whose coordinates are all deepwave.IGNORE_LOCATION is ignored: it injects nothing. A point with only some coordinates set to the sentinel raises. Compare against deepwave.IGNORE_LOCATION; do not hard-code its value.

  • source_locations_pressure_rate – Integer locations of the source_amplitudes_pressure_rate sources, with dimensions [shot, source, ndim]. Applied to both stress channels. A deepwave.Hicks object is accepted only when neither stress channel has sources of its own, since two source sets cannot be concatenated inside a Hicks; build the two channels yourself in that case. Optional; required if source_amplitudes_pressure_rate is given. A point whose coordinates are all deepwave.IGNORE_LOCATION is ignored: it injects nothing. A point with only some coordinates set to the sentinel raises. Compare against deepwave.IGNORE_LOCATION; do not hard-code its value.

  • source_locations_sigma_h – Integer locations of the sigma_h sources, the normal stress across the symmetry axis. A point whose coordinates are all deepwave.IGNORE_LOCATION is ignored: it injects nothing. A point with only some coordinates set to the sentinel raises. Compare against deepwave.IGNORE_LOCATION; do not hard-code its value.

  • source_locations_sigma_v – Integer locations of the sigma_v sources. A point whose coordinates are all deepwave.IGNORE_LOCATION is ignored: it injects nothing. A point with only some coordinates set to the sentinel raises. Compare against deepwave.IGNORE_LOCATION; do not hard-code its value.

  • source_mask_pressure_rate – A boolean torch.Tensor with dimensions [shot, source] selecting which sources of the pressure_rate channel are active. True means active; False means that point injects nothing, and its coordinates in source_locations_pressure_rate are then ignored entirely (they need not be valid, in range, or unique). The shape must match the leading dimensions of source_locations_pressure_rate, which must be given. This is the modern spelling of the deepwave.IGNORE_LOCATION sentinel and produces bit-identical results; supplying both a mask and a sentinel-containing locations tensor for the same component raises, as does combining a mask with a deepwave.Hicks object: a Hicks carries its own already-resolved points, so disable points inside it by setting all of their coordinates to deepwave.IGNORE_LOCATION in the locations it was built from. Optional.

  • source_mask_z – A boolean torch.Tensor with dimensions [shot, source] selecting which sources of the z channel (3-D only) are active. True means active; False means that point injects nothing, and its coordinates in source_locations_z are then ignored entirely (they need not be valid, in range, or unique). The shape must match the leading dimensions of source_locations_z, which must be given. This is the modern spelling of the deepwave.IGNORE_LOCATION sentinel and produces bit-identical results; supplying both a mask and a sentinel-containing locations tensor for the same component raises, as does combining a mask with a deepwave.Hicks object: a Hicks carries its own already-resolved points, so disable points inside it by setting all of their coordinates to deepwave.IGNORE_LOCATION in the locations it was built from. Optional.

  • source_mask_y – A boolean torch.Tensor with dimensions [shot, source] selecting which sources of the y channel are active. True means active; False means that point injects nothing, and its coordinates in source_locations_y are then ignored entirely (they need not be valid, in range, or unique). The shape must match the leading dimensions of source_locations_y, which must be given. This is the modern spelling of the deepwave.IGNORE_LOCATION sentinel and produces bit-identical results; supplying both a mask and a sentinel-containing locations tensor for the same component raises, as does combining a mask with a deepwave.Hicks object: a Hicks carries its own already-resolved points, so disable points inside it by setting all of their coordinates to deepwave.IGNORE_LOCATION in the locations it was built from. Optional.

  • source_mask_x – A boolean torch.Tensor with dimensions [shot, source] selecting which sources of the x channel are active. True means active; False means that point injects nothing, and its coordinates in source_locations_x are then ignored entirely (they need not be valid, in range, or unique). The shape must match the leading dimensions of source_locations_x, which must be given. This is the modern spelling of the deepwave.IGNORE_LOCATION sentinel and produces bit-identical results; supplying both a mask and a sentinel-containing locations tensor for the same component raises, as does combining a mask with a deepwave.Hicks object: a Hicks carries its own already-resolved points, so disable points inside it by setting all of their coordinates to deepwave.IGNORE_LOCATION in the locations it was built from. Optional.

  • source_mask_sigma_v – A boolean torch.Tensor with dimensions [shot, source] selecting which sources of the sigma_v channel are active. True means active; False means that point injects nothing, and its coordinates in source_locations_sigma_v are then ignored entirely (they need not be valid, in range, or unique). The shape must match the leading dimensions of source_locations_sigma_v, which must be given. This is the modern spelling of the deepwave.IGNORE_LOCATION sentinel and produces bit-identical results; supplying both a mask and a sentinel-containing locations tensor for the same component raises, as does combining a mask with a deepwave.Hicks object: a Hicks carries its own already-resolved points, so disable points inside it by setting all of their coordinates to deepwave.IGNORE_LOCATION in the locations it was built from. Optional.

  • source_mask_sigma_h – A boolean torch.Tensor with dimensions [shot, source] selecting which sources of the sigma_h channel are active. True means active; False means that point injects nothing, and its coordinates in source_locations_sigma_h are then ignored entirely (they need not be valid, in range, or unique). The shape must match the leading dimensions of source_locations_sigma_h, which must be given. This is the modern spelling of the deepwave.IGNORE_LOCATION sentinel and produces bit-identical results; supplying both a mask and a sentinel-containing locations tensor for the same component raises, as does combining a mask with a deepwave.Hicks object: a Hicks carries its own already-resolved points, so disable points inside it by setting all of their coordinates to deepwave.IGNORE_LOCATION in the locations it was built from. Optional.

  • receiver_locations_z – See source_locations_z. This channel exists only in 3-D. A point whose coordinates are all deepwave.IGNORE_LOCATION is ignored: it records zeros. A point with only some coordinates set to the sentinel raises. Compare against deepwave.IGNORE_LOCATION; do not hard-code its value.

  • receiver_locations_y – See source_locations_z. A point whose coordinates are all deepwave.IGNORE_LOCATION is ignored: it records zeros. A point with only some coordinates set to the sentinel raises. Compare against deepwave.IGNORE_LOCATION; do not hard-code its value.

  • receiver_locations_x – See source_locations_z. A point whose coordinates are all deepwave.IGNORE_LOCATION is ignored: it records zeros. A point with only some coordinates set to the sentinel raises. Compare against deepwave.IGNORE_LOCATION; do not hard-code its value.

  • receiver_locations_sigma_h – Integer locations of sigma_h receivers, the normal stress across the symmetry axis. A point whose coordinates are all deepwave.IGNORE_LOCATION is ignored: it records zeros. A point with only some coordinates set to the sentinel raises. Compare against deepwave.IGNORE_LOCATION; do not hard-code its value.

  • receiver_locations_sigma_v – Integer locations of sigma_v receivers, the normal stress along the symmetry axis. A point whose coordinates are all deepwave.IGNORE_LOCATION is ignored: it records zeros. A point with only some coordinates set to the sentinel raises. Compare against deepwave.IGNORE_LOCATION; do not hard-code its value.

  • receiver_locations_p – Integer locations of the pressure receivers. This propagator has no pressure variable, so the pressure is recorded as minus the mean normal stress, -(sigma_v + (ndim - 1) sigma_h) / ndim: the same quantity every other propagator’s p receiver records, and what a hydrophone in this medium measures. It is computed by asking both stress channels for these points, so a deepwave.Hicks object is accepted only when neither stress channel has receivers of its own (two receiver sets cannot be concatenated inside a Hicks); record the two stresses yourself and combine them in that case. A point whose coordinates are all deepwave.IGNORE_LOCATION is ignored: it records zeros. A point with only some coordinates set to the sentinel raises. Optional.

  • receiver_mask_z – A boolean torch.Tensor with dimensions [shot, receiver] selecting which receivers of the z channel (3-D only) are active. True means active; False means that point records zeros, and its coordinates in receiver_locations_z are then ignored entirely (they need not be valid, in range, or unique). The shape must match the leading dimensions of receiver_locations_z, which must be given. This is the modern spelling of the deepwave.IGNORE_LOCATION sentinel and produces bit-identical results; supplying both a mask and a sentinel-containing locations tensor for the same component raises, as does combining a mask with a deepwave.Hicks object: a Hicks carries its own already-resolved points, so disable points inside it by setting all of their coordinates to deepwave.IGNORE_LOCATION in the locations it was built from. Optional.

  • receiver_mask_y – A boolean torch.Tensor with dimensions [shot, receiver] selecting which receivers of the y channel are active. True means active; False means that point records zeros, and its coordinates in receiver_locations_y are then ignored entirely (they need not be valid, in range, or unique). The shape must match the leading dimensions of receiver_locations_y, which must be given. This is the modern spelling of the deepwave.IGNORE_LOCATION sentinel and produces bit-identical results; supplying both a mask and a sentinel-containing locations tensor for the same component raises, as does combining a mask with a deepwave.Hicks object: a Hicks carries its own already-resolved points, so disable points inside it by setting all of their coordinates to deepwave.IGNORE_LOCATION in the locations it was built from. Optional.

  • receiver_mask_x – A boolean torch.Tensor with dimensions [shot, receiver] selecting which receivers of the x channel are active. True means active; False means that point records zeros, and its coordinates in receiver_locations_x are then ignored entirely (they need not be valid, in range, or unique). The shape must match the leading dimensions of receiver_locations_x, which must be given. This is the modern spelling of the deepwave.IGNORE_LOCATION sentinel and produces bit-identical results; supplying both a mask and a sentinel-containing locations tensor for the same component raises, as does combining a mask with a deepwave.Hicks object: a Hicks carries its own already-resolved points, so disable points inside it by setting all of their coordinates to deepwave.IGNORE_LOCATION in the locations it was built from. Optional.

  • receiver_mask_p – A boolean torch.Tensor with dimensions [shot, receiver] selecting which receivers of the p channel are active. True means active; False means that point records zeros, and its coordinates in receiver_locations_p are then ignored entirely (they need not be valid, in range, or unique). The shape must match the leading dimensions of receiver_locations_p, which must be given. This is the modern spelling of the deepwave.IGNORE_LOCATION sentinel and produces bit-identical results; supplying both a mask and a sentinel-containing locations tensor for the same component raises, as does combining a mask with a deepwave.Hicks object. Optional.

  • receiver_mask_sigma_v – A boolean torch.Tensor with dimensions [shot, receiver] selecting which receivers of the sigma_v channel are active. True means active; False means that point records zeros, and its coordinates in receiver_locations_sigma_v are then ignored entirely (they need not be valid, in range, or unique). The shape must match the leading dimensions of receiver_locations_sigma_v, which must be given. This is the modern spelling of the deepwave.IGNORE_LOCATION sentinel and produces bit-identical results; supplying both a mask and a sentinel-containing locations tensor for the same component raises, as does combining a mask with a deepwave.Hicks object: a Hicks carries its own already-resolved points, so disable points inside it by setting all of their coordinates to deepwave.IGNORE_LOCATION in the locations it was built from. Optional.

  • receiver_mask_sigma_h – A boolean torch.Tensor with dimensions [shot, receiver] selecting which receivers of the sigma_h channel are active. True means active; False means that point records zeros, and its coordinates in receiver_locations_sigma_h are then ignored entirely (they need not be valid, in range, or unique). The shape must match the leading dimensions of receiver_locations_sigma_h, which must be given. This is the modern spelling of the deepwave.IGNORE_LOCATION sentinel and produces bit-identical results; supplying both a mask and a sentinel-containing locations tensor for the same component raises, as does combining a mask with a deepwave.Hicks object: a Hicks carries its own already-resolved points, so disable points inside it by setting all of their coordinates to deepwave.IGNORE_LOCATION in the locations it was built from. Optional.

  • accuracy – See deepwave.elastic(). Defaults to 4.

  • pml_width – See deepwave.elastic(). Defaults to 20. A face whose pml_width is zero does not absorb: it becomes an implicit reflecting boundary whose type depends on the propagator and the field component. See Reflecting edges for the per-propagator reflection coefficient and surface location, and prefer naming the condition with boundary (or deepwave.boundaries()), which also uses the exact image rather than this approximate one.

  • boundary – An optional single string, applying to every face, or a list of 2 * ndim strings selecting a first-class boundary condition per face, in the same order as pml_width and with the same semantics as deepwave.acoustic()’s boundary (“pml”, “free”, “rigid”, or “periodic”; a non-“pml” face requires pml_width == 0 on that face). acoustic_vti has two normal stresses instead of acoustic’s one pressure: sigma_v (the axial stress) plays the “pressure” role – and is guard-filled – only on the axis face (dimension 0: z in 3-D, y in 2-D), while sigma_h (the transverse stress) plays that role, and is guard-filled, only on the transverse faces; each velocity is imaged on its own axis exactly as in deepwave.acoustic(). This follows directly from acoustic_vti’s governing equations (see the module docstring): sigma_v is fed only by the axis derivative and feeds only the axis velocity back, sigma_h only by the transverse derivatives. See docs/boundaries.rst for the full image-rule citation. Validated on the eager (backend=”eager”) and the default compiled C/CUDA backends; the “torch_compile” Python mode shares the eager guard-fill code path but is not separately validated for boundary=. Availability: “pml” and “rigid” are accepted on every face at every accuracy. “free” and “periodic” raise deepwave.DeepwaveNotImplementedError: those guard-ring fills do not conserve a discrete energy, so the solution can grow without bound. Model a free surface with a vacuum layer instead (zero stiffnesses and zero buoyancy in the cells above the surface). Faces may be accepted in a later release; none is removed.

  • pml_freq – See deepwave.elastic().

  • mpml_fraction – The multiaxial PML (M-PML) cross-damping fraction. A small positive value (0.15-0.2) can cure the C-PML corner instability that strong anisotropy sometimes triggers, at the cost of slightly larger boundary reflections. Defaults to 0.0 (standard C-PML).

  • max_vel – See deepwave.elastic(). If not provided it is bounded from the stiffnesses (see below).

  • courant_number – See deepwave.elastic().

  • survey_pad – See deepwave.scalar().

  • vz_0 – The initial z velocity wavefield (3-D only). See deepwave.elastic() (and similarly for the other initial wavefields and PML memory variables).

  • vy_0 – The initial y velocity wavefield.

  • vx_0 – The initial x velocity wavefield.

  • sigma_v_0 – The initial normal stress along the symmetry axis.

  • sigma_h_0 – The initial normal stress across the symmetry axis.

  • initial_state – See deepwave.elastic(). The mapping keys are this propagator’s own public state field names (vz_0, sigma_v_0, …) and auxiliary_state. The individual absorbing-boundary field names (m_vzz_0, …, m_sigma_h_x_0) are no longer accepted as keys.

  • origin – See deepwave.scalar().

  • nt – See deepwave.elastic().

  • model_gradient_sampling_interval – See deepwave.elastic().

  • checkpoint_segments –

    If given, split the time axis into this many segments and run each of them under torch.utils.checkpoint, which is the memory lever for a run whose wavefield history does not fit: peak backward memory falls to roughly one segment’s history plus the states held at the segment boundaries, at the cost of running the forward pass of each segment a second time during the backward pass. None (the default) runs the whole time axis in one piece, exactly as before. It is the same thing as calling deepwave.checkpointing.run_segments() with n_segments= and checkpoint=True, and returns the same combined output – the same fields, the same info and the same auxiliary_state a direct call gives. initial_state, the storage arguments and every physics option are supported; nt may pad or truncate supplied source amplitudes for the whole run. Source-free nt calls, individual initial-wavefield arguments and per-step callbacks are not supported, and say so.

    Take the gradient with loss.backward(). The checkpointing is reentrant, and torch.utils.checkpoint does not support torch.autograd.grad() (or an inputs= argument to .backward()) in that mode: it raises. If you need torch.autograd.grad, call deepwave.checkpointing.run_segments() directly with use_reentrant=False.

  • freq_taper_frac – See deepwave.elastic().

  • time_pad_frac – See deepwave.elastic().

  • time_taper – See deepwave.elastic().

  • check_output_finite – See deepwave.elastic().

  • forward_callback – See deepwave.elastic().

  • backward_callback – See deepwave.elastic(). Not supported by the eager backend (raises if given).

  • callback_frequency – See deepwave.elastic().

  • backend – Which execution backend to use: "auto" (the default), "compiled", "eager" or "torch_compile". See Backends for what each value selects, what "auto" resolves to, and how the backends agree numerically. Both forward and backward are implemented in the compiled C/CUDA backend, so "auto" uses it. At model_gradient_sampling_interval == 1 with a courant-safe dt (step_ratio == 1), model gradients (c11/c13/c33/buoyancy) match the eager backend to near machine precision; at step_ratio > 1 (from either a coarse dt or model_gradient_sampling_interval > 1) they are a bounded, non-machine-precision approximation (the model gradient is sampled and rescaled once per step_ratio block rather than exactly integrated), matching the shared behaviour of deepwave.elastic_vti(). The forward pass and the source/receiver-amplitude gradients are exact regardless of step_ratio.

  • storage – The storage policy for the wavefield history that the model gradient is computed from, as one object: either a mode string (“device”, “cpu”, “disk” or “none”) or a deepwave.Storage, which also carries the path and the lossy-compression flag. Defaults to “device”. This is an alternative spelling for the four individual storage_* arguments below, which remain permanently supported and are not deprecated; passing storage together with any of them raises DeepwaveValueError, because there is no honest way to merge two policies.

  • storage_mode – A string specifying the storage mode for intermediate data. One of “device”, “cpu”, “disk”, or “none”. Defaults to “device”. A permanent alias for Storage.mode; not deprecated. Compiled backend only (the eager backend requires “device”).

  • storage_path – The directory that storage_mode=”disk” writes to. A string or any os.PathLike (such as a pathlib.Path). Defaults to the system temporary directory, resolved when you call rather than when Deepwave is imported, so TMPDIR set at any point before the call is honoured. Using the default with storage_mode=”disk” emits a one-time warning naming the directory, because on many systems it is a RAM-backed tmpfs far smaller than the disk. A permanent alias for Storage.path; not deprecated.

  • storage_compression – Lossy – changes the model gradient by about 0.2-4% in 2-D and 0.2-8% in 3-D. See deepwave.elastic().

  • location_interpolation – See deepwave.elastic(). "auto" interpolates a floating-point locations Tensor only when at least one non-ignored coordinate lies more than deepwave.ON_NODE_TOLERANCE cells off its component’s grid node – except that a floating-point Tensor with requires_grad=True is always interpolated, even when every coordinate is on-node, because only the interpolated path carries gradients back to the positions. That changes the forward values for an on-node requires_grad locations Tensor relative to the same Tensor without requires_grad. Pass location_interpolation="none" for the exact path (positions are then not differentiable), or accept the band-limited values. RunInfo.location_interpolation_used records which path was taken: "none" or "hicks", or "mixed" if this propagator has several channels of one kind (several source components, say) and they did not all take the same path.

  • location_interpolation_halfwidth – See deepwave.elastic().

Acoustic VTI Function

deepwave.acoustic_vti(c11: Tensor, c13: Tensor, c33: Tensor, buoyancy: Tensor, grid_spacing: float | Sequence[float], dt: float, *, sources: Mapping[str, tuple[Tensor, Tensor | Hicks] | tuple[Tensor, Tensor | Hicks, Tensor | None]] | None = None, receivers: Mapping[str, Tensor | Hicks | tuple[Tensor | Hicks, Tensor | None]] | None = None, source_amplitudes_pressure_rate: Tensor | None = None, source_amplitudes_z: Tensor | None = None, source_amplitudes_y: Tensor | None = None, source_amplitudes_x: Tensor | None = None, source_amplitudes_sigma_v: Tensor | None = None, source_amplitudes_sigma_h: Tensor | None = None, source_locations_pressure_rate: Tensor | Hicks | None = None, source_locations_z: Tensor | Hicks | None = None, source_locations_y: Tensor | Hicks | None = None, source_locations_x: Tensor | Hicks | None = None, source_locations_sigma_v: Tensor | Hicks | None = None, source_locations_sigma_h: Tensor | Hicks | None = None, source_mask_pressure_rate: Tensor | None = None, source_mask_z: Tensor | None = None, source_mask_y: Tensor | None = None, source_mask_x: Tensor | None = None, source_mask_sigma_v: Tensor | None = None, source_mask_sigma_h: Tensor | None = None, receiver_locations_p: Tensor | Hicks | None = None, receiver_locations_z: Tensor | Hicks | None = None, receiver_locations_y: Tensor | Hicks | None = None, receiver_locations_x: Tensor | Hicks | None = None, receiver_locations_sigma_v: Tensor | Hicks | None = None, receiver_locations_sigma_h: Tensor | Hicks | None = None, receiver_mask_p: Tensor | None = None, receiver_mask_z: Tensor | None = None, receiver_mask_y: Tensor | None = None, receiver_mask_x: Tensor | None = None, receiver_mask_sigma_v: Tensor | None = None, receiver_mask_sigma_h: Tensor | None = None, vz_0: Tensor | None = None, vy_0: Tensor | None = None, vx_0: Tensor | None = None, sigma_v_0: Tensor | None = None, sigma_h_0: Tensor | None = None, initial_state: PropagatorOutput | Mapping[str, Tensor | AuxiliaryState] | None = None, accuracy: Literal[2, 4, 6, 8] = 4, pml_width: int | Sequence[int] = 20, boundary: str | Sequence[str] | None = None, pml_freq: float | None = None, mpml_fraction: float = 0.0, max_vel: float | None = None, courant_number: float | None = None, survey_pad: int | Sequence[int | None] | None = None, origin: Sequence[int] | None = None, nt: int | None = None, model_gradient_sampling_interval: int = 1, checkpoint_segments: int | None = None, freq_taper_frac: float = 0.0, time_pad_frac: float = 0.0, time_taper: bool = False, check_output_finite: bool = True, forward_callback: Callback | None = None, backward_callback: Callback | None = None, callback_frequency: int = 1, backend: str = 'auto', storage: str | Storage | None = None, storage_mode: Literal['device', 'cpu', 'disk', 'none'] | None = None, storage_path: str | PathLike[str] | None = None, storage_compression: bool | None = None, location_interpolation: Literal['auto', 'hicks', 'none'] = 'auto', location_interpolation_halfwidth: int = 4) → PropagatorOutput

Pseudo-acoustic VTI wave propagation (functional interface).

Stability: experimental (see Stability policy).

Forward modelling of the Duveneck et al. (2008) first-order velocity-stress pseudo-acoustic VTI wave equation (the V_S = 0 limit of VTI elasticity) in variable-density media. The outputs are differentiable with respect to the input float torch.Tensors (each stiffness and the buoyancy) and the source amplitudes.

The propagator uses the same staggered grid, C-PML/M-PML absorbing boundaries, and off-grid (Hicks) source/receiver interpolation as deepwave.elastic_vti(), and is its exact c55 = c66 = 0 reduction: the two normal stresses sigma_v (along the symmetry axis) and sigma_h (in the transverse plane) evolve, all shear stresses being identically zero and dropped along with their PML memories. See the module docstring for the governing equations.

The symmetry axis is the slowest spatial dimension: z in 3-D, y in 2-D. There is no 1-D form (only c33 would survive, i.e. the 1-D scalar equation), so 1-D inputs raise an error.

All stiffnesses are specified at the normal-stress (integer grid) nodes, with units of pressure (e.g. Pa in SI); buoyancy is 1/density and is internally averaged onto the staggered velocity nodes exactly as in deepwave.elastic() (a buoyancy = 0 cell, with zero stiffnesses, is a vacuum, giving a free surface). The stiffnesses relate to the vertical P velocity vp and Thomsen eps/delta by c33 = rho vp**2, c11 = c33 (1 + 2 eps), c13 = c33 sqrt(1 + 2 delta); deepwave.anisotropy.thomsen_to_cij() with vs = 0 produces exactly these (its c55 output is discarded).

Stability. The medium must satisfy the Grechka/Duveneck condition c11 c33 >= c13**2 (equivalently eps >= delta) everywhere, else the pseudo-acoustic system is ill-posed; this is validated and a ValueError is raised otherwise (eps = delta, elliptical anisotropy, is allowed and emits no pseudo-shear artifact).

Pseudo-shear source artifact. Where eps != delta a point source also emits a spurious diamond/rhombic pseudo-shear wave (intrinsic to the V_S = 0 formulation). deepwave.anisotropy.source_taper() optionally mitigates it by making c13 locally elliptical near the sources.

Sources and receivers may be placed on any velocity component (z, y, x; force-density sources, scaled internally by buoyancy and dt as in deepwave.elastic()) and on either normal stress (sigma_h, sigma_v; stress-rate sources s_h/s_v, scaled internally by dt). An isotropic explosive/pressure source is the same wavelet applied to both the sigma_h and sigma_v channels.

The compiled C/CUDA backend (backend="compiled", and what the default backend="auto" selects here) implements both forward propagation and a hand-derived adjoint, matching the rest of the compiled propagator family (deepwave.elastic_vti(), etc.); see the backend Args entry below for the model-gradient step_ratio caveat. The eager Python backend (backend="eager") instead provides gradients via native autograd through the time loop; the "torch_compile" Python mode runs the same eager time loop with the two step functions compiled.

Deepwave orders spatial dimensions from slowest-varying to fastest-varying and attaches no physical meaning to any of them; the component suffixes count from the fastest axis, so a 2-D run uses _y and _x and a 3-D run uses _z, _y and _x. See Dimension order and the axis convention. The one exception to that freedom is this family: its symmetry axis is dimension 0 by construction, so here the axis order is a physics constraint rather than a documentation convention.

Parameters:
  • c11 – The c11 stiffness model (horizontal P modulus), of shape [*model_shape] or, for a batched model, [n_shots, *model_shape], where model_shape has ndim entries. See Batched models.

  • c13 – The c13 stiffness model, of shape [*model_shape] or, for a batched model, [n_shots, *model_shape], where model_shape has ndim entries. See Batched models.

  • c33 – The c33 stiffness model (vertical P modulus), of shape [*model_shape] or, for a batched model, [n_shots, *model_shape], where model_shape has ndim entries. See Batched models.

  • buoyancy – The buoyancy (1/density) model. A cell with buoyancy = 0 is a vacuum, not an infinitely dense cell; see the vacuum sentinel in Boundary conditions, which also explains how the sentinel is averaged onto the staggered nodes. It is of shape [*model_shape] or, for a batched model, [n_shots, *model_shape], where model_shape has ndim entries. See Batched models.

  • grid_spacing – The spatial grid cell size (a single number for all dimensions, or one per dimension).

  • dt – The time step interval of the input and output. Deepwave is unit-agnostic: choose any single consistent system of units for the stiffnesses, buoyancy, grid_spacing, and dt; see Units and source conventions.

  • source_amplitudes_z – Source amplitudes for the z velocity component (3-D only). See deepwave.elastic(). This channel exists only in 3-D.

  • source_amplitudes_y – Source amplitudes for the y velocity component: a body-force density, as source_amplitudes_z.

  • source_amplitudes_x – Source amplitudes for the x velocity component: a body-force density, as source_amplitudes_z.

  • source_amplitudes_sigma_h – Source amplitudes for sigma_h, the normal stress across the symmetry axis (a stress-rate source term s_h, with units of pressure/time).

  • sources – This simulation’s sources, keyed by channel. This is the canonical way to specify a survey. Each value is (amplitudes, locations), or (amplitudes, locations, mask) to include an activity mask. The channels are pressure_rate, z, y, x, sigma_v, sigma_h (z only in 3-D); these are equivalent to the flat source_amplitudes_*/source_locations_* keywords, which remain permanently supported; giving one channel in both forms raises. Optional.

  • receivers – This simulation’s receivers, keyed by channel, as the canonical alternative to the flat receiver_locations* keywords. Each value is a locations object, or (locations, mask) to include an activity mask. The channels are p, z, y, x, sigma_v, sigma_h (z only in 3-D). Giving one channel in both forms raises. Optional.

  • source_amplitudes_pressure_rate – The amplitudes of a compression-positive pressure-rate source, with dimensions [shot, source, time]. This propagator has no pressure variable and no volume-injection term: its only scalar sources are the two normal-stress rates, so source_amplitudes_pressure_rate is a convenience that drives both of them at once. It is exactly equivalent to passing source_amplitudes_sigma_v = -source_amplitudes_pressure_rate and source_amplitudes_sigma_h = -source_amplitudes_pressure_rate at source_locations_pressure_rate on both stress channels – the sign flip is because stress here is tension-positive while a pressure is compression-positive – and is bit-identical to writing that out by hand. The quantity is therefore a pressure rate (units of pressure/time), the same quantity as the elastic family’s source_amplitudes_pressure_rate, not the acoustic family’s volume rate; see Units and source conventions. If the sigma_v/sigma_h channels also have their own sources, these are concatenated with them along the source axis. The matching p receiver channel records the pressure this drives; see receiver_locations_p. Optional; if given, source_locations_pressure_rate must also be given.

  • source_amplitudes_sigma_v – Source amplitudes for sigma_v, the normal stress along the symmetry axis (a stress-rate source term s_v, with units of pressure/time). The same wavelet on both stress channels is an explosive/pressure source. Stress is tension-positive, so a positive amplitude is dilatational, the opposite sign to the elastic family’s compression-positive source_amplitudes_pressure_rate; see Units and source conventions.

  • source_locations_z – See deepwave.elastic() (and similarly for the other source/receiver location arguments). This channel exists only in 3-D. A point whose coordinates are all deepwave.IGNORE_LOCATION is ignored: it injects nothing. A point with only some coordinates set to the sentinel raises. Compare against deepwave.IGNORE_LOCATION; do not hard-code its value.

  • source_locations_y – See source_locations_z. A point whose coordinates are all deepwave.IGNORE_LOCATION is ignored: it injects nothing. A point with only some coordinates set to the sentinel raises. Compare against deepwave.IGNORE_LOCATION; do not hard-code its value.

  • source_locations_x – See source_locations_z. A point whose coordinates are all deepwave.IGNORE_LOCATION is ignored: it injects nothing. A point with only some coordinates set to the sentinel raises. Compare against deepwave.IGNORE_LOCATION; do not hard-code its value.

  • source_locations_pressure_rate – Integer locations of the source_amplitudes_pressure_rate sources, with dimensions [shot, source, ndim]. Applied to both stress channels. A deepwave.Hicks object is accepted only when neither stress channel has sources of its own, since two source sets cannot be concatenated inside a Hicks; build the two channels yourself in that case. Optional; required if source_amplitudes_pressure_rate is given. A point whose coordinates are all deepwave.IGNORE_LOCATION is ignored: it injects nothing. A point with only some coordinates set to the sentinel raises. Compare against deepwave.IGNORE_LOCATION; do not hard-code its value.

  • source_locations_sigma_h – Integer locations of the sigma_h sources, the normal stress across the symmetry axis. A point whose coordinates are all deepwave.IGNORE_LOCATION is ignored: it injects nothing. A point with only some coordinates set to the sentinel raises. Compare against deepwave.IGNORE_LOCATION; do not hard-code its value.

  • source_locations_sigma_v – Integer locations of the sigma_v sources. A point whose coordinates are all deepwave.IGNORE_LOCATION is ignored: it injects nothing. A point with only some coordinates set to the sentinel raises. Compare against deepwave.IGNORE_LOCATION; do not hard-code its value.

  • source_mask_pressure_rate – A boolean torch.Tensor with dimensions [shot, source] selecting which sources of the pressure_rate channel are active. True means active; False means that point injects nothing, and its coordinates in source_locations_pressure_rate are then ignored entirely (they need not be valid, in range, or unique). The shape must match the leading dimensions of source_locations_pressure_rate, which must be given. This is the modern spelling of the deepwave.IGNORE_LOCATION sentinel and produces bit-identical results; supplying both a mask and a sentinel-containing locations tensor for the same component raises, as does combining a mask with a deepwave.Hicks object: a Hicks carries its own already-resolved points, so disable points inside it by setting all of their coordinates to deepwave.IGNORE_LOCATION in the locations it was built from. Optional.

  • source_mask_z – A boolean torch.Tensor with dimensions [shot, source] selecting which sources of the z channel (3-D only) are active. True means active; False means that point injects nothing, and its coordinates in source_locations_z are then ignored entirely (they need not be valid, in range, or unique). The shape must match the leading dimensions of source_locations_z, which must be given. This is the modern spelling of the deepwave.IGNORE_LOCATION sentinel and produces bit-identical results; supplying both a mask and a sentinel-containing locations tensor for the same component raises, as does combining a mask with a deepwave.Hicks object: a Hicks carries its own already-resolved points, so disable points inside it by setting all of their coordinates to deepwave.IGNORE_LOCATION in the locations it was built from. Optional.

  • source_mask_y – A boolean torch.Tensor with dimensions [shot, source] selecting which sources of the y channel are active. True means active; False means that point injects nothing, and its coordinates in source_locations_y are then ignored entirely (they need not be valid, in range, or unique). The shape must match the leading dimensions of source_locations_y, which must be given. This is the modern spelling of the deepwave.IGNORE_LOCATION sentinel and produces bit-identical results; supplying both a mask and a sentinel-containing locations tensor for the same component raises, as does combining a mask with a deepwave.Hicks object: a Hicks carries its own already-resolved points, so disable points inside it by setting all of their coordinates to deepwave.IGNORE_LOCATION in the locations it was built from. Optional.

  • source_mask_x – A boolean torch.Tensor with dimensions [shot, source] selecting which sources of the x channel are active. True means active; False means that point injects nothing, and its coordinates in source_locations_x are then ignored entirely (they need not be valid, in range, or unique). The shape must match the leading dimensions of source_locations_x, which must be given. This is the modern spelling of the deepwave.IGNORE_LOCATION sentinel and produces bit-identical results; supplying both a mask and a sentinel-containing locations tensor for the same component raises, as does combining a mask with a deepwave.Hicks object: a Hicks carries its own already-resolved points, so disable points inside it by setting all of their coordinates to deepwave.IGNORE_LOCATION in the locations it was built from. Optional.

  • source_mask_sigma_v – A boolean torch.Tensor with dimensions [shot, source] selecting which sources of the sigma_v channel are active. True means active; False means that point injects nothing, and its coordinates in source_locations_sigma_v are then ignored entirely (they need not be valid, in range, or unique). The shape must match the leading dimensions of source_locations_sigma_v, which must be given. This is the modern spelling of the deepwave.IGNORE_LOCATION sentinel and produces bit-identical results; supplying both a mask and a sentinel-containing locations tensor for the same component raises, as does combining a mask with a deepwave.Hicks object: a Hicks carries its own already-resolved points, so disable points inside it by setting all of their coordinates to deepwave.IGNORE_LOCATION in the locations it was built from. Optional.

  • source_mask_sigma_h – A boolean torch.Tensor with dimensions [shot, source] selecting which sources of the sigma_h channel are active. True means active; False means that point injects nothing, and its coordinates in source_locations_sigma_h are then ignored entirely (they need not be valid, in range, or unique). The shape must match the leading dimensions of source_locations_sigma_h, which must be given. This is the modern spelling of the deepwave.IGNORE_LOCATION sentinel and produces bit-identical results; supplying both a mask and a sentinel-containing locations tensor for the same component raises, as does combining a mask with a deepwave.Hicks object: a Hicks carries its own already-resolved points, so disable points inside it by setting all of their coordinates to deepwave.IGNORE_LOCATION in the locations it was built from. Optional.

  • receiver_locations_z – See source_locations_z. This channel exists only in 3-D. A point whose coordinates are all deepwave.IGNORE_LOCATION is ignored: it records zeros. A point with only some coordinates set to the sentinel raises. Compare against deepwave.IGNORE_LOCATION; do not hard-code its value.

  • receiver_locations_y – See source_locations_z. A point whose coordinates are all deepwave.IGNORE_LOCATION is ignored: it records zeros. A point with only some coordinates set to the sentinel raises. Compare against deepwave.IGNORE_LOCATION; do not hard-code its value.

  • receiver_locations_x – See source_locations_z. A point whose coordinates are all deepwave.IGNORE_LOCATION is ignored: it records zeros. A point with only some coordinates set to the sentinel raises. Compare against deepwave.IGNORE_LOCATION; do not hard-code its value.

  • receiver_locations_sigma_h – Integer locations of sigma_h receivers, the normal stress across the symmetry axis. A point whose coordinates are all deepwave.IGNORE_LOCATION is ignored: it records zeros. A point with only some coordinates set to the sentinel raises. Compare against deepwave.IGNORE_LOCATION; do not hard-code its value.

  • receiver_locations_sigma_v – Integer locations of sigma_v receivers, the normal stress along the symmetry axis. A point whose coordinates are all deepwave.IGNORE_LOCATION is ignored: it records zeros. A point with only some coordinates set to the sentinel raises. Compare against deepwave.IGNORE_LOCATION; do not hard-code its value.

  • receiver_locations_p – Integer locations of the pressure receivers. This propagator has no pressure variable, so the pressure is recorded as minus the mean normal stress, -(sigma_v + (ndim - 1) sigma_h) / ndim: the same quantity every other propagator’s p receiver records, and what a hydrophone in this medium measures. It is computed by asking both stress channels for these points, so a deepwave.Hicks object is accepted only when neither stress channel has receivers of its own (two receiver sets cannot be concatenated inside a Hicks); record the two stresses yourself and combine them in that case. A point whose coordinates are all deepwave.IGNORE_LOCATION is ignored: it records zeros. A point with only some coordinates set to the sentinel raises. Optional.

  • receiver_mask_z – A boolean torch.Tensor with dimensions [shot, receiver] selecting which receivers of the z channel (3-D only) are active. True means active; False means that point records zeros, and its coordinates in receiver_locations_z are then ignored entirely (they need not be valid, in range, or unique). The shape must match the leading dimensions of receiver_locations_z, which must be given. This is the modern spelling of the deepwave.IGNORE_LOCATION sentinel and produces bit-identical results; supplying both a mask and a sentinel-containing locations tensor for the same component raises, as does combining a mask with a deepwave.Hicks object: a Hicks carries its own already-resolved points, so disable points inside it by setting all of their coordinates to deepwave.IGNORE_LOCATION in the locations it was built from. Optional.

  • receiver_mask_y – A boolean torch.Tensor with dimensions [shot, receiver] selecting which receivers of the y channel are active. True means active; False means that point records zeros, and its coordinates in receiver_locations_y are then ignored entirely (they need not be valid, in range, or unique). The shape must match the leading dimensions of receiver_locations_y, which must be given. This is the modern spelling of the deepwave.IGNORE_LOCATION sentinel and produces bit-identical results; supplying both a mask and a sentinel-containing locations tensor for the same component raises, as does combining a mask with a deepwave.Hicks object: a Hicks carries its own already-resolved points, so disable points inside it by setting all of their coordinates to deepwave.IGNORE_LOCATION in the locations it was built from. Optional.

  • receiver_mask_x – A boolean torch.Tensor with dimensions [shot, receiver] selecting which receivers of the x channel are active. True means active; False means that point records zeros, and its coordinates in receiver_locations_x are then ignored entirely (they need not be valid, in range, or unique). The shape must match the leading dimensions of receiver_locations_x, which must be given. This is the modern spelling of the deepwave.IGNORE_LOCATION sentinel and produces bit-identical results; supplying both a mask and a sentinel-containing locations tensor for the same component raises, as does combining a mask with a deepwave.Hicks object: a Hicks carries its own already-resolved points, so disable points inside it by setting all of their coordinates to deepwave.IGNORE_LOCATION in the locations it was built from. Optional.

  • receiver_mask_p – A boolean torch.Tensor with dimensions [shot, receiver] selecting which receivers of the p channel are active. True means active; False means that point records zeros, and its coordinates in receiver_locations_p are then ignored entirely (they need not be valid, in range, or unique). The shape must match the leading dimensions of receiver_locations_p, which must be given. This is the modern spelling of the deepwave.IGNORE_LOCATION sentinel and produces bit-identical results; supplying both a mask and a sentinel-containing locations tensor for the same component raises, as does combining a mask with a deepwave.Hicks object. Optional.

  • receiver_mask_sigma_v – A boolean torch.Tensor with dimensions [shot, receiver] selecting which receivers of the sigma_v channel are active. True means active; False means that point records zeros, and its coordinates in receiver_locations_sigma_v are then ignored entirely (they need not be valid, in range, or unique). The shape must match the leading dimensions of receiver_locations_sigma_v, which must be given. This is the modern spelling of the deepwave.IGNORE_LOCATION sentinel and produces bit-identical results; supplying both a mask and a sentinel-containing locations tensor for the same component raises, as does combining a mask with a deepwave.Hicks object: a Hicks carries its own already-resolved points, so disable points inside it by setting all of their coordinates to deepwave.IGNORE_LOCATION in the locations it was built from. Optional.

  • receiver_mask_sigma_h – A boolean torch.Tensor with dimensions [shot, receiver] selecting which receivers of the sigma_h channel are active. True means active; False means that point records zeros, and its coordinates in receiver_locations_sigma_h are then ignored entirely (they need not be valid, in range, or unique). The shape must match the leading dimensions of receiver_locations_sigma_h, which must be given. This is the modern spelling of the deepwave.IGNORE_LOCATION sentinel and produces bit-identical results; supplying both a mask and a sentinel-containing locations tensor for the same component raises, as does combining a mask with a deepwave.Hicks object: a Hicks carries its own already-resolved points, so disable points inside it by setting all of their coordinates to deepwave.IGNORE_LOCATION in the locations it was built from. Optional.

  • accuracy – See deepwave.elastic(). Defaults to 4.

  • pml_width – See deepwave.elastic(). Defaults to 20. A face whose pml_width is zero does not absorb: it becomes an implicit reflecting boundary whose type depends on the propagator and the field component. See Reflecting edges for the per-propagator reflection coefficient and surface location, and prefer naming the condition with boundary (or deepwave.boundaries()), which also uses the exact image rather than this approximate one.

  • boundary – An optional single string, applying to every face, or a list of 2 * ndim strings selecting a first-class boundary condition per face, in the same order as pml_width and with the same semantics as deepwave.acoustic()’s boundary (“pml”, “free”, “rigid”, or “periodic”; a non-“pml” face requires pml_width == 0 on that face). acoustic_vti has two normal stresses instead of acoustic’s one pressure: sigma_v (the axial stress) plays the “pressure” role – and is guard-filled – only on the axis face (dimension 0: z in 3-D, y in 2-D), while sigma_h (the transverse stress) plays that role, and is guard-filled, only on the transverse faces; each velocity is imaged on its own axis exactly as in deepwave.acoustic(). This follows directly from acoustic_vti’s governing equations (see the module docstring): sigma_v is fed only by the axis derivative and feeds only the axis velocity back, sigma_h only by the transverse derivatives. See docs/boundaries.rst for the full image-rule citation. Validated on the eager (backend=”eager”) and the default compiled C/CUDA backends; the “torch_compile” Python mode shares the eager guard-fill code path but is not separately validated for boundary=. Availability: “pml” and “rigid” are accepted on every face at every accuracy. “free” and “periodic” raise deepwave.DeepwaveNotImplementedError: those guard-ring fills do not conserve a discrete energy, so the solution can grow without bound. Model a free surface with a vacuum layer instead (zero stiffnesses and zero buoyancy in the cells above the surface). Faces may be accepted in a later release; none is removed.

  • pml_freq – See deepwave.elastic().

  • mpml_fraction – The multiaxial PML (M-PML) cross-damping fraction. A small positive value (0.15-0.2) can cure the C-PML corner instability that strong anisotropy sometimes triggers, at the cost of slightly larger boundary reflections. Defaults to 0.0 (standard C-PML).

  • max_vel – See deepwave.elastic(). If not provided it is bounded from the stiffnesses (see below).

  • courant_number – See deepwave.elastic().

  • survey_pad – See deepwave.scalar().

  • vz_0 – The initial z velocity wavefield (3-D only). See deepwave.elastic() (and similarly for the other initial wavefields and PML memory variables).

  • vy_0 – The initial y velocity wavefield.

  • vx_0 – The initial x velocity wavefield.

  • sigma_v_0 – The initial normal stress along the symmetry axis.

  • sigma_h_0 – The initial normal stress across the symmetry axis.

  • initial_state – See deepwave.elastic(). The mapping keys are this propagator’s own public state field names (vz_0, sigma_v_0, …) and auxiliary_state. The individual absorbing-boundary field names (m_vzz_0, …, m_sigma_h_x_0) are no longer accepted as keys.

  • origin – See deepwave.scalar().

  • nt – See deepwave.elastic().

  • model_gradient_sampling_interval – See deepwave.elastic().

  • checkpoint_segments –

    If given, split the time axis into this many segments and run each of them under torch.utils.checkpoint, which is the memory lever for a run whose wavefield history does not fit: peak backward memory falls to roughly one segment’s history plus the states held at the segment boundaries, at the cost of running the forward pass of each segment a second time during the backward pass. None (the default) runs the whole time axis in one piece, exactly as before. It is the same thing as calling deepwave.checkpointing.run_segments() with n_segments= and checkpoint=True, and returns the same combined output – the same fields, the same info and the same auxiliary_state a direct call gives. initial_state, the storage arguments and every physics option are supported; nt may pad or truncate supplied source amplitudes for the whole run. Source-free nt calls, individual initial-wavefield arguments and per-step callbacks are not supported, and say so.

    Take the gradient with loss.backward(). The checkpointing is reentrant, and torch.utils.checkpoint does not support torch.autograd.grad() (or an inputs= argument to .backward()) in that mode: it raises. If you need torch.autograd.grad, call deepwave.checkpointing.run_segments() directly with use_reentrant=False.

  • freq_taper_frac – See deepwave.elastic().

  • time_pad_frac – See deepwave.elastic().

  • time_taper – See deepwave.elastic().

  • check_output_finite – See deepwave.elastic().

  • forward_callback – See deepwave.elastic().

  • backward_callback – See deepwave.elastic(). Not supported by the eager backend (raises if given).

  • callback_frequency – See deepwave.elastic().

  • backend – Which execution backend to use: "auto" (the default), "compiled", "eager" or "torch_compile". See Backends for what each value selects, what "auto" resolves to, and how the backends agree numerically. Both forward and backward are implemented in the compiled C/CUDA backend, so "auto" uses it. At model_gradient_sampling_interval == 1 with a courant-safe dt (step_ratio == 1), model gradients (c11/c13/c33/buoyancy) match the eager backend to near machine precision; at step_ratio > 1 (from either a coarse dt or model_gradient_sampling_interval > 1) they are a bounded, non-machine-precision approximation (the model gradient is sampled and rescaled once per step_ratio block rather than exactly integrated), matching the shared behaviour of deepwave.elastic_vti(). The forward pass and the source/receiver-amplitude gradients are exact regardless of step_ratio.

  • storage – The storage policy for the wavefield history that the model gradient is computed from, as one object: either a mode string (“device”, “cpu”, “disk” or “none”) or a deepwave.Storage, which also carries the path and the lossy-compression flag. Defaults to “device”. This is an alternative spelling for the four individual storage_* arguments below, which remain permanently supported and are not deprecated; passing storage together with any of them raises DeepwaveValueError, because there is no honest way to merge two policies.

  • storage_mode – A string specifying the storage mode for intermediate data. One of “device”, “cpu”, “disk”, or “none”. Defaults to “device”. A permanent alias for Storage.mode; not deprecated. Compiled backend only (the eager backend requires “device”).

  • storage_path – The directory that storage_mode=”disk” writes to. A string or any os.PathLike (such as a pathlib.Path). Defaults to the system temporary directory, resolved when you call rather than when Deepwave is imported, so TMPDIR set at any point before the call is honoured. Using the default with storage_mode=”disk” emits a one-time warning naming the directory, because on many systems it is a RAM-backed tmpfs far smaller than the disk. A permanent alias for Storage.path; not deprecated.

  • storage_compression – Lossy – changes the model gradient by about 0.2-4% in 2-D and 0.2-8% in 3-D. See deepwave.elastic().

  • location_interpolation – See deepwave.elastic(). "auto" interpolates a floating-point locations Tensor only when at least one non-ignored coordinate lies more than deepwave.ON_NODE_TOLERANCE cells off its component’s grid node – except that a floating-point Tensor with requires_grad=True is always interpolated, even when every coordinate is on-node, because only the interpolated path carries gradients back to the positions. That changes the forward values for an on-node requires_grad locations Tensor relative to the same Tensor without requires_grad. Pass location_interpolation="none" for the exact path (positions are then not differentiable), or accept the band-limited values. RunInfo.location_interpolation_used records which path was taken: "none" or "hicks", or "mixed" if this propagator has several channels of one kind (several source components, say) and they did not all take the same path.

  • location_interpolation_halfwidth – See deepwave.elastic().

Returns:

a tuple subclass whose fields, in order, are:

  • vz_0: Final z-velocity wavefield (if ndim == 3).

  • vy_0: Final y-velocity wavefield.

  • vx_0: Final x-velocity wavefield.

  • sigma_v_0: Final normal stress along the symmetry axis.

  • sigma_h_0: Final normal stress across the symmetry axis.

  • auxiliary_state: A deepwave.AuxiliaryState holding the absorbing boundary’s memory variables. Opaque: pass it back (as part of initial_state) to continue the simulation; its contents are implementation state rather than physics.

  • receiver_amplitudes_p: Recorded pressure data, computed as minus the mean normal stress, -(sigma_v + (ndim - 1) sigma_h) / ndim.

  • receiver_amplitudes_z: Recorded z-velocity data (if ndim == 3).

  • receiver_amplitudes_y: Recorded y-velocity data.

  • receiver_amplitudes_x: Recorded x-velocity data.

  • receiver_amplitudes_sigma_v: Recorded normal stress along the symmetry axis.

  • receiver_amplitudes_sigma_h: Recorded normal stress across the symmetry axis.

This positional order is easy to index incorrectly; prefer accessing the fields by name instead.

Return type:

deepwave.PropagatorOutput