Jupyter Notebook

This page is automatically generated from a Jupyter Notebook.

Note that everything here is fully automatically tested against - and thus guaranteed to work - only for the latest versions of all the Salvus packages. So please update if anything works differently on your machine.

# Point Sources and Receivers for the Wave Equation¶

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 salvus_flow. This is completely optional and a convenience
# option.
%config Completer.use_jedi = False

from salvus_flow import simple_config


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'}


## Sources¶

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.

#### Sources in Acoustic Media¶

• simple_config.source.cartesian.ScalarPoint2D
• simple_config.source.cartesian.ScalarPoint3D

• simple_config.source.cartesian.ScalarGradientPoint2D

• simple_config.source.cartesian.ScalarGradientPoint3D

#### Source in Elastic Media¶

• 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]}


#### Source Time Functions¶

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

## Using Sources and Receivers¶

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


<salvus_flow.simple_config.simulation.Waveform object at 0x114dad048>


### Running the Simulation¶

This can now finally be used to actually run the simulation.

# NBVAL_IGNORE_OUTPUT
import salvus_flow.api

salvus_flow.api.run(
site_name="local", input_file=w,
output_folder="output", overwrite=True)

Job job_1904251841_09e21 running on local with 2 rank(s).
Site information:
* Salvus version: 0.8.2-67-g2029a7f
* Floating point size: 32
Results have been downloaded to output.

!ls -1 output

meta.json