├── User’s manual.pdf ├── README.md ├── chmod_all_scripts.sh ├── CFSsrc ├── computeCFS │ ├── computeCFS │ ├── deg2rad.f90 │ ├── makefile │ ├── computeCFS.f90 │ └── CFF.f90 ├── src │ ├── CoulombStressAnalysis │ ├── deg2rad.f90 │ ├── InitializeStress.f90 │ ├── StressTensor2StressArray.f90 │ ├── StressArray2StressTensor.f90 │ ├── GradientDisp2Strain.f90 │ ├── Strain2Stress.f90 │ ├── makefile │ ├── Rphi.f90 │ ├── TensorTrans.f90 │ ├── CFF.f90 │ ├── generalxy2BL.f90 │ ├── generalBL2xy.f90 │ ├── CoulombStressAnalysis.f90 │ └── DC3D.f └── find_minmax_values │ ├── find_minmax_values │ ├── find_minmax_values.f90 │ └── get_gmt_boundary.f90 ├── readme.txt ├── profile ├── profile.in ├── synthetic_1slipmodel.in ├── cal_CFS.sh ├── draw_CFS.sh └── all.sh ├── OOP ├── synthetic_1slipmodel.in ├── scripts │ ├── find_the_second_nodal_plane.m │ ├── OOP_coefficients.m │ ├── strike_dip_rake_angles2normal_slip_directions.m │ ├── CFF.m │ ├── normal_slip_directions2_strike_dip_rake_angles.m │ ├── OOP1D_vertical_right_lateral_strike_slip.m │ ├── OOP1D_vertical_left_lateral_strike_slip.m │ ├── find_3D_OOP.m │ ├── resolve_OOP.m │ ├── principal_stress2_stress_tensor.f90 │ ├── OOP_thrust.m │ ├── OOP_normal.m │ └── OOPCFFmax.f90 ├── tectonic.sh ├── cal_CFS.sh ├── generate_tectonic_stress.sh ├── draw_CFS.sh └── all.sh ├── grid ├── synthetic_1slipmodel.in ├── cal_CFS.sh ├── draw_CFS.sh └── all.sh ├── faultrace ├── synthetic_1slipmodel.in ├── draw_CFS.sh ├── all.sh ├── cal_CFS.sh └── sampling_faulttrace.in ├── preproc ├── generalxy2BL.m ├── generalBL2xy.m ├── tectonic_stress.m ├── preproc_sampling_grids.m ├── preproc_sampling_OOP.m └── preproc_sampling_profile.m └── drawCFS_script ├── drawgridCFS.sh └── drawgridCFS.m /User’s manual.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jjwangw/CoulombAnalysis/HEAD/User’s manual.pdf -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # CoulombAnalysis 2 | A program used to compute Coulomb stress changes induced by earthquakes 3 | -------------------------------------------------------------------------------- /chmod_all_scripts.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | for file in $(find . -iname "*.sh") 3 | do 4 | chmod +x $file 5 | done 6 | -------------------------------------------------------------------------------- /CFSsrc/computeCFS/computeCFS: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jjwangw/CoulombAnalysis/HEAD/CFSsrc/computeCFS/computeCFS -------------------------------------------------------------------------------- /CFSsrc/src/CoulombStressAnalysis: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jjwangw/CoulombAnalysis/HEAD/CFSsrc/src/CoulombStressAnalysis -------------------------------------------------------------------------------- /CFSsrc/find_minmax_values/find_minmax_values: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jjwangw/CoulombAnalysis/HEAD/CFSsrc/find_minmax_values/find_minmax_values -------------------------------------------------------------------------------- /CFSsrc/src/deg2rad.f90: -------------------------------------------------------------------------------- 1 | real*8 function deg2rad(deg_angle) 2 | implicit none 3 | real*8 deg_angle 4 | deg2rad=deg_angle/180.0d0*acos(-1.0d0) 5 | end 6 | -------------------------------------------------------------------------------- /CFSsrc/computeCFS/deg2rad.f90: -------------------------------------------------------------------------------- 1 | real*8 function deg2rad(deg_angle) 2 | implicit none 3 | real*8 deg_angle 4 | deg2rad=deg_angle/180.0*acos(-1.0) 5 | end 6 | -------------------------------------------------------------------------------- /CFSsrc/src/InitializeStress.f90: -------------------------------------------------------------------------------- 1 | subroutine InitializeStress(stress) 2 | ! 3 | implicit none 4 | ! 5 | real*8 stress(6) 6 | integer*4 i 7 | do i=1,6 8 | stress(i)=0.0 9 | enddo 10 | end 11 | -------------------------------------------------------------------------------- /readme.txt: -------------------------------------------------------------------------------- 1 | This program is termed ‘AutoCoulomb’, which is written to compute Coulomb stress changes imparted by earthquakes. 2 | Email:jjwang@sgg.whu.edu.cn 3 | 8 Oct, 2018 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /profile/profile.in: -------------------------------------------------------------------------------- 1 | 1 2 | 32 104.000000 0.000000 200.000000 20.000000 -100.000000 100.000000 -20.000000 0.000000 90.000000 90.000000 4.000000 0.000000 0.000000 0.000000 0.000000 0.000000 3 | -------------------------------------------------------------------------------- /OOP/synthetic_1slipmodel.in: -------------------------------------------------------------------------------- 1 | 1 2 | 31.549074 104.000000 -0.000000 100.000000 20.000000 0.000000 100.000000 -20.000000 0.000000 0.000000 90.000000 4.000000 0.000000 0.000000 0.000000 0.000000 0.000000 3 | -------------------------------------------------------------------------------- /grid/synthetic_1slipmodel.in: -------------------------------------------------------------------------------- 1 | 1 2 | 31.549074 104.000000 0.000000 100.000000 20.000000 0.000000 100.000000 -20.000000 0.000000 0.000000 90.000000 4.000000 0.000000 0.000000 0.000000 0.000000 0.000000 3 | -------------------------------------------------------------------------------- /profile/synthetic_1slipmodel.in: -------------------------------------------------------------------------------- 1 | 1 2 | 31.549074 104.000000 0.000000 100.000000 20.000000 0.000000 100.000000 -20.000000 0.000000 0.000000 90.000000 4.000000 0.000000 0.000000 0.000000 0.000000 0.000000 3 | -------------------------------------------------------------------------------- /faultrace/synthetic_1slipmodel.in: -------------------------------------------------------------------------------- 1 | 1 2 | 31.549074 104.000000 0.000000 100.000000 20.000000 0.000000 100.000000 -20.000000 0.000000 0.000000 90.000000 4.000000 0.000000 0.000000 0.000000 0.000000 0.000000 3 | -------------------------------------------------------------------------------- /OOP/scripts/find_the_second_nodal_plane.m: -------------------------------------------------------------------------------- 1 | function [strike, dip, rake]=find_the_second_nodal_plane(strike,dip,rake) 2 | [normal,slip]=strike_dip_rake_angles2normal_slip_directions(strike,dip,rake); 3 | [strike,dip,rake]=normal_slip_directions2_strike_dip_rake_angles(slip,normal); -------------------------------------------------------------------------------- /CFSsrc/computeCFS/makefile: -------------------------------------------------------------------------------- 1 | PROG=computeCFS 2 | SRC= computeCFS.f90 \ 3 | CFF.f90 \ 4 | deg2rad.f90 5 | FC= gfortran 6 | FFLAGS= -g -O3 7 | # FFLAGS= -g 8 | OBJS=$(SRC:.f90=.o) 9 | $(PROG):$(OBJS) 10 | $(FC) -o $@ $(OBJS) $(FFLAGS) 11 | %.o:%.f90 12 | $(FC) -c $(FFLAGS) $< 13 | clean: 14 | rm -rf *.o 15 | -------------------------------------------------------------------------------- /CFSsrc/src/StressTensor2StressArray.f90: -------------------------------------------------------------------------------- 1 | subroutine StressTensor2StressArray(stresstensor,stressarray) 2 | ! 3 | implicit none 4 | ! 5 | real*8 stresstensor(3,3),stressarray(6) 6 | integer*4 i,j,n 7 | n=1 8 | do 100 i=1,3 9 | do 200 j=i,3 10 | stressarray(n)=stresstensor(i,j) 11 | n=n+1 12 | 200 continue 13 | 100 continue 14 | end 15 | -------------------------------------------------------------------------------- /OOP/tectonic.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | if [ $# -ne 8 ];then 3 | echo "Usage: ./tectonic.sh " 4 | exit -1 5 | fi 6 | i=0 7 | string=`echo "$1 $2 $3 $4 $5 $6"` 8 | echo "$string" > "$7" 9 | for((i=2;i<=$8;i++)) 10 | do 11 | echo "$string" >> "$7" 12 | done 13 | #cat -n "$7" 14 | echo "done!" 15 | -------------------------------------------------------------------------------- /CFSsrc/src/StressArray2StressTensor.f90: -------------------------------------------------------------------------------- 1 | subroutine StressArray2StressTensor(stressarray,stresstensor) 2 | ! 3 | implicit none 4 | ! 5 | real*8 stressarray(6),stresstensor(3,3) 6 | integer*4 i,j,n 7 | n=1 8 | do 100 i=1,3 9 | do 200 j=1,3 10 | if(j.ge.i)then 11 | stresstensor(i,j)=stressarray(n) 12 | n=n+1 13 | else 14 | stresstensor(i,j)=stresstensor(j,i) 15 | endif 16 | 200 continue 17 | 100 continue 18 | end 19 | -------------------------------------------------------------------------------- /CFSsrc/src/GradientDisp2Strain.f90: -------------------------------------------------------------------------------- 1 | subroutine GradientDisp2Strain(UXX,UYX,UZX,UXY,UYY,UZY,UXZ,UYZ,UZZ,strain) 2 | !transform graident of displacement into strain tensor using strain-displacment 3 | !relationship 4 | ! 5 | implicit none 6 | ! 7 | real*8 UXX,UYX,UZX,UXY,UYY,UZY,UXZ,UYZ,UZZ 8 | real*8 strain(6) 9 | strain(1)=UXX !e11 10 | strain(2)=0.5*(UXY+UYX) !e12 11 | strain(3)=0.5*(UXZ+UZX) !e13 12 | strain(4)=UYY !e22 13 | strain(5)=0.5*(UYZ+UZY) !e23 14 | strain(6)=UZZ !e33 15 | end 16 | -------------------------------------------------------------------------------- /CFSsrc/find_minmax_values/find_minmax_values.f90: -------------------------------------------------------------------------------- 1 | program find_minmax_values 2 | real*8 minvalue,maxvalue,val 3 | minvalue=1.0e+10 4 | maxvalue=-1.0e+10 5 | open(10,file='values.txt') 6 | open(11,file='minmaxvalues.txt') 7 | do while(.true.) 8 | read(10,*,end=100)val 9 | if(val.gt.maxvalue) maxvalue=val 10 | if(val.lt.minvalue) minvalue=val 11 | enddo 12 | 100 close(10) 13 | write(11,1000)minvalue,maxvalue 14 | 1000 format(1x,'minvalue= ',f13.6,1x,'maxvalue=',f13.6) 15 | end program find_minmax_values 16 | -------------------------------------------------------------------------------- /OOP/scripts/OOP_coefficients.m: -------------------------------------------------------------------------------- 1 | function OOP_coefficients(delta,lambda,friction) 2 | dip=deg2rad(delta); 3 | rake=deg2rad(lambda); 4 | miu=friction; 5 | % 6 | k11=(-1.0/2.0*sin(rake)*sin(2*dip)+miu*sin(dip)^2); 7 | k12=(1.0/2.0*sin(rake)*sin(2*dip)-miu*sin(dip)^2); 8 | k13=(sin(rake)*cos(2*dip)-miu*sin(2*dip)); 9 | k22=(-1.0/2.0*sin(rake)*sin(2*dip)+miu*sin(dip)^2); 10 | k23=(-sin(rake)*cos(2*dip)+miu*sin(2*dip)); 11 | k33=(1.0/2.0*sin(rake)*sin(2*dip)+miu*cos(dip)^2); 12 | % 13 | KOOP=[k11 k12 k13 k22 k23 k33]; 14 | save('grid_OOP_coeff.mat','KOOP'); 15 | -------------------------------------------------------------------------------- /CFSsrc/src/Strain2Stress.f90: -------------------------------------------------------------------------------- 1 | subroutine Strain2Stress(strain,lambda,mu,stress) 2 | !strain(1)=e11 strain(2)=e12 strain(3)=e13 3 | !strain(4)=e22 strain(5)=e23 strain(6)=e33 4 | ! 5 | implicit none 6 | ! 7 | real*8 lambda,mu 8 | real*8 strain(6),stress(6) 9 | real*8 dilation 10 | ! 11 | dilation=strain(1)+strain(4)+strain(6) 12 | stress(1)=lambda*dilation+2*mu*strain(1) 13 | stress(2)=2*mu*strain(2) 14 | stress(3)=2*mu*strain(3) 15 | stress(4)=lambda*dilation+2*mu*strain(4) 16 | stress(5)=2*mu*strain(5) 17 | stress(6)=lambda*dilation+2*mu*strain(6) 18 | end 19 | -------------------------------------------------------------------------------- /OOP/scripts/strike_dip_rake_angles2normal_slip_directions.m: -------------------------------------------------------------------------------- 1 | function [normal,slip]=strike_dip_rake_angles2normal_slip_directions(strike,dip,rake) 2 | %note that the normal to a fault plane and the slip direction belong to a 3 | %local topographic Cartesian coordinate system whose x, y and z axes are 4 | %northern, eastern and upward, respectively. 5 | strike=deg2rad(strike(:)); 6 | dip=deg2rad(dip(:)); 7 | rake=deg2rad(rake(:)); 8 | normal=[-sin(strike).*sin(dip) cos(strike).*sin(dip) cos(dip)]'; 9 | slip=[ cos(strike).*cos(rake)+sin(strike).*cos(dip).*sin(rake) ... 10 | sin(strike).*cos(rake)-cos(strike).*cos(dip).*sin(rake) ... 11 | sin(dip).*sin(rake) ]'; 12 | -------------------------------------------------------------------------------- /CFSsrc/src/makefile: -------------------------------------------------------------------------------- 1 | PROG=CoulombStressAnalysis 2 | SRC= CoulombStressAnalysis.f90 \ 3 | GradientDisp2Strain.f90 \ 4 | Strain2Stress.f90 \ 5 | TensorTrans.f90 \ 6 | StressArray2StressTensor.f90 \ 7 | StressTensor2StressArray.f90 \ 8 | CFF.f90 \ 9 | deg2rad.f90 \ 10 | Rphi.f90\ 11 | InitializeStress.f90 \ 12 | generalxy2BL.f90 \ 13 | generalBL2xy.f90 14 | 15 | SSRC=DC3D.f 16 | FC= gfortran 17 | #FFLAGS= -g -O3 18 | FFLAGS= -g 19 | OBJS=$(SRC:.f90=.o) $(SSRC:.f=.o) 20 | $(PROG):$(OBJS) 21 | $(FC) -o $@ $(OBJS) $(FFLAGS) 22 | %.o:%.f90 23 | $(FC) -c $(FFLAGS) $< 24 | %.o:%.f 25 | $(FC) -c $(FFLAGS) $< 26 | clean: 27 | rm -rf *.o -------------------------------------------------------------------------------- /CFSsrc/src/Rphi.f90: -------------------------------------------------------------------------------- 1 | subroutine Rphi(phi_angle,P) 2 | !phi is the strike angle of source fault 3 | !P is a transform matrix of basis vectors from fault coordinate system 4 | !to a local Cartesian coordinate system. The axes of the fault coordinate 5 | !system are like this: x is along strike, y is perpendicular x and z is upward; 6 | !the axes of x,y,z are right-hand. The local Cartesian coordinate sytem is defined as: 7 | !x is northern, y is eastern and z is upward. 8 | ! 9 | implicit none 10 | real*8 phi_angle,P(3,3),phi 11 | ! 12 | real*8,external::deg2rad 13 | ! 14 | phi=deg2rad(phi_angle) 15 | P(1,1)=cos(phi) 16 | P(1,2)=sin(phi) 17 | P(1,3)=0.0 18 | ! 19 | P(2,1)=sin(phi) 20 | P(2,2)=-cos(phi) 21 | P(2,3)=0.0 22 | ! 23 | P(3,1)=0.0 24 | P(3,2)=0.0 25 | P(3,3)=1.0 26 | end 27 | -------------------------------------------------------------------------------- /faultrace/draw_CFS.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | psfile=coulomb.ps 3 | range=102/106/30/34 4 | echo -e "\033[31mNOTE: the ranges of geographic coordinates consistent with GMT should be predefined 5 | when drawing CFS for a fault trace.Here the range is like 102/106/30/34\033[0m." 6 | projection=m2 7 | offx=9 8 | offy=1.2 9 | delta=1m 10 | workdir=./CFS_map 11 | if [ ! -d $workdir ];then 12 | mkdir $workdir 13 | else 14 | rm -rf $workdir/* 15 | fi 16 | cd $workdir 17 | coulomb=../CFS_result/coulomb.out 18 | cptfile=CFS.cpt 19 | makecpt -Cno_green -T-2/2/0.1 > $cptfile 20 | psbasemap -J$projection -R$range -Bpxa2 -Bpya2 -BSWne -K -X$offx -Y$offy >$psfile 21 | awk '{print $1,$2,$5}' $coulomb | psxy -J -R -K -O -B -Sc0.2 -C$cptfile >>${psfile} 22 | psscale -Dn0.8/0.1+w1.5i/0.15i -J -R -C$cptfile -Ba0.5x+l"@~\104@~CFS" -By+l"bars" -K -O --FONT_ANNOT_PRIMARY=12p --FONT_LABEL=12p>>$psfile 23 | ps2pdf $psfile 24 | open ${psfile%.*}.pdf 25 | 26 | -------------------------------------------------------------------------------- /faultrace/all.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | if [ $# -eq 6 ];then 3 | while getopts 'T:M:R:' opt 4 | do 5 | case $opt in 6 | T) 7 | sourcefault=$OPTARG 8 | ;; 9 | M) 10 | meridian=$OPTARG 11 | ;; 12 | R) 13 | receiverfault=$OPTARG 14 | esac 15 | done 16 | else 17 | #echo "there are not enough commandline parameters!" 18 | echo -e "\033[1;30mUSAGE(e.g.):\033[0m ./all.sh -T sourcefault -M meridian -R receiverfault" 19 | exit 1 20 | fi 21 | echo -e "sourcefault=$sourcefault meridian=$meridian receiverfault=$receiverfault" 22 | #-------------------------------------------------------------# 23 | strike_receiver=150 #dummy value 24 | dip_receiver=78 #dummy value 25 | rake_receiver=-13 #dummy value 26 | friction=0.4 #dummy value 27 | Skempton=0.0 #dummy value 28 | echo "----$sourcefault $receiverfault ${strike_receiver} ${dip_receiver} ${rake_receiver} ${friction} ${Skempton} ${meridian}----" 29 | ./cal_CFS.sh $sourcefault $receiverfault ${strike_receiver} ${dip_receiver} ${rake_receiver} ${friction} ${Skempton} ${meridian} 30 | ./draw_CFS.sh 31 | 32 | -------------------------------------------------------------------------------- /CFSsrc/find_minmax_values/get_gmt_boundary.f90: -------------------------------------------------------------------------------- 1 | program get_gmt_boundary 2 | implicit none 3 | character*100 filename 4 | real*8 lon,lat 5 | real*8 minlon,maxlon,minlat,maxlat 6 | integer*4 nargs 7 | minlon=1.0e+9 8 | maxlon=-1.0e+9 9 | minlat=1.0e+9 10 | maxlat=-1.0e+9 11 | nargs=iargc(); 12 | if(nargs.ne.1) then 13 | write(*,*)'Usage: ./get_gmt_boundary inputfile' 14 | write(*,*)'the inputfile has the following format:' 15 | write(*,*)'latitude(deg) longitude(deg)' 16 | return 17 | endif 18 | call getarg(1,filename) 19 | open(10,file=filename) 20 | do while(.true.) 21 | read(10,*,end=20)lat,lon 22 | if(minlon.gt.lon) minlon=lon 23 | if(maxlon.lt.lon) maxlon=lon 24 | if(minlat.gt.lat) minlat=lat 25 | if(maxlat.lt.lat) maxlat=lat 26 | enddo 27 | 20 continue 28 | open(11,file="gmtbounds.txt") 29 | write(*,*)" minlon maxlon minlat maxlat" 30 | write(*,1000)minlon,maxlon,minlat,maxlat 31 | write(11,1001)minlon,maxlon,minlat,maxlat 32 | 1000 format(4f9.2) 33 | 1001 format(4f13.6) 34 | close(10) 35 | close(11) 36 | end program get_gmt_boundary 37 | -------------------------------------------------------------------------------- /CFSsrc/computeCFS/computeCFS.f90: -------------------------------------------------------------------------------- 1 | program computeCFS 2 | integer*4 i 3 | character*100 arg,path_stress 4 | real*8 strike,dip,rake,friction,skempton 5 | real*8 stress(6),shear_stress,normal_stress,coulomb_stress 6 | call getarg(1,arg) 7 | read(arg,*)strike 8 | call getarg(2,arg) 9 | read(arg,*)dip 10 | call getarg(3,arg) 11 | read(arg,*)rake 12 | call getarg(4,arg) 13 | read(arg,*)friction 14 | call getarg(5,arg) 15 | read(arg,*)skempton 16 | write(*,*)'-----the parameters of receiver faults-----' 17 | write(*,*)strike,dip,rake,friction,skempton 18 | open(10,file='stress.out') 19 | open(11,file='shearnormalcoulomb.out') 20 | write(*,*)'processing...' 21 | write(11,*)' shear_stress(bar) normal_stress(bar) coulomb_stress(bar)' 22 | do while(.true.) 23 | read(10,*,end=100)(stress(i),i=1,6) 24 | write(*,*)(stress(i),i=1,6) 25 | call CFF(stress,strike,dip,rake,friction,skempton,shear_stress,normal_stress,coulomb_stress) 26 | write(11,1000)shear_stress,normal_stress,coulomb_stress 27 | 1000 format(3e18.6) 28 | enddo 29 | 100 close(10) 30 | write(*,*)'done!' 31 | end program computeCFS 32 | -------------------------------------------------------------------------------- /profile/cal_CFS.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | ######Compile programs################################### 3 | cd ../CFSsrc/src 4 | make 5 | make clean 6 | cp CoulombStressAnalysis ../../profile 7 | cd ../../profile 8 | # 9 | source_fault=$1 10 | sampling_file=$2 11 | filefolder=./CFS_result 12 | if [ ! -d $filefolder ];then 13 | mkdir $filefolder 14 | else 15 | rm -rf $filefolder/* 16 | fi 17 | cp $sampling_file samplingpoints.in 18 | echo -e "\033[31m----processing ...---\033[0m" 19 | naltermode_receiver=0 20 | #note the following receiver fault is merely used for compatable reading format of the 'CoulombAnalysis' program. The real receiver fault will be read from the sampling file that is saved in the filefolder 'grid'. 21 | strike_receiver=$3 22 | dip_receiver=$4 23 | rake_receiver=$5 24 | friction=$6 25 | Skempton=$7 26 | meridian=$8 27 | cp $source_fault slipmodel.in 28 | ./CoulombStressAnalysis ${naltermode_receiver} ${strike_receiver} ${dip_receiver} ${rake_receiver} ${friction} ${Skempton} ${meridian} 29 | mv stress.out "${filefolder}" 30 | mv coulomb.out "${filefolder}/coulomb.out" 31 | rm -rf slipmodel.in samplingpoints.in 32 | -------------------------------------------------------------------------------- /OOP/scripts/CFF.m: -------------------------------------------------------------------------------- 1 | function [shear_stress,normal_stress,coulomb]=CFF(stress,receiver_strike,receiver_dip,receiver_rake,friction,skempton) 2 | %stress:e11 e12 e13 e22 e23 e33.these stress components belongs to a local 3 | %Cartesian coordinate system whose x is north, y is east and z is upward. 4 | %friction:[0,1]. commonly it's 0.4 5 | %skempton:[0,1]. commonly it's 0.6 6 | %receiver_strike,receiver_dip and receiver_rake are angles of receiver 7 | %fault. 8 | %coded on June 19, 2015 jjwang 9 | 10 | s=[stress([1 2 3]);... 11 | stress([2 4 5]);... 12 | stress([3 5 6])]; 13 | % 14 | strike=deg2rad(receiver_strike); 15 | dip=deg2rad(receiver_dip); 16 | rake=deg2rad(receiver_rake); 17 | % 18 | normal=[-sin(strike)*sin(dip);... 19 | cos(strike)*sin(dip);... 20 | cos(dip)]; 21 | slip=[cos(strike)*cos(rake)+sin(strike)*cos(dip)*sin(rake);... 22 | sin(strike)*cos(rake)-cos(strike)*cos(dip)*sin(rake);... 23 | sin(dip)*sin(rake)]; 24 | p=s*normal; 25 | normal_stress=normal'*p; 26 | shear_stress=slip'*p; 27 | poropressure=-skempton/3*(s(1,1)+s(2,2)+s(3,3)); 28 | coulomb=shear_stress+friction*(normal_stress+poropressure); -------------------------------------------------------------------------------- /OOP/cal_CFS.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | ######Compile programs################################### 3 | cd ../CFSsrc/src 4 | make 5 | make clean 6 | cp CoulombStressAnalysis ../../OOP 7 | # 8 | cd ../computeCFS 9 | make 10 | make clean 11 | cp computeCFS ../../OOP 12 | cd ../../OOP 13 | # 14 | source_fault=$1 15 | sampling_file=$2 16 | filefolder=./CFS_result 17 | if [ ! -d $filefolder ];then 18 | mkdir $filefolder 19 | else 20 | rm -rf $filefolder/* 21 | fi 22 | cp $sampling_file samplingpoints.in 23 | echo -e "\033[31m----processing ...---\033[0m" 24 | naltermode_receiver=0 25 | #note the following receiver fault is merely used for compatable reading format of the 'CoulombAnalysis' program. The real receiver fault will be read from the sampling file that is saved in the filefolder 'grid'. 26 | strike_receiver=$3 27 | dip_receiver=$4 28 | rake_receiver=$5 29 | friction=$6 30 | Skempton=$7 31 | meridian=$8 32 | cp $source_fault slipmodel.in 33 | ./CoulombStressAnalysis ${naltermode_receiver} ${strike_receiver} ${dip_receiver} ${rake_receiver} ${friction} ${Skempton} ${meridian} 34 | mv stress.out "${filefolder}" 35 | mv coulomb.out "${filefolder}/coulomb.out" 36 | rm -rf slipmodel.in samplingpoints.in sampling_temp.txt 37 | -------------------------------------------------------------------------------- /grid/cal_CFS.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | ######Compile programs################################### 3 | cd ../CFSsrc/src 4 | make 5 | make clean 6 | cp CoulombStressAnalysis ../../grid 7 | # 8 | cd ../computeCFS 9 | make 10 | make clean 11 | cp computeCFS ../../grid 12 | cd ../../grid 13 | # 14 | source_fault=$1 15 | sampling_file=$2 16 | filefolder=./CFS_result 17 | if [ ! -d $filefolder ];then 18 | mkdir $filefolder 19 | else 20 | rm -rf $filefolder/* 21 | fi 22 | cp $sampling_file samplingpoints.in 23 | echo -e "\033[31m----processing ...---\033[0m" 24 | naltermode_receiver=0 25 | #note when naltermode_receiver=1 the following receiver fault is merely used for compatable reading format of the 'CoulombAnalysis' program. The real receiver fault will be read from the sampling file that is saved in the filefolder 'grid'. 26 | strike_receiver=$3 27 | dip_receiver=$4 28 | rake_receiver=$5 29 | friction=$6 30 | Skempton=$7 31 | meridian=$8 32 | cp $source_fault slipmodel.in 33 | ./CoulombStressAnalysis ${naltermode_receiver} ${strike_receiver} ${dip_receiver} ${rake_receiver} ${friction} ${Skempton} ${meridian} 34 | mv stress.out "${filefolder}" 35 | mv coulomb.out "${filefolder}/coulomb.out" 36 | rm -rf slipmodel.in samplingpoints.in 37 | -------------------------------------------------------------------------------- /OOP/scripts/normal_slip_directions2_strike_dip_rake_angles.m: -------------------------------------------------------------------------------- 1 | function [strike_angle,dip_angle,rake_angle]=normal_slip_directions2_strike_dip_rake_angles(normal_direc,slip_direc) 2 | col=size(normal_direc,2); 3 | strike_angle=[]; 4 | dip_angle=[]; 5 | rake_angle=[]; 6 | for j=1:col 7 | normal=normal_direc(:,j); 8 | slip=slip_direc(:,j); 9 | %to make sure that the Aki&Richards's convention for the dip angle of a 10 | %receiver fault is satisfied. 11 | if normal(3)<0 12 | normal=-normal; 13 | slip=-slip; 14 | end 15 | % 16 | n1=normal(1);n2=normal(2);n3=normal(3); 17 | s1=slip(1);s2=slip(2);s3=slip(3); 18 | dip=acos(n3); 19 | epsilon=1.0e-6; 20 | if dip>epsilon 21 | strike=atan2(-n1,n2); 22 | rake=atan2( s3/sin(dip), s1*cos(strike)+s2*sin(strike) ); 23 | else 24 | dip=0.0; 25 | rake=0.0;%compulsively set the rake angel to be zero because in this case only the difference of strike and rake angles can be constrained. 26 | strike=rake+atan2(s2,s1); 27 | end 28 | strike=(strike<0)*(2*pi+strike)+(strike>=0)*strike; 29 | strike=rad2deg(strike); 30 | dip=rad2deg(dip); 31 | rake=rad2deg(rake); 32 | % 33 | strike_angle=[strike_angle;strike]; 34 | dip_angle=[dip_angle;dip]; 35 | rake_angle=[rake_angle;rake]; 36 | end 37 | -------------------------------------------------------------------------------- /grid/draw_CFS.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | psfile=coulomb.ps 3 | gfortran ../CFSsrc/find_minmax_values/get_gmt_boundary.f90 -o get_gmt_boundary 4 | sed '1d' $1 > tempgrids.txt 5 | ./get_gmt_boundary tempgrids.txt >/dev/null 6 | range=`awk '{printf("%13.6f/%13.6f/%13.6f/%13.6f\n"),$1,$2,$3,$4}' gmtbounds.txt | \ 7 | sed 's/ //g'` 8 | rm -rf tempgrids.txt gmtbounds.txt get_gmt_boundary 9 | #range=102/106/30/34 10 | projection=m4 11 | offx=7 12 | offy=1.5 13 | delta=1m 14 | workdir=./CFS_map 15 | bshut=0 16 | if [ ! -d $workdir ];then 17 | mkdir $workdir 18 | else 19 | rm -rf $workdir/* 20 | fi 21 | cd ./$workdir 22 | coulomb=../CFS_result/coulomb.out 23 | cptfile=CFS.cpt 24 | makecpt -Cno_green -T-2/2/0.1 > $cptfile 25 | psbasemap -J$projection -R$range -Bpxa2 -Bpya2 -BSWne -K -X$offx -Y$offy >$psfile 26 | if [ $bshut -eq 0 ];then 27 | awk '{print $1,$2,$5}' $coulomb | psxy -J -R -K -O -B -Ss0.1 -C$cptfile >>${psfile} 28 | else 29 | awk '{print $1,$2,$5}' $coulomb | blockmean -I$delta -R$range | \ 30 | surface -Gcoulomb.grd -I$delta -R$range 31 | grdimage -R -B coulomb.grd -C$cptfile -J$projection -K -O>> $psfile 32 | fi 33 | psscale -Dn0.8/0.1+w1.5i/0.15i -J -R -C$cptfile -Ba0.5x+l"@~\104@~CFS" -By+l"bars" -K -O --FONT_ANNOT_PRIMARY=12p --FONT_LABEL=12p>>$psfile 34 | ps2pdf $psfile 35 | open ${psfile%.*}.pdf 36 | 37 | -------------------------------------------------------------------------------- /profile/draw_CFS.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | psfile=coulomb.ps 3 | #range=100/106/28/36 4 | range_file=range_for_GMT_drawing.txt 5 | range_along_strike=`sed '1,5d' $range_file | head -n 1 ` 6 | range_downdip=`sed '1,6d' $range_file | head -n 1 ` 7 | range=`echo "$range_along_strike $range_downdip" | awk '{printf "%-f/%-f/%-f/%-f",$1,$2,$3,$4}'` 8 | echo "range=$range" 9 | projection=X18/-7 10 | offx=6 11 | offy=7 12 | delta=1m 13 | workdir=./CFS_map 14 | bshut=0 15 | if [ ! -d $workdir ];then 16 | mkdir $workdir 17 | else 18 | rm -rf $workdir/* 19 | fi 20 | cd $workdir 21 | coulomb=../CFS_result/coulomb.out 22 | cptfile=CFS.cpt 23 | makecpt -Cno_green -T-2/2/0.1 > $cptfile 24 | psbasemap -J$projection -R$range -Bpxa10f5+l"Along strike (km)" -Bpya2+l"Downdip (km)" -BSWne -K -X$offx -Y$offy >$psfile 25 | if [ $bshut -eq 0 ];then 26 | awk '{print $4,$5,$8}' $coulomb | psxy -J -R -K -O -B -Ss0.1 -C$cptfile -hi1>>${psfile} 27 | else 28 | awk '{print $1,$2,$5}' $coulomb | blockmean -I$delta -R$range | \ 29 | surface -Gcoulomb.grd -I$delta -R$range 30 | grdimage -R -B coulomb.grd -C$cptfile -J$projection -K -O>> $psfile 31 | fi 32 | psscale -Dn0.8/0.1+w1.5i/0.15i -J -R -C$cptfile -Ba0.5x+l"@~\104@~CFS" -By+l"bars" -K -O --FONT_ANNOT_PRIMARY=12p --FONT_LABEL=12p>>$psfile 33 | ps2pdf $psfile 34 | open ${psfile%.*}.pdf 35 | 36 | -------------------------------------------------------------------------------- /faultrace/cal_CFS.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | ######Compile programs################################### 3 | cd ../CFSsrc/src 4 | make 5 | make clean 6 | cp CoulombStressAnalysis ../../faultrace 7 | # 8 | cd ../../faultrace 9 | # 10 | source_fault=$1 11 | sampling_file=$2 12 | filefolder=./CFS_result 13 | if [ ! -d $filefolder ];then 14 | mkdir ./$filefolder 15 | else 16 | rm -rf $filefolder/* 17 | fi 18 | cp $sampling_file samplingpoints.in 19 | echo -e "\033[31m----processing ...---\033[0m" 20 | naltermode_receiver=1 21 | #note the following receiver fault is merely used for compatable reading format of the 'CoulombAnalysis' program. The real receiver fault will be read from the sampling file that is saved in the filefolder 'grid'. 22 | strike_receiver=$3 23 | dip_receiver=$4 24 | rake_receiver=$5 25 | friction=$6 26 | Skempton=$7 27 | meridian=$8 28 | cp $source_fault slipmodel.in 29 | echo "$1 $2 $3 $4 $5 $6 $7 $8" 30 | echo "naltermode_receiver=$naltermode_receiver strike_receiver=$strike_receiver dip_receiver=$dip_receiver rake_receiver=$rake_receiver friction=$friction Skempton=$Skempton meridian=$meridian" 31 | ./CoulombStressAnalysis ${naltermode_receiver} ${strike_receiver} ${dip_receiver} ${rake_receiver} ${friction} ${Skempton} ${meridian} 32 | mv stress.out "${filefolder}" 33 | mv coulomb.out "${filefolder}/coulomb.out" 34 | rm -rf slipmodel.in samplingpoints.in sampling_temp.txt CoulombStressAnalysis 35 | -------------------------------------------------------------------------------- /CFSsrc/computeCFS/CFF.f90: -------------------------------------------------------------------------------- 1 | subroutine CFF(stress,strike,dip,rake,friction,skempton,shear_stress,normal_stress,coulomb_stress) 2 | !stress(6) is in a coordinate system of which x is northern, y is eastern and z is upward. 3 | ! 4 | implicit none 5 | ! 6 | real*8 stress(6) 7 | real*8 strike,dip,rake,friction,skempton 8 | real*8 shear_stress,normal_stress,pore_pressure,coulomb_stress 9 | real*8 e11,e12,e13,e22,e23,e33 10 | real*8 phi,delta,lambda 11 | ! 12 | real*8, external::deg2rad 13 | ! 14 | e11=stress(1) 15 | e12=stress(2) 16 | e13=stress(3) 17 | e22=stress(4) 18 | e23=stress(5) 19 | e33=stress(6) 20 | ! 21 | phi=deg2rad(strike) 22 | delta=deg2rad(dip) 23 | lambda=deg2rad(rake) 24 | ! 25 | shear_stress=sin(lambda)*(-1.0/2.0*sin(phi)**2*sin(2*delta)*e11+1.0/2.0*sin(2*phi)*sin(2*delta)*e12+ & 26 | sin(phi)*cos(2*delta)*e13-1.0/2.0*cos(phi)**2*sin(2*delta)*e22-cos(phi)*cos(2*delta)*e23+1.0/2.0*sin(2*delta)*e33)+ & 27 | cos(lambda)*(-1.0/2.0*sin(2*phi)*sin(delta)*e11+cos(2*phi)*sin(delta)*e12+cos(phi)*cos(delta)*e13+ & 28 | 1.0/2.0*sin(2*phi)*sin(delta)*e22+sin(phi)*cos(delta)*e23) 29 | normal_stress=sin(phi)**2*sin(delta)**2*e11-sin(2*phi)*sin(delta)**2*e12-sin(phi)*sin(2*delta)*e13+ & 30 | cos(phi)**2*sin(delta)**2*e22+cos(phi)*sin(2*delta)*e23+cos(delta)**2*e33 31 | pore_pressure=-skempton/3.0*(e11+e22+e33) 32 | coulomb_stress=shear_stress+friction*(normal_stress+pore_pressure) 33 | end 34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /CFSsrc/src/TensorTrans.f90: -------------------------------------------------------------------------------- 1 | subroutine TensorTrans(stressin,trans_matrix,stressout) 2 | !tensor transformation:stressout=transpose(trans_matrix)*stressin*trans_matrix 3 | ![e1 e2 e3]=[E1 E2 E3]*trans_matrix. e1,e2,e3 are the basis vectors of the new 4 | !coordinate system, E1,E2,E3 are the basis vecotors of the old coordinate system. 5 | !stressin is the stress tensor in the old coordinate system. stressout is the stress tensor 6 | !in the new coordinate system. 7 | ! 8 | implicit none 9 | ! 10 | real*8 stressin(3,3),trans_matrix(3,3),stressout(3,3) 11 | real*8 temp1(3,3),temp2(3,3) 12 | !temp1=stressin*trans_matrix 13 | call MatrixProduct(stressin,trans_matrix,temp1) 14 | !temp2=trans_matrix' 15 | call MatrixTranspose(trans_matrix,temp2) 16 | !stressout=temp2*temp1 17 | call MatrixProduct(temp2,temp1,stressout) 18 | end 19 | !-----------------------------------! 20 | subroutine MatrixProduct(A,B,C) 21 | !C=A*B 22 | ! 23 | implicit none 24 | ! 25 | real*8 A(3,3),B(3,3),C(3,3) 26 | real*8 temp 27 | integer*4 i,j,k 28 | do 100 i=1,3 29 | do 200 j=1,3 30 | temp=0.0 31 | do 300 k=1,3 32 | temp=temp+A(i,k)*B(k,j) 33 | 300 continue 34 | C(i,j)=temp 35 | 200 continue 36 | 100 continue 37 | end 38 | !-----------------------------------! 39 | subroutine MatrixTranspose(A,B) 40 | !B=A' 41 | ! 42 | implicit none 43 | ! 44 | real*8 A(3,3),B(3,3) 45 | integer*4 i,j 46 | do 100 i=1,3 47 | do 200 j=1,3 48 | B(i,j)=A(j,i) 49 | 200 continue 50 | 100 continue 51 | end 52 | -------------------------------------------------------------------------------- /preproc/generalxy2BL.m: -------------------------------------------------------------------------------- 1 | function [sB sL]=generalxy2BL(x,y,sL0,nchoiceellip) 2 | ratio=180.0/pi; 3 | % 4 | if nchoiceellip==1%then %Krassovsky ellipsphere 5 | a=6378245.0; 6 | e2=0.006693421622966; 7 | elseif nchoiceellip==2%then %1975 international ellipsphere 8 | a=6378140.0; 9 | e2=0.006694384999588; 10 | elseif nchoiceellip==3%then %WGS-84 ellipsphere 11 | a=6378137.0; 12 | e2=0.0066943799013; 13 | else 14 | disp('please choose the right ellipsphere'); 15 | return 16 | end 17 | % 18 | m0=a*(1-e2); 19 | m2=3*e2*m0/2; 20 | m4=5*e2*m2/4; 21 | m6=7*e2*m4/6; 22 | m8=9*e2*m6/8; 23 | % 24 | a0=m0+m2/2+3*m4/8+5*m6/16+35*m8/128; 25 | a2=m2/2+m4/2+15*m6/32+7*m8/16; 26 | a4=m4/8+3*m6/16+7*m8/32; 27 | a6=m6/32+m8/16; 28 | a8=m8/128; 29 | % 30 | beta=x/a0; 31 | p2=-a2/(2*a0); 32 | p4=a4/(4*a0); 33 | p6=-a6/(6*a0); 34 | % 35 | q2=-p2-p2*p4+p2^3/2; 36 | q4=-p4+p2^2-2*p2*p6+4*p2^2*p4; 37 | q6=-p6+3*p2*p4-3*p2^3/2; 38 | % 39 | Bf=beta+q2*sin(2*beta)+q4*sin(4*beta)+q6*sin(6*beta); 40 | sNf=a/( (1-e2*sin(Bf)^2)^(0.5) ); 41 | sMf=a*(1-e2)*(1-e2*sin(Bf)^2)^(-1.5); 42 | t=tan(Bf); 43 | seconde2=e2/(1-e2); 44 | seta=seconde2^(0.5)*cos(Bf); 45 | sB=Bf-t*y^2/(2*sMf*sNf*cos(Bf))+t*( 5+3*t^2+seta^2-9*(seta^2)*(t^2) )*y^4/(24*sMf*(sNf^3)) ... 46 | -t*(61+90*t^2+45*t^4)*(y^6)/(720*sMf*sNf^5); 47 | sB=sB*ratio; 48 | ssl=y/(sNf*cos(Bf)) -(1+2*t^2+seta^2)*(y^3)/( 6*cos(Bf)*(sNf^3) ) +... 49 | ( 5+28*t^2+24*t^4+6*seta^2+8*(seta^2)*(t^2) )*(y^5)/(120*(sNf^5)*cos(Bf) ); 50 | sL=sL0+ssl*ratio; 51 | -------------------------------------------------------------------------------- /CFSsrc/src/CFF.f90: -------------------------------------------------------------------------------- 1 | subroutine CFF(stress,strike,dip,rake,friction,skempton,shear_stress,normal_stress,coulomb_stress) 2 | !stress(6) is in a coordinate system of which x is northern, y is eastern and z is upward. 3 | ! 4 | implicit none 5 | ! 6 | real*8 stress(6) 7 | real*8 strike,dip,rake,friction,skempton 8 | real*8 shear_stress,normal_stress,pore_pressure,coulomb_stress 9 | real*8 e11,e12,e13,e22,e23,e33 10 | real*8 phi,delta,lambda 11 | ! 12 | real*8, external::deg2rad 13 | ! 14 | e11=stress(1) 15 | e12=stress(2) 16 | e13=stress(3) 17 | e22=stress(4) 18 | e23=stress(5) 19 | e33=stress(6) 20 | ! 21 | phi=deg2rad(strike) 22 | delta=deg2rad(dip) 23 | lambda=deg2rad(rake) 24 | ! 25 | shear_stress=sin(lambda)*(-1.0d0/2.0d0*sin(phi)**2d0*sin(2d0*delta)*e11+1.0d0/2.0d0*sin(2d0*phi)*sin(2d0*delta)*e12+ & 26 | sin(phi)*cos(2d0*delta)*e13-1.0d0/2.0d0*cos(phi)**2d0*sin(2d0*delta)*e22-cos(phi)*cos(2d0*delta)*e23+ & 27 | 1.0d0/2.0d0*sin(2d0*delta)*e33)+ & 28 | cos(lambda)*(-1.0d0/2.0d0*sin(2d0*phi)*sin(delta)*e11+cos(2d0*phi)*sin(delta)*e12+ & 29 | cos(phi)*cos(delta)*e13+ & 30 | 1.0d0/2.0d0*sin(2d0*phi)*sin(delta)*e22+sin(phi)*cos(delta)*e23) 31 | normal_stress=sin(phi)**2d0*sin(delta)**2d0*e11-sin(2d0*phi)*sin(delta)**2d0*e12- & 32 | sin(phi)*sin(2d0*delta)*e13+ & 33 | cos(phi)**2d0*sin(delta)**2d0*e22+cos(phi)*sin(2d0*delta)*e23+cos(delta)**2d0*e33 34 | pore_pressure=-skempton/3.0d0*(e11+e22+e33) 35 | coulomb_stress=shear_stress+friction*(normal_stress+pore_pressure) 36 | end 37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /preproc/generalBL2xy.m: -------------------------------------------------------------------------------- 1 | function [x y]=generalGaussproj(sB,sL,sL0,nchoiceellip,nchoiceplane) 2 | B=deg2rad(sB); 3 | newsL=deg2rad(sL); 4 | newsL0=deg2rad(sL0); 5 | % 6 | if nchoiceellip==1%then %Krassovsky ellipsphere 7 | a=6378245.0; 8 | e2=0.006693421622966; 9 | elseif nchoiceellip==2%then %1975 international ellipsphere 10 | a=6378140.0; 11 | e2=0.006694384999588; 12 | elseif nchoiceellip==3%then %WGS-84 ellipsphere 13 | a=6378137.0; 14 | e2=0.0066943799013; 15 | else 16 | disp('please choose the right ellipsphere'); 17 | return 18 | end 19 | % 20 | if nchoiceplane==1%then %Gaussian projection 21 | scale=1.0; 22 | elseif nchoiceplane==2%then %UTM 23 | scale=0.9996; 24 | else 25 | disp('please choose the right kind of projection'); 26 | return 27 | end 28 | % 29 | m0=a*(1-e2); 30 | m2=3*e2*m0/2; 31 | m4=5*e2*m2/4; 32 | m6=7*e2*m4/6; 33 | m8=9*e2*m6/8; 34 | % 35 | a0=m0+m2/2+3*m4/8+5*m6/16+35*m8/128; 36 | a2=m2/2+m4/2+15*m6/32+7*m8/16; 37 | a4=m4/8+3*m6/16+7*m8/32; 38 | a6=m6/32+m8/16; 39 | a8=m8/128; 40 | % 41 | arclength=a0*B-a2*sin(2*B)/2+a4*sin(4*B)/4-a6*sin(6*B)/6+a8*sin(8*B)/8; 42 | sN=a*(1-e2*sin(B)^2)^(-0.5); 43 | st=tan(B); 44 | seconde2=e2/(1-e2); 45 | seta=seconde2^(0.5)*cos(B); 46 | diffl=newsL-newsL0; 47 | x=arclength+sN/2*st*( cos(B)^2 )*( diffl^2 ) +sN/24.0*st*( 5-st^2+9*seta^2+4*seta^4)*cos(B)^4*diffl^4+ ... 48 | sN/720.0*st*(61-58*st^2+st^4)*cos(B)^6*diffl^6; 49 | y=sN*cos(B)*diffl+sN/6*(1-st^2+seta^2)*cos(B)^3*diffl^3+sN/120*(5-18*st^2+st^4+14*seta^2-58*seta^2*st^2)*cos(B)^5*diffl^5 ; 50 | x=scale*x; 51 | y=scale*y; 52 | -------------------------------------------------------------------------------- /preproc/tectonic_stress.m: -------------------------------------------------------------------------------- 1 | function [s]=tectonic_stress(stress_plung_trend_angle) 2 | %P1 is the plunge angle of the principal stress s1. T1 is its azimuth. 3 | %P2 is the plunge angle of the principal stress s2. T2 is its azimuth. 4 | %P3 is the plunge angle of the principal stress s3. T3 is its azimuth. 5 | %note x is north, y is east and z is upward. 6 | %coded on 23:57 Sep. 28, 2014. 7 | % 8 | s1=stress_plung_trend_angle(1,1); 9 | s2=stress_plung_trend_angle(2,1); 10 | s3=stress_plung_trend_angle(3,1); 11 | % 12 | P1=stress_plung_trend_angle(1,2); 13 | T1=stress_plung_trend_angle(1,3); 14 | % 15 | P2=stress_plung_trend_angle(2,2); 16 | T2=stress_plung_trend_angle(2,3); 17 | % 18 | P3=stress_plung_trend_angle(3,2); 19 | T3=stress_plung_trend_angle(3,3); 20 | % 21 | P1=deg2rad(P1); 22 | T1=deg2rad(T1); 23 | % 24 | P2=deg2rad(P2); 25 | T2=deg2rad(T2); 26 | % 27 | P3=deg2rad(P3); 28 | T3=deg2rad(T3); 29 | % 30 | %check orthogonality 31 | D=[cos(P1)*cos(T1) cos(P2)*cos(T2) cos(P3)*cos(T3);... 32 | cos(P1)*sin(T1) cos(P2)*sin(T2) cos(P3)*sin(T3);... 33 | sin(P1) sin(P2) sin(P3)]; 34 | if length(find(abs(reshape(D*D'-eye(3),9,1))<1.0e-6))~=9 35 | disp('error!!!the principal axes of principal stresses are not orthogonal!!!'); 36 | s=[]; 37 | return 38 | end 39 | % 40 | s11=s1*cos(P1)^2*cos(T1)^2+s2*cos(P2)^2*cos(T2)^2+s3*cos(P3)^2*cos(T3)^2; 41 | s12=1/2*(s1*cos(P1)^2*sin(2*T1)+s2*cos(P2)^2*sin(2*T2)+s3*cos(P3)^2*sin(2*T3)); 42 | s13=1/2*(s1*sin(2*P1)*cos(T1)+s2*sin(2*P2)*cos(T2)+s3*sin(2*P3)*cos(T3)); 43 | s22=s1*cos(P1)^2*sin(T1)^2+s2*cos(P2)^2*sin(T2)^2+s3*cos(P3)^2*sin(T3)^2; 44 | s23=1/2*(s1*sin(2*P1)*sin(T1)+s2*sin(2*P2)*sin(T2)+s3*sin(2*P3)*sin(T3)); 45 | s33=s1*sin(P1)^2+s2*sin(P2)^2+s3*sin(P3)^2; 46 | % 47 | s=[s11 s12 s13;s12 s22 s23;s13 s23 s33];%my coordinate. x is northern, y is eastern and z is upward. 48 | -------------------------------------------------------------------------------- /OOP/scripts/OOP1D_vertical_right_lateral_strike_slip.m: -------------------------------------------------------------------------------- 1 | function [opt_strike,opt_dip,opt_rake,shear_stress,normal_stress,coulomb_stress,total_CFFmax]=OOP1D_vertical_right_lateral_strike_slip(earthquake_stress,tectonic_stress,friction,skempton) 2 | %earthquake_stress:se11 se12 se13 se22 se23 se33 3 | %tectonic_stress: st11 st12 st13 st22 st23 st33 4 | %Both 'earthquake_stress' and 'tectonic_stress' belong to a local topographic Cartesian coordinate system whose 5 | %x is northern, y is eastern and z is upward. 6 | s=earthquake_stress+tectonic_stress; 7 | row=size(s,1); 8 | opt_strike=[]; 9 | opt_dip=[]; 10 | opt_rake=[]; 11 | shear_stress=[]; 12 | normal_stress=[]; 13 | coulomb_stress=[]; 14 | total_CFFmax=[]; 15 | for i=1:row 16 | A=1/2*( s(i,1) - s(i,4) ) - friction*s(i,2); 17 | B=1/2*friction*( s(i,4) - s(i,1) ) - s(i,2); 18 | CFFmax=sqrt(1+friction^2)*sqrt( 1/4*( s(i,4)-s(i,1) )^2 + s(i,2)^2 ) +1/2*friction*( s(i,1)+s(i,4) ); 19 | theta=1/2*atan(A/B); 20 | if B<0 21 | K=[1;3]; 22 | strike=theta+1/2*K*pi; 23 | else 24 | if A>=0 25 | K=[0;1]; 26 | strike=theta+K*pi; 27 | else 28 | K=[1;2]; 29 | strike=theta+K*pi; 30 | end 31 | end 32 | dip=pi/2; 33 | rake=pi; 34 | receiver_strike=rad2deg(strike(1)); 35 | receiver_dip=rad2deg(dip(1)); 36 | receiver_rake=rad2deg(rake(1)); 37 | [shear,normal,coulomb]=CFF(earthquake_stress,receiver_strike,receiver_dip,receiver_rake,friction,skempton); 38 | shear_stress=[shear_stress;shear]; 39 | normal_stress=[normal_stress;normal]; 40 | coulomb_stress=[coulomb_stress;coulomb]; 41 | opt_strike=[opt_strike;strike']; 42 | opt_dip=[opt_dip;dip dip]; 43 | opt_rake=[opt_rake;rake rake]; 44 | total_CFFmax=[total_CFFmax;CFFmax]; 45 | end 46 | opt_strike=rad2deg(opt_strike); 47 | opt_dip=rad2deg(opt_dip); 48 | opt_rake=rad2deg(opt_rake); -------------------------------------------------------------------------------- /preproc/preproc_sampling_grids.m: -------------------------------------------------------------------------------- 1 | function preproc_sampling_grids() 2 | clc;clear;close all; 3 | %------------------------Modify Parameters at here------------------------% 4 | %minlon=100;%deg 5 | %maxlon=106;%deg 6 | %minlat=28;%deg 7 | %maxlat=36;%deg 8 | %dlon=0.05;%deg 9 | %dlat=0.05;%deg 10 | %depth=10;%km 11 | % receiver_strike=150;%deg 12 | % receiver_dip=78;%deg 13 | % receiver_rake=-13;%deg 14 | % friction=0.4; 15 | % skempton=0.0; 16 | %-------------------------------------------------------------------------% 17 | minlon=input('the minimum longitude (deg): '); 18 | maxlon=input('the maximum longitude (deg): '); 19 | minlat=input('the minimum latitude (deg): '); 20 | maxlat=input('the maximum latitude (deg): '); 21 | dlon=input('the longitude interval (deg): '); 22 | dlat=input('the latitude interval (deg): '); 23 | depth=input('the depth at which CFS is computed (km): '); 24 | %-------------------------------------------------------------------------% 25 | outputfile='../grid/sampling_grids.in'; 26 | lon=minlon:dlon:maxlon; 27 | lat=minlat:dlat:maxlat; 28 | if lon(end) -N " 5 | echo "" 6 | echo -e "\033[31m-I\033[0m Coulombfile is a Coulomb stress file produced by the AutoCoulomb software and saved in a folder named CFS_result. 7 | The format of this file is as follows: the first line is a header. Then each of the following lines has five columns, 8 | which are lon.(deg) lat.(deg) shearstress(bar) normalstress(bar) Coulombstress(bar) when Ncase = 1 or 2, and 9 | lon.(deg) lat.(deg) optstr1(deg) optdip1(deg) optrake1(deg) optstr2(deg) optdip2(deg) optrake2(deg) shearstress(bar) normalstress(bar) Coulombstress(bar) when Ncase = 3." 10 | echo -e "\033[31m-N\033[0m Ncase = 1 for drawing a Coulomb stress map with fixed receiver faults at horizontal grids. 11 | Ncase = 2 for drawing a Coulomb stress map with varying receiver faults along a fault trace. 12 | Ncase = 3 for drawing a Coulomb stress map on optimally oriented failure planes." 13 | echo "" 14 | echo "The following are three command lines used to exhibit relevant Coulomb stress maps:" 15 | echo "e.g. ./drawgridCFS.sh -I ../grid/CFS_result/coulomb.out -N 1" 16 | echo "e.g. ./drawgridCFS.sh -I ../faultrace/CFS_result/coulomb.out -N 2" 17 | echo "e.g. ./drawgridCFS.sh -I ../OOP/CFS_result/coulomb.out -N 3" 18 | echo "" 19 | echo "Coded on 8 Jan.,2022 by jjwang" 20 | echo "" 21 | exit 1 22 | } 23 | if [ $# -ne 4 ];then 24 | usage 25 | fi 26 | # 27 | while getopts 'I:N:' opt 28 | do 29 | case "$opt" in 30 | I) 31 | coulombfile=$OPTARG 32 | ;; 33 | N) 34 | ncase=$OPTARG 35 | esac 36 | done 37 | # 38 | if [ ! -f $coulombfile ];then 39 | echo -e "\033[31m ***The input file doesn't exist***\033[0m" 40 | exit 1 41 | fi 42 | if [ ! -s $coulombfile ];then 43 | echo -e "\033[31m ***The input file is empty***\033[0m" 44 | exit 1 45 | fi 46 | case "$ncase" in 47 | 1|2) 48 | cp $coulombfile coulomb.out 49 | ;; 50 | 3) 51 | echo "lon.(deg) lat(deg) shear(bar) normal(bar) CFS(bar)" > coulomb.out 52 | sed '1d' $coulombfile | awk '{print $1,$2,$9,$10,$11}' >> coulomb.out 53 | esac 54 | echo -e "coulomb.out\n$ncase" | matlab -nodisplay -nodesktop -nosplash -r "drawgridCFS;quit" 55 | rm coulomb.out 56 | echo "done!" 57 | open coulomb.pdf 58 | -------------------------------------------------------------------------------- /OOP/generate_tectonic_stress.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | if [ $# -ne 10 ];then 3 | echo -e "This scirpt is used to transform a principal stress tensor into one in a local topographic coordinate system whose x, y and z axses are due east, due north and upward, respectively. The transformed stress tensor is added to stress tensors aroused by an earthquake faulting when resolving the OOPs." 4 | echo -e "\n\033[1mUsage:\033[0m ./generate_tectonic_stress.sh -s1 \"sigma1(bar) plunge1(deg) azimuth1(deg)\" -s2 \"sigma2(bar) plunge2(deg) azimuth2(deg)\" \ 5 | \n -s3 \"sigma3(bar) plunge3(deg) azimuth3(deg)\" -o outputfilename -n N" 6 | echo -e "\n -s1, -s2, -s3 are the options of the maximum, intermediate and minimum principal stresses.\n -o is the option for targeted file in which \ 7 | tectonic background stress is to be saved.\n -n is the option for the number of copies of the six independent comoponents of the principal stress tensor.\n note that tectonic stress field here to be considered is homogeneous." 8 | exit -1 9 | fi 10 | while [ $# -gt 0 ] 11 | do 12 | case "$1" in 13 | -s1) 14 | s1=`echo "$2" | awk '{print $1}'` 15 | p1=`echo "$2" | awk '{print $2}'` 16 | t1=`echo "$2" | awk '{print $3}'` 17 | shift 18 | ;; 19 | -s2) 20 | s2=`echo "$2" | awk '{print $1}'` 21 | p2=`echo "$2" | awk '{print $2}'` 22 | t2=`echo "$2" | awk '{print $3}'` 23 | shift 24 | ;; 25 | -s3) 26 | s3=`echo "$2" | awk '{print $1}'` 27 | p3=`echo "$2" | awk '{print $2}'` 28 | t3=`echo "$2" | awk '{print $3}'` 29 | shift 30 | ;; 31 | -o) 32 | outputfile=$2 33 | shift 34 | ;; 35 | -n) 36 | nlines=$2 37 | shift 38 | esac 39 | shift 40 | done 41 | echo -e "$s1 $p1 $t1\n$s2 $p2 $t2\n$s3 $p3 $t3\n$outputfile $nlines" 42 | gfortran ./scripts/principal_stress2_stress_tensor.f90 -o principal_stress2_stress_tensor 43 | ./principal_stress2_stress_tensor $s1 $s2 $s3 $p1 $p2 $p3 $t1 $t2 $t3 > temp_p.txt 44 | e11=`grep 'e11' temp_p.txt | awk '{print $3}'` 45 | e12=`grep 'e11' temp_p.txt | awk '{print $6}'` 46 | e13=`grep 'e11' temp_p.txt | awk '{print $9}'` 47 | e22=`grep 'e22' temp_p.txt | awk '{print $3}'` 48 | e23=`grep 'e22' temp_p.txt | awk '{print $6}'` 49 | e33=`grep 'e22' temp_p.txt | awk '{print $9}'` 50 | echo "$e11 $e12 $e13 $e22 $e23 $e33" 51 | ./tectonic.sh $e11 $e12 $e13 $e22 $e23 $e33 $outputfile $nlines 52 | rm -f principal_stress2_stress_tensor temp_p.txt 53 | -------------------------------------------------------------------------------- /OOP/scripts/OOP1D_vertical_left_lateral_strike_slip.m: -------------------------------------------------------------------------------- 1 | function [opt_strike,opt_dip,opt_rake,shear_stress,normal_stress,coulomb_stress,total_CFFmax]=OOP1D_vertical_left_lateral_strike_slip(earthquake_stress,tectonic_stress,friction,skempton) 2 | %earthquake_stress:se11 se12 se13 se22 se23 se33 3 | %tectonic_stress: st11 st12 st13 st22 st23 st33 4 | %Both 'earthquake_stress' and 'tectonic_stress' belong to a local topographic Cartesian coordinate system whose 5 | %x is northern, y is eastern and z is upward. 6 | s=earthquake_stress+tectonic_stress; 7 | row=size(s,1); 8 | opt_strike=[]; 9 | opt_dip=[]; 10 | opt_rake=[]; 11 | total_CFFmax=[]; 12 | shear_stress=[]; 13 | normal_stress=[]; 14 | coulomb_stress=[]; 15 | for i=1:row 16 | A=1/2*( s(i,4) - s(i,1) ) - friction*s(i,2); 17 | B=1/2*friction*( s(i,4) - s(i,1) ) + s(i,2); 18 | %-------------------------------------------% 19 | %just for testing 20 | A1=A; 21 | B1=B; 22 | A2=1/2*( s(i,1) - s(i,4) ) - friction*s(i,2); 23 | B2=1/2*friction*( s(i,4) - s(i,1) ) - s(i,2); 24 | A1_bar=1/2*( earthquake_stress(i,4) - earthquake_stress(i,1) ) - friction*earthquake_stress(i,2); 25 | B1_bar=1/2*friction*( earthquake_stress(i,4) - earthquake_stress(i,1) ) + earthquake_stress(i,2); 26 | A2_bar=1/2*( earthquake_stress(i,1) - earthquake_stress(i,4) ) - friction*earthquake_stress(i,2); 27 | B2_bar=1/2*friction*( earthquake_stress(i,4) - earthquake_stress(i,1) ) - earthquake_stress(i,2); 28 | [(friction^2-1)/(friction^2+1)+2*A1*friction/(1+friction^2)/B1 (A1*A1_bar+B1*B1_bar)/(A2*A2_bar+B2*B2_bar)*B2/B1] 29 | %-------------------------------------------% 30 | CFFmax=sqrt(1+friction^2)*sqrt( 1/4*( s(i,4)-s(i,1) )^2 + s(i,2)^2 ) +1/2*friction*( s(i,1)+s(i,4) ); 31 | theta=1/2*atan(A/B); 32 | if B<0 33 | K=[1;3]; 34 | strike=theta+1/2*K*pi; 35 | else 36 | if A>=0 37 | K=[0;1]; 38 | strike=theta+K*pi; 39 | else 40 | K=[1;2]; 41 | strike=theta+K*pi; 42 | end 43 | end 44 | dip=pi/2; 45 | rake=0; 46 | receiver_strike=rad2deg(strike(1)); 47 | receiver_dip=rad2deg(dip(1)); 48 | receiver_rake=rad2deg(rake(1)); 49 | [shear,normal,coulomb]=CFF(earthquake_stress,receiver_strike,receiver_dip,receiver_rake,friction,skempton); 50 | shear_stress=[shear_stress;shear]; 51 | normal_stress=[normal_stress;normal]; 52 | coulomb_stress=[coulomb_stress;coulomb]; 53 | opt_strike=[opt_strike;strike']; 54 | opt_dip=[opt_dip;dip dip]; 55 | opt_rake=[opt_rake;rake rake]; 56 | total_CFFmax=[total_CFFmax;CFFmax]; 57 | end 58 | opt_strike=rad2deg(opt_strike); 59 | opt_dip=rad2deg(opt_dip); 60 | opt_rake=rad2deg(opt_rake); -------------------------------------------------------------------------------- /OOP/draw_CFS.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | psfile=coulomb.ps 3 | gfortran ../CFSsrc/find_minmax_values/get_gmt_boundary.f90 -o get_gmt_boundary 4 | sed '1d' $2 > tempgrids.txt 5 | ./get_gmt_boundary tempgrids.txt >/dev/null 6 | range=`awk '{printf("%13.6f/%13.6f/%13.6f/%13.6f\n"),$1,$2,$3,$4}' gmtbounds.txt | \ 7 | sed 's/ //g'` 8 | rm -rf tempgrids.txt gmtbounds.txt get_gmt_boundary 9 | #range=102/106/30/34 10 | projection=m4 11 | offx=7 12 | offy=1.5 13 | delta=1m 14 | workdir=./CFS_map 15 | bshut=0 16 | #-----------------------------------------------------------------------------------# 17 | if [ $# != 2 ];then 18 | echo -e "\033[31m USAGE: $0 nchoice\033[0m" 19 | echo -e "\033[31m nchoice=1,2,3. nchoice=1 for displaying CFS resolved on the vertical strike-slip OOPs;\033[31m" 20 | echo -e "\033[31m nchoice=2 for displaying CFS resolved on the 3D OOPs;\n nchoice=3 for displaying CFS resolved on constrained OOPs.\033[0m" 21 | echo -e "\033[31m For the first two choices CFS are resolved using analytical formulae and the execution speed is very fast.\033[0m" 22 | echo -e "\033[31m In contrast, for the third choice CFS are resolved using grid search and the execution speed depends on the step of grid search \n and the size of the parameter space of receiver faults..\033[0m" 23 | echo -e "\033[31m The step is declared by the variable 'NN' in the Line 23 of the program './scripts/OOPCFFmax.f90'. One can modify it to a smaller value\n for accerlating execution speed. But in this circumstance the strike angles, dip angles and rake angles of OOPs are roughly determined.\033[0m" 24 | exit 1 25 | fi 26 | #-----------------------------------------------------------------------------------# 27 | if [ ! -d $workdir ];then 28 | mkdir $workdir 29 | else 30 | rm -rf $workdir/* 31 | fi 32 | cd $workdir 33 | coulomb=../CFS_result/coulomb.out 34 | cptfile=CFS.cpt 35 | makecpt -Cno_green -T-2/2/0.1 > $cptfile 36 | psbasemap -J$projection -R$range -Bpxa2 -Bpya2 -BSWne -K -X$offx -Y$offy >$psfile 37 | if [ $bshut -eq 0 ];then 38 | case $1 in 39 | 1|2|3|4) #1: 1D-strike-OOP 2:1D-thrust-OOP 3:1D-normal-OOP 4:3D-OOP 40 | sed '1d' $coulomb | awk '{print $1,$2,$11}' | psxy -J -R -K -O -B -Ss0.1 -C$cptfile -hi1>>${psfile} 41 | ;; 42 | 5) #grid search 43 | sed '1d' $coulomb | awk '{print $1,$2,$8}' | psxy -J -R -K -O -B -Ss0.1 -C$cptfile -hi1>>${psfile} 44 | esac 45 | else #smoothing CFS at first 46 | case $1 in 47 | 1|2|3|4) 48 | awk '{print $1,$2,$11}' $coulomb | blockmean -I$delta -R$range | \ 49 | surface -Gcoulomb.grd -I$delta -R$range 50 | grdimage -R -B coulomb.grd -C$cptfile -J$projection -K -O>> $psfile 51 | ;; 52 | 5) 53 | awk '{print $1,$2,$8}' $coulomb | blockmean -I$delta -R$range | \ 54 | surface -Gcoulomb.grd -I$delta -R$range 55 | grdimage -R -B coulomb.grd -C$cptfile -J$projection -K -O>> $psfile 56 | esac 57 | fi 58 | psscale -Dn0.8/0.1+w1.5i/0.15i -J -R -C$cptfile -Ba0.5x+l"@~\104@~CFS" -By+l"bars" -K -O --FONT_ANNOT_PRIMARY=12p --FONT_LABEL=12p>>$psfile 59 | ps2pdf $psfile 60 | open ${psfile%.*}.pdf 61 | 62 | -------------------------------------------------------------------------------- /OOP/scripts/find_3D_OOP.m: -------------------------------------------------------------------------------- 1 | function [opt_strike1, opt_dip1, opt_rake1, opt_strike2, opt_dip2, opt_rake2,opt_shear_stress, opt_normal_stress, opt_coulomb_stress ] ... 2 | = find_3D_OOP(earthquake_stress,tectonic_stress,friction,skempton) 3 | %earthquake_stress:e11 e12 e13 e22 e23 e33 4 | %tectonic_stress:t11 t12 t13 t22 t23 t33 5 | %note that the earthquake_stress and tectonic_stress belong to a local 6 | %topographic Cartesian coordinate system whose x, y and z axes are 7 | %northern, eastern and upward. 8 | %opt_strike1, opt_dip1, opt_rake1 are the strike, dip and rake angles of 9 | %the first optimally oriented failure plane (OOP), respectively. 10 | %opt_strike2, opt_dip2, opt_rake2 are the strike, dip and rake angles of 11 | %the second OOP,respectively. 12 | %opt_shear_stress, opt_normal_stress and opt_coulomb_stress are shear stress change, 13 | %normal stress change and Coulomb stress change on the both OOPs (the Coulomb 14 | %stress changes on the both OOPs are equal to each other), respectively. 15 | 16 | 17 | row=size(earthquake_stress,1); 18 | opt_strike1=[]; 19 | opt_dip1=[]; 20 | opt_rake1=[]; 21 | opt_strike2=[]; 22 | opt_dip2=[]; 23 | opt_rake2=[]; 24 | opt_shear_stress=[]; 25 | opt_normal_stress=[]; 26 | opt_coulomb_stress=[]; 27 | for i=1:row 28 | stress = earthquake_stress(i,:) + tectonic_stress(i,:); 29 | stress_tensor=[stress([1 2 3]);... 30 | stress([2 4 5]);... 31 | stress([3 5 6])]; 32 | [V,D]=eig(stress_tensor); 33 | [tempD,tempN]=sort(diag(D)); 34 | D=diag(tempD); 35 | V=V(:,tempN); 36 | sigma1=D(3,3);%the maximum principal stress 37 | %s2=D(2,2);%the intermediate principal stress 38 | sigma3=D(1,1);%the minimum principal stress 39 | P=V(:,[3 2 1]);%the principal stress axes 40 | alpha=0.5*atan(1/friction); 41 | n1=[cos(alpha);0;sin(alpha)]; 42 | s1=[sin(alpha);0;-cos(alpha)]; 43 | % 44 | n2=[cos(alpha);0;-sin(alpha)]; 45 | s2=[sin(alpha);0;cos(alpha)]; 46 | % 47 | new_n1=P*n1; 48 | new_s1=P*s1; 49 | [strike1,dip1,rake1]=normal_slip_directions2_strike_dip_rake_angles(new_n1,new_s1); 50 | opt_strike1=[opt_strike1;strike1]; 51 | opt_dip1=[opt_dip1;dip1]; 52 | opt_rake1=[opt_rake1;rake1]; 53 | % 54 | new_n2=P*n2; 55 | new_s2=P*s2; 56 | [strike2,dip2,rake2]=normal_slip_directions2_strike_dip_rake_angles(new_n2,new_s2); 57 | opt_strike2=[opt_strike2;strike2]; 58 | opt_dip2=[opt_dip2;dip2]; 59 | opt_rake2=[opt_rake2;rake2]; 60 | % 61 | stress= earthquake_stress(i,:); 62 | temp=[]; 63 | [shear_stress,normal_stress,coulomb]=CFF(stress,strike1,dip1,rake1,friction,skempton); 64 | temp=[temp;shear_stress,normal_stress,coulomb]; 65 | [shear_stress,normal_stress,coulomb]=CFF(stress,strike2,dip2,rake2,friction,skempton); 66 | temp=[temp;shear_stress,normal_stress,coulomb]; 67 | temp 68 | opt_shear_stress=[opt_shear_stress;shear_stress]; 69 | opt_normal_stress=[opt_normal_stress;normal_stress]; 70 | opt_coulomb_stress=[opt_coulomb_stress;coulomb]; 71 | end 72 | -------------------------------------------------------------------------------- /OOP/scripts/resolve_OOP.m: -------------------------------------------------------------------------------- 1 | function resolve_OOP(earthquake_stress_path,tectonic_stress_path,coulomb_path,nchoice,friction,skempton) 2 | fp1=fopen(earthquake_stress_path,'r'); 3 | fp2=fopen(tectonic_stress_path,'r'); 4 | fp3=fopen(coulomb_path,'wt'); 5 | fprintf(fp3,' opt_str1 opt_dip1 opt_rake1 opt_str2 opt_dip2 opt_rake2 shear stress(bar) normal stress(bar) coulomb stress(bar)\n'); 6 | disp('processing ...'); 7 | Nslice=360;%the number of equal fractions for the range of strike angle [0,360], used in 'OOP_thrust.m' and 'OOP_normal'. 8 | ncount=1; 9 | while ~feof(fp1) 10 | se=fscanf(fp1,'%f',6); 11 | st=fscanf(fp2,'%f',6); 12 | if isempty(se)||isempty(st) 13 | break; 14 | end 15 | switch nchoice 16 | case 1 %OOP_strike 17 | [opt_strike1,opt_dip1,opt_rake1,opt_shear_stress, opt_normal_stress, opt_coulomb_stress,total_CFFmax]=OOP1D_vertical_left_lateral_strike_slip(se',st',friction,skempton); 18 | num2str(opt_coulomb_stress) 19 | [opt_strike2,opt_dip2,opt_rake2,opt_shear_stress, opt_normal_stress, opt_coulomb_stress,total_CFFmax]=OOP1D_vertical_right_lateral_strike_slip(se',st',friction,skempton); 20 | num2str(opt_coulomb_stress) 21 | disp('OOP_strike'); 22 | case 2 %OOP_thrust 23 | [opt_strike1, opt_dip1, opt_rake1, opt_strike2, opt_dip2, opt_rake2,opt_shear_stress, opt_normal_stress, opt_coulomb_stress ] ... 24 | = OOP_thrust(se',st' ,friction,skempton,ncount,Nslice); 25 | disp('OOP_thrust'); 26 | [opt_strike1 opt_dip1 opt_rake1 opt_strike2 opt_dip2 opt_rake2] 27 | case 3 %OOP_normal 28 | [opt_strike1, opt_dip1, opt_rake1, opt_strike2, opt_dip2, opt_rake2,opt_shear_stress, opt_normal_stress, opt_coulomb_stress ] ... 29 | = OOP_normal(se',st' ,friction,skempton,ncount,Nslice); 30 | disp('OOP_normal'); 31 | [opt_strike1 opt_dip1 opt_rake1 opt_strike2 opt_dip2 opt_rake2] 32 | % %------------------ 33 | case 4 %3D OOP 34 | % se=[ 0.232598517618278 0.006902909733292 0.622396950079850 0.694061438524276 0.229326531659840 0.688507293361295]'; 35 | % st=zeros(6,1); 36 | [opt_strike1, opt_dip1, opt_rake1, opt_strike2, opt_dip2, opt_rake2,opt_shear_stress, opt_normal_stress, opt_coulomb_stress ] ... 37 | = find_3D_OOP(se',st' ,friction,skempton); 38 | disp('the 3D OOP'); 39 | end 40 | % fprintf(fp3,'%10.4f%10.4f%10.4f%10.4f%10.4f%10.4f%19.6e%19.6e%19.6e\n',opt_strike1(1), opt_dip1(1), opt_rake1(1), opt_strike2(1), opt_dip2(1), opt_rake2(1),... 41 | disp(['------save in file: ',coulomb_path]); 42 | [opt_strike1 opt_dip1 opt_rake1 opt_strike2 opt_dip2 opt_rake2] 43 | 44 | fprintf(fp3,'%10.4f%10.4f%10.4f%10.4f%10.4f%10.4f%28.16e%28.16e%28.16e\n',opt_strike1(1), opt_dip1(1), opt_rake1(1), opt_strike2(1), opt_dip2(1), opt_rake2(1),... 45 | opt_shear_stress(1), opt_normal_stress(1), opt_coulomb_stress(1)); 46 | disp(sprintf('ncount=%d',ncount)); ncount=ncount+1; 47 | end 48 | fclose(fp1); 49 | fclose(fp2); 50 | fclose(fp3); 51 | if exist('grid_search_OOP_coeff.mat','file')~=0 52 | delete('grid_search_OOP_coeff.mat'); 53 | end 54 | disp('all done!'); 55 | -------------------------------------------------------------------------------- /grid/all.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | #-------------------------------------------------------------# 3 | if [ $# -eq 18 ];then 4 | while getopts 'T:P:M:C:S:D:R:F:B:' opt 5 | do 6 | case $opt in 7 | T) 8 | sourcefault=$OPTARG 9 | ;; 10 | P) 11 | receiverfault=$OPTARG 12 | ;; 13 | M) 14 | meridian=$OPTARG 15 | ;; 16 | C) 17 | brecompute_stress=$OPTARG 18 | ;; 19 | S) 20 | strike_receiver=$OPTARG 21 | ;; 22 | D) 23 | dip_receiver=$OPTARG 24 | ;; 25 | R) 26 | rake_receiver=$OPTARG 27 | ;; 28 | F) 29 | friction=$OPTARG 30 | ;; 31 | B) 32 | Skempton=$OPTARG 33 | esac 34 | done 35 | else 36 | #echo "there are not enough commandline parameters!" 37 | echo -e "\033[1;30mUSAGE(e.g.):\033[0m ./all.sh -T sourcefaultslipmodel.in -P samplingpoints.in -M meridian -C 1 -S strike_angle -D dip_angle -R rake_angle -F friction -B Skempton" 38 | exit 1 39 | fi 40 | echo -e "sourcefault=$sourcefault meridian=$meridian brecompute_stress=$brecompute_stress\n strike_receiver=$strike_receiver dip_receiver=$dip_receiver rake_receiver=$rake_receiver friction=$friction Skempton=$Skempton" 41 | #receiverfault=sampling_grids.in 42 | #when brecompute_stress=0, the stress changes keep the same for choosing different receiver fault. In this case, computing Coulomb stress 43 | #changes can be dramatically speeded up because the stress changes are not needed to compute again. On the other hand, when brecompute_stress=1, 44 | #the stress changes are computed. In this case, computing Coulomb stress would be a little slower, depending on the number of grid points at 45 | #which Coulomb stress changes are calculated. Note that the variable 'brecompute_stress' should be set to be 1 for the first time to compute 46 | #stress changes and then the stress changes can be used for computing Coulomb stress changes on other receiver fault planes when brecompute_stress=0 47 | #brecompute_stress=1 48 | #-------------------------------------------------------------# 49 | earthquake_stress=./CFS_result/stress.out 50 | if [ $brecompute_stress -eq 0 ];then 51 | if [ ! -f $earthquake_stress ];then 52 | echo -e "\033[31m $earthquake_stress doesn't exist! set brecompute_stress=1 and run the script to generate '${earthquake_stress}' at first.\n\033[0m" 53 | exit 1 54 | fi 55 | sed '1d' ${earthquake_stress} > stress.out 56 | cd ../CFSsrc/computeCFS 57 | make 58 | make clean 59 | cp computeCFS ../../grid 60 | cd ../../grid 61 | ./computeCFS ${strike_receiver} ${dip_receiver} ${rake_receiver} ${friction} ${Skempton} 62 | echo "lon(deg) lat(deg)" > temp_sampling_lonlat.txt 63 | sed '1d' $receiverfault | awk '{print $2,$1}' >>temp_sampling_lonlat.txt 64 | paste temp_sampling_lonlat.txt shearnormalcoulomb.out > lonlatshearnormalcoulomb.out 65 | mv lonlatshearnormalcoulomb.out ${earthquake_stress%stress*}/coulomb.out 66 | rm -rf stress.out shearnormalcoulomb.out 67 | else 68 | ./cal_CFS.sh $sourcefault $receiverfault ${strike_receiver} ${dip_receiver} ${rake_receiver} ${friction} ${Skempton} ${meridian} 69 | fi 70 | rm -rf computeCFS CoulombStressAnalysis sampling_temp.txt 71 | ./draw_CFS.sh $receiverfault 72 | 73 | -------------------------------------------------------------------------------- /drawCFS_script/drawgridCFS.m: -------------------------------------------------------------------------------- 1 | function drawgridCFS() 2 | path=input('input the path of a CFS file: ','s'); 3 | nmode=input('input the selected number(1,2,or 3):'); 4 | [lon,lat,shear,normal,coulomb]=textread(path,'%f%f%f%f%f','delimiter','\t','headerlines',1); 5 | cutoff=2; 6 | minlon=min(lon); 7 | maxlon=max(lon); 8 | minlat=min(lat); 9 | maxlat=max(lat); 10 | lonnew=linspace(minlon,maxlon,300); 11 | latnew=linspace(minlat,maxlat,300); 12 | [lonnew,latnew]=meshgrid(lonnew,latnew); 13 | h=figure; 14 | set(h,'colormap',color_map()); 15 | switch nmode 16 | case {1,3} 17 | coul=griddata(lon,lat,coulomb,lonnew,latnew); 18 | h=pcolor(lonnew,latnew,coul); 19 | shading interp; 20 | case 2 21 | scatter(lon,lat,5,coulomb); 22 | scale=4; 23 | dlat=maxlat-minlat; 24 | dlon=maxlon-minlon; 25 | axis([minlon-dlon*scale,maxlon+dlon*scale,minlat-dlat*scale,maxlat+dlat*scale]); 26 | end 27 | caxis([-cutoff,cutoff]); 28 | xlabel('Longitude(deg)'); 29 | ylabel('Latitude(deg)'); 30 | set(gca,'fontsize',18); 31 | title(colorbar,'bars'); 32 | [~,filename,~] = fileparts(path); 33 | print([filename,'.pdf'],'-dpdf'); 34 | % 35 | function [map]=color_map() 36 | map=[... 37 | 0.125490196078431 0.376470588235294 1.000000000000000;... 38 | 0.125490196078431 0.376470588235294 1.000000000000000;... 39 | 0.125490196078431 0.623529411764706 1.000000000000000;... 40 | 0.125490196078431 0.623529411764706 1.000000000000000;... 41 | 0.125490196078431 0.749019607843137 1.000000000000000;... 42 | 0.125490196078431 0.749019607843137 1.000000000000000;... 43 | 0 0.811764705882353 1.000000000000000;... 44 | 0 0.811764705882353 1.000000000000000;... 45 | 0.164705882352941 1.000000000000000 1.000000000000000;... 46 | 0.164705882352941 1.000000000000000 1.000000000000000;... 47 | 0.333333333333333 1.000000000000000 1.000000000000000;... 48 | 0.333333333333333 1.000000000000000 1.000000000000000;... 49 | 0.498039215686275 1.000000000000000 1.000000000000000;... 50 | 0.498039215686275 1.000000000000000 1.000000000000000;... 51 | 0.666666666666667 1.000000000000000 1.000000000000000;... 52 | 0.666666666666667 1.000000000000000 1.000000000000000;... 53 | 1.000000000000000 1.000000000000000 0.329411764705882;... 54 | 1.000000000000000 1.000000000000000 0.329411764705882;... 55 | 1.000000000000000 0.941176470588235 0;... 56 | 1.000000000000000 0.941176470588235 0;... 57 | 1.000000000000000 0.749019607843137 0;... 58 | 1.000000000000000 0.749019607843137 0;... 59 | 1.000000000000000 0.658823529411765 0;... 60 | 1.000000000000000 0.658823529411765 0;... 61 | 1.000000000000000 0.541176470588235 0;... 62 | 1.000000000000000 0.541176470588235 0;... 63 | 1.000000000000000 0.439215686274510 0;... 64 | 1.000000000000000 0.439215686274510 0;... 65 | 1.000000000000000 0.301960784313725 0;... 66 | 1.000000000000000 0.301960784313725 0;... 67 | 1.000000000000000 0 0;... 68 | 1.000000000000000 0 0]; 69 | -------------------------------------------------------------------------------- /OOP/scripts/principal_stress2_stress_tensor.f90: -------------------------------------------------------------------------------- 1 | program principal_stress2_stress_tensor 2 | implicit none 3 | real*8 sigma1,sigma2,sigma3 4 | real*8 plunge1,plunge2,plunge3 5 | real*8 azimuth1,azimuth2,azimuth3 6 | real*8 P1,P2,P3,T1,T2,T3 7 | real*8 s(3,3) 8 | real*8 deg2rad 9 | real*8 A(3),B(3),C 10 | character*100 arg 11 | integer*4 nargc,i,j,N 12 | real*8 e11,e12,e13,e22,e23,e33 13 | ! 14 | !coded on 22:39 Aug.7th,2016 jjwang 15 | ! 16 | nargc=iargc() 17 | if(nargc.ne.9)then 18 | write(*,*)' ' 19 | write(*,*)'Usage: ./principal_stress2_stress_tensor sigma1 sigma2 sigma3 plunge1 plunge2 plunge3 azimuth1 azimuth2 azimuth3' 20 | write(*,*)'This function is used to compute background tectonic stress tensor in a given coordinate system whose' 21 | write(*,*)'x is northern, y is eastern and z is upward. The inputs are the principal stresses of sigma1, sigma2 and sigma3,' 22 | write(*,*)'plunge angles of plunge1, plunge2, plunge3 with respect to horizontal plane(x-o-y) of the three principal axes,' 23 | write(*,*)'and azimuth angles of azimuth1, azimuth2, azimuth3 for the horizontal projection of the three principal axes' 24 | write(*,*)'counted clockwisely from due north (x axis).' 25 | write(*,*)' ' 26 | return 27 | endif 28 | ! 29 | deg2rad=acos(-1.0d0)/180.0d0 30 | ! 31 | call getarg(1,arg) 32 | read(arg,*)sigma1 33 | ! 34 | call getarg(2,arg) 35 | read(arg,*)sigma2 36 | ! 37 | call getarg(3,arg) 38 | read(arg,*)sigma3 39 | ! 40 | call getarg(4,arg) 41 | read(arg,*)plunge1 42 | ! 43 | call getarg(5,arg) 44 | read(arg,*)plunge2 45 | ! 46 | call getarg(6,arg) 47 | read(arg,*)plunge3 48 | ! 49 | call getarg(7,arg) 50 | read(arg,*)azimuth1 51 | ! 52 | call getarg(8,arg) 53 | read(arg,*)azimuth2 54 | ! 55 | call getarg(9,arg) 56 | read(arg,*)azimuth3 57 | ! 58 | !write(*,*)sigma1,sigma2,sigma3,plung1,plung2,plung3,azimuth1,azimuth2,azimuth3 59 | ! 60 | P1=plunge1*deg2rad 61 | P2=plunge2*deg2rad 62 | P3=plunge3*deg2rad 63 | ! 64 | T1=azimuth1*deg2rad 65 | T2=azimuth2*deg2rad 66 | T3=azimuth3*deg2rad 67 | ! 68 | s(1,1)=cos(P1)*cos(T1) 69 | s(2,1)=cos(P1)*sin(T1) 70 | s(3,1)=sin(P1) 71 | ! 72 | s(1,2)=cos(P2)*cos(T2) 73 | s(2,2)=cos(P2)*sin(T2) 74 | s(3,3)=sin(P2) 75 | ! 76 | s(1,3)=cos(P3)*cos(T3) 77 | s(2,3)=cos(P3)*sin(T3) 78 | s(3,3)=sin(P3) 79 | !write(*,*)P1,P2,P3,T1,T2,T3 80 | ! 81 | !write(*,*)((s(i,j),i=1,3),j=1,3) 82 | ! 83 | N=3 84 | do i=1,2 85 | A(1)=s(1,i) 86 | A(2)=s(2,i) 87 | A(3)=s(3,i) 88 | do j=i+1,3 89 | B(1)=s(1,j) 90 | B(2)=s(2,j) 91 | B(3)=s(3,j) 92 | C=A(1)*B(1)+A(2)*B(2)+A(3)*B(3) 93 | ! call two_vector_dot_product(A,B,N,C) 94 | ! write(*,*)'C=',C 95 | if(abs(C).gt.1.0e-6)then 96 | write(*,*)'***error: at least two principal axes are not orthogonal to each other!' 97 | return 98 | endif 99 | enddo 100 | enddo 101 | ! 102 | e11=cos(P1)**2d0*cos(T1)**2d0*sigma1+cos(P2)**2d0*cos(T2)**2d0*sigma2+cos(P3)**2d0*cos(T3)**2d0*sigma3 103 | e12=0.5d0*( cos(P1)**2d0*sin(2d0*T1)*sigma1+cos(P2)**2d0*sin(2d0*T2)*sigma2+cos(P3)**2d0*sin(2d0*T3)*sigma3 ) 104 | e13=0.5d0*( sin(2d0*P1)*cos(T1)*sigma1+sin(2d0*P2)*cos(T2)*sigma2+sin(2d0*P3)*cos(T3)*sigma3 ) 105 | e22=cos(P1)**2d0*sin(T1)**2d0*sigma1+cos(P2)**2d0*sin(T2)**2d0*sigma2+cos(P3)**2d0*sin(T3)**2d0*sigma3 106 | e23=0.5d0*( sin(2d0*P1)*sin(T1)*sigma1+sin(2d0*P2)*sin(T2)*sigma2+sin(2d0*P3)*sin(T3)*sigma3 ) 107 | e33=sin(P1)**2d0*sigma1+sin(P2)**2d0*sigma2+sin(P3)**2d0*sigma3 108 | write(*,1000)e11,e12,e13,e22,e23,e33 109 | 1000 format(1x,'e11 = ',1x,e13.6,1x,'e12 = ',1x,e13.6,1x,'e13 = ',1x,e13.6,/,& 110 | 1x,'e22 = ',1x,e13.6,1x,'e23 = ',1x,e13.6,1x,'e33 = ',1x,e13.6) 111 | end program principal_stress2_stress_tensor 112 | 113 | 114 | subroutine two_vector_dot_product(a,b,N,c) 115 | implicit none 116 | integer*4 i,N 117 | real*8 a(N),b(N),c,temp 118 | temp=0d0 119 | do i=1,N 120 | temp=temp+a(i)*b(i) 121 | enddo 122 | end 123 | -------------------------------------------------------------------------------- /OOP/scripts/OOP_thrust.m: -------------------------------------------------------------------------------- 1 | function [opt_strike1, opt_dip1, opt_rake1, opt_strike2, opt_dip2, opt_rake2,opt_shear_stress, opt_normal_stress, opt_coulomb_stress ] ... 2 | = OOP_thrust(earthquake_stress,tectonic_stress,friction,skempton,nload,Nslice) 3 | %earthquake_stress:e11 e12 e13 e22 e23 e33 4 | %tectonic_stress:t11 t12 t13 t22 t23 t33 5 | %note that the earthquake_stress and tectonic_stress belong to a local 6 | %topographic Cartesian coordinate system whose x, y and z axes are 7 | %northern, eastern and upward. 8 | %opt_strike1, opt_dip1, opt_rake1 are the strike, dip and rake angles of 9 | %the first optimally oriented failure plane (OOP), respectively. 10 | %opt_strike2, opt_dip2, opt_rake2 are the strike, dip and rake angles of 11 | %the second OOP,respectively. 12 | %opt_shear_stress, opt_normal_stress and opt_coulomb_stress are shear stress change, 13 | %normal stress change and Coulomb stress change on the both OOPs (the Coulomb 14 | %stress changes on the both OOPs are equal to each other), respectively. 15 | 16 | 17 | row=size(earthquake_stress,1); 18 | opt_strike1=[]; 19 | opt_dip1=[]; 20 | opt_rake1=[]; 21 | opt_strike2=[]; 22 | opt_dip2=[]; 23 | opt_rake2=[]; 24 | opt_shear_stress=[]; 25 | opt_normal_stress=[]; 26 | opt_coulomb_stress=[]; 27 | % 28 | dip=0.5*atand(1/friction);%dip angle in the principal stresses coordinate system 29 | rake=90; 30 | if nload==1 31 | disp('prepare the parameter space') 32 | OOP_coefficients(dip,rake,friction); 33 | end 34 | load('grid_OOP_coeff.mat'); 35 | for i=1:row 36 | stress = earthquake_stress(i,:) + tectonic_stress(i,:); 37 | K=KOOP.*stress; 38 | %k11 k12 k13 k22 k23 k33 39 | %1 2 3 4 5 6 40 | A1=K(1)-K(4); %A1=k11-k22 41 | A2=2*K(2); %A2=2*k12 42 | A3=K(3); %A3=k13 43 | A4=-K(5); %A4=-k23 44 | % 45 | B1=4*(A1^2+A2^2); 46 | B2=4*(A1*A4+A2*A3); 47 | B3=-4*A1^2-4*A2^2+A3^2+A4^2; 48 | B4=-2*A2*A3-4*A1*A4; 49 | B5=A2^2-A4^2; 50 | % 51 | if B1==0 52 | if A3==0&&A4==0 53 | x=[-1,1]; 54 | else 55 | temp=sqrt( A4^2/(A3^2+A4^2) ); 56 | x=[-temp,temp]; 57 | end 58 | else 59 | x=roots([B1,B2,B3,B4,B5]); 60 | x=real( x((imag(x)==0),:) );%cos(phi) 61 | end 62 | % 63 | if isempty(x) 64 | warning('fail to find the 1D thrust-slip OOP!'); 65 | else 66 | strikes=[]; 67 | coulombs=[]; 68 | nx=length(x); 69 | for j=1:nx 70 | tempstrike1=acosd( x(j) ); 71 | tempstrike2=180+acosd( -x(j) ); 72 | strikes=[strikes;tempstrike1;tempstrike2]; 73 | [~,~,tempcoulomb]=CFF(stress,tempstrike1,dip,rake,friction,skempton); 74 | coulombs=[coulombs;tempcoulomb]; 75 | [~,~,tempcoulomb]=CFF(stress,tempstrike2,dip,rake,friction,skempton); 76 | coulombs=[coulombs;tempcoulomb]; 77 | end 78 | end 79 | strikes=strikes(max(coulombs)==coulombs); 80 | if length(strikes)==1 81 | strikes=[strikes strikes]; 82 | end 83 | strike1=strikes(1); 84 | dip1=dip; 85 | rake1=90; 86 | opt_strike1=[opt_strike1;strike1]; 87 | opt_dip1=[opt_dip1;dip1]; 88 | opt_rake1=[opt_rake1;rake1]; 89 | % 90 | strike2=strikes(2); 91 | dip2=dip; 92 | rake2=90; 93 | opt_strike2=[opt_strike2;strike2]; 94 | opt_dip2=[opt_dip2;dip2]; 95 | opt_rake2=[opt_rake2;rake2]; 96 | % 97 | stress= earthquake_stress(i,:); 98 | temp=[]; 99 | [shear_stress,normal_stress,coulomb]=CFF(stress,strike1,dip1,rake1,friction,skempton); 100 | temp=[temp;shear_stress,normal_stress,coulomb]; 101 | [shear_stress,normal_stress,coulomb]=CFF(stress,strike2,dip2,rake2,friction,skempton); 102 | temp=[temp;shear_stress,normal_stress,coulomb]; 103 | temp 104 | opt_shear_stress=[opt_shear_stress;shear_stress]; 105 | opt_normal_stress=[opt_normal_stress;normal_stress]; 106 | opt_coulomb_stress=[opt_coulomb_stress;coulomb]; 107 | disp(sprintf('optstrike=%13.6f,optdip=%13.6f,optrake=%13.6f,shear=%13.6f,normal=%13.6f,coulomb=%13.6f',... 108 | opt_strike1(1),opt_dip1(1),opt_rake1(1),shear_stress(1),normal_stress(1),coulomb(1))); 109 | end 110 | -------------------------------------------------------------------------------- /OOP/scripts/OOP_normal.m: -------------------------------------------------------------------------------- 1 | function [opt_strike1, opt_dip1, opt_rake1, opt_strike2, opt_dip2, opt_rake2,opt_shear_stress, opt_normal_stress, opt_coulomb_stress ] ... 2 | = OOP_normal(earthquake_stress,tectonic_stress,friction,skempton,nload,Nslice) 3 | %earthquake_stress:e11 e12 e13 e22 e23 e33 4 | %tectonic_stress:t11 t12 t13 t22 t23 t33 5 | %note that the earthquake_stress and tectonic_stress belong to a local 6 | %topographic Cartesian coordinate system whose x, y and z axes are 7 | %northern, eastern and upward. 8 | %opt_strike1, opt_dip1, opt_rake1 are the strike, dip and rake angles of 9 | %the first optimally oriented failure plane (OOP), respectively. 10 | %opt_strike2, opt_dip2, opt_rake2 are the strike, dip and rake angles of 11 | %the second OOP,respectively. 12 | %opt_shear_stress, opt_normal_stress and opt_coulomb_stress are shear stress change, 13 | %normal stress change and Coulomb stress change on the both OOPs (the Coulomb 14 | %stress changes on the both OOPs are equal to each other), respectively. 15 | 16 | 17 | row=size(earthquake_stress,1); 18 | opt_strike1=[]; 19 | opt_dip1=[]; 20 | opt_rake1=[]; 21 | opt_strike2=[]; 22 | opt_dip2=[]; 23 | opt_rake2=[]; 24 | opt_shear_stress=[]; 25 | opt_normal_stress=[]; 26 | opt_coulomb_stress=[]; 27 | % 28 | dip=90-0.5*atand(1/friction);%dip angle in the principal stresses coordinate system 29 | rake=-90; 30 | if nload==1 31 | disp('prepare the parameter space') 32 | OOP_coefficients(dip,rake,friction); 33 | end 34 | load('grid_OOP_coeff.mat'); 35 | for i=1:row 36 | stress = earthquake_stress(i,:) + tectonic_stress(i,:); 37 | K=KOOP.*stress; 38 | %k11 k12 k13 k22 k23 k33 39 | %1 2 3 4 5 6 40 | A1=K(1)-K(4); %A1=k11-k22 41 | A2=2*K(2); %A2=2*k12 42 | A3=K(3); %A3=k13 43 | A4=-K(5); %A4=-k23 44 | % 45 | B1=4*(A1^2+A2^2); 46 | B2=4*(A1*A4+A2*A3); 47 | B3=-4*A1^2-4*A2^2+A3^2+A4^2; 48 | B4=-2*A2*A3-4*A1*A4; 49 | B5=A2^2-A4^2; 50 | % 51 | if B1==0 52 | if A3==0&&A4==0 53 | x=[-1,1]; 54 | else 55 | temp=sqrt( A4^2/(A3^2+A4^2) ); 56 | x=[-temp,temp]; 57 | end 58 | else 59 | x=roots([B1,B2,B3,B4,B5]); 60 | x=real( x((imag(x)==0),:) );%cos(phi) 61 | end 62 | % 63 | if isempty(x) 64 | warning('fail to find the 1D thrust-slip OOP!'); 65 | else 66 | strikes=[]; 67 | coulombs=[]; 68 | nx=length(x); 69 | for j=1:nx 70 | tempstrike1=acosd( x(j) ); 71 | tempstrike2=180+acosd( -x(j) ); 72 | strikes=[strikes;tempstrike1;tempstrike2]; 73 | [~,~,tempcoulomb]=CFF(stress,tempstrike1,dip,rake,friction,skempton); 74 | coulombs=[coulombs;tempcoulomb]; 75 | [~,~,tempcoulomb]=CFF(stress,tempstrike2,dip,rake,friction,skempton); 76 | coulombs=[coulombs;tempcoulomb]; 77 | end 78 | end 79 | strikes=strikes(max(coulombs)==coulombs); 80 | if length(strikes)==1 81 | strikes=[strikes strikes]; 82 | end 83 | strike1=strikes(1); 84 | dip1=dip; 85 | rake1=-90; 86 | opt_strike1=[opt_strike1;strike1]; 87 | opt_dip1=[opt_dip1;dip1]; 88 | opt_rake1=[opt_rake1;rake1]; 89 | % 90 | strike2=strikes(2); 91 | dip2=dip; 92 | rake2=-90; 93 | opt_strike2=[opt_strike2;strike2]; 94 | opt_dip2=[opt_dip2;dip2]; 95 | opt_rake2=[opt_rake2;rake2]; 96 | % 97 | stress= earthquake_stress(i,:); 98 | temp=[]; 99 | [shear_stress,normal_stress,coulomb]=CFF(stress,strike1,dip1,rake1,friction,skempton); 100 | temp=[temp;shear_stress,normal_stress,coulomb]; 101 | [shear_stress,normal_stress,coulomb]=CFF(stress,strike2,dip2,rake2,friction,skempton); 102 | temp=[temp;shear_stress,normal_stress,coulomb]; 103 | temp 104 | opt_shear_stress=[opt_shear_stress;shear_stress]; 105 | opt_normal_stress=[opt_normal_stress;normal_stress]; 106 | opt_coulomb_stress=[opt_coulomb_stress;coulomb]; 107 | disp(sprintf('optstrike=%13.6f,optdip=%13.6f,optrake=%13.6f,shear=%13.6f,normal=%13.6f,coulomb=%13.6f',... 108 | opt_strike1(1),opt_dip1(1),opt_rake1(1),shear_stress(1),normal_stress(1),coulomb(1))); 109 | end 110 | -------------------------------------------------------------------------------- /preproc/preproc_sampling_OOP.m: -------------------------------------------------------------------------------- 1 | function preproc_sampling_OOP() 2 | clc;clear;close all; 3 | disp('-----the boundary and grid size of sampling points-----'); 4 | minlon=input('minimum longitude (deg): '); 5 | maxlon=input('maximum longitude (deg): '); 6 | minlat=input('minimum latitude (deg): '); 7 | maxlat=input('maximum latitude (deg): '); 8 | dlon=input('step of longitude (deg): '); 9 | dlat=input('step of latitude (deg): '); 10 | depth=input('depth (km): '); 11 | disp('-----the principal tectonic stress-----'); 12 | disp('the maximum principal stress s1 (magnitdue(bar), plunge(deg),trend(deg)):'); 13 | s1=input('s1: '); 14 | disp('the intermediate principal stress s2 (magnitdue(bar), plunge(deg),trend(deg)):'); 15 | s2=input('s2: '); 16 | disp('the minimum principal stress s3 (magnitdue(bar), plunge(deg),trend(deg)):'); 17 | s3=input('s3: '); 18 | regional_stress=[s1;s2;s3]; 19 | %------------------------Modify Parameters at here------------------------% 20 | nchoice=0; 21 | switch nchoice 22 | case 1 23 | minlon=100;%deg 24 | maxlon=106;%deg 25 | minlat=28;%deg 26 | maxlat=36;%deg 27 | dlon=0.01;%deg 28 | dlat=0.01;%deg 29 | depth=5;%km 30 | % receiver_strike=150;%deg 31 | % receiver_dip=78;%deg 32 | % receiver_rake=-13;%deg 33 | % friction=0.4; 34 | % skempton=0.0; 35 | %regional_stress=[-100 0 75;-10 90 0;-50 0 165]; 36 | % regional_stress=[-100 0 60;... 37 | % -10 90 0;... 38 | % 0 0 150]; 39 | regional_stress=[-100 0 30;... 40 | -10 90 0;... 41 | 0 0 120]; 42 | % regional_stress=[-100 0 90;... 43 | % -10 90 0;... 44 | % 0 0 180]; 45 | case 2 46 | minlon=102;%deg 47 | maxlon=106;%deg 48 | minlat=30;%deg 49 | maxlat=34;%deg 50 | dlon=0.01;%deg 51 | dlat=0.01;%deg 52 | depth=10;%km 53 | % receiver_strike=150;%deg 54 | % receiver_dip=78;%deg 55 | % receiver_rake=-13;%deg 56 | % friction=0.4; 57 | % skempton=0.0; 58 | %regional_stress=[-100 0 75;-10 90 0;-50 0 165]; 59 | % regional_stress=[-100 0 60;... 60 | % -10 90 0;... 61 | % 0 0 150]; 62 | regional_stress=[-100 0 60;... 63 | -10 90 0;... 64 | 0 0 150]; 65 | % regional_stress=[-100 0 90;... 66 | % -10 90 0;... 67 | % 0 0 180]; 68 | end 69 | %-------------------------------------------------------------------------% 70 | outputfile='../OOP/sampling_grids.in'; 71 | N=2; 72 | N=601; 73 | ddlon=9999; 74 | epsilon=1.0e-4; 75 | % while abs(ddlon-dlon)>epsilon 76 | % lon=linspace(minlon,maxlon,N); 77 | % ddlon=lon(2)-lon(1); 78 | % N=N+1; 79 | % end 80 | % % 81 | % N=2; 82 | % N=801; 83 | % ddlat=9999; 84 | % while abs(ddlat-dlat)>epsilon 85 | % lat=linspace(minlat,maxlat,N); 86 | % ddlat=lat(2)-lat(1); 87 | % N=N+1; 88 | % end 89 | lon=minlon:dlon:maxlon; 90 | lat=minlat:dlat:maxlat; 91 | ddlon=dlon; 92 | ddlat=dlat; 93 | %----------------------------- 94 | [lon,lat]=meshgrid(lon,lat); 95 | lon=lon(:); 96 | lat=lat(:); 97 | totalN=length(lon); 98 | fp=fopen(outputfile,'wt'); 99 | fprintf(fp,'%d\n',totalN); 100 | for i=1:totalN 101 | fprintf(fp,'%13.6f%13.6f%13.6f\n',lat(i),lon(i),depth); 102 | end 103 | fclose(fp); 104 | path=pwd; 105 | n=find(path=='/'); 106 | disp([mfilename,'.m: The sampling file was save in the following directory:']); 107 | disp([path(1:max(n)),outputfile(4:end)]); 108 | disp(sprintf('total sampling points: %d\ndlon=%8.1f km dlat=%8.1f km',totalN,deg2rad(ddlon)*6378,deg2rad(ddlat)*6378)); 109 | % 110 | figure; 111 | plot(lon,lat,'r.'); 112 | xlabel('Longitude(deg)'); 113 | ylabel('Latitude(deg)'); 114 | title('Gridded points'); 115 | set(gca,'FontSize',20); 116 | set(gcf,'color','w'); 117 | %-------------------------------------------------------------------------% 118 | outputfile='../OOP/tectonic_stress.in'; 119 | s=tectonic_stress(regional_stress); 120 | if isempty(s) 121 | disp('something is wrong for generating tectonic background stresses.'); 122 | return; 123 | end 124 | T=repmat([s(1,:) s(2,2:3) s(3,3)] ,totalN,1);%x is northern, y is eastern and z is upward. 125 | dlmwrite(outputfile,T,'delimiter','\t','precision','%13.6e'); 126 | disp([mfilename,'.m: The regional tectonic stress file was save in the following directory:']); 127 | disp([path(1:max(n)),outputfile(4:end)]); 128 | % 129 | -------------------------------------------------------------------------------- /profile/all.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | if [ $# -eq 18 ];then 3 | while getopts 'T:P:M:C:S:D:R:F:B:' opt 4 | do 5 | case $opt in 6 | T) 7 | sourcefault=$OPTARG 8 | ;; 9 | M) 10 | meridian=$OPTARG 11 | ;; 12 | P) 13 | profile_grid=$OPTARG 14 | ;; 15 | C) 16 | brecompute_stress=$OPTARG 17 | ;; 18 | S) 19 | strike_receiver=$OPTARG 20 | ;; 21 | D) 22 | dip_receiver=$OPTARG 23 | ;; 24 | R) 25 | rake_receiver=$OPTARG 26 | ;; 27 | F) 28 | friction=$OPTARG 29 | ;; 30 | B) 31 | Skempton=$OPTARG 32 | esac 33 | done 34 | else 35 | #echo "there are not enough commandline parameters!" 36 | echo -e "\033[1;30mUSAGE(e.g.):\033[0m ./all.sh -T sourcefaultslipmodel.in -P samplingprofile.in -M meridian -C 1 -S strike_angle -D dip_angle -R rake_angle -F friction -B Skempton" 37 | exit 1 38 | fi 39 | echo -e "sourcefault=$sourcefault meridian=$meridian brecompute_stress=$brecompute_stress\n strike_receiver=$strike_receiver dip_receiver=$dip_receiver rake_receiver=$rake_receiver friction=$friction Skempton=$Skempton" 40 | #-------------------------------------------------------------# 41 | receiverfault=sampling_grids.in 42 | #profile_grid=./inputdata/profile_along_fault_plane1.txt 43 | #when brecompute_stress=0, the stress changes keep the same for choosing different receiver fault. In this case, computing Coulomb stress 44 | #changes can be dramatically speeded because the stress changes are not needed to compute again. On the other hand, when brecompute_stress=1, 45 | #the stress changes are computed. In this case, computing Coulomb stress would be a little slower, depending on the number of grid points at 46 | #which Coulomb stress changes are calculated. Note that the variable 'brecompute_stress' should be set to be 1 for the first time to compute 47 | #stress changes and then the stress changes can be used for computing Coulomb stress changes on other receiver fault planes when brecompute_stress=0 48 | #-------------------------------------------------------------# 49 | sed '1,28d' $profile_grid | awk '{print $1,$2,$3}' > $receiverfault 50 | gfortran ../CFSsrc/find_minmax_values/find_minmax_values.f90 -o find_minmax_values 51 | find_range_for_GMT_drawing() 52 | { 53 | coulomb_file=$1 54 | for((j=1;j<=5;j++)) 55 | do 56 | case $j in 57 | 1) 58 | sed '1d' "$coulomb_file" | awk '{print $1}' > values.txt 59 | ;; 60 | 2) 61 | sed '1d' "$coulomb_file" | awk '{print $2}' > values.txt 62 | ;; 63 | 3) 64 | sed '1d' "$coulomb_file" | awk '{print $3}' > values.txt 65 | ;; 66 | 4) 67 | sed '1d' "$coulomb_file" | awk '{print $4}' > values.txt 68 | ;; 69 | 5) 70 | sed '1d' "$coulomb_file" | awk '{print $5}' > values.txt 71 | esac 72 | ./find_minmax_values 73 | if [ $j -eq 1 ];then 74 | echo "(lon.,lat,depth) geographic range of the grids in the profile" > range_for_GMT_drawing.txt 75 | awk '{print $2,$4}' minmaxvalues.txt >> range_for_GMT_drawing.txt 76 | elif [ $j -le 3 ];then 77 | awk '{print $2,$4}' minmaxvalues.txt >> range_for_GMT_drawing.txt 78 | else 79 | if [ $j -eq 4 ];then 80 | echo "(along-strike(km),downdip(km)) local range of the grids in the profile" >> range_for_GMT_drawing.txt 81 | awk '{print $2,$4}' minmaxvalues.txt >> range_for_GMT_drawing.txt 82 | else 83 | awk '{print $2,$4}' minmaxvalues.txt >> range_for_GMT_drawing.txt 84 | fi 85 | fi 86 | done 87 | 88 | } 89 | earthquake_stress=./CFS_result/stress.out 90 | if [ $brecompute_stress -eq 0 ];then 91 | if [ ! -f $earthquake_stress ];then 92 | echo -e "\033[31m The file '${earthquake_stress}' doesn't exist! please modify the variable 'brecompute_stress' to be 'brecompute_stress=1' and run the script.\033[0m" 93 | exit 1 94 | fi 95 | sed '1d' ${earthquake_stress} > stress.out 96 | cd ../CFSsrc/computeCFS/ 97 | make clean 98 | make 99 | cp computeCFS ../../profile/ 100 | cd ../../profile 101 | ./computeCFS ${strike_receiver} ${dip_receiver} ${rake_receiver} ${friction} ${Skempton} 102 | else 103 | echo "--------------" 104 | pwd 105 | echo "#############" 106 | echo -e "sourcefault=$sourcefault meridian=$meridian brecompute_stress=$brecompute_stress\n strike_receiver=$strike_receiver dip_receiver=$dip_receiver rake_receiver=$rake_receiver friction=$friction Skempton=$Skempton" 107 | ./cal_CFS.sh $sourcefault $receiverfault ${strike_receiver} ${dip_receiver} ${rake_receiver} ${friction} ${Skempton} ${meridian} 108 | awk '{print $3,$4,$5}' ${earthquake_stress%stress*}/coulomb.out > shearnormalcoulomb.out 109 | fi 110 | # 111 | echo "lon(deg) lat(deg) depth(km) ksi(km) downdip(km)" > temp_sampling_lonlat.txt 112 | sed '1,29d' $profile_grid | awk '{print $2,$1,$3,$4,$5}' >>temp_sampling_lonlat.txt 113 | paste temp_sampling_lonlat.txt shearnormalcoulomb.out > coulomb.out 114 | find_range_for_GMT_drawing coulomb.out 115 | mv coulomb.out ${earthquake_stress%stress*} 116 | rm -rf stress.out temp_sampling_lonlat.txt shearnormalcoulomb.out 117 | rm -rf values.txt minmaxvalues.txt sampling_temp.txt 118 | rm -rf computeCFS find_minmax_values CoulombStressAnalysis 119 | rm -rf sampling_grids.in 120 | #####################Draw figure########################### 121 | ./draw_CFS.sh 122 | ############### 123 | rm -rf range_for_GMT_drawing.txt 124 | 125 | -------------------------------------------------------------------------------- /OOP/all.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | #-------------------------------------------------------------# 3 | if [ $# -ge 16 ];then 4 | while getopts 'T:P:M:C:F:B:S:N:' opt 5 | do 6 | case $opt in 7 | T) 8 | sourcefault=$OPTARG 9 | ;; 10 | P) 11 | receiverfault=$OPTARG 12 | ;; 13 | M) 14 | meridian=$OPTARG 15 | ;; 16 | C) 17 | brecompute_stress=$OPTARG 18 | ;; 19 | F) 20 | friction=$OPTARG 21 | ;; 22 | B) 23 | Skempton=$OPTARG 24 | ;; 25 | S) 26 | tectonic_stress=$OPTARG 27 | ;; 28 | N) 29 | nchoiceOOP=$OPTARG 30 | esac 31 | done 32 | else 33 | #echo "there are not enough commandline parameters!" 34 | echo -e "\033[1;30mUSAGE(e.g.):\033[0m ./all.sh -T sourcefaultslipmodel.in -P samplingpoints.in -M meridian -C 1 -F friction -B Skempton -S tectonic_stress -N nchoiceOOP \n" 35 | exit 1 36 | fi 37 | if [ $nchoiceOOP -eq 5 ];then 38 | shift 16 39 | if [ $# -eq 7 ];then 40 | minstrike=$1 41 | maxstrike=$2 42 | mindip=$3 43 | maxdip=$4 44 | minrake=$5 45 | maxrake=$6 46 | NN=$7 47 | else 48 | echo -e "\033[1;30mUSAGE(e.g.):\033[0m ./all.sh -T sourcefaultslipmodel.in -P samplingpoints.in -M meridian -C 1 -F friction -B Skempton -S tectonic_stress -N nchoiceOOP 0 360 0 90 0 360 36" 49 | exit -1 50 | fi 51 | fi 52 | echo -e "sourcefault=$sourcefault receiverfault=$receiverfault meridian=$meridian brecompute_stress=$brecompute_stress friction=$friction Skempton=$Skempton \n tectonic_stress_path=$tectonic_stress_path nchoiceOOP=$nchoiceOOP" 53 | echo "minstrike=$minstrike maxstrike=$maxstrike mindip=$mindip maxdip=$maxdip minrake=$minrake maxrake=$maxrake NN=$NN" 54 | ##sourcefault=Hashimoto_slipmodel10.in 55 | ##receiverfault=sampling_grids.in 56 | ##friction=0.4 57 | ##Skempton=0.0 58 | #meridan is used for Gaussian projection. For the whole study region, it can be prescribed to be the middle of the longitude. 59 | ##meridian=104 #deg 60 | #when brecompute_stress=0, the stress changes keep the same for choosing different receiver fault. In this case, computing Coulomb stress 61 | #changes can be dramatically speeded because the stress changes are not needed to compute again. On the other hand, when brecompute_stress=1, 62 | #the stress changes are computed. In this case, computing Coulomb stress would be a little slower, depending on the number of grid points at 63 | #which Coulomb stress changes are calculated. Note that the variable 'brecompute_stress' should be set to be 1 for the first time to compute 64 | #stress changes and then the stress changes can be used for computing Coulomb stress changes on other receiver fault planes when brecompute_stress=0 65 | ##brecompute_stress=1 66 | ############################################################# 67 | #note that here the strike angle, dip angle and rake angle of the receiver fault 68 | #are merely used to compute stress tensor through running the 'CoulombAnalysis' program with these dummy parameters. 69 | #Therefore, any valid values of them are approriate. 70 | #In the case of resolving the OOP, the strike angle, dip angle and rake angles of the OOP are in fact determined by the OOP models 71 | #rather than being predefined. 72 | strike_receiver=150 73 | dip_receiver=78 74 | rake_receiver=-13 75 | #earthquake_stress=./CFS_result/stress.out 76 | commonpath=./CFS_result 77 | if [ ! -d $commonpath ];then 78 | mkdir $commonpath 79 | fi 80 | earthquake_stress=${commonpath}/stress_backup.out 81 | if [ $brecompute_stress -eq 1 ];then 82 | rm -rf ${earthquake_stress%stress*}coulomb.out 83 | ./cal_CFS.sh $sourcefault $receiverfault ${strike_receiver} ${dip_receiver} ${rake_receiver} ${friction} ${Skempton} ${meridian} 84 | cp ./CFS_result/stress.out ${earthquake_stress} 85 | fi 86 | # 87 | echo "$earthquake_stress" 88 | #-------------------resolve the OOP------------------------# 89 | if [ ! -f $earthquake_stress ];then 90 | echo -e "\033[31mthe file '${earthquake_stress}' does not exist! set the variable 'brecompute_stress=1' at the beginning of this script\033[0m" 91 | echo -e "\033[31m and then run this script. Only when the file exists the variable 'brecompute_stress' can be set to 'brecompute_stress=0'\033[0m" 92 | echo -e "\033[31m Also, please check whether the file of the slip model of source fault and the sampling file are correctly prepared because without\033[0m" 93 | echo -e "\033[31m the both files the file '${earthquake_stress}' cannot be generated.\033[0m" 94 | exit 1 95 | fi 96 | sed '1d' $earthquake_stress > stress.out 97 | earthquake_stress_path=stress.out 98 | #for test Sep.27,2018 99 | #earthquake_stress_path=stress1.out 100 | #--------------------------------------------- 101 | tectonic_stress_path=tectonic_stress.in 102 | if [ $tectonic_stress_path == $tectonic_stress ];then 103 | echo -e "\033[31mwarning(ignorable): please set the filename of the regional stress field other than 'tectonic_stress.in'.\033[0m" 104 | fi 105 | #--------------------------------------------- 106 | cp $tectonic_stress $tectonic_stress_path 107 | coulomb_path=coulomb.out 108 | rm -rf $coulomb_path 109 | #------------------ 110 | case $nchoiceOOP in 111 | 1|2|3|4) 112 | cd ./scripts 113 | matlab -nodesktop -nodisplay -nosplash -r "resolve_OOP('../${earthquake_stress_path}','../${tectonic_stress_path}','../${coulomb_path}',${nchoiceOOP},${friction},${Skempton});quit" 114 | cd .. 115 | echo "lon(deg) lat(deg)" > temp.txt 116 | #sed '1d' sampling_grids.in | awk '{print $2,$1}' >> temp.txt 117 | sed '1d' ${receiverfault} | awk '{print $2,$1}' >> temp.txt 118 | #cp coulomb.out coulomb_backup.out 119 | paste temp.txt coulomb.out > temp1.txt 120 | mv temp1.txt ${earthquake_stress%stress*}coulomb.out 121 | rm -rf temp.txt temp1.txt coulomb.out stress.out 122 | ;; 123 | 5) 124 | gfortran ./scripts/OOPCFFmax.f90 -o OOPCFFmax 125 | echo "compiling OOPCFFmax is done!" 126 | ./OOPCFFmax $earthquake_stress_path $tectonic_stress_path $coulomb_path $minstrike $maxstrike $mindip $maxdip $minrake $maxrake $friction $Skempton $NN 127 | echo "lon(deg) lat(deg)" > temp.txt 128 | #sed '1d' sampling_grids.in | awk '{print $2,$1}' >> temp.txt 129 | sed '1d' ${receiverfault} | awk '{print $2,$1}' >> temp.txt 130 | paste temp.txt coulomb.out > temp1.txt 131 | mv temp1.txt ${earthquake_stress%stress*}coulomb.out 132 | rm -rf temp.txt temp1.txt coulomb.out stress.out 133 | esac 134 | rm -rf computeCFS CoulombStressAnalysis OOPCFFmax 135 | if [ "${earthquake_stress%stress*}" != "./CFS_result/" ];then 136 | cp ${earthquake_stress%stress*}coulomb.out ./CFS_result/ 137 | fi 138 | ./draw_CFS.sh $nchoiceOOP $receiverfault 139 | 140 | -------------------------------------------------------------------------------- /preproc/preproc_sampling_profile.m: -------------------------------------------------------------------------------- 1 | function preproc_sampling_profile() 2 | clc;clear;close all; 3 | %-------------------------------------------------------------------------% 4 | path_receiver_fault=input('profile plane with the same format as a single source fault: ','s'); 5 | MM=700; 6 | NN=200; 7 | %MM=400; 8 | %NN=50; 9 | bprofile=1; 10 | k1=0;k2=1; 11 | k3=0;k4=1; 12 | %-------------------------------------------------------------------------% 13 | fp=fopen(path_receiver_fault,'r'); 14 | ss=textscan(fp,'%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f','headerlines',1); 15 | fclose(fp); 16 | lat=ss{:,1}; 17 | lon=ss{:,2}; 18 | depth=ss{:,3}; 19 | length=ss{:,4}; 20 | width=ss{:,5}; 21 | AL1=ss{:,6}; 22 | AL2=ss{:,7}; 23 | AW1=ss{:,8}; 24 | AW2=ss{:,9}; 25 | strike=ss{:,10}; 26 | dip=ss{:,11}; 27 | row=size(lat,1); 28 | unit=1.0e-3; 29 | for i=1:row 30 | sL0=lon(i); 31 | L=length(i); 32 | W=width(i); 33 | strikee=strike(i); 34 | dipp=dip(i); 35 | ksi0=abs(AL1); 36 | eta0=abs(AW1); 37 | z0=-depth(i);%km 38 | sB=lat(i); 39 | sL=lon(i); 40 | [x0,y0]=generalBL2xy(sB,sL,sL0,3,1); 41 | x0=x0*unit;%from meter to kilometer 42 | y0=y0*unit; 43 | % 44 | %-----------------------------------% 45 | if W*sind(dip)>(-z0+abs(AW1)*sind(dip)) 46 | disp('wrong width!the upper edge of the fault plane is above the earth''s surface!'); 47 | W=-z0/sind(dip)+abs(AW1); 48 | end 49 | ksi_range=[k1*L, k2*L]; 50 | eta_range=[k3*W,k4*W]; 51 | %-----------------------------------% 52 | result_fault_corners=[]; 53 | for j=1:6 54 | switch j 55 | case 1 %lower-left corner of fault plane 56 | ksi=0; 57 | eta=0; 58 | n=0; 59 | case 2 %lower-right corner of fault plane 60 | ksi=L; 61 | eta=0; 62 | n=0; 63 | case 3 %upper-right corner of fault plane 64 | ksi=L; 65 | eta=W; 66 | n=0; 67 | case 4 %upper-left corner of fault plane 68 | ksi=0; 69 | eta=W; 70 | n=0; 71 | case 5 %uppler-left corner of the projected plane along the updip direction 72 | ksi=0; 73 | eta=-z0/sind(dip)+abs(AW1); 74 | n=0; 75 | case 6 %uppler-right corner of the projected plane along the updip direction 76 | ksi=L; 77 | eta=-z0/sind(dip)+abs(AW1); 78 | n=0; 79 | end 80 | [x,y,z]=faultplanecoord2localCartesiancoord(strikee,dipp,ksi0,eta0,x0,y0,z0,ksi,eta,n); 81 | x=x/unit;%km to m 82 | y=y/unit; 83 | [Bc,Lc]=generalxy2BL(x,y,sL0,3); 84 | result_fault_corners=[result_fault_corners;Lc Bc z]; 85 | end 86 | figure; 87 | temp=result_fault_corners; 88 | fill3(temp(1:4,1),temp(1:4,2),temp(1:4,3),'r');hold on; 89 | plot3(sL,sB,z0,'go','MarkerSize',5); 90 | %-------------------------------------------------------------------------% 91 | if bprofile==1 92 | %discritizing the fault plane 93 | NT=MM*NN; 94 | LL=linspace(min(ksi_range),max(ksi_range),MM); 95 | WW=linspace(min(eta_range),max(eta_range),NN); 96 | [LL,WW]=meshgrid(LL,WW); 97 | LL=LL(:); 98 | WW=WW(:); 99 | pathout=['../profile/profile_along_fault_plane',num2str(i),'.txt']; 100 | fp=fopen(pathout,'wt'); 101 | fprintf(fp,'%s\n','Fault corners of the fault plane and the projected line on the earth''s surface of the fault plane along updip direction.'); 102 | fprintf(fp,'%s\n','the 1st line: lower left corner; the 2nd line: lower right corner; the 3rd line:upper right corner; the 4th corner: upper left corner'); 103 | fprintf(fp,'%s\n','the 5th line: the starting point of the projected line; the 6th line: the ending point of the projected line.'); 104 | fprintf(fp,'%s\n',' lon(deg) lat(deg) depth(km)'); 105 | for ii=1:6 106 | fprintf(fp,'%13.6f%13.6f%13.6f\n',temp(ii,1),temp(ii,2),temp(ii,3)); 107 | end 108 | fprintf(fp,'%s\n','coordinate on the fault plane:(ksi, W-eta(downdip km))'); 109 | fprintf(fp,'%13.6f%13.6f\n%13.6f%13.6f\n%13.6f%13.6f\n%13.6f%13.6f\n',0,max(eta_range)-0,L,max(eta_range)-0,L,max(eta_range)-W,0,max(eta_range)-W); 110 | fprintf(fp,'%s\n','''Downdip'' means the reference point of the fault plane coordinate system is the upper left corner on the earth''s surface') 111 | fprintf(fp,'range of the sampled plane(note that x axis is along strike direction, y axis is along downdip direction, and the origin is the\n upper left corner of the plane intersected with the earth''s surface):\n'); 112 | fprintf(fp,'along strike: %13.6f%13.6f\n', min(ksi_range),max(ksi_range)); 113 | fprintf(fp,'along downdip: %13.6f%13.6f\n', 0,max(eta_range)-min(eta_range)); 114 | fprintf(fp,'fault box is:\n'); 115 | fprintf(fp,'%13.6f%13.6f\n%13.6f%13.6f\n%13.6f%13.6f\n%13.6f%13.6f\n%13.6f%13.6f\n',0, max(eta_range)-0,L, max(eta_range)-0, L, max(eta_range)-W, ... 116 | 0, max(eta_range)-W,0, max(eta_range)-0); 117 | fprintf(fp,'%s\n%s\n%d\n','The following are the sampling points on the fault plane',' lat(deg) lon(deg) depth(km) ksi(km) W-eta(km)(downdip)',NT); 118 | 119 | for k=1:NT 120 | ksi=LL(k); 121 | eta=WW(k); 122 | n=0; 123 | [x,y,z]=faultplanecoord2localCartesiancoord(strikee,dipp,ksi0,eta0,x0,y0,z0,ksi,eta,n); 124 | x=x/unit;%km to m 125 | y=y/unit; 126 | [Bc,Lc]=generalxy2BL(x,y,sL0,3); 127 | fprintf(fp,'%13.6f%13.6f%13.6f%13.6f%13.6f\n',Bc,Lc,-z,ksi,max(eta_range)-eta); 128 | sprintf('k=%d N=%d done(%4.1f%%)\n',k,NT,k*100/NT) 129 | plot3(Lc,Bc,z,'b.'); 130 | end 131 | fclose(fp); 132 | end 133 | end 134 | return; 135 | %-------------------------------------------------------------------------% 136 | % 137 | pathout='../profile/inputdata/profile_aftershocks.txt'; 138 | aftershocks=importdata(path_aftershocks); 139 | %plot3(aftershocks(:,7),aftershocks(:,8),-aftershocks(:,9),'go'); 140 | % 141 | fp1=fopen(pathout,'wt'); 142 | fprintf(fp1,'%s\n','''Downdip'' means the referecen point of the fault plane coordinate system is the upper left corner.'); 143 | fprintf(fp1,'%s\n','''n(km)'' means the distance to the fault plane positive towards its normal.'); 144 | fprintf(fp1,'%s\n%s\n','The following are the projected points of aftershocks on the fault plane',' lat(deg) lon(deg) depth(km) ksi(km) W-eta(km)(downdip) n(km)'); 145 | row=size(aftershocks,1); 146 | for k=1:row 147 | sL=aftershocks(k,7); 148 | sB=aftershocks(k,8); 149 | z=-aftershocks(k,9); 150 | [x,y]=generalBL2xy(sB,sL,sL0,3,1); 151 | x=x*unit;%note that from meter to kilometer 152 | y=y*unit; 153 | [ksi,eta,n]=localCartesiancoord2faultplanecoord(strikee,dipp,ksi0,eta0,x0,y0,z0,x,y,z); 154 | %fprintf(fp1,'%13.6f%13.6f%13.6f%13.6f%13.6f%23.6f\n',sB,sL,-z,ksi,W-eta,n); 155 | fprintf(fp1,'%13.6f%13.6f%13.6f%13.6f%13.6f%23.6f\n',sB,sL,-z,ksi,max(eta_range)-eta,n); 156 | end 157 | fclose(fp1); 158 | % 159 | 160 | function [x,y,z]=faultplanecoord2localCartesiancoord(strike,dip,ksi0,eta0,x0,y0,z0,ksi,eta,n) 161 | %ksi,eta,n with reference point being the lower left corner of fault plane 162 | theta=deg2rad(strike); 163 | D=deg2rad(dip); 164 | Rtheta=[cos(theta) sin(theta) 0;... %x north, y east, z upward 165 | sin(theta) -cos(theta) 0;... 166 | 0 0 1]; 167 | Rdip=[1 0 0 ;... 168 | 0 cos(D) -sin(D);... 169 | 0 sin(D) cos(D)]; 170 | C=Rtheta*Rdip*[ksi-ksi0;eta-eta0;n]+[x0;y0;z0]; 171 | x=C(1); 172 | y=C(2); 173 | z=C(3); 174 | function [ksi,eta,n]=localCartesiancoord2faultplanecoord(strike,dip,ksi0,eta0,x0,y0,z0,x,y,z) 175 | %ksi,eta,n with reference point being the lower left corner of fault plane 176 | theta=deg2rad(strike); 177 | D=deg2rad(dip); 178 | Rtheta=[cos(theta) sin(theta) 0;... %x north, y east, z upward 179 | sin(theta) -cos(theta) 0;... 180 | 0 0 1]; 181 | Rdip=[1 0 0 ;... 182 | 0 cos(D) -sin(D);... 183 | 0 sin(D) cos(D)]; 184 | A=Rdip'*Rtheta'*[x-x0;y-y0;z-z0]+[ksi0;eta0;0]; 185 | ksi=A(1); 186 | eta=A(2); 187 | n=A(3); 188 | -------------------------------------------------------------------------------- /OOP/scripts/OOPCFFmax.f90: -------------------------------------------------------------------------------- 1 | program OOPCFFmax 2 | !this code is used to compute the optimally oriented failure plane and the Coulomb stress 3 | !on the OOP based on grid search. The error of grid search is 0.36 deg. The grid search, in my opinion, 4 | !is a good approach used to resolve the OOP because other nonlinear methods would just find a local minima 5 | !and it is possible that no right OOP could be determined. I have tested this point using PSO method. 6 | ! 7 | !coded on March 22, 2016 8 | 9 | implicit none 10 | real*8 strike,dip,rake,friction,skempton,CFFvalue,optCFFvalue,optCFFvalue_onfault 11 | real*8 stress(6),earthquake_stress(6),tectonic_stress(6) 12 | real*8 minStrike,maxStrike,minDip,maxDip,minRake,maxRake 13 | real*8 optStrike,optDip,optRake 14 | real*8 optshearstress,optnormalstress 15 | real*8 delta_strike,delta_dip,delta_rake 16 | real*8 tempCFF,tempstrike,tempdip,temprake 17 | integer*4 i,n 18 | integer*8 ii,jj,kk,j,k,m,Nloop 19 | integer*8 Npoints,Mpoints,NN 20 | character*100 inputfile_earthquake_stress,inputfile_tectonic_stress,outputfile,strline 21 | character*100 argstr 22 | integer*4 ntest,bshutdown 23 | !parameter(NN=36) 24 | !------------------------------------------ 25 | ntest=0 26 | if(ntest.eq.1)then 27 | !toda 28 | strike=113.991 29 | dip=34.099 30 | rake=90 31 | !mine 32 | !strike=329.76 33 | !dip=76.59 34 | !rake=90 35 | friction=0.4 36 | skempton=0.0 37 | stress(1)=1. 38 | stress(2)=2. 39 | stress(3)=3. 40 | stress(4)=4. 41 | stress(5)=5. 42 | stress(6)=6. 43 | call CFF_cal(stress,strike,dip,rake,friction,skempton,optshearstress,optnormalstress,CFFvalue) 44 | write(*,*)'CFFvalue=',CFFvalue 45 | return 46 | endif 47 | n=iargc() 48 | if(n.lt.12)then 49 | write(*,*)'the input parameters are too less!' 50 | write(*,*)'Usage: ./OOPCFFmax earthquake_stress tectonic_stress stress.out 0 360 0 90 -180 180 0.4 0 36' 51 | write(*,*)'''earthquake_stress'' is the file of stress tensors imparted by earthquake.it''s data format is as follows:' 52 | write(*,*)'e11 e12 e13 e22 e23 e33' 53 | write(*,*)'1.0e-6 2.0e-6 3.0e-6 4.0e-6 5.0e-6 6.0e-6' 54 | write(*,*)'both the earthquake stress and tectonic stress belong to the coordinate system' 55 | write(*,*)'whose x is northern, y is eastern and z is upward.' 56 | write(*,*)'''tectonic_stress'' is the file of stress tensors of regional stress field. the data format of' 57 | write(*,*)'tectonic stress is the same as that of the earthquake stress.' 58 | write(*,*)'''coulomb.out'' is the output file of optimal CFF and strike, dip and rake angles.' 59 | write(*,*)'0 360 are the range of the strike angles of receiver fault.' 60 | write(*,*)'0 90 are the range of the dip angles of receiver fault.' 61 | write(*,*)'-180 180 are the range of the rake angles of receiver fault.' 62 | write(*,*)'0.4 is the friction coefficient.It''s in the range of [0,1] and commonly it''s 0.4' 63 | write(*,*)'0 is the skempton''s coefficient.It''s in the range of [0,1]' 64 | write(*,*)'36 is the gridded number of strike, dip and rake angles.' 65 | return 66 | endif 67 | do i=1,n 68 | call getarg(i,argstr) 69 | write(*,*)'i=',i,'argstr=',argstr 70 | select case(i) 71 | case (1) 72 | read(argstr,*)inputfile_earthquake_stress 73 | write(*,*)'inputfile_earthquake_stress=',inputfile_earthquake_stress 74 | case (2) 75 | read(argstr,*)inputfile_tectonic_stress 76 | write(*,*)'inputfile_tectonic_stress=',inputfile_tectonic_stress 77 | case (3) 78 | read(argstr,*)outputfile 79 | write(*,*)'outputfile=',outputfile 80 | case (4) 81 | read(argstr,*)minStrike 82 | write(*,*)'minStrike=',minStrike 83 | case (5) 84 | read(argstr,*)maxStrike 85 | write(*,*)'maxStrike=',maxStrike 86 | case (6) 87 | read(argstr,*)minDip 88 | write(*,*)'minDip=',minDip 89 | case (7) 90 | read(argstr,*)maxDip 91 | write(*,*)'maxDip=',maxDip 92 | case (8) 93 | read(argstr,*)minRake 94 | write(*,*)'minDip=',minRake 95 | case (9) 96 | read(argstr,*)maxRake 97 | write(*,*)'maxRake=',maxRake 98 | case (10) 99 | read(argstr,*)friction 100 | write(*,*)'friction=',friction 101 | case (11) 102 | read(argstr,*)skempton 103 | write(*,*)'skempton=',skempton 104 | case (12) 105 | read(argstr,*)NN 106 | write(*,*)'grid N=',NN 107 | case default 108 | write(*,*)'dummy parameter!' 109 | end select 110 | enddo 111 | !-------------------------- 112 | !inputfile_earthquake_stress='stress_e.out' 113 | !inputfile_tectonic_stress='tectonic_stress.in' 114 | !outputfile='stress_test.out' 115 | !minStrike=0. 116 | !maxStrike=180.!bug.March 23,2016 117 | !maxStrike=360.0 118 | !minDip=0. 119 | !maxDip=90. 120 | !minRake=-180. 121 | !maxRake=180. 122 | !friction=0.6 123 | !skempton=0.0 124 | !-------------------------- 125 | ! 126 | delta_strike=(maxStrike-minStrike)/NN 127 | delta_dip=(maxDip-minDip)/NN 128 | delta_rake=(maxRake-minRake)/NN 129 | ! 130 | open(1,file=inputfile_earthquake_stress) 131 | open(2,file=inputfile_tectonic_stress) 132 | open(3,file=outputfile) 133 | write(3,*)' opt_str1 opt_dip1 opt_rake1 shear stress(bar) normal stress(bar) coulomb stress(bar)' 134 | ! 135 | write(*,*)'processing...' 136 | do while(.true.) 137 | ii=ii+1 138 | read(1,*,end=100)(earthquake_stress(jj),jj=1,6) 139 | write(*,*)'earthquake stress' 140 | write(*,*)(earthquake_stress(jj),jj=1,6) 141 | read(2,*)(tectonic_stress(jj),jj=1,6) 142 | write(*,*)'regional tectonic stress' 143 | write(*,*)(tectonic_stress(jj),jj=1,6) 144 | do kk=1,6 145 | stress(kk)=earthquake_stress(kk)+tectonic_stress(kk) 146 | enddo 147 | optCFFvalue=-1.0e+10 148 | !grid search the optimal strike,dip and rake angles of the receiver fault on which the CFF is the maximum. 149 | do j=0,NN !strike 150 | strike=delta_strike*j+minStrike 151 | do k=0,NN !dip 152 | dip=delta_dip*k+minDip 153 | do m=0,NN !rake 154 | rake=delta_rake*m+minRake 155 | call CFF_cal(stress,strike,dip,rake,friction,skempton,optshearstress,optnormalstress,CFFvalue) 156 | if(CFFvalue.gt.optCFFvalue)then 157 | optStrike=strike 158 | optDip=dip 159 | optRake=rake 160 | optCFFvalue=CFFvalue 161 | endif 162 | if(abs(delta_rake).le.1.0d-6)then 163 | exit 164 | endif 165 | enddo !end of rake loop 166 | if(abs(delta_dip).le.1.0d-6)then 167 | exit 168 | endif 169 | enddo !end of dip loop 170 | write(*,1000)strike 171 | 1000 format(1x,'strike=',f8.3,1x,'deg') 172 | enddo 173 | !---------------- 174 | write(*,*)'i=',ii,'optCFFvalue=',optCFFvalue,'optStrike=',optStrike,'optDip=',optDip,'optRake=',optRake 175 | call CFF_cal(earthquake_stress,optStrike,optDip,optRake,friction,skempton,optshearstress,optnormalstress,optCFFvalue_onfault) 176 | write(3,1500)optStrike,optDip,optRake,optshearstress,optnormalstress,optCFFvalue_onfault 177 | 1500 format(1x,3f13.6,3e28.16) 178 | enddo 179 | 100 close(1) 180 | close(2) 181 | close(3) 182 | write(*,*)'it''s done!' 183 | 184 | 185 | end program OOPCFFmax 186 | 187 | 188 | 189 | subroutine CFF_cal(stress,strike,dip,rake,friction,skempton,shear_stress,normal_stress,CFFvalue) 190 | ! 191 | !calculate coulomb stress change by projecting the stress belonging to a coordinate system whose x is northern, 192 | !y is eastern and z is upward onto a predefined fault plane with strike, dip and rake angles. 193 | ! 194 | !coded on 14:16 March 22,2016 195 | ! 196 | 197 | implicit none 198 | real*8 strike,dip,rake,friction,skempton,CFFvalue,stress(6) 199 | real*8 shear_stress,normal_stress 200 | real*8 A,D,L,miu,B,e11,e12,e13,e22,e23,e33 201 | real*8 deg2rad 202 | parameter(deg2rad=0.017453292519943) 203 | A=strike*deg2rad 204 | D=dip*deg2rad 205 | L=rake*deg2rad 206 | miu=friction 207 | skempton=B 208 | e11=stress(1) 209 | e12=stress(2) 210 | e13=stress(3) 211 | e22=stress(4) 212 | e23=stress(5) 213 | e33=stress(6) 214 | ! 215 | shear_stress=sin(L)*(-0.5*sin(A)**2.*sin(2.*D)*e11+0.5*sin(2.*A)*sin(2.*D)*e12+sin(A)*cos(2.*D)*e13-& 216 | 0.5*cos(A)**2.*sin(2.*D)*e22-cos(A)*cos(2.*D)*e23+0.5*sin(2.*D)*e33)+ & 217 | cos(L)*(-0.5*sin(2.*A)*sin(D)*e11+cos(2.*A)*sin(D)*e12+cos(A)*cos(D)*e13+& 218 | 0.5*sin(2.*A)*sin(D)*e22+sin(A)*cos(D)*e23) 219 | normal_stress=sin(A)**2.*sin(D)**2.*e11-sin(2.*A)*sin(D)**2.*e12-sin(A)*sin(2.*D)*e13+& 220 | cos(A)**2.*sin(D)**2.*e22+cos(A)*sin(2.*D)*e23+cos(D)**2.*e33 221 | CFFvalue=shear_stress+miu*(normal_stress-B/3.0*(e11+e22+e33)) 222 | ! 223 | end 224 | 225 | 226 | 227 | -------------------------------------------------------------------------------- /CFSsrc/src/CoulombStressAnalysis.f90: -------------------------------------------------------------------------------- 1 | program CoulombStressAnalysis 2 | !This source code is used to compute the static Coulomb stress change induced by earthquake 3 | !faulting in a half space. The key elements of this source code include: (1) computing stress tensor 4 | !using the Okada's dislocation model (Okada et al., 1992,BSSA); (2) performing tensor transformation to 5 | !transform stress tensor in fault coordinate system into local Cartesian coordinate system and (3) substituting 6 | !the transformed stress tensor into the Coulomb stress model to compute the static Coulomb stress change. 7 | ! 8 | !coded on Sep. 25, 2014, AK 9 | !jjwang@sgg.whu.edu.cn 10 | 11 | ! 12 | implicit none 13 | !displacment 14 | real*8 UX,UY,UZ 15 | !gradient of displacement 16 | real*8 UXX,UYX,UZX,UXY,UYY,UZY,UXZ,UYZ,UZZ 17 | !stran and stress 18 | real*8 strain(6),stress(6),sum_stress(6),stressin(3,3),trans_matrix(3,3),stressout(3,3) 19 | !Lame constants. 20 | real*8 lambda,mu,alpha 21 | !observation point 22 | real*8 x,y,z 23 | !source fault 24 | real*8 depth,ksi0,eta0,length,width,strike,dip,strike_slip,dip_slip,tensile_slip 25 | !receiver fault 26 | real*8 strike_receiver,dip_receiver,rake_receiver,friction,Skempton 27 | ! 28 | real*8, allocatable::xs(:) 29 | real*8, allocatable::ys(:) 30 | real*8, allocatable::xr(:) 31 | real*8, allocatable::yr(:) 32 | ! 33 | integer*4 IRET 34 | integer*8 bjudge,i,j,k 35 | integer*8 naltermode_receiver 36 | !pathname 37 | character*100 slip_model_file,sampling_points_file,stress_file,coulomb_file,commonpath,strline 38 | !number of source faults and number of sampling points 39 | integer*8 Nfaults,Nsamplings 40 | !source fault and samping points 41 | real*8, allocatable::faults(:,:) 42 | real*8, allocatable::samplingpoints(:,:) 43 | !real*8 faults(100,10),samplingpoints(500,8) 44 | !central meridian of Gaussian plane 45 | real*8 meridian 46 | ! 47 | real*8 deltax,deltay 48 | ! 49 | !coulomb stress 50 | real*8 shear_stress,normal_stress,coulomb_stress 51 | ! 52 | real*8 temp 53 | ! 54 | ! 55 | real*8, external::deg2rad 56 | ! 57 | real*8 AL1,AL2,AW1,AW2 58 | ! 59 | character*100 arg 60 | 61 | !------------------------------------------ 62 | lambda=3.3e+5 !bars 63 | mu=3.3e+5 !bars 64 | alpha=(lambda+mu)/(lambda+2*mu) 65 | !---------------------------------------- 66 | print *,'----read source fault model----' 67 | slip_model_file='slipmodel.in' 68 | !read(*,'(a)')slip_model_file 69 | !write(*,*)slip_model_file 70 | print*,'source fault model file: ',slip_model_file 71 | open(unit=10,file=slip_model_file) 72 | read(10,*)Nfaults 73 | write(*,1000)Nfaults 74 | 1000 format(1x,"Nfaults=",i4) 75 | allocate(faults(Nfaults,14)) 76 | allocate(xs(Nfaults)) 77 | allocate(ys(Nfaults)) 78 | print *,'the source faults are as follows:' 79 | !print *,' lat.(deg) lon.(deg) depth(km) length(km) width(km) AL1(km) AL2(km) AW1(km) AW2(km) strike(deg) dip(deg) s1(m) s2(m) s3(m)' 80 | !temp=0; 81 | do i=1,Nfaults 82 | read(10,*)(faults(i,j),j=1,14) 83 | write(*,1001)(faults(i,j),j=1,14) 84 | 1001 format(14f10.3) 85 | ! temp=temp+faults(i,2) 86 | enddo 87 | close(10) 88 | print *, '----read sampling points(receiver faults)----' 89 | sampling_points_file='samplingpoints.in' 90 | print*,'sampping points file: ',sampling_points_file 91 | !read(*,'(a)')sampling_points_file 92 | !write(*,*)sampling_points_file 93 | open(11,file=sampling_points_file) 94 | read(11,*)Nsamplings 95 | write(*,1002)Nsamplings 96 | 1002 format(1x,"Nsamplings=",i4) 97 | allocate(samplingpoints(Nsamplings,8)) 98 | allocate(xr(Nsamplings)) 99 | allocate(yr(Nsamplings)) 100 | print *,'the sampling points are as follows:' 101 | print *,'lat.(deg) lon.(deg) depth(km) strike(deg) dip(deg) rake(deg) friction Skempton' 102 | temp=0.0 103 | call getarg(1,arg) 104 | read(arg,*)naltermode_receiver 105 | write(*,*)naltermode_receiver 106 | do i=1,Nsamplings 107 | if (naltermode_receiver.ne.1)then 108 | read(11,*)(samplingpoints(i,j),j=1,3) 109 | write(*,1003)(samplingpoints(i,j),j=1,3)!lat., lon, depth 110 | else 111 | read(11,*)(samplingpoints(i,j),j=1,8) !lat., lon., depth, strike, dip, rake, friction, Skempton 112 | write(*,1003)(samplingpoints(i,j),j=1,8) 113 | endif 114 | 1003 format(3f10.3) 115 | temp=temp+samplingpoints(i,2) 116 | enddo 117 | close(11) 118 | ! 119 | print *,'----Gauss projection of reference points of source faults and sampling points----' 120 | !meridian=temp/(Nfaults+Nsamplings) 121 | meridian=temp/Nsamplings 122 | ! 123 | call getarg(7,arg) 124 | read(arg,*)meridian 125 | ! 126 | write(*,1004)meridian 127 | 1004 format(1x,"The central meridian of Gauss projection is:",f8.3) 128 | print *, '----Gauss projection of reference points of source faults----' 129 | print *,' lat.(deg) lon.(deg) xs(m) ys(m)' 130 | !xs is the northern component of gaussian coordinate 131 | !ys is the sourthern component of gaussian coordinate 132 | do i=1,Nfaults 133 | call generalBL2xy(faults(i,1),faults(i,2),meridian,3,1,xs(i),ys(i)) 134 | write(*,1005)faults(i,1),faults(i,2),xs(i),ys(i) 135 | 1005 format(1x,2f13.6,2e16.6) 136 | enddo 137 | print *, '----Gauss projection of sampling points----' 138 | print *,' lat.(deg) lon.(deg) xr(m) yr(m)' 139 | do i=1,Nsamplings 140 | call generalBL2xy(samplingpoints(i,1),samplingpoints(i,2),meridian,3,1,xr(i),yr(i)) 141 | write(*,1006)samplingpoints(i,1),samplingpoints(i,2),xr(i),yr(i) 142 | 1006 format(1x,2f13.6,2e16.6) 143 | enddo 144 | ! 145 | print *,'----computing stress tensor at each sampling point----' 146 | !read(*,'(a)')stress_file 147 | !write(*,*)stress_file 148 | !read(*,'(a)')coulomb_file 149 | !write(*,*)coulomb_file 150 | stress_file='stress.out' 151 | coulomb_file='coulomb.out' 152 | open(unit=12,file=stress_file) 153 | open(unit=13,file=coulomb_file) 154 | write(12,*)' e11 e12 e13 e22 e23 e33' 155 | write(13,*)' lon. lat. shear_stress(bar) normal_stress(bar) coulomb_stress(bar)' 156 | call getarg(2,arg) 157 | read(arg,*)strike_receiver 158 | write(*,*)strike_receiver 159 | ! 160 | call getarg(3,arg) 161 | read(arg,*)dip_receiver 162 | write(*,*)dip_receiver 163 | ! 164 | call getarg(4,arg) 165 | read(arg,*)rake_receiver 166 | write(*,*)rake_receiver 167 | ! 168 | call getarg(5,arg) 169 | read(arg,*)friction 170 | write(*,*)friction 171 | call getarg(6,arg) 172 | read(arg,*)Skempton 173 | write(*,*)Skempton 174 | ! 175 | print *,'processing...' 176 | do i=1,Nsamplings 177 | call InitializeStress(sum_stress) 178 | do j=1,Nfaults 179 | deltax=( xr(i)-xs(j) )*1.0d-3 !deltax=x-x0. (x,y) is the coordinate of each sampling point in a Guassian plane 180 | deltay=( yr(i)-ys(j) )*1.0d-3 !deltay=y-y0. (x0,y0) is the coordinate of reference point of each source fault 181 | ! in the same Guassian plane. 182 | !------------------- 183 | !transform coordinate of each sampling point into fault system corresponding to each source fault 184 | !whose x is along strike, y is perpendicular to x, z is upward and x-y-z are right-hand coordinate system; 185 | !its origin is (x0,y0) in a Guassian plane and the distance between this origin and its projection on the fault plane of the source fault 186 | !is the depth of the reference point of the source fault. 187 | strike=deg2rad(faults(j,10)) 188 | x=cos(strike)*deltax+sin(strike)*deltay 189 | y=sin(strike)*deltax-cos(strike)*deltay 190 | z=-samplingpoints(i,3) 191 | depth=faults(j,3) 192 | dip=faults(j,11) 193 | length=faults(j,4) 194 | width=faults(j,5) 195 | !(ksi0,eta0) is the coordinate of the referecne point on the source fault plane in the fault plane coordiante 196 | !system whose x is along strike, y is along updip and z is the normal of the fault plane 197 | !note that if the reference point of each source fault is not the lower left corner of the rectangular fault plane, 198 | !then ks0 and eta0 should be changed. For instance, if the reference point is the centroid of the rectangluar fault plane 199 | !then ks0=length/2,eta0=width/2; if the upper left corner of the rectangluar fault plane, then ks0=0,eta0=width. 200 | !more details on this can be found on the site:http://www.bosai.go.jp/study/application/dc3d/DC3Dhtml_E.html. The subroutine 201 | !DC3D.f is downloaded from this site. 202 | ! 203 | AL1=faults(j,6) 204 | AL2=faults(j,7) 205 | AW1=faults(j,8) 206 | AW2=faults(j,9) 207 | ! 208 | strike_slip=faults(j,12) 209 | dip_slip=faults(j,13) 210 | tensile_slip=faults(j,14) 211 | call DC3D(alpha,x,y,z,depth,dip, & 212 | AL1,AL2,AW1,AW2,& 213 | strike_slip,dip_slip,tensile_slip,& 214 | UX,UY,UZ,UXX,UYX,UZX,UXY,UYY,UZY,UXZ,UYZ,UZZ,IRET) 215 | call GradientDisp2Strain(UXX,UYX,UZX,UXY,UYY,UZY,UXZ,UYZ,UZZ,strain) 216 | call Strain2Stress(strain,lambda,mu,stress) 217 | call StressArray2StressTensor(stress,stressin) 218 | call Rphi(faults(j,10),trans_matrix) !because new format of inpdat data is used. here faults(j,10) instead of faults(j,6) is strike angle.10:00 Nov.14,2014 219 | call TensorTrans(stressin,trans_matrix,stressout) 220 | call StressTensor2StressArray(stressout,stress) 221 | do k=1,6 222 | sum_stress(k)=sum_stress(k)+stress(k) 223 | enddo 224 | enddo !end of loop for source faults j 225 | write(12,1007)(sum_stress(k)*1.0d-3,k=1,6) !note that as the unit of slip is meter and the unit of length is kilometer, the unit of strain should be 1.0e-3. 226 | !1007 format(6e18.6) !so stress should be multiplied by a factor of 1.0e-3. 227 | 1007 format(6e28.16) 228 | if (naltermode_receiver==1)then 229 | strike_receiver=samplingpoints(i,4) 230 | dip_receiver=samplingpoints(i,5) 231 | rake_receiver=samplingpoints(i,6) 232 | friction=samplingpoints(i,7) 233 | Skempton=samplingpoints(i,8) 234 | write(*,1009)strike_receiver,dip_receiver,rake_receiver,friction,Skempton 235 | 1009 format(1x,'receiver strike=',f9.3,2x,'receiver dip=',f9.3,2x,'receiver rake=',f9.3,2x,'friction=',f7.2,2x,'Skempton=',f7.2) 236 | endif 237 | do k=1,6 238 | stress(k)=sum_stress(k)*1.0d-3 239 | enddo 240 | call CFF(stress,strike_receiver,dip_receiver,rake_receiver,friction,Skempton,shear_stress,normal_stress,coulomb_stress) 241 | write(13,1008)samplingpoints(i,2),samplingpoints(i,1),shear_stress,normal_stress,coulomb_stress 242 | !1008 format(2f13.6,3e18.6) 243 | 1008 format(2f13.6,3e26.15) 244 | enddo !end of loop for sampling points i 245 | 246 | !close outputfile 247 | close(12) 248 | close(13) 249 | !free memory 250 | deallocate(faults) 251 | deallocate(samplingpoints) 252 | deallocate(xs) 253 | deallocate(ys) 254 | deallocate(xr) 255 | deallocate(yr) 256 | print *, '----it''s done!----' 257 | ! 258 | end program CoulombStressAnalysis 259 | -------------------------------------------------------------------------------- /CFSsrc/src/DC3D.f: -------------------------------------------------------------------------------- 1 | SUBROUTINE DC3D(ALPHA,X,Y,Z,DEPTH,DIP, 2 | * AL1,AL2,AW1,AW2,DISL1,DISL2,DISL3, 3 | * UX,UY,UZ,UXX,UYX,UZX,UXY,UYY,UZY,UXZ,UYZ,UZZ,IRET) 4 | IMPLICIT REAL*8 (A-H,O-Z) 5 | REAL*8 ALPHA,X,Y,Z,DEPTH,DIP,AL1,AL2,AW1,AW2,DISL1,DISL2,DISL3, 6 | * UX,UY,UZ,UXX,UYX,UZX,UXY,UYY,UZY,UXZ,UYZ,UZZ 7 | C 8 | C******************************************************************** 9 | C***** ***** 10 | C***** DISPLACEMENT AND STRAIN AT DEPTH ***** 11 | C***** DUE TO BURIED FINITE FAULT IN A SEMIINFINITE MEDIUM ***** 12 | C***** CODED BY Y.OKADA ... SEP.1991 ***** 13 | C***** REVISED ... NOV.1991, APR.1992, MAY.1993, ***** 14 | C***** JUL.1993, MAY.2002 ***** 15 | C******************************************************************** 16 | C 17 | C***** INPUT 18 | C***** ALPHA : MEDIUM CONSTANT (LAMBDA+MYU)/(LAMBDA+2*MYU) 19 | C***** X,Y,Z : COORDINATE OF OBSERVING POINT 20 | C***** DEPTH : DEPTH OF REFERENCE POINT 21 | C***** DIP : DIP-ANGLE (DEGREE) 22 | C***** AL1,AL2 : FAULT LENGTH RANGE 23 | C***** AW1,AW2 : FAULT WIDTH RANGE 24 | C***** DISL1-DISL3 : STRIKE-, DIP-, TENSILE-DISLOCATIONS 25 | C 26 | C***** OUTPUT 27 | C***** UX, UY, UZ : DISPLACEMENT ( UNIT=(UNIT OF DISL) 28 | C***** UXX,UYX,UZX : X-DERIVATIVE ( UNIT=(UNIT OF DISL) / 29 | C***** UXY,UYY,UZY : Y-DERIVATIVE (UNIT OF X,Y,Z,DEPTH,AL,AW) ) 30 | C***** UXZ,UYZ,UZZ : Z-DERIVATIVE 31 | C***** IRET : RETURN CODE 32 | C***** : =0....NORMAL 33 | C***** : =1....SINGULAR 34 | C***** : =2....POSITIVE Z WAS GIVEN 35 | C 36 | COMMON /C0/DUMMY(5),SD,CD 37 | DIMENSION XI(2),ET(2),KXI(2),KET(2) 38 | DIMENSION U(12),DU(12),DUA(12),DUB(12),DUC(12) 39 | DATA F0,EPS/ 0.D0, 1.D-6 / 40 | C----- 41 | IRET=0 42 | IF(Z.GT.0.) THEN 43 | IRET=2 44 | GO TO 99 45 | ENDIF 46 | C----- 47 | DO 111 I=1,12 48 | U (I)=F0 49 | DUA(I)=F0 50 | DUB(I)=F0 51 | DUC(I)=F0 52 | 111 CONTINUE 53 | AALPHA=ALPHA 54 | DDIP=DIP 55 | CALL DCCON0(AALPHA,DDIP) 56 | C----- 57 | ZZ=Z 58 | DD1=DISL1 59 | DD2=DISL2 60 | DD3=DISL3 61 | XI(1)=X-AL1 62 | XI(2)=X-AL2 63 | IF(DABS(XI(1)).LT.EPS) XI(1)=F0 64 | IF(DABS(XI(2)).LT.EPS) XI(2)=F0 65 | C====================================== 66 | C===== REAL-SOURCE CONTRIBUTION ===== 67 | C====================================== 68 | D=DEPTH+Z 69 | P=Y*CD+D*SD 70 | Q=Y*SD-D*CD 71 | ET(1)=P-AW1 72 | ET(2)=P-AW2 73 | IF(DABS(Q).LT.EPS) Q=F0 74 | IF(DABS(ET(1)).LT.EPS) ET(1)=F0 75 | IF(DABS(ET(2)).LT.EPS) ET(2)=F0 76 | C-------------------------------- 77 | C----- REJECT SINGULAR CASE ----- 78 | C-------------------------------- 79 | C----- ON FAULT EDGE 80 | IF(Q.EQ.F0 .AND. 81 | * ( (XI(1)*XI(2).LE.F0 .AND. ET(1)*ET(2).EQ.F0) 82 | * .OR.(ET(1)*ET(2).LE.F0 .AND. XI(1)*XI(2).EQ.F0) )) THEN 83 | IRET=1 84 | GO TO 99 85 | ENDIF 86 | C----- ON NEGATIVE EXTENSION OF FAULT EDGE 87 | KXI(1)=0 88 | KXI(2)=0 89 | KET(1)=0 90 | KET(2)=0 91 | R12=DSQRT(XI(1)*XI(1)+ET(2)*ET(2)+Q*Q) 92 | R21=DSQRT(XI(2)*XI(2)+ET(1)*ET(1)+Q*Q) 93 | R22=DSQRT(XI(2)*XI(2)+ET(2)*ET(2)+Q*Q) 94 | IF(XI(1).LT.F0 .AND. R21+XI(2).LT.EPS) KXI(1)=1 95 | IF(XI(1).LT.F0 .AND. R22+XI(2).LT.EPS) KXI(2)=1 96 | IF(ET(1).LT.F0 .AND. R12+ET(2).LT.EPS) KET(1)=1 97 | IF(ET(1).LT.F0 .AND. R22+ET(2).LT.EPS) KET(2)=1 98 | C===== 99 | DO 223 K=1,2 100 | DO 222 J=1,2 101 | CALL DCCON2(XI(J),ET(K),Q,SD,CD,KXI(K),KET(J)) 102 | CALL UA(XI(J),ET(K),Q,DD1,DD2,DD3,DUA) 103 | C----- 104 | DO 220 I=1,10,3 105 | DU(I) =-DUA(I) 106 | DU(I+1)=-DUA(I+1)*CD+DUA(I+2)*SD 107 | DU(I+2)=-DUA(I+1)*SD-DUA(I+2)*CD 108 | IF(I.LT.10) GO TO 220 109 | DU(I) =-DU(I) 110 | DU(I+1)=-DU(I+1) 111 | DU(I+2)=-DU(I+2) 112 | 220 CONTINUE 113 | DO 221 I=1,12 114 | IF(J+K.NE.3) U(I)=U(I)+DU(I) 115 | IF(J+K.EQ.3) U(I)=U(I)-DU(I) 116 | 221 CONTINUE 117 | C----- 118 | 222 CONTINUE 119 | 223 CONTINUE 120 | C======================================= 121 | C===== IMAGE-SOURCE CONTRIBUTION ===== 122 | C======================================= 123 | D=DEPTH-Z 124 | P=Y*CD+D*SD 125 | Q=Y*SD-D*CD 126 | ET(1)=P-AW1 127 | ET(2)=P-AW2 128 | IF(DABS(Q).LT.EPS) Q=F0 129 | IF(DABS(ET(1)).LT.EPS) ET(1)=F0 130 | IF(DABS(ET(2)).LT.EPS) ET(2)=F0 131 | C-------------------------------- 132 | C----- REJECT SINGULAR CASE ----- 133 | C-------------------------------- 134 | C----- ON FAULT EDGE 135 | IF(Q.EQ.F0 .AND. 136 | * ( (XI(1)*XI(2).LE.F0 .AND. ET(1)*ET(2).EQ.F0) 137 | * .OR.(ET(1)*ET(2).LE.F0 .AND. XI(1)*XI(2).EQ.F0) )) THEN 138 | IRET=1 139 | GO TO 99 140 | ENDIF 141 | C----- ON NEGATIVE EXTENSION OF FAULT EDGE 142 | KXI(1)=0 143 | KXI(2)=0 144 | KET(1)=0 145 | KET(2)=0 146 | R12=DSQRT(XI(1)*XI(1)+ET(2)*ET(2)+Q*Q) 147 | R21=DSQRT(XI(2)*XI(2)+ET(1)*ET(1)+Q*Q) 148 | R22=DSQRT(XI(2)*XI(2)+ET(2)*ET(2)+Q*Q) 149 | IF(XI(1).LT.F0 .AND. R21+XI(2).LT.EPS) KXI(1)=1 150 | IF(XI(1).LT.F0 .AND. R22+XI(2).LT.EPS) KXI(2)=1 151 | IF(ET(1).LT.F0 .AND. R12+ET(2).LT.EPS) KET(1)=1 152 | IF(ET(1).LT.F0 .AND. R22+ET(2).LT.EPS) KET(2)=1 153 | C===== 154 | DO 334 K=1,2 155 | DO 333 J=1,2 156 | CALL DCCON2(XI(J),ET(K),Q,SD,CD,KXI(K),KET(J)) 157 | CALL UA(XI(J),ET(K),Q,DD1,DD2,DD3,DUA) 158 | CALL UB(XI(J),ET(K),Q,DD1,DD2,DD3,DUB) 159 | CALL UC(XI(J),ET(K),Q,ZZ,DD1,DD2,DD3,DUC) 160 | C----- 161 | DO 330 I=1,10,3 162 | DU(I)=DUA(I)+DUB(I)+Z*DUC(I) 163 | DU(I+1)=(DUA(I+1)+DUB(I+1)+Z*DUC(I+1))*CD 164 | * -(DUA(I+2)+DUB(I+2)+Z*DUC(I+2))*SD 165 | DU(I+2)=(DUA(I+1)+DUB(I+1)-Z*DUC(I+1))*SD 166 | * +(DUA(I+2)+DUB(I+2)-Z*DUC(I+2))*CD 167 | IF(I.LT.10) GO TO 330 168 | DU(10)=DU(10)+DUC(1) 169 | DU(11)=DU(11)+DUC(2)*CD-DUC(3)*SD 170 | DU(12)=DU(12)-DUC(2)*SD-DUC(3)*CD 171 | 330 CONTINUE 172 | DO 331 I=1,12 173 | IF(J+K.NE.3) U(I)=U(I)+DU(I) 174 | IF(J+K.EQ.3) U(I)=U(I)-DU(I) 175 | 331 CONTINUE 176 | C----- 177 | 333 CONTINUE 178 | 334 CONTINUE 179 | C===== 180 | UX=U(1) 181 | UY=U(2) 182 | UZ=U(3) 183 | UXX=U(4) 184 | UYX=U(5) 185 | UZX=U(6) 186 | UXY=U(7) 187 | UYY=U(8) 188 | UZY=U(9) 189 | UXZ=U(10) 190 | UYZ=U(11) 191 | UZZ=U(12) 192 | RETURN 193 | C=========================================== 194 | C===== IN CASE OF SINGULAR (ON EDGE) ===== 195 | C=========================================== 196 | 99 UX=F0 197 | UY=F0 198 | UZ=F0 199 | UXX=F0 200 | UYX=F0 201 | UZX=F0 202 | UXY=F0 203 | UYY=F0 204 | UZY=F0 205 | UXZ=F0 206 | UYZ=F0 207 | UZZ=F0 208 | RETURN 209 | END 210 | SUBROUTINE UA(XI,ET,Q,DISL1,DISL2,DISL3,U) 211 | IMPLICIT REAL*8 (A-H,O-Z) 212 | DIMENSION U(12),DU(12) 213 | C 214 | C******************************************************************** 215 | C***** DISPLACEMENT AND STRAIN AT DEPTH (PART-A) ***** 216 | C***** DUE TO BURIED FINITE FAULT IN A SEMIINFINITE MEDIUM ***** 217 | C******************************************************************** 218 | C 219 | C***** INPUT 220 | C***** XI,ET,Q : STATION COORDINATES IN FAULT SYSTEM 221 | C***** DISL1-DISL3 : STRIKE-, DIP-, TENSILE-DISLOCATIONS 222 | C***** OUTPUT 223 | C***** U(12) : DISPLACEMENT AND THEIR DERIVATIVES 224 | C 225 | COMMON /C0/ALP1,ALP2,ALP3,ALP4,ALP5,SD,CD,SDSD,CDCD,SDCD,S2D,C2D 226 | COMMON /C2/XI2,ET2,Q2,R,R2,R3,R5,Y,D,TT,ALX,ALE,X11,Y11,X32,Y32, 227 | * EY,EZ,FY,FZ,GY,GZ,HY,HZ 228 | DATA F0,F2,PI2/0.D0,2.D0,6.283185307179586D0/ 229 | C----- 230 | DO 111 I=1,12 231 | 111 U(I)=F0 232 | XY=XI*Y11 233 | QX=Q *X11 234 | QY=Q *Y11 235 | C====================================== 236 | C===== STRIKE-SLIP CONTRIBUTION ===== 237 | C====================================== 238 | IF(DISL1.NE.F0) THEN 239 | DU( 1)= TT/F2 +ALP2*XI*QY 240 | DU( 2)= ALP2*Q/R 241 | DU( 3)= ALP1*ALE -ALP2*Q*QY 242 | DU( 4)=-ALP1*QY -ALP2*XI2*Q*Y32 243 | DU( 5)= -ALP2*XI*Q/R3 244 | DU( 6)= ALP1*XY +ALP2*XI*Q2*Y32 245 | DU( 7)= ALP1*XY*SD +ALP2*XI*FY+D/F2*X11 246 | DU( 8)= ALP2*EY 247 | DU( 9)= ALP1*(CD/R+QY*SD) -ALP2*Q*FY 248 | DU(10)= ALP1*XY*CD +ALP2*XI*FZ+Y/F2*X11 249 | DU(11)= ALP2*EZ 250 | DU(12)=-ALP1*(SD/R-QY*CD) -ALP2*Q*FZ 251 | DO 222 I=1,12 252 | 222 U(I)=U(I)+DISL1/PI2*DU(I) 253 | ENDIF 254 | C====================================== 255 | C===== DIP-SLIP CONTRIBUTION ===== 256 | C====================================== 257 | IF(DISL2.NE.F0) THEN 258 | DU( 1)= ALP2*Q/R 259 | DU( 2)= TT/F2 +ALP2*ET*QX 260 | DU( 3)= ALP1*ALX -ALP2*Q*QX 261 | DU( 4)= -ALP2*XI*Q/R3 262 | DU( 5)= -QY/F2 -ALP2*ET*Q/R3 263 | DU( 6)= ALP1/R +ALP2*Q2/R3 264 | DU( 7)= ALP2*EY 265 | DU( 8)= ALP1*D*X11+XY/F2*SD +ALP2*ET*GY 266 | DU( 9)= ALP1*Y*X11 -ALP2*Q*GY 267 | DU(10)= ALP2*EZ 268 | DU(11)= ALP1*Y*X11+XY/F2*CD +ALP2*ET*GZ 269 | DU(12)=-ALP1*D*X11 -ALP2*Q*GZ 270 | DO 333 I=1,12 271 | 333 U(I)=U(I)+DISL2/PI2*DU(I) 272 | ENDIF 273 | C======================================== 274 | C===== TENSILE-FAULT CONTRIBUTION ===== 275 | C======================================== 276 | IF(DISL3.NE.F0) THEN 277 | DU( 1)=-ALP1*ALE -ALP2*Q*QY 278 | DU( 2)=-ALP1*ALX -ALP2*Q*QX 279 | DU( 3)= TT/F2 -ALP2*(ET*QX+XI*QY) 280 | DU( 4)=-ALP1*XY +ALP2*XI*Q2*Y32 281 | DU( 5)=-ALP1/R +ALP2*Q2/R3 282 | DU( 6)=-ALP1*QY -ALP2*Q*Q2*Y32 283 | DU( 7)=-ALP1*(CD/R+QY*SD) -ALP2*Q*FY 284 | DU( 8)=-ALP1*Y*X11 -ALP2*Q*GY 285 | DU( 9)= ALP1*(D*X11+XY*SD) +ALP2*Q*HY 286 | DU(10)= ALP1*(SD/R-QY*CD) -ALP2*Q*FZ 287 | DU(11)= ALP1*D*X11 -ALP2*Q*GZ 288 | DU(12)= ALP1*(Y*X11+XY*CD) +ALP2*Q*HZ 289 | DO 444 I=1,12 290 | 444 U(I)=U(I)+DISL3/PI2*DU(I) 291 | ENDIF 292 | RETURN 293 | END 294 | SUBROUTINE UB(XI,ET,Q,DISL1,DISL2,DISL3,U) 295 | IMPLICIT REAL*8 (A-H,O-Z) 296 | DIMENSION U(12),DU(12) 297 | C 298 | C******************************************************************** 299 | C***** DISPLACEMENT AND STRAIN AT DEPTH (PART-B) ***** 300 | C***** DUE TO BURIED FINITE FAULT IN A SEMIINFINITE MEDIUM ***** 301 | C******************************************************************** 302 | C 303 | C***** INPUT 304 | C***** XI,ET,Q : STATION COORDINATES IN FAULT SYSTEM 305 | C***** DISL1-DISL3 : STRIKE-, DIP-, TENSILE-DISLOCATIONS 306 | C***** OUTPUT 307 | C***** U(12) : DISPLACEMENT AND THEIR DERIVATIVES 308 | C 309 | COMMON /C0/ALP1,ALP2,ALP3,ALP4,ALP5,SD,CD,SDSD,CDCD,SDCD,S2D,C2D 310 | COMMON /C2/XI2,ET2,Q2,R,R2,R3,R5,Y,D,TT,ALX,ALE,X11,Y11,X32,Y32, 311 | * EY,EZ,FY,FZ,GY,GZ,HY,HZ 312 | DATA F0,F1,F2,PI2/0.D0,1.D0,2.D0,6.283185307179586D0/ 313 | C----- 314 | RD=R+D 315 | D11=F1/(R*RD) 316 | AJ2=XI*Y/RD*D11 317 | AJ5=-(D+Y*Y/RD)*D11 318 | IF(CD.NE.F0) THEN 319 | IF(XI.EQ.F0) THEN 320 | AI4=F0 321 | ELSE 322 | X=DSQRT(XI2+Q2) 323 | AI4=F1/CDCD*( XI/RD*SDCD 324 | * +F2*DATAN((ET*(X+Q*CD)+X*(R+X)*SD)/(XI*(R+X)*CD)) ) 325 | ENDIF 326 | AI3=(Y*CD/RD-ALE+SD*DLOG(RD))/CDCD 327 | AK1=XI*(D11-Y11*SD)/CD 328 | AK3=(Q*Y11-Y*D11)/CD 329 | AJ3=(AK1-AJ2*SD)/CD 330 | AJ6=(AK3-AJ5*SD)/CD 331 | ELSE 332 | RD2=RD*RD 333 | AI3=(ET/RD+Y*Q/RD2-ALE)/F2 334 | AI4=XI*Y/RD2/F2 335 | AK1=XI*Q/RD*D11 336 | AK3=SD/RD*(XI2*D11-F1) 337 | AJ3=-XI/RD2*(Q2*D11-F1/F2) 338 | AJ6=-Y/RD2*(XI2*D11-F1/F2) 339 | ENDIF 340 | C----- 341 | XY=XI*Y11 342 | AI1=-XI/RD*CD-AI4*SD 343 | AI2= DLOG(RD)+AI3*SD 344 | AK2= F1/R+AK3*SD 345 | AK4= XY*CD-AK1*SD 346 | AJ1= AJ5*CD-AJ6*SD 347 | AJ4=-XY-AJ2*CD+AJ3*SD 348 | C===== 349 | DO 111 I=1,12 350 | 111 U(I)=F0 351 | QX=Q*X11 352 | QY=Q*Y11 353 | C====================================== 354 | C===== STRIKE-SLIP CONTRIBUTION ===== 355 | C====================================== 356 | IF(DISL1.NE.F0) THEN 357 | DU( 1)=-XI*QY-TT -ALP3*AI1*SD 358 | DU( 2)=-Q/R +ALP3*Y/RD*SD 359 | DU( 3)= Q*QY -ALP3*AI2*SD 360 | DU( 4)= XI2*Q*Y32 -ALP3*AJ1*SD 361 | DU( 5)= XI*Q/R3 -ALP3*AJ2*SD 362 | DU( 6)=-XI*Q2*Y32 -ALP3*AJ3*SD 363 | DU( 7)=-XI*FY-D*X11 +ALP3*(XY+AJ4)*SD 364 | DU( 8)=-EY +ALP3*(F1/R+AJ5)*SD 365 | DU( 9)= Q*FY -ALP3*(QY-AJ6)*SD 366 | DU(10)=-XI*FZ-Y*X11 +ALP3*AK1*SD 367 | DU(11)=-EZ +ALP3*Y*D11*SD 368 | DU(12)= Q*FZ +ALP3*AK2*SD 369 | DO 222 I=1,12 370 | 222 U(I)=U(I)+DISL1/PI2*DU(I) 371 | ENDIF 372 | C====================================== 373 | C===== DIP-SLIP CONTRIBUTION ===== 374 | C====================================== 375 | IF(DISL2.NE.F0) THEN 376 | DU( 1)=-Q/R +ALP3*AI3*SDCD 377 | DU( 2)=-ET*QX-TT -ALP3*XI/RD*SDCD 378 | DU( 3)= Q*QX +ALP3*AI4*SDCD 379 | DU( 4)= XI*Q/R3 +ALP3*AJ4*SDCD 380 | DU( 5)= ET*Q/R3+QY +ALP3*AJ5*SDCD 381 | DU( 6)=-Q2/R3 +ALP3*AJ6*SDCD 382 | DU( 7)=-EY +ALP3*AJ1*SDCD 383 | DU( 8)=-ET*GY-XY*SD +ALP3*AJ2*SDCD 384 | DU( 9)= Q*GY +ALP3*AJ3*SDCD 385 | DU(10)=-EZ -ALP3*AK3*SDCD 386 | DU(11)=-ET*GZ-XY*CD -ALP3*XI*D11*SDCD 387 | DU(12)= Q*GZ -ALP3*AK4*SDCD 388 | DO 333 I=1,12 389 | 333 U(I)=U(I)+DISL2/PI2*DU(I) 390 | ENDIF 391 | C======================================== 392 | C===== TENSILE-FAULT CONTRIBUTION ===== 393 | C======================================== 394 | IF(DISL3.NE.F0) THEN 395 | DU( 1)= Q*QY -ALP3*AI3*SDSD 396 | DU( 2)= Q*QX +ALP3*XI/RD*SDSD 397 | DU( 3)= ET*QX+XI*QY-TT -ALP3*AI4*SDSD 398 | DU( 4)=-XI*Q2*Y32 -ALP3*AJ4*SDSD 399 | DU( 5)=-Q2/R3 -ALP3*AJ5*SDSD 400 | DU( 6)= Q*Q2*Y32 -ALP3*AJ6*SDSD 401 | DU( 7)= Q*FY -ALP3*AJ1*SDSD 402 | DU( 8)= Q*GY -ALP3*AJ2*SDSD 403 | DU( 9)=-Q*HY -ALP3*AJ3*SDSD 404 | DU(10)= Q*FZ +ALP3*AK3*SDSD 405 | DU(11)= Q*GZ +ALP3*XI*D11*SDSD 406 | DU(12)=-Q*HZ +ALP3*AK4*SDSD 407 | DO 444 I=1,12 408 | 444 U(I)=U(I)+DISL3/PI2*DU(I) 409 | ENDIF 410 | RETURN 411 | END 412 | SUBROUTINE UC(XI,ET,Q,Z,DISL1,DISL2,DISL3,U) 413 | IMPLICIT REAL*8 (A-H,O-Z) 414 | DIMENSION U(12),DU(12) 415 | C 416 | C******************************************************************** 417 | C***** DISPLACEMENT AND STRAIN AT DEPTH (PART-C) ***** 418 | C***** DUE TO BURIED FINITE FAULT IN A SEMIINFINITE MEDIUM ***** 419 | C******************************************************************** 420 | C 421 | C***** INPUT 422 | C***** XI,ET,Q,Z : STATION COORDINATES IN FAULT SYSTEM 423 | C***** DISL1-DISL3 : STRIKE-, DIP-, TENSILE-DISLOCATIONS 424 | C***** OUTPUT 425 | C***** U(12) : DISPLACEMENT AND THEIR DERIVATIVES 426 | C 427 | COMMON /C0/ALP1,ALP2,ALP3,ALP4,ALP5,SD,CD,SDSD,CDCD,SDCD,S2D,C2D 428 | COMMON /C2/XI2,ET2,Q2,R,R2,R3,R5,Y,D,TT,ALX,ALE,X11,Y11,X32,Y32, 429 | * EY,EZ,FY,FZ,GY,GZ,HY,HZ 430 | DATA F0,F1,F2,F3,PI2/0.D0,1.D0,2.D0,3.D0,6.283185307179586D0/ 431 | C----- 432 | C=D+Z 433 | X53=(8.D0*R2+9.D0*R*XI+F3*XI2)*X11*X11*X11/R2 434 | Y53=(8.D0*R2+9.D0*R*ET+F3*ET2)*Y11*Y11*Y11/R2 435 | H=Q*CD-Z 436 | Z32=SD/R3-H*Y32 437 | Z53=F3*SD/R5-H*Y53 438 | Y0=Y11-XI2*Y32 439 | Z0=Z32-XI2*Z53 440 | PPY=CD/R3+Q*Y32*SD 441 | PPZ=SD/R3-Q*Y32*CD 442 | QQ=Z*Y32+Z32+Z0 443 | QQY=F3*C*D/R5-QQ*SD 444 | QQZ=F3*C*Y/R5-QQ*CD+Q*Y32 445 | XY=XI*Y11 446 | QX=Q*X11 447 | QY=Q*Y11 448 | QR=F3*Q/R5 449 | CQX=C*Q*X53 450 | CDR=(C+D)/R3 451 | YY0=Y/R3-Y0*CD 452 | C===== 453 | DO 111 I=1,12 454 | 111 U(I)=F0 455 | C====================================== 456 | C===== STRIKE-SLIP CONTRIBUTION ===== 457 | C====================================== 458 | IF(DISL1.NE.F0) THEN 459 | DU( 1)= ALP4*XY*CD -ALP5*XI*Q*Z32 460 | DU( 2)= ALP4*(CD/R+F2*QY*SD) -ALP5*C*Q/R3 461 | DU( 3)= ALP4*QY*CD -ALP5*(C*ET/R3-Z*Y11+XI2*Z32) 462 | DU( 4)= ALP4*Y0*CD -ALP5*Q*Z0 463 | DU( 5)=-ALP4*XI*(CD/R3+F2*Q*Y32*SD) +ALP5*C*XI*QR 464 | DU( 6)=-ALP4*XI*Q*Y32*CD +ALP5*XI*(F3*C*ET/R5-QQ) 465 | DU( 7)=-ALP4*XI*PPY*CD -ALP5*XI*QQY 466 | DU( 8)= ALP4*F2*(D/R3-Y0*SD)*SD-Y/R3*CD 467 | * -ALP5*(CDR*SD-ET/R3-C*Y*QR) 468 | DU( 9)=-ALP4*Q/R3+YY0*SD +ALP5*(CDR*CD+C*D*QR-(Y0*CD+Q*Z0)*SD) 469 | DU(10)= ALP4*XI*PPZ*CD -ALP5*XI*QQZ 470 | DU(11)= ALP4*F2*(Y/R3-Y0*CD)*SD+D/R3*CD -ALP5*(CDR*CD+C*D*QR) 471 | DU(12)= YY0*CD -ALP5*(CDR*SD-C*Y*QR-Y0*SDSD+Q*Z0*CD) 472 | DO 222 I=1,12 473 | 222 U(I)=U(I)+DISL1/PI2*DU(I) 474 | ENDIF 475 | C====================================== 476 | C===== DIP-SLIP CONTRIBUTION ===== 477 | C====================================== 478 | IF(DISL2.NE.F0) THEN 479 | DU( 1)= ALP4*CD/R -QY*SD -ALP5*C*Q/R3 480 | DU( 2)= ALP4*Y*X11 -ALP5*C*ET*Q*X32 481 | DU( 3)= -D*X11-XY*SD -ALP5*C*(X11-Q2*X32) 482 | DU( 4)=-ALP4*XI/R3*CD +ALP5*C*XI*QR +XI*Q*Y32*SD 483 | DU( 5)=-ALP4*Y/R3 +ALP5*C*ET*QR 484 | DU( 6)= D/R3-Y0*SD +ALP5*C/R3*(F1-F3*Q2/R2) 485 | DU( 7)=-ALP4*ET/R3+Y0*SDSD -ALP5*(CDR*SD-C*Y*QR) 486 | DU( 8)= ALP4*(X11-Y*Y*X32) -ALP5*C*((D+F2*Q*CD)*X32-Y*ET*Q*X53) 487 | DU( 9)= XI*PPY*SD+Y*D*X32 +ALP5*C*((Y+F2*Q*SD)*X32-Y*Q2*X53) 488 | DU(10)= -Q/R3+Y0*SDCD -ALP5*(CDR*CD+C*D*QR) 489 | DU(11)= ALP4*Y*D*X32 -ALP5*C*((Y-F2*Q*SD)*X32+D*ET*Q*X53) 490 | DU(12)=-XI*PPZ*SD+X11-D*D*X32-ALP5*C*((D-F2*Q*CD)*X32-D*Q2*X53) 491 | DO 333 I=1,12 492 | 333 U(I)=U(I)+DISL2/PI2*DU(I) 493 | ENDIF 494 | C======================================== 495 | C===== TENSILE-FAULT CONTRIBUTION ===== 496 | C======================================== 497 | IF(DISL3.NE.F0) THEN 498 | DU( 1)=-ALP4*(SD/R+QY*CD) -ALP5*(Z*Y11-Q2*Z32) 499 | DU( 2)= ALP4*F2*XY*SD+D*X11 -ALP5*C*(X11-Q2*X32) 500 | DU( 3)= ALP4*(Y*X11+XY*CD) +ALP5*Q*(C*ET*X32+XI*Z32) 501 | DU( 4)= ALP4*XI/R3*SD+XI*Q*Y32*CD+ALP5*XI*(F3*C*ET/R5-F2*Z32-Z0) 502 | DU( 5)= ALP4*F2*Y0*SD-D/R3 +ALP5*C/R3*(F1-F3*Q2/R2) 503 | DU( 6)=-ALP4*YY0 -ALP5*(C*ET*QR-Q*Z0) 504 | DU( 7)= ALP4*(Q/R3+Y0*SDCD) +ALP5*(Z/R3*CD+C*D*QR-Q*Z0*SD) 505 | DU( 8)=-ALP4*F2*XI*PPY*SD-Y*D*X32 506 | * +ALP5*C*((Y+F2*Q*SD)*X32-Y*Q2*X53) 507 | DU( 9)=-ALP4*(XI*PPY*CD-X11+Y*Y*X32) 508 | * +ALP5*(C*((D+F2*Q*CD)*X32-Y*ET*Q*X53)+XI*QQY) 509 | DU(10)= -ET/R3+Y0*CDCD -ALP5*(Z/R3*SD-C*Y*QR-Y0*SDSD+Q*Z0*CD) 510 | DU(11)= ALP4*F2*XI*PPZ*SD-X11+D*D*X32 511 | * -ALP5*C*((D-F2*Q*CD)*X32-D*Q2*X53) 512 | DU(12)= ALP4*(XI*PPZ*CD+Y*D*X32) 513 | * +ALP5*(C*((Y-F2*Q*SD)*X32+D*ET*Q*X53)+XI*QQZ) 514 | DO 444 I=1,12 515 | 444 U(I)=U(I)+DISL3/PI2*DU(I) 516 | ENDIF 517 | RETURN 518 | END 519 | SUBROUTINE DCCON0(ALPHA,DIP) 520 | IMPLICIT REAL*8 (A-H,O-Z) 521 | C 522 | C******************************************************************* 523 | C***** CALCULATE MEDIUM CONSTANTS AND FAULT-DIP CONSTANTS ***** 524 | C******************************************************************* 525 | C 526 | C***** INPUT 527 | C***** ALPHA : MEDIUM CONSTANT (LAMBDA+MYU)/(LAMBDA+2*MYU) 528 | C***** DIP : DIP-ANGLE (DEGREE) 529 | C### CAUTION ### IF COS(DIP) IS SUFFICIENTLY SMALL, IT IS SET TO ZERO 530 | C 531 | COMMON /C0/ALP1,ALP2,ALP3,ALP4,ALP5,SD,CD,SDSD,CDCD,SDCD,S2D,C2D 532 | DATA F0,F1,F2,PI2/0.D0,1.D0,2.D0,6.283185307179586D0/ 533 | DATA EPS/1.D-6/ 534 | C----- 535 | ALP1=(F1-ALPHA)/F2 536 | ALP2= ALPHA/F2 537 | ALP3=(F1-ALPHA)/ALPHA 538 | ALP4= F1-ALPHA 539 | ALP5= ALPHA 540 | C----- 541 | P18=PI2/360.D0 542 | SD=DSIN(DIP*P18) 543 | CD=DCOS(DIP*P18) 544 | IF(DABS(CD).LT.EPS) THEN 545 | CD=F0 546 | IF(SD.GT.F0) SD= F1 547 | IF(SD.LT.F0) SD=-F1 548 | ENDIF 549 | SDSD=SD*SD 550 | CDCD=CD*CD 551 | SDCD=SD*CD 552 | S2D=F2*SDCD 553 | C2D=CDCD-SDSD 554 | RETURN 555 | END 556 | SUBROUTINE DCCON1(X,Y,D) 557 | IMPLICIT REAL*8 (A-H,O-Z) 558 | C 559 | C********************************************************************** 560 | C***** CALCULATE STATION GEOMETRY CONSTANTS FOR POINT SOURCE ***** 561 | C********************************************************************** 562 | C 563 | C***** INPUT 564 | C***** X,Y,D : STATION COORDINATES IN FAULT SYSTEM 565 | C### CAUTION ### IF X,Y,D ARE SUFFICIENTLY SMALL, THEY ARE SET TO ZERO 566 | C 567 | COMMON /C0/DUMMY(5),SD,CD 568 | COMMON /C1/P,Q,S,T,XY,X2,Y2,D2,R,R2,R3,R5,QR,QRX,A3,A5,B3,C3, 569 | * UY,VY,WY,UZ,VZ,WZ 570 | DATA F0,F1,F3,F5,EPS/0.D0,1.D0,3.D0,5.D0,1.D-6/ 571 | C----- 572 | IF(DABS(X).LT.EPS) X=F0 573 | IF(DABS(Y).LT.EPS) Y=F0 574 | IF(DABS(D).LT.EPS) D=F0 575 | P=Y*CD+D*SD 576 | Q=Y*SD-D*CD 577 | S=P*SD+Q*CD 578 | T=P*CD-Q*SD 579 | XY=X*Y 580 | X2=X*X 581 | Y2=Y*Y 582 | D2=D*D 583 | R2=X2+Y2+D2 584 | R =DSQRT(R2) 585 | IF(R.EQ.F0) RETURN 586 | R3=R *R2 587 | R5=R3*R2 588 | R7=R5*R2 589 | C----- 590 | A3=F1-F3*X2/R2 591 | A5=F1-F5*X2/R2 592 | B3=F1-F3*Y2/R2 593 | C3=F1-F3*D2/R2 594 | C----- 595 | QR=F3*Q/R5 596 | QRX=F5*QR*X/R2 597 | C----- 598 | UY=SD-F5*Y*Q/R2 599 | UZ=CD+F5*D*Q/R2 600 | VY=S -F5*Y*P*Q/R2 601 | VZ=T +F5*D*P*Q/R2 602 | WY=UY+SD 603 | WZ=UZ+CD 604 | RETURN 605 | END 606 | SUBROUTINE DCCON2(XI,ET,Q,SD,CD,KXI,KET) 607 | IMPLICIT REAL*8 (A-H,O-Z) 608 | C 609 | C********************************************************************** 610 | C***** CALCULATE STATION GEOMETRY CONSTANTS FOR FINITE SOURCE ***** 611 | C********************************************************************** 612 | C 613 | C***** INPUT 614 | C***** XI,ET,Q : STATION COORDINATES IN FAULT SYSTEM 615 | C***** SD,CD : SIN, COS OF DIP-ANGLE 616 | C***** KXI,KET : KXI=1, KET=1 MEANS R+XI