Software | Language |
---|---|
Geopsy | Graphical User Interface |
swprocess and swprepost | Python |
MASWaves | Matlab |
BayHunter | Python |
import os
SALVUS_FLOW_SITE_NAME = os.environ.get("SITE_NAME", "local")
PROJECT_DIR = "project"
import numpy as np
import xarray as xr
from scipy.ndimage import gaussian_filter1d
import salvus.namespace as sn
p = sn.Project(PROJECT_DIR)
# Define the size of the model to be slightly larger than the domain
buffer = 0.05 * (p.domain.bounds.hc["x"][1] - p.domain.bounds.hc["x"][0]) / 2
nx, ny = 820, 300
x = np.linspace(
p.domain.bounds.hc["x"][0] - buffer,
p.domain.bounds.hc["x"][1] + buffer,
nx,
)
y = np.linspace(
p.domain.bounds.vc["y"][0] - buffer,
p.domain.bounds.vc["y"][1] + buffer,
ny,
)
xx, yy = np.meshgrid(x, y, indexing="ij")
# Approximate 1D model extracted from MASW
model_1D = {
"depth": np.array([5.8, 13.1, 30.0]),
"VP": np.array([1600.0, 1750.0, 1800.0]),
"RHO": np.ones(3) * 2000.0,
"VS": np.array([165.0, 230.0, 240.0]),
}
# Get an array of which indices correspond to which depth
depths = np.linspace(-y.min(), -y.max(), ny)
depth_inds = np.zeros(ny, dtype=int)
for i in range(len(model_1D["depth"])):
# For the first layer, just get the values above the first depth
if i == 0:
mask = depths <= model_1D["depth"][0]
# For the last layer, just get the values below the last depth
elif i == len(model_1D["depth"]) - 1:
mask = depths > model_1D["depth"][i - 1]
else:
mask = (depths > model_1D["depth"][i - 1]) & (
depths <= model_1D["depth"][i]
)
depth_inds[mask] = i
# Create 2-D array of material properties
model_2D = {}
for field in ["VP", "RHO", "VS"]:
# Create a single depth profile in 1-D
sharp_1D = np.zeros(ny)
for i, value in enumerate(model_1D[field]):
sharp_1D[depth_inds == i] = value
# Smooth the 1-D model using a gaussian filter
smooth_1D = gaussian_filter1d(sharp_1D, 10, mode="nearest")
# Extrude the 1D model to 2-D
model_2D[field] = (["x", "y"], np.broadcast_to(smooth_1D, [nx, ny]))
# Create an Xarray dataset from the data
ds = xr.Dataset(
data_vars=model_2D,
coords={"x": x, "y": y},
)
ds.VP.T.plot(figsize=(10, 6))
<matplotlib.collections.QuadMesh at 0x769dea6f4b50>
VP
, RHO
, and VS
to the SalvusProject. This dataset can first be added to the project as a volume model.model = sn.model.volume.cartesian.GenericModel(name="volume", data=ds)
p.add_to_project(model, overwrite=True)
SimulationConfiguration
for this volume model. A few things to note regarding this SimulationConfiguration
:max_frequency_in_hertz
should reflect the maximum frequencies which are contained within the source being used. If you aren't sure yet at this stage what your source signature looks like, a good starting point can be to look at the power spectrum for a single trace to see what its dominant frequencies are (see the previous tutorial for an example).tensor_order
can be chosen as either 1
, 2
, 4
, or 7
. This controls the number of nodes per element with a higher tensor order resulting in a greater number of nodes per element. Using more nodes per element allows for smoother transitions in material properties throughout the mesh. While using a higher tensor order can increase the file size of the mesh substantially, using higher tensor order meshes does not increase the computational cost of the subsequent wave simulations (apart adding a bit of overhead for reading in the larger mesh from disk) since the number of elements is unaffected.p.add_to_project(
sn.SimulationConfiguration(
name="volumetric_model",
max_frequency_in_hertz=100.0,
elements_per_wavelength=1.0,
tensor_order=2,
model_configuration=sn.ModelConfiguration(
background_model=sn.model.background.from_volume_model(
model=model
),
volume_models=["volume"],
),
event_configuration=sn.EventConfiguration(
wavelet=sn.simple_config.stf.Ricker(center_frequency=50.0),
waveform_simulation_configuration=sn.WaveformSimulationConfiguration(
end_time_in_seconds=0.6
),
),
),
overwrite=True,
)
p.viz.nb.simulation_setup(
simulation_configuration="volumetric_model", events=p.events.list()
)
[2024-11-15 14:49:05,970] INFO: Creating mesh. Hang on.
<salvus.flow.simple_config.simulation.waveform.Waveform object at 0x769de9237550>