docs: update dynamic rupture topic

feature/orthodrom-crossdist
Sebastian Heimann 2 years ago
parent 5ae55b9155
commit 68a43c329c

Binary file not shown.

Before

Width:  |  Height:  |  Size: 158 KiB

After

Width:  |  Height:  |  Size: 178 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

After

Width:  |  Height:  |  Size: 15 KiB

@ -195,7 +195,7 @@
x="14762"
class="TextPosition"><tspan
style="fill:#000000;stroke:none"
id="tspan262">and time-dependet</tspan></tspan></tspan><tspan
id="tspan262">and time-dependent</tspan></tspan></tspan><tspan
style="font-weight:400;font-size:388px;font-family:'DejaVu Sans', sans-serif"
id="tspan278"
font-weight="400"
@ -6855,4 +6855,4 @@
</g>
</g>
</g>
</svg>
</svg>

Before

Width:  |  Height:  |  Size: 240 KiB

After

Width:  |  Height:  |  Size: 240 KiB

@ -6,14 +6,14 @@ Pseudo Dynamic Rupture - *A stress-based self-similar finite source model*
Introduction
************
Physics-based, dynamic rupture models, which rely on few parameters only, are needed to allow a realistic forward modelling and to reduce the effort and non-uniqueness of the inversion. The :py:class:`~pyrocko.gf.seismosizer.PseudoDynamicRupture` is a simplified, quasi-dynamic, semi-analytical rupture model suited for wavefield and static displacement simulations and earthquake source inversion. The rupture builds on the class of self-similar crack models. On one hand it is approximative as it neglects inertia and so far the details of frictional effects, and treats the rupture front growth in a simplified way. On the other hand, it is complete as the slip fulfils the boundary condition on the broken plane for every instantaneous rupture front geometry and applied stress.
Physics-based, dynamic rupture models, which rely on few parameters only, are needed for realistic forward modelling and to reduce the effort and non-uniqueness of the inversion. The :py:class:`~pyrocko.gf.seismosizer.PseudoDynamicRupture` is a simplified, quasi-dynamic, semi-analytical rupture model suited for wavefield and static displacement simulation and earthquake source inversion. The rupture model builds on the class of self-similar crack models. On one hand it is approximative as it neglects inertia and so far the details of frictional effects and treats the rupture front growth in a simplified way. On the other hand, it is complete as the slip fulfils the boundary condition on the broken plane for every instantaneous rupture front geometry and applied stress.
Theoretical foundation
======================
.. note ::
Dahm, T., Metz, M., Heimann, S., Isken, M. P. (2021). A self-similar dynamic rupture model based on the simplified wave-rupture analogy. Geophysical Journal International. Volume 225, Issue 3, June 2021, Pages 15861604, https://doi.org/10.1093/gji/ggab045
Dahm, T., Heimann, S., Metz, M., Isken, M. P. (2021). A self-similar dynamic rupture model based on the simplified wave-rupture analogy. Geophysical Journal International. Volume 225, Issue 3, June 2021, Pages 15861604, https://doi.org/10.1093/gji/ggab045
.. contents :: Content
:depth: 4
@ -23,7 +23,7 @@ Source implementation details
*****************************
The implementation of the pseudo dynamic rupture model into the Pyrocko and Pyrocko-GF framework is based on [Dahm2021]_. Essential building blocks are the classes :py:class:`~pyrocko.gf.seismosizer.PseudoDynamicRupture` and :py:class:`~pyrocko.gf.tractions.AbstractTractionField`. Additionally the model is constrained by the subsurface underground model as provided by the :py:class:`~pyrocko.gf.seismosizer.Store`. See [Dahm2021_] which describes the rupture source model in detail.
The implementation of the pseudo dynamic rupture model into the Pyrocko and Pyrocko-GF framework is based on [Dahm2021]_. Essential building blocks are the class :py:class:`~pyrocko.gf.seismosizer.PseudoDynamicRupture` and in the :py:class:`~pyrocko.gf.tractions.AbstractTractionField` subclasses. Additionally the model is constrained by the subsurface underground model as provided by the metadata in the Pyrocko GF :py:class:`~pyrocko.gf.store.Store`. See [Dahm2021_] which describes the rupture source model in detail.
.. figure :: /static/pseudo-dynamic-flow-2.svg
:align: center
@ -44,14 +44,16 @@ In this section we will show the parametrisation, introspection and resulting se
Forward calculation of waveforms and static displacement
========================================================
Parametrisation of the source model is straight forward, as for any other Pyrocko-GF source. In the below code example we parametrize a shallow bi-directional strike-slip source.
Parametrisation of the source model is straight forward, as for any other Pyrocko-GF source. In the below code example we parametrize a shallow bidirectional strike-slip source.
More details on dynamic and static Green's function databases and other source models are layed out in :doc:`pyrocko-gf`.
More details on dynamic and static Green's function databases and other source models are laid out in section :doc:`pyrocko-gf`.
Simple pseudo dynamic rupture forward model
-------------------------------------------
We create a simple forward model and calculate waveforms for one seismic station (:py:class:`~pyrocko.gf.targets.Target`) at about 14 km distance - The tractions will be aligned to force the defined ``rake``. The modeled waveform is displayed in the *snuffler* GUI.
We create a simple forward model and calculate waveforms for one seismic station (:py:class:`~pyrocko.gf.targets.Target`) at about 14 km distance - The tractions will be aligned to force the defined slip rake angle. The modeled waveform is displayed in the :doc:`Snuffler <../apps/snuffler/index>` application.
**Important:** the spatial sampling of the GF store used in the example must be dense enough to prevent aliasing artifacts.
Download :download:`gf_forward_pseudo_rupture_basic.py </../../examples/gf_forward_pseudo_rupture_basic.py>`
@ -59,26 +61,27 @@ Download :download:`gf_forward_pseudo_rupture_basic.py </../../examples/gf_forwa
:language: python
Traction and stress field parametrisation
=========================================
The rupture plane can be exposed to different stress/traction field models which drive and interact with the rupture process.
A :class:`~pyrocko.gf.tractions.TractionField` constrains the absolute traction field:
A :class:`~pyrocko.gf.tractions.TractionField` defines the absolute stress release on the fault plane:
* :class:`~pyrocko.gf.tractions.UniformTractions`
* :class:`~pyrocko.gf.tractions.HomogeneousTractions`
* :class:`~pyrocko.gf.tractions.DirectedTractions`
* :class:`~pyrocko.gf.tractions.FractalTractions`
An :py:class:`~pyrocko.gf.tractions.AbstractTractionField` modify an existing :class:`~pyrocko.gf.tractions.TractionField`:
An :py:class:`~pyrocko.gf.tractions.AbstractTractionField` can modify an existing :class:`~pyrocko.gf.tractions.TractionField`:
* :class:`~pyrocko.gf.tractions.RectangularTaper`
* :class:`~pyrocko.gf.tractions.DepthTaper`
These fields can be used independently or be combined into a :py:class:`~pyrocko.gf.tractions.TractionComposition`, where :py:class:`~pyrocko.gf.tractions.TractionField` are stacked and :py:class:`~pyrocko.gf.tractions.AbstractTractionField` are multiplied with the stack. See the reference and code for implementation details.
Pure tractions can be visualised using the utility function :py:func:`pyrocko.gf.tractions.plot_tractions`.
Pure tractions can be visualised using the utility function :py:func:`~pyrocko.gf.tractions.plot_tractions`.
@ -90,7 +93,7 @@ Convenience functions for plotting and introspection of the dynamic rupture mode
Traction and rupture evolution
------------------------------
Initialize a simple dynamic rupture with uniform rake tractions and visualize the tractions and rupture propagation using the :py:mod:`pyrocko.plot.dynamic_rupture` module.
Initialize a simple dynamic rupture with uniform rake tractions and visualize the tractions and rupture propagation.
Download :download:`gf_forward_pseudo_rupture_basic_plot.py </../../examples/gf_forward_pseudo_rupture_basic_plot.py>`
@ -103,17 +106,19 @@ Download :download:`gf_forward_pseudo_rupture_basic_plot.py </../../examples/gf_
:alt: Rupture propagation and tractions of a simple dynamic rupture source
with uniform rake tractions
Absolute tractions of a simple dynamic source model with a uniform rake. Contour lines show the propagation of the rupture front.
Absolute tractions of a simple dynamic source model with a uniform rake. Contour lines are isochrones of the rupture front.
Rupture propagation
-------------------
We can investigate the rupture propagation speed :math:`v_r` with :py:meth:`~pyrocko.plot.dynamic_rupture.RuptureView.draw_patch_parameter`:
We can investigate the rupture propagation speed :math:`v_r` with :py:meth:`~pyrocko.plot.dynamic_rupture.RuptureView.draw_patch_parameter`.
Rupture speed is proportional to the S-wave velocity in the Earth model and scaled with the attribute :py:gattr:`~pyrocko.gf.seismosizer.PseudoDynamicRupture.gamma`.
.. code-block :: python
plot = RuptureView(dyn_rupture)
# rupture is a PseudoDynamicRupture object
plot = RuptureView(rupture)
plot.draw_patch_parameter('vr')
plot.draw_time_contour(store)
@ -127,7 +132,7 @@ We can investigate the rupture propagation speed :math:`v_r` with :py:meth:`~pyr
:alt: Rupture propagation and tractions of a simple dynamic rupture source
with uniform rake tractions
Rupture propagation speed of a simple dynamic source model with a uniform rake. Contour lines show the propagation of the rupture front.
Rupture propagation speed of a simple dynamic source model. Contour lines are isochrones of the rupture front.
Slip distribution
@ -137,7 +142,8 @@ Dislocations of the dynamic rupture source can be plotted with :py:meth:`~pyrock
.. code-block :: python
plot = RuptureView(dyn_rupture)
# rupture is a PseudoDynamicRupture object
plot = RuptureView(rupture)
plot.draw_dislocation()
plot.draw_time_contour(store)
@ -151,21 +157,20 @@ Dislocations of the dynamic rupture source can be plotted with :py:meth:`~pyrock
:alt: Rupture propagation and dislocation of a simple dynamic rupture source
with uniform rake tractions
Absolute dislocation of a simple dynamic rupture source model with uniform rake tractions.
Contour lines show the propagation of the rupture front.
Absolute dislocation of a simple dynamic rupture source model with uniform rake tractions. Contour lines are isochrones of the rupture front.
Rupture evolution
-----------------
We can animate the rupture evolution using the :py:func:`pyrocko.plot.dynamic_rupture.rupture_movie` function.
We can animate the rupture evolution using the :py:func:`~pyrocko.plot.dynamic_rupture.rupture_movie` function.
.. code-block :: python
from pyrocko.plot.dynamic_rupture import rupture_movie
rupture_movie(
dyn_rupture, store, 'dislocation',
rupture, store, 'dislocation',
plot_type='view')
@ -182,9 +187,9 @@ We can animate the rupture evolution using the :py:func:`pyrocko.plot.dynamic_ru
Combined complex traction fields
--------------------------------
In this example we will combine different traction fields: :py:class:`~pyrocko.gf.tractions.DirectedTractions`, :py:class:`~pyrocko.gf.tractions.FractalTractions` and :py:class:`~pyrocko.gf.tractions.RectangularTaper`.
In this example we will combine different traction fields: :py:class:`~pyrocko.gf.tractions.DirectedTractions`, :py:class:`~pyrocko.gf.tractions.FractalTractions` and taper them using :py:class:`~pyrocko.gf.tractions.RectangularTaper`.
After plotting the tractions and final dislocations we will forward model the waveforms.
After plotting the tractions and final dislocations, we will forward model the waveforms.
Download :download:`gf_forward_pseudo_rupture_complex.py </../../examples/gf_forward_pseudo_rupture_complex.py>`
@ -208,7 +213,7 @@ Download :download:`gf_forward_pseudo_rupture_complex.py </../../examples/gf_for
:alt: Rupture propagation and dislocation of a complex dynamic rupture source
with uniform rake tractions and random fractal perturbations.
Absolute dislocation of a complex dynamic rupture source with uniform rake and superimposed random fractal perturbations. Contour lines show the propagation of the rupture front.
Absolute dislocation of a complex dynamic rupture source with uniform rake and superimposed random fractal perturbations. Contour lines are isochrones of the rupture front.
.. figure :: /static/dynamic_complex_waveforms_snuffler.png
@ -216,23 +221,23 @@ Download :download:`gf_forward_pseudo_rupture_complex.py </../../examples/gf_for
:width: 80%
:alt: Synthetic waveforms modelled from the pseudo dynamic rupture source model.
Synthetic waveforms generated by :doc:`pyrocko-gf` from the pseudo dynamic rupture model at ~31 km distance.
Synthetic waveforms generated by :doc:`Pyrocko-GF <pyrocko-gf>` from the pseudo dynamic rupture model at 31 km distance.
Moment rate function / Source time function
Moment rate function / source time function
-------------------------------------------
With this example we demonstrate, how the moment rate function or source time function (STF) of a rupture can be simulated using the slip changes on each subfault, the average shear modulus and the subfault areas:
With this example we demonstrate, how the moment rate :math:`\dot{M}(t)` or source time function (STF) of a rupture can be simulated using the slip rate on each subfault :math:`\dot{u_i}(t)`, the average shear modulus :math:`\mu` and the subfault areas :math:`A_i`:
.. math:: STF = \dot{dM} = \sum_{i_{sf}=1}^{n_{sf}} \dot{du_{i_{sf}}} \mu A_{i_{sf}}
.. math:: \dot{M}(t) = \sum_{i=1}^{n_{sf}} \dot{u_i}(t) \mu A_i
Use the method :py:meth:`pyrocko.plot.dynamic_rupture.RuptureView.draw_source_dynamics`.
Use the method :py:meth:`~pyrocko.plot.dynamic_rupture.RuptureView.draw_source_dynamics`:
.. code-block :: python
plot = RuptureView(dyn_rupture)
plot = RuptureView(rupture)
# variable can be:
# - 'stf', 'moment_rate': moment rate function
@ -255,24 +260,24 @@ Use the method :py:meth:`pyrocko.plot.dynamic_rupture.RuptureView.draw_source_dy
Individual time-dependent subfault characteristics
--------------------------------------------------
Sometimes it might be also interesting to check the time-dependent behaviour of an individual subfaults.
Sometimes it might be also interesting to check the time-dependent behaviour of an individual subfault.
Use the method :py:meth:`pyrocko.plot.dynamic_rupture.RuptureView.draw_patch_dynamics`.
Use the method :py:meth:`~pyrocko.plot.dynamic_rupture.RuptureView.draw_patch_dynamics`:
.. code-block :: python
plot = RuptureView(dyn_rupture)
plot = RuptureView(rupture)
# nx and ny are the indices of the subfault along strike (nx) and down dip (ny)
# variable can be:
# - 'dislocation': length of subfault dislocation vector [m]
# - 'dislocation_<x, y, z>': subfault dislocation vector component
# in strike, updip or normal direction in [m]
# - 'slip_rate': subfault slip change in [m/s]
# - 'slip_rate': subfault slip rate in [m/s]
# - 'moment_rate': subfault moment rate function
# - 'cumulative_moment', 'moment': subfault summed moment function
# of the rupture
plot.draw_patch_dynamics(variable='slip_rate', nx=15, ny=10, store=store)
plot.draw_patch_dynamics(variable='slip_rate', nx=6, ny=3, store=store)
plot.show_plot()
@ -281,13 +286,13 @@ Use the method :py:meth:`pyrocko.plot.dynamic_rupture.RuptureView.draw_patch_dyn
:width: 70%
:alt: Slip rate function of a single subfault of the complex dynamic rupture source with uniform rake tractions and random fractal perturbations.
Slip rate function of a single subfault (:math:`n_x=20, n_y=10`) of the complex dynamic rupture source with uniform rake tractions and random fractal perturbations.
Slip rate function of a single subfault (:math:`n_x=6, n_y=3`) of the complex dynamic rupture source with uniform rake tractions and random fractal perturbations.
Radiated seismic energy
-----------------------
For rather complex ruptures also directivity effects in the waveforms are of interest. Using the function :py:func:`pyrocko.plot.directivity.plot_directivity` allows to plot synthetic waveforms or its envelopes at a certain distance from the source in a circular plot. It provides an easy way of visual directivity effect imaging.
For rather complex ruptures also directivity effects in the waveforms are of interest. Using the function :py:func:`~pyrocko.plot.directivity.plot_directivity` allows to plot synthetic waveforms or its envelopes at a certain distance from the source in a circular plot. It provides an easy way of visual directivity effect imaging.
.. code-block :: python
@ -296,8 +301,11 @@ For rather complex ruptures also directivity effects in the waveforms are of int
# many more possible arguments are provided in the help of plot_directivity
resp = plot_directivity(
engine,
dyn_rupture,
rupture,
store_id,
phases={
'P': '{cake:p|cake:P}-10%',
'S': '{cake:s|cake:S}+50'},
# distance and azimuthal density of modelled waveforms
distance=300*km,
@ -322,4 +330,4 @@ For rather complex ruptures also directivity effects in the waveforms are of int
**********
References
**********
.. [Dahm2021] Dahm, T., Metz, M., Heimann, S., Isken, M. P. (2021). A self-similar dynamic rupture model based on the simplified wave-rupture analogy. Geophysical Journal International. Volume 225, Issue 3, June 2021, Pages 15861604, https://doi.org/10.1093/gji/ggab045
.. [Dahm2021] Dahm, T., Heimann, S., Metz, M., Isken, M. P. (2021). A self-similar dynamic rupture model based on the simplified wave-rupture analogy. Geophysical Journal International. Volume 225, Issue 3, June 2021, Pages 15861604, https://doi.org/10.1093/gji/ggab045

@ -6,9 +6,9 @@ km = 1e3
# The store we are going extract data from:
store_id = 'iceland_reg_v2'
# First, download a Greens Functions store. If you already have one that you
# would like to use, you can skip this step and point the *store_superdirs* in
# the next step to that directory.
# First, download a Green's functions store. If you already have one that you
# would like to use, you can skip this step and point the *store_superdirs* to
# the containing directory.
if not op.exists(store_id):
gf.ws.download_gf_store(site='kinherd', store_id=store_id)
@ -17,12 +17,12 @@ if not op.exists(store_id):
# engine since we are going to query a local store.
engine = gf.LocalEngine(store_superdirs=['.'])
# The dynamic parameter used for discretization of the PseudoDynamicRupture are
# extracted from the stores config file.
# The dynamic parameters used for discretization of the PseudoDynamicRupture
# are extracted from the store's config file.
store = engine.get_store(store_id)
# Let's define the source now with its extension, orientation etc.
dyn_rupture = gf.PseudoDynamicRupture(
rupture = gf.PseudoDynamicRupture(
lat=0.,
lon=0.,
north_shift=2.*km,
@ -50,8 +50,8 @@ dyn_rupture = gf.PseudoDynamicRupture(
# Force pure shear rupture
pure_shear=True)
# Recalculate slip, that rupture magnitude fits given magnitude
dyn_rupture.rescale_slip(magnitude=7.0, store=store)
# Recalculate slip, so that the rupture's magnitude fits the given value
rupture.rescale_slip(magnitude=7.0, store=store)
# Create waveform target, where synthetic waveforms are calculated for
waveform_target = gf.Target(
@ -59,8 +59,9 @@ waveform_target = gf.Target(
lon=0.,
east_shift=10*km,
north_shift=10.*km,
interpolation='multilinear',
store_id=store_id)
# Get synthetic waveforms and display them in snuffler
result = engine.process(dyn_rupture, waveform_target)
result.snuffle()
response = engine.process(rupture, waveform_target)
response.snuffle()

@ -7,9 +7,9 @@ km = 1e3
# The store we are going extract data from:
store_id = 'iceland_reg_v2'
# First, download a Greens Functions store. If you already have one that you
# would like to use, you can skip this step and point the *store_superdirs* in
# the next step to that directory.
# First, download a Green's functions store. If you already have one that you
# would like to use, you can skip this step and point the *store_superdirs* to
# the containing directory.
if not op.exists(store_id):
gf.ws.download_gf_store(site='kinherd', store_id=store_id)
@ -18,12 +18,12 @@ if not op.exists(store_id):
# engine since we are going to query a local store.
engine = gf.LocalEngine(store_superdirs=['.'])
# The dynamic parameter used for discretization of the PseudoDynamicRupture are
# extracted from the stores config file.
# The dynamic parameters used for discretization of the PseudoDynamicRupture
# are extracted from the store's config file.
store = engine.get_store(store_id)
# Let's define the source now with its extension, orientation etc.
dyn_rupture = gf.PseudoDynamicRupture(
rupture = gf.PseudoDynamicRupture(
# At lat 0. and lon 0. (default)
north_shift=2.*km,
east_shift=2.*km,
@ -51,9 +51,9 @@ dyn_rupture = gf.PseudoDynamicRupture(
pure_shear=True)
# Recalculate slip, that rupture magnitude fits given magnitude
dyn_rupture.rescale_slip(magnitude=7.0, store=store)
rupture.rescale_slip(magnitude=7.0, store=store)
plot = RuptureView(dyn_rupture, figsize=(8, 4))
plot = RuptureView(rupture, figsize=(8, 4))
plot.draw_patch_parameter('traction')
plot.draw_time_contour(store)
plot.draw_nucleation_point()

@ -8,9 +8,9 @@ km = 1e3
# The store we are going extract data from:
store_id = 'iceland_reg_v2'
# First, download a Greens Functions store. If you already have one that you
# would like to use, you can skip this step and point the *store_superdirs* in
# the next step to that directory.
# First, download a Green's functions store. If you already have one that you
# would like to use, you can skip this step and point the *store_superdirs* to
# the containing directory.
if not op.exists(store_id):
gf.ws.download_gf_store(site='kinherd', store_id=store_id)
@ -19,12 +19,12 @@ if not op.exists(store_id):
# engine since we are going to query a local store.
engine = gf.LocalEngine(store_superdirs=['.'])
# The dynamic parameter used for discretization of the PseudoDynamicRupture are
# extracted from the stores config file.
# The dynamic parameters used for discretization of the PseudoDynamicRupture
# are extracted from the store's config file.
store = engine.get_store(store_id)
# Let's define the source now with its extension, orientation etc.
dyn_rupture = gf.PseudoDynamicRupture(
rupture = gf.PseudoDynamicRupture(
lat=0.,
lon=0.,
north_shift=2.*km,
@ -66,16 +66,16 @@ dyn_rupture = gf.PseudoDynamicRupture(
])
)
dyn_rupture.discretize_patches(store)
rupture.discretize_patches(store)
# Plot the absolute tractions from strike, dip, normal
plot = RuptureView(dyn_rupture, figsize=(8, 4))
plot = RuptureView(rupture, figsize=(8, 4))
plot.draw_patch_parameter('traction')
plot.draw_nucleation_point()
plot.save('dynamic_complex_tractions.png')
# Plot the modelled dislocations
plot = RuptureView(dyn_rupture, figsize=(8, 4))
plot = RuptureView(rupture, figsize=(8, 4))
plot.draw_dislocation()
# We can also define a time for the snapshot:
# plot.draw_dislocation(time=1.5)
@ -92,7 +92,8 @@ waveform_target = gf.Target(
lon=0.,
east_shift=10*km,
north_shift=30.*km,
interpolation='multilinear',
store_id=store_id)
result = engine.process(dyn_rupture, waveform_target)
result.snuffle()
response = engine.process(rupture, waveform_target)
response.snuffle()

@ -2,6 +2,30 @@
#
# The Pyrocko Developers, 21st Century
# ---|P------/S----------~Lg----------
'''
.. _coordinate-system-names:
Coordinate systems
..................
Coordinate system names commonly used in source models.
================= ============================================
Name Description
================= ============================================
``'xyz'`` northing, easting, depth in [m]
``'xy'`` northing, easting in [m]
``'latlon'`` latitude, longitude in [deg]
``'lonlat'`` longitude, latitude in [deg]
``'latlondepth'`` latitude, longitude in [deg], depth in [m]
================= ============================================
'''
from __future__ import absolute_import, division, print_function
from collections import defaultdict
@ -2359,7 +2383,8 @@ class RectangularSource(SourceWithDerivedMagnitude):
class PseudoDynamicRupture(SourceWithDerivedMagnitude):
'''Merged Eikonal and Okada Source for quasi-dynamic rupture modeling.
'''
Combined Eikonal and Okada quasi-dynamic rupture model.
Details are described in :doc:`/topics/pseudo-dynamic-rupture`.
Note: attribute `stf` is not used so far, but kept for future applications.
@ -2369,72 +2394,73 @@ class PseudoDynamicRupture(SourceWithDerivedMagnitude):
strike = Float.T(
default=0.0,
help='strike direction in [deg], measured clockwise from north')
help='Strike direction in [deg], measured clockwise from north.')
dip = Float.T(
default=0.0,
help='dip angle in [deg], measured downward from horizontal')
help='Dip angle in [deg], measured downward from horizontal.')
length = Float.T(
default=10. * km,
help='length of rectangular source area in [m]')
help='Length of rectangular source area in [m].')
width = Float.T(
default=5. * km,
help='width of rectangular source area in [m]')
help='Width of rectangular source area in [m].')
anchor = StringChoice.T(
choices=['top', 'top_left', 'top_right', 'center', 'bottom',
'bottom_left', 'bottom_right'],
default='center',
optional=True,
help='anchor point for positioning the plane, can be: ``top, center, '
help='Anchor point for positioning the plane, can be: ``top, center, '
'bottom, top_left, top_right, bottom_left, '
'bottom_right, center_left, center_right``')
'bottom_right, center_left, center_right``.')
nucleation_x__ = Array.T(
default=num.array([0.]),
dtype=num.float,
serialize_as='list',
help='horizontal position of rupture nucleation in normalized fault '
'plane coordinates (``-1.`` = left edge, ``+1.`` = right edge)')
help='Horizontal position of rupture nucleation in normalized fault '
'plane coordinates (``-1.`` = left edge, ``+1.`` = right edge).')
nucleation_y__ = Array.T(
default=num.array([0.]),
dtype=num.float,
serialize_as='list',
help='down-dip position of rupture nucleation in normalized fault '
'plane coordinates (``-1.`` = upper edge, ``+1.`` = lower edge)')
help='Down-dip position of rupture nucleation in normalized fault '
'plane coordinates (``-1.`` = upper edge, ``+1.`` = lower edge).')
nucleation_time__ = Array.T(
optional=True,
help='time in [s] after origin, when nucleation points defined by '
help='Time in [s] after origin, when nucleation points defined by '
'``nucleation_x`` and ``nucleation_y`` rupture.',
dtype=num.float,
serialize_as='list')
gamma = Float.T(
default=0.8,
help='scaling factor between rupture velocity and S-wave velocity: '
r':math:`v_r = \gamma * v_s`')
help='Scaling factor between rupture velocity and S-wave velocity: '
r':math:`v_r = \gamma * v_s`.')
nx = Int.T(
default=2,
help='number of discrete source patches in x direction (along strike)')
help='Number of discrete source patches in x direction (along '
'strike).')
ny = Int.T(
default=2,
help='number of discrete source patches in y direction (down dip)')
help='Number of discrete source patches in y direction (down dip).')
slip = Float.T(
optional=True,
help='maximum slip of the rectangular source [m]. '
help='Maximum slip of the rectangular source [m]. '
'Setting the slip the tractions/stress field '
'will be normalized to accomodate the desired maximum slip.')
rake = Float.T(
optional=True,
help='rake angle in [deg], '
help='Rake angle in [deg], '
'measured counter-clockwise from right-horizontal '
'in on-plane view. Rake is translated into homogenous tractions '
'in strike and up-dip direction. ``rake`` is mutually exclusive '
@ -2443,19 +2469,19 @@ class PseudoDynamicRupture(SourceWithDerivedMagnitude):
patches = List.T(
OkadaSource.T(),
optional=True,
help='list of all boundary elements/sub faults/fault patches')
help='List of all boundary elements/sub faults/fault patches.')
patch_mask__ = Array.T(
dtype=num.bool,
serialize_as='list',
shape=(None,),
optional=True,
help='mask for all boundary elements/sub faults/fault patches. True '
help='Mask for all boundary elements/sub faults/fault patches. True '
'leaves the patch in the calculation, False excludes the patch.')
tractions = TractionField.T(
optional=True,
help='traction field the rupture plane is exposed to. See the'
help='Traction field the rupture plane is exposed to. See the'
':py:mod:`pyrocko.gf.tractions` module for more details. '
'If ``tractions=None`` and ``rake`` is given'
' :py:class:`~pyrocko.gf.tractions.DirectedTractions` will'
@ -2463,44 +2489,44 @@ class PseudoDynamicRupture(SourceWithDerivedMagnitude):
coef_mat = Array.T(
optional=True,
help='coefficient matrix linking traction and dislocation field',
help='Coefficient matrix linking traction and dislocation field.',
dtype=num.float,
shape=(None, None))
eikonal_decimation = Int.T(
optional=True,
default=1,
help='sub-source eikonal factor, a smaller eikonal factor will'
help='Sub-source eikonal factor, a smaller eikonal factor will'
' increase the accuracy of rupture front calculation but'
' increases also the computation time.')
decimation_factor = Int.T(
optional=True,
default=1,
help='sub-source decimation factor, a larger decimation will'
help='Sub-source decimation factor, a larger decimation will'
' make the result inaccurate but shorten the necessary'
' computation time (use for testing puposes only).')
nthreads = Int.T(
optional=True,
default=1,
help='number of threads for Okada forward modelling, '
help='Number of threads for Okada forward modelling, '
'matrix inversion and calculation of point subsources. '
'Note: for small/medium matrices 1 thread is most efficient!')
'Note: for small/medium matrices 1 thread is most efficient.')
pure_shear = Bool.T(
optional=True,
default=False,
help='calculate only shear tractions and omit tensile tractions.')
help='Calculate only shear tractions and omit tensile tractions.')
smooth_rupture = Bool.T(
default=True,
help='smooth the tractions by weighting partially ruptured'
help='Smooth the tractions by weighting partially ruptured'
' fault patches.')
aggressive_oversampling = Bool.T(
default=False,
help='aggressive oversampling for basesource discretization. '
help='Aggressive oversampling for basesource discretization. '
'When using \'multilinear\' interpolation oversampling has'
' practically no effect.')
@ -2585,14 +2611,17 @@ class PseudoDynamicRupture(SourceWithDerivedMagnitude):
self.patch_mask__ = patch_mask
def get_tractions(self):
'''Return source traction vectors
'''
Get source traction vectors.
If :py:attr:`rake` is given, unit length directed traction vectors
(:py:class:`pyrocko.gf.tractions.DirectedTractions`) are returned, else
the given :py:attr:`tractions` are used.
(:py:class:`~pyrocko.gf.tractions.DirectedTractions`) are returned,
else the given :py:attr:`tractions` are used.
:returns: traction vectors per patch
:rtype: :py:class:`numpy.ndarray` of shape ``(n_patches, 3)``
:returns:
Traction vectors per patch.
:rtype:
:py:class:`~numpy.ndarray`: ``(n_patches, 3)``.
'''
if self.rake is not None:
@ -2600,7 +2629,7 @@ class PseudoDynamicRupture(SourceWithDerivedMagnitude):
raise ValueError('Rake must be a real number, not NaN.')
logger.warning(
'tractions are derived based on the given source rake')
'Tractions are derived based on the given source rake.')
tractions = DirectedTractions(rake=self.rake)
else:
tractions = self.tractions
@ -2625,7 +2654,7 @@ class PseudoDynamicRupture(SourceWithDerivedMagnitude):
def check_conflicts(self):
if self.tractions and self.rake:
raise AttributeError(
'tractions and rake are mutually exclusive')
'Tractions and rake are mutually exclusive.')
if self.tractions is None and self.rake is None:
self.rake = 0.
@ -2634,9 +2663,9 @@ class PseudoDynamicRupture(SourceWithDerivedMagnitude):
if self.slip is not None or self.tractions is not None:
if store is None:
raise DerivedMagnitudeError(
'magnitude for a rectangular source with slip or '
'Magnitude for a rectangular source with slip or '
'tractions defined can only be derived when earth model '
'is set')
'is set.')
moment_rate, calc_times = self.discretize_basesource(
store, target=target).get_moment_rate(store.config.deltat)
@ -2655,18 +2684,18 @@ class PseudoDynamicRupture(SourceWithDerivedMagnitude):
return 1.0
def outline(self, cs='xyz'):
''' Get source outline corner coordinates
:param cs: output coordinate system. Choose between:
``xyz`` - north_shift, east_shift, depth in [m],
``xy`` - north_shift, east_shift in [m],
``latlon`` - Latitude, Longitude in [deg],
``lonlat`` - Longitude, Latitude in [deg] or
``latlondepth`` - Latitude, Longitude in [deg], depth in [m].
:type cs: optional, str
:returns: Corner points in desired coordinate system
:rtype: :py:class:`numpy.ndarray` of shape ``(5, [2, 3])``
'''
Get source outline corner coordinates.
:param cs:
:ref:`Output coordinate system <coordinate-system-names>`.
:type cs:
optional, str
:returns:
Corner points in desired coordinate system.
:rtype:
:py:class:`~numpy.ndarray`: ``(5, [2, 3])``.
'''
points = outline_rect_source(self.strike, self.dip, self.length,
self.width, self.anchor)
@ -2693,23 +2722,23 @@ class PseudoDynamicRupture(SourceWithDerivedMagnitude):
axis=1)
def points_on_source(self, cs='xyz', **kwargs):
''' Convert relative x, y coordinates to geographical coordinates
'''
Convert relative plane coordinates to geographical coordinates.
Given x and y coordinates (relative source coordinates between -1.
and 1.) are converted to desired geographical coordinates. Coordinates
need to be given as :py:class:`numpy.ndarray` arguments ``points_x``
and ``points_y``
:param cs: output coordinate system. Choose between:
``xyz`` - north_shift, east_shift, depth in [m],
``xy`` - north_shift, east_shift in [m],
``latlon`` - Latitude, Longitude in [deg],
``lonlat`` - Longitude, Latitude in [deg] or
``latlondepth`` - Latitude, Longitude in [deg], depth in [m].
:type cs: optional, str
:returns: point coordinates in desired coordinate system
:rtype: :py:class:`numpy.ndarray` of shape ``(n_points, [2, 3])``
need to be given as :py:class:`~numpy.ndarray` arguments ``points_x``
and ``points_y``.
:param cs:
:ref:`Output coordinate system <coordinate-system-names>`.
:type cs:
optional, str
:returns:
Point coordinates in desired coordinate system.
:rtype:
:py:class:`~numpy.ndarray`: ``(n_points, [2, 3])``.
'''
points = points_on_rect_source(
self.strike, self.dip, self.length, self.width,
@ -2770,19 +2799,24 @@ class PseudoDynamicRupture(SourceWithDerivedMagnitude):
def _discretize_points(self, store, *args, **kwargs):
'''
Discretize source plane with equal vertical and horizontal spacing
Discretize source plane with equal vertical and horizontal spacing.
Arguments and keyword arguments needed for :py:meth:`points_on_source`.
Additional ``*args`` and ``**kwargs`` are passed to
:py:meth:`points_on_source`.
:param store: Greens function database (needs to cover whole region of
the source)
:type store: :py:class:`pyrocko.gf.store.Store`
:param store:
Green's function database (needs to cover whole region of the
source).
:type store:
:py:class:`~pyrocko.gf.store.Store`
:returns: Number of points in strike and dip direction, distance
:returns:
Number of points in strike and dip direction, distance
between adjacent points, coordinates (latlondepth) and coordinates
(xy on fault) for discrete points
:rtype: int, int, float, :py:class:`numpy.ndarray`,
:py:class:`numpy.ndarray`
(xy on fault) for discrete points.
:rtype:
(int, int, float, :py:class:`~numpy.ndarray`,
:py:class:`~numpy.ndarray`).
'''
anch_x, anch_y = map_anchor[self.anchor]
@ -2834,19 +2868,30 @@ class PseudoDynamicRupture(SourceWithDerivedMagnitude):
def _discretize_rupture_v(self, store, interpolation='nearest_neighbor',
points=None):
'''
Get rupture velocity for discrete points on source plane
:param store: Greens function database (needs to cover whole region of
of the source)
:type store: optional, :py:class:`pyrocko.gf.store.Store`
:param interpolation: Interpolation method to use ("multilinear")
:type interpolation: optional, str
:param points: xy coordinates on fault (-1.:1.) of discrete points
:type points: optional, :py:class:`numpy.ndarray`, ``(n_points, 2)``
:returns: Rupture velocity assumed as :math:`v_s * \\gamma` for
discrete points
:rtype: :py:class:`numpy.ndarray`, ``(points.shape[0], 1)``
Get rupture velocity for discrete points on source plane.
:param store:
Green's function database (needs to cover the whole region of the
source)
:type store:
optional, :py:class:`~pyrocko.gf.store.Store`
:param interpolation:
Interpolation method to use (choose between ``'nearest_neighbor'``
and ``'multilinear'``).
:type interpolation:
optional, str
:param points:
Coordinates on fault (-1.:1.) of discrete points.
:type points:
optional, :py:class:`~numpy.ndarray`: ``(n_points, 2)``
:returns:
Rupture velocity assumed as :math:`v_s * \\gamma` for discrete
points.
:rtype:
:py:class:`~numpy.ndarray`: ``(n_points, )``.
'''
if points is None:
@ -2861,30 +2906,42 @@ class PseudoDynamicRupture(SourceWithDerivedMagnitude):
self, store, interpolation='nearest_neighbor',
vr=None, times=None, *args, **kwargs):
'''
Get rupture start time for discrete points on source plane
:param store: Greens function database (needs to cover whole region of
of the source)
:type store: :py:class:`pyrocko.gf.store.Store`
:param interpolation: Interpolation method to use (choose between
``nearest_neighbor`` and ``multilinear``)
:type interpolation: optional, str
:param vr: Array, containing rupture user defined rupture velocity
values
:type vr: optional, :py:class:`numpy.ndarray`
:param times: Array, containing zeros, where rupture is starting, real
positive numbers at later secondary nucleation points and -1, where
time will be calculated. If not given, rupture starts at
nucleation_x, nucleation_y. Times are given for discrete points
with equal horizontal and vertical spacing
:type times: optional, :py:class:`numpy.ndarray`
:returns: Coordinates (latlondepth), Coordinates (xy), rupture velocity
rupture propagation time of discrete points
:rtype: :py:class:`numpy.ndarray`, ``(points.shape[0], 1)``,
:py:class:`numpy.ndarray`, ``(points.shape[0], 1)``,
:py:class:`numpy.ndarray`, ``(n_points_dip, n_points_strike)``,
:py:class:`numpy.ndarray`, ``(n_points_dip, n_points_strike)``
Get rupture start time for discrete points on source plane.
:param store:
Green's function database (needs to cover whole region of the
source)
:type store:
:py:class:`~pyrocko.gf.store.Store`
:param interpolation:
Interpolation method to use (choose between ``'nearest_neighbor'``
and ``'multilinear'``).
:type interpolation:
optional, str
:param vr:
Array, containing rupture user defined rupture velocity values.
:type vr:
optional, :py:class:`~numpy.ndarray`
:param times:
Array, containing zeros, where rupture is starting, real positive
numbers at later secondary nucleation points and -1, where time
will be calculated. If not given, rupture starts at nucleation_x,
nucleation_y. Times are given for discrete points with equal
horizontal and vertical spacing.
:type times:
optional, :py:class:`~numpy.ndarray`
:returns:
Coordinates (latlondepth), coordinates (xy), rupture velocity,
rupture propagation time of discrete points.
:rtype:
:py:class:`~numpy.ndarray`: ``(n_points, 3)``,
:py:class:`~numpy.ndarray`: ``(n_points, 2)``,
:py:class:`~numpy.ndarray`: ``(n_points_dip, n_points_strike)``,
:py:class:`~numpy.ndarray`: ``(n_points_dip, n_points_strike)``.
'''
nx, ny, delta, points, points_xy = self._discretize_points(
store, cs='xyz')
@ -2943,21 +3000,29 @@ class PseudoDynamicRupture(SourceWithDerivedMagnitude):
def get_vr_time_interpolators(
self, store, interpolation='nearest_neighbor', force=False,
*args, **kwargs):
**kwargs):
'''
Calculate/return interpolators for rupture velocity and rupture time
Arguments and keyword arguments needed for :py:meth:`discretize_time`.
:param store: Greens function database (needs to cover whole region of
of the source)
:type store: :py:class:`pyrocko.gf.store.Store`
:param interpolation: Kind of interpolation used. Choice between
``multilinear`` and ``nearest_neighbor``
:type interpolation: optional, str
:param force: Force recalculation of the interpolators (e.g. after
change of nucleation point locations/times). Default is False
:type force: optional, bool
Get interpolators for rupture velocity and rupture time.
Additional ``**kwargs`` are passed to :py:meth:`discretize_time`.
:param store:
Green's function database (needs to cover whole region of the
source).
:type store:
:py:class:`~pyrocko.gf.store.Store`
:param interpolation:
Interpolation method to use (choose between ``'nearest_neighbor'``
and ``'multilinear'``).
:type interpolation:
optional, str
:param force:
Force recalculation of the interpolators (e.g. after change of
nucleation point locations/times). Default is ``False``.
:type force:
optional, bool
'''
interp_map = {'multilinear': 'linear', 'nearest_neighbor': 'nearest'}
if interpolation not in interp_map:
@ -2966,7 +3031,7 @@ class PseudoDynamicRupture(SourceWithDerivedMagnitude):
if not self._interpolators.get(interpolation, False) or force:
_, points_xy, vr, times = self.discretize_time(
store, *args, **kwargs)
store, **kwargs)
if self.length <= 0.:
raise ValueError(
@ -2995,32 +3060,42 @@ class PseudoDynamicRupture(SourceWithDerivedMagnitude):
def discretize_patches(
self, store, interpolation='nearest_neighbor', force=False,
grid_shape=(),
*args, **kwargs):
**kwargs):
'''
Get rupture start time and OkadaSource elements for points on rupture
Get rupture start time and OkadaSource elements for points on rupture.
All source elements and their corresponding center points are
calculated and stored in the :py:attr:`patches` attribute
Arguments and keyword arguments needed for :py:meth:`discretize_time`.
:param store: Greens function database (needs to cover whole region of
of the source)
:type store: :py:class:`pyrocko.gf.store.Store`
:param interpolation: Kind of interpolation used. Choice between
``multilinear`` and ``nearest_neighbor``
:type interpolation: optional, str
:param force: Force recalculation of the vr and time interpolators (
e.g. after change of nucleation point locations/times). Default is
False
:type force: optional, bool
:param grid_shape: Desired sub fault patch grid size (nlength, nwidth).
Either factor or grid_shape should be set.
:type grid_shape: optional, tuple of int
calculated and stored in the :py:attr:`patches` attribute.
Additional ``**kwargs`` are passed to :py:meth:`discretize_time`.
:param store:
Green's function database (needs to cover whole region of the
source).
:type store:
:py:class:`~pyrocko.gf.store.Store`
:param interpolation:
Interpolation method to use (choose between ``'nearest_neighbor'``
and ``'multilinear'``).
:type interpolation:
optional, str
:param force:
Force recalculation of the vr and time interpolators ( e.g. after
change of nucleation point locations/times). Default is ``False``.
:type force:
optional, bool
:param grid_shape:
Desired sub fault patch grid size (nlength, nwidth). Either factor
or grid_shape should be set.
:type grid_shape:
optional, tuple of int
'''
nx, ny, times, vr, time_interpolator, vr_interpolator = \
self.get_vr_time_interpolators(
store, *args,
store,
interpolation=interpolation, force=force, **kwargs)
anch_x, anch_y = map_anchor[self.anchor]
@ -3083,16 +3158,23 @@ class PseudoDynamicRupture(SourceWithDerivedMagnitude):
def discretize_basesource(self, store, target=None):
'''
Prepare source for synthetic waveform calculation
:param store: Greens function database (needs to cover whole region of
of the source)
:type store: :py:class:`pyrocko.gf.store.Store`
:param target: Target information
:type target: optional, :py:class:`pyrocko.gf.targets.Target`
:returns: Source discretized by a set of moment tensors and times
:rtype: :py:class:`pyrocko.gf.meta.DiscretizedMTSource`
Prepare source for synthetic waveform calculation.
:param store:
Green's function database (needs to cover whole region of the
source).
:type store:
:py:class:`~pyrocko.gf.store.Store`
:param target:
Target information.
:type target:
optional, :py:class:`~pyrocko.gf.targets.Target`
:returns:
Source discretized by a set of moment tensors and times.
:rtype:
:py:class:`~pyrocko.gf.meta.DiscretizedMTSource`
'''
if not target:
interpolation = 'nearest_neighbor'
@ -3286,8 +3368,7 @@ class PseudoDynamicRupture(SourceWithDerivedMagnitude):
def calc_coef_mat(self):
'''
Calculate linear coefficient relating tractions and dislocations on the
patches
Calculate coefficients connecting tractions and dislocations.
'''
if not self.patches:
raise ValueError(
@ -3298,15 +3379,18 @@ class PseudoDynamicRupture(SourceWithDerivedMagnitude):
def get_patch_attribute(self, attr):
'''
Get array of patch attributes
Get patch attributes.
:param attr: Attribute of fault patches which shall be listed for
all patches in an array (possible attributes: check
:py:class`pyrocko.modelling.okada.OkadaSource`)
:type attr: str
:param attr:
Name of selected attribute (see
:py:class`pyrocko.modelling.okada.OkadaSource`).
:type attr:
str
:returns: Array of attribute values per fault patch
:rtype: :py:class`numpy.ndarray`
:returns:
Array with attribute value for each fault patch.
:rtype:
:py:class:`~numpy.ndarray`
'''
if not self.patches:
@ -3321,28 +3405,31 @@ class PseudoDynamicRupture(SourceWithDerivedMagnitude):
interpolation='nearest_neighbor',
**kwargs):
'''
Get slip per subfault patch for given time after rupture start
:param time: time after origin [s], for which slip is computed. If not
given, final static slip is returned
:type time: optional, float > 0.
:param scale_slip: If ``True`` and :py:attr:`slip` given, all slip
values are scaled to fit the given maximum slip
:type scale_slip: optional, bool
:param interpolation: Kind of interpolation used. Choice between
``multilinear`` and ``nearest_neighbor``
:type interpolation: optional, str
:returns: inverted dislocations (:math:`u_{strike}, u_{dip} ,
u_{tensile}`) for each source patch. order:
.. math::
&[\\\\
&[u_{strike, patch1}, u_{dip, patch1}, u_{tensile, patch1}],\\\\
&[u_{strike, patch2}, ...]]\\\\
:rtype: :py:class:`numpy.ndarray`, ``(n_sources, 3)``
Get slip per subfault patch for given time after rupture start.
:param time:
Time after origin [s], for which slip is computed. If not
given, final static slip is returned.
:type time:
optional, float > 0.
:param scale_slip:
If ``True`` and :py:attr:`slip` given, all slip values are scaled
to fit the given maximum slip.
:type scale_slip:
optional, bool
:param interpolation:
Interpolation method to use (choose between ``'nearest_neighbor'``
and ``'multilinear'``).
:type interpolation:
optional, str
:returns:
Inverted dislocations (:math:`u_{strike}, u_{dip}, u_{tensile}`)
for each source patch.
:rtype:
:py:class:`~numpy.ndarray`: ``(n_sources, 3)``
'''
if self.patches is None:
@ -3461,48 +3548,59 @@ class PseudoDynamicRupture(SourceWithDerivedMagnitude):
interpolation='nearest_neighbor',
**kwargs):
'''
Get slip change inverted from patches depending on certain deltat
Get slip change snapshots.
The time intervall, within which the slip changes are computed is
determined by the sampling rate of the Greens function database or
``deltat``. Arguments and keyword arguments needed for
:py:meth:`get_slip`.
The time interval, within which the slip changes are computed is
determined by the sampling rate of the Green's function database or
``deltat``. Additional ``**kwargs`` are passed to :py:meth:`get_slip`.
:param store: Greens function database (needs to cover whole region of
of the source). Its deltat [s] is used as time increment for slip
:param store:
Green's function database (needs to cover whole region of of the
source). Its sampling interval is used as time increment for slip
difference calculation. Either ``deltat`` or ``store`` should be
given.
:type store: optional, :py:class:`pyrocko.gf.store.Store`
:param deltat: time increment for slip difference calculation [s].
Either ``deltat`` or ``store`` should be given.
:type deltat: optional, float
:param delta: If ``True``, slip differences between two time steps are
given. If ``False``, cumulative slip for all time steps
:type delta: optional, bool
:param interpolation: Kind of interpolation used. Choice between
``multilinear`` and ``nearest_neighbor``
:type interpolation: optional, str
:returns: displacement changes(:math:`\\Delta u_{strike},
:type store:
optional, :py:class:`~pyrocko.gf.store.Store`
:param deltat:
Time interval for slip difference calculation [s]. Either
``deltat`` or ``store`` should be given.
:type deltat:
optional, float
:param delta:
If ``True``, slip differences between two time steps are given. If
``False``, cumulative slip for all time steps.
:type delta:
optional, bool
:param interpolation:
Interpolation method to use (choose between ``'nearest_neighbor'``
and ``'multilinear'``).
:type interpolation:
optional, str
:returns:
Displacement changes(:math:`\\Delta u_{strike},
\\Delta u_{dip} , \\Delta u_{tensile}`) for each source patch and
time; corner times, for which delta slip is computed. The order of
displacement changes array is:
.. math::
&[[\\\\
&[\\Delta u_{strike, patch1, t1},
\\Delta u_{dip, patch1, t1},
\\Delta u_{tensile, patch1, t1}],\\\\
&[\\Delta u_{strike, patch1, t2},
\\Delta u_{dip, patch1, t2},
\\Delta u_{tensile, patch1, t2}]\\\\
&], [\\\\
&[\\Delta u_{strike, patch2, t1}, ...],\\\\
&[\\Delta u_{strike, patch2, t2}, ...]]]\\\\
:rtype: :py:class:`numpy.ndarray`, ``(n_sources, n_times, 3)``
:py:class:`numpy.ndarray`, ``(n_times, 1)``
.. math::
&[[\\\\
&[\\Delta u_{strike, patch1, t1},
\\Delta u_{dip, patch1, t1},
\\Delta u_{tensile, patch1, t1}],\\\\
&[\\Delta u_{strike, patch1, t2},
\\Delta u_{dip, patch1, t2},
\\Delta u_{tensile, patch1, t2}]\\\\
&], [\\\\
&[\\Delta u_{strike, patch2, t1}, ...],\\\\
&[\\Delta u_{strike, patch2, t2}, ...]]]\\\\
:rtype: :py:class:`~numpy.ndarray`: ``(n_sources, n_times, 3)``,
:py:class:`~numpy.ndarray`: ``(n_times, )``
'''
if store and deltat:
raise AttributeError(
@ -3558,32 +3656,33 @@ class PseudoDynamicRupture(SourceWithDerivedMagnitude):
def get_slip_rate(self, *args, **kwargs):
'''
Get slip rate inverted from patches
Get slip rate inverted from patches.
The time intervall, within which the slip rates are computed is
determined by the sampling rate of the Greens function database or
``deltat``. Arguments and keyword arguments needed for
The time interval, within which the slip rates are computed is
determined by the sampling rate of the Green's function database or
``deltat``. Additional ``*args`` and ``**kwargs`` are passed to
:py:meth:`get_delta_slip`.
:returns: slip rates(:math:`\\Delta u_{strike}/\\Delta t`,
:returns:
Slip rates (:math:`\\Delta u_{strike}/\\Delta t`,
:math:`\\Delta u_{dip}/\\Delta t, \\Delta u_{tensile}/\\Delta t`)
for each source patch and time; corner times, for which slip rate
is computed. The order of sliprate array is:
.. math::
.. math::
&[[\\\\
&[\\Delta u_{strike, patch1, t1}/\\Delta t,
\\Delta u_{dip, patch1, t1}/\\Delta t,
\\Delta u_{tensile, patch1, t1}/\\Delta t],\\\\
&[\\Delta u_{strike, patch1, t2}/\\Delta t,
\\Delta u_{dip, patch1, t2}/\\Delta t,
\\Delta u_{tensile, patch1, t2}/\\Delta t]], [\\\\
&[\\Delta u_{strike, patch2, t1}/\\Delta t, ...],\\\\
&[\\Delta u_{strike, patch2, t2}/\\Delta t, ...]]]\\\\
&[[\\\\
&[\\Delta u_{strike, patch1, t1}/\\Delta t,
\\Delta u_{dip, patch1, t1}/\\Delta t,
\\Delta u_{tensile, patch1, t1}/\\Delta t],\\\\
&[\\Delta u_{strike, patch1, t2}/\\Delta t,
\\Delta u_{dip, patch1, t2}/\\Delta t,
\\Delta u_{tensile, patch1, t2}/\\Delta t]], [\\\\
&[\\Delta u_{strike, patch2, t1}/\\Delta t, ...],\\\\
&[\\Delta u_{strike, patch2, t2}/\\Delta t, ...]]]\\\\
:rtype: :py:class:`numpy.ndarray`, ``(n_sources, n_times, 3)``
:py:class:`numpy.ndarray`, ``(n_times, 1)``
:rtype: :py:class:`~numpy.ndarray`: ``(n_sources, n_times, 3)``,
:py:class:`~numpy