This documentation is not for the latest stable Salvus version.
Without injected energy there is nothing to simulate and the most common scenario is to do this at individual points. Point evaluations of the resulting wavefield are similarly the most widely used output of waveform simulations. Salvus is particularly flexible in this regard and the tutorials in this section will explain all possible options.
SalvusCompute internally operates in Cartesian x
, y
(, z
) coordinates and thus everything has to be specified in this reference system. For simple domains this is no problem, but for complicated, unstructured domains using higher order shape functions for the individual elements this poses a significant challenge.
This notebook explains the straightforward case of directly specifying the coordinates and other parameters. It is also possible to specifiy coordinates relative to specific surfaces in a mesh and in a seismological reference system. For this, please have a look at the other tutorials.
We will again use SalvusFlow's simple_config
interface.
# This line helps with tab-completion of the simple_config objects.
# The IPython/Jupyter project default to a differnet inference based
# tab completion engine which unfortunately does not yet fully work
# with SalvusFlow. This is completely optional and a convenience
# option.
%config Completer.use_jedi = False
import os
from salvus.flow import simple_config
SALVUS_FLOW_SITE_NAME = os.environ.get("SITE_NAME", "local")
There are two basic receiver classes:
simple_config.receiver.cartesian.Point2D
simple_config.receiver.cartesian.Point3D
The only difference is that (as the name implies) one is for 2D simulations, and the other one for 3D simulations. Otherwise they behave identically. Like all objects in the simple_config
, it is not possible to initialize invalid objects.
rec = simple_config.receiver.cartesian.Point2D(
# Cartesian coordinates.
x=2000.0,
y=2000.0,
# The network is optional but helps to group receivers.
network_code="XX",
# The name of the receiver.
station_code="A1",
# An additional level to group receivers.
location_code="",
# At least one output field is required. More are possible.
# Have a look at the API documentation for a list of all
# available fields.
fields=["displacement", "acceleration"],
)
# They are internally represented as dictionaries exactly
# corresponding to what SalvusCompute demands.
print(rec)
{'fields': ['displacement', 'acceleration'], 'location': [2000.0, 2000.0], 'location_code': '', 'network_code': 'XX', 'station_code': 'A1'}
Source by necessity are a bit more complicated. As of new we support 4 types of point sources, in 2 as well as 3 dimensions, with self-explaining names.
simple_config.source.cartesian.ScalarPoint2D
simple_config.source.cartesian.ScalarPoint3D
simple_config.source.cartesian.ScalarGradientPoint2D
simple_config.source.cartesian.ScalarGradientPoint3D
simple_config.source.cartesian.VectorPoint2D
simple_config.source.cartesian.VectorPoint3D
simple_config.source.cartesian.MomentTensorPoint2D
simple_config.source.cartesian.MomentTensorPoint3D
src = simple_config.source.cartesian.VectorPoint2D(
# Coordinates of the source.
x=500.0,
y=1000.0,
# Force vector in x and y direction in Nm.
fx=1e5,
fy=-1e4,
# It also requires a source time function.
source_time_function=simple_config.stf.Ricker(center_frequency=1.0),
)
# They are again internally represented as a dictionary.
print(src)
{'location': [500.0, 1000.0], 'source_time_function': {'center_frequency': 1.0, 'wavelet': 'ricker'}, 'spatial_type': 'vector', 'spatial_weights': [100000.0, -10000.0]}
SalvusCompute
as of now supports 4 parameterized source time functions as well as a custom source time function. A source object cannot be initialized without one.
simple_config.stf.Delta
simple_config.stf.GaussianRate
simple_config.stf.Heaviside
simple_config.stf.Ricker
simple_config.stf.Custom
Our Python based configuration interface is now used to assemble mesh, source, and receiver into a single simulation object that can be visualized in the browser.
from salvus.mesh import simple_mesh
m = simple_mesh.CartesianHomogeneousIsotropicElastic2D(
vp=2000.0,
vs=1500.0,
rho=2000.0,
x_max=3000.0,
y_max=2000.0,
max_frequency=2.0,
)
w = simple_config.simulation.Waveform(mesh=m.create_mesh())
w.add_receivers(rec)
w.add_sources(src)
w
<salvus.flow.simple_config.simulation.Waveform object at 0x7f2764a76110>
This can now finally be used to actually run the simulation.
import salvus.flow.api
salvus.flow.api.run(
site_name=SALVUS_FLOW_SITE_NAME, input_file=w, output_folder="output"
)
Job `job_2011102301911735_a8ed865539` running on `local` with 4 rank(s). Site information: * Salvus version: 0.11.22 * Floating point size: 32 -> Current Task: Time loop complete* Downloaded 17.7 KB of results to `output`. * Total run time: 1.18 seconds. * Pure simulation time: 0.88 seconds.
<salvus.flow.sites.salvus_job.SalvusJob at 0x7f287f487d90>