This documentation is not for the latest stable Salvus version.
%matplotlib inline
%config Completer.use_jedi = False
from salvus.mesh.simple_mesh import SmoothieSEM
from salvus import namespace as sn
period_global = 100.0
# a quake in Turkey that we will use in this tutorial, original data from IRIS spud:
# http://service.iris.edu/fdsnws/event/1/query?eventid=2847365
# http://ds.iris.edu/spudservice/momenttensor/gcmtid/C201003241411A/quakeml#momenttensor
source = sn.simple_config.source.seismology.SideSetMomentTensorPoint3D(
latitude=38.82,
longitude=40.14,
depth_in_m=4500,
side_set_name="r1",
mrr=5.47e15,
mtt=-4.11e16,
mpp=3.56e16,
mrt=2.26e16,
mrp=-2.25e16,
mtp=1.92e16,
)nlat allows to vary the number of elements in the lateral direction that is used throughout the whole mesh. Compare Figure 9 in [1] to choose values appropriate for your application.sm = SmoothieSEM()
sm.basic.model = "prem_iso_one_crust"
sm.basic.min_period_in_seconds = period_global
sm.basic.elements_per_wavelength = 2.0
sm.advanced.tensor_order = 2
sm.basic.number_of_lateral_elements = 4
sm.source.latitude = source._initial_arguments["latitude"]
sm.source.longitude = source._initial_arguments["longitude"]
sm.create_mesh()<salvus.mesh.unstructured_mesh.UnstructuredMesh at 0x7fc27683c910>
theta is the angular distance from the source in the range [0°, 180°]. Multiple such refinements can be combined, but refinement boundaries should not cross to ensure high quality elements: each refinement should be fully contained in all previous refinements.sm.refinement.lateral_refinements = [
{
"theta_min": 60.0,
"theta_max": 150.0,
"r_min": 6000.0,
},
{
"theta_min": 80.0,
"theta_max": 130.0,
"r_min": 6200.0,
},
]
sm.create_mesh()<salvus.mesh.unstructured_mesh.UnstructuredMesh at 0x7fc27512afd0>
phi_min, phi_max] relative to the source azimuths measured clockwise from north. This may be a practical alternative to absorbing boundaries and a azimuthally constrained domain.sm.refinement.lateral_refinements = [
{
"theta_min": 40.0,
"theta_max": 110.0,
"r_min": 6000.0,
"phi_min": -45.0,
"phi_max": 45.0,
}
]
sm.source.azimuth = 270.0
sm.create_mesh()<salvus.mesh.unstructured_mesh.UnstructuredMesh at 0x7fc273d18d50>
r_max parameter of ther lateral refinement object:sm.refinement.lateral_refinements = [
{
"theta_min": 40.0,
"theta_max": 110.0,
"r_min": 3000.0,
"r_max": 4000.0,
"phi_min": -45.0,
"phi_max": 45.0,
}
]
sm.create_mesh()<salvus.mesh.unstructured_mesh.UnstructuredMesh at 0x7fc271d5ed50>
sml = SmoothieSEM()
sml.basic.model = "prem_iso_one_crust"
sml.basic.min_period_in_seconds = 10.0
sml.basic.elements_per_wavelength = 2.0
sml.spherical.min_radius = 6000.0
sml.chunk.max_colatitude = 10.0
sml.advanced.tensor_order = 2
sml.basic.number_of_lateral_elements = 4
sml.source.latitude = source._initial_arguments["latitude"]
sml.source.longitude = source._initial_arguments["longitude"]
sml.create_mesh()<salvus.mesh.unstructured_mesh.UnstructuredMesh at 0x7fc2750a5f10>
import pathlib
import requests
for fname in [
"topography_earth2014_egm2008_lmax_256.nc",
"bathymetry_earth2014_lmax_256.nc",
"moho_topography_crust_1_0_egm2008.nc",
]:
topography_file = pathlib.Path(fname)
if not topography_file.exists():
r = requests.get(
f"https://data.mondaic.com/topography-data/{fname}",
stream=True,
)
assert r.ok
with topography_file.open("wb") as f:
f.write(r.raw.read())sm = SmoothieSEM()
sm.basic.model = "prem_iso_one_crust"
sm.basic.min_period_in_seconds = 100.0
sm.basic.elements_per_wavelength = 2.0
sm.basic.number_of_lateral_elements = 6
sm.advanced.tensor_order = 2
sm.source.latitude = 38.82
sm.source.longitude = 40.14
sm.topography.topography_file = "topography_earth2014_egm2008_lmax_256.nc"
sm.topography.topography_varname = (
"topography_earth2014_egm2008_lmax_256_lmax_32"
)
sm.topography.moho_topography_file = "moho_topography_crust_1_0_egm2008.nc"
sm.topography.moho_topography_varname = (
"moho_topography_crust_1_0_egm2008_lmax_32"
)NetCDF Reader) to vizualize the available datasets. The variable name is composed of the filename appended with the maximum resolution in terms of the spherical harmonic degree and order lmax. For reasonable accuracy, lmax should not be larger than approximately number_of_lateral_elements * tensor_order, so the settings in the example here are very optimistic to keep it small enough.# WGS84 ellipticity value
sm.spherical.ellipticity = 0.0033528106647474805
m = sm.create_mesh()
# for vizualisation compute the radius (note that this in case includes the ellipticity)
m.attach_field("r", (m.points**2).sum(axis=1) ** 0.5)
# choose 'r' in the widget to see the 3D data
m<salvus.mesh.unstructured_mesh.UnstructuredMesh at 0x7fc273a01250>