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
_yand_xand a 3-D run uses_z,_yand_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], wheremodel_shapehasndimentries. See Batched models.rho – The density model, of shape
[*model_shape]or, for a batched model,[n_shots, *model_shape], wheremodel_shapehasndimentries. 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_gradflags below, each of which is unset (None) by default and then meansFalse.Trueselects every model this module owns,Falseselects none, and a sequence of model names selects exactly those. Passing it together with an individual flag that was given explicitly raisesValueErrorrather 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.Parameterthat 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’srequires_gradargument or by callingmodule.<model>.requires_grad_(True)afterwards; handmodule.parameters()to atorch.optimoptimiser as usual. An optional model left asNoneis not a Parameter at all, so it appears in neitherparameters()norstate_dict(); assigning a tensor to that attribute later stores a plain tensor rather than registering a Parameter, so it stays out ofparameters()andstate_dict()(and out of any checkpoint) – give the model to the constructor, or wrap it yourself intorch.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, anddt; 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 arevolume_rate,z,y,x(zonly in 3-D,yonly in 2-D and 3-D);pis a deprecated spelling ofvolume_ratehere. Exactly equivalent to the flatsource_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 arep,z,y,x(zonly in 3-D,yonly 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, whosesource_amplitudes_pressure_rateis 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 withdeepwave.wavefields.source_field_to_sources().source_amplitudes_p – Deprecated spelling of
source_amplitudes_volume_rate, which means exactly the same thing. It warnsdeepwave.DeepwaveFutureWarningand will be removed in Deepwave 0.4.0: the letterpnames 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.premains the receiver channel’s name. Passing both raises. Optional.source_locations_volume_rate – Source locations. A point whose coordinates are all
deepwave.IGNORE_LOCATIONis ignored: it injects nothing. A point with only some coordinates set to the sentinel raises. Compare againstdeepwave.IGNORE_LOCATION; do not hard-code its value.source_locations_p – Deprecated spelling of
source_locations_volume_rate, assource_amplitudes_pis ofsource_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 att*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_LOCATIONis ignored: it injects nothing. A point with only some coordinates set to the sentinel raises. Compare againstdeepwave.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_LOCATIONis ignored: it injects nothing. A point with only some coordinates set to the sentinel raises. Compare againstdeepwave.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_LOCATIONis ignored: it injects nothing. A point with only some coordinates set to the sentinel raises. Compare againstdeepwave.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_ratechannel are active.Truemeans active;Falsemeans that point injects nothing, and its coordinates insource_locations_volume_rateare then ignored entirely (they need not be valid, in range, or unique). The shape must match the leading dimensions ofsource_locations_volume_rate, which must be given. This is the modern spelling of thedeepwave.IGNORE_LOCATIONsentinel 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 adeepwave.Hicksobject: aHickscarries its own already-resolved points, so disable points inside it by setting all of their coordinates todeepwave.IGNORE_LOCATIONin the locations it was built from. Optional.source_mask_z – A boolean torch.Tensor with dimensions [shot, source] selecting which sources of the
zchannel (3-D only) are active.Truemeans active;Falsemeans that point injects nothing, and its coordinates insource_locations_zare then ignored entirely (they need not be valid, in range, or unique). The shape must match the leading dimensions ofsource_locations_z, which must be given. This is the modern spelling of thedeepwave.IGNORE_LOCATIONsentinel 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 adeepwave.Hicksobject: aHickscarries its own already-resolved points, so disable points inside it by setting all of their coordinates todeepwave.IGNORE_LOCATIONin the locations it was built from. Optional.source_mask_y – A boolean torch.Tensor with dimensions [shot, source] selecting which sources of the
ychannel are active.Truemeans active;Falsemeans that point injects nothing, and its coordinates insource_locations_yare then ignored entirely (they need not be valid, in range, or unique). The shape must match the leading dimensions ofsource_locations_y, which must be given. This is the modern spelling of thedeepwave.IGNORE_LOCATIONsentinel 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 adeepwave.Hicksobject: aHickscarries its own already-resolved points, so disable points inside it by setting all of their coordinates todeepwave.IGNORE_LOCATIONin the locations it was built from. Optional.source_mask_x – A boolean torch.Tensor with dimensions [shot, source] selecting which sources of the
xchannel are active.Truemeans active;Falsemeans that point injects nothing, and its coordinates insource_locations_xare then ignored entirely (they need not be valid, in range, or unique). The shape must match the leading dimensions ofsource_locations_x, which must be given. This is the modern spelling of thedeepwave.IGNORE_LOCATIONsentinel 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 adeepwave.Hicksobject: aHickscarries its own already-resolved points, so disable points inside it by setting all of their coordinates todeepwave.IGNORE_LOCATIONin the locations it was built from. Optional.receiver_locations_p – Pressure receiver locations. A point whose coordinates are all
deepwave.IGNORE_LOCATIONis ignored: it records zeros. A point with only some coordinates set to the sentinel raises. Compare againstdeepwave.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_LOCATIONis ignored: it records zeros. A point with only some coordinates set to the sentinel raises. Compare againstdeepwave.IGNORE_LOCATION; do not hard-code its value.receiver_locations_y – Y-component velocity receiver locations. A point whose coordinates are all
deepwave.IGNORE_LOCATIONis ignored: it records zeros. A point with only some coordinates set to the sentinel raises. Compare againstdeepwave.IGNORE_LOCATION; do not hard-code its value.receiver_locations_x – X-component velocity receiver locations. A point whose coordinates are all
deepwave.IGNORE_LOCATIONis ignored: it records zeros. A point with only some coordinates set to the sentinel raises. Compare againstdeepwave.IGNORE_LOCATION; do not hard-code its value.receiver_mask_p – A boolean torch.Tensor with dimensions [shot, receiver] selecting which receivers of the
pchannel are active.Truemeans active;Falsemeans that point records zeros, and its coordinates inreceiver_locations_pare then ignored entirely (they need not be valid, in range, or unique). The shape must match the leading dimensions ofreceiver_locations_p, which must be given. This is the modern spelling of thedeepwave.IGNORE_LOCATIONsentinel 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 adeepwave.Hicksobject: aHickscarries its own already-resolved points, so disable points inside it by setting all of their coordinates todeepwave.IGNORE_LOCATIONin the locations it was built from. Optional.receiver_mask_z – A boolean torch.Tensor with dimensions [shot, receiver] selecting which receivers of the
zchannel (3-D only) are active.Truemeans active;Falsemeans that point records zeros, and its coordinates inreceiver_locations_zare then ignored entirely (they need not be valid, in range, or unique). The shape must match the leading dimensions ofreceiver_locations_z, which must be given. This is the modern spelling of thedeepwave.IGNORE_LOCATIONsentinel 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 adeepwave.Hicksobject: aHickscarries its own already-resolved points, so disable points inside it by setting all of their coordinates todeepwave.IGNORE_LOCATIONin the locations it was built from. Optional.receiver_mask_y – A boolean torch.Tensor with dimensions [shot, receiver] selecting which receivers of the
ychannel are active.Truemeans active;Falsemeans that point records zeros, and its coordinates inreceiver_locations_yare then ignored entirely (they need not be valid, in range, or unique). The shape must match the leading dimensions ofreceiver_locations_y, which must be given. This is the modern spelling of thedeepwave.IGNORE_LOCATIONsentinel 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 adeepwave.Hicksobject: aHickscarries its own already-resolved points, so disable points inside it by setting all of their coordinates todeepwave.IGNORE_LOCATIONin the locations it was built from. Optional.receiver_mask_x – A boolean torch.Tensor with dimensions [shot, receiver] selecting which receivers of the
xchannel are active.Truemeans active;Falsemeans that point records zeros, and its coordinates inreceiver_locations_xare then ignored entirely (they need not be valid, in range, or unique). The shape must match the leading dimensions ofreceiver_locations_x, which must be given. This is the modern spelling of thedeepwave.IGNORE_LOCATIONsentinel 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 adeepwave.Hicksobject: aHickscarries its own already-resolved points, so disable points inside it by setting all of their coordinates todeepwave.IGNORE_LOCATIONin 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 whosepml_widthis 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 withboundary(ordeepwave.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 callingdeepwave.checkpointing.run_segments()withn_segments=andcheckpoint=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, andtorch.utils.checkpointdoes not supporttorch.autograd.grad()(or aninputs=argument to.backward()) in that mode: it raises. If you needtorch.autograd.grad, calldeepwave.checkpointing.run_segments()directly withuse_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 thandeepwave.ON_NODE_TOLERANCEcells off its component’s grid node – except that a floating-point Tensor withrequires_grad=Trueis 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-noderequires_gradlocations Tensor relative to the same Tensor withoutrequires_grad. Passlocation_interpolation="none"for the exact path (positions are then not differentiable), or accept the band-limited values.RunInfo.location_interpolation_usedrecords 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
_yand_xand a 3-D run uses_z,_yand_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], wheremodel_shapehasndimentries. See Batched models.rho – The density model, of shape
[*model_shape]or, for a batched model,[n_shots, *model_shape], wheremodel_shapehasndimentries. 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, anddt; 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 arevolume_rate,z,y,x(zonly in 3-D,yonly in 2-D and 3-D);pis a deprecated spelling ofvolume_ratehere. Exactly equivalent to the flatsource_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 arep,z,y,x(zonly in 3-D,yonly 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, whosesource_amplitudes_pressure_rateis 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 withdeepwave.wavefields.source_field_to_sources().source_amplitudes_p – Deprecated spelling of
source_amplitudes_volume_rate, which means exactly the same thing. It warnsdeepwave.DeepwaveFutureWarningand will be removed in Deepwave 0.4.0: the letterpnames 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.premains the receiver channel’s name. Passing both raises. Optional.source_locations_volume_rate – Source locations. A point whose coordinates are all
deepwave.IGNORE_LOCATIONis ignored: it injects nothing. A point with only some coordinates set to the sentinel raises. Compare againstdeepwave.IGNORE_LOCATION; do not hard-code its value.source_locations_p – Deprecated spelling of
source_locations_volume_rate, assource_amplitudes_pis ofsource_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 att*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_LOCATIONis ignored: it injects nothing. A point with only some coordinates set to the sentinel raises. Compare againstdeepwave.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_LOCATIONis ignored: it injects nothing. A point with only some coordinates set to the sentinel raises. Compare againstdeepwave.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_LOCATIONis ignored: it injects nothing. A point with only some coordinates set to the sentinel raises. Compare againstdeepwave.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_ratechannel are active.Truemeans active;Falsemeans that point injects nothing, and its coordinates insource_locations_volume_rateare then ignored entirely (they need not be valid, in range, or unique). The shape must match the leading dimensions ofsource_locations_volume_rate, which must be given. This is the modern spelling of thedeepwave.IGNORE_LOCATIONsentinel 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 adeepwave.Hicksobject: aHickscarries its own already-resolved points, so disable points inside it by setting all of their coordinates todeepwave.IGNORE_LOCATIONin the locations it was built from. Optional.source_mask_z – A boolean torch.Tensor with dimensions [shot, source] selecting which sources of the
zchannel (3-D only) are active.Truemeans active;Falsemeans that point injects nothing, and its coordinates insource_locations_zare then ignored entirely (they need not be valid, in range, or unique). The shape must match the leading dimensions ofsource_locations_z, which must be given. This is the modern spelling of thedeepwave.IGNORE_LOCATIONsentinel 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 adeepwave.Hicksobject: aHickscarries its own already-resolved points, so disable points inside it by setting all of their coordinates todeepwave.IGNORE_LOCATIONin the locations it was built from. Optional.source_mask_y – A boolean torch.Tensor with dimensions [shot, source] selecting which sources of the
ychannel are active.Truemeans active;Falsemeans that point injects nothing, and its coordinates insource_locations_yare then ignored entirely (they need not be valid, in range, or unique). The shape must match the leading dimensions ofsource_locations_y, which must be given. This is the modern spelling of thedeepwave.IGNORE_LOCATIONsentinel 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 adeepwave.Hicksobject: aHickscarries its own already-resolved points, so disable points inside it by setting all of their coordinates todeepwave.IGNORE_LOCATIONin the locations it was built from. Optional.source_mask_x – A boolean torch.Tensor with dimensions [shot, source] selecting which sources of the
xchannel are active.Truemeans active;Falsemeans that point injects nothing, and its coordinates insource_locations_xare then ignored entirely (they need not be valid, in range, or unique). The shape must match the leading dimensions ofsource_locations_x, which must be given. This is the modern spelling of thedeepwave.IGNORE_LOCATIONsentinel 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 adeepwave.Hicksobject: aHickscarries its own already-resolved points, so disable points inside it by setting all of their coordinates todeepwave.IGNORE_LOCATIONin the locations it was built from. Optional.receiver_locations_p – Pressure receiver locations. A point whose coordinates are all
deepwave.IGNORE_LOCATIONis ignored: it records zeros. A point with only some coordinates set to the sentinel raises. Compare againstdeepwave.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_LOCATIONis ignored: it records zeros. A point with only some coordinates set to the sentinel raises. Compare againstdeepwave.IGNORE_LOCATION; do not hard-code its value.receiver_locations_y – Y-component velocity receiver locations. A point whose coordinates are all
deepwave.IGNORE_LOCATIONis ignored: it records zeros. A point with only some coordinates set to the sentinel raises. Compare againstdeepwave.IGNORE_LOCATION; do not hard-code its value.receiver_locations_x – X-component velocity receiver locations. A point whose coordinates are all
deepwave.IGNORE_LOCATIONis ignored: it records zeros. A point with only some coordinates set to the sentinel raises. Compare againstdeepwave.IGNORE_LOCATION; do not hard-code its value.receiver_mask_p – A boolean torch.Tensor with dimensions [shot, receiver] selecting which receivers of the
pchannel are active.Truemeans active;Falsemeans that point records zeros, and its coordinates inreceiver_locations_pare then ignored entirely (they need not be valid, in range, or unique). The shape must match the leading dimensions ofreceiver_locations_p, which must be given. This is the modern spelling of thedeepwave.IGNORE_LOCATIONsentinel 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 adeepwave.Hicksobject: aHickscarries its own already-resolved points, so disable points inside it by setting all of their coordinates todeepwave.IGNORE_LOCATIONin the locations it was built from. Optional.receiver_mask_z – A boolean torch.Tensor with dimensions [shot, receiver] selecting which receivers of the
zchannel (3-D only) are active.Truemeans active;Falsemeans that point records zeros, and its coordinates inreceiver_locations_zare then ignored entirely (they need not be valid, in range, or unique). The shape must match the leading dimensions ofreceiver_locations_z, which must be given. This is the modern spelling of thedeepwave.IGNORE_LOCATIONsentinel 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 adeepwave.Hicksobject: aHickscarries its own already-resolved points, so disable points inside it by setting all of their coordinates todeepwave.IGNORE_LOCATIONin the locations it was built from. Optional.receiver_mask_y – A boolean torch.Tensor with dimensions [shot, receiver] selecting which receivers of the
ychannel are active.Truemeans active;Falsemeans that point records zeros, and its coordinates inreceiver_locations_yare then ignored entirely (they need not be valid, in range, or unique). The shape must match the leading dimensions ofreceiver_locations_y, which must be given. This is the modern spelling of thedeepwave.IGNORE_LOCATIONsentinel 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 adeepwave.Hicksobject: aHickscarries its own already-resolved points, so disable points inside it by setting all of their coordinates todeepwave.IGNORE_LOCATIONin the locations it was built from. Optional.receiver_mask_x – A boolean torch.Tensor with dimensions [shot, receiver] selecting which receivers of the
xchannel are active.Truemeans active;Falsemeans that point records zeros, and its coordinates inreceiver_locations_xare then ignored entirely (they need not be valid, in range, or unique). The shape must match the leading dimensions ofreceiver_locations_x, which must be given. This is the modern spelling of thedeepwave.IGNORE_LOCATIONsentinel 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 adeepwave.Hicksobject: aHickscarries its own already-resolved points, so disable points inside it by setting all of their coordinates todeepwave.IGNORE_LOCATIONin 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 whosepml_widthis 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 withboundary(ordeepwave.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 callingdeepwave.checkpointing.run_segments()withn_segments=andcheckpoint=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, andtorch.utils.checkpointdoes not supporttorch.autograd.grad()(or aninputs=argument to.backward()) in that mode: it raises. If you needtorch.autograd.grad, calldeepwave.checkpointing.run_segments()directly withuse_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 thandeepwave.ON_NODE_TOLERANCEcells off its component’s grid node – except that a floating-point Tensor withrequires_grad=Trueis 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-noderequires_gradlocations Tensor relative to the same Tensor withoutrequires_grad. Passlocation_interpolation="none"for the exact path (positions are then not differentiable), or accept the band-limited values.RunInfo.location_interpolation_usedrecords 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.AuxiliaryStateholding 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:
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 eachforward()call needs only the arguments that vary between calls. As in the functionalacoustic_born(), at least one ofdv/drhomust be provided (the other defaults toNone, treated as a zero perturbation); the module defers this validation toacoustic_born()itself, which is called on everyforward().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
_yand_xand a 3-D run uses_z,_yand_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], wheremodel_shapehasndimentries. See Batched models.rho – The background density model, of shape
[*model_shape]or, for a batched model,[n_shots, *model_shape], wheremodel_shapehasndimentries. 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], wheremodel_shapehasndimentries. 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], wheremodel_shapehasndimentries. 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) andFalseselect none,Trueselects 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, raisesValueError. It is an alternative spelling for the<model>_requires_gradflags below, each of which is unset (None) by default and then meansFalse. Passing it together with an individual flag that was given explicitly raisesValueErrorrather 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.Parameterthat 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’srequires_gradargument or by callingmodule.<model>.requires_grad_(True)afterwards; handmodule.parameters()to atorch.optimoptimiser as usual. An optional model left asNoneis not a Parameter at all, so it appears in neitherparameters()norstate_dict(); assigning a tensor to that attribute later stores a plain tensor rather than registering a Parameter, so it stays out ofparameters()andstate_dict()(and out of any checkpoint) – give the model to the constructor, or wrap it yourself intorch.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-ownedv/rho/dv/drho/grid_spacingand the storage settings are supplied from the stored module state).- Parameters:
dt – Time step interval. See
deepwave.acoustic()for the unit-consistency requirement acrossv/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 arevolume_rate,z,y,x(zonly in 3-D,yonly in 2-D and 3-D); these are equivalent to the flatsource_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 arep,z,y,x(zonly in 3-D,yonly 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 asreceivers’. 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 withdeepwave.wavefields.source_field_to_sources().source_locations_volume_rate – Source locations, as in
deepwave.acoustic(). A point whose coordinates are alldeepwave.IGNORE_LOCATIONis ignored: it injects nothing. A point with only some coordinates set to the sentinel raises. Compare againstdeepwave.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 alldeepwave.IGNORE_LOCATIONis ignored: it injects nothing. A point with only some coordinates set to the sentinel raises. Compare againstdeepwave.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 alldeepwave.IGNORE_LOCATIONis ignored: it injects nothing. A point with only some coordinates set to the sentinel raises. Compare againstdeepwave.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 alldeepwave.IGNORE_LOCATIONis ignored: it injects nothing. A point with only some coordinates set to the sentinel raises. Compare againstdeepwave.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_ratechannel are active.Truemeans active;Falsemeans that point injects nothing, and its coordinates insource_locations_volume_rateare then ignored entirely (they need not be valid, in range, or unique). The shape must match the leading dimensions ofsource_locations_volume_rate, which must be given. This is the modern spelling of thedeepwave.IGNORE_LOCATIONsentinel 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 adeepwave.Hicksobject: aHickscarries its own already-resolved points, so disable points inside it by setting all of their coordinates todeepwave.IGNORE_LOCATIONin the locations it was built from. Optional.source_mask_z – A boolean torch.Tensor with dimensions [shot, source] selecting which sources of the
zchannel (3-D only) are active.Truemeans active;Falsemeans that point injects nothing, and its coordinates insource_locations_zare then ignored entirely (they need not be valid, in range, or unique). The shape must match the leading dimensions ofsource_locations_z, which must be given. This is the modern spelling of thedeepwave.IGNORE_LOCATIONsentinel 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 adeepwave.Hicksobject: aHickscarries its own already-resolved points, so disable points inside it by setting all of their coordinates todeepwave.IGNORE_LOCATIONin the locations it was built from. Optional.source_mask_y – A boolean torch.Tensor with dimensions [shot, source] selecting which sources of the
ychannel are active.Truemeans active;Falsemeans that point injects nothing, and its coordinates insource_locations_yare then ignored entirely (they need not be valid, in range, or unique). The shape must match the leading dimensions ofsource_locations_y, which must be given. This is the modern spelling of thedeepwave.IGNORE_LOCATIONsentinel 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 adeepwave.Hicksobject: aHickscarries its own already-resolved points, so disable points inside it by setting all of their coordinates todeepwave.IGNORE_LOCATIONin the locations it was built from. Optional.source_mask_x – A boolean torch.Tensor with dimensions [shot, source] selecting which sources of the
xchannel are active.Truemeans active;Falsemeans that point injects nothing, and its coordinates insource_locations_xare then ignored entirely (they need not be valid, in range, or unique). The shape must match the leading dimensions ofsource_locations_x, which must be given. This is the modern spelling of thedeepwave.IGNORE_LOCATIONsentinel 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 adeepwave.Hicksobject: aHickscarries its own already-resolved points, so disable points inside it by setting all of their coordinates todeepwave.IGNORE_LOCATIONin 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_LOCATIONis ignored: it records zeros. A point with only some coordinates set to the sentinel raises. Compare againstdeepwave.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_LOCATIONis ignored: it records zeros. A point with only some coordinates set to the sentinel raises. Compare againstdeepwave.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_LOCATIONis ignored: it records zeros. A point with only some coordinates set to the sentinel raises. Compare againstdeepwave.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_LOCATIONis ignored: it records zeros. A point with only some coordinates set to the sentinel raises. Compare againstdeepwave.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
pchannel are active.Truemeans active;Falsemeans that point records zeros, and its coordinates insc_receiver_locations_pare then ignored entirely (they need not be valid, in range, or unique). The shape must match the leading dimensions ofsc_receiver_locations_p, which must be given. This is the modern spelling of thedeepwave.IGNORE_LOCATIONsentinel 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 adeepwave.Hicksobject: aHickscarries its own already-resolved points, so disable points inside it by setting all of their coordinates todeepwave.IGNORE_LOCATIONin the locations it was built from. Optional.sc_receiver_mask_z – A boolean torch.Tensor with dimensions [shot, receiver] selecting which receivers of the
zchannel (3-D only) are active.Truemeans active;Falsemeans that point records zeros, and its coordinates insc_receiver_locations_zare then ignored entirely (they need not be valid, in range, or unique). The shape must match the leading dimensions ofsc_receiver_locations_z, which must be given. This is the modern spelling of thedeepwave.IGNORE_LOCATIONsentinel 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 adeepwave.Hicksobject: aHickscarries its own already-resolved points, so disable points inside it by setting all of their coordinates todeepwave.IGNORE_LOCATIONin the locations it was built from. Optional.sc_receiver_mask_y – A boolean torch.Tensor with dimensions [shot, receiver] selecting which receivers of the
ychannel are active.Truemeans active;Falsemeans that point records zeros, and its coordinates insc_receiver_locations_yare then ignored entirely (they need not be valid, in range, or unique). The shape must match the leading dimensions ofsc_receiver_locations_y, which must be given. This is the modern spelling of thedeepwave.IGNORE_LOCATIONsentinel 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 adeepwave.Hicksobject: aHickscarries its own already-resolved points, so disable points inside it by setting all of their coordinates todeepwave.IGNORE_LOCATIONin the locations it was built from. Optional.sc_receiver_mask_x – A boolean torch.Tensor with dimensions [shot, receiver] selecting which receivers of the
xchannel are active.Truemeans active;Falsemeans that point records zeros, and its coordinates insc_receiver_locations_xare then ignored entirely (they need not be valid, in range, or unique). The shape must match the leading dimensions ofsc_receiver_locations_x, which must be given. This is the modern spelling of thedeepwave.IGNORE_LOCATIONsentinel 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 adeepwave.Hicksobject: aHickscarries its own already-resolved points, so disable points inside it by setting all of their coordinates todeepwave.IGNORE_LOCATIONin 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_LOCATIONis ignored: it records zeros. A point with only some coordinates set to the sentinel raises. Compare againstdeepwave.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_LOCATIONis ignored: it records zeros. A point with only some coordinates set to the sentinel raises. Compare againstdeepwave.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_LOCATIONis ignored: it records zeros. A point with only some coordinates set to the sentinel raises. Compare againstdeepwave.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_LOCATIONis ignored: it records zeros. A point with only some coordinates set to the sentinel raises. Compare againstdeepwave.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
pchannel recording the background wavefield are active.Truemeans active;Falsemeans that point records zeros, and its coordinates inbg_receiver_locations_pare then ignored entirely (they need not be valid, in range, or unique). The shape must match the leading dimensions ofbg_receiver_locations_p, which must be given. This is the modern spelling of thedeepwave.IGNORE_LOCATIONsentinel 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 adeepwave.Hicksobject: aHickscarries its own already-resolved points, so disable points inside it by setting all of their coordinates todeepwave.IGNORE_LOCATIONin the locations it was built from. Optional.bg_receiver_mask_z – A boolean torch.Tensor with dimensions [shot, receiver] selecting which receivers of the
zchannel (3-D only) recording the background wavefield are active.Truemeans active;Falsemeans that point records zeros, and its coordinates inbg_receiver_locations_zare then ignored entirely (they need not be valid, in range, or unique). The shape must match the leading dimensions ofbg_receiver_locations_z, which must be given. This is the modern spelling of thedeepwave.IGNORE_LOCATIONsentinel 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 adeepwave.Hicksobject: aHickscarries its own already-resolved points, so disable points inside it by setting all of their coordinates todeepwave.IGNORE_LOCATIONin the locations it was built from. Optional.bg_receiver_mask_y – A boolean torch.Tensor with dimensions [shot, receiver] selecting which receivers of the
ychannel recording the background wavefield are active.Truemeans active;Falsemeans that point records zeros, and its coordinates inbg_receiver_locations_yare then ignored entirely (they need not be valid, in range, or unique). The shape must match the leading dimensions ofbg_receiver_locations_y, which must be given. This is the modern spelling of thedeepwave.IGNORE_LOCATIONsentinel 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 adeepwave.Hicksobject: aHickscarries its own already-resolved points, so disable points inside it by setting all of their coordinates todeepwave.IGNORE_LOCATIONin the locations it was built from. Optional.bg_receiver_mask_x – A boolean torch.Tensor with dimensions [shot, receiver] selecting which receivers of the
xchannel recording the background wavefield are active.Truemeans active;Falsemeans that point records zeros, and its coordinates inbg_receiver_locations_xare then ignored entirely (they need not be valid, in range, or unique). The shape must match the leading dimensions ofbg_receiver_locations_x, which must be given. This is the modern spelling of thedeepwave.IGNORE_LOCATIONsentinel 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 adeepwave.Hicksobject: aHickscarries its own already-resolved points, so disable points inside it by setting all of their coordinates todeepwave.IGNORE_LOCATIONin 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 whosepml_widthis 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 withboundary(ordeepwave.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 whatdeepwave.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, raisedeepwave.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 ofdeepwave.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 callingdeepwave.checkpointing.run_segments()withn_segments=andcheckpoint=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, andtorch.utils.checkpointdoes not supporttorch.autograd.grad()(or aninputs=argument to.backward()) in that mode: it raises. If you needtorch.autograd.grad, calldeepwave.checkpointing.run_segments()directly withuse_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 thandeepwave.ON_NODE_TOLERANCEcells off its component’s grid node – except that a floating-point Tensor withrequires_grad=Trueis 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-noderequires_gradlocations Tensor relative to the same Tensor withoutrequires_grad. Passlocation_interpolation="none"for the exact path (positions are then not differentiable), or accept the band-limited values.RunInfo.location_interpolation_usedrecords 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 perturbationsdv,drho, driven by virtual sources built from the constitutive perturbationsdK = 2 rho v dv + v**2 drhoanddB_d = -d(rho_avg_d)/rho_avg_d**2(seedocs/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 bydt*K/dt*B_d); the scattered field is automatically driven by the same amplitudes scaled bydt*dK/dt*dB_d– the “source-cell” term that arises because that scaling is itself model-dependent (mirrorsdeepwave.scalar_born()’s single sharedsource_amplitudes). No separate scattered-source argument is needed or accepted.Backend note.
torch.functransforms (vmap, forward-modejvp) and higher-order derivatives are not available on the default compiled backend, but the pure-PyTorchbackend="eager"driver runs under native autograd and composes with them (vmapover 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
_yand_xand a 3-D run uses_z,_yand_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], wheremodel_shapehasndimentries. See Batched models.rho – The background density model, of shape
[*model_shape]or, for a batched model,[n_shots, *model_shape], wheremodel_shapehasndimentries. See Batched models.grid_spacing – Spatial grid cell size.
dt – Time step interval. See
deepwave.acoustic()for the unit-consistency requirement acrossv/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], wheremodel_shapehasndimentries. See Batched models. At least one ofdv/drhomust be provided.drho – The density scattering perturbation model (
None-> zero), of shape[*model_shape]or, for a batched model,[n_shots, *model_shape], wheremodel_shapehasndimentries. 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 arevolume_rate,z,y,x(zonly in 3-D,yonly in 2-D and 3-D); these are equivalent to the flatsource_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 arep,z,y,x(zonly in 3-D,yonly 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 asreceivers’. 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 withdeepwave.wavefields.source_field_to_sources().source_locations_volume_rate – Source locations, as in
deepwave.acoustic(). A point whose coordinates are alldeepwave.IGNORE_LOCATIONis ignored: it injects nothing. A point with only some coordinates set to the sentinel raises. Compare againstdeepwave.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 alldeepwave.IGNORE_LOCATIONis ignored: it injects nothing. A point with only some coordinates set to the sentinel raises. Compare againstdeepwave.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 alldeepwave.IGNORE_LOCATIONis ignored: it injects nothing. A point with only some coordinates set to the sentinel raises. Compare againstdeepwave.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 alldeepwave.IGNORE_LOCATIONis ignored: it injects nothing. A point with only some coordinates set to the sentinel raises. Compare againstdeepwave.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_ratechannel are active.Truemeans active;Falsemeans that point injects nothing, and its coordinates insource_locations_volume_rateare then ignored entirely (they need not be valid, in range, or unique). The shape must match the leading dimensions ofsource_locations_volume_rate, which must be given. This is the modern spelling of thedeepwave.IGNORE_LOCATIONsentinel 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 adeepwave.Hicksobject: aHickscarries its own already-resolved points, so disable points inside it by setting all of their coordinates todeepwave.IGNORE_LOCATIONin the locations it was built from. Optional.source_mask_z – A boolean torch.Tensor with dimensions [shot, source] selecting which sources of the
zchannel (3-D only) are active.Truemeans active;Falsemeans that point injects nothing, and its coordinates insource_locations_zare then ignored entirely (they need not be valid, in range, or unique). The shape must match the leading dimensions ofsource_locations_z, which must be given. This is the modern spelling of thedeepwave.IGNORE_LOCATIONsentinel 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 adeepwave.Hicksobject: aHickscarries its own already-resolved points, so disable points inside it by setting all of their coordinates todeepwave.IGNORE_LOCATIONin the locations it was built from. Optional.source_mask_y – A boolean torch.Tensor with dimensions [shot, source] selecting which sources of the
ychannel are active.Truemeans active;Falsemeans that point injects nothing, and its coordinates insource_locations_yare then ignored entirely (they need not be valid, in range, or unique). The shape must match the leading dimensions ofsource_locations_y, which must be given. This is the modern spelling of thedeepwave.IGNORE_LOCATIONsentinel 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 adeepwave.Hicksobject: aHickscarries its own already-resolved points, so disable points inside it by setting all of their coordinates todeepwave.IGNORE_LOCATIONin the locations it was built from. Optional.source_mask_x – A boolean torch.Tensor with dimensions [shot, source] selecting which sources of the
xchannel are active.Truemeans active;Falsemeans that point injects nothing, and its coordinates insource_locations_xare then ignored entirely (they need not be valid, in range, or unique). The shape must match the leading dimensions ofsource_locations_x, which must be given. This is the modern spelling of thedeepwave.IGNORE_LOCATIONsentinel 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 adeepwave.Hicksobject: aHickscarries its own already-resolved points, so disable points inside it by setting all of their coordinates todeepwave.IGNORE_LOCATIONin 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_LOCATIONis ignored: it records zeros. A point with only some coordinates set to the sentinel raises. Compare againstdeepwave.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_LOCATIONis ignored: it records zeros. A point with only some coordinates set to the sentinel raises. Compare againstdeepwave.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_LOCATIONis ignored: it records zeros. A point with only some coordinates set to the sentinel raises. Compare againstdeepwave.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_LOCATIONis ignored: it records zeros. A point with only some coordinates set to the sentinel raises. Compare againstdeepwave.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
pchannel are active.Truemeans active;Falsemeans that point records zeros, and its coordinates insc_receiver_locations_pare then ignored entirely (they need not be valid, in range, or unique). The shape must match the leading dimensions ofsc_receiver_locations_p, which must be given. This is the modern spelling of thedeepwave.IGNORE_LOCATIONsentinel 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 adeepwave.Hicksobject: aHickscarries its own already-resolved points, so disable points inside it by setting all of their coordinates todeepwave.IGNORE_LOCATIONin the locations it was built from. Optional.sc_receiver_mask_z – A boolean torch.Tensor with dimensions [shot, receiver] selecting which receivers of the
zchannel (3-D only) are active.Truemeans active;Falsemeans that point records zeros, and its coordinates insc_receiver_locations_zare then ignored entirely (they need not be valid, in range, or unique). The shape must match the leading dimensions ofsc_receiver_locations_z, which must be given. This is the modern spelling of thedeepwave.IGNORE_LOCATIONsentinel 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 adeepwave.Hicksobject: aHickscarries its own already-resolved points, so disable points inside it by setting all of their coordinates todeepwave.IGNORE_LOCATIONin the locations it was built from. Optional.sc_receiver_mask_y – A boolean torch.Tensor with dimensions [shot, receiver] selecting which receivers of the
ychannel are active.Truemeans active;Falsemeans that point records zeros, and its coordinates insc_receiver_locations_yare then ignored entirely (they need not be valid, in range, or unique). The shape must match the leading dimensions ofsc_receiver_locations_y, which must be given. This is the modern spelling of thedeepwave.IGNORE_LOCATIONsentinel 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 adeepwave.Hicksobject: aHickscarries its own already-resolved points, so disable points inside it by setting all of their coordinates todeepwave.IGNORE_LOCATIONin the locations it was built from. Optional.sc_receiver_mask_x – A boolean torch.Tensor with dimensions [shot, receiver] selecting which receivers of the
xchannel are active.Truemeans active;Falsemeans that point records zeros, and its coordinates insc_receiver_locations_xare then ignored entirely (they need not be valid, in range, or unique). The shape must match the leading dimensions ofsc_receiver_locations_x, which must be given. This is the modern spelling of thedeepwave.IGNORE_LOCATIONsentinel 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 adeepwave.Hicksobject: aHickscarries its own already-resolved points, so disable points inside it by setting all of their coordinates todeepwave.IGNORE_LOCATIONin 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_LOCATIONis ignored: it records zeros. A point with only some coordinates set to the sentinel raises. Compare againstdeepwave.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_LOCATIONis ignored: it records zeros. A point with only some coordinates set to the sentinel raises. Compare againstdeepwave.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_LOCATIONis ignored: it records zeros. A point with only some coordinates set to the sentinel raises. Compare againstdeepwave.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_LOCATIONis ignored: it records zeros. A point with only some coordinates set to the sentinel raises. Compare againstdeepwave.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
pchannel recording the background wavefield are active.Truemeans active;Falsemeans that point records zeros, and its coordinates inbg_receiver_locations_pare then ignored entirely (they need not be valid, in range, or unique). The shape must match the leading dimensions ofbg_receiver_locations_p, which must be given. This is the modern spelling of thedeepwave.IGNORE_LOCATIONsentinel 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 adeepwave.Hicksobject: aHickscarries its own already-resolved points, so disable points inside it by setting all of their coordinates todeepwave.IGNORE_LOCATIONin the locations it was built from. Optional.bg_receiver_mask_z – A boolean torch.Tensor with dimensions [shot, receiver] selecting which receivers of the
zchannel (3-D only) recording the background wavefield are active.Truemeans active;Falsemeans that point records zeros, and its coordinates inbg_receiver_locations_zare then ignored entirely (they need not be valid, in range, or unique). The shape must match the leading dimensions ofbg_receiver_locations_z, which must be given. This is the modern spelling of thedeepwave.IGNORE_LOCATIONsentinel 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 adeepwave.Hicksobject: aHickscarries its own already-resolved points, so disable points inside it by setting all of their coordinates todeepwave.IGNORE_LOCATIONin the locations it was built from. Optional.bg_receiver_mask_y – A boolean torch.Tensor with dimensions [shot, receiver] selecting which receivers of the
ychannel recording the background wavefield are active.Truemeans active;Falsemeans that point records zeros, and its coordinates inbg_receiver_locations_yare then ignored entirely (they need not be valid, in range, or unique). The shape must match the leading dimensions ofbg_receiver_locations_y, which must be given. This is the modern spelling of thedeepwave.IGNORE_LOCATIONsentinel 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 adeepwave.Hicksobject: aHickscarries its own already-resolved points, so disable points inside it by setting all of their coordinates todeepwave.IGNORE_LOCATIONin the locations it was built from. Optional.bg_receiver_mask_x – A boolean torch.Tensor with dimensions [shot, receiver] selecting which receivers of the
xchannel recording the background wavefield are active.Truemeans active;Falsemeans that point records zeros, and its coordinates inbg_receiver_locations_xare then ignored entirely (they need not be valid, in range, or unique). The shape must match the leading dimensions ofbg_receiver_locations_x, which must be given. This is the modern spelling of thedeepwave.IGNORE_LOCATIONsentinel 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 adeepwave.Hicksobject: aHickscarries its own already-resolved points, so disable points inside it by setting all of their coordinates todeepwave.IGNORE_LOCATIONin 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 whosepml_widthis 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 withboundary(ordeepwave.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 whatdeepwave.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, raisedeepwave.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 ofdeepwave.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 callingdeepwave.checkpointing.run_segments()withn_segments=andcheckpoint=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, andtorch.utils.checkpointdoes not supporttorch.autograd.grad()(or aninputs=argument to.backward()) in that mode: it raises. If you needtorch.autograd.grad, calldeepwave.checkpointing.run_segments()directly withuse_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 thandeepwave.ON_NODE_TOLERANCEcells off its component’s grid node – except that a floating-point Tensor withrequires_grad=Trueis 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-noderequires_gradlocations Tensor relative to the same Tensor withoutrequires_grad. Passlocation_interpolation="none"for the exact path (positions are then not differentiable), or accept the band-limited values.RunInfo.location_interpolation_usedrecords 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.AuxiliaryStateholding 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:
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,qandgrid_spacingonce, so that eachforward()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
_yand_xand a 3-D run uses_z,_yand_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], wheremodel_shapehasndimentries. See Batched models.rho – The density model, of shape
[*model_shape]or, for a batched model,[n_shots, *model_shape], wheremodel_shapehasndimentries. 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], wheremodel_shapehasndimentries. 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) andFalseselect none,Trueselects 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, raisesValueError. It is an alternative spelling for the<model>_requires_gradflags below, each of which is unset (None) by default and then meansFalse. Passing it together with an individual flag that was given explicitly raisesValueErrorrather 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.Parameterthat 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’srequires_gradargument or by callingmodule.<model>.requires_grad_(True)afterwards; handmodule.parameters()to atorch.optimoptimiser as usual. An optional model left asNoneis not a Parameter at all, so it appears in neitherparameters()norstate_dict(); assigning a tensor to that attribute later stores a plain tensor rather than registering a Parameter, so it stays out ofparameters()andstate_dict()(and out of any checkpoint) – give the model to the constructor, or wrap it yourself intorch.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, anddt(q/q_freqhave 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 arepressure_rate,z,y,x(zonly in 3-D,yonly in 2-D and 3-D); these are equivalent to the flatsource_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 arep,z,y,x(zonly in 3-D,yonly 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 * amplitudedirectly 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 sourcesource_amplitudes_volume_rateby multiplying it byK = 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_LOCATIONis ignored: it injects nothing. A point with only some coordinates set to the sentinel raises. Compare againstdeepwave.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_LOCATIONis ignored: it injects nothing. A point with only some coordinates set to the sentinel raises. Compare againstdeepwave.IGNORE_LOCATION; do not hard-code its value.source_locations_y – Y-force source locations. A point whose coordinates are all
deepwave.IGNORE_LOCATIONis ignored: it injects nothing. A point with only some coordinates set to the sentinel raises. Compare againstdeepwave.IGNORE_LOCATION; do not hard-code its value.source_locations_x – X-force source locations. A point whose coordinates are all
deepwave.IGNORE_LOCATIONis ignored: it injects nothing. A point with only some coordinates set to the sentinel raises. Compare againstdeepwave.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_ratechannel are active.Truemeans active;Falsemeans that point injects nothing, and its coordinates insource_locations_pressure_rateare then ignored entirely (they need not be valid, in range, or unique). The shape must match the leading dimensions ofsource_locations_pressure_rate, which must be given. This is the modern spelling of thedeepwave.IGNORE_LOCATIONsentinel 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 adeepwave.Hicksobject: aHickscarries its own already-resolved points, so disable points inside it by setting all of their coordinates todeepwave.IGNORE_LOCATIONin the locations it was built from. Optional.source_mask_z – A boolean torch.Tensor with dimensions [shot, source] selecting which sources of the
zchannel (3-D only) are active.Truemeans active;Falsemeans that point injects nothing, and its coordinates insource_locations_zare then ignored entirely (they need not be valid, in range, or unique). The shape must match the leading dimensions ofsource_locations_z, which must be given. This is the modern spelling of thedeepwave.IGNORE_LOCATIONsentinel 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 adeepwave.Hicksobject: aHickscarries its own already-resolved points, so disable points inside it by setting all of their coordinates todeepwave.IGNORE_LOCATIONin the locations it was built from. Optional.source_mask_y – A boolean torch.Tensor with dimensions [shot, source] selecting which sources of the
ychannel are active.Truemeans active;Falsemeans that point injects nothing, and its coordinates insource_locations_yare then ignored entirely (they need not be valid, in range, or unique). The shape must match the leading dimensions ofsource_locations_y, which must be given. This is the modern spelling of thedeepwave.IGNORE_LOCATIONsentinel 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 adeepwave.Hicksobject: aHickscarries its own already-resolved points, so disable points inside it by setting all of their coordinates todeepwave.IGNORE_LOCATIONin the locations it was built from. Optional.source_mask_x – A boolean torch.Tensor with dimensions [shot, source] selecting which sources of the
xchannel are active.Truemeans active;Falsemeans that point injects nothing, and its coordinates insource_locations_xare then ignored entirely (they need not be valid, in range, or unique). The shape must match the leading dimensions ofsource_locations_x, which must be given. This is the modern spelling of thedeepwave.IGNORE_LOCATIONsentinel 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 adeepwave.Hicksobject: aHickscarries its own already-resolved points, so disable points inside it by setting all of their coordinates todeepwave.IGNORE_LOCATIONin the locations it was built from. Optional.receiver_locations_p – Pressure receiver locations. A point whose coordinates are all
deepwave.IGNORE_LOCATIONis ignored: it records zeros. A point with only some coordinates set to the sentinel raises. Compare againstdeepwave.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_LOCATIONis ignored: it records zeros. A point with only some coordinates set to the sentinel raises. Compare againstdeepwave.IGNORE_LOCATION; do not hard-code its value.receiver_locations_y – Y-velocity receiver locations. A point whose coordinates are all
deepwave.IGNORE_LOCATIONis ignored: it records zeros. A point with only some coordinates set to the sentinel raises. Compare againstdeepwave.IGNORE_LOCATION; do not hard-code its value.receiver_locations_x – X-velocity receiver locations. A point whose coordinates are all
deepwave.IGNORE_LOCATIONis ignored: it records zeros. A point with only some coordinates set to the sentinel raises. Compare againstdeepwave.IGNORE_LOCATION; do not hard-code its value.receiver_mask_p – A boolean torch.Tensor with dimensions [shot, receiver] selecting which receivers of the
pchannel are active.Truemeans active;Falsemeans that point records zeros, and its coordinates inreceiver_locations_pare then ignored entirely (they need not be valid, in range, or unique). The shape must match the leading dimensions ofreceiver_locations_p, which must be given. This is the modern spelling of thedeepwave.IGNORE_LOCATIONsentinel 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 adeepwave.Hicksobject: aHickscarries its own already-resolved points, so disable points inside it by setting all of their coordinates todeepwave.IGNORE_LOCATIONin the locations it was built from. Optional.receiver_mask_z – A boolean torch.Tensor with dimensions [shot, receiver] selecting which receivers of the
zchannel (3-D only) are active.Truemeans active;Falsemeans that point records zeros, and its coordinates inreceiver_locations_zare then ignored entirely (they need not be valid, in range, or unique). The shape must match the leading dimensions ofreceiver_locations_z, which must be given. This is the modern spelling of thedeepwave.IGNORE_LOCATIONsentinel 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 adeepwave.Hicksobject: aHickscarries its own already-resolved points, so disable points inside it by setting all of their coordinates todeepwave.IGNORE_LOCATIONin the locations it was built from. Optional.receiver_mask_y – A boolean torch.Tensor with dimensions [shot, receiver] selecting which receivers of the
ychannel are active.Truemeans active;Falsemeans that point records zeros, and its coordinates inreceiver_locations_yare then ignored entirely (they need not be valid, in range, or unique). The shape must match the leading dimensions ofreceiver_locations_y, which must be given. This is the modern spelling of thedeepwave.IGNORE_LOCATIONsentinel 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 adeepwave.Hicksobject: aHickscarries its own already-resolved points, so disable points inside it by setting all of their coordinates todeepwave.IGNORE_LOCATIONin the locations it was built from. Optional.receiver_mask_x – A boolean torch.Tensor with dimensions [shot, receiver] selecting which receivers of the
xchannel are active.Truemeans active;Falsemeans that point records zeros, and its coordinates inreceiver_locations_xare then ignored entirely (they need not be valid, in range, or unique). The shape must match the leading dimensions ofreceiver_locations_x, which must be given. This is the modern spelling of thedeepwave.IGNORE_LOCATIONsentinel 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 adeepwave.Hicksobject: aHickscarries its own already-resolved points, so disable points inside it by setting all of their coordinates todeepwave.IGNORE_LOCATIONin 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 whosepml_widthis 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 withboundary(ordeepwave.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, raisedeepwave.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
Qis specified, in the same units as1 / dt. Required whenq_n_mechanisms == 1(the default), and must beNonewhenq_n_mechanisms > 1, where the constant-Qfit spansq_bandinstead and no single reference frequency applies. There is no default:Qhas no meaning without the frequency it was measured at, and it is never taken frompml_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_bandmust beNone). Forq_n_mechanisms > 1,q_band=(f1, f2)is required:q_n_mechanismsrelaxation frequencies are chosen log-spaced across the band and their per-mechanism nonnegative weights are fit once in float64, independently ofq, to the weak-loss band target. Their scaling by1/qremains differentiable. The resulting passive modulus can have an actual effective Q different fromq; inspect it withdeepwave.attenuation.response(). More mechanisms do not guarantee a better fit. Each mechanism gets its own memory variable, carried inauxiliary_state, each with its own Crank-Nicolson update, summed into the pressure update.q_n_mechanisms > 1is supported on the eager backend (backend="eager") and the default compiled C/CUDA backend (aDW_GSLSkernel variant; not combinable there withstorage_compression=Trueor per-shot batched models – those combinations raiseNotImplementedErrorand work on the eager backend); the"torch_compile"mode raisesNotImplementedError.q_band –
(f1, f2)frequency band for the GSLS constant-Q fit; required whenq_n_mechanisms > 1, must beNonewhenq_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 callingdeepwave.checkpointing.run_segments()withn_segments=andcheckpoint=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, andtorch.utils.checkpointdoes not supporttorch.autograd.grad()(or aninputs=argument to.backward()) in that mode: it raises. If you needtorch.autograd.grad, calldeepwave.checkpointing.run_segments()directly withuse_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 thandeepwave.ON_NODE_TOLERANCEcells off its component’s grid node – except that a floating-point Tensor withrequires_grad=Trueis 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-noderequires_gradlocations Tensor relative to the same Tensor withoutrequires_grad. Passlocation_interpolation="none"for the exact path (positions are then not differentiable), or accept the band-limited values.RunInfo.location_interpolation_usedrecords 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
_yand_xand a 3-D run uses_z,_yand_x. See Dimension order and the axis convention.- Parameters:
v – The wavespeed model (the low-frequency / relaxed phase velocity;
K = rho v**2is the relaxed modulus), of shape[*model_shape]or, for a batched model,[n_shots, *model_shape], wheremodel_shapehasndimentries. See Batched models.rho – The density model, of shape
[*model_shape]or, for a batched model,[n_shots, *model_shape], wheremodel_shapehasndimentries. See Batched models.q – The quality factor
Qmodel at the reference angular frequencyomega0 = 2*pi*q_freq, of shape[*model_shape]or, for a batched model,[n_shots, *model_shape], wheremodel_shapehasndimentries. See Batched models. A differentiable model input. LargerQmeans weaker attenuation;Q = +infgives 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, anddt(q/q_freqhave 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 arepressure_rate,z,y,x(zonly in 3-D,yonly in 2-D and 3-D); these are equivalent to the flatsource_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 arep,z,y,x(zonly in 3-D,yonly 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 * amplitudedirectly 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 sourcesource_amplitudes_volume_rateby multiplying it byK = 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_LOCATIONis ignored: it injects nothing. A point with only some coordinates set to the sentinel raises. Compare againstdeepwave.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_LOCATIONis ignored: it injects nothing. A point with only some coordinates set to the sentinel raises. Compare againstdeepwave.IGNORE_LOCATION; do not hard-code its value.source_locations_y – Y-force source locations. A point whose coordinates are all
deepwave.IGNORE_LOCATIONis ignored: it injects nothing. A point with only some coordinates set to the sentinel raises. Compare againstdeepwave.IGNORE_LOCATION; do not hard-code its value.source_locations_x – X-force source locations. A point whose coordinates are all
deepwave.IGNORE_LOCATIONis ignored: it injects nothing. A point with only some coordinates set to the sentinel raises. Compare againstdeepwave.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_ratechannel are active.Truemeans active;Falsemeans that point injects nothing, and its coordinates insource_locations_pressure_rateare then ignored entirely (they need not be valid, in range, or unique). The shape must match the leading dimensions ofsource_locations_pressure_rate, which must be given. This is the modern spelling of thedeepwave.IGNORE_LOCATIONsentinel 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 adeepwave.Hicksobject: aHickscarries its own already-resolved points, so disable points inside it by setting all of their coordinates todeepwave.IGNORE_LOCATIONin the locations it was built from. Optional.source_mask_z – A boolean torch.Tensor with dimensions [shot, source] selecting which sources of the
zchannel (3-D only) are active.Truemeans active;Falsemeans that point injects nothing, and its coordinates insource_locations_zare then ignored entirely (they need not be valid, in range, or unique). The shape must match the leading dimensions ofsource_locations_z, which must be given. This is the modern spelling of thedeepwave.IGNORE_LOCATIONsentinel 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 adeepwave.Hicksobject: aHickscarries its own already-resolved points, so disable points inside it by setting all of their coordinates todeepwave.IGNORE_LOCATIONin the locations it was built from. Optional.source_mask_y – A boolean torch.Tensor with dimensions [shot, source] selecting which sources of the
ychannel are active.Truemeans active;Falsemeans that point injects nothing, and its coordinates insource_locations_yare then ignored entirely (they need not be valid, in range, or unique). The shape must match the leading dimensions ofsource_locations_y, which must be given. This is the modern spelling of thedeepwave.IGNORE_LOCATIONsentinel 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 adeepwave.Hicksobject: aHickscarries its own already-resolved points, so disable points inside it by setting all of their coordinates todeepwave.IGNORE_LOCATIONin the locations it was built from. Optional.source_mask_x – A boolean torch.Tensor with dimensions [shot, source] selecting which sources of the
xchannel are active.Truemeans active;Falsemeans that point injects nothing, and its coordinates insource_locations_xare then ignored entirely (they need not be valid, in range, or unique). The shape must match the leading dimensions ofsource_locations_x, which must be given. This is the modern spelling of thedeepwave.IGNORE_LOCATIONsentinel 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 adeepwave.Hicksobject: aHickscarries its own already-resolved points, so disable points inside it by setting all of their coordinates todeepwave.IGNORE_LOCATIONin the locations it was built from. Optional.receiver_locations_p – Pressure receiver locations. A point whose coordinates are all
deepwave.IGNORE_LOCATIONis ignored: it records zeros. A point with only some coordinates set to the sentinel raises. Compare againstdeepwave.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_LOCATIONis ignored: it records zeros. A point with only some coordinates set to the sentinel raises. Compare againstdeepwave.IGNORE_LOCATION; do not hard-code its value.receiver_locations_y – Y-velocity receiver locations. A point whose coordinates are all
deepwave.IGNORE_LOCATIONis ignored: it records zeros. A point with only some coordinates set to the sentinel raises. Compare againstdeepwave.IGNORE_LOCATION; do not hard-code its value.receiver_locations_x – X-velocity receiver locations. A point whose coordinates are all
deepwave.IGNORE_LOCATIONis ignored: it records zeros. A point with only some coordinates set to the sentinel raises. Compare againstdeepwave.IGNORE_LOCATION; do not hard-code its value.receiver_mask_p – A boolean torch.Tensor with dimensions [shot, receiver] selecting which receivers of the
pchannel are active.Truemeans active;Falsemeans that point records zeros, and its coordinates inreceiver_locations_pare then ignored entirely (they need not be valid, in range, or unique). The shape must match the leading dimensions ofreceiver_locations_p, which must be given. This is the modern spelling of thedeepwave.IGNORE_LOCATIONsentinel 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 adeepwave.Hicksobject: aHickscarries its own already-resolved points, so disable points inside it by setting all of their coordinates todeepwave.IGNORE_LOCATIONin the locations it was built from. Optional.receiver_mask_z – A boolean torch.Tensor with dimensions [shot, receiver] selecting which receivers of the
zchannel (3-D only) are active.Truemeans active;Falsemeans that point records zeros, and its coordinates inreceiver_locations_zare then ignored entirely (they need not be valid, in range, or unique). The shape must match the leading dimensions ofreceiver_locations_z, which must be given. This is the modern spelling of thedeepwave.IGNORE_LOCATIONsentinel 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 adeepwave.Hicksobject: aHickscarries its own already-resolved points, so disable points inside it by setting all of their coordinates todeepwave.IGNORE_LOCATIONin the locations it was built from. Optional.receiver_mask_y – A boolean torch.Tensor with dimensions [shot, receiver] selecting which receivers of the
ychannel are active.Truemeans active;Falsemeans that point records zeros, and its coordinates inreceiver_locations_yare then ignored entirely (they need not be valid, in range, or unique). The shape must match the leading dimensions ofreceiver_locations_y, which must be given. This is the modern spelling of thedeepwave.IGNORE_LOCATIONsentinel 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 adeepwave.Hicksobject: aHickscarries its own already-resolved points, so disable points inside it by setting all of their coordinates todeepwave.IGNORE_LOCATIONin the locations it was built from. Optional.receiver_mask_x – A boolean torch.Tensor with dimensions [shot, receiver] selecting which receivers of the
xchannel are active.Truemeans active;Falsemeans that point records zeros, and its coordinates inreceiver_locations_xare then ignored entirely (they need not be valid, in range, or unique). The shape must match the leading dimensions ofreceiver_locations_x, which must be given. This is the modern spelling of thedeepwave.IGNORE_LOCATIONsentinel 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 adeepwave.Hicksobject: aHickscarries its own already-resolved points, so disable points inside it by setting all of their coordinates todeepwave.IGNORE_LOCATIONin 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 whosepml_widthis 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 withboundary(ordeepwave.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, raisedeepwave.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
Qis specified, in the same units as1 / dt. Required whenq_n_mechanisms == 1(the default), and must beNonewhenq_n_mechanisms > 1, where the constant-Qfit spansq_bandinstead and no single reference frequency applies. There is no default:Qhas no meaning without the frequency it was measured at, and it is never taken frompml_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_bandmust beNone). Forq_n_mechanisms > 1,q_band=(f1, f2)is required:q_n_mechanismsrelaxation frequencies are chosen log-spaced across the band and their per-mechanism nonnegative weights are fit once in float64, independently ofq, to the weak-loss band target. Their scaling by1/qremains differentiable. The resulting passive modulus can have an actual effective Q different fromq; inspect it withdeepwave.attenuation.response(). More mechanisms do not guarantee a better fit. Each mechanism gets its own memory variable, carried inauxiliary_state, each with its own Crank-Nicolson update, summed into the pressure update.q_n_mechanisms > 1is supported on the eager backend (backend="eager") and the default compiled C/CUDA backend (aDW_GSLSkernel variant; not combinable there withstorage_compression=Trueor per-shot batched models – those combinations raiseNotImplementedErrorand work on the eager backend); the"torch_compile"mode raisesNotImplementedError.q_band –
(f1, f2)frequency band for the GSLS constant-Q fit; required whenq_n_mechanisms > 1, must beNonewhenq_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 callingdeepwave.checkpointing.run_segments()withn_segments=andcheckpoint=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, andtorch.utils.checkpointdoes not supporttorch.autograd.grad()(or aninputs=argument to.backward()) in that mode: it raises. If you needtorch.autograd.grad, calldeepwave.checkpointing.run_segments()directly withuse_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 thandeepwave.ON_NODE_TOLERANCEcells off its component’s grid node – except that a floating-point Tensor withrequires_grad=Trueis 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-noderequires_gradlocations Tensor relative to the same Tensor withoutrequires_grad. Passlocation_interpolation="none"for the exact path (positions are then not differentiable), or accept the band-limited values.RunInfo.location_interpolation_usedrecords 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.AuxiliaryStateholding the absorbing boundary’s memory variables and the GSLS relaxation memory variables (one per mechanism). Opaque: pass it back (as part ofinitial_state) to continue the simulation; its contents are implementation state rather than physics. The field list therefore does not change withq_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:
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 astorch.nn.Parameterobjects, allowing gradients to be computed with respect to them if desired. Seeacoustic_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
_yand_xand a 3-D run uses_z,_yand_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], wheremodel_shapehasndimentries. See Batched models.c13 – The c13 stiffness model, of shape
[*model_shape]or, for a batched model,[n_shots, *model_shape], wheremodel_shapehasndimentries. See Batched models.c33 – The c33 stiffness model (vertical P modulus), of shape
[*model_shape]or, for a batched model,[n_shots, *model_shape], wheremodel_shapehasndimentries. See Batched models.buoyancy – The buoyancy (1/density) model. A cell with
buoyancy = 0is 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], wheremodel_shapehasndimentries. 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) andFalseselect none,Trueselects 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, raisesValueError. It is an alternative spelling for the<model>_requires_gradflags below, each of which is unset (None) by default and then meansFalse. Passing it together with an individual flag that was given explicitly raisesValueErrorrather 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.Parameterthat 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’srequires_gradargument or by callingmodule.<model>.requires_grad_(True)afterwards; handmodule.parameters()to atorch.optimoptimiser as usual. An optional model left asNoneis not a Parameter at all, so it appears in neitherparameters()norstate_dict(); assigning a tensor to that attribute later stores a plain tensor rather than registering a Parameter, so it stays out ofparameters()andstate_dict()(and out of any checkpoint) – give the model to the constructor, or wrap it yourself intorch.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. Seeacoustic_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, anddt; see Units and source conventions.source_amplitudes_z – Source amplitudes for the
zvelocity component (3-D only). Seedeepwave.elastic(). This channel exists only in 3-D.source_amplitudes_y – Source amplitudes for the
yvelocity component: a body-force density, assource_amplitudes_z.source_amplitudes_x – Source amplitudes for the
xvelocity component: a body-force density, assource_amplitudes_z.source_amplitudes_sigma_h – Source amplitudes for
sigma_h, the normal stress across the symmetry axis (a stress-rate source terms_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 arepressure_rate,z,y,x,sigma_v,sigma_h(zonly in 3-D); these are equivalent to the flatsource_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 arep,z,y,x,sigma_v,sigma_h(zonly 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_rateis a convenience that drives both of them at once. It is exactly equivalent to passingsource_amplitudes_sigma_v = -source_amplitudes_pressure_rateandsource_amplitudes_sigma_h = -source_amplitudes_pressure_rateatsource_locations_pressure_rateon 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’ssource_amplitudes_pressure_rate, not the acoustic family’s volume rate; see Units and source conventions. If thesigma_v/sigma_hchannels also have their own sources, these are concatenated with them along the source axis. The matchingpreceiver channel records the pressure this drives; seereceiver_locations_p. Optional; if given,source_locations_pressure_ratemust also be given.source_amplitudes_sigma_v – Source amplitudes for
sigma_v, the normal stress along the symmetry axis (a stress-rate source terms_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-positivesource_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 alldeepwave.IGNORE_LOCATIONis ignored: it injects nothing. A point with only some coordinates set to the sentinel raises. Compare againstdeepwave.IGNORE_LOCATION; do not hard-code its value.source_locations_y – See
source_locations_z. A point whose coordinates are alldeepwave.IGNORE_LOCATIONis ignored: it injects nothing. A point with only some coordinates set to the sentinel raises. Compare againstdeepwave.IGNORE_LOCATION; do not hard-code its value.source_locations_x – See
source_locations_z. A point whose coordinates are alldeepwave.IGNORE_LOCATIONis ignored: it injects nothing. A point with only some coordinates set to the sentinel raises. Compare againstdeepwave.IGNORE_LOCATION; do not hard-code its value.source_locations_pressure_rate – Integer locations of the
source_amplitudes_pressure_ratesources, with dimensions [shot, source, ndim]. Applied to both stress channels. Adeepwave.Hicksobject 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 ifsource_amplitudes_pressure_rateis given. A point whose coordinates are alldeepwave.IGNORE_LOCATIONis ignored: it injects nothing. A point with only some coordinates set to the sentinel raises. Compare againstdeepwave.IGNORE_LOCATION; do not hard-code its value.source_locations_sigma_h – Integer locations of the
sigma_hsources, the normal stress across the symmetry axis. A point whose coordinates are alldeepwave.IGNORE_LOCATIONis ignored: it injects nothing. A point with only some coordinates set to the sentinel raises. Compare againstdeepwave.IGNORE_LOCATION; do not hard-code its value.source_locations_sigma_v – Integer locations of the
sigma_vsources. A point whose coordinates are alldeepwave.IGNORE_LOCATIONis ignored: it injects nothing. A point with only some coordinates set to the sentinel raises. Compare againstdeepwave.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_ratechannel are active.Truemeans active;Falsemeans that point injects nothing, and its coordinates insource_locations_pressure_rateare then ignored entirely (they need not be valid, in range, or unique). The shape must match the leading dimensions ofsource_locations_pressure_rate, which must be given. This is the modern spelling of thedeepwave.IGNORE_LOCATIONsentinel 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 adeepwave.Hicksobject: aHickscarries its own already-resolved points, so disable points inside it by setting all of their coordinates todeepwave.IGNORE_LOCATIONin the locations it was built from. Optional.source_mask_z – A boolean torch.Tensor with dimensions [shot, source] selecting which sources of the
zchannel (3-D only) are active.Truemeans active;Falsemeans that point injects nothing, and its coordinates insource_locations_zare then ignored entirely (they need not be valid, in range, or unique). The shape must match the leading dimensions ofsource_locations_z, which must be given. This is the modern spelling of thedeepwave.IGNORE_LOCATIONsentinel 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 adeepwave.Hicksobject: aHickscarries its own already-resolved points, so disable points inside it by setting all of their coordinates todeepwave.IGNORE_LOCATIONin the locations it was built from. Optional.source_mask_y – A boolean torch.Tensor with dimensions [shot, source] selecting which sources of the
ychannel are active.Truemeans active;Falsemeans that point injects nothing, and its coordinates insource_locations_yare then ignored entirely (they need not be valid, in range, or unique). The shape must match the leading dimensions ofsource_locations_y, which must be given. This is the modern spelling of thedeepwave.IGNORE_LOCATIONsentinel 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 adeepwave.Hicksobject: aHickscarries its own already-resolved points, so disable points inside it by setting all of their coordinates todeepwave.IGNORE_LOCATIONin the locations it was built from. Optional.source_mask_x – A boolean torch.Tensor with dimensions [shot, source] selecting which sources of the
xchannel are active.Truemeans active;Falsemeans that point injects nothing, and its coordinates insource_locations_xare then ignored entirely (they need not be valid, in range, or unique). The shape must match the leading dimensions ofsource_locations_x, which must be given. This is the modern spelling of thedeepwave.IGNORE_LOCATIONsentinel 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 adeepwave.Hicksobject: aHickscarries its own already-resolved points, so disable points inside it by setting all of their coordinates todeepwave.IGNORE_LOCATIONin 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_vchannel are active.Truemeans active;Falsemeans that point injects nothing, and its coordinates insource_locations_sigma_vare then ignored entirely (they need not be valid, in range, or unique). The shape must match the leading dimensions ofsource_locations_sigma_v, which must be given. This is the modern spelling of thedeepwave.IGNORE_LOCATIONsentinel 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 adeepwave.Hicksobject: aHickscarries its own already-resolved points, so disable points inside it by setting all of their coordinates todeepwave.IGNORE_LOCATIONin 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_hchannel are active.Truemeans active;Falsemeans that point injects nothing, and its coordinates insource_locations_sigma_hare then ignored entirely (they need not be valid, in range, or unique). The shape must match the leading dimensions ofsource_locations_sigma_h, which must be given. This is the modern spelling of thedeepwave.IGNORE_LOCATIONsentinel 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 adeepwave.Hicksobject: aHickscarries its own already-resolved points, so disable points inside it by setting all of their coordinates todeepwave.IGNORE_LOCATIONin 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 alldeepwave.IGNORE_LOCATIONis ignored: it records zeros. A point with only some coordinates set to the sentinel raises. Compare againstdeepwave.IGNORE_LOCATION; do not hard-code its value.receiver_locations_y – See
source_locations_z. A point whose coordinates are alldeepwave.IGNORE_LOCATIONis ignored: it records zeros. A point with only some coordinates set to the sentinel raises. Compare againstdeepwave.IGNORE_LOCATION; do not hard-code its value.receiver_locations_x – See
source_locations_z. A point whose coordinates are alldeepwave.IGNORE_LOCATIONis ignored: it records zeros. A point with only some coordinates set to the sentinel raises. Compare againstdeepwave.IGNORE_LOCATION; do not hard-code its value.receiver_locations_sigma_h – Integer locations of
sigma_hreceivers, the normal stress across the symmetry axis. A point whose coordinates are alldeepwave.IGNORE_LOCATIONis ignored: it records zeros. A point with only some coordinates set to the sentinel raises. Compare againstdeepwave.IGNORE_LOCATION; do not hard-code its value.receiver_locations_sigma_v – Integer locations of
sigma_vreceivers, the normal stress along the symmetry axis. A point whose coordinates are alldeepwave.IGNORE_LOCATIONis ignored: it records zeros. A point with only some coordinates set to the sentinel raises. Compare againstdeepwave.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’spreceiver records, and what a hydrophone in this medium measures. It is computed by asking both stress channels for these points, so adeepwave.Hicksobject 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 alldeepwave.IGNORE_LOCATIONis 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
zchannel (3-D only) are active.Truemeans active;Falsemeans that point records zeros, and its coordinates inreceiver_locations_zare then ignored entirely (they need not be valid, in range, or unique). The shape must match the leading dimensions ofreceiver_locations_z, which must be given. This is the modern spelling of thedeepwave.IGNORE_LOCATIONsentinel 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 adeepwave.Hicksobject: aHickscarries its own already-resolved points, so disable points inside it by setting all of their coordinates todeepwave.IGNORE_LOCATIONin the locations it was built from. Optional.receiver_mask_y – A boolean torch.Tensor with dimensions [shot, receiver] selecting which receivers of the
ychannel are active.Truemeans active;Falsemeans that point records zeros, and its coordinates inreceiver_locations_yare then ignored entirely (they need not be valid, in range, or unique). The shape must match the leading dimensions ofreceiver_locations_y, which must be given. This is the modern spelling of thedeepwave.IGNORE_LOCATIONsentinel 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 adeepwave.Hicksobject: aHickscarries its own already-resolved points, so disable points inside it by setting all of their coordinates todeepwave.IGNORE_LOCATIONin the locations it was built from. Optional.receiver_mask_x – A boolean torch.Tensor with dimensions [shot, receiver] selecting which receivers of the
xchannel are active.Truemeans active;Falsemeans that point records zeros, and its coordinates inreceiver_locations_xare then ignored entirely (they need not be valid, in range, or unique). The shape must match the leading dimensions ofreceiver_locations_x, which must be given. This is the modern spelling of thedeepwave.IGNORE_LOCATIONsentinel 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 adeepwave.Hicksobject: aHickscarries its own already-resolved points, so disable points inside it by setting all of their coordinates todeepwave.IGNORE_LOCATIONin the locations it was built from. Optional.receiver_mask_p – A boolean torch.Tensor with dimensions [shot, receiver] selecting which receivers of the
pchannel are active.Truemeans active;Falsemeans that point records zeros, and its coordinates inreceiver_locations_pare then ignored entirely (they need not be valid, in range, or unique). The shape must match the leading dimensions ofreceiver_locations_p, which must be given. This is the modern spelling of thedeepwave.IGNORE_LOCATIONsentinel 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 adeepwave.Hicksobject. Optional.receiver_mask_sigma_v – A boolean torch.Tensor with dimensions [shot, receiver] selecting which receivers of the
sigma_vchannel are active.Truemeans active;Falsemeans that point records zeros, and its coordinates inreceiver_locations_sigma_vare then ignored entirely (they need not be valid, in range, or unique). The shape must match the leading dimensions ofreceiver_locations_sigma_v, which must be given. This is the modern spelling of thedeepwave.IGNORE_LOCATIONsentinel 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 adeepwave.Hicksobject: aHickscarries its own already-resolved points, so disable points inside it by setting all of their coordinates todeepwave.IGNORE_LOCATIONin 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_hchannel are active.Truemeans active;Falsemeans that point records zeros, and its coordinates inreceiver_locations_sigma_hare then ignored entirely (they need not be valid, in range, or unique). The shape must match the leading dimensions ofreceiver_locations_sigma_h, which must be given. This is the modern spelling of thedeepwave.IGNORE_LOCATIONsentinel 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 adeepwave.Hicksobject: aHickscarries its own already-resolved points, so disable points inside it by setting all of their coordinates todeepwave.IGNORE_LOCATIONin the locations it was built from. Optional.accuracy – See
deepwave.elastic(). Defaults to 4.pml_width – See
deepwave.elastic(). Defaults to 20. A face whosepml_widthis 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 withboundary(ordeepwave.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 indeepwave.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” raisedeepwave.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
zvelocity wavefield (3-D only). Seedeepwave.elastic()(and similarly for the other initial wavefields and PML memory variables).vy_0 – The initial
yvelocity wavefield.vx_0 – The initial
xvelocity 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 callingdeepwave.checkpointing.run_segments()withn_segments=andcheckpoint=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, andtorch.utils.checkpointdoes not supporttorch.autograd.grad()(or aninputs=argument to.backward()) in that mode: it raises. If you needtorch.autograd.grad, calldeepwave.checkpointing.run_segments()directly withuse_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. Atmodel_gradient_sampling_interval == 1with a courant-safedt(step_ratio == 1), model gradients (c11/c13/c33/buoyancy) match the eager backend to near machine precision; atstep_ratio > 1(from either a coarsedtormodel_gradient_sampling_interval > 1) they are a bounded, non-machine-precision approximation (the model gradient is sampled and rescaled once perstep_ratioblock rather than exactly integrated), matching the shared behaviour ofdeepwave.elastic_vti(). The forward pass and the source/receiver-amplitude gradients are exact regardless ofstep_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 thandeepwave.ON_NODE_TOLERANCEcells off its component’s grid node – except that a floating-point Tensor withrequires_grad=Trueis 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-noderequires_gradlocations Tensor relative to the same Tensor withoutrequires_grad. Passlocation_interpolation="none"for the exact path (positions are then not differentiable), or accept the band-limited values.RunInfo.location_interpolation_usedrecords 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 = 0limit 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 exactc55 = c66 = 0reduction: the two normal stressessigma_v(along the symmetry axis) andsigma_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:
zin 3-D,yin 2-D. There is no 1-D form (onlyc33would 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);
buoyancyis 1/density and is internally averaged onto the staggered velocity nodes exactly as indeepwave.elastic()(abuoyancy = 0cell, with zero stiffnesses, is a vacuum, giving a free surface). The stiffnesses relate to the vertical P velocityvpand Thomseneps/deltabyc33 = rho vp**2,c11 = c33 (1 + 2 eps),c13 = c33 sqrt(1 + 2 delta);deepwave.anisotropy.thomsen_to_cij()withvs = 0produces exactly these (itsc55output is discarded).Stability. The medium must satisfy the Grechka/Duveneck condition
c11 c33 >= c13**2(equivalentlyeps >= delta) everywhere, else the pseudo-acoustic system is ill-posed; this is validated and aValueErroris raised otherwise (eps = delta, elliptical anisotropy, is allowed and emits no pseudo-shear artifact).Pseudo-shear source artifact. Where
eps != deltaa point source also emits a spurious diamond/rhombic pseudo-shear wave (intrinsic to theV_S = 0formulation).deepwave.anisotropy.source_taper()optionally mitigates it by makingc13locally elliptical near the sources.Sources and receivers may be placed on any velocity component (
z,y,x; force-density sources, scaled internally by buoyancy anddtas indeepwave.elastic()) and on either normal stress (sigma_h,sigma_v; stress-rate sourcess_h/s_v, scaled internally bydt). An isotropic explosive/pressure source is the same wavelet applied to both thesigma_handsigma_vchannels.The compiled C/CUDA backend (
backend="compiled", and what the defaultbackend="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 thebackendArgs entry below for the model-gradientstep_ratiocaveat. 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
_yand_xand a 3-D run uses_z,_yand_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], wheremodel_shapehasndimentries. See Batched models.c13 – The c13 stiffness model, of shape
[*model_shape]or, for a batched model,[n_shots, *model_shape], wheremodel_shapehasndimentries. See Batched models.c33 – The c33 stiffness model (vertical P modulus), of shape
[*model_shape]or, for a batched model,[n_shots, *model_shape], wheremodel_shapehasndimentries. See Batched models.buoyancy – The buoyancy (1/density) model. A cell with
buoyancy = 0is 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], wheremodel_shapehasndimentries. 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, anddt; see Units and source conventions.source_amplitudes_z – Source amplitudes for the
zvelocity component (3-D only). Seedeepwave.elastic(). This channel exists only in 3-D.source_amplitudes_y – Source amplitudes for the
yvelocity component: a body-force density, assource_amplitudes_z.source_amplitudes_x – Source amplitudes for the
xvelocity component: a body-force density, assource_amplitudes_z.source_amplitudes_sigma_h – Source amplitudes for
sigma_h, the normal stress across the symmetry axis (a stress-rate source terms_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 arepressure_rate,z,y,x,sigma_v,sigma_h(zonly in 3-D); these are equivalent to the flatsource_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 arep,z,y,x,sigma_v,sigma_h(zonly 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_rateis a convenience that drives both of them at once. It is exactly equivalent to passingsource_amplitudes_sigma_v = -source_amplitudes_pressure_rateandsource_amplitudes_sigma_h = -source_amplitudes_pressure_rateatsource_locations_pressure_rateon 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’ssource_amplitudes_pressure_rate, not the acoustic family’s volume rate; see Units and source conventions. If thesigma_v/sigma_hchannels also have their own sources, these are concatenated with them along the source axis. The matchingpreceiver channel records the pressure this drives; seereceiver_locations_p. Optional; if given,source_locations_pressure_ratemust also be given.source_amplitudes_sigma_v – Source amplitudes for
sigma_v, the normal stress along the symmetry axis (a stress-rate source terms_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-positivesource_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 alldeepwave.IGNORE_LOCATIONis ignored: it injects nothing. A point with only some coordinates set to the sentinel raises. Compare againstdeepwave.IGNORE_LOCATION; do not hard-code its value.source_locations_y – See
source_locations_z. A point whose coordinates are alldeepwave.IGNORE_LOCATIONis ignored: it injects nothing. A point with only some coordinates set to the sentinel raises. Compare againstdeepwave.IGNORE_LOCATION; do not hard-code its value.source_locations_x – See
source_locations_z. A point whose coordinates are alldeepwave.IGNORE_LOCATIONis ignored: it injects nothing. A point with only some coordinates set to the sentinel raises. Compare againstdeepwave.IGNORE_LOCATION; do not hard-code its value.source_locations_pressure_rate – Integer locations of the
source_amplitudes_pressure_ratesources, with dimensions [shot, source, ndim]. Applied to both stress channels. Adeepwave.Hicksobject 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 ifsource_amplitudes_pressure_rateis given. A point whose coordinates are alldeepwave.IGNORE_LOCATIONis ignored: it injects nothing. A point with only some coordinates set to the sentinel raises. Compare againstdeepwave.IGNORE_LOCATION; do not hard-code its value.source_locations_sigma_h – Integer locations of the
sigma_hsources, the normal stress across the symmetry axis. A point whose coordinates are alldeepwave.IGNORE_LOCATIONis ignored: it injects nothing. A point with only some coordinates set to the sentinel raises. Compare againstdeepwave.IGNORE_LOCATION; do not hard-code its value.source_locations_sigma_v – Integer locations of the
sigma_vsources. A point whose coordinates are alldeepwave.IGNORE_LOCATIONis ignored: it injects nothing. A point with only some coordinates set to the sentinel raises. Compare againstdeepwave.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_ratechannel are active.Truemeans active;Falsemeans that point injects nothing, and its coordinates insource_locations_pressure_rateare then ignored entirely (they need not be valid, in range, or unique). The shape must match the leading dimensions ofsource_locations_pressure_rate, which must be given. This is the modern spelling of thedeepwave.IGNORE_LOCATIONsentinel 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 adeepwave.Hicksobject: aHickscarries its own already-resolved points, so disable points inside it by setting all of their coordinates todeepwave.IGNORE_LOCATIONin the locations it was built from. Optional.source_mask_z – A boolean torch.Tensor with dimensions [shot, source] selecting which sources of the
zchannel (3-D only) are active.Truemeans active;Falsemeans that point injects nothing, and its coordinates insource_locations_zare then ignored entirely (they need not be valid, in range, or unique). The shape must match the leading dimensions ofsource_locations_z, which must be given. This is the modern spelling of thedeepwave.IGNORE_LOCATIONsentinel 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 adeepwave.Hicksobject: aHickscarries its own already-resolved points, so disable points inside it by setting all of their coordinates todeepwave.IGNORE_LOCATIONin the locations it was built from. Optional.source_mask_y – A boolean torch.Tensor with dimensions [shot, source] selecting which sources of the
ychannel are active.Truemeans active;Falsemeans that point injects nothing, and its coordinates insource_locations_yare then ignored entirely (they need not be valid, in range, or unique). The shape must match the leading dimensions ofsource_locations_y, which must be given. This is the modern spelling of thedeepwave.IGNORE_LOCATIONsentinel 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 adeepwave.Hicksobject: aHickscarries its own already-resolved points, so disable points inside it by setting all of their coordinates todeepwave.IGNORE_LOCATIONin the locations it was built from. Optional.source_mask_x – A boolean torch.Tensor with dimensions [shot, source] selecting which sources of the
xchannel are active.Truemeans active;Falsemeans that point injects nothing, and its coordinates insource_locations_xare then ignored entirely (they need not be valid, in range, or unique). The shape must match the leading dimensions ofsource_locations_x, which must be given. This is the modern spelling of thedeepwave.IGNORE_LOCATIONsentinel 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 adeepwave.Hicksobject: aHickscarries its own already-resolved points, so disable points inside it by setting all of their coordinates todeepwave.IGNORE_LOCATIONin 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_vchannel are active.Truemeans active;Falsemeans that point injects nothing, and its coordinates insource_locations_sigma_vare then ignored entirely (they need not be valid, in range, or unique). The shape must match the leading dimensions ofsource_locations_sigma_v, which must be given. This is the modern spelling of thedeepwave.IGNORE_LOCATIONsentinel 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 adeepwave.Hicksobject: aHickscarries its own already-resolved points, so disable points inside it by setting all of their coordinates todeepwave.IGNORE_LOCATIONin 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_hchannel are active.Truemeans active;Falsemeans that point injects nothing, and its coordinates insource_locations_sigma_hare then ignored entirely (they need not be valid, in range, or unique). The shape must match the leading dimensions ofsource_locations_sigma_h, which must be given. This is the modern spelling of thedeepwave.IGNORE_LOCATIONsentinel 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 adeepwave.Hicksobject: aHickscarries its own already-resolved points, so disable points inside it by setting all of their coordinates todeepwave.IGNORE_LOCATIONin 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 alldeepwave.IGNORE_LOCATIONis ignored: it records zeros. A point with only some coordinates set to the sentinel raises. Compare againstdeepwave.IGNORE_LOCATION; do not hard-code its value.receiver_locations_y – See
source_locations_z. A point whose coordinates are alldeepwave.IGNORE_LOCATIONis ignored: it records zeros. A point with only some coordinates set to the sentinel raises. Compare againstdeepwave.IGNORE_LOCATION; do not hard-code its value.receiver_locations_x – See
source_locations_z. A point whose coordinates are alldeepwave.IGNORE_LOCATIONis ignored: it records zeros. A point with only some coordinates set to the sentinel raises. Compare againstdeepwave.IGNORE_LOCATION; do not hard-code its value.receiver_locations_sigma_h – Integer locations of
sigma_hreceivers, the normal stress across the symmetry axis. A point whose coordinates are alldeepwave.IGNORE_LOCATIONis ignored: it records zeros. A point with only some coordinates set to the sentinel raises. Compare againstdeepwave.IGNORE_LOCATION; do not hard-code its value.receiver_locations_sigma_v – Integer locations of
sigma_vreceivers, the normal stress along the symmetry axis. A point whose coordinates are alldeepwave.IGNORE_LOCATIONis ignored: it records zeros. A point with only some coordinates set to the sentinel raises. Compare againstdeepwave.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’spreceiver records, and what a hydrophone in this medium measures. It is computed by asking both stress channels for these points, so adeepwave.Hicksobject 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 alldeepwave.IGNORE_LOCATIONis 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
zchannel (3-D only) are active.Truemeans active;Falsemeans that point records zeros, and its coordinates inreceiver_locations_zare then ignored entirely (they need not be valid, in range, or unique). The shape must match the leading dimensions ofreceiver_locations_z, which must be given. This is the modern spelling of thedeepwave.IGNORE_LOCATIONsentinel 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 adeepwave.Hicksobject: aHickscarries its own already-resolved points, so disable points inside it by setting all of their coordinates todeepwave.IGNORE_LOCATIONin the locations it was built from. Optional.receiver_mask_y – A boolean torch.Tensor with dimensions [shot, receiver] selecting which receivers of the
ychannel are active.Truemeans active;Falsemeans that point records zeros, and its coordinates inreceiver_locations_yare then ignored entirely (they need not be valid, in range, or unique). The shape must match the leading dimensions ofreceiver_locations_y, which must be given. This is the modern spelling of thedeepwave.IGNORE_LOCATIONsentinel 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 adeepwave.Hicksobject: aHickscarries its own already-resolved points, so disable points inside it by setting all of their coordinates todeepwave.IGNORE_LOCATIONin the locations it was built from. Optional.receiver_mask_x – A boolean torch.Tensor with dimensions [shot, receiver] selecting which receivers of the
xchannel are active.Truemeans active;Falsemeans that point records zeros, and its coordinates inreceiver_locations_xare then ignored entirely (they need not be valid, in range, or unique). The shape must match the leading dimensions ofreceiver_locations_x, which must be given. This is the modern spelling of thedeepwave.IGNORE_LOCATIONsentinel 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 adeepwave.Hicksobject: aHickscarries its own already-resolved points, so disable points inside it by setting all of their coordinates todeepwave.IGNORE_LOCATIONin the locations it was built from. Optional.receiver_mask_p – A boolean torch.Tensor with dimensions [shot, receiver] selecting which receivers of the
pchannel are active.Truemeans active;Falsemeans that point records zeros, and its coordinates inreceiver_locations_pare then ignored entirely (they need not be valid, in range, or unique). The shape must match the leading dimensions ofreceiver_locations_p, which must be given. This is the modern spelling of thedeepwave.IGNORE_LOCATIONsentinel 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 adeepwave.Hicksobject. Optional.receiver_mask_sigma_v – A boolean torch.Tensor with dimensions [shot, receiver] selecting which receivers of the
sigma_vchannel are active.Truemeans active;Falsemeans that point records zeros, and its coordinates inreceiver_locations_sigma_vare then ignored entirely (they need not be valid, in range, or unique). The shape must match the leading dimensions ofreceiver_locations_sigma_v, which must be given. This is the modern spelling of thedeepwave.IGNORE_LOCATIONsentinel 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 adeepwave.Hicksobject: aHickscarries its own already-resolved points, so disable points inside it by setting all of their coordinates todeepwave.IGNORE_LOCATIONin 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_hchannel are active.Truemeans active;Falsemeans that point records zeros, and its coordinates inreceiver_locations_sigma_hare then ignored entirely (they need not be valid, in range, or unique). The shape must match the leading dimensions ofreceiver_locations_sigma_h, which must be given. This is the modern spelling of thedeepwave.IGNORE_LOCATIONsentinel 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 adeepwave.Hicksobject: aHickscarries its own already-resolved points, so disable points inside it by setting all of their coordinates todeepwave.IGNORE_LOCATIONin the locations it was built from. Optional.accuracy – See
deepwave.elastic(). Defaults to 4.pml_width – See
deepwave.elastic(). Defaults to 20. A face whosepml_widthis 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 withboundary(ordeepwave.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 indeepwave.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” raisedeepwave.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
zvelocity wavefield (3-D only). Seedeepwave.elastic()(and similarly for the other initial wavefields and PML memory variables).vy_0 – The initial
yvelocity wavefield.vx_0 – The initial
xvelocity 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 callingdeepwave.checkpointing.run_segments()withn_segments=andcheckpoint=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, andtorch.utils.checkpointdoes not supporttorch.autograd.grad()(or aninputs=argument to.backward()) in that mode: it raises. If you needtorch.autograd.grad, calldeepwave.checkpointing.run_segments()directly withuse_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. Atmodel_gradient_sampling_interval == 1with a courant-safedt(step_ratio == 1), model gradients (c11/c13/c33/buoyancy) match the eager backend to near machine precision; atstep_ratio > 1(from either a coarsedtormodel_gradient_sampling_interval > 1) they are a bounded, non-machine-precision approximation (the model gradient is sampled and rescaled once perstep_ratioblock rather than exactly integrated), matching the shared behaviour ofdeepwave.elastic_vti(). The forward pass and the source/receiver-amplitude gradients are exact regardless ofstep_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 thandeepwave.ON_NODE_TOLERANCEcells off its component’s grid node – except that a floating-point Tensor withrequires_grad=Trueis 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-noderequires_gradlocations Tensor relative to the same Tensor withoutrequires_grad. Passlocation_interpolation="none"for the exact path (positions are then not differentiable), or accept the band-limited values.RunInfo.location_interpolation_usedrecords 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.AuxiliaryStateholding 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: