[cig-commits] [commit] devel: adds scalar moment and moment magnitude information to source output (8c5d25d)
cig_noreply at geodynamics.org
cig_noreply at geodynamics.org
Tue Sep 16 08:26:17 PDT 2014
Repository : https://github.com/geodynamics/specfem3d_globe
On branch : devel
Link : https://github.com/geodynamics/specfem3d_globe/compare/0aa2df069164153a157cf61edc5ea1bce1e70644...6034d3445ce173fc6a0a1cfd5c31dfd2558a2eaf
>---------------------------------------------------------------
commit 8c5d25d24d616fc8fc61643fc384077ad4c7ba49
Author: daniel peter <peterda at ethz.ch>
Date: Wed Sep 3 15:05:11 2014 +0200
adds scalar moment and moment magnitude information to source output
>---------------------------------------------------------------
8c5d25d24d616fc8fc61643fc384077ad4c7ba49
src/specfem3D/get_cmt.f90 | 107 +++++++++++++++++++++++++++++++++++++--
src/specfem3D/locate_sources.f90 | 16 ++++--
2 files changed, 116 insertions(+), 7 deletions(-)
diff --git a/src/specfem3D/get_cmt.f90 b/src/specfem3D/get_cmt.f90
index f895d87..7e12553 100644
--- a/src/specfem3D/get_cmt.f90
+++ b/src/specfem3D/get_cmt.f90
@@ -95,11 +95,15 @@
! debug
!print*,'line ----',string,'----'
- ! read header line with event information
+ ! reads header line with event information (assumes fixed format)
! old line: read(string,"(a4,i5,i3,i3,i3,i3,f6.2)") datasource,yr,mo,da,ho,mi,sec
- ! reads in chunks of the first line (which contain numbers)
- ! to get rid of the first datasource qualifyer string like PDE,PDEQ,.. which can have variable length)
+ ! reads header line with event information (free format)
+ ! gets rid of the first datasource qualifyer string which can have variable length, like:
+ ! "PDE 2014 9 3 .."
+ ! " PDEQ2014 9 3 .."
+ ! " MLI 1971 1 1 .."
+ ! note: globalcmt.org solutions might have missing spaces after datasource qualifier
!
! reads in year,month,day,hour,minutes,seconds
istart = 1
@@ -167,7 +171,7 @@
! checks time information
- if (yr <= 0 .or. yr > 10000) then
+ if (yr <= 0 .or. yr > 3000) then
write(IMAIN,*) 'Error reading year: ',yr,' in source ',isource,'is invalid'
stop 'Error reading year out of header line in CMTSOLUTION file'
endif
@@ -243,6 +247,8 @@
endif
read(string(7:len_trim(string)),*) depth(isource)
+ ! seismic moment tensor
+ ! CMTSOLUTION: components given in dyne-cm
! read Mrr
read(IIN,"(a)",iostat=ier) string
if (ier /= 0) then
@@ -370,3 +376,96 @@
end function
end subroutine get_cmt
+
+!
+!-------------------------------------------------------------------------------------------------
+!
+
+ double precision function get_cmt_scalar_moment(Mxx,Myy,Mzz,Mxy,Mxz,Myz)
+
+ ! calculates scalar moment (M0)
+
+ use constants,only: RHOAV,R_EARTH,PI,GRAV
+
+ implicit none
+
+ double precision, intent(in) :: Mxx,Myy,Mzz,Mxy,Mxz,Myz
+ ! local parameters
+ double precision :: scalar_moment,scaleM
+
+ ! scalar moment:
+ ! see equation (1.4) in P.G. Silver and T.H. Jordan, 1982,
+ ! "Optimal estiamtion of scalar seismic moment",
+ ! Geophys. J.R. astr. Soc., 70, 755 - 787
+ !
+ ! or see equation (5.91) in Dahlen & Tromp (1998)
+ !
+ ! moment tensor M is a symmetric 3x3 tensor, and has six independent components
+ !
+ ! the euclidean matrix norm is invariant under rotation.
+ ! thus, input can be:
+ ! Mxx,Myy,Mzz,Mxy,Mxz,Myz
+ ! or
+ ! Mrr,Mtt,Mpp,Mrt,Mrp,Mtp
+ !
+ ! euclidean (or Frobenius) norm of a matrix: M0**2 = sum( Mij**2 )
+ scalar_moment = Mxx**2 + Myy**2 + Mzz**2 + 2.d0 * Mxy**2 + 2.d0 * Mxz**2 + 2.d0 * Myz**2
+
+ ! adds 1/2 to be coherent with double couple or point sources
+ scalar_moment = dsqrt(scalar_moment/2.0d0)
+
+ ! note: moment tensor is non-dimensionalized
+ !
+ ! re-adds scale factor for the moment tensor
+ ! CMTSOLUTION file values are in dyne.cm
+ ! 1 dyne is 1 gram * 1 cm / (1 second)^2
+ ! 1 Newton is 1 kg * 1 m / (1 second)^2
+ ! thus 1 Newton = 100,000 dynes
+ ! therefore 1 dyne.cm = 1e-7 Newton.m
+ scaleM = 1.d7 * RHOAV * (R_EARTH**5) * PI * GRAV * RHOAV
+
+ ! return value (in dyne-cm)
+ get_cmt_scalar_moment = scalar_moment * scaleM
+
+ end function
+
+!
+!-------------------------------------------------------------------------------------------------
+!
+
+ double precision function get_cmt_moment_magnitude(Mxx,Myy,Mzz,Mxy,Mxz,Myz)
+
+ ! calculates scalar moment (M0)
+
+ implicit none
+
+ double precision, intent(in) :: Mxx,Myy,Mzz,Mxy,Mxz,Myz
+ ! local parameters
+ double precision :: M0,Mw
+ double precision,external :: get_cmt_scalar_moment
+
+ ! scalar moment
+ M0 = get_cmt_scalar_moment(Mxx,Myy,Mzz,Mxy,Mxz,Myz)
+
+ ! moment magnitude by Hanks & Kanamori, 1979
+ ! Mw = 2/3 log( M0 ) - 10.7 (dyne-cm)
+ !
+ ! alternative forms:
+ ! Mw = 2/3 ( log( M0 ) - 16.1 ) (N-m) "moment magnitude" by Hanks & Kanamori(1979) or "energy magnitude" by Kanamori (1977)
+ !
+ ! Aki & Richards ("Quantitative Seismology",2002):
+ ! Mw = 2/3 ( log( M0 ) - 9.1 ) (N-m)
+ !
+ ! conversion: dyne-cm = 10**-7 N-m
+ !
+ ! we follow here the USGS magnitude policy:
+ ! "All USGS statements of moment magnitude should use M = (log M0)/1.5-10.7
+ ! for converting from scalar moment M0 to moment magnitude. (..)"
+ ! see: http://earthquake.usgs.gov/aboutus/docs/020204mag_policy.php
+
+ Mw = 2.d0/3.d0 * log10( M0 ) - 10.7
+
+ ! return value
+ get_cmt_moment_magnitude = Mw
+
+ end function
diff --git a/src/specfem3D/locate_sources.f90 b/src/specfem3D/locate_sources.f90
index e2df265..9dc1e0c 100644
--- a/src/specfem3D/locate_sources.f90
+++ b/src/specfem3D/locate_sources.f90
@@ -124,6 +124,9 @@
integer :: imin,imax,jmin,jmax,kmin,kmax
double precision :: f0,t0_ricker
+ double precision, external :: get_cmt_scalar_moment
+ double precision, external :: get_cmt_moment_magnitude
+
! mask source region (mask values are between 0 and 1, with 0 around sources)
real(kind=CUSTOM_REAL), dimension(:,:,:,:),allocatable :: mask_source
@@ -665,6 +668,13 @@
write(IMAIN,*) ' half duration: ',hdur(isource),' seconds'
endif
write(IMAIN,*) ' time shift: ',tshift_cmt(isource),' seconds'
+ write(IMAIN,*)
+ write(IMAIN,*) 'magnitude of the source:'
+ write(IMAIN,*) ' scalar moment M0 = ', &
+ get_cmt_scalar_moment(Mxx(isource),Myy(isource),Mzz(isource),Mxy(isource),Mxz(isource),Myz(isource)),' dyne-cm'
+ write(IMAIN,*) ' moment magnitude Mw = ', &
+ get_cmt_moment_magnitude(Mxx(isource),Myy(isource),Mzz(isource),Mxy(isource),Mxz(isource),Myz(isource))
+ write(IMAIN,*)
! writes out actual source position to VTK file
write(IOUT_VTK,'(3e18.6)') sngl(x_found_source(isource_in_this_subset)), &
@@ -896,6 +906,7 @@
double precision, external :: comp_source_time_function,comp_source_spectrum
double precision, external :: comp_source_time_function_rickr
+ double precision, external :: get_cmt_scalar_moment
character(len=150) :: plot_file
@@ -925,9 +936,8 @@
status='unknown',iostat=ier)
if (ier /= 0 ) call exit_mpi(0,'Error opening plot_source_time_function file')
- scalar_moment = Mxx(isource)**2 + Myy(isource)**2 + Mzz(isource)**2 &
- + Mxy(isource)**2 + Mxz(isource)**2 + Myz(isource)**2
- scalar_moment = dsqrt(scalar_moment/2.0d0)
+ ! calculates scalar moment M0
+ scalar_moment = get_cmt_scalar_moment(Mxx(isource),Myy(isource),Mzz(isource),Mxy(isource),Mxz(isource),Myz(isource))
! define t0 as the earliest start time
! note: this calculation here is only used for outputting the plot_source_time_function file
More information about the CIG-COMMITS
mailing list