This documentation is not for the latest stable Salvus version.
period
here) and re-running the whole notebook could also be used to run realistic and large-scale simulations.pyasdf
and obspy
Python libraries which can be installed either via pip
or via conda
.import os
import pyasdf
from salvus.flow import api, simple_config
from salvus.mesh import simple_mesh
SALVUS_FLOW_SITE_NAME = os.environ.get("SITE_NAME", "local")
# Controls the dominant period of the mesh and the width
# of the source time function. It is given in seconds.
period = 4000.0
# We'll first build a mesh using the simple_mesh interface.
m = simple_mesh.Globe3D()
m.basic.min_period_in_seconds = period
# At these period we don't require a crust. Adding a 3D model
# is the topic of another tutorial.
m.basic.model = "prem_ani_no_crust"
# Higher order shapes and models better approximate the sphere.
# With order 4 we achieve a very good approximation of it
# even with only very few elements.
m.advanced.tensor_order = 4
# In order to make it a bit more interesting we'll create an
# elliptic mesh. This is the WGS84 ellipsoid.
m.spherical.ellipticity = 0.0033528106647474805
# This is an important setting. The more elementes per wavelength
# the more accurate the solution. 2 is a conservative value and
# the default. Many global seismologist only use 1 element per
# wavelength which ends up being 16 times cheaper in terms of
# simulation cost but is still usable in many scenarios.
m.basic.elements_per_wavelength = 2.0
# Tohuko-Oki earthquake. Information is taken from the GCMT catalog
# which unfortunately does not offer a proper web service.
source = simple_config.source.seismology.SideSetMomentTensorPoint3D(
latitude=37.5200,
longitude=143.0500,
depth_in_m=20000,
side_set_name="r1",
mrr=1.730000e22,
mtt=-2.810000e21,
mpp=-1.450000e22,
mrt=2.120000e22,
mrp=4.550000e22,
mtp=-6.570000e21,
source_time_function=simple_config.stf.GaussianRate(
half_duration_in_seconds=period / 2
),
)
# Create the simulation object and combine all the information.
w = simple_config.simulation.Waveform(mesh=m.create_mesh())
# Sources and receivers will be placed exactly relative to the
# local mesh surface. Please refer to the sources and receivers
# documentation for more details.
w.add_sources(source)
# Here we use a pre-compiled STATIONXML.
# Alternatively, we could use obspy's FDSN client to directly
# download GSN stations via IRIS. _GSN is the virtual GSN network
# which groups a number of actual seismic network.
# inv = obspy.clients.fdsn.Client("IRIS").get_stations(
# network="_GSN", level="station", format="text"
# )
w.add_receivers(
simple_config.receiver.seismology.parse(
"data/inventory.xml", dimensions=3, fields=["displacement"]
)
)
# Visualize it.
w
<salvus.flow.simple_config.simulation.waveform.Waveform object at 0x7fc9af5c5310>
# We use SalvusFlow to run the simulation. The site determines
# where it will run in the end. Might be the local machine, or
# a large remote cluster.
api.run(
input_file=w,
site_name=SALVUS_FLOW_SITE_NAME,
output_folder="global_simulation",
)
SalvusJob `job_2403150935814350_a2e6a34353` running on `local` with 4 rank(s). Site information: * Salvus version: 0.12.16 * Floating point size: 32
* Downloaded 35.1 MB of results to `global_simulation`. * Total run time: 9.38 seconds. * Pure simulation time: 8.43 seconds.
<salvus.flow.sites.salvus_job.SalvusJob at 0x7fc9a9086110>
# Now we'll just randomly select a waveform to plot.
ds = pyasdf.ASDFDataSet("./global_simulation/receivers.h5")
ds.waveforms.IU_ANMO.displacement.plot()
<Figure size 800x750 with 3 Axes>