import numpy as np
import matplotlib.pyplot as plt
import psutil
nthreads = int(np.ceil(psutil.cpu_count() / 3 * 2))A visual overview of the propagators
We provide in this notebook a comparison of the wavefields propagated with the different propagators implemented in th recipes. We consider a fixed anisotropic elastic multilayer model for all experiemnts.
Utility functions
We setup a few utility function to plot the model and wavefield nicely
def plot_model(model):
iy = param.shape[1]//2
domain_size = 1.e-3 * np.array(param.grid.domain_size)
extent = [model.origin[0], model.origin[0] + domain_size[0],
model.origin[1] + domain_size[1], model.origin[1]]
plt.imshow(param.data[:, iy, :].T, aspect="auto", cmap="vik", extent=extent)
plt.title("%s" % param.name)
plt.colorbar()Setup model
We first setup the model using the most complex physics available tti-elastic. This model contains all necessary parameters to propagate waves with all propagators.
from recipes import recipes_registry, layered_model
# Available propagators
print("\n".join(recipes_registry.keys()))Submodule devito version mismatch. Installed: 4.8.14+89.gd6980b7e9, Required: 4.8.14+86.g6d494dbdf
iso-acoustic
tti-zhang
tti-fletcher
tti-selfadjoint
iso-elastic
tti-elastic
vti-zhang
vti-fletcher
vti-selfadjoint
vti-elastic
# Setup grid
n = (64, 64, 64)
so = 8
args = {'time_order': 2, 'space_order': so, 'shape': n, 'fs': True,
'nt' : 600, 'fd_kernel_only': False, 'density': True, 'abox': False,
'dtype': np.float32, 'save': False, 'ndim': 3, 'nbl': 40, 'f0': 0.0075}
modelelas = layered_model('elastic-tti', nlayers=4, spacing=(20, 20, 20), **args)
modelacou = layered_model('acoustic-tti', nlayers=4, spacing=(20, 20, 20), dt=modelelas.critical_dt, **args)modelelas.physical_params(){'delta': delta(x, y, z),
'eta': eta(x, y, z),
'f': f(x, y, z),
'mu': mu(x, y, z),
'vp': vp(x, y, z),
'theta': theta(x, y, z),
'b': b(x, y, z),
'epsilon': epsilon(x, y, z),
'lam': lam(x, y, z),
'phi': phi(x, y, z)}
plt.figure(figsize=(10, 10))
plt.subplot(4,2,1)
plt.imshow(modelelas.vp.data[:, 11, :].T, aspect="auto")
plt.title("P-wave velocity")
plt.colorbar()
plt.subplot(4,2,2)
plt.imshow(modelelas.mu.data[:, 11, :].T, aspect="auto")
plt.title(r"S-wave velocity (Lame \mu)")
plt.colorbar()
plt.subplot(4,2,3)
plt.imshow(modelelas.epsilon.data[:, 11, :].T, aspect="auto")
plt.title(r"$\epsilon$")
plt.colorbar()
plt.subplot(4,2,4)
plt.imshow(modelelas.delta.data[:, 11, :].T, aspect="auto")
plt.title(r"$\delta$")
plt.colorbar()
plt.subplot(4,2,5)
plt.imshow(modelelas.theta.data[:, 11, :].T, aspect="auto")
plt.title(r"$\theta$")
plt.colorbar()
plt.subplot(4,2,6)
plt.imshow(modelelas.phi.data[:, 11, :].T, aspect="auto")
plt.title(r"$\phi$")
plt.colorbar()
plt.tight_layout()
props = []
for k, prop in recipes_registry.items():
if 'vti' in k:
continue
if 'elas' in k:
model = modelelas
else:
model = modelacou
props.append(prop(model, args))ElasticTTI factorization: on-the-fly C_{ij}
props = sorted(props, key=lambda x: x.__class__.__name__)from IPython.display import display, clear_output
plt.figure(figsize=(10, 10))
for (i, solver) in enumerate(props):
name = solver.__class__.__name__
src = solver.src
src.coordinates.data[0, 0] /= 3
if solver.time_order == 1:
src.data[:, 0] = np.cumsum(props[0].src.data, axis=0)[:, 0] / props[0].model.critical_dt
# get pressure
solver.forward(save=False, nthreads=nthreads, src=src)
p = np.array(solver.pressure_data)
iy = p.shape[1] // 2
c = np.quantile(np.abs(p[:, iy, :].reshape(-1)), .99)
plt.subplot(3, 2, i+1)
plt.imshow(p[:, iy, :].T, cmap="seismic", vmin=-c, vmax=c, aspect="auto")
plt.title(name)
display(plt.gcf()) # Show current figure
clear_output(wait=True) # Clear previous output (optional to avoid clutter)
plt.tight_layout()
# display(plt.gcf()) # Final display