/*
* EasyWave - A realtime tsunami simulation program with GPU support.
* Copyright (C) 2014 Andrey Babeyko, Johannes Spazier
* GFZ German Research Centre for Geosciences (http://www.gfz-potsdam.de)
*
* Parts of this program (especially the GPU extension) were developed
* within the context of the following publicly funded project:
* - TRIDEC, EU 7th Framework Programme, Grant Agreement 258723
* (http://www.tridec-online.eu)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see .
*/
// Y. Okada (1985) Surface deformation due to shear and tensile faults in a half-space:
// Bull.Seism.Soc.Am., v.75, p.1135-1154.
// okada@bosai.go.jp
#include
#define My_PI 3.14159265358979
#define DISPLMAX 1000
double fun_Chinnery( double (*fun)(double ksi, double eta), double x, double y );
double f_ssUx(double ksi, double eta);
double f_ssUy(double ksi, double eta);
double f_ssUz(double ksi, double eta);
double f_dsUx(double ksi, double eta);
double f_dsUy(double ksi, double eta);
double f_dsUz(double ksi, double eta);
double fun_R(double ksi, double eta);
double fun_X(double ksi, double eta);
double fun_yp(double ksi, double eta);
double fun_dp(double ksi, double eta);
double fun_I1(double ksi, double eta);
double fun_I2(double ksi, double eta);
double fun_I3(double ksi, double eta);
double fun_I4(double ksi, double eta);
double fun_I5(double ksi, double eta);
static double sdip;
static double cdip;
static double p;
static double q;
static double width;
static double length;
static double elast;
//============================================================================
int okada( double L,double W,double D,double sinD,double cosD,double U1,double U2,
double x,double y, int flag_xy, double *Ux,double *Uy,double *Uz )
{
double U1x,U2x,U1y,U2y,U1z,U2z;
sdip = sinD;
if( fabs(sdip)<1.e-10 ) sdip = 0;
cdip = cosD;
if( fabs(cdip)<1.e-10 ) cdip = 0;
p = y*cdip + D*sdip;
q = y*sdip - D*cdip;
width = W;
length = L;
elast = 0.5; // mu/(lambda+mu)
U1x=U2x=U1y=U2y=U1z=U2z=0;
if( U1 != 0 ) {
if( flag_xy ) {
U1x = -U1/2/My_PI * fun_Chinnery( f_ssUx, x,y );
if( fabs(U1x) > DISPLMAX ) U1x = 0;
U1y = -U1/2/My_PI * fun_Chinnery( f_ssUy, x,y );
if( fabs(U1y) > DISPLMAX ) U1y = 0;
}
U1z = -U1/2/My_PI * fun_Chinnery( f_ssUz, x,y );
if( fabs(U1z) > DISPLMAX ) U1z = 0;
}
if( U2 != 0 ) {
if( flag_xy ) {
U2x = -U2/2/My_PI * fun_Chinnery( f_dsUx, x,y );
if( fabs(U2x) > DISPLMAX ) U2x = 0;
U2y = -U2/2/My_PI * fun_Chinnery( f_dsUy, x,y );
if( fabs(U2y) > DISPLMAX ) U2y = 0;
}
U2z = -U2/2/My_PI * fun_Chinnery( f_dsUz, x,y );
if( fabs(U2z) > DISPLMAX ) U2z = 0;
}
*Ux = U1x + U2x;
*Uy = U1y + U2y;
*Uz = U1z + U2z;
return 0;
}
double fun_Chinnery( double (*fun)(double ksi, double eta), double x, double y )
{
double value;
value = fun(x,p) - fun(x,p-width) - fun(x-length,p) + fun(x-length,p-width);
return value;
}
double f_ssUx(double ksi, double eta)
{
double val,R,I1,term2;
R = fun_R(ksi,eta);
I1 = fun_I1(ksi,eta);
if( q*R == 0 ) {
if( ksi*eta == 0 ) {
term2 = 0;
} else {
if( ksi*eta*q*R > 0 )
term2 = My_PI;
else
term2 = -My_PI;
}
} else {
term2 = atan(ksi*eta/q/R);
}
val = ksi*q/R/(R+eta) + term2 + I1*sdip;
return val;
}
double f_ssUy(double ksi, double eta)
{
double val,yp,R,I2;
R = fun_R(ksi,eta);
I2 = fun_I2(ksi,eta);
yp = fun_yp(ksi,eta);
val = yp*q/R/(R+eta) + q*cdip/(R+eta) + I2*sdip;
return val;
}
double f_ssUz(double ksi, double eta)
{
double val,dp,R,I4;
R = fun_R(ksi,eta);
I4 = fun_I4(ksi,eta);
dp = fun_dp(ksi,eta);
val = dp*q/R/(R+eta) + q*sdip/(R+eta) + I4*sdip;
return val;
}
double f_dsUx(double ksi, double eta)
{
double val,R,I3;
R = fun_R(ksi,eta);
I3 = fun_I3(ksi,eta);
val = q/R - I3*sdip*cdip;
return val;
}
double f_dsUy(double ksi, double eta)
{
double val,yp,R,I1,term2;
R = fun_R(ksi,eta);
I1 = fun_I1(ksi,eta);
yp = fun_yp(ksi,eta);
if( q*R == 0 ) {
if( ksi*eta == 0 ) {
term2 = 0;
} else {
if( ksi*eta*q*R > 0 )
term2 = My_PI;
else
term2 = -My_PI;
}
} else {
term2 = atan(ksi*eta/q/R);
}
val = yp*q/R/(R+ksi) + cdip*term2 - I1*sdip*cdip;
return val;
}
double f_dsUz(double ksi, double eta)
{
double val,dp,R,I5,term2;
R = fun_R(ksi,eta);
I5 = fun_I5(ksi,eta);
dp = fun_dp(ksi,eta);
if( q*R == 0 ) {
if( ksi*eta == 0 ) {
term2 = 0;
} else {
if( ksi*eta*q*R > 0 )
term2 = My_PI;
else
term2 = -My_PI;
}
} else {
term2 = atan(ksi*eta/q/R);
}
val = dp*q/R/(R+ksi) + sdip*term2 - I5*sdip*cdip;
return val;
}
double fun_R( double ksi, double eta )
{
double val;
val = sqrt(ksi*ksi + eta*eta + q*q);
return val;
}
double fun_X( double ksi, double eta )
{
double val;
val = sqrt(ksi*ksi + q*q);
return val;
}
double fun_dp( double ksi, double eta )
{
double val;
val = eta*sdip - q*cdip;
return val;
}
double fun_yp( double ksi, double eta )
{
double val;
val = eta*cdip + q*sdip;
return val;
}
double fun_I1( double ksi, double eta )
{
double val,R,dp,I5;
R = fun_R(ksi,eta);
dp = fun_dp(ksi,eta);
I5 = fun_I5(ksi,eta);
if( cdip != 0 )
val = elast*(-1./cdip*ksi/(R+dp)) - sdip/cdip*I5;
else
val = -elast/2*ksi*q/(R+dp)/(R+dp);
return val;
}
double fun_I2( double ksi, double eta )
{
double val,R,I3;
R = fun_R(ksi,eta);
I3 = fun_I3(ksi,eta);
val = elast*(-log(R+eta)) - I3;
return val;
}
double fun_I3( double ksi, double eta )
{
double val,R,yp,dp,I4;
R = fun_R(ksi,eta);
yp = fun_yp(ksi,eta);
dp = fun_dp(ksi,eta);
I4 = fun_I4(ksi,eta);
if( cdip != 0 )
val = elast*(1./cdip*yp/(R+dp) - log(R+eta)) + sdip/cdip*I4;
else
val = elast/2*(eta/(R+dp) + yp*q/(R+dp)/(R+dp) - log(R+eta));
return val;
}
double fun_I4( double ksi, double eta )
{
double val,R,dp;
R = fun_R(ksi,eta);
dp = fun_dp(ksi,eta);
if( cdip != 0 )
val = elast/cdip*(log(R+dp)-sdip*log(R+eta));
else
val = -elast*q/(R+dp);
return val;
}
double fun_I5( double ksi, double eta )
{
double val,dp,X,R;
if( ksi == 0 )
return (double)0;
R = fun_R(ksi,eta);
X = fun_X(ksi,eta);
dp = fun_dp(ksi,eta);
if( cdip != 0 )
val = elast*2/cdip * atan( ( eta*(X+q*cdip)+X*(R+X)*sdip ) / (ksi*(R+X)*cdip) );
else
val = -elast*ksi*sdip/(R+dp);
return val;
}