diff --git a/doc/latex/6_Parameter_Definition.tex b/doc/latex/6_Parameter_Definition.tex index 685d53691c50fe4648016a50dbdee9a1a30a787b..faddb168a0ca19fb3b2438ad785ad9dc91c9ef63 100644 --- a/doc/latex/6_Parameter_Definition.tex +++ b/doc/latex/6_Parameter_Definition.tex @@ -375,6 +375,29 @@ Small $Q$ values ($Q<50$) may lead to significant amplitude decay and velocity d The frequency dependence of attenuation, i.e. $Q$ and phase velocity as a function of frequency, may be calculated using the Matlab functions in the directory mfiles. The Matlab script /mfiles/qplot.m can be used to plot $Q(\omega)$ for different values of L, $f_l$ and $\tau$. The m-file qapprox.m in the same directory finds optimal values for L, $f_l$ and $\tau$ that fit a desired function $Q(\omega)=const$ in a least-squares sense. +\section{Anisotropic modeling and inversion} +\label{anisotropy} +{\color{blue}{\begin{verbatim} +"Anisotropy" : "comment", + "VTI" : "0", +\end{verbatim}}} + +With VTI=1, the forward modeling and the inversion is calculated for a vertically transversely isotropic medium. For the forward modeling with WAVETYPE=1, additional models of the Thomsen parameters $\varepsilon$ and $\delta$ are needed with the file name expansions .epsilon'' and .delta''. For WAVETYPE=2, the input models are density, vertical S-wave velocity and horizontal S-wave velocity (.rho'', .vs'', .vshor''). The inversion is only implemented for SH waves (WAVETYPE=2) and should only be used with VELOCITY=1. Additional parameters that are used equivalent to those existing for the isotropic case are + +{\color{blue}{\begin{verbatim} + "INV_VSHOR_ITER" : "0", + "VSHORUPPERLIM" : "5000", + "VSHORLOWERLIM" : "0", +\end{verbatim}}} +\noindent + Additionally, with + {\color{blue}{\begin{verbatim} + "GAMMA_VTI" : "0", + \end{verbatim}}} + + a maximal absolute value of the Thomsen parameter $\gamma$ can be defined to constrain updates of the velocities (constraint is not active for GAMMA\_VTI=0). + + \section{Wavefield snapshots} {\color{blue}{\begin{verbatim} "Snapshots" : "comment", diff --git a/genmod/1D_linear_gradient_el_vti.c b/genmod/1D_linear_gradient_el_vti.c new file mode 100644 index 0000000000000000000000000000000000000000..b5839c996549846f6e08eee48273b7177af14cb7 --- /dev/null +++ b/genmod/1D_linear_gradient_el_vti.c @@ -0,0 +1,134 @@ +/*----------------------------------------------------------------------------------------- + * Copyright (C) 2005 + * + * This file is part of DENISE. + * + * DENISE is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, version 2.0 of the License only. + * + * DENISE 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with DENISE. See file COPYING and/or . +-----------------------------------------------------------------------------------------*/ + +/* + * Model 1D linear gradient + * Vertically transversely isotropic model + */ + +#include "fd.h" + +void model_elastic_vti(float ** rho, float ** pi, float ** u, float ** delta, float ** epsilon, float ** vshor){ + + /*--------------------------------------------------------------------------*/ + /* extern variables */ + + extern int NX, NY, NXG, NYG, POS[3], L, MYID; + extern char MFILE[STRING_SIZE]; + extern char INV_MODELFILE[STRING_SIZE]; + extern float DH; + /* local variables */ + float vp, vs, rhov, grad1, grad2, grad3, grad4, grad5, grad6, y; + float c11v, c13v, c33v, c55v, c66v, deltav, epsilonv, vshorv; + int i, j, ii, jj; + char modfile[STRING_SIZE]; + float ** pwavemod=NULL, ** swavemod=NULL; + + /* parameter defintion: + * vp = vertical P-wave-velocity, vs = vertical S-wave-velocity, vshor = horizontal S-wave-velocity + * delta, epsilon = Thomsen parameters */ + + /* parameters for layer 1 */ + const float vp1=500.0, vs1=300.0, rho1=1800.0, h=15.0; + const float delta1=0.1, epsilon1=0.2, vshor1=550; + + /* parameters for layer 2 due to calculation of grad1, grad2 and grad3*/ + const float vp2=1200.0, vs2=700.0, rho2=2000.0; + const float delta2=0.1, epsilon2=0.2, vshor2=1500; + + + /*-----------------------------------------------------------------------*/ + + y=h/DH; + if(y==NYG) declare_error(" \n y is equal NYG !! see src/model_grad.c \n "); + grad1=(vp2-vp1)/y; + grad2=(vs2-vs1)/y; + grad3=(rho2-rho1)/y; + grad4=(delta2-delta1)/y; + grad5=(epsilon2-epsilon1)/y; + grad6=(vshor2-vshor1)/y; + + + + /* loop over global grid */ + for (i=1;i<=NXG;i++){ + for (j=1;j<=NYG;j++){ + + if(j<=y){ + vp=vp1+(j*grad1); + vs=vs1+(j*grad2); + rhov=rho1+(j*grad3); + deltav=delta1+(j*grad4); + epsilonv=epsilon1+(j*grad5); + vshorv=vshor1+(j*grad6); + } + + else{ + vp=vp2; + vs=vs2; + rhov=rho2; + deltav=delta2; + epsilonv=epsilon2; + vshorv=vshor2; + } + + + + /* only the PE which belongs to the current global gridpoint + is saving model parameters in his local arrays */ + if ((POS[1]==((i-1)/NX)) && + (POS[2]==((j-1)/NY))){ + ii=i-POS[1]*NX; + jj=j-POS[2]*NY; + + u[jj][ii]=vs; + pi[jj][ii]=vp; + rho[jj][ii]=rhov; + delta[jj][ii]=deltav; + epsilon[jj][ii]=epsilonv; + vshor[jj][ii]=vshorv; + + + } + } + } + + +sprintf(modfile,"%s_rho_it_0.bin",INV_MODELFILE); +writemod(modfile,rho,3); +MPI_Barrier(MPI_COMM_WORLD); +if (MYID==0) mergemod(modfile,3); + +sprintf(modfile,"%s_vs_it_0.bin",INV_MODELFILE); +writemod(modfile,u,3); +MPI_Barrier(MPI_COMM_WORLD); +if (MYID==0) mergemod(modfile,3); + +sprintf(modfile,"%s_vp_it_0.bin",INV_MODELFILE); +writemod(modfile,pi,3); +MPI_Barrier(MPI_COMM_WORLD); +if (MYID==0) mergemod(modfile,3); + +sprintf(modfile,"%s_vshor_it_0.bin",INV_MODELFILE); +writemod(modfile,vshor,3); +MPI_Barrier(MPI_COMM_WORLD); +if (MYID==0) mergemod(modfile,3); +} + + + diff --git a/par/in_and_out/IFOS2D_FW_all_parameters.json b/par/in_and_out/IFOS2D_FW_all_parameters.json index 91fc8548273af9c7247b281cff4a91d8453ccb3f..5cc52543a249fbc322aabd82dc4cdb4b6ddde146 100644 --- a/par/in_and_out/IFOS2D_FW_all_parameters.json +++ b/par/in_and_out/IFOS2D_FW_all_parameters.json @@ -62,6 +62,9 @@ "NDT" : "1", "SEIS_FORMAT" : "1", "SEIS_FILE" : "su/IFOS", + +"Anisotropy" : "comment", + "VTI" : "0", "Q-approximation" : "comment", "L" : "0", diff --git a/par/in_and_out/IFOS2D_INV_all_parameters.json b/par/in_and_out/IFOS2D_INV_all_parameters.json index 84ce4be119d7eb627dd46e2e215b5d5484fe34cf..1d437e9e0e5b4a367b86b652efa79851a313153c 100644 --- a/par/in_and_out/IFOS2D_INV_all_parameters.json +++ b/par/in_and_out/IFOS2D_INV_all_parameters.json @@ -62,6 +62,9 @@ "NDT" : "1", "SEIS_FORMAT" : "1", "SEIS_FILE" : "su/IFOS", + +"Anisotropy" : "comment", + "VTI" : "0", "Q-approximation" : "comment", "L" : "0", @@ -222,6 +225,8 @@ "VSLOWERLIM" : "0", "RHOUPPERLIM" : "5000", "RHOLOWERLIM" : "0", + "VSHORUPPERLIM" : "5000", + "VSHORLOWERLIM" : "0", "Limited update of model parameters in reference to the starting model" : "comment", "S" : "0", @@ -232,6 +237,9 @@ "Minimum Vp/Vs-ratio" : "comment", "VP_VS_RATIO" : "0.0", +"Maximal gamma-value (Thomsen parameter for VTI)" : "comment", + "GAMMA_VTI" : "0", + "Definition of smoothing the models vp and vs" : "comment", "MODEL_FILTER" : "0", "FILT_SIZE" : "5", diff --git a/src/IFOS2D.c b/src/IFOS2D.c index b5c1f8cb5fea8ab6fef60efb2226fa5bca9f4f42..7c8734f1edb40369f3120623a05b57e01c8dece0 100644 --- a/src/IFOS2D.c +++ b/src/IFOS2D.c @@ -40,7 +40,7 @@ int main(int argc, char **argv){ float muss, lamss; float memdyn, memmodel, memseismograms, membuffer, memtotal, eps_scale; float fac1, fac2; - float opteps_vp, opteps_vs, opteps_rho, Vp_avg, C_vp, Vs_avg, C_vs, rho_avg, C_rho; + float opteps_vp, opteps_vs, opteps_rho, Vp_avg, C_vp, Vs_avg, C_vs, rho_avg, C_rho, vshor_avg, C_vshor; float memfwt, memfwt1, memfwtdata; char *buff_addr, ext[10], *fileinp; char jac[225]; @@ -61,8 +61,9 @@ int main(int argc, char **argv){ float ** psxx, ** psxy, ** psyy, ** psxz, ** psyz, **psp, ** ux, ** uy, ** uxy, ** uyx, ** u, ** Vp0, ** uttx, ** utty, ** Vs0, ** Rho0; float ** pvx, ** pvy, ** pvz, **waveconv, **waveconv_lam, **waveconv_mu, **waveconv_rho, **waveconv_rho_s, **waveconv_u, **waveconvtmp, **wcpart, **wavejac,**waveconv_rho_s_z,**waveconv_u_z,**waveconv_rho_z; float **waveconv_shot, **waveconv_u_shot, **waveconv_rho_shot, **waveconv_u_shot_z, **waveconv_rho_shot_z; + float **waveconv_c55_shot_z, **waveconv_c66_shot_z, **waveconv_c55_s_z, **waveconv_c66_s_z, **waveconv_vshor_shot_z, **waveconv_vshor_z; float ** pvxp1, ** pvyp1, ** pvzp1, ** pvxm1, ** pvym1, ** pvzm1; - float ** gradg, ** gradp,** gradg_rho, ** gradp_rho, ** gradg_u, ** gradp_u, ** gradp_u_z,** gradp_rho_z; + float ** gradg, ** gradp,** gradg_rho, ** gradp_rho, ** gradg_u, ** gradp_u, ** gradp_u_z,** gradp_rho_z, **gradp_vshor_z; float ** prho,** prhonp1, **prip=NULL, **prjp=NULL, **pripnp1=NULL, **prjpnp1=NULL, ** ppi, ** pu, ** punp1, ** puipjp, ** ppinp1; float ** vpmat, ***forward_prop_x, ***forward_prop_y, ***forward_prop_rho_x, ***forward_prop_u, ***forward_prop_rho_y, ***forward_prop_p; @@ -86,6 +87,10 @@ int main(int argc, char **argv){ float ** psi_sxx_x, ** psi_syy_y, ** psi_sxy_y, ** psi_sxy_x, ** psi_vxx, ** psi_vyy, ** psi_vxy, ** psi_vyx, ** psi_vxxs; float ** psi_sxz_x, ** psi_syz_y, ** psi_vzx, ** psi_vzy; + /* Variables for vertically transversely isotropic modeling */ + float **pc11=NULL, **pc13=NULL, **pc33=NULL, **pc55=NULL, **pc55ipjp=NULL, **pc66=NULL, **pc66ipjp=NULL; + float **pdelta=NULL, **pepsilon=NULL, **pgamma=NULL, **pvshornp1=NULL, **pvshor=NULL; + /* Variables for viscoelastic modeling */ float **ptaus=NULL, **ptaup=NULL, *etaip=NULL, *etajm=NULL, *peta=NULL, **ptausipjp=NULL, **fipjp=NULL, ***dip=NULL, *bip=NULL, *bjm=NULL; float *cip=NULL, *cjm=NULL, ***d=NULL, ***e=NULL, ***pr=NULL, ***pp=NULL, ***pq=NULL, **f=NULL, **g=NULL; @@ -115,8 +120,8 @@ int main(int argc, char **argv){ int gradient_optimization=1; float alpha_SL_min=0, alpha_SL_max=0, alpha_SL=1.0; float alpha_SL_old; - float ** waveconv_old,** waveconv_u_old,** waveconv_rho_old; - float ** waveconv_up,** waveconv_u_up,** waveconv_rho_up; + float ** waveconv_old,** waveconv_u_old,** waveconv_rho_old,** waveconv_vshor_old; + float ** waveconv_up,** waveconv_u_up,** waveconv_rho_up,** waveconv_vshor_up; float L2_SL_old=0, L2_SL_new=0; float c1_SL=1e-4, c2_SL=0.9; int wolfe_status; @@ -388,7 +393,7 @@ int main(int argc, char **argv){ if(GRAD_METHOD==2) { /* Allocate memory for L-BFGS */ - if(WAVETYPE==2) LBFGS_NPAR=2; + if(WAVETYPE==2 && !VTI) LBFGS_NPAR=2; s_LBFGS=fmatrix(1,N_LBFGS,1,LBFGS_NPAR*NX*NY); @@ -488,6 +493,24 @@ int main(int argc, char **argv){ } } + if (VTI) { + /* dynamic arrays for anisotropic modeling */ + pc11 = matrix(-nd+1,NY+nd,-nd+1,NX+nd); + pc13 = matrix(-nd+1,NY+nd,-nd+1,NX+nd); + pc33 = matrix(-nd+1,NY+nd,-nd+1,NX+nd); + pc55 = matrix(-nd+1,NY+nd,-nd+1,NX+nd); + pc55ipjp = matrix(-nd+1,NY+nd,-nd+1,NX+nd); + pc66 = matrix(-nd+1,NY+nd,-nd+1,NX+nd); + pc66ipjp = matrix(-nd+1,NY+nd,-nd+1,NX+nd); + pdelta = matrix(-nd+1,NY+nd,-nd+1,NX+nd); + pepsilon = matrix(-nd+1,NY+nd,-nd+1,NX+nd); + if(WAVETYPE==2 || WAVETYPE==3) { + pgamma = matrix(-nd+1,NY+nd,-nd+1,NX+nd); + pvshornp1 = matrix(-nd+1,NY+nd,-nd+1,NX+nd); + } + pvshor = matrix(-nd+1,NY+nd,-nd+1,NX+nd); + } + if (L) { /* dynamic (wavefield) arrays for viscoelastic modeling */ pr = f3tensor(-nd+1,NY+nd,-nd+1,NX+nd,1,L); @@ -550,7 +573,16 @@ int main(int argc, char **argv){ forward_prop_z_xz = f3tensor(-nd+1,NY+nd,-nd+1,NX+nd,1,NT/DTINV); forward_prop_z_yz = f3tensor(-nd+1,NY+nd,-nd+1,NX+nd,1,NT/DTINV); waveconv_rho_shot_z = matrix(-nd+1,NY+nd,-nd+1,NX+nd); - waveconv_u_shot_z = matrix(-nd+1,NY+nd,-nd+1,NX+nd); + if (VTI) { + waveconv_c55_shot_z = matrix(-nd+1,NY+nd,-nd+1,NX+nd); + waveconv_c66_shot_z = matrix(-nd+1,NY+nd,-nd+1,NX+nd); + waveconv_c55_s_z = matrix(-nd+1,NY+nd,-nd+1,NX+nd); + waveconv_c66_s_z = matrix(-nd+1,NY+nd,-nd+1,NX+nd); + waveconv_vshor_shot_z = matrix(-nd+1,NY+nd,-nd+1,NX+nd); + waveconv_vshor_z = matrix(-nd+1,NY+nd,-nd+1,NX+nd); + gradp_vshor_z = matrix(-nd+1,NY+nd,-nd+1,NX+nd); + } + waveconv_u_shot_z = matrix(-nd+1,NY+nd,-nd+1,NX+nd); waveconv_mu_z = matrix(-nd+1,NY+nd,-nd+1,NX+nd); waveconv_rho_s_z = matrix(-nd+1,NY+nd,-nd+1,NX+nd); waveconv_u_z = matrix(-nd+1,NY+nd,-nd+1,NX+nd); @@ -571,11 +603,17 @@ int main(int argc, char **argv){ c2_SL=WOLFE_C2_SL; waveconv_old= matrix(-nd+1,NY+nd,-nd+1,NX+nd); - if(!ACOUSTIC) waveconv_u_old= matrix(-nd+1,NY+nd,-nd+1,NX+nd); + if(!ACOUSTIC){ + waveconv_u_old= matrix(-nd+1,NY+nd,-nd+1,NX+nd); + waveconv_vshor_old= matrix(-nd+1,NY+nd,-nd+1,NX+nd); + } waveconv_rho_old= matrix(-nd+1,NY+nd,-nd+1,NX+nd); waveconv_up= matrix(-nd+1,NY+nd,-nd+1,NX+nd); - if(!ACOUSTIC) waveconv_u_up= matrix(-nd+1,NY+nd,-nd+1,NX+nd); + if(!ACOUSTIC) { + waveconv_u_up= matrix(-nd+1,NY+nd,-nd+1,NX+nd); + waveconv_vshor_up= matrix(-nd+1,NY+nd,-nd+1,NX+nd); + } waveconv_rho_up= matrix(-nd+1,NY+nd,-nd+1,NX+nd); } @@ -778,7 +816,12 @@ int main(int argc, char **argv){ if(L){ if(!ACOUSTIC){ if (READMOD){ - readmod(prho,ppi,pu,ptaus,ptaup,peta); + if(VTI){ + readmod_vti(prho,ppi,pu,pdelta,pepsilon,pvshor,ptaus,ptaup,peta); + } + else { + readmod(prho,ppi,pu,ptaus,ptaup,peta); + } }else{ model(prho,ppi,pu,ptaus,ptaup,peta); } @@ -792,9 +835,19 @@ int main(int argc, char **argv){ }else{ if(!ACOUSTIC){ if (READMOD){ - readmod_elastic(prho,ppi,pu); + if (VTI) { + readmod_el_vti(prho,ppi,pu,pdelta,pepsilon,pvshor); + } + else { + readmod_elastic(prho,ppi,pu); + } }else{ - model_elastic(prho,ppi,pu); + if(VTI){ + model_elastic_vti(prho,ppi,pu,pdelta,pepsilon,pvshor); + } + else { + model_elastic(prho,ppi,pu); + } } }else{ if (READMOD){ @@ -806,7 +859,7 @@ int main(int argc, char **argv){ } /* check if the FD run will be stable and free of numerical dispersion */ - checkfd(FP, prho, ppi, pu, ptaus, ptaup, peta, hc, srcpos, nsrc, recpos, ntr_glob); + checkfd(FP, prho, ppi, pu, ptaus, ptaup, peta, hc, srcpos, nsrc, recpos, ntr_glob, pepsilon, pdelta, pvshor); /* calculate damping coefficients for CPMLs*/ if(FW>0) @@ -899,15 +952,28 @@ int main(int argc, char **argv){ they have to be averaged. For this, values lying at 0 and NX+1, for example, are required on the local grid. These are now copied from the neighbouring grids */ + if (VTI){ + change_parameterization_vti(prho, ppi, pu, pepsilon, pdelta, pvshor, pc11, pc13, pc33, pc55, pc66); + } if (L){ if(!ACOUSTIC){ - matcopy(prho,ppi,pu,ptaus,ptaup); + if(VTI){ + matcopy_vti(prho, pc11, pc13, pc33, pc55, pc66, ptaus, ptaup); + } + else { + matcopy(prho,ppi,pu,ptaus,ptaup); + } } else { matcopy_viscac(prho,ppi,ptaup); } }else{ if(!ACOUSTIC){ - matcopy_elastic(prho, ppi, pu); + if (VTI) { + matcopy_elastic_vti(prho, pc11, pc13, pc33, pc55, pc66); + } + else { + matcopy_elastic(prho, ppi, pu); + } }else{ matcopy_acoustic(prho, ppi); } @@ -929,12 +995,18 @@ int main(int argc, char **argv){ if(!ACOUSTIC) av_mue(pu,puipjp,prho); av_rho(prho,prip,prjp); if (!ACOUSTIC && L) av_tau(ptaus,ptausipjp); + if (VTI) av_c55c66(pc55,pc55ipjp, pc66,pc66ipjp); /* Preparing memory variables for update_s (viscoelastic) */ if (L) { if(!ACOUSTIC){ - prepare_update_s(etajm,etaip,peta,fipjp,pu,puipjp,ppi,prho,ptaus,ptaup,ptausipjp,f,g,bip,bjm,cip,cjm,dip,d,e); + if(VTI){ + prepare_update_s_vti(etajm,etaip,peta,fipjp,pc55,pc66ipjp,ppi,prho,ptaus,ptaup,ptausipjp,f,g,bip,bjm,cip,cjm,dip,d,e); + } + else { + prepare_update_s(etajm,etaip,peta,fipjp,pu,puipjp,ppi,prho,ptaus,ptaup,ptausipjp,f,g,bip,bjm,cip,cjm,dip,d,e); + } } else { prepare_update_p(etajm,peta,ppi,prho,ptaup,g,bjm,cjm,e); } @@ -978,13 +1050,24 @@ int main(int argc, char **argv){ Vp_avg=average_matrix(ppi); rho_avg=average_matrix(prho); if(!ACOUSTIC) Vs_avg=average_matrix(pu); + if (VTI) { + vshor_avg=average_matrix(pvshor); + } - if(!ACOUSTIC) if(VERBOSE) printf("MYID = %d \t Vp_avg = %e \t Vs_avg = %e \t rho_avg = %e \n ",MYID,Vp_avg,Vs_avg,rho_avg); + if(!ACOUSTIC) { + if (VTI) { + if (VERBOSE) printf("MYID = %d \t Vp_avg = %e \t Vs_avg = %e \t rho_avg = %e \t vshor_avg = %e \n ",MYID,Vp_avg,Vs_avg,rho_avg,vshor_avg); + } + else if(VERBOSE) printf("MYID = %d \t Vp_avg = %e \t Vs_avg = %e \t rho_avg = %e \n ",MYID,Vp_avg,Vs_avg,rho_avg); + } else if(VERBOSE) printf("MYID = %d \t Vp_avg = %e \t rho_avg = %e \n ",MYID,Vp_avg,rho_avg); C_vp = Vp_avg*Vp_avg; if(!ACOUSTIC) C_vs = Vs_avg*Vs_avg; C_rho = rho_avg*rho_avg; + if (VTI) { + C_vshor = vshor_avg*vshor_avg; + } } @@ -1057,6 +1140,9 @@ int main(int argc, char **argv){ for (i=1;i<=NX;i=i+IDX){ waveconv_rho_z[j][i]=0.0; waveconv_u_z[j][i]=0.0; + if (VTI) { + waveconv_vshor_z[j][i]=0.0; + } } } @@ -1251,18 +1337,33 @@ int main(int argc, char **argv){ } } if (WAVETYPE==2 || WAVETYPE==3) { - update_s_visc_PML_SH(1, NX, 1, NY, pvz, psxz, psyz, pt, po, bip, bjm, cip, cjm, d, dip,fipjp, f, hc,infoout, K_x, a_x, b_x, K_x_half, a_x_half, b_x_half, K_y, a_y, b_y, K_y_half, a_y_half, b_y_half,psi_vzx, psi_vzy); + if(VTI){ + update_s_visc_vti_PML_SH(1, NX, 1, NY, pvz, uxz, uyz, psxz, psyz, pt, po, bip, bjm, cip, cjm, d, dip,fipjp, f, hc,infoout, K_x, a_x, b_x, K_x_half, a_x_half, b_x_half, K_y, a_y, b_y, K_y_half, a_y_half, b_y_half,psi_vzx, psi_vzy, pc55,pc66ipjp,prho); + } + else { + update_s_visc_PML_SH(1, NX, 1, NY, pvz, uxz, uyz, psxz, psyz, pt, po, bip, bjm, cip, cjm, d, dip,fipjp, f, hc,infoout, K_x, a_x, b_x, K_x_half, a_x_half, b_x_half, K_y, a_y, b_y, K_y_half, a_y_half, b_y_half,psi_vzx, psi_vzy); + } } } else { /* elastic */ if (WAVETYPE==1 || WAVETYPE==3) { if(!ACOUSTIC) { - update_s_elastic_PML(1, NX, 1, NY, pvx, pvy, ux, uy, uxy, uyx, psxx, psyy, psxy, ppi, pu, puipjp, absorb_coeff, prho, hc, infoout, K_x, a_x, b_x, K_x_half, a_x_half, b_x_half, K_y, a_y, b_y, K_y_half, a_y_half, b_y_half, psi_vxx, psi_vyy, psi_vxy, psi_vyx); + if (VTI) { + update_s_el_vti_PML(1, NX, 1, NY, pvx, pvy, ux, uy, uxy, uyx, psxx, psyy, psxy, pc11, pc13, pc33, pc55ipjp, absorb_coeff, prho, hc, infoout, K_x, a_x, b_x, K_x_half, a_x_half, b_x_half, K_y, a_y, b_y, K_y_half, a_y_half, b_y_half, psi_vxx, psi_vyy, psi_vxy, psi_vyx); + } + else { + update_s_elastic_PML(1, NX, 1, NY, pvx, pvy, ux, uy, uxy, uyx, psxx, psyy, psxy, ppi, pu, puipjp, absorb_coeff, prho, hc, infoout, K_x, a_x, b_x, K_x_half, a_x_half, b_x_half, K_y, a_y, b_y, K_y_half, a_y_half, b_y_half, psi_vxx, psi_vyy, psi_vxy, psi_vyx); + } } else { update_p_PML(1, NX, 1, NY, pvx, pvy, psp, u, ppi, absorb_coeff, prho, hc, infoout, K_x, a_x, b_x, K_x_half, a_x_half, b_x_half, K_y, a_y, b_y, K_y_half, a_y_half, b_y_half, psi_vxx, psi_vyy, psi_vxy, psi_vyx); } } if (WAVETYPE==2 || WAVETYPE==3) { - update_s_elastic_PML_SH(1, NX, 1, NY, pvz,psxz,psyz,uxz,uyz,hc,infoout, K_x, a_x, b_x, K_x_half, a_x_half, b_x_half, K_y, a_y, b_y, K_y_half, a_y_half, b_y_half,psi_vzx, psi_vzy,puipjp,pu,prho); + if (VTI) { + update_s_el_vti_PML_SH(1, NX, 1, NY, pvz,psxz,psyz,uxz,uyz,hc,infoout, K_x, a_x, b_x, K_x_half, a_x_half, b_x_half, K_y, a_y, b_y, K_y_half, a_y_half, b_y_half,psi_vzx, psi_vzy,pc55,pc66ipjp,prho); + } + else { + update_s_elastic_PML_SH(1, NX, 1, NY, pvz,psxz,psyz,uxz,uyz,hc,infoout, K_x, a_x, b_x, K_x_half, a_x_half, b_x_half, K_y, a_y, b_y, K_y_half, a_y_half, b_y_half,psi_vzx, psi_vzy,puipjp,pu,prho); + } } } @@ -1279,7 +1380,12 @@ int main(int argc, char **argv){ surface_PML(1, pvx, pvy, psxx, psyy, psxy,psyz, pp, pq, ppi, pu, prho, ptaup, ptaus, etajm, peta, hc, K_x, a_x, b_x, psi_vxxs, ux, uy,uxy,uyz,psxz,uxz); }else{ /* elastic */ - surface_elastic_PML(1, pvx, pvy, psxx, psyy, psxy,psyz, ppi, pu, prho, hc, K_x, a_x, b_x, psi_vxxs, ux, uy, uxy,uyz,psxz,uxz); + if (VTI) { + surface_el_vti_PML(1, pvx, pvy, psxx, psyy, psxy,psyz, pc11, pc13, pc33, prho, hc, K_x, a_x, b_x, psi_vxxs, ux, uy, uxy,uyz,psxz,uxz); + } + else { + surface_elastic_PML(1, pvx, pvy, psxx, psyy, psxy,psyz, ppi, pu, prho, hc, K_x, a_x, b_x, psi_vxxs, ux, uy, uxy,uyz,psxz,uxz); + } } } else { /* viscoelastic and elastic ACOUSTIC */ @@ -1588,12 +1694,23 @@ int main(int argc, char **argv){ /*initialize gradient matrices for each shot with zeros SH*/ if(WAVETYPE==2 || WAVETYPE==3){ if(FORWARD_ONLY==0){ - for(j=1;j<=NY;j=j+IDY){ - for(i=1;i<=NX;i=i+IDX){ - waveconv_rho_shot_z[j][i]=0.0; - waveconv_u_shot_z[j][i]=0.0; - } - } + if (VTI) { + for(j=1;j<=NY;j=j+IDY){ + for(i=1;i<=NX;i=i+IDX){ + waveconv_rho_shot_z[j][i]=0.0; + waveconv_c55_shot_z[j][i]=0.0; + waveconv_c66_shot_z[j][i]=0.0; + } + } + } + else { + for(j=1;j<=NY;j=j+IDY){ + for(i=1;i<=NX;i=i+IDX){ + waveconv_rho_shot_z[j][i]=0.0; + waveconv_u_shot_z[j][i]=0.0; + } + } + } } } @@ -1694,18 +1811,33 @@ int main(int argc, char **argv){ } } if (WAVETYPE==2 || WAVETYPE==3) { - update_s_visc_PML_SH(1, NX, 1, NY, pvz, psxz, psyz, pt, po, bip, bjm, cip, cjm, d, dip,fipjp, f, hc,infoout, K_x, a_x, b_x, K_x_half, a_x_half, b_x_half, K_y, a_y, b_y, K_y_half, a_y_half, b_y_half,psi_vzx, psi_vzy); + if(VTI){ + update_s_visc_vti_PML_SH(1, NX, 1, NY, pvz, uxz, uyz, psxz, psyz, pt, po, bip, bjm, cip, cjm, d, dip,fipjp, f, hc,infoout, K_x, a_x, b_x, K_x_half, a_x_half, b_x_half, K_y, a_y, b_y, K_y_half, a_y_half, b_y_half,psi_vzx, psi_vzy, pc55,pc66ipjp,prho); + } + else { + update_s_visc_PML_SH(1, NX, 1, NY, pvz, uxz, uyz, psxz, psyz, pt, po, bip, bjm, cip, cjm, d, dip,fipjp, f, hc,infoout, K_x, a_x, b_x, K_x_half, a_x_half, b_x_half, K_y, a_y, b_y, K_y_half, a_y_half, b_y_half,psi_vzx, psi_vzy); + } } } else { /* elastic */ if (WAVETYPE==1 || WAVETYPE==3) { if(!ACOUSTIC) { - update_s_elastic_PML(1, NX, 1, NY, pvx, pvy, ux, uy, uxy, uyx, psxx, psyy, psxy, ppi, pu, puipjp, absorb_coeff, prho, hc, infoout, K_x, a_x, b_x, K_x_half, a_x_half, b_x_half, K_y, a_y, b_y, K_y_half, a_y_half, b_y_half, psi_vxx, psi_vyy, psi_vxy, psi_vyx); + if (VTI) { + update_s_el_vti_PML(1, NX, 1, NY, pvx, pvy, ux, uy, uxy, uyx, psxx, psyy, psxy, pc11, pc13, pc33, pc55ipjp, absorb_coeff, prho, hc, infoout, K_x, a_x, b_x, K_x_half, a_x_half, b_x_half, K_y, a_y, b_y, K_y_half, a_y_half, b_y_half, psi_vxx, psi_vyy, psi_vxy, psi_vyx); + } + else { + update_s_elastic_PML(1, NX, 1, NY, pvx, pvy, ux, uy, uxy, uyx, psxx, psyy, psxy, ppi, pu, puipjp, absorb_coeff, prho, hc, infoout, K_x, a_x, b_x, K_x_half, a_x_half, b_x_half, K_y, a_y, b_y, K_y_half, a_y_half, b_y_half, psi_vxx, psi_vyy, psi_vxy, psi_vyx); + } } else { update_p_PML(1, NX, 1, NY, pvx, pvy, psp, u, ppi, absorb_coeff, prho, hc, infoout, K_x, a_x, b_x, K_x_half, a_x_half, b_x_half, K_y, a_y, b_y, K_y_half, a_y_half, b_y_half, psi_vxx, psi_vyy, psi_vxy, psi_vyx); } } if (WAVETYPE==2 || WAVETYPE==3) { - update_s_elastic_PML_SH(1, NX, 1, NY, pvz,psxz,psyz,uxz,uyz,hc,infoout, K_x, a_x, b_x, K_x_half, a_x_half, b_x_half, K_y, a_y, b_y, K_y_half, a_y_half, b_y_half,psi_vzx, psi_vzy,puipjp,pu,prho); + if (VTI) { + update_s_el_vti_PML_SH(1, NX, 1, NY, pvz,psxz,psyz,uxz,uyz,hc,infoout, K_x, a_x, b_x, K_x_half, a_x_half, b_x_half, K_y, a_y, b_y, K_y_half, a_y_half, b_y_half,psi_vzx, psi_vzy,pc55,pc66ipjp,prho); + } + else { + update_s_elastic_PML_SH(1, NX, 1, NY, pvz,psxz,psyz,uxz,uyz,hc,infoout, K_x, a_x, b_x, K_x_half, a_x_half, b_x_half, K_y, a_y, b_y, K_y_half, a_y_half, b_y_half,psi_vzx, psi_vzy,puipjp,pu,prho); + } } } @@ -1723,7 +1855,12 @@ int main(int argc, char **argv){ surface_PML(1, pvx, pvy, psxx, psyy, psxy,psyz, pp, pq, ppi, pu, prho, ptaup, ptaus, etajm, peta, hc, K_x, a_x, b_x, psi_vxxs, ux, uy,uxy,uyz,psxz,uxz); }else{ /* elastic */ - surface_elastic_PML(1, pvx, pvy, psxx, psyy, psxy,psyz, ppi, pu, prho, hc, K_x, a_x, b_x, psi_vxxs, ux, uy, uxy,uyz,psxz,uxz); + if (VTI) { + surface_el_vti_PML(1, pvx, pvy, psxx, psyy, psxy,psyz, pc11, pc13, pc33, prho, hc, K_x, a_x, b_x, psi_vxxs, ux, uy, uxy,uyz,psxz,uxz); + } + else { + surface_elastic_PML(1, pvx, pvy, psxx, psyy, psxy,psyz, ppi, pu, prho, hc, K_x, a_x, b_x, psi_vxxs, ux, uy, uxy,uyz,psxz,uxz); + } } } else { /* viscoelastic and elastic ACOUSTIC */ @@ -2201,16 +2338,31 @@ int main(int argc, char **argv){ } } if (WAVETYPE==2 || WAVETYPE==3) { - update_s_visc_PML_SH(1, NX, 1, NY, pvz, psxz, psyz, pt, po, bip, bjm, cip, cjm, d, dip,fipjp, f, hc,infoout, K_x, a_x, b_x, K_x_half, a_x_half, b_x_half, K_y, a_y, b_y, K_y_half, a_y_half, b_y_half,psi_vzx, psi_vzy); + if(VTI){ + update_s_visc_vti_PML_SH(1, NX, 1, NY, pvz, uxz, uyz, psxz, psyz, pt, po, bip, bjm, cip, cjm, d, dip,fipjp, f, hc,infoout, K_x, a_x, b_x, K_x_half, a_x_half, b_x_half, K_y, a_y, b_y, K_y_half, a_y_half, b_y_half,psi_vzx, psi_vzy, pc55,pc66ipjp,prho); + } + else { + update_s_visc_PML_SH(1, NX, 1, NY, pvz, uxz, uyz, psxz, psyz, pt, po, bip, bjm, cip, cjm, d, dip,fipjp, f, hc,infoout, K_x, a_x, b_x, K_x_half, a_x_half, b_x_half, K_y, a_y, b_y, K_y_half, a_y_half, b_y_half,psi_vzx, psi_vzy); + } } } else{ /* elastic */ if(!ACOUSTIC){ if (WAVETYPE==1 || WAVETYPE==3) { - update_s_elastic_PML(1, NX, 1, NY, pvx, pvy, ux, uy, uxy, uyx, psxx, psyy, psxy, ppi, pu, puipjp, absorb_coeff, prho, hc, infoout, K_x, a_x, b_x, K_x_half, a_x_half, b_x_half, K_y, a_y, b_y, K_y_half, a_y_half, b_y_half, psi_vxx, psi_vyy, psi_vxy, psi_vyx); + if (VTI) { + update_s_el_vti_PML(1, NX, 1, NY, pvx, pvy, ux, uy, uxy, uyx, psxx, psyy, psxy, pc11, pc13, pc33, pc55ipjp, absorb_coeff, prho, hc, infoout, K_x, a_x, b_x, K_x_half, a_x_half, b_x_half, K_y, a_y, b_y, K_y_half, a_y_half, b_y_half, psi_vxx, psi_vyy, psi_vxy, psi_vyx); + } + else { + update_s_elastic_PML(1, NX, 1, NY, pvx, pvy, ux, uy, uxy, uyx, psxx, psyy, psxy, ppi, pu, puipjp, absorb_coeff, prho, hc, infoout, K_x, a_x, b_x, K_x_half, a_x_half, b_x_half, K_y, a_y, b_y, K_y_half, a_y_half, b_y_half, psi_vxx, psi_vyy, psi_vxy, psi_vyx); + } } if (WAVETYPE==2 || WAVETYPE==3) { - update_s_elastic_PML_SH(1, NX, 1, NY, pvz,psxz,psyz,uxz,uyz,hc,infoout, K_x, a_x, b_x, K_x_half, a_x_half, b_x_half, K_y, a_y, b_y, K_y_half, a_y_half, b_y_half,psi_vzx, psi_vzy,puipjp,pu,prho); + if (VTI) { + update_s_el_vti_PML_SH(1, NX, 1, NY, pvz,psxz,psyz,uxz,uyz,hc,infoout, K_x, a_x, b_x, K_x_half, a_x_half, b_x_half, K_y, a_y, b_y, K_y_half, a_y_half, b_y_half,psi_vzx, psi_vzy,pc55,pc66ipjp,prho); + } + else { + update_s_elastic_PML_SH(1, NX, 1, NY, pvz,psxz,psyz,uxz,uyz,hc,infoout, K_x, a_x, b_x, K_x_half, a_x_half, b_x_half, K_y, a_y, b_y, K_y_half, a_y_half, b_y_half,psi_vzx, psi_vzy,puipjp,pu,prho); + } } } else { update_p_PML(1, NX, 1, NY, pvx, pvy, psp, u, ppi, absorb_coeff, prho, hc, infoout, K_x, a_x, b_x, K_x_half, a_x_half, b_x_half, K_y, a_y, b_y, K_y_half, a_y_half, b_y_half, psi_vxx, psi_vyy, psi_vxy, psi_vyx); @@ -2229,7 +2381,12 @@ int main(int argc, char **argv){ surface_PML(1, pvx, pvy, psxx, psyy, psxy,psyz, pp, pq, ppi, pu, prho, ptaup, ptaus, etajm, peta, hc, K_x, a_x, b_x, psi_vxxs, ux, uy,uxy,uyz,psxz,uxz); }else{ /* elastic */ - surface_elastic_PML(1, pvx, pvy, psxx, psyy, psxy,psyz, ppi, pu, prho, hc, K_x, a_x, b_x, psi_vxxs, ux, uy, uxy,uyz,psxz,uxz); + if (VTI) { + surface_el_vti_PML(1, pvx, pvy, psxx, psyy, psxy,psyz, pc11, pc13, pc33, prho, hc, K_x, a_x, b_x, psi_vxxs, ux, uy, uxy,uyz,psxz,uxz); + } + else { + surface_elastic_PML(1, pvx, pvy, psxx, psyy, psxy,psyz, ppi, pu, prho, hc, K_x, a_x, b_x, psi_vxxs, ux, uy, uxy,uyz,psxz,uxz); + } } } else { /* viscoelastic and elastic ACOUSTIC */ @@ -2292,9 +2449,15 @@ int main(int argc, char **argv){ } if (WAVETYPE==2 || WAVETYPE==3) { - waveconv_rho_shot_z[j][i]+=(pvzp1[j][i]*forward_prop_rho_z[j][i][NTDTINV-hin+1]); - muss = prho[j][i] * pu[j][i] * pu[j][i]; - waveconv_u_shot_z[j][i]+=(1.0/(muss*muss))*(forward_prop_z_xz[j][i][NTDTINV-hin+1]*psxz[j][i]+forward_prop_z_yz[j][i][NTDTINV-hin+1]*psyz[j][i]); + waveconv_rho_shot_z[j][i]+=(pvzp1[j][i]*forward_prop_rho_z[j][i][NTDTINV-hin+1]); + if (VTI) { + waveconv_c55_shot_z[j][i] += (1.0/(pc55[j][i]*pc55[j][i]))*(forward_prop_z_yz[j][i][NTDTINV-hin+1]*psyz[j][i]); + waveconv_c66_shot_z[j][i] += (1.0/(pc66[j][i]*pc66[j][i]))*(forward_prop_z_xz[j][i][NTDTINV-hin+1]*psxz[j][i]); + } + else { + muss = prho[j][i] * pu[j][i] * pu[j][i]; + waveconv_u_shot_z[j][i]+=(1.0/(muss*muss))*(forward_prop_z_xz[j][i][NTDTINV-hin+1]*psxz[j][i]+forward_prop_z_yz[j][i][NTDTINV-hin+1]*psyz[j][i]); + } } } } @@ -2439,24 +2602,37 @@ int main(int argc, char **argv){ /* interpolate unknown values */ if((IDXI>1)||(IDYI>1)){ interpol(IDXI,IDYI,waveconv_u_shot_z,1); + if (VTI) { + interpol(IDXI,IDYI,waveconv_c55_shot_z,1); + interpol(IDXI,IDYI,waveconv_c66_shot_z,1); + } } /* calculate complete gradient */ for (j=1;j<=NY;j=j+IDY){ for (i=1;i<=NX;i=i+IDX){ - /* calculate mu gradient */ - waveconv_mu_z[j][i] = - DT * waveconv_u_shot_z[j][i]; - - if(PARAMETERIZATION==1){ - /* calculate Vs gradient */ - waveconv_u_shot_z[j][i] = (2.0 * prho[j][i] * pu[j][i] * waveconv_mu_z[j][i]); - } - - if(PARAMETERIZATION==3){ - /* calculate u gradient */ - waveconv_u_shot_z[j][i] = waveconv_mu_z[j][i]; - } + if (VTI) { + waveconv_c55_s_z[j][i] = -DT * waveconv_c55_shot_z[j][i]; + waveconv_c66_s_z[j][i] = -DT * waveconv_c66_shot_z[j][i]; + + waveconv_u_shot_z[j][i] = 2.0*prho[j][i]*pu[j][i]*waveconv_c55_s_z[j][i]; + } + + else { + /* calculate mu gradient */ + waveconv_mu_z[j][i] = - DT * waveconv_u_shot_z[j][i]; + + if(PARAMETERIZATION==1){ + /* calculate Vs gradient */ + waveconv_u_shot_z[j][i] = (2.0 * prho[j][i] * pu[j][i] * waveconv_mu_z[j][i]); + } + + if(PARAMETERIZATION==3){ + /* calculate u gradient */ + waveconv_u_shot_z[j][i] = waveconv_mu_z[j][i]; + } + } } } } @@ -2515,22 +2691,45 @@ int main(int argc, char **argv){ /* calculate density gradient rho' */ waveconv_rho_s_z[j][i]= - DT * waveconv_rho_shot_z[j][i]; - if(PARAMETERIZATION==1){ - /* calculate density gradient */ - waveconv_rho_shot_z[j][i] = ( (pu[j][i] * pu[j][i] * waveconv_mu_z[j][i]) + waveconv_rho_s_z[j][i]); - - } - - if(PARAMETERIZATION==3){ - /* calculate density gradient */ - waveconv_rho_shot_z[j][i] = waveconv_rho_s_z[j][i]; - } + if (VTI) { + waveconv_rho_shot_z[j][i] = pu[j][i]*pu[j][i]*waveconv_c55_s_z[j][i] + pvshor[j][i]*pvshor[j][i]*waveconv_c66_s_z[j][i] + waveconv_rho_s_z[j][i]; + } + + else { + if(PARAMETERIZATION==1){ + /* calculate density gradient */ + waveconv_rho_shot_z[j][i] = ( (pu[j][i] * pu[j][i] * waveconv_mu_z[j][i]) + waveconv_rho_s_z[j][i]); + + } + + if(PARAMETERIZATION==3){ + /* calculate density gradient */ + waveconv_rho_shot_z[j][i] = waveconv_rho_s_z[j][i]; + } + } } } } + /* -------------------------------------------- */ + /* calculate gradient direction horizontal Vs (VTI, SH) */ + /* -------------------------------------------- */ + if (VTI) { + if((WAVETYPE==2 || WAVETYPE==3)&&(FORWARD_ONLY==0)){ + + + for (j=1;j<=NY;j=j+IDY){ + for (i=1;i<=NX;i=i+IDX){ + + waveconv_vshor_shot_z[j][i] = 2.0*prho[j][i]*pvshor[j][i]*waveconv_c66_s_z[j][i]; + } + } + } + } + + /* -------------------------------------------- */ /* calculate and apply energy preconditioning */ /* -------------------------------------------- */ @@ -2566,11 +2765,16 @@ int main(int argc, char **argv){ if(EPRECOND_PER_SHOT_SH && (WAVETYPE==2 || WAVETYPE==3)){ fprintf(FP,"\n Applying approx. Hessian for shot %i SH. EPRECOND=%i, EPSILON_WE=%f",ishot,EPRECOND,EPSILON_WE); + + for (j=1;j<=NY;j=j+IDY){ for (i=1;i<=NX;i=i+IDX){ We_SH[j][i]=We_SH[j][i]/We_max_SH; waveconv_u_shot_z[j][i] = waveconv_u_shot_z[j][i]/(We_SH[j][i]); waveconv_rho_shot_z[j][i] = waveconv_rho_shot_z[j][i]/(We_SH[j][i]); + if (VTI) { + waveconv_vshor_shot_z[j][i] = waveconv_vshor_shot_z[j][i]/(We_SH[j][i]); + } } } } @@ -2594,7 +2798,9 @@ int main(int argc, char **argv){ /* applying the preconditioning */ taper_grad_shot(waveconv_u_shot_z,taper_coeff,srcpos,nsrc,recpos,ntr_glob,ishot,1); taper_grad_shot(waveconv_rho_shot_z,taper_coeff,srcpos,nsrc,recpos,ntr_glob,ishot,1); - + if (VTI) { + taper_grad_shot(waveconv_vshor_shot_z,taper_coeff,srcpos,nsrc,recpos,ntr_glob,ishot,1); + } } /* end of SWS_TAPER_CIRCULAR_PER_SHOT == 1 */ @@ -2604,6 +2810,7 @@ int main(int argc, char **argv){ /* applying the preconditioning */ taper_grad_shot(waveconv_u_shot_z,taper_coeff,srcpos,nsrc,recpos,ntr_glob,ishot,3); /*taper vs gradient */ taper_grad_shot(waveconv_rho_shot_z,taper_coeff,srcpos,nsrc,recpos,ntr_glob,ishot,4); /*taper rho gradient */ + taper_grad_shot(waveconv_vshor_shot_z,taper_coeff,srcpos,nsrc,recpos,ntr_glob,ishot,5); /*taper vshor gradient */ } } @@ -2657,12 +2864,25 @@ int main(int argc, char **argv){ /* Summing up the gradient for all shots SH */ /* ----------------------------------------- */ if (WAVETYPE==2 || WAVETYPE==3) { - for (j=1;j<=NY;j=j+IDY){ - for (i=1;i<=NX;i=i+IDX){ - waveconv_u_z[j][i] += waveconv_u_shot_z[j][i]; - waveconv_rho_z[j][i] += waveconv_rho_shot_z[j][i]; - } - } + if (VTI) { + + + for (j=1;j<=NY;j=j+IDY){ + for (i=1;i<=NX;i=i+IDX){ + waveconv_u_z[j][i] += waveconv_u_shot_z[j][i]; + waveconv_rho_z[j][i] += waveconv_rho_shot_z[j][i]; + waveconv_vshor_z[j][i] += waveconv_vshor_shot_z[j][i]; + } + } + } + else{ + for (j=1;j<=NY;j=j+IDY){ + for (i=1;i<=NX;i=i+IDX){ + waveconv_u_z[j][i] += waveconv_u_shot_z[j][i]; + waveconv_rho_z[j][i] += waveconv_rho_shot_z[j][i]; + } + } + } } } @@ -2699,6 +2919,7 @@ int main(int argc, char **argv){ } } + if(!EPRECOND_PER_SHOT_SH && (WAVETYPE==2 || WAVETYPE==3)){ fprintf(FP,"\n Applying approx. Hessian to summed gradient SH. EPRECOND=%i, EPSILON_WE=%f",EPRECOND,EPSILON_WE); @@ -2708,6 +2929,9 @@ int main(int argc, char **argv){ We_sum_SH[j][i]=We_sum_SH[j][i]/We_sum_max1; waveconv_u_z[j][i] = waveconv_u_z[j][i]*We_sum_SH[j][i]; waveconv_rho_z[j][i] = waveconv_rho_z[j][i]*We_sum_SH[j][i]; + if (VTI) { + waveconv_vshor_z[j][i] = waveconv_vshor_z[j][i]*We_sum_SH[j][i]; + } } } } @@ -2740,6 +2964,9 @@ int main(int argc, char **argv){ for (i=1;i<=NX;i=i+IDX){ if(iter2 && WOLFE_TRY_OLD_STEPLENGTH) alpha_SL=alpha_SL_old; /* Calculate update */ - calc_mat_change_test(waveconv_up,waveconv_rho_up,waveconv_u_up,prhonp1,prho,ppinp1,ppi,punp1,pu,iter,1,FORWARD_ONLY,alpha_SL,1,nfstart,Vs0,Vp0,Rho0,wavetype_start,s_LBFGS,N_LBFGS,LBFGS_NPAR,Vs_avg,Vp_avg,rho_avg,LBFGS_iter_start); - FWI_run=1; + if (VTI) { + calc_mat_change_test_vti(waveconv_up,waveconv_rho_up,waveconv_u_up,waveconv_vshor_up,prhonp1,prho,ppinp1,ppi,punp1,pu,pvshornp1,pvshor,iter,1,FORWARD_ONLY,alpha_SL,1,nfstart,Vs0,Vp0,Rho0,wavetype_start,s_LBFGS,N_LBFGS,LBFGS_NPAR,Vs_avg,Vp_avg,rho_avg,vshor_avg,LBFGS_iter_start); + } + else { + calc_mat_change_test(waveconv_up,waveconv_rho_up,waveconv_u_up,prhonp1,prho,ppinp1,ppi,punp1,pu,iter,1,FORWARD_ONLY,alpha_SL,1,nfstart,Vs0,Vp0,Rho0,wavetype_start,s_LBFGS,N_LBFGS,LBFGS_NPAR,Vs_avg,Vp_avg,rho_avg,LBFGS_iter_start); + } + FWI_run=1; } /* Check if current step length satisfy wolfe condition, if not call linesearch for new step length */ if(countstep>0) { - wolfe_status=check_wolfe(alpha_SL, L2_SL_old, L2_SL_new, waveconv_u_old, waveconv_u, waveconv_u_up,waveconv_rho_old, waveconv_rho, waveconv_rho_up,waveconv_old, waveconv, waveconv_up, c1_SL, c2_SL,LBFGS_NPAR); + wolfe_status=check_wolfe(alpha_SL, L2_SL_old, L2_SL_new, waveconv_u_old, waveconv_u, waveconv_u_up,waveconv_rho_old, waveconv_rho, waveconv_rho_up,waveconv_old, waveconv, waveconv_up, waveconv_vshor_old, waveconv_vshor_z, waveconv_vshor_up, c1_SL, c2_SL,LBFGS_NPAR); if(wolfe_status==0) { /* Current step length satisfy wolfe condition, abort step length search */ @@ -3067,8 +3337,13 @@ int main(int argc, char **argv){ /* Current step length do not satisfy wolfe condition, try new step length */ wolfe_linesearch(wolfe_status, &alpha_SL_min, &alpha_SL_max, &alpha_SL); - calc_mat_change_test(waveconv_up,waveconv_rho_up,waveconv_u_up,prhonp1,prho,ppinp1,ppi,punp1,pu,iter,1,FORWARD_ONLY,alpha_SL,1,nfstart,Vs0,Vp0,Rho0,wavetype_start,s_LBFGS,N_LBFGS,LBFGS_NPAR,Vs_avg,Vp_avg,rho_avg,LBFGS_iter_start); - fprintf(FP,"; New steplength=%1.3f",alpha_SL); + if (VTI) { + calc_mat_change_test_vti(waveconv_up,waveconv_rho_up,waveconv_u_up,waveconv_vshor_up,prhonp1,prho,ppinp1,ppi,punp1,pu,pvshornp1,pvshor,iter,1,FORWARD_ONLY,alpha_SL,1,nfstart,Vs0,Vp0,Rho0,wavetype_start,s_LBFGS,N_LBFGS,LBFGS_NPAR,Vs_avg,Vp_avg,rho_avg,vshor_avg,LBFGS_iter_start); + } + else { + calc_mat_change_test(waveconv_up,waveconv_rho_up,waveconv_u_up,prhonp1,prho,ppinp1,ppi,punp1,pu,iter,1,FORWARD_ONLY,alpha_SL,1,nfstart,Vs0,Vp0,Rho0,wavetype_start,s_LBFGS,N_LBFGS,LBFGS_NPAR,Vs_avg,Vp_avg,rho_avg,LBFGS_iter_start); + } + fprintf(FP,"; New steplength=%1.3f",alpha_SL); FWI_run=1; } @@ -3097,8 +3372,12 @@ int main(int argc, char **argv){ /* No update is done here, however model fils are written to disk for easy post processing */ alpha_SL=0.0; - calc_mat_change_test(waveconv_up,waveconv_rho_up,waveconv_u_up,prhonp1,prho,ppinp1,ppi,punp1,pu,iter,1,FORWARD_ONLY,alpha_SL,0,nfstart,Vs0,Vp0,Rho0,wavetype_start,s_LBFGS,N_LBFGS,LBFGS_NPAR,Vs_avg,Vp_avg,rho_avg,LBFGS_iter_start); - + if (VTI) { + calc_mat_change_test_vti(waveconv_up,waveconv_rho_up,waveconv_u_up,waveconv_vshor_up,prhonp1,prho,ppinp1,ppi,punp1,pu,pvshornp1,pvshor,iter,1,FORWARD_ONLY,alpha_SL,0,nfstart,Vs0,Vp0,Rho0,wavetype_start,s_LBFGS,N_LBFGS,LBFGS_NPAR,Vs_avg,Vp_avg,rho_avg,vshor_avg,LBFGS_iter_start); + } + else { + calc_mat_change_test(waveconv_up,waveconv_rho_up,waveconv_u_up,prhonp1,prho,ppinp1,ppi,punp1,pu,iter,1,FORWARD_ONLY,alpha_SL,0,nfstart,Vs0,Vp0,Rho0,wavetype_start,s_LBFGS,N_LBFGS,LBFGS_NPAR,Vs_avg,Vp_avg,rho_avg,LBFGS_iter_start); + } alpha_SL_old=1; /* If minimum number of iterations would be enforced, L-BFGS is likely to crash */ @@ -3118,13 +3397,19 @@ int main(int argc, char **argv){ for (i=1;i<=NX;i=i+IDX){ prho[j][i]=prhonp1[j][i]; if(WAVETYPE!=2) ppi[j][i]=ppinp1[j][i]; + else if (VTI) pvshor[j][i]=pvshornp1[j][i]; if(!ACOUSTIC) pu[j][i]=punp1[j][i]; } } /* do the final model update */ - calc_mat_change_test(waveconv_up,waveconv_rho_up,waveconv_u_up,prhonp1,prho,ppinp1,ppi,punp1,pu,iter,1,FORWARD_ONLY,alpha_SL,0,nfstart,Vs0,Vp0,Rho0,wavetype_start,s_LBFGS,N_LBFGS,LBFGS_NPAR,Vs_avg,Vp_avg,rho_avg,LBFGS_iter_start); - + if (VTI) { + calc_mat_change_test_vti(waveconv_up,waveconv_rho_up,waveconv_u_up,waveconv_vshor_up,prhonp1,prho,ppinp1,ppi,punp1,pu,pvshornp1,pvshor,iter,1,FORWARD_ONLY,alpha_SL,0,nfstart,Vs0,Vp0,Rho0,wavetype_start,s_LBFGS,N_LBFGS,LBFGS_NPAR,Vs_avg,Vp_avg,rho_avg,vshor_avg,LBFGS_iter_start); + } + else{ + calc_mat_change_test(waveconv_up,waveconv_rho_up,waveconv_u_up,prhonp1,prho,ppinp1,ppi,punp1,pu,iter,1,FORWARD_ONLY,alpha_SL,0,nfstart,Vs0,Vp0,Rho0,wavetype_start,s_LBFGS,N_LBFGS,LBFGS_NPAR,Vs_avg,Vp_avg,rho_avg,LBFGS_iter_start); + } + L2_hist[iter]=L2t[4]; /* write L2 log file */ @@ -3211,13 +3496,21 @@ int main(int argc, char **argv){ for (itest=itests;itest<=iteste;itest++){ /* calculate change in the material parameters */ - calc_mat_change_test(waveconv,waveconv_rho,waveconv_u,prho,prhonp1,ppi,ppinp1,pu,punp1,iter,1,FORWARD_ONLY,eps_scale,1,nfstart,Vs0,Vp0,Rho0,wavetype_start,s_LBFGS,N_LBFGS,LBFGS_NPAR,Vs_avg,Vp_avg,rho_avg,LBFGS_iter_start); - + if (VTI) { + calc_mat_change_test_vti(waveconv,waveconv_rho,waveconv_u,waveconv_vshor_z,prho,prhonp1,ppi,ppinp1,pu,punp1,pvshor,pvshornp1,iter,1,FORWARD_ONLY,eps_scale,1,nfstart,Vs0,Vp0,Rho0,wavetype_start,s_LBFGS,N_LBFGS,LBFGS_NPAR,Vs_avg,Vp_avg,rho_avg,vshor_avg,LBFGS_iter_start); + } + else { + calc_mat_change_test(waveconv,waveconv_rho,waveconv_u,prho,prhonp1,ppi,ppinp1,pu,punp1,iter,1,FORWARD_ONLY,eps_scale,1,nfstart,Vs0,Vp0,Rho0,wavetype_start,s_LBFGS,N_LBFGS,LBFGS_NPAR,Vs_avg,Vp_avg,rho_avg,LBFGS_iter_start); + } /* For the calculation of the material parameters beteween gridpoints the have to be averaged. For this, values lying at 0 and NX+1, for example, are required on the local grid. These are now copied from the neighbouring grids */ if(!ACOUSTIC) { + if (VTI) { + change_parameterization_vti(prhonp1,ppinp1,punp1,pepsilon,pdelta,pvshornp1,pc11,pc13,pc33,pc55,pc66 ); + matcopy_elastic_vti(prhonp1,pc11,pc13,pc33,pc55,pc66); + } matcopy_elastic(prhonp1, ppinp1, punp1); /* no differentiation of elastic and viscoelastic modelling because the viscoelastic parameters did not change during the forward modelling */ }else{ matcopy_acoustic(prhonp1, ppinp1); @@ -3227,11 +3520,19 @@ int main(int argc, char **argv){ if(!ACOUSTIC) av_mue(punp1,puipjp,prhonp1); av_rho(prhonp1,prip,prjp); - + if (VTI) { + av_c55c66(pc55,pc55ipjp,pc66,pc66ipjp); + } + /* Preparing memory variables for update_s (viscoelastic) */ if (L) { if(!ACOUSTIC) { - prepare_update_s(etajm,etaip,peta,fipjp,punp1,puipjp,ppinp1,prhonp1,ptaus,ptaup,ptausipjp,f,g, bip,bjm,cip,cjm,dip,d,e); + if(VTI){ + prepare_update_s_vti(etajm,etaip,peta,fipjp,pc55,pc66ipjp,ppinp1,prhonp1,ptaus,ptaup,ptausipjp,f,g,bip,bjm,cip,cjm,dip,d,e); + } + else { + prepare_update_s(etajm,etaip,peta,fipjp,punp1,puipjp,ppinp1,prhonp1,ptaus,ptaup,ptausipjp,f,g, bip,bjm,cip,cjm,dip,d,e); + } }else{ prepare_update_p(etajm,peta,ppinp1,prhonp1,ptaup,g,bjm,cjm,e); } @@ -3416,7 +3717,12 @@ int main(int argc, char **argv){ } } if (WAVETYPE==2 || WAVETYPE==3) { - update_s_visc_PML_SH(1, NX, 1, NY, pvz, psxz, psyz, pt, po, bip, bjm, cip, cjm, d, dip,fipjp, f, hc,infoout, K_x, a_x, b_x, K_x_half, a_x_half, b_x_half, K_y, a_y, b_y, K_y_half, a_y_half, b_y_half,psi_vzx, psi_vzy); + if(VTI){ + update_s_visc_vti_PML_SH(1, NX, 1, NY, pvz, uxz, uyz, psxz, psyz, pt, po, bip, bjm, cip, cjm, d, dip,fipjp, f, hc,infoout, K_x, a_x, b_x, K_x_half, a_x_half, b_x_half, K_y, a_y, b_y, K_y_half, a_y_half, b_y_half,psi_vzx, psi_vzy, pc55,pc66ipjp,prho); + } + else { + update_s_visc_PML_SH(1, NX, 1, NY, pvz, uxz, uyz, psxz, psyz, pt, po, bip, bjm, cip, cjm, d, dip,fipjp, f, hc,infoout, K_x, a_x, b_x, K_x_half, a_x_half, b_x_half, K_y, a_y, b_y, K_y_half, a_y_half, b_y_half,psi_vzx, psi_vzy); + } } } else { /* elastic */ if(!ACOUSTIC){ @@ -3424,8 +3730,13 @@ int main(int argc, char **argv){ update_s_elastic_PML(1, NX, 1, NY, pvx, pvy, ux, uy, uxy, uyx, psxx, psyy, psxy, ppinp1, punp1, puipjp, absorb_coeff, prhonp1, hc, infoout, K_x, a_x, b_x, K_x_half, a_x_half, b_x_half, K_y, a_y, b_y, K_y_half, a_y_half, b_y_half, psi_vxx, psi_vyy, psi_vxy, psi_vyx); } if (WAVETYPE==2 || WAVETYPE==3) { - update_s_elastic_PML_SH(1, NX, 1, NY, pvz,psxz,psyz,uxz,uyz,hc,infoout, K_x, a_x, b_x, K_x_half, a_x_half, b_x_half, K_y, a_y, b_y, K_y_half, a_y_half, b_y_half,psi_vzx, psi_vzy,puipjp,punp1,prhonp1); - } + if (VTI) { + update_s_el_vti_PML_SH(1, NX, 1, NY, pvz,psxz,psyz,uxz,uyz,hc,infoout, K_x, a_x, b_x, K_x_half, a_x_half, b_x_half, K_y, a_y, b_y, K_y_half, a_y_half, b_y_half,psi_vzx, psi_vzy,pc55,pc66ipjp,prhonp1); + } + else { + update_s_elastic_PML_SH(1, NX, 1, NY, pvz,psxz,psyz,uxz,uyz,hc,infoout, K_x, a_x, b_x, K_x_half, a_x_half, b_x_half, K_y, a_y, b_y, K_y_half, a_y_half, b_y_half,psi_vzx, psi_vzy,puipjp,punp1,prhonp1); + } + } } else /* acoustic */ update_p_PML(1, NX, 1, NY, pvx, pvy, psp, u, ppinp1, absorb_coeff, prhonp1, hc, infoout, K_x, a_x, b_x, K_x_half, a_x_half, b_x_half, K_y, a_y, b_y, K_y_half, a_y_half, b_y_half, psi_vxx, psi_vyy, psi_vxy, psi_vyx); @@ -3449,8 +3760,13 @@ int main(int argc, char **argv){ surface_PML(1, pvx, pvy, psxx, psyy, psxy,psyz, pp, pq, ppinp1, punp1, prhonp1, ptaup, ptaus, etajm, peta, hc, K_x, a_x, b_x, psi_vxxs, ux, uy,uxy,uyz,psxz,uxz); }else{ /* elastic */ - surface_elastic_PML(1, pvx, pvy, psxx, psyy, psxy,psyz, ppinp1, punp1, prhonp1, hc, K_x, a_x, b_x, psi_vxxs, ux, uy, uxy,uyz,psxz,uxz); - } + if (VTI) { + surface_el_vti_PML(1, pvx, pvy, psxx, psyy, psxy,psyz, pc11, pc13, pc33, prhonp1, hc, K_x, a_x, b_x, psi_vxxs, ux, uy, uxy,uyz,psxz,uxz); + } + else { + surface_elastic_PML(1, pvx, pvy, psxx, psyy, psxy,psyz, ppinp1, punp1, prhonp1, hc, K_x, a_x, b_x, psi_vxxs, ux, uy, uxy,uyz,psxz,uxz); + } + } } else { /* viscoelastic and elastic ACOUSTIC */ surface_acoustic_PML(1, psp); @@ -3621,25 +3937,42 @@ int main(int argc, char **argv){ if(ADJOINT_TYPE==1){ /* x and y component are used in the inversion */ L2t[itest]=2.0*(1.0+(L2sum/((float)((NO_OF_TESTSHOTS*ntr_glob-sum_killed_traces_testshots)*2.0)))); if (MYID==0){ - printf("sum_killed_traces_testshots=%d\n",sum_killed_traces_testshots);}} + printf("sum_killed_traces_testshots=%d\n",sum_killed_traces_testshots);} + } else{ - L2t[itest]=2.0*(1.0+(L2sum/((float)(NO_OF_TESTSHOTS*ntr_glob-sum_killed_traces_testshots)))); - if (MYID==0){ - printf("sum_killed_traces_testshots=%d\n",sum_killed_traces_testshots); - printf("ntr_glob=%d\n",ntr_glob); - printf("NO_OF_TESTSHOTS=%d\n",NO_OF_TESTSHOTS);}}} + L2t[itest]=2.0*(1.0+(L2sum/((float)(NO_OF_TESTSHOTS*ntr_glob-sum_killed_traces_testshots)))); + if (MYID==0){ + printf("sum_killed_traces_testshots=%d\n",sum_killed_traces_testshots); + printf("ntr_glob=%d\n",ntr_glob); + printf("NO_OF_TESTSHOTS=%d\n",NO_OF_TESTSHOTS);} + } + if(WAVETYPE==2){ + L2t[itest]=2.0*(1.0+(L2sum_SH/((float)((NO_OF_TESTSHOTS*ntr_glob-sum_killed_traces_testshots))))); + } + } else{ if(ADJOINT_TYPE==1){ /* x and y component are used in the inversion */ L2t[itest]=2.0*(1.0+(L2sum/((float)NO_OF_TESTSHOTS*(float)ntr_glob*2.0)));} else{ - L2t[itest]=2.0*(1.0+(L2sum/((float)NO_OF_TESTSHOTS*(float)ntr_glob)));} + if (WAVETYPE==1 || WAVETYPE==3) { + L2t[itest]=2.0*(1.0+(L2sum/((float)NO_OF_TESTSHOTS*(float)ntr_glob))); + } + } + if (WAVETYPE==2) { + L2t[itest]=2.0*(1.0+(L2sum_SH/((float)NO_OF_TESTSHOTS*(float)ntr_glob))); + } } break; case 8: L2t[itest]=L2sum/energy_sum; break; default: - L2t[itest]=L2sum; + if ((WAVETYPE==1) || (WAVETYPE==3)) { + L2t[itest]=L2sum; + } + if (WAVETYPE==2) { + L2t[itest]=L2sum_SH; + } break; } @@ -3819,8 +4152,15 @@ int main(int argc, char **argv){ /* -----------------------------------------------------------------------*/ /* ----------- Do the actual update to the material parameters -----------*/ /* -----------------------------------------------------------------------*/ - calc_mat_change_test(waveconv,waveconv_rho,waveconv_u,prho,prhonp1,ppi,ppinp1,pu,punp1,iter,1,FORWARD_ONLY,eps_scale,0,nfstart,Vs0,Vp0,Rho0,wavetype_start,s_LBFGS,N_LBFGS,LBFGS_NPAR,Vs_avg,Vp_avg,rho_avg,LBFGS_iter_start); - fprintf(FP,"=================================================================================================\n"); + + if (VTI) { + calc_mat_change_test_vti(waveconv,waveconv_rho,waveconv_u,waveconv_vshor_z,prho,prhonp1,ppi,ppinp1,pu,punp1,pvshor,pvshornp1,iter,1,FORWARD_ONLY,eps_scale,0,nfstart,Vs0,Vp0,Rho0,wavetype_start,s_LBFGS,N_LBFGS,LBFGS_NPAR,Vs_avg,Vp_avg,rho_avg,vshor_avg,LBFGS_iter_start); + } + else { + calc_mat_change_test(waveconv,waveconv_rho,waveconv_u,prho,prhonp1,ppi,ppinp1,pu,punp1,iter,1,FORWARD_ONLY,eps_scale,0,nfstart,Vs0,Vp0,Rho0,wavetype_start,s_LBFGS,N_LBFGS,LBFGS_NPAR,Vs_avg,Vp_avg,rho_avg,LBFGS_iter_start); + } + + fprintf(FP,"=================================================================================================\n"); } /* end of if(FORWARD_ONLY!=4) */ @@ -3830,6 +4170,11 @@ int main(int argc, char **argv){ if (FORWARD_ONLY==0 && (opteps_vp>0.0 || WOLFE_CONDITION)){ if(!ACOUSTIC){ if(WAVETYPE==1||WAVETYPE==3) if(MODEL_FILTER)smooth(ppi,4,2,Vs_avg,F_LOW_PASS); + if(WAVETYPE==2||WAVETYPE==3) { + if (VTI) { + if(MODEL_FILTER)smooth(pvshor,8,2,vshor_avg,F_LOW_PASS); + } + } if(MODEL_FILTER)smooth(pu,5,2,Vs_avg,F_LOW_PASS); if(MODEL_FILTER)smooth(prho,6,2,Vs_avg,F_LOW_PASS); }else{ @@ -4085,6 +4430,10 @@ int main(int argc, char **argv){ free_matrix(uttx,-nd+1,NY+nd,-nd+1,NX+nd); free_matrix(utty,-nd+1,NY+nd,-nd+1,NX+nd); } + if (WAVETYPE==2 || WAVETYPE==3) { + free_matrix(uxz,-nd+1,NY+nd,-nd+1,NX+nd); + free_matrix(uyz,-nd+1,NY+nd,-nd+1,NX+nd); + } } free_matrix(Vp0,-nd+1,NY+nd,-nd+1,NX+nd); if(!ACOUSTIC) @@ -4128,6 +4477,25 @@ int main(int argc, char **argv){ free_vector(cip,1,L); free_vector(cjm,1,L); } + + /* free memory for anisotropic modeling variables */ + if (VTI) { + free_matrix ( pc11, -nd + 1, NY + nd, -nd + 1, NX + nd ); + free_matrix ( pc13, -nd + 1, NY + nd, -nd + 1, NX + nd ); + free_matrix ( pc33, -nd + 1, NY + nd, -nd + 1, NX + nd ); + free_matrix ( pc55, -nd + 1, NY + nd, -nd + 1, NX + nd ); + free_matrix ( pc55ipjp, -nd + 1, NY + nd, -nd + 1, NX + nd ); + free_matrix ( pc66, -nd + 1, NY + nd, -nd + 1, NX + nd ); + free_matrix ( pc66ipjp, -nd + 1, NY + nd, -nd + 1, NX + nd ); + free_matrix ( pdelta, -nd+1,NY+nd,-nd+1,NX+nd); + free_matrix ( pepsilon, -nd+1,NY+nd,-nd+1,NX+nd); + if (WAVETYPE==2 || WAVETYPE==3) { + free_matrix ( pgamma, -nd+1,NY+nd,-nd+1,NX+nd); + free_matrix ( pvshornp1, -nd+1,NY+nd,-nd+1,NX+nd); + } + free_matrix (pvshor, -nd+1,NY+nd,-nd+1,NX+nd); + } + if(FORWARD_ONLY==0){ free_matrix(waveconv,-nd+1,NY+nd,-nd+1,NX+nd); free_matrix(waveconv_lam,-nd+1,NY+nd,-nd+1,NX+nd); @@ -4301,11 +4669,17 @@ int main(int argc, char **argv){ if(WOLFE_CONDITION){ free_matrix(waveconv_old,-nd+1,NY+nd,-nd+1,NX+nd); - if(!ACOUSTIC) free_matrix(waveconv_u_old,-nd+1,NY+nd,-nd+1,NX+nd); + if(!ACOUSTIC){ + free_matrix(waveconv_u_old,-nd+1,NY+nd,-nd+1,NX+nd); + free_matrix(waveconv_vshor_old,-nd+1,NY+nd,-nd+1,NX+nd); + } free_matrix(waveconv_rho_old,-nd+1,NY+nd,-nd+1,NX+nd); free_matrix(waveconv_up,-nd+1,NY+nd,-nd+1,NX+nd); - if(!ACOUSTIC) free_matrix(waveconv_u_up,-nd+1,NY+nd,-nd+1,NX+nd); + if(!ACOUSTIC){ + free_matrix(waveconv_u_up,-nd+1,NY+nd,-nd+1,NX+nd); + free_matrix(waveconv_vshor_up,-nd+1,NY+nd,-nd+1,NX+nd); + } free_matrix(waveconv_rho_up,-nd+1,NY+nd,-nd+1,NX+nd); } @@ -4317,7 +4691,16 @@ int main(int argc, char **argv){ free_matrix(waveconv_u_shot_z,-nd+1,NY+nd,-nd+1,NX+nd); free_matrix(waveconv_mu_z,-nd+1,NY+nd,-nd+1,NX+nd); free_matrix(waveconv_rho_s_z,-nd+1,NY+nd,-nd+1,NX+nd); - free_matrix(waveconv_u_z,-nd+1,NY+nd,-nd+1,NX+nd); + if (VTI) { + free_matrix (waveconv_c55_shot_z, -nd+1,NY+nd,-nd+1,NX+nd); + free_matrix (waveconv_c66_shot_z, -nd+1,NY+nd,-nd+1,NX+nd); + free_matrix (waveconv_c55_s_z, -nd+1,NY+nd,-nd+1,NX+nd); + free_matrix (waveconv_c66_s_z, -nd+1,NY+nd,-nd+1,NX+nd); + free_matrix (waveconv_vshor_shot_z, -nd+1,NY+nd,-nd+1,NX+nd); + free_matrix (waveconv_vshor_z, -nd+1,NY+nd,-nd+1,NX+nd); + free_matrix (gradp_vshor_z,-nd+1,NY+nd,-nd+1,NX+nd); + } + free_matrix(waveconv_u_z,-nd+1,NY+nd,-nd+1,NX+nd); free_matrix(waveconv_rho_z,-nd+1,NY+nd,-nd+1,NX+nd); free_matrix(gradp_u_z,-nd+1,NY+nd,-nd+1,NX+nd); free_matrix(gradp_rho_z,-nd+1,NY+nd,-nd+1,NX+nd); diff --git a/src/LBFGS.c b/src/LBFGS.c index bfc35ff367024d7a00a750d9b6472b0afd49ecf6..859fcacb3c2ccfa62fa79555aadb36425fc33498 100644 --- a/src/LBFGS.c +++ b/src/LBFGS.c @@ -25,14 +25,14 @@ void lbfgs_reset(int iter, int N_LBFGS, int NPAR_LBFGS,float ** s_LBFGS1, float ** y_LBFGS1, float * rho_LBFGS1); void lbfgs_core(int iteration, int N_LBFGS, int NPAR_LBFGS,float ** s_LBFGS, float ** y_LBFGS, float * rho_LBFGS,float *q_LBFGS,float *alpha_LBFGS,float *r_LBFGS); -void lbfgs(float **grad_vs, float **grad_rho, float **grad_vp,float Vs_avg,float rho_avg,float Vp_avg, float *rho_LBFGS, float **s_LBFGS, float **y_LBFGS,int N_LBFGS,int NPAR_LBFGS, int iteration, int *LBFGS_iter_start){ +void lbfgs(float **grad_vs, float **grad_rho, float **grad_vp, float **grad_vshor, float Vs_avg,float rho_avg,float Vp_avg, float Vshor_avg, float *rho_LBFGS, float **s_LBFGS, float **y_LBFGS,int N_LBFGS,int NPAR_LBFGS, int iteration, int *LBFGS_iter_start){ /* global */ extern int NX,NY,MYID; extern FILE *FP; extern int POS[3]; extern char JACOBIAN[STRING_SIZE]; - extern int WAVETYPE; + extern int WAVETYPE, VTI; extern int ACOUSTIC; extern float LBFGS_SCALE_GRADIENTS; @@ -61,6 +61,11 @@ void lbfgs(float **grad_vs, float **grad_rho, float **grad_vp,float Vs_avg,float write_matrix_disk(grad_vp, jac); } + if(WAVETYPE==2 && VTI) { + sprintf(jac,"%s_grad1_vshor_it%d",JACOBIAN,iteration); + write_matrix_disk(grad_vshor, jac); + } + /*---------------------*/ /* Experimental */ /*---------------------*/ @@ -76,7 +81,8 @@ void lbfgs(float **grad_vs, float **grad_rho, float **grad_vp,float Vs_avg,float for (j=1;j<=NY;j++){ if(!ACOUSTIC) grad_vs[j][i]=grad_vs[j][i]*LBFGS_SCALE_GRADIENTS; if(NPAR_LBFGS>1) grad_rho[j][i]=grad_rho[j][i]*LBFGS_SCALE_GRADIENTS; - if(NPAR_LBFGS>2) grad_vp[j][i]=grad_vp[j][i]*LBFGS_SCALE_GRADIENTS; + if(NPAR_LBFGS>2 && WAVETYPE!=2) grad_vp[j][i]=grad_vp[j][i]*LBFGS_SCALE_GRADIENTS; + if(NPAR_LBFGS>2 && VTI) grad_vshor[j][i]=grad_vshor[j][i]*LBFGS_SCALE_GRADIENTS; } } } @@ -94,7 +100,10 @@ void lbfgs(float **grad_vs, float **grad_rho, float **grad_vp,float Vs_avg,float l++; if(!ACOUSTIC) y_LBFGS[w][l]=-grad_vs[j][i]*Vs_avg; /* VS */ if(NPAR_LBFGS>1) y_LBFGS[w][l+NX*NY]=-grad_rho[j][i]*rho_avg; /* RHO */ - if(NPAR_LBFGS>2) y_LBFGS[w][l+2*NX*NY]=-grad_vp[j][i]*Vp_avg; /* VP */ + if(NPAR_LBFGS>2){ + if(WAVETYPE!=2) y_LBFGS[w][l+2*NX*NY]=-grad_vp[j][i]*Vp_avg; /* VP */ + else if(VTI) y_LBFGS[w][l+2*NX*NY]=-grad_vshor[j][i]*Vshor_avg; /* VS HORIZONTAL (VTI) */ + } } } } @@ -141,8 +150,14 @@ void lbfgs(float **grad_vs, float **grad_rho, float **grad_vp,float Vs_avg,float /* VP */ if(NPAR_LBFGS>2) { - y_LBFGS[w][l+2*NY*NX]+=grad_vp[j][i]*Vp_avg; /* add grad(i) to build grad(i)-grad(i-1) */ - q_LBFGS[l+2*NY*NX]=grad_vp[j][i]*Vp_avg; /* Normalisation */ + if (WAVETYPE!=2) { + y_LBFGS[w][l+2*NY*NX]+=grad_vp[j][i]*Vp_avg; /* add grad(i) to build grad(i)-grad(i-1) */ + q_LBFGS[l+2*NY*NX]=grad_vp[j][i]*Vp_avg; /* Normalisation */ + } + else if (VTI) { + y_LBFGS[w][l+2*NY*NX]+=grad_vshor[j][i]*Vshor_avg; /* add grad(i) to build grad(i)-grad(i-1) */ + q_LBFGS[l+2*NY*NX]=grad_vshor[j][i]*Vshor_avg; /* Normalisation */ + } } /* Debugging */ @@ -194,8 +209,14 @@ void lbfgs(float **grad_vs, float **grad_rho, float **grad_vp,float Vs_avg,float /* VP */ if(NPAR_LBFGS>2) { - y_LBFGS[w][l+2*NY*NX]=-grad_vp[j][i]*Vp_avg; /* add -grad(i-1) to build grad(i)-grad(i-1) */ - grad_vp[j][i]=r_LBFGS[l+2*NY*NX]*Vp_avg; /* Denormalization */ + if (WAVETYPE!=2) { + y_LBFGS[w][l+2*NY*NX]=-grad_vp[j][i]*Vp_avg; /* add -grad(i-1) to build grad(i)-grad(i-1) */ + grad_vp[j][i]=r_LBFGS[l+2*NY*NX]*Vp_avg; /* Denormalization */ + } + else if (VTI) { + y_LBFGS[w][l+2*NY*NX]=-grad_vshor[j][i]*Vshor_avg; /* add -grad(i-1) to build grad(i)-grad(i-1) */ + grad_vshor[j][i]=r_LBFGS[l+2*NY*NX]*Vshor_avg; /* Denormalization */ + } } } } @@ -221,6 +242,11 @@ void lbfgs(float **grad_vs, float **grad_rho, float **grad_vp,float Vs_avg,float sprintf(jac,"%s_grad2_vp_it%d",JACOBIAN,iteration); write_matrix_disk(grad_vp, jac); } + + if(WAVETYPE==2 && VTI) { + sprintf(jac,"%s_grad2_vshor_it%d",JACOBIAN,iteration); + write_matrix_disk(grad_vshor, jac); + } } void lbfgs_core(int iteration, int N_LBFGS, int NPAR_LBFGS,float ** s_LBFGS, float ** y_LBFGS, float * rho_LBFGS,float *q_LBFGS,float *alpha_LBFGS,float *r_LBFGS) { diff --git a/src/Makefile b/src/Makefile index fc6788810ac199eca464902a6cc5a3960bd0d6d9..1826acf8779970bf0c54cf5a311a2bc77f64ccf2 100644 --- a/src/Makefile +++ b/src/Makefile @@ -9,6 +9,7 @@ MODEL = ../genmod/1D_linear_gradient_visc.c MODEL_AC = ../genmod/1D_linear_gradient_ac.c MODEL_EL = ../genmod/1D_linear_gradient_el.c +MODEL_EL_VTI = ../genmod/1D_linear_gradient_el_vti.c MODEL_VAC = ../genmod/1D_linear_gradient_viscac.c EXEC= ../bin @@ -72,10 +73,12 @@ IFOS2D= \ window_cos.c \ alloc_sections.c \ calc_mat_change_test.c \ + calc_mat_change_test_vti.c \ calc_res.c \ calc_misfit.c \ calc_opt_step.c \ calc_energy.c \ + change_parameterization_vti.c \ checkfd.c \ checkfd_ssg_elastic.c \ checkfd_ssg_visc.c \ @@ -91,6 +94,7 @@ IFOS2D= \ snap_ssg_SH.c \ seismo_ssg.c \ surface_elastic_PML.c \ + surface_el_vti_PML.c \ surface_acoustic_PML.c \ surface_PML.c \ update_v_ssg.c \ @@ -98,15 +102,20 @@ IFOS2D= \ update_v_PML_SH.c \ update_v_acoustic_PML.c \ prepare_update_s.c \ + prepare_update_s_vti.c \ update_p_PML.c \ update_s_elastic_ssg.c \ update_s_elastic_PML.c \ + update_s_el_vti_PML.c \ update_s_elastic_PML_SH.c \ + update_s_el_vti_PML_SH.c \ update_s_visc_PML.c \ update_s_visc_PML_SH.c \ + update_s_visc_vti_PML_SH.c \ av_mue.c \ av_rho.c \ av_tau.c \ + av_c55c66.c \ median2D.c \ exchange_par.c \ info.c \ @@ -120,9 +129,12 @@ IFOS2D= \ $(MODEL) \$(MODEL_AC) \ $(MODEL_EL) \ +$(MODEL_EL_VTI) \ \$(MODEL_VAC) \ matcopy.c \ + matcopy_vti.c \ matcopy_elastic.c \ + matcopy_elastic_vti.c \ matcopy_acoustic.c \ mergemod.c \ max_grad.c \ @@ -134,11 +146,14 @@ IFOS2D= \ output_source_signal.c \ PCG.c \ PCG_SH.c \ + PCG_SH_vti.c \ PML_pro.c \ readdsk.c \ read_par_json.c \ readmod.c \ + readmod_vti.c \ readmod_elastic.c \ + readmod_el_vti.c \ readmod_acoustic.c \ receiver.c \ rd_sour.c \ diff --git a/src/PCG_SH_vti.c b/src/PCG_SH_vti.c new file mode 100644 index 0000000000000000000000000000000000000000..d9efa414b10f40a31b5ee1171be0bf587a5fe42c --- /dev/null +++ b/src/PCG_SH_vti.c @@ -0,0 +1,745 @@ +/*----------------------------------------------------------------------------------------- + * Copyright (C) 2016 For the list of authors, see file AUTHORS. + * + * This file is part of IFOS. + * + * IFOS is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, version 2.0 of the License only. + * + * IFOS 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with IFOS. See file COPYING and/or . + -----------------------------------------------------------------------------------------*/ + +/*------------------------------------------------------------------------ + * Module for the Preconditioned Conjugate Gradient Method (PCG) + * for the material parameters vp, vs, rho and lambda, mu, rho respectively + * + * ----------------------------------------------------------------------*/ + +#include "fd.h" + +void PCG_SH_vti(float ** taper_coeff, int nsrc, float ** srcpos, int ** recpos, int ntr_glob, int iter, int nfstart_jac, float ** waveconv_u, float C_vs, float ** gradp_u, + float ** waveconv_rho, float C_rho, float ** gradp_rho, float **waveconv_vshor, float C_vshor, float **gradp_vshor, float Vs_avg, float F_LOW_PASS, int PCG_iter_start){ + + extern int NX, NY, IDX, IDY, SPATFILTER, GRAD_FILTER; + extern int FORWARD_ONLY, SWS_TAPER_GRAD_VERT, SWS_TAPER_GRAD_HOR, SWS_TAPER_GRAD_SOURCES, SWS_TAPER_FILE; + extern int POS[3], MYID, ACOUSTIC,WAVETYPE; + extern char JACOBIAN[STRING_SIZE]; + + char jac[225], jac2[225]; + int i, j; + float betaz, betan, gradplastiter, gradclastiter, betar, beta; + extern FILE *FP; + FILE *FP3, *FP4, *FP6, *FP5 = NULL; + int use_conjugate_1=1; + int use_conjugate_2=1; + + + /* Check if conjugate gradient can be used */ + if( (iter-PCG_iter_start) < 2 ) { + use_conjugate_2=0; + if( (iter-PCG_iter_start) < 1 ) { + use_conjugate_1=0; + } + } + + /* ===================================================================================================================================================== */ + /* ===================================================== GRADIENT Zs ================================================================================== */ + /* ===================================================================================================================================================== */ + + if((FORWARD_ONLY==0)&&(!ACOUSTIC)){ + + /* Preconditioning of the gradient */ + /* ------------------------------- */ + + /* apply taper on the gradient */ + /* --------------------------- */ + if (SWS_TAPER_GRAD_VERT){ /*vertical gradient taper is applied*/ + taper_grad(waveconv_u,taper_coeff,srcpos,nsrc,recpos,ntr_glob,1);} + + if (SWS_TAPER_GRAD_HOR){ /*horizontal gradient taper is applied*/ + taper_grad(waveconv_u,taper_coeff,srcpos,nsrc,recpos,ntr_glob,2);} + + if (SWS_TAPER_GRAD_SOURCES){ /*cylindrical taper around sources is applied*/ + taper_grad(waveconv_u,taper_coeff,srcpos,nsrc,recpos,ntr_glob,3);} + + if (SWS_TAPER_FILE){ /* read taper from BIN-File*/ + taper_grad(waveconv_u,taper_coeff,srcpos,nsrc,recpos,ntr_glob,5);} + + /* save gradient */ + sprintf(jac,"%s_g_u_SH.old.%i.%i",JACOBIAN,POS[1],POS[2]); + FP3=fopen(jac,"wb"); + + for (i=1;i<=NX;i=i+IDX){ + for (j=1;j<=NY;j=j+IDY){ + fwrite(&waveconv_u[j][i],sizeof(float),1,FP3); + } + } + + fclose(FP3); + + MPI_Barrier(MPI_COMM_WORLD); + + /* merge gradient file */ + sprintf(jac,"%s_g_u_SH.old",JACOBIAN); + if (MYID==0) mergemod(jac,3); + + /* Normalize gradient to maximum value */ + /*norm(waveconv_u,iter,2);*/ + + /* apply spatial wavelength filter */ + if(SPATFILTER==1){ + if (MYID==0){ + fprintf(FP,"\n Spatial filter is applied to gradient (written by PE %d)\n",MYID);} + spat_filt(waveconv_u,iter,2);} + + /* apply 2D-Gaussian filter*/ + if(GRAD_FILTER==1){smooth(waveconv_u,2,1,Vs_avg,F_LOW_PASS);} + + /* output of the preconditioned gradient */ + for (i=1;i<=NX;i=i+IDX){ + for (j=1;j<=NY;j=j+IDY){ + waveconv_u[j][i] = C_vs * waveconv_u[j][i]; + gradp_u[j][i]=waveconv_u[j][i]; + } + } + + /* save gradient for output as inversion result */ + if(iter==nfstart_jac){ + sprintf(jac,"%s_p_u_SH_it%d.old.%i.%i",JACOBIAN,iter,POS[1],POS[2]); + FP3=fopen(jac,"wb"); + + for (i=1;i<=NX;i=i+IDX){ + for (j=1;j<=NY;j=j+IDY){ + fwrite(&waveconv_u[j][i],sizeof(float),1,FP3); + } + } + + fclose(FP3); + + MPI_Barrier(MPI_COMM_WORLD); + + /* merge gradient file */ + sprintf(jac,"%s_p_u_SH_it%d.old",JACOBIAN,iter); + if (MYID==0) mergemod(jac,3); + MPI_Barrier(MPI_COMM_WORLD); + sprintf(jac,"%s_p_u_SH_it%d.old.%i.%i",JACOBIAN,iter,POS[1],POS[2]); + remove(jac); + } + + /* calculate conjugate gradient direction, if iter > 1 (after Mora 1987) */ + /* --------------------------------------------------------------------- */ + + if((iter>1)&&(use_conjugate_1)){ + + + + sprintf(jac,"%s_p_u_SH.old.%i.%i",JACOBIAN,POS[1],POS[2]); + FP6=fopen(jac,"rb"); + + if((iter>2)&&(use_conjugate_2)){ + sprintf(jac2,"%s_c_u_SH.old.%i.%i",JACOBIAN,POS[1],POS[2]); + FP5=fopen(jac2,"rb"); + } + + /* apply scalar product to obtain the coefficient beta */ + betaz = 0.0; + betan = 0.0; + for (i=1;i<=NX;i=i+IDX){ + for (j=1;j<=NY;j=j+IDY){ + + fread(&gradplastiter,sizeof(float),1,FP6); + + /*if(gradglastiter==gradg[j][i]) declare_error("TEST1");*/ + /*if (MYID==10) printf("TEST beta (MYID=%d) bei (j,i)=(%i,%i): gradg(k-1) = %e, gradg(k) = %e\n",MYID,j,i,gradglastiter,gradg[j][i]);*/ + + /* + betaz += (1e5*gradp[j][i]) * ( (1e5*gradg[j][i]) - (1e5*gradglastiter) ); + betan += (1e5*gradplastiter) * (1e5*gradglastiter); + */ + + /* Polak and Ribiere */ + /*betaz += (gradp_u[j][i]) * ( (gradg_u[j][i]) - (gradglastiter) ); + betan += (gradplastiter) * (gradglastiter);*/ + + /* Polak and Ribiere */ + betaz += (gradp_u[j][i]) * ( (gradp_u[j][i]) - (gradplastiter) ); + betan += (gradplastiter) * (gradplastiter); + + /* Fletcher and Reeves */ + /*betaz += (gradp[j][i]) * (gradg[j][i]); + betan += (gradplastiter) * (gradglastiter);*/ + + } + } + + // printf("TEST: vor exchange (MYID=%d): beta = betaz/betan = %e/%e = %e\n",MYID,betaz,betan,betaz/betan); + + /*betaz = exchange_L2(betaz,1,1); + betan = exchange_L2(betan,1,1);*/ + + betar = 0.0; + MPI_Allreduce(&betaz,&betar,1,MPI_FLOAT,MPI_SUM,MPI_COMM_WORLD); + betaz = betar; + + betar = 0.0; + MPI_Allreduce(&betan,&betar,1,MPI_FLOAT,MPI_SUM,MPI_COMM_WORLD); + betan = betar; + + // beta = betaz/betan; + beta = 0.0f; + if(betan !=0.0f) beta = betaz/betan; + + /* direction reset */ + if(beta<0.0){beta = 0.0;} + + /*betaVs = beta;*/ + // printf("\n\nTEST: nach exchange (MYID=%d): beta = %e / %e = %e\n",MYID,betaz,betan,beta); + + fseek(FP6,0,SEEK_SET); + + for (i=1;i<=NX;i=i+IDX){ + for (j=1;j<=NY;j=j+IDY){ + + if(iter==2){ + fread(&gradplastiter,sizeof(float),1,FP6); + waveconv_u[j][i] = gradp_u[j][i] + gradplastiter * beta; + } + + if((iter>2)&&(use_conjugate_2)){ + fread(&gradclastiter,sizeof(float),1,FP5); + waveconv_u[j][i] = gradp_u[j][i] + gradclastiter * beta; + } + + +// if (iter >= 2){ +// if (isnan(waveconv_u[j][i]) || isinf(waveconv_u[j][i])){ +// sum = 0.0; +// h = 0; +// for (ii=-1;ii<=1;ii++){ +// for (jj=-1;jj<=1;jj++){ +// if (isnan(waveconv_u[j+jj][i+ii]) || isinf(waveconv_u[j+jj][i+ii])) continue; +// sum += waveconv_u[j+jj][i+ii]; +// h++; +// } +// } +// if (h>0) waveconv_u[j][i] = sum / h; +// else waveconv_u[j][i] = 0.0; +// } +// } + + } + } + + fclose(FP6); + + if((iter>2)&&(use_conjugate_2)){fclose(FP5);} + } + + /* output of the conjugate gradient */ + if((iter>1)&&(use_conjugate_1)){ + sprintf(jac2,"%s_c_u_SH.old.%i.%i",JACOBIAN,POS[1],POS[2]); + FP5=fopen(jac2,"wb"); + + for (i=1;i<=NX;i=i+IDX){ + for (j=1;j<=NY;j=j+IDY){ + fwrite(&waveconv_u[j][i],sizeof(float),1,FP5); + } + } + + fclose(FP5); + + MPI_Barrier(MPI_COMM_WORLD); + + /* merge gradient file */ + sprintf(jac2,"%s_c_u_SH.old",JACOBIAN); + if (MYID==0) mergemod(jac2,3); + } + + sprintf(jac,"%s_p_u_SH.old.%i.%i",JACOBIAN,POS[1],POS[2]); + FP4=fopen(jac,"wb"); + + /* output of the preconditioned gradient */ + for (i=1;i<=NX;i=i+IDX){ + for (j=1;j<=NY;j=j+IDY){ + /*fwrite(&waveconv_u[j][i],sizeof(float),1,FP4);*/ + fwrite(&gradp_u[j][i],sizeof(float),1,FP4); + } + } + + fclose(FP4); + + MPI_Barrier(MPI_COMM_WORLD); + + /* merge gradient file */ + sprintf(jac,"%s_p_u_SH.old",JACOBIAN); + if (MYID==0) mergemod(jac,3); + + } + + /* ===================================================================================================================================================== */ + /* ===================================================== GRADIENT rho ================================================================================== */ + /* ===================================================================================================================================================== */ + + if(FORWARD_ONLY==0){ + + /* Preconditioning of the gradient */ + /* ------------------------------- */ + if (SWS_TAPER_GRAD_VERT){ /*vertical gradient taper is applied*/ + taper_grad(waveconv_rho,taper_coeff,srcpos,nsrc,recpos,ntr_glob,1);} + + if (SWS_TAPER_GRAD_HOR){ /*horizontal gradient taper is applied*/ + taper_grad(waveconv_rho,taper_coeff,srcpos,nsrc,recpos,ntr_glob,2);} + + if (SWS_TAPER_GRAD_SOURCES){ /*cylindrical taper around sources is applied*/ + taper_grad(waveconv_rho,taper_coeff,srcpos,nsrc,recpos,ntr_glob,3);} + + if (SWS_TAPER_FILE){ /* read taper from BIN-File*/ + taper_grad(waveconv_rho,taper_coeff,srcpos,nsrc,recpos,ntr_glob,6);} + + /* save gradient */ + sprintf(jac,"%s_g_rho_SH.old.%i.%i",JACOBIAN,POS[1],POS[2]); + FP3=fopen(jac,"wb"); + + for (i=1;i<=NX;i=i+IDX){ + for (j=1;j<=NY;j=j+IDY){ + fwrite(&waveconv_rho[j][i],sizeof(float),1,FP3); + } + } + + fclose(FP3); + + MPI_Barrier(MPI_COMM_WORLD); + + /* merge gradient file */ + sprintf(jac,"%s_g_rho_SH.old",JACOBIAN); + if (MYID==0) mergemod(jac,3); + + /* Normalize gradient to maximum value */ + /*norm(waveconv_rho,iter,3);*/ + + /* apply spatial wavelength filter */ + if(SPATFILTER==1){ + if (MYID==0){ + fprintf(FP,"\n Spatial filter is applied to gradient (written by PE %d)\n",MYID);} + spat_filt(waveconv_rho,iter,3);} + + /* apply 2D-Gaussian filter*/ + if(GRAD_FILTER==1){smooth(waveconv_rho,3,1,Vs_avg,F_LOW_PASS);} + + /* output of the preconditioned gradient */ + for (i=1;i<=NX;i=i+IDX){ + for (j=1;j<=NY;j=j+IDY){ + waveconv_rho[j][i] = C_rho * waveconv_rho[j][i]; + gradp_rho[j][i]=waveconv_rho[j][i]; + } + } + + /* save gradient for output as inversion result */ + if(iter==nfstart_jac){ + sprintf(jac,"%s_p_rho_SH_it%d.old.%i.%i",JACOBIAN,iter,POS[1],POS[2]); + FP3=fopen(jac,"wb"); + + for (i=1;i<=NX;i=i+IDX){ + for (j=1;j<=NY;j=j+IDY){ + fwrite(&waveconv_rho[j][i],sizeof(float),1,FP3); + } + } + + fclose(FP3); + + MPI_Barrier(MPI_COMM_WORLD); + + /* merge gradient file */ + sprintf(jac,"%s_p_rho_SH_it%d.old",JACOBIAN,iter); + if (MYID==0) mergemod(jac,3); + MPI_Barrier(MPI_COMM_WORLD); + sprintf(jac,"%s_p_rho_SH_it%d.old.%i.%i",JACOBIAN,iter,POS[1],POS[2]); + remove(jac); + } + + /* calculate conjugate gradient direction, if iter > 1 (after Mora 1987) */ + /* --------------------------------------------------------------------- */ + + if((iter>1)&&(use_conjugate_1)){ + + sprintf(jac,"%s_p_rho_SH.old.%i.%i",JACOBIAN,POS[1],POS[2]); + FP6=fopen(jac,"rb"); + + if((iter>2)&&(use_conjugate_2)){ + sprintf(jac2,"%s_c_rho_SH.old.%i.%i",JACOBIAN,POS[1],POS[2]); + FP5=fopen(jac2,"rb"); + } + + /* apply scalar product to obtain the coefficient beta */ + betaz = 0.0; + betan = 0.0; + for (i=1;i<=NX;i=i+IDX){ + for (j=1;j<=NY;j=j+IDY){ + + fread(&gradplastiter,sizeof(float),1,FP6); + + /*if(gradglastiter==gradg[j][i]) declare_error("TEST1");*/ + /*if (MYID==10) printf("TEST beta (MYID=%d) bei (j,i)=(%i,%i): gradg(k-1) = %e, gradg(k) = %e\n",MYID,j,i,gradglastiter,gradg[j][i]);*/ + + /* + betaz += (1e5*gradp[j][i]) * ( (1e5*gradg[j][i]) - (1e5*gradglastiter) ); + betan += (1e5*gradplastiter) * (1e5*gradglastiter); + */ + + /* Polak and Ribiere */ + /*betaz += (gradp_rho[j][i]) * ( (gradg_rho[j][i]) - (gradglastiter) ); + betan += (gradplastiter) * (gradglastiter);*/ + + /* Polak and Ribiere */ + betaz += (gradp_rho[j][i]) * ( (gradp_rho[j][i]) - (gradplastiter) ); + betan += (gradplastiter) * (gradplastiter); + + /* Fletcher and Reeves */ + /*betaz += (gradp[j][i]) * (gradg[j][i]); + betan += (gradplastiter) * (gradglastiter);*/ + + } + } + + /*printf("TEST: vor exchange (MYID=%d): beta = betaz/betan = %e/%e = %e\n",MYID,betaz,betan,betaz/betan);*/ + + /*betaz = exchange_L2(betaz,1,1); + betan = exchange_L2(betan,1,1);*/ + + betar = 0.0; + MPI_Allreduce(&betaz,&betar,1,MPI_FLOAT,MPI_SUM,MPI_COMM_WORLD); + betaz = betar; + + betar = 0.0; + MPI_Allreduce(&betan,&betar,1,MPI_FLOAT,MPI_SUM,MPI_COMM_WORLD); + betan = betar; + + // beta = betaz/betan; + beta = 0.0f; + if(betan !=0.0f) beta = betaz/betan; + + /* direction reset */ + if(beta<0.0){beta = 0.0;} + + /*betarho = beta;*/ + //printf("\n\nTEST: nach exchange (MYID=%d): beta = %e / %e = %e\n",MYID,betaz,betan,beta); + + fseek(FP6,0,SEEK_SET); + + for (i=1;i<=NX;i=i+IDX){ + for (j=1;j<=NY;j=j+IDY){ + + if(iter==2){ + fread(&gradplastiter,sizeof(float),1,FP6); + waveconv_rho[j][i] = gradp_rho[j][i] + gradplastiter * beta; + } + + if((iter>2)&&(use_conjugate_2)){ + fread(&gradclastiter,sizeof(float),1,FP5); + waveconv_rho[j][i] = gradp_rho[j][i] + gradclastiter * beta; + } + + /*if (iter >= 2){ + if (isnan(waveconv_u[j][i]) || isinf(waveconv_u[j][i])){ + sum = 0.0; + h = 0; + for (ii=-1;ii<=1;ii++){ + for (jj=-1;jj<=1;jj++){ + if (isnan(waveconv_rho[j+jj][i+ii]) || isinf(waveconv_rho[j+jj][i+ii])) continue; + sum += waveconv_rho[j+jj][i+ii]; + h++; + } + } + if (h>0) waveconv_rho[j][i] = sum / h; + else waveconv_rho[j][i] = 0.0; + } + }*/ + } + } + + fclose(FP6); + + if((iter>2)&&(use_conjugate_2)){fclose(FP5);} + } + + /* output of the conjugate gradient */ + if((iter>1)&&(use_conjugate_1)){ + sprintf(jac2,"%s_c_rho_SH.old.%i.%i",JACOBIAN,POS[1],POS[2]); + FP5=fopen(jac2,"wb"); + + for (i=1;i<=NX;i=i+IDX){ + for (j=1;j<=NY;j=j+IDY){ + fwrite(&waveconv_rho[j][i],sizeof(float),1,FP5); + } + } + + fclose(FP5); + + MPI_Barrier(MPI_COMM_WORLD); + + /* merge gradient file */ + sprintf(jac2,"%s_c_rho_SH.old",JACOBIAN); + if (MYID==0) mergemod(jac2,3); + } + + sprintf(jac,"%s_p_rho_SH.old.%i.%i",JACOBIAN,POS[1],POS[2]); + FP4=fopen(jac,"wb"); + + /* output of the preconditioned gradient */ + for (i=1;i<=NX;i=i+IDX){ + for (j=1;j<=NY;j=j+IDY){ + /*fwrite(&waveconv_rho[j][i],sizeof(float),1,FP4);*/ + fwrite(&gradp_rho[j][i],sizeof(float),1,FP4); + } + } + + fclose(FP4); + + MPI_Barrier(MPI_COMM_WORLD); + + /* merge gradient file */ + sprintf(jac,"%s_p_rho_SH.old",JACOBIAN); + if (MYID==0) mergemod(jac,3); + + } + + + + + /* ===================================================================================================================================================== */ + /* ===================================================== GRADIENT horizontal VS (SH, VTI)=============================================================== */ + /* ===================================================================================================================================================== */ + + if(FORWARD_ONLY==0){ + + /* Preconditioning of the gradient */ + /* ------------------------------- */ + if (SWS_TAPER_GRAD_VERT){ /*vertical gradient taper is applied*/ + taper_grad(waveconv_vshor,taper_coeff,srcpos,nsrc,recpos,ntr_glob,1);} + + if (SWS_TAPER_GRAD_HOR){ /*horizontal gradient taper is applied*/ + taper_grad(waveconv_vshor,taper_coeff,srcpos,nsrc,recpos,ntr_glob,2);} + + if (SWS_TAPER_GRAD_SOURCES){ /*cylindrical taper around sources is applied*/ + taper_grad(waveconv_vshor,taper_coeff,srcpos,nsrc,recpos,ntr_glob,3);} + + if (SWS_TAPER_FILE){ /* read taper from BIN-File*/ + taper_grad(waveconv_vshor,taper_coeff,srcpos,nsrc,recpos,ntr_glob,7);} + + /* save gradient */ + sprintf(jac,"%s_g_vshor_SH.old.%i.%i",JACOBIAN,POS[1],POS[2]); + FP3=fopen(jac,"wb"); + + for (i=1;i<=NX;i=i+IDX){ + for (j=1;j<=NY;j=j+IDY){ + fwrite(&waveconv_vshor[j][i],sizeof(float),1,FP3); + } + } + + fclose(FP3); + + MPI_Barrier(MPI_COMM_WORLD); + + /* merge gradient file */ + sprintf(jac,"%s_g_vshor_SH.old",JACOBIAN); + if (MYID==0) mergemod(jac,3); + + /* Normalize gradient to maximum value */ + /*norm(waveconv_rho,iter,3);*/ + + /* apply spatial wavelength filter */ + if(SPATFILTER==1){ + if (MYID==0){ + fprintf(FP,"\n Spatial filter is applied to gradient (written by PE %d)\n",MYID);} + spat_filt(waveconv_vshor,iter,4);} + + /* apply 2D-Gaussian filter*/ + if(GRAD_FILTER==1){smooth(waveconv_vshor,7,1,Vs_avg,F_LOW_PASS);} + + /* output of the preconditioned gradient */ + for (i=1;i<=NX;i=i+IDX){ + for (j=1;j<=NY;j=j+IDY){ + waveconv_vshor[j][i] = C_vshor * waveconv_vshor[j][i]; + gradp_vshor[j][i]=waveconv_vshor[j][i]; + } + } + + /* save gradient for output as inversion result */ + if(iter==nfstart_jac){ + sprintf(jac,"%s_p_vshor_SH_it%d.old.%i.%i",JACOBIAN,iter,POS[1],POS[2]); + FP3=fopen(jac,"wb"); + + for (i=1;i<=NX;i=i+IDX){ + for (j=1;j<=NY;j=j+IDY){ + fwrite(&waveconv_vshor[j][i],sizeof(float),1,FP3); + } + } + + fclose(FP3); + + MPI_Barrier(MPI_COMM_WORLD); + + /* merge gradient file */ + sprintf(jac,"%s_p_vshor_SH_it%d.old",JACOBIAN,iter); + if (MYID==0) mergemod(jac,3); + MPI_Barrier(MPI_COMM_WORLD); + sprintf(jac,"%s_p_vshor_SH_it%d.old.%i.%i",JACOBIAN,iter,POS[1],POS[2]); + remove(jac); + } + + /* calculate conjugate gradient direction, if iter > 1 (after Mora 1987) */ + /* --------------------------------------------------------------------- */ + + if((iter>1)&&(use_conjugate_1)){ + + sprintf(jac,"%s_p_vshor_SH.old.%i.%i",JACOBIAN,POS[1],POS[2]); + FP6=fopen(jac,"rb"); + + if((iter>2)&&(use_conjugate_2)){ + sprintf(jac2,"%s_c_vshor_SH.old.%i.%i",JACOBIAN,POS[1],POS[2]); + FP5=fopen(jac2,"rb"); + } + + /* apply scalar product to obtain the coefficient beta */ + betaz = 0.0; + betan = 0.0; + + + + for (i=1;i<=NX;i=i+IDX){ + for (j=1;j<=NY;j=j+IDY){ + + fread(&gradplastiter,sizeof(float),1,FP6); + + /*if(gradglastiter==gradg[j][i]) declare_error("TEST1");*/ + /*if (MYID==10) printf("TEST beta (MYID=%d) bei (j,i)=(%i,%i): gradg(k-1) = %e, gradg(k) = %e\n",MYID,j,i,gradglastiter,gradg[j][i]);*/ + + /* + betaz += (1e5*gradp[j][i]) * ( (1e5*gradg[j][i]) - (1e5*gradglastiter) ); + betan += (1e5*gradplastiter) * (1e5*gradglastiter); + */ + + /* Polak and Ribiere */ + /*betaz += (gradp_rho[j][i]) * ( (gradg_rho[j][i]) - (gradglastiter) ); + betan += (gradplastiter) * (gradglastiter);*/ + + /* Polak and Ribiere */ + betaz += (gradp_vshor[j][i]) * ( (gradp_vshor[j][i]) - (gradplastiter) ); + betan += (gradplastiter) * (gradplastiter); + + /* Fletcher and Reeves */ + /*betaz += (gradp[j][i]) * (gradg[j][i]); + betan += (gradplastiter) * (gradglastiter);*/ + + } + } + + /* printf("TEST: vor exchange (MYID=%d): beta = betaz/betan = %e/%e = %e\n",MYID,betaz,betan,betaz/betan); */ + + /*betaz = exchange_L2(betaz,1,1); + betan = exchange_L2(betan,1,1);*/ + + betar = 0.0; + MPI_Allreduce(&betaz,&betar,1,MPI_FLOAT,MPI_SUM,MPI_COMM_WORLD); + betaz = betar; + + betar = 0.0; + MPI_Allreduce(&betan,&betar,1,MPI_FLOAT,MPI_SUM,MPI_COMM_WORLD); + betan = betar; + + // beta = betaz/betan; + beta = 0.0f; + if(betan !=0.0f) beta = betaz/betan; + + /* direction reset */ + if(beta<0.0){beta = 0.0;} + + /*betarho = beta;*/ + /* fprintf(FP,"\n\nTEST: nach exchange (MYID=%d): beta = %e / %e = %e\n",MYID,betaz,betan,beta); */ + + fseek(FP6,0,SEEK_SET); + + for (i=1;i<=NX;i=i+IDX){ + for (j=1;j<=NY;j=j+IDY){ + + if(iter==2){ + fread(&gradplastiter,sizeof(float),1,FP6); + waveconv_vshor[j][i] = gradp_vshor[j][i] + gradplastiter * beta; + } + + if((iter>2)&&(use_conjugate_2)){ + fread(&gradclastiter,sizeof(float),1,FP5); + waveconv_vshor[j][i] = gradp_vshor[j][i] + gradclastiter * beta; + } + + /*if (iter >= 2){ + if (isnan(waveconv_u[j][i]) || isinf(waveconv_u[j][i])){ + sum = 0.0; + h = 0; + for (ii=-1;ii<=1;ii++){ + for (jj=-1;jj<=1;jj++){ + if (isnan(waveconv_rho[j+jj][i+ii]) || isinf(waveconv_rho[j+jj][i+ii])) continue; + sum += waveconv_rho[j+jj][i+ii]; + h++; + } + } + if (h>0) waveconv_rho[j][i] = sum / h; + else waveconv_rho[j][i] = 0.0; + } + }*/ + } + } + + fclose(FP6); + + if((iter>2)&&(use_conjugate_2)){fclose(FP5);} + } + + /* output of the conjugate gradient */ + if((iter>1)&&(use_conjugate_1)){ + sprintf(jac2,"%s_c_vshor_SH.old.%i.%i",JACOBIAN,POS[1],POS[2]); + FP5=fopen(jac2,"wb"); + + for (i=1;i<=NX;i=i+IDX){ + for (j=1;j<=NY;j=j+IDY){ + fwrite(&waveconv_vshor[j][i],sizeof(float),1,FP5); + } + } + + fclose(FP5); + + MPI_Barrier(MPI_COMM_WORLD); + + /* merge gradient file */ + sprintf(jac2,"%s_c_vshor_SH.old",JACOBIAN); + if (MYID==0) mergemod(jac2,3); + } + + sprintf(jac,"%s_p_vshor_SH.old.%i.%i",JACOBIAN,POS[1],POS[2]); + FP4=fopen(jac,"wb"); + + /* output of the preconditioned gradient */ + for (i=1;i<=NX;i=i+IDX){ + for (j=1;j<=NY;j=j+IDY){ + /*fwrite(&waveconv_rho[j][i],sizeof(float),1,FP4);*/ + fwrite(&gradp_vshor[j][i],sizeof(float),1,FP4); + } + } + + fclose(FP4); + + MPI_Barrier(MPI_COMM_WORLD); + + /* merge gradient file */ + sprintf(jac,"%s_p_vshor_SH.old",JACOBIAN); + if (MYID==0) mergemod(jac,3); + + } +} diff --git a/src/apply_workflow.c b/src/apply_workflow.c index 7f5507b41370c199f07a58bcafbc6ac240cdc62b..496e1b194c38cf8ca1a8e1d689351bf77c651325 100644 --- a/src/apply_workflow.c +++ b/src/apply_workflow.c @@ -38,7 +38,7 @@ void apply_workflow(float ** workflow,int workflow_lines,char workflow_header[ST extern float JOINT_INVERSION_PSV_SH_ALPHA_RHO; extern int EPRECOND; extern float EPSILON_WE; - extern int GRAD_METHOD; + extern int GRAD_METHOD, WOLFE_CONDITION; extern int WORKFLOW_STAGE; /******************/ @@ -54,6 +54,13 @@ void apply_workflow(float ** workflow,int workflow_lines,char workflow_header[ST } } + /* PCG or LBFGS */ + if( TIME_FILT > 0 ) { + if( GRAD_METHOD != workflow[WORKFLOW_STAGE][1] ) *LBFGS_iter_start=*iter; + GRAD_METHOD=workflow[WORKFLOW_STAGE][1]; + if(workflow[WORKFLOW_STAGE][1]==1) WOLFE_CONDITION=0; + } + /* Inversion of material parameter */ if(workflow[WORKFLOW_STAGE][2]!=-1) { if(workflow[WORKFLOW_STAGE][2]==1) { diff --git a/src/av_c55c66.c b/src/av_c55c66.c new file mode 100644 index 0000000000000000000000000000000000000000..d5b748768313fb192313a50833f8ffcd7b371286 --- /dev/null +++ b/src/av_c55c66.c @@ -0,0 +1,44 @@ +/*----------------------------------------------------------------------------------------- + * Copyright (C) 2016 For the list of authors, see file AUTHORS. + * + * This file is part of IFOS. + * + * IFOS is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, version 2.0 of the License only. + * + * IFOS 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with IFOS. See file COPYING and/or . +-----------------------------------------------------------------------------------------*/ + +/*------------------------------------------------------------------------ + * averaging of elastic constants c55 and c66 + * ----------------------------------------------------------------------*/ + +#include "fd.h" + +void av_c55c66(float **c55, float **c55ipjp, float **c66, float **c66ipjp){ + + extern int NX, NY; + int i, j; + for (j=1;j<=NY;j++){ + for (i=1;i<=NX;i++){ + +// c55ipjp[j][i] = 0.25*(c55[j][i]+c55[j][i+1]+c55[j+1][i]+c55[j+1][i+1]); +// c66ipjp[j][i] = 0.25*(c66[j][i]+c66[j][i+1]+c66[j+1][i]+c66[j+1][i+1]); + c55ipjp[j][i] = 4.0/(1.0/c55[j][i]+1.0/c55[j][i+1]+1.0/c55[j+1][i]+1.0/c55[j+1][i+1]); + if((c55[j][i]==0.0)||(c55[j][i+1]==0.0)||(c55[j+1][i]==0.0)||(c55[j+1][i+1]==0.0)){ + c55ipjp[j][i]=0.0; + } + c66ipjp[j][i] = 4.0/(1.0/c66[j][i]+1.0/c66[j][i+1]+1.0/c66[j+1][i]+1.0/c66[j+1][i+1]); + if((c66[j][i]==0.0)||(c66[j][i+1]==0.0)||(c66[j+1][i]==0.0)||(c66[j+1][i+1]==0.0)){ + c66ipjp[j][i]=0.0; + } + } + } +} diff --git a/src/calc_mat_change_test_vti.c b/src/calc_mat_change_test_vti.c new file mode 100644 index 0000000000000000000000000000000000000000..f0b3ddfddb91e482c67c4c339eec16661860a9a3 --- /dev/null +++ b/src/calc_mat_change_test_vti.c @@ -0,0 +1,625 @@ +/*----------------------------------------------------------------------------------------- + * Copyright (C) 2016 For the list of authors, see file AUTHORS. + * + * This file is part of IFOS. + * + * IFOS is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, version 2.0 of the License only. + * + * IFOS 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with IFOS. See file COPYING and/or . + -----------------------------------------------------------------------------------------*/ + +/*------------------------------------------------------------------------ + * calculate test step length for material parameter update + * + * + * ---------------------------------------------------------------------*/ + +#include "fd.h" +void calc_mat_change_test_vti(float ** waveconv, float ** waveconv_rho, float ** waveconv_u, float **waveconv_vshor, + float ** rho, float ** rhonp1, float ** pi, float ** pinp1, float ** u, float ** unp1, float **vshor, float **vshornp1, int iter, + int epstest, int FORWARD_ONLY, float eps_scale, int itest, int nfstart, float ** u_start, float ** pi_start, float ** rho_start,int wavetype_start, + float **s_LBFGS,int N_LBFGS,int LBFGS_NPAR,float Vs_avg,float Vp_avg,float rho_avg, float vshor_avg, int LBFGS_iter_start){ + + + /*--------------------------------------------------------------------------*/ + /* extern variables */ + extern float DH, DT, VP_VS_RATIO, GAMMA_VTI; + extern float EPSILON, EPSILON_u, EPSILON_rho, EPSILON_vshor, MUN; + extern int NX, NY, NXG, NYG, POS[3], MYID, PARAMETERIZATION,WAVETYPE; + + extern int INV_RHO_ITER, INV_VP_ITER, INV_VS_ITER, INV_VSHOR_ITER; + extern int VERBOSE; + extern char INV_MODELFILE[STRING_SIZE]; + extern int GRAD_METHOD; + extern float VPUPPERLIM, VPLOWERLIM, VSUPPERLIM, VSLOWERLIM, RHOUPPERLIM, RHOLOWERLIM, VSHORUPPERLIM, VSHORLOWERLIM; + extern int LBFGS_STEP_LENGTH; + extern int S, ACOUSTIC; + extern float S_VS, S_VP, S_RHO; + extern int GRAD_METHOD; + /* local variables */ + + float Zp, Zs, pro_vs, pro_vp, pro_rho; + float pimax, rhomax, umax, gradmax, gradmax_rho, gradmax_u, epsilon1, pimaxr, gradmaxr, gradmaxr_u = 0.0, umaxr = 0.0, gradmaxr_rho, rhomaxr; + float vshormax, gradmax_vshor, vshormaxr, gradmaxr_vshor; + int i, j, testuplow, pr=0; + char modfile[STRING_SIZE]; + int w=0,l=0; + + extern char JACOBIAN[STRING_SIZE]; + char jac[225],jac2[225]; + FILE *FP_JAC = NULL,*FP_JAC2 = NULL,*FP_JAC3 = NULL; + + if(GRAD_METHOD==2&&(itest==0)){ + w=iter%N_LBFGS; + if(w==0) w=N_LBFGS; + + if(!ACOUSTIC){ + sprintf(jac,"%s_s_LBFGS_vs_it%d.bin.%i.%i",JACOBIAN,iter+1,POS[1],POS[2]); + FP_JAC=fopen(jac,"wb"); + } + + if(LBFGS_NPAR>1){ + sprintf(jac2,"%s_s_LBFGS_rho_it%d.bin.%i.%i",JACOBIAN,iter+1,POS[1],POS[2]); + FP_JAC2=fopen(jac2,"wb"); + } + + if(LBFGS_NPAR>2){ + if(WAVETYPE!=2){ + sprintf(jac2,"%s_s_LBFGS_vp_it%d.bin.%i.%i",JACOBIAN,iter+1,POS[1],POS[2]); + FP_JAC3=fopen(jac2,"wb"); + } + else{ + sprintf(jac2,"%s_s_LBFGS_vshor_it%d.bin.%i.%i",JACOBIAN,iter+1,POS[1],POS[2]); + FP_JAC3=fopen(jac2,"wb"); + } + } + + if(MYID==0) printf("\n\n ------------ L-BFGS ---------------"); + if(MYID==0) printf("\n Saving model difference for L-BFGS"); + if(MYID==0) printf("\n At Iteration %i in L-BFGS vector %i\n",iter,w); + l=0; + + + } + /* invert for Zp and Zs */ + /* ------------------------------------------------------------------------------------ */ + + /* find maximum of Zp and gradient waveconv */ + pimax = 0.0; + gradmax = 0.0; + + for (j=1;j<=NY;j++){ + for (i=1;i<=NX;i++){ + + Zp = pi[j][i]; + + if(Zp>pimax) + pimax=Zp; + + if((i*j == 1) || (gradmax == 0.0)) { + gradmax = fabs(waveconv[j][i]); + } else { + if(fabs(waveconv[j][i]) > gradmax) + gradmax = fabs(waveconv[j][i]); + } + } + } + + /* find maximum of Zs and gradient waveconv_u */ + if(!ACOUSTIC){ + umax = 0.0; + gradmax_u = 0.0; + + for (j=1;j<=NY;j++){ + for (i=1;i<=NX;i++){ + + Zs = u[j][i]; + + if(Zs>umax) + umax=Zs; + + if((i*j == 1) || (gradmax_u == 0.0)) { + gradmax_u = fabs(waveconv_u[j][i]); + } else { + if(fabs(waveconv_u[j][i]) > gradmax_u) + gradmax_u = fabs(waveconv_u[j][i]); + } + } + } + } + + /* find maximum of rho and gradient waveconv_rho */ + rhomax = 0.0; + gradmax_rho = 0.0; + + for (j=1;j<=NY;j++){ + for (i=1;i<=NX;i++){ + + if(rho[j][i]>rhomax){rhomax=rho[j][i];} + + if((i*j == 1) || (gradmax_rho == 0.0)) { + gradmax_rho = fabs(waveconv_rho[j][i]); + } else { + if(fabs(waveconv_rho[j][i]) > gradmax_rho) + gradmax_rho = fabs(waveconv_rho[j][i]); + } + + } + } + + /* find maximum of vs_hor and gradient waveconv_vshor */ + vshormax = 0.0; + gradmax_vshor = 0.0; + + for (j=1;j<=NY;j++){ + for (i=1;i<=NX;i++){ + + if (vshor[j][i]>vshormax){vshormax=vshor[j][i];} + + if((i*j == 1) || (gradmax_vshor == 0.0)) { + gradmax_vshor = fabs(waveconv_vshor[j][i]); + } else { + if(fabs(waveconv_vshor[j][i]) > gradmax_vshor) + gradmax_vshor = fabs(waveconv_vshor[j][i]); + } + + } + } + + + + /* calculate scaling factor for the gradients */ + /* --------------------------------------------- */ + + /* parameter 1 */ + MPI_Allreduce(&pimax, &pimaxr, 1,MPI_FLOAT,MPI_MAX,MPI_COMM_WORLD); + MPI_Allreduce(&gradmax,&gradmaxr,1,MPI_FLOAT,MPI_MAX,MPI_COMM_WORLD); + + EPSILON = eps_scale * (pimaxr/gradmaxr); + if (iterLBFGS_iter_start)&&LBFGS_STEP_LENGTH) { + EPSILON=eps_scale; + if (iterLBFGS_iter_start)&&LBFGS_STEP_LENGTH) { + EPSILON_u=eps_scale; + if (iterLBFGS_iter_start)&&LBFGS_STEP_LENGTH) { + EPSILON_rho=eps_scale; + if (iterLBFGS_iter_start)&&LBFGS_STEP_LENGTH) { + EPSILON_vshor=eps_scale; + if (iterVSHORUPPERLIM) { + vshornp1[j][i] = VSHORUPPERLIM; + } + + } + + + + + if(pinp1[j][i]VPUPPERLIM){ + pinp1[j][i] = VPUPPERLIM; + } + + + if(!ACOUSTIC){ + if((unp1[j][i]1e-6)){ + unp1[j][i] = VSLOWERLIM; + } + if(unp1[j][i]>VSUPPERLIM){ + unp1[j][i] = u[j][i]; + } + + /* checking poisson ratio */ + if(VP_VS_RATIO>1){ + if((pinp1[j][i]/unp1[j][i])1) */ + + if(GAMMA_VTI!=0){ + if(((vshornp1[j][i]*vshornp1[j][i])/(unp1[j][i]*unp1[j][i])-1.0)/2.0 > GAMMA_VTI){ + unp1[j][i]=vshornp1[j][i]/sqrt(1.0+2.0*GAMMA_VTI); + } + else if(((vshornp1[j][i]*vshornp1[j][i])/(unp1[j][i]*unp1[j][i])-1.0)/2.0 < GAMMA_VTI*(-1.0)){ + unp1[j][i]=vshornp1[j][i]/sqrt(1.0-2.0*GAMMA_VTI); + } + } + } + + if(S==1){ + if(!ACOUSTIC){ + /* limited update for Vs */ + pro_vs=((u_start[j][i]-unp1[j][i])/u_start[j][i])*100.0; + if(((fabs(pro_vs))>S_VS)&&(pro_vs>0.0)) + unp1[j][i] = u_start[j][i] - u_start[j][i] * S_VS / 100.0; + if(((fabs(pro_vs))>S_VS)&&(pro_vs<0.0)) + unp1[j][i] = u_start[j][i] + u_start[j][i] * S_VS / 100.0; + } + + /* limited update for Vp */ + pro_vp=((pi_start[j][i]-pinp1[j][i])/pi_start[j][i])*100.0; + if(((fabs(pro_vp))>S_VP)&&(pro_vp>0.0)) + pinp1[j][i] = pi_start[j][i] - pi_start[j][i] * S_VP / 100.0; + if(((fabs(pro_vp))>S_VP)&&(pro_vp<0.0)) + pinp1[j][i] = pi_start[j][i] + pi_start[j][i] * S_VP / 100.0; + + /* limited update for Rho */ + pro_rho=((rho_start[j][i]-rhonp1[j][i])/rho_start[j][i])*100.0; + if(((fabs(pro_rho))>S_RHO)&&(pro_rho>0.0)) + rhonp1[j][i] = rho_start[j][i] - rho_start[j][i] * S_RHO / 100.0; + if(((fabs(pro_rho))>S_RHO)&&(pro_rho<0.0)) + rhonp1[j][i] = rho_start[j][i] + rho_start[j][i] * S_RHO / 100.0; + } + + + if((rhonp1[j][i]RHOUPPERLIM) && (INV_RHO_ITER < iter)){ + rhonp1[j][i] = rho[j][i]; + } + + + /* None of these parameters should be smaller than zero */ + if(pinp1[j][i]<0.0){ + pinp1[j][i] = pi[j][i]; + } + if(!ACOUSTIC) + if(unp1[j][i]<0.0){ + unp1[j][i] = u[j][i]; + } + if(rhonp1[j][i]<0.0){ + rhonp1[j][i] = rho[j][i]; + } + + if(itest==0){ + if(GRAD_METHOD==2){ + l++; + + if(!ACOUSTIC) { + s_LBFGS[w][l]=(unp1[j][i]-u[j][i])/Vs_avg; + fwrite(&s_LBFGS[w][l],sizeof(float),1,FP_JAC); + } + + if(LBFGS_NPAR>1) { + s_LBFGS[w][l+NX*NY]=(rhonp1[j][i]-rho[j][i])/rho_avg; + fwrite(&s_LBFGS[w][l+NY*NX],sizeof(float),1,FP_JAC2); + } + + if(LBFGS_NPAR>2){ + if(WAVETYPE!=2){ + s_LBFGS[w][l+2*NX*NY]=(pinp1[j][i]-pi[j][i])/Vp_avg; + fwrite(&s_LBFGS[w][l+2*NY*NX],sizeof(float),1,FP_JAC3); + } + else { + s_LBFGS[w][l+2*NX*NY]=(vshornp1[j][i]-vshor[j][i])/vshor_avg; + fwrite(&s_LBFGS[w][l+2*NY*NX],sizeof(float),1,FP_JAC3); + } + } + + } + if(!ACOUSTIC) u[j][i] = unp1[j][i]; + rho[j][i] = rhonp1[j][i]; + pi[j][i] = pinp1[j][i]; + if (WAVETYPE==2 || WAVETYPE==3) { + vshor[j][i] = vshornp1[j][i]; + } + } + } + } + } + + if(GRAD_METHOD==2&&(itest==0)){ + if(!ACOUSTIC){ + fclose(FP_JAC); + MPI_Barrier(MPI_COMM_WORLD); + sprintf(jac,"%s_s_LBFGS_vs_it%d.bin",JACOBIAN,iter+1); + if (MYID==0) mergemod(jac,3); + MPI_Barrier(MPI_COMM_WORLD); + sprintf(jac,"%s_s_LBFGS_vs_it%d.bin.%i.%i",JACOBIAN,iter+1,POS[1],POS[2]); + remove(jac); + } + + if(LBFGS_NPAR>1){ + fclose(FP_JAC2); + MPI_Barrier(MPI_COMM_WORLD); + sprintf(jac,"%s_s_LBFGS_rho_it%d.bin",JACOBIAN,iter+1); + if (MYID==0) mergemod(jac,3); + MPI_Barrier(MPI_COMM_WORLD); + sprintf(jac,"%s_s_LBFGS_rho_it%d.bin.%i.%i",JACOBIAN,iter+1,POS[1],POS[2]); + remove(jac); + } + + if(LBFGS_NPAR>2){ + if(WAVETYPE!=2){ + fclose(FP_JAC3); + MPI_Barrier(MPI_COMM_WORLD); + sprintf(jac,"%s_s_LBFGS_vp_it%d.bin",JACOBIAN,iter+1); + if (MYID==0) mergemod(jac,3); + MPI_Barrier(MPI_COMM_WORLD); + sprintf(jac,"%s_s_LBFGS_vp_it%d.bin.%i.%i",JACOBIAN,iter+1,POS[1],POS[2]); + remove(jac); + } + else{ + fclose(FP_JAC3); + MPI_Barrier(MPI_COMM_WORLD); + sprintf(jac,"%s_s_LBFGS_vshor_it%d.bin",JACOBIAN,iter+1); + if (MYID==0) mergemod(jac,3); + MPI_Barrier(MPI_COMM_WORLD); + sprintf(jac,"%s_s_LBFGS_vshor_it%d.bin.%i.%i",JACOBIAN,iter+1,POS[1],POS[2]); + remove(jac); + } + } + } + if(!ACOUSTIC) + if((MYID==0)&&(pr==1))printf("\nThe Vp/Vs-ratio of %4.2f is violated. P-wave velocity will be increased that the Vp/Vs-ratio is at least %4.2f \n",VP_VS_RATIO,VP_VS_RATIO); + /*if((MYID==0)&&(f==1))printf("\n RHO_VS == %d: Rho is coupled to Vp about Gardner Relationship \n",RHO_VS); */ + + + if(itest==0){ + if((wavetype_start==1||wavetype_start==3)){ + + sprintf(modfile,"%s_vp.bin",INV_MODELFILE); + writemod(modfile,pinp1,3); + + MPI_Barrier(MPI_COMM_WORLD); + + if (MYID==0) mergemod(modfile,3); + + MPI_Barrier(MPI_COMM_WORLD); + sprintf(modfile,"%s_vp.bin.%i.%i",INV_MODELFILE,POS[1],POS[2]); + remove(modfile); + + } + if(!ACOUSTIC){ + + sprintf(modfile,"%s_vs.bin",INV_MODELFILE); + + writemod(modfile,unp1,3); + + MPI_Barrier(MPI_COMM_WORLD); + + if (MYID==0) mergemod(modfile,3); + + MPI_Barrier(MPI_COMM_WORLD); + sprintf(modfile,"%s_vs.bin.%i.%i",INV_MODELFILE,POS[1],POS[2]); + remove(modfile); + + } + + + sprintf(modfile,"%s_rho.bin",INV_MODELFILE); + writemod(modfile,rho,3); + + MPI_Barrier(MPI_COMM_WORLD); + + if (MYID==0) mergemod(modfile,3); + + MPI_Barrier(MPI_COMM_WORLD); + sprintf(modfile,"%s_rho.bin.%i.%i",INV_MODELFILE,POS[1],POS[2]); + remove(modfile); + + if (WAVETYPE==2 || WAVETYPE==3) { + + sprintf(modfile,"%s_vshor.bin",INV_MODELFILE); + writemod(modfile,vshor,3); + + MPI_Barrier(MPI_COMM_WORLD); + + if (MYID==0) mergemod(modfile,3); + + MPI_Barrier(MPI_COMM_WORLD); + sprintf(modfile,"%s_vshor.bin.%i.%i",INV_MODELFILE,POS[1],POS[2]); + remove(modfile); + } + + } + + if((itest==0)&&(iter==nfstart)){ + if((wavetype_start==1||wavetype_start==3)){ + sprintf(modfile,"%s_vp_it%d.bin",INV_MODELFILE,iter); + writemod(modfile,pi,3); + + MPI_Barrier(MPI_COMM_WORLD); + + if (MYID==0) mergemod(modfile,3); + MPI_Barrier(MPI_COMM_WORLD); + sprintf(modfile,"%s_vp_it%d.bin.%i.%i",INV_MODELFILE,iter,POS[1],POS[2]); + remove(modfile); + } + if(!ACOUSTIC){ + sprintf(modfile,"%s_vs_it%d.bin",INV_MODELFILE,iter); + writemod(modfile,u,3); + MPI_Barrier(MPI_COMM_WORLD); + + if (MYID==0) mergemod(modfile,3); + MPI_Barrier(MPI_COMM_WORLD); + sprintf(modfile,"%s_vs_it%d.bin.%i.%i",INV_MODELFILE,iter,POS[1],POS[2]); + remove(modfile); + } + + sprintf(modfile,"%s_rho_it%d.bin",INV_MODELFILE,iter); + writemod(modfile,rho,3); + MPI_Barrier(MPI_COMM_WORLD); + + if (MYID==0) mergemod(modfile,3); + MPI_Barrier(MPI_COMM_WORLD); + sprintf(modfile,"%s_rho_it%d.bin.%i.%i",INV_MODELFILE,iter,POS[1],POS[2]); + remove(modfile); + + if (WAVETYPE==2 || WAVETYPE==3) { + + sprintf(modfile,"%s_vshor_it%d.bin",INV_MODELFILE,iter); + writemod(modfile,vshor,3); + MPI_Barrier(MPI_COMM_WORLD); + + if (MYID==0) mergemod(modfile,3); + MPI_Barrier(MPI_COMM_WORLD); + sprintf(modfile,"%s_vshor_it%d.bin.%i.%i",INV_MODELFILE,iter,POS[1],POS[2]); + remove(modfile); + } + + } + + if(VERBOSE&&(itest==1)){ + if((wavetype_start==1||wavetype_start==3)){ + + sprintf(modfile,"%s_vp.step.bin",INV_MODELFILE); + writemod(modfile,pinp1,3); + + MPI_Barrier(MPI_COMM_WORLD); + + if (MYID==0) mergemod(modfile,3); + + MPI_Barrier(MPI_COMM_WORLD); + sprintf(modfile,"%s_vp.step.bin.%i.%i",INV_MODELFILE,POS[1],POS[2]); + remove(modfile); + + } + if(!ACOUSTIC){ + + sprintf(modfile,"%s_vs.step.bin",INV_MODELFILE); + + writemod(modfile,unp1,3); + + MPI_Barrier(MPI_COMM_WORLD); + + if (MYID==0) mergemod(modfile,3); + + MPI_Barrier(MPI_COMM_WORLD); + sprintf(modfile,"%s_vs.step.bin.%i.%i",INV_MODELFILE,POS[1],POS[2]); + remove(modfile); + + } + + + sprintf(modfile,"%s_rho.step.bin",INV_MODELFILE); + writemod(modfile,rho,3); + + MPI_Barrier(MPI_COMM_WORLD); + + if (MYID==0) mergemod(modfile,3); + + MPI_Barrier(MPI_COMM_WORLD); + sprintf(modfile,"%s_rho.bin.step.%i.%i",INV_MODELFILE,POS[1],POS[2]); + remove(modfile); + + } +} \ No newline at end of file diff --git a/src/change_parameterization_vti.c b/src/change_parameterization_vti.c new file mode 100644 index 0000000000000000000000000000000000000000..3472542691c898bba74a70e304adf5945277fe57 --- /dev/null +++ b/src/change_parameterization_vti.c @@ -0,0 +1,43 @@ +/* This file is part of IFOS. + * + * IFOS is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, version 2.0 of the License only. + * + * IFOS 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with IFOS. See file COPYING and/or . +-----------------------------------------------------------------------------------------*/ + +/*------------------------------------------------------------------------ + * transforms parameters (rho,vp,vs,epsilon,gamma,delta) + * into (rho,c11,c13,c33,c55,c66) + * and averages c55 and c66 + * ----------------------------------------------------------------------*/ + +#include "fd.h" + + +void change_parameterization_vti(float **rho, float **pi, float **u, float **epsilon, float **delta, float **vshor, + float **c11, float **c13, float **c33, float **c55, float **c66) { + + extern int NX,NY; + int i,j; + + for (j=1;j<=NY;j++){ + for (i=1;i<=NX;i++){ + + c33[j][i]=pi[j][i]*pi[j][i]*rho[j][i]; + c55[j][i]=u[j][i]*u[j][i]*rho[j][i]; + c11[j][i]=c33[j][i]*(1+2*epsilon[j][i]); + c13[j][i]=sqrt(2*delta[j][i]*c33[j][i]*(c33[j][i]-c55[j][i])+(c33[j][i]-c55[j][i])*(c33[j][i]-c55[j][i]))-c55[j][i]; + c66[j][i]=vshor[j][i]*vshor[j][i]*rho[j][i]; + + } + } + +} \ No newline at end of file diff --git a/src/checkfd.c b/src/checkfd.c index f1694c7263206cd419d2c22ea715c75d302b5b7f..efa4284c8a3478522fd1da79142bbf5afe6fef27 100644 --- a/src/checkfd.c +++ b/src/checkfd.c @@ -26,11 +26,12 @@ #include #include "fd.h" -void checkfd(FILE *fp, float ** prho, float ** ppi, float ** pu, float ** ptaus, float ** ptaup, float *peta, float *hc, float **srcpos, int nsrc, int **recpos, int ntr){ +void checkfd(FILE *fp, float ** prho, float ** ppi, float ** pu, float ** ptaus, float ** ptaup, float *peta, float *hc, float **srcpos, int nsrc, int **recpos, int ntr, + float ** pepsilon, float ** pdelta, float ** pvshor) { extern float DH, DT, TS; extern float XREC1, XREC2, YREC1, YREC2; - extern int NX, NY, MYID, PARAMETERIZATION, FW, L, NT, NDT, ACOUSTIC; + extern int NX, NY, MYID, PARAMETERIZATION, FW, VTI, L, NT, NDT, ACOUSTIC; extern int READREC, NPROCX,NPROCY, SRCREC, FREE_SURF; extern int SEISMO, SEIS_FORMAT[6]; extern char SOURCE_FILE[STRING_SIZE], REC_FILE[STRING_SIZE]; @@ -38,6 +39,7 @@ void checkfd(FILE *fp, float ** prho, float ** ppi, float ** pu, float ** ptaus, /* local variables */ float c = 0.0, cmax_p=0.0, cmin_p=1e9, cmax_s=0.0, cmin_s=1e9, fmax, gamma; + float chor, cmax_phor=0.0, cmin_phor=1e9, cmax_shor=0, cmin_shor=1e9; float cmax=0.0, cmin=1e9, dtstab, dhstab, cmax_r, cmin_r; float sumu, sumpi, ws, ts, ppi_ref = 0.0, pu_ref; int nfw=iround(FW/DH); @@ -89,17 +91,35 @@ void checkfd(FILE *fp, float ** prho, float ** ppi, float ** pu, float ** ptaus, } } } else { /*L=0, elastic*/ - for (i=1+nfw;i<=(nx-nfw);i++){ - for (j=ny1;j<=(ny-nfw);j++){ - - if(PARAMETERIZATION==3){ - c=sqrt(pu[j][i]/prho[j][i]); - } else { - c=pu[j][i]; + if (VTI) { + for (i=1+nfw; i<= (nx-nfw); i++) { + for (j=ny1; j<= (ny-nfw); j++) { + c=pu[j][i]; /* vertical s-velocity */ + chor=pvshor[j][i]; /* horizontal s-velocity */ + + if (cmax_sc) cmin_s=c; + if (cmax_shorchor) cmin_shor=chor; + + if (cmax_shor>cmax_s) cmax_s=cmax_shor; + if (cmin_shorc) cmin_s=c; + if(PARAMETERIZATION==3){ + c=sqrt(pu[j][i]/prho[j][i]); + } else { + c=pu[j][i]; + } + + if (cmax_sc) cmin_s=c; + } } } } @@ -137,20 +157,38 @@ void checkfd(FILE *fp, float ** prho, float ** ppi, float ** pu, float ** ptaus, } } else{ /*L=0, elastic*/ - for (i=1+nfw;i<=(nx-nfw);i++){ - for (j=ny1;j<=(ny-nfw);j++){ + if (VTI) { + for (i=1+nfw; i<= (nx-nfw); i++) { + for (j=ny1; j<= (ny-nfw); j++) { + c=ppi[j][i]; /* vertical p-velocity */ + chor=c*(1+pepsilon[j][i]); /* horizontal p-velocity */ + + if (cmax_pc) cmin_p=c; + if (cmax_phorchor) cmin_phor=chor; + + if (cmax_phor>cmax_p) cmax_p=cmax_phor; + if (cmin_phorc) cmin_p=c; + if (cmax_pc) cmin_p=c; + } } - } - + } } diff --git a/src/exchange_par.c b/src/exchange_par.c index 5c0c4a189ffc0ac2d2abf0da40873597d5fc7e49..1c7a58573fc10d6e6f0349db2c60cb83ce0cb9b6 100644 --- a/src/exchange_par.c +++ b/src/exchange_par.c @@ -25,10 +25,10 @@ void exchange_par(void){ /* declaration of extern variables */ - extern int NX, NY, FDORDER, MAXRELERROR, SOURCE_SHAPE, SOURCE_TYPE, SNAP, SNAP_FORMAT, L; + extern int NX, NY, FDORDER, MAXRELERROR, SOURCE_SHAPE, SOURCE_TYPE, SNAP, SNAP_FORMAT, L, VTI; extern float DH, TIME, DT, TS, *FL, TAU, VPPML, PLANE_WAVE_DEPTH, PHI, F_REF; extern float XREC1, XREC2, YREC1, YREC2, FPML; - extern float REC_ARRAY_DEPTH, REC_ARRAY_DIST, MUN, EPSILON, EPSILON_u, EPSILON_rho; + extern float REC_ARRAY_DEPTH, REC_ARRAY_DIST, MUN, EPSILON, EPSILON_u, EPSILON_rho, EPSILON_vshor; extern int SEISMO, NDT, NGEOPH, SEIS_FORMAT, FREE_SURF, READMOD, READREC, SRCREC; extern int BOUNDARY, REC_ARRAY, DRX, FW; extern int SNAPSHOT_START,SNAPSHOT_END,SNAPSHOT_INCR; @@ -51,11 +51,11 @@ void exchange_par(void){ extern float SRTRADIUS; extern char TAPER_FILE_NAME[STRING_SIZE]; extern int SPATFILTER, SPAT_FILT_SIZE, SPAT_FILT_1, SPAT_FILT_ITER; - extern int INV_RHO_ITER, INV_VP_ITER, INV_VS_ITER; + extern int INV_RHO_ITER, INV_VP_ITER, INV_VS_ITER, INV_VSHOR_ITER; extern int MIN_ITER; extern int nfstart, nf; extern int nfstart_jac, nf_jac; - extern float VPUPPERLIM, VPLOWERLIM, VSUPPERLIM, VSLOWERLIM, RHOUPPERLIM, RHOLOWERLIM; + extern float VPUPPERLIM, VPLOWERLIM, VSUPPERLIM, VSLOWERLIM, RHOUPPERLIM, RHOLOWERLIM, VSHORUPPERLIM, VSHORLOWERLIM; extern float npower, k_max_PML; extern int INV_STF, N_STF, N_STF_START; extern char PARA[STRING_SIZE]; @@ -74,7 +74,7 @@ void exchange_par(void){ extern char MISFIT_LOG_FILE[STRING_SIZE]; extern int VELOCITY; extern float WATERLEVEL_LNORM8; - extern float VP_VS_RATIO; + extern float VP_VS_RATIO, GAMMA_VTI; extern int S; extern float S_VP, S_VS, S_RHO; extern int GRAD_FILT_WAVELENGTH; @@ -162,6 +162,7 @@ void exchange_par(void){ fdum[27] = EPSILON; fdum[28] = EPSILON_u; fdum[29] = EPSILON_rho; + fdum[30] = EPSILON_vshor; fdum[31] = FPML; fdum[32] = SRTRADIUS; @@ -221,6 +222,10 @@ void exchange_par(void){ fdum[69]=TRKILL_OFFSET_UPPER; fdum[70]=LBFGS_SCALE_GRADIENTS; + + fdum[71]=VSHORUPPERLIM; + fdum[72]=VSHORLOWERLIM; + fdum[73]=GAMMA_VTI; /***********/ /* Integer */ @@ -253,6 +258,8 @@ void exchange_par(void){ idum[26] = NGEOPH; idum[27] = NDT; idum[28] = SEIS_FORMAT; + + idum[29] = VTI; idum[31] = FDORDER; @@ -377,6 +384,8 @@ void exchange_par(void){ idum[116]=TRKILL_STF_OFFSET_INVERT; idum[117]=JOINT_EQUAL_WEIGHTING; + + idum[118]=INV_VSHOR_ITER; } /** if (MYID == 0) **/ @@ -444,6 +453,7 @@ void exchange_par(void){ EPSILON = fdum[27]; EPSILON_u = fdum[28]; EPSILON_rho = fdum[29]; + EPSILON_vshor = fdum[30]; FPML = fdum[31]; SRTRADIUS = fdum[32]; @@ -506,6 +516,10 @@ void exchange_par(void){ LBFGS_SCALE_GRADIENTS=fdum[70]; + VSHORUPPERLIM=fdum[71]; + VSHORLOWERLIM=fdum[72]; + GAMMA_VTI=fdum[73]; + /***********/ /* Integer */ /***********/ @@ -537,6 +551,8 @@ void exchange_par(void){ NGEOPH = idum[26]; NDT = idum[27]; SEIS_FORMAT = idum[28]; + + VTI = idum[29]; FDORDER = idum[31]; @@ -665,6 +681,8 @@ void exchange_par(void){ JOINT_EQUAL_WEIGHTING=idum[117]; + INV_VSHOR_ITER=idum[118]; + if ( MYID!=0 && L>0 ) { FL=vector(1,L); } diff --git a/src/fd.h b/src/fd.h index abe206801fbb84528f44a08e73cc7bb813f24e38..06b64c9d6d928d4384039fa30c4d917de8209d91 100644 --- a/src/fd.h +++ b/src/fd.h @@ -60,6 +60,8 @@ void av_rho(float **rho, float **rip, float **rjp); void av_tau(float **taus, float **tausipjp); +void av_c55c66(float **c55s, float **c55sipjp, float **c66s, float **c66sipjp); + float median2d(float **mat, int ny, int nx); void calc_mat_change(float ** waveconv, float ** waveconv_rho, float ** waveconv_u, float ** rho, float ** rhonp1, float ** pi, float ** pinp1, float ** u, @@ -68,6 +70,11 @@ void calc_mat_change(float ** waveconv, float ** waveconv_rho, float ** waveco void calc_mat_change_test(float ** waveconv, float ** waveconv_rho, float ** waveconv_u, float ** rho, float ** rhonp1, float ** pi, float ** pinp1, float ** u, float ** unp1, int iter, int epstest, int FORWARD_ONLY, float eps_scale, int itest, int nfstart, float ** u_start, float ** pi_start, float ** rho_start,int wavetype_start,float **bfgsmod,int bfgsnum,int bfgspar,float Vs_avg,float Vp_avg,float rho_avg,int LBFGS_iter_start); +void calc_mat_change_test_vti(float ** waveconv, float ** waveconv_rho, float ** waveconv_u, float **waveconv_gam, + float ** rho, float ** rhonp1, float ** pi, float ** pinp1, float ** u, float ** unp1, float **gamma, float **gamnp1, int iter, + int epstest, int FORWARD_ONLY, float eps_scale, int itest, int nfstart, float ** u_start, float ** pi_start, float ** rho_start,int wavetype_start, + float **s_LBFGS,int N_LBFGS,int LBFGS_NPAR,float Vs_avg,float Vp_avg,float rho_avg,float vshor_avg,int LBFGS_iter_start); + double calc_res(float **sectiondata, float **section, float **sectiondiff, float **sectiondiffold, int ntr, int ns, int LNORM, float L2, int itest, int sws, int swstestshot, int ntr_glob, int **recpos_loc, int nsrc_glob, int ishot, int iter, float ** srcpos, int ** recpos); double calc_misfit(float **sectiondata, float **section, int ntr, int ns, int LNORM, float L2, int itest, int sws, int swstestshot,int ntr_glob, int **recpos_loc, int nsrc_glob, int ishot, int iter, float ** srcpos, int ** recpos); @@ -78,7 +85,10 @@ float calc_opt_step_test(float * L2t, float ** waveconv, float ** gradp, float double calc_energy(float **sectiondata, int ntr, int ns, float energy, int ntr_glob, int **recpos_loc, int nsrc_glob, int ishot, int iter, float ** srcpos, int ** recpos); -void checkfd(FILE *fp, float ** prho, float ** ppi, float ** pu, float ** ptaus, float ** ptaup, float * peta, float *hc, float **srcpos, int nsrc, int **recpos, int ntr); +void change_parameterization_vti(float **rho, float **pi, float **u, float **epsilon, float **delta, float **vshor, + float **c11, float **c13, float **c33, float **c55, float **c66); + +void checkfd(FILE *fp, float ** prho, float ** ppi, float ** pu, float ** ptaus, float ** ptaup, float * peta, float *hc, float **srcpos, int nsrc, int **recpos, int ntr, float **pepsilon, float **pdelta, float **pgamma); void checkfd_hc(FILE *fp, float ** prho, float ** ppi, float ** pu, float ** ptaus, float ** ptaup, float *peta, float *hc); @@ -154,6 +164,8 @@ void model(float ** rho, float ** pi, float ** u, void model_elastic(float ** rho, float ** pi, float ** u); +void model_elastic_vti(float ** rho, float ** pi, float ** u, float ** delta, float ** epsilon, float ** vshor ); + void model_ani(float ** rho, float ** c11, float ** c15, float ** c13, float ** c35, float ** c33, float ** c55, float ** taus, float ** taup, float * eta); @@ -161,8 +173,12 @@ void model_ani(float ** rho, float ** c11, float ** c15, float ** c13, void matcopy(float ** prho, float ** ppi, float ** pu, float ** ptaup, float ** ptaus); +void matcopy_vti(float ** rho, float ** c11, float ** c13, float ** c33, float ** c55, float ** c66, float ** taus, float **taup); + void matcopy_elastic(float ** prho, float ** ppi, float ** pu); +void matcopy_elastic_vti(float ** rho, float ** c11, float ** c13, float ** c33, float ** c55, float ** c66); + void matcopy_ani(float ** rho, float ** c11, float ** c15, float ** c13, float ** c35, float ** c33, float ** c55, float ** taus, float ** taup); @@ -198,6 +214,9 @@ void PCG(float ** waveconv, float ** taper_coeff, int nsrc, float ** srcpos, int void PCG_SH(float ** taper_coeff, int nsrc, float ** srcpos, int ** recpos, int ntr_glob, int iter, int nfstart_jac, float ** waveconv_u, float C_vs, float ** gradp_u, float ** waveconv_rho, float C_rho, float ** gradp_rho, float Vs_avg, float F_LOW_PASS, int PCG_iter_start); +void PCG_SH_vti(float ** taper_coeff, int nsrc, float ** srcpos, int ** recpos, int ntr_glob, int iter, int nfstart_jac, float ** waveconv_u, float C_vs, float ** gradp_u, + float ** waveconv_rho, float C_rho, float ** gradp_rho, float **waveconv_gam, float C_gamma, float **gradp_gam, float Vs_avg, float F_LOW_PASS, int PCG_iter_start); + void PML_pro(float * d_x, float * K_x, float * alpha_prime_x, float * a_x, float * b_x, float * d_x_half, float * K_x_half, float * alpha_prime_x_half, float * a_x_half, float * b_x_half, float * d_y, float * K_y, float * alpha_prime_y, float * a_y, float * b_y, @@ -230,10 +249,15 @@ void read_par_json(FILE *fp, char *fileinp); void readmod(float ** rho, float ** pi, float ** u, float ** taus, float ** taup, float * eta); +void readmod_vti(float ** rho, float ** pi, float ** u, float **delta, + float **epsilon, float **vshor, float **taus, float **taup, float * eta); + void readmod_elastic(float ** rho, float ** pi, float ** u); void readmod_elastic_es(float ** rho, float ** pi, float ** u, float ** matmod, int is); +void readmod_el_vti(float ** rho, float ** pi, float ** u, float **delta, float **epsilon, float **vshor); + int **receiver(int* ntr, float** srcpos, int shotno); void save_checkpoint(int nx1, int nx2, int ny1, int ny2, @@ -285,6 +309,11 @@ void surface_elastic(int ndepth, float ** vx, float ** vy, float ** sxx, float * void surface_elastic_PML(int ndepth, float ** vx, float ** vy, float ** sxx, float ** syy, float ** sxy, float ** syz, float ** pi, float ** u, float ** rho, float * hc, float * K_x, float * a_x, float * b_x, float ** psi_vxx, float ** ux, float ** uy, float ** uxy, float ** uyz,float ** sxz,float **uxz); +void surface_el_vti_PML(int ndepth, float ** vx, float ** vy, float ** sxx, float ** syy, + float ** sxy, float ** syz, float ** c11, float ** c13, float ** c33, + float ** rho, float * hc, float * K_x, float * a_x, float * b_x, float ** psi_vxx, + float ** ux, float ** uy, float ** uxy, float ** uyz,float ** sxz,float **uxz); + void surface_PML(int ndepth, float ** vx, float ** vy, float ** sxx, float ** syy, float ** sxy, float ** syz, float ***p, float ***q, float ** ppi, float ** pu, float **prho, float **ptaup, float **ptaus, float *etajm, float *peta, float * hc, float * K_x, float * a_x, float * b_x, float ** psi_vxx, float ** ux, float ** uy, float ** uxy, float ** uyz,float ** sxz,float **uxz); void timedomain_filt(float ** data, float fc, int order, int ntr, int ns, int method); @@ -298,6 +327,11 @@ void prepare_update_s(float *etajm, float *etaip, float *peta, float **fipjp, fl float **ptausipjp, float **f, float **g, float *bip, float *bjm, float *cip, float *cjm, float ***dip, float ***d, float ***e); +void prepare_update_s_vti(float *etajm, float *etaip, float *peta, float **fipjp, float **pc55, + float **pc66ipjp, float **ppi, float **prho, float **ptaus, float **ptaup, + float **ptausipjp, float **f, float **g, float *bip, float *bjm, + float *cip, float *cjm, float ***dip, float ***d, float ***e); + void update_s(int nx1, int nx2, int ny1, int ny2, float ** vx, float ** vy, float ** sxx, float ** syy, float ** sxy, float *** r, float *** p, float *** q, @@ -313,7 +347,15 @@ void update_s_visc_hc(int nx1, int nx2, int ny1, int ny2, void update_s_elastic_PML_SH(int nx1, int nx2, int ny1, int ny2, float ** vz, float ** sxz, float ** syz, float ** uxz, float ** uyz, float *hc, int infoout,float * K_x, float * a_x, float * b_x, float * K_x_half, float * a_x_half, float * b_x_half, float * K_y, float * a_y, float * b_y, float * K_y_half, float * a_y_half, float * b_y_half,float ** psi_vzx, float ** psi_vzy,float ** uipjp,float ** u,float ** rho); -void update_s_visc_PML_SH(int nx1, int nx2, int ny1, int ny2, float ** vz, float ** sxz, float ** syz, float ***t, float ***o, float *bip, float *bjm, float *cip, float *cjm, float ***d, float ***dip, float **fipjp, float **f, float *hc, int infoout,float * K_x, float * a_x, float * b_x, float * K_x_half, float * a_x_half, float * b_x_half,float * K_y, float * a_y, float * b_y, float * K_y_half, float * a_y_half, float * b_y_half,float ** psi_vzx, float ** psi_vzy); +void update_s_el_vti_PML_SH(int nx1, int nx2, int ny1, int ny2, float ** vz, float ** sxz, float ** syz, float ** uxz, float ** uyz, float *hc, int infoout,float * K_x, float * a_x, float * b_x, float * K_x_half, float * a_x_half, float * b_x_half, + float * K_y, float * a_y, float * b_y, float * K_y_half, float * a_y_half, float * b_y_half,float ** psi_vzx, float ** psi_vzy, float ** c55,float ** c66ipjp, float ** rho); + +void update_s_visc_PML_SH(int nx1, int nx2, int ny1, int ny2, float ** vz, float ** uxz, float ** uyz, float ** sxz, float ** syz, float ***t, float ***o, float *bip, float *bjm, float *cip, float *cjm, float ***d, float ***dip, float **fipjp, float **f, float *hc, int infoout,float * K_x, float * a_x, float * b_x, float * K_x_half, float * a_x_half, float * b_x_half,float * K_y, float * a_y, float * b_y, float * K_y_half, float * a_y_half, float * b_y_half,float ** psi_vzx, float ** psi_vzy); + +void update_s_visc_vti_PML_SH(int nx1, int nx2, int ny1, int ny2, float ** vz, float ** uxz, float ** uyz, float ** sxz, float ** syz, + float ***t, float ***o, float *bip, float *bjm, float *cip, float *cjm, float ***d, float ***dip, float **fipjp, float **f, + float *hc, int infoout,float * K_x, float * a_x, float * b_x, float * K_x_half, float * a_x_half, float * b_x_half, + float * K_y, float * a_y, float * b_y, float * K_y_half, float * a_y_half, float * b_y_half,float ** psi_vzx, float ** psi_vzy, float ** c55,float ** c66ipjp, float ** rho); void update_s_rsg(int nx1, int nx2, int ny1, int ny2, float ** pvx, float ** pvy, float ** psxx, float ** psyy, @@ -356,6 +398,13 @@ void update_s_elastic_PML(int nx1, int nx2, int ny1, int ny2, float * K_y, float * a_y, float * b_y, float * K_y_half, float * a_y_half, float * b_y_half, float ** psi_vxx, float ** psi_vyy, float ** psi_vxy, float ** psi_vyx); +void update_s_el_vti_PML(int nx1, int nx2, int ny1, int ny2, + float ** vx, float ** vy, float ** ux, float ** uy, float ** uxy, float ** uyx, float ** sxx, float ** syy, + float ** sxy, float ** c11, float ** c13, float ** c33, float ** c55, float ** absorb_coeff, float **rho, float *hc, int infoout, + float * K_x, float * a_x, float * b_x, float * K_x_half, float * a_x_half, float * b_x_half, + float * K_y, float * a_y, float * b_y, float * K_y_half, float * a_y_half, float * b_y_half, + float ** psi_vxx, float ** psi_vyy, float ** psi_vxy, float ** psi_vyx); + void update_s_elastic_hh(int nx1, int nx2, int ny1, int ny2, float ** vx, float ** vy, float ** sxx, float ** syy, float ** sxy, float ** pi, float ** u ); @@ -536,12 +585,13 @@ void write_matrix_disk(float ** gradient,char path_name[STRING_SIZE]); float matrix_product(float ** matrix1, float **matrix2); /* L-BFGS */ -void lbfgs(float **grad1, float **grad2, float **grad3,float Vs_avg,float rho_avg,float Vp_avg, float *bfgsscale, float **bfgsmod, float **bfgsgrad,int bfgsnum,int bfgspar, int iteration, int * LBFGS_iter_start); +void lbfgs(float **grad1, float **grad2, float **grad3, float **grad4, float Vs_avg,float rho_avg,float Vp_avg, float vshor_avg, float *bfgsscale, float **bfgsmod, float **bfgsgrad,int bfgsnum,int bfgspar, int iteration, int * LBFGS_iter_start); void lbfgs_reset(int iter, int bfgsnum, int bfgspar,float ** bfgsmod1, float ** bfgsgrad1, float * bfgsscale1); void lbfgs_core(int iteration, int N_LBFGS, int NPAR_LBFGS,float ** s_LBFGS, float ** y_LBFGS, float * rho_LBFGS,float *q_LBFGS,float *alpha_LBFGS,float *r_LBFGS); /* Wolfe condition */ -int check_wolfe(float steplength, float misfit_old, float misfit_new, float ** grad_old_vs, float ** grad_new_vs, float ** update_vs, float ** grad_old_rho, float ** grad_new_rho, float ** update_rho, float ** grad_old_vp, float ** grad_new_vp, float ** update_vp, float c1, float c2, int NPAR_LBFGS); +int check_wolfe(float steplength, float misfit_old, float misfit_new, float ** grad_old_vs, float ** grad_new_vs, float ** update_vs, float ** grad_old_rho, float ** grad_new_rho, float ** update_rho, float ** grad_old_vp, float ** grad_new_vp, float ** update_vp, + float **grad_old_vshor, float **grad_new_vshor, float **update_vshor, float c1, float c2, int NPAR_LBFGS); void wolfe_linesearch(int wolfe_status, float *alpha_SL_min, float *alpha_SL_max, float *alpha_SL); /* functions for viscoacoustic modelling */ diff --git a/src/globvar.h b/src/globvar.h index 41be6bf657eccefd2eb47d1c1d5db6c45d71ca9d..3e94fb4073ab48316baf47c63989e15db5cb7f2d 100644 --- a/src/globvar.h +++ b/src/globvar.h @@ -15,7 +15,7 @@ float REC_ARRAY_DEPTH, REC_ARRAY_DIST; float REFREC[4]={0.0, 0.0, 0.0, 0.0}, FPML; int SEISMO, NDT, NGEOPH, NSRC=1, SEIS_FORMAT, FREE_SURF, READMOD, READREC, SRCREC, FW=0; int NX, NY, NT, SOURCE_SHAPE,SOURCE_SHAPE_SH, SOURCE_TYPE, SNAP, SNAP_FORMAT, REC_ARRAY, RUN_MULTIPLE_SHOTS, NTRG; -int L, BOUNDARY, DC, DRX, NXG, NYG, IDX, IDY, FDORDER, MAXRELERROR; +int VTI, L, BOUNDARY, DC, DRX, NXG, NYG, IDX, IDY, FDORDER, MAXRELERROR; char SNAP_FILE[STRING_SIZE], SOURCE_FILE[STRING_SIZE], SIGNAL_FILE[STRING_SIZE], SIGNAL_FILE_SH[STRING_SIZE]; char MFILE[STRING_SIZE], REC_FILE[STRING_SIZE]; char LOG_FILE[STRING_SIZE]; @@ -45,7 +45,7 @@ int ITERMAX, REC1, REC2, PARAMETERIZATION, FORWARD_ONLY, ADJOINT_TYPE; int GRAD_METHOD; float TSHIFT_back; int MODEL_FILTER, FILT_SIZE; -float EPSILON, MUN, EPSILON_u, EPSILON_rho; +float EPSILON, MUN, EPSILON_u, EPSILON_rho, EPSILON_vshor; int TESTSHOT_START, TESTSHOT_END, TESTSHOT_INCR, NO_OF_TESTSHOTS; int SWS_TAPER_GRAD_VERT, SWS_TAPER_GRAD_HOR, SWS_TAPER_GRAD_SOURCES, SWS_TAPER_CIRCULAR_PER_SHOT, SRTSHAPE, FILTSIZE; @@ -55,7 +55,7 @@ char TAPER_FILE_NAME[STRING_SIZE]; int SPATFILTER, SPAT_FILT_SIZE, SPAT_FILT_1, SPAT_FILT_ITER; -int INV_RHO_ITER, INV_VS_ITER, INV_VP_ITER; +int INV_RHO_ITER, INV_VS_ITER, INV_VP_ITER, INV_VSHOR_ITER; int MIN_ITER; @@ -64,7 +64,7 @@ int nfstart, nf; int nfstart_jac, nf_jac; -float VPUPPERLIM, VPLOWERLIM, VSUPPERLIM, VSLOWERLIM, RHOUPPERLIM, RHOLOWERLIM; +float VPUPPERLIM, VPLOWERLIM, VSUPPERLIM, VSLOWERLIM, RHOUPPERLIM, RHOLOWERLIM, VSHORUPPERLIM, VSHORLOWERLIM; float npower, k_max_PML; @@ -129,6 +129,8 @@ float WATERLEVEL_LNORM8; float VP_VS_RATIO; +float GAMMA_VTI; + int S; float S_VP, S_VS, S_RHO; diff --git a/src/matcopy_elastic_vti.c b/src/matcopy_elastic_vti.c new file mode 100644 index 0000000000000000000000000000000000000000..c8f528229aeb9a85ae16f99b4d0a53c528670499 --- /dev/null +++ b/src/matcopy_elastic_vti.c @@ -0,0 +1,177 @@ +/*----------------------------------------------------------------------------------------- + * Copyright (C) 2016 For the list of authors, see file AUTHORS. + * + * This file is part of IFOS. + * + * IFOS is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as pc13blished by + * the Free Software Foc13ndation, version 2.0 of the License only. + * + * IFOS 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 General Pc13blic License for more details. + * + * You should have received a copy of the GNU General Public License + * along with IFOS. See file COPYING and/or . +-----------------------------------------------------------------------------------------*/ + +/*------------------------------------------------------------------------ + * For the averaging of material properties each process requires valc13es + * at the indices 0 and NX+1 etc. These lie on the neighbouring processes. + * Thus, they have to be coc11ed which is done by this function. + * + * + * ----------------------------------------------------------------------*/ + +#include "fd.h" + +void matcopy_elastic_vti(float ** rho, float ** c11, float ** c13, float ** c33, float ** c55, float ** c66){ + + extern int MYID, NX, NY, INDEX[5],VERBOSE; + extern const int TAG1,TAG2,TAG5,TAG6; + extern FILE *FP; + + + MPI_Status status; + double time1, time2; + int i, j; + float ** bufferlef_to_rig_1, ** bufferrig_to_lef_1; + float ** buffertop_to_bot_1, ** bufferbot_to_top_1; + + bufferlef_to_rig_1 = matrix(0,NY+1,1,6); + bufferrig_to_lef_1 = matrix(0,NY+1,1,6); + buffertop_to_bot_1 = matrix(0,NX+1,1,6); + bufferbot_to_top_1 = matrix(0,NX+1,1,6); + + if(VERBOSE){ + fprintf(FP,"\n\n **Message from matcopy (written by PE %d):",MYID); + fprintf(FP,"\n Copy material properties at inner boundaries ... \n"); + time1=MPI_Wtime(); + } + + + +/* if (POS[2]!=0)*/ /* no boundary exchange at top of global grid */ + for (i=0;i<=NX+1;i++){ + /* storage of top of local volc13me into buffer */ + buffertop_to_bot_1[i][1] = rho[1][i]; + buffertop_to_bot_1[i][2] = c11[1][i]; + buffertop_to_bot_1[i][3] = c13[1][i]; + buffertop_to_bot_1[i][4] = c33[1][i]; + buffertop_to_bot_1[i][5] = c55[1][i]; + buffertop_to_bot_1[i][6] = c66[1][i]; + } + + +/* if (POS[2]!=NPROCY-1)*/ /* no boc13ndary exchange at bottom of global grid */ + for (i=0;i<=NX+1;i++){ + + /* storage of bottom of local volume into buffer */ + bufferbot_to_top_1[i][1] = rho[NY][i]; + bufferbot_to_top_1[i][2] = c11[NY][i]; + bufferbot_to_top_1[i][3] = c13[NY][i]; + bufferbot_to_top_1[i][4] = c33[NY][i]; + bufferbot_to_top_1[i][5] = c55[NY][i]; + bufferbot_to_top_1[i][6] = c66[NY][i]; + } + + + /*=========sending and receiving of the boundaries==========*/ + + MPI_Bsend(&buffertop_to_bot_1[0][1],(NX+2)*6,MPI_FLOAT,INDEX[3],TAG5,MPI_COMM_WORLD); + MPI_Barrier(MPI_COMM_WORLD); + MPI_Recv(&buffertop_to_bot_1[0][1],(NX+2)*6,MPI_FLOAT,INDEX[4],TAG5,MPI_COMM_WORLD,&status); + MPI_Bsend(&bufferbot_to_top_1[0][1],(NX+2)*6,MPI_FLOAT,INDEX[4],TAG6,MPI_COMM_WORLD); + MPI_Barrier(MPI_COMM_WORLD); + MPI_Recv(&bufferbot_to_top_1[0][1],(NX+2)*6,MPI_FLOAT,INDEX[3],TAG6,MPI_COMM_WORLD,&status); + + +/* if (POS[2]!=NPROCY-1)*/ /* no boundary exchange at bottom of global grid */ + for (i=0;i<=NX+1;i++){ + rho[NY+1][i] = buffertop_to_bot_1[i][1]; + c11[NY+1][i] = buffertop_to_bot_1[i][2]; + c13[NY+1][i] = buffertop_to_bot_1[i][3]; + c33[NY+1][i] = buffertop_to_bot_1[i][4]; + c55[NY+1][i] = buffertop_to_bot_1[i][5]; + c66[NY+1][i] = buffertop_to_bot_1[i][6]; + } + +/* if (POS[2]!=0)*/ /* no boc13ndary exchange at top of global grid */ + for (i=0;i<=NX+1;i++){ + rho[0][i] = bufferbot_to_top_1[i][1]; + c11[0][i] = bufferbot_to_top_1[i][2]; + c13[0][i] = bufferbot_to_top_1[i][3]; + c33[0][i] = bufferbot_to_top_1[i][4]; + c55[0][i] = bufferbot_to_top_1[i][5]; + c66[0][i] = bufferbot_to_top_1[i][6]; + } + + + + +/* if (POS[1]!=0)*/ /* no boundary exchange at left edge of global grid */ + for (j=0;j<=NY+1;j++) + { + /* storage of left edge of local volc13me into buffer */ + bufferlef_to_rig_1[j][1] = rho[j][1]; + bufferlef_to_rig_1[j][2] = c11[j][1]; + bufferlef_to_rig_1[j][3] = c13[j][1]; + bufferlef_to_rig_1[j][4] = c33[j][1]; + bufferlef_to_rig_1[j][5] = c55[j][1]; + bufferlef_to_rig_1[j][6] = c66[j][1]; + } + + +/* if (POS[1]!=NPROCX-1)*/ /* no boundary exchange at right edge of global grid */ + for (j=0;j<=NY+1;j++){ + /* storage of right edge of local volume into buffer */ + bufferrig_to_lef_1[j][1] = rho[j][NX]; + bufferrig_to_lef_1[j][2] = c11[j][NX]; + bufferrig_to_lef_1[j][3] = c13[j][NX]; + bufferrig_to_lef_1[j][4] = c33[j][NX]; + bufferrig_to_lef_1[j][5] = c55[j][NX]; + bufferrig_to_lef_1[j][6] = c66[j][NX]; + } + + + + MPI_Bsend(&bufferlef_to_rig_1[0][1],(NY+2)*6,MPI_FLOAT,INDEX[1],TAG1,MPI_COMM_WORLD); + MPI_Barrier(MPI_COMM_WORLD); + MPI_Recv(&bufferlef_to_rig_1[0][1],(NY+2)*6,MPI_FLOAT,INDEX[2],TAG1,MPI_COMM_WORLD,&status); + MPI_Bsend(&bufferrig_to_lef_1[0][1],(NY+2)*6,MPI_FLOAT,INDEX[2],TAG2,MPI_COMM_WORLD); + MPI_Barrier(MPI_COMM_WORLD); + MPI_Recv(&bufferrig_to_lef_1[0][1],(NY+2)*6,MPI_FLOAT,INDEX[1],TAG2,MPI_COMM_WORLD,&status); + + +/* if (POS[1]!=NPROCX-1)*/ /* no boundary exchange at right edge of global grid */ + for (j=0;j<=NY+1;j++){ + rho[j][NX+1] = bufferlef_to_rig_1[j][1]; + c11[j][NX+1] = bufferlef_to_rig_1[j][2]; + c13[j][NX+1] = bufferlef_to_rig_1[j][3]; + c33[j][NX+1] = bufferlef_to_rig_1[j][4]; + c55[j][NX+1] = bufferlef_to_rig_1[j][5]; + c66[j][NX+1] = bufferlef_to_rig_1[j][6]; + } + +/* if (POS[1]!=0)*/ /* no boundary exchange at left edge of global grid */ + for (j=0;j<=NY+1;j++){ + rho[j][0] = bufferrig_to_lef_1[j][1]; + c11[j][0] = bufferrig_to_lef_1[j][2]; + c13[j][0] = bufferrig_to_lef_1[j][3]; + c33[j][0] = bufferrig_to_lef_1[j][4]; + c55[j][0] = bufferrig_to_lef_1[j][5]; + c66[j][0] = bufferrig_to_lef_1[j][6]; + } + + + if (MYID==0&&VERBOSE){ + time2=MPI_Wtime(); + fprintf(FP," finished (real time: %4.2f s).\n",time2-time1); + } + + free_matrix(bufferlef_to_rig_1,0,NY+1,1,6); + free_matrix(bufferrig_to_lef_1,0,NY+1,1,6); + free_matrix(buffertop_to_bot_1,0,NX+1,1,6); + free_matrix(bufferbot_to_top_1,0,NX+1,1,6); +} diff --git a/src/matcopy_vti.c b/src/matcopy_vti.c new file mode 100644 index 0000000000000000000000000000000000000000..ca77d16b793cd8712b3eb59f663f62843cb6c009 --- /dev/null +++ b/src/matcopy_vti.c @@ -0,0 +1,193 @@ +/*----------------------------------------------------------------------------------------- + * Copyright (C) 2016 For the list of authors, see file AUTHORS. + * + * This file is part of IFOS. + * + * IFOS is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as pc13blished by + * the Free Software Foc13ndation, version 2.0 of the License only. + * + * IFOS 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 General Pc13blic License for more details. + * + * You should have received a copy of the GNU General Public License + * along with IFOS. See file COPYING and/or . +-----------------------------------------------------------------------------------------*/ + +/*------------------------------------------------------------------------ + * For the averaging of material properties each process requires valc13es + * at the indices 0 and NX+1 etc. These lie on the neighbouring processes. + * Thus, they have to be coc11ed which is done by this function. + * + * + * ----------------------------------------------------------------------*/ + +#include "fd.h" + +void matcopy_vti(float ** rho, float ** c11, float ** c13, float ** c33, float ** c55, float ** c66, float ** taus, float **taup){ + + extern int MYID, NX, NY, INDEX[5],VERBOSE; + extern const int TAG1,TAG2,TAG5,TAG6; + extern FILE *FP; + + + MPI_Status status; + double time1, time2; + int i, j; + float ** bufferlef_to_rig_1, ** bufferrig_to_lef_1; + float ** buffertop_to_bot_1, ** bufferbot_to_top_1; + + bufferlef_to_rig_1 = matrix(0,NY+1,1,8); + bufferrig_to_lef_1 = matrix(0,NY+1,1,8); + buffertop_to_bot_1 = matrix(0,NX+1,1,8); + bufferbot_to_top_1 = matrix(0,NX+1,1,8); + + if(VERBOSE){ + fprintf(FP,"\n\n **Message from matcopy (written by PE %d):",MYID); + fprintf(FP,"\n Copy material properties at inner boundaries ... \n"); + time1=MPI_Wtime(); + } + + + +/* if (POS[2]!=0)*/ /* no boundary exchange at top of global grid */ + for (i=0;i<=NX+1;i++){ + /* storage of top of local volc13me into buffer */ + buffertop_to_bot_1[i][1] = rho[1][i]; + buffertop_to_bot_1[i][2] = c11[1][i]; + buffertop_to_bot_1[i][3] = c13[1][i]; + buffertop_to_bot_1[i][4] = c33[1][i]; + buffertop_to_bot_1[i][5] = c55[1][i]; + buffertop_to_bot_1[i][6] = c66[1][i]; + buffertop_to_bot_1[i][7] = taus[1][i]; + buffertop_to_bot_1[i][8] = taup[1][i]; + } + + +/* if (POS[2]!=NPROCY-1)*/ /* no boc13ndary exchange at bottom of global grid */ + for (i=0;i<=NX+1;i++){ + + /* storage of bottom of local volume into buffer */ + bufferbot_to_top_1[i][1] = rho[NY][i]; + bufferbot_to_top_1[i][2] = c11[NY][i]; + bufferbot_to_top_1[i][3] = c13[NY][i]; + bufferbot_to_top_1[i][4] = c33[NY][i]; + bufferbot_to_top_1[i][5] = c55[NY][i]; + bufferbot_to_top_1[i][6] = c66[NY][i]; + bufferbot_to_top_1[i][7] = taus[NY][i]; + bufferbot_to_top_1[i][8] = taup[NY][i]; + } + + + /*=========sending and receiving of the boundaries==========*/ + + MPI_Bsend(&buffertop_to_bot_1[0][1],(NX+2)*8,MPI_FLOAT,INDEX[3],TAG5,MPI_COMM_WORLD); + MPI_Barrier(MPI_COMM_WORLD); + MPI_Recv(&buffertop_to_bot_1[0][1],(NX+2)*8,MPI_FLOAT,INDEX[4],TAG5,MPI_COMM_WORLD,&status); + MPI_Bsend(&bufferbot_to_top_1[0][1],(NX+2)*8,MPI_FLOAT,INDEX[4],TAG6,MPI_COMM_WORLD); + MPI_Barrier(MPI_COMM_WORLD); + MPI_Recv(&bufferbot_to_top_1[0][1],(NX+2)*8,MPI_FLOAT,INDEX[3],TAG6,MPI_COMM_WORLD,&status); + + +/* if (POS[2]!=NPROCY-1)*/ /* no boundary exchange at bottom of global grid */ + for (i=0;i<=NX+1;i++){ + rho[NY+1][i] = buffertop_to_bot_1[i][1]; + c11[NY+1][i] = buffertop_to_bot_1[i][2]; + c13[NY+1][i] = buffertop_to_bot_1[i][3]; + c33[NY+1][i] = buffertop_to_bot_1[i][4]; + c55[NY+1][i] = buffertop_to_bot_1[i][5]; + c66[NY+1][i] = buffertop_to_bot_1[i][6]; + taus[NY+1][i] = buffertop_to_bot_1[i][7]; + taup[NY+1][i] = buffertop_to_bot_1[i][8]; + } + +/* if (POS[2]!=0)*/ /* no boc13ndary exchange at top of global grid */ + for (i=0;i<=NX+1;i++){ + rho[0][i] = bufferbot_to_top_1[i][1]; + c11[0][i] = bufferbot_to_top_1[i][2]; + c13[0][i] = bufferbot_to_top_1[i][3]; + c33[0][i] = bufferbot_to_top_1[i][4]; + c55[0][i] = bufferbot_to_top_1[i][5]; + c66[0][i] = bufferbot_to_top_1[i][6]; + taus[0][i] = bufferbot_to_top_1[i][7]; + taup[0][i] = bufferbot_to_top_1[i][8]; + } + + + + +/* if (POS[1]!=0)*/ /* no boundary exchange at left edge of global grid */ + for (j=0;j<=NY+1;j++) + { + /* storage of left edge of local volc13me into buffer */ + bufferlef_to_rig_1[j][1] = rho[j][1]; + bufferlef_to_rig_1[j][2] = c11[j][1]; + bufferlef_to_rig_1[j][3] = c13[j][1]; + bufferlef_to_rig_1[j][4] = c33[j][1]; + bufferlef_to_rig_1[j][5] = c55[j][1]; + bufferlef_to_rig_1[j][6] = c66[j][1]; + bufferlef_to_rig_1[j][7] = taus[j][1]; + bufferlef_to_rig_1[j][8] = taup[j][1]; + } + + +/* if (POS[1]!=NPROCX-1)*/ /* no boundary exchange at right edge of global grid */ + for (j=0;j<=NY+1;j++){ + /* storage of right edge of local volume into buffer */ + bufferrig_to_lef_1[j][1] = rho[j][NX]; + bufferrig_to_lef_1[j][2] = c11[j][NX]; + bufferrig_to_lef_1[j][3] = c13[j][NX]; + bufferrig_to_lef_1[j][4] = c33[j][NX]; + bufferrig_to_lef_1[j][5] = c55[j][NX]; + bufferrig_to_lef_1[j][6] = c66[j][NX]; + bufferrig_to_lef_1[j][7] = taus[j][NX]; + bufferrig_to_lef_1[j][8] = taup[j][NX]; + } + + + + MPI_Bsend(&bufferlef_to_rig_1[0][1],(NY+2)*8,MPI_FLOAT,INDEX[1],TAG1,MPI_COMM_WORLD); + MPI_Barrier(MPI_COMM_WORLD); + MPI_Recv(&bufferlef_to_rig_1[0][1],(NY+2)*8,MPI_FLOAT,INDEX[2],TAG1,MPI_COMM_WORLD,&status); + MPI_Bsend(&bufferrig_to_lef_1[0][1],(NY+2)*8,MPI_FLOAT,INDEX[2],TAG2,MPI_COMM_WORLD); + MPI_Barrier(MPI_COMM_WORLD); + MPI_Recv(&bufferrig_to_lef_1[0][1],(NY+2)*8,MPI_FLOAT,INDEX[1],TAG2,MPI_COMM_WORLD,&status); + + +/* if (POS[1]!=NPROCX-1)*/ /* no boundary exchange at right edge of global grid */ + for (j=0;j<=NY+1;j++){ + rho[j][NX+1] = bufferlef_to_rig_1[j][1]; + c11[j][NX+1] = bufferlef_to_rig_1[j][2]; + c13[j][NX+1] = bufferlef_to_rig_1[j][3]; + c33[j][NX+1] = bufferlef_to_rig_1[j][4]; + c55[j][NX+1] = bufferlef_to_rig_1[j][5]; + c66[j][NX+1] = bufferlef_to_rig_1[j][6]; + taus[j][NX+1] = bufferlef_to_rig_1[j][7]; + taup[j][NX+1] = bufferlef_to_rig_1[j][8]; + } + +/* if (POS[1]!=0)*/ /* no boundary exchange at left edge of global grid */ + for (j=0;j<=NY+1;j++){ + rho[j][0] = bufferrig_to_lef_1[j][1]; + c11[j][0] = bufferrig_to_lef_1[j][2]; + c13[j][0] = bufferrig_to_lef_1[j][3]; + c33[j][0] = bufferrig_to_lef_1[j][4]; + c55[j][0] = bufferrig_to_lef_1[j][5]; + c66[j][0] = bufferrig_to_lef_1[j][6]; + taus[j][0] = bufferrig_to_lef_1[j][7]; + taup[j][0] = bufferrig_to_lef_1[j][8]; + } + + + if (MYID==0&&VERBOSE){ + time2=MPI_Wtime(); + fprintf(FP," finished (real time: %4.2f s).\n",time2-time1); + } + + free_matrix(bufferlef_to_rig_1,0,NY+1,1,8); + free_matrix(bufferrig_to_lef_1,0,NY+1,1,8); + free_matrix(buffertop_to_bot_1,0,NX+1,1,8); + free_matrix(bufferbot_to_top_1,0,NX+1,1,8); +} diff --git a/src/prepare_update_s_vti.c b/src/prepare_update_s_vti.c new file mode 100644 index 0000000000000000000000000000000000000000..eca167b3aebfea5b8b939e8bd141c80d2379766e --- /dev/null +++ b/src/prepare_update_s_vti.c @@ -0,0 +1,108 @@ +/*----------------------------------------------------------------------------------------- + * Copyright (C) 2016 For the list of authors, see file AUTHORS. + * + * This file is part of IFOS. + * + * IFOS is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, version 2.0 of the License only. + * + * IFOS 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with IFOS. See file COPYING and/or . +-----------------------------------------------------------------------------------------*/ + +#include "fd.h" + +void prepare_update_s_vti(float *etajm, float *etaip, float *peta, float **fipjp, float **pc55, + float **pc66ipjp, float **ppi, float **prho, float **ptaus, float **ptaup, + float **ptausipjp, float **f, float **g, float *bip, float *bjm, + float *cip, float *cjm, float ***dip, float ***d, float ***e) { + + extern int NX, NY, L, PARAMETERIZATION, MYID; + extern float DT, *FL; + int i, j, l; + extern char MFILE[STRING_SIZE]; + extern float F_REF; + extern int VERBOSE; + + float sumu, sumpi, ws, *pts; + float c55, pi, c66ipjp; + + /* vector for maxwellbodies */ + pts=vector(1,L); + for (l=1;l<=L;l++) { + pts[l]=1.0/(2.0*PI*FL[l]); + } + + + /*ws=2.0*PI*FL[1];*/ + ws=2.0*PI*F_REF; + if(MYID==0&&VERBOSE)printf("MYID %d: F_REF = %f\n",MYID,F_REF); + + sumu=0.0; + sumpi=0.0; + for (l=1;l<=L;l++){ + sumu=sumu+((ws*ws*pts[l]*pts[l])/(1.0+ws*ws*pts[l]*pts[l])); + sumpi=sumpi+((ws*ws*pts[l]*pts[l])/(1.0+ws*ws*pts[l]*pts[l])); + } + + + for (l=1;l<=L;l++){ + etajm[l] = peta[l]; + etaip[l] = peta[l]; + } + + if (PARAMETERIZATION==1){ + for (j=1;j<=NY;j++){ + for (i=1;i<=NX;i++){ + c55=pc55[j][i]/(1.0+sumu*ptaus[j][i]); + pi=(ppi[j][i]*ppi[j][i]*prho[j][i])/(1.0+sumpi*ptaup[j][i]); + c66ipjp=pc66ipjp[j][i]/(1.0+sumu*ptausipjp[j][i]); + + fipjp[j][i] = c66ipjp*DT*(1.0+L*ptausipjp[j][i]); + f[j][i] = c55*DT*(1.0+L*ptaus[j][i]); + g[j][i] = pi*DT*(1.0+L*ptaup[j][i]); + for (l=1;l<=L;l++){ + bip[l] = 1.0/(1.0+(etaip[l]*0.5)); + bjm[l] = 1.0/(1.0+(etajm[l]*0.5)); + cip[l] = 1.0-(etaip[l]*0.5); + cjm[l] = 1.0-(etajm[l]*0.5); + dip[j][i][l] = c66ipjp*etaip[l]*ptausipjp[j][i]; + d[j][i][l] = c55*etajm[l]*ptaus[j][i]; + e[j][i][l] = pi*etajm[l]*ptaup[j][i]; + } + } + } + } + + /*if (PARAMETERIZATION==3){ + for (j=1;j<=NY;j++){ + for (i=1;i<=NX;i++){ + mu=pu[j][i]/(1.0+sumu*ptaus[j][i]); + pi=(ppi[j][i]+2*pu[j][i])/(1.0+sumpi*ptaup[j][i]); + muipjp=puipjp[j][i]/(1.0+sumu*ptausipjp[j][i]); + + fipjp[j][i] = muipjp*DT*(1.0+L*ptausipjp[j][i]); + f[j][i] = mu*DT*(1.0+L*ptaus[j][i]); + g[j][i] = pi*DT*(1.0+L*ptaup[j][i]); + for (l=1;l<=L;l++){ + bip[l] = 1.0/(1.0+(etaip[l]*0.5)); + bjm[l] = 1.0/(1.0+(etajm[l]*0.5)); + cip[l] = 1.0-(etaip[l]*0.5); + cjm[l] = 1.0-(etajm[l]*0.5); + dip[j][i][l] = muipjp*etaip[l]*ptausipjp[j][i]; + d[j][i][l] = mu*etajm[l]*ptaus[j][i]; + e[j][i][l] = pi*etajm[l]*ptaup[j][i]; + } + } + } + }*/ + + + free_vector(pts,1,L); +} diff --git a/src/read_par_json.c b/src/read_par_json.c index 20d4ee67e3211efbb38f898a25ad80d8a536abf6..1e24ae11762a480b6ce5b75991ebf0ca5ecd1669 100644 --- a/src/read_par_json.c +++ b/src/read_par_json.c @@ -28,7 +28,7 @@ char ** varname_list,** value_list; void read_par_json(FILE *fp, char *fileinp){ /* declaration of extern variables */ - extern int NX, NY, FDORDER, MAXRELERROR, SOURCE_SHAPE,SOURCE_SHAPE_SH, SOURCE_TYPE, SNAP, SNAP_FORMAT, ACOUSTIC, L, VERBOSE, WAVETYPE,JOINT_INVERSION_PSV_SH_TYPE,JOINT_EQUAL_WEIGHTING; + extern int NX, NY, FDORDER, MAXRELERROR, SOURCE_SHAPE,SOURCE_SHAPE_SH, SOURCE_TYPE, SNAP, SNAP_FORMAT, ACOUSTIC, VTI, L, VERBOSE, WAVETYPE,JOINT_INVERSION_PSV_SH_TYPE,JOINT_EQUAL_WEIGHTING; extern float DH, TIME, DT, TS, *FL, TAU, VPPML, PLANE_WAVE_DEPTH, PHI, F_REF,JOINT_INVERSION_PSV_SH_ALPHA_VS,JOINT_INVERSION_PSV_SH_ALPHA_RHO; extern float XREC1, XREC2, YREC1, YREC2, FPML; extern float REC_ARRAY_DEPTH, REC_ARRAY_DIST; @@ -52,11 +52,11 @@ void read_par_json(FILE *fp, char *fileinp){ extern float SRTRADIUS; extern char TAPER_FILE_NAME[STRING_SIZE]; extern int SPATFILTER, SPAT_FILT_SIZE, SPAT_FILT_1, SPAT_FILT_ITER; - extern int INV_RHO_ITER, INV_VS_ITER, INV_VP_ITER; + extern int INV_RHO_ITER, INV_VS_ITER, INV_VP_ITER, INV_VSHOR_ITER; extern char INV_MODELFILE[STRING_SIZE]; extern int nfstart, nf; extern int nfstart_jac, nf_jac; - extern float VPUPPERLIM, VPLOWERLIM, VSUPPERLIM, VSLOWERLIM, RHOUPPERLIM, RHOLOWERLIM; + extern float VPUPPERLIM, VPLOWERLIM, VSUPPERLIM, VSLOWERLIM, RHOUPPERLIM, RHOLOWERLIM, VSHORUPPERLIM, VSHORLOWERLIM; extern float npower, k_max_PML; extern int INV_STF, N_STF, N_STF_START; @@ -100,7 +100,7 @@ void read_par_json(FILE *fp, char *fileinp){ extern float WATERLEVEL_LNORM8; - extern float VP_VS_RATIO; + extern float VP_VS_RATIO, GAMMA_VTI; extern int S; @@ -444,6 +444,9 @@ void read_par_json(FILE *fp, char *fileinp){ if (get_float_from_objectlist("F_REF",number_readobjects,&F_REF,varname_list, value_list)){ F_REF=-1.0; fprintf(fp,"Reference frequency for viscoelastic modeling is set to center frequency of the source wavelet.\n");} + + if (get_int_from_objectlist("VTI",number_readobjects,&VTI,varname_list, value_list)) + declare_error("Variable VTI could not be retrieved from the json input file!"); } @@ -658,11 +661,21 @@ void read_par_json(FILE *fp, char *fileinp){ if (get_int_from_objectlist("INV_VS_ITER",number_readobjects,&INV_VS_ITER,varname_list, value_list)){ INV_VS_ITER=0; fprintf(fp,"Variable INV_VS_ITER is set to default value %d.\n",INV_VS_ITER);} + + /* Inversion for gamma */ + if (get_int_from_objectlist("INV_VSHOR_ITER",number_readobjects,&INV_VSHOR_ITER,varname_list, value_list)){ + INV_VSHOR_ITER=0; + fprintf(fp,"Variable INV_VSHOR_ITER is set to default value %d.\n",INV_VSHOR_ITER);} /* Vp/Vs-Ratio */ if (get_float_from_objectlist("VP_VS_RATIO",number_readobjects,&VP_VS_RATIO,varname_list, value_list)){ VP_VS_RATIO=0.0; fprintf(fp,"Variable VP_VS_RATIO is set to default value %4.2f which means that it is disregarded.\n",VP_VS_RATIO);} + + /* Limited Thomsen parameter gamma */ + if (get_float_from_objectlist("GAMMA_VTI",number_readobjects,&GAMMA_VTI,varname_list, value_list)){ + GAMMA_VTI=0.0; + fprintf(fp,"Variable GAMMA_VTI is set to default value %4.2f which means that it is disregarded.\n",GAMMA_VTI);} /* Limited update of model parameters in reference to the starting model */ if (get_int_from_objectlist("S",number_readobjects,&S,varname_list, value_list)){ @@ -699,6 +712,12 @@ void read_par_json(FILE *fp, char *fileinp){ if (get_float_from_objectlist("RHOLOWERLIM",number_readobjects,&RHOLOWERLIM,varname_list, value_list)){ RHOLOWERLIM=0.0; fprintf(fp,"Variable RHOLOWERLIM is set to default value %f.\n",RHOLOWERLIM);} + if (get_float_from_objectlist("VSHORUPPERLIM",number_readobjects,&VSHORUPPERLIM,varname_list, value_list)){ + VSHORUPPERLIM=25000.0; + fprintf(fp,"Variable VSHORUPPERLIM is set to default value %f.\n",VSHORUPPERLIM);} + if (get_float_from_objectlist("VSHORLOWERLIM",number_readobjects,&VSHORLOWERLIM,varname_list, value_list)){ + VSHORLOWERLIM=0.0; + fprintf(fp,"Variable VSHORLOWERLIM is set to default value %f.\n",VSHORLOWERLIM);} /* Hessian and Gradient-Method */ diff --git a/src/readmod.c b/src/readmod.c index 53a4ecbc0ddb6ec0d96cff1e9f91856bb8896d75..6423c8486b3f6ee0e6e728236e43b8c82f70df5f 100644 --- a/src/readmod.c +++ b/src/readmod.c @@ -174,7 +174,7 @@ void readmod(float ** rho, float ** pi, float ** u, float ** taus, float ** if (sw_Qs){ - if(feof(fp_vs)){ + if(feof(fp_qs)){ declare_error("Model file QS is to small. Check dimensions NX*NY of file."); } diff --git a/src/readmod_el_vti.c b/src/readmod_el_vti.c new file mode 100644 index 0000000000000000000000000000000000000000..17659ff0695b097e01acd17f640926e17b6c6c6a --- /dev/null +++ b/src/readmod_el_vti.c @@ -0,0 +1,258 @@ +/*----------------------------------------------------------------------------------------- + * Copyright (C) 2016 For the list of authors, see file AUTHORS. + * + * This file is part of IFOS. + * + * IFOS is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, version 2.0 of the License only. + * + * IFOS 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with IFOS. See file COPYING and/or . + -----------------------------------------------------------------------------------------*/ + +/*------------------------------------------------------------------------ + * Read elastic model properties (vp,vs,density,delta,epsilon,gamma) from files + * + * ----------------------------------------------------------------------*/ + + +/* This file contains function readmod, which has the purpose + to read data from model-files for viscoelastic simulation */ + +#include "fd.h" + +void readmod_el_vti(float ** rho, float ** pi, float ** u, float **delta, float **epsilon, float **vshor){ + + extern int NX, NY, NXG, NYG, POS[3], MYID, PARAMETERIZATION,WAVETYPE; + extern char MFILE[STRING_SIZE]; + extern FILE *FP; + + + /* local variables */ + float rhov, vp = 0.0, vs, deltav, epsilonv, vshorv; + int i, j, ii, jj; + FILE *fp_vs, *fp_vp = NULL, *fp_rho, *fp_epsilon, *fp_delta, *fp_vshor; + char filename[STRING_SIZE]; + + + + + + + fprintf(FP,"\n...reading model information from model-files...\n"); + /* ----------------------------------- */ + /* read density and seismic velocities */ + /* ----------------------------------- */ + if(PARAMETERIZATION==1){ + + if(WAVETYPE==1||WAVETYPE==3){ + fprintf(FP,"\t Vp:\n\t %s.vp\n\n",MFILE); + sprintf(filename,"%s.vp",MFILE); + fp_vp=fopen(filename,"r"); + if (fp_vp==NULL) declare_error(" Could not open model file for Vp ! "); + + fprintf(FP,"\t Epsilon:\n\t %s.epsilon\n\n",MFILE); + sprintf(filename,"%s.epsilon",MFILE); + fp_epsilon=fopen(filename,"r"); + if (fp_epsilon==NULL) declare_error(" Could not open model file for epsilon ! "); + + fprintf(FP,"\t Delta:\n\t %s.delta\n\n",MFILE); + sprintf(filename,"%s.delta",MFILE); + fp_delta=fopen(filename,"r"); + if (fp_delta==NULL) declare_error(" Could not open model file for delta ! "); + } + + + if(WAVETYPE==2||WAVETYPE==3){ + fprintf(FP,"\t Vshor:\n\t %s.vshor\n\n",MFILE); + sprintf(filename,"%s.vshor",MFILE); + fp_vshor=fopen(filename,"r"); + if (fp_vshor==NULL) declare_error(" Could not open model file for vshor ! "); + } + + fprintf(FP,"\t Vs:\n\t %s.vs\n\n",MFILE); + sprintf(filename,"%s.vs",MFILE); + fp_vs=fopen(filename,"r"); + if (fp_vs==NULL) declare_error(" Could not open model file for Vs ! "); + + fprintf(FP,"\t Density:\n\t %s.rho\n\n",MFILE); + sprintf(filename,"%s.rho",MFILE); + fp_rho=fopen(filename,"r"); + if (fp_rho==NULL) declare_error(" Could not open model file for densities ! "); + + + } else { + + /* read density and Lame parameters */ + /* ----------------------------------- */ + fprintf(FP,"\t Lame parameter lambda:\n\t %s.lam\n\n",MFILE); + sprintf(filename,"%s.lam",MFILE); + fp_vp=fopen(filename,"r"); + if (fp_vp==NULL) declare_error(" Could not open model file for Lame parameter lambda ! "); + + + fprintf(FP,"\t Lame parameter mu:\n\t %s.mu\n\n",MFILE); + sprintf(filename,"%s.mu",MFILE); + fp_vs=fopen(filename,"r"); + if (fp_vs==NULL) declare_error(" Could not open model file for Lame parameter mu ! "); + + fprintf(FP,"\t Density:\n\t %s.rho\n\n",MFILE); + sprintf(filename,"%s.rho",MFILE); + fp_rho=fopen(filename,"r"); + if (fp_rho==NULL) declare_error(" Could not open model file for densities ! "); + } + + + /* loop over global grid */ + for (i=1;i<=NXG;i++){ + for (j=1;j<=NYG;j++){ + + if(WAVETYPE==1||WAVETYPE==3){ + + if(feof(fp_vp)){ + declare_error("Model file VP is to small. Check dimensions NX*NY of file."); + } + if(feof(fp_epsilon) || feof(fp_delta)){ + declare_error("Model file EPSILON or DELTA is to small. Check dimensions NX*NY of file."); + } + + fread(&vp, sizeof(float), 1, fp_vp); + fread(&epsilonv, sizeof(float), 1, fp_epsilon); + fread(&deltav, sizeof(float), 1, fp_delta); + + } + + if(WAVETYPE==2||WAVETYPE==3){ + + if(feof(fp_vshor)){ + declare_error("Model file VSHOR is to small. Check dimensions NX*NY of file."); + } + + fread(&vshorv, sizeof(float), 1, fp_vshor); + } + + + + if(feof(fp_vs) || feof(fp_rho)){ + declare_error("Model file VS or RHO is to small. Check dimensions NX*NY of file."); + } + + fread(&vs, sizeof(float), 1, fp_vs); + fread(&rhov, sizeof(float), 1, fp_rho); + + + + + /* only the PE which belongs to the current global gridpoint + is saving model parameters in his local arrays */ + if ((POS[1]==((i-1)/NX)) && + (POS[2]==((j-1)/NY))){ + ii=i-POS[1]*NX; + jj=j-POS[2]*NY; + +// c33v=vp*vp*rhov; +// c55v=vs*vs*rhov; +// c11v=c33v*(1+2*epsilon); +// c13v=sqrt(2*delta*c33v*(c33v-c55v)+(c33v-c55v)*(c33v-c55v))-c55v; +// c66v=c55v*(2*gamma+1); + + u[jj][ii]=vs; + pi[jj][ii]=vp; + delta[jj][ii]=deltav; + epsilon[jj][ii]=epsilonv; + vshor[jj][ii]=vshorv; //horizontal SH-velocity + rho[jj][ii]=rhov; + + + +// u[jj][ii]=vs; +// rho[jj][ii]=rhov; +// if(WAVETYPE==1||WAVETYPE==3){ +// // pi[jj][ii]=vp; +// } + + + + } + } + } + if(WAVETYPE==1||WAVETYPE==3){ + + fread(&vp, sizeof(float), 1, fp_vp); + if(!feof(fp_vp)){ + declare_error("Model file VP is to big. Check dimensions NX*NY of file."); + } + + fread(&epsilonv, sizeof(float), 1, fp_epsilon); + fread(&delta, sizeof(float), 1, fp_delta); + if(!feof(fp_epsilon) || !feof(fp_delta)){ + declare_error("Model file EPSILON or DELTA is to big. Check dimensions NX*NY of file."); + } + + fclose(fp_vp); + fclose(fp_epsilon); + fclose(fp_delta); + } + + if(WAVETYPE==2||WAVETYPE==3){ + + fread(&vshorv, sizeof(float), 1, fp_vshor); + if(!feof(fp_vshor)){ + declare_error("Model file VSHOR is to big. Check dimensions NX*NY of file."); + } + fclose(fp_vshor); + } + + fread(&vs, sizeof(float), 1, fp_vs); + fread(&rhov, sizeof(float), 1, fp_rho); + if(!feof(fp_vs) || !feof(fp_rho)){ + declare_error("Model file VS or RHO is to big. Check dimensions NX*NY of file."); + } + fclose(fp_vs); + fclose(fp_rho); + + + + + + /* each PE writes his model to disk */ + if(WAVETYPE==1||WAVETYPE==3){ + if(PARAMETERIZATION==1) sprintf(filename,"%s.out.vp",MFILE); + if(PARAMETERIZATION==3) sprintf(filename,"%s.out.pi",MFILE); + write_matrix_disk(pi, filename); + + sprintf(filename,"%s.out.epsilon",MFILE); + write_matrix_disk(epsilon, filename); + + sprintf(filename,"%s.out.delta",MFILE); + write_matrix_disk(delta, filename); + } + + if(WAVETYPE==2||WAVETYPE==3){ + sprintf(filename,"%s.out.vshor",MFILE); + write_matrix_disk(vshor, filename); + } + + + if(PARAMETERIZATION==1) sprintf(filename,"%s.out.vs",MFILE); + if(PARAMETERIZATION==3) sprintf(filename,"%s.out.mu",MFILE); + write_matrix_disk(u, filename); + + sprintf(filename,"%s.out.rho",MFILE); + write_matrix_disk(rho, filename); + + + + + +} + + + + diff --git a/src/readmod_elastic.c b/src/readmod_elastic.c index 56e6a81cb26d338e356331be7d8acbed59c56bd3..d2d27ad872f6b09476bcd2014d16ab9b8f28dd4c 100644 --- a/src/readmod_elastic.c +++ b/src/readmod_elastic.c @@ -104,7 +104,7 @@ void readmod_elastic(float ** rho, float ** pi, float ** u){ } - if(feof(fp_vs) && feof(fp_rho)){ + if(feof(fp_vs) || feof(fp_rho)){ declare_error("Model file VS or RHO is to small. Check dimensions NX*NY of file."); } @@ -141,7 +141,7 @@ void readmod_elastic(float ** rho, float ** pi, float ** u){ fread(&vs, sizeof(float), 1, fp_vs); fread(&rho, sizeof(float), 1, fp_rho); - if(!feof(fp_vs) && !feof(fp_rho)){ + if(!feof(fp_vs) || !feof(fp_rho)){ declare_error("Model file VS or RHO is to big. Check dimensions NX*NY of file."); } fclose(fp_vs); diff --git a/src/readmod_vti.c b/src/readmod_vti.c new file mode 100644 index 0000000000000000000000000000000000000000..960348fc6ac2ae7d7b0e5a51a407d8641a4b7794 --- /dev/null +++ b/src/readmod_vti.c @@ -0,0 +1,332 @@ +/*----------------------------------------------------------------------------------------- + * Copyright (C) 2016 For the list of authors, see file AUTHORS. + * + * This file is part of IFOS. + * + * IFOS is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, version 2.0 of the License only. + * + * IFOS 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with IFOS. See file COPYING and/or . + -----------------------------------------------------------------------------------------*/ + +/*------------------------------------------------------------------------ + * Read elastic model properties (vp,vs,density,delta,epsilon,gamma) from files + * + * ----------------------------------------------------------------------*/ + + +/* This file contains function readmod, which has the purpose + to read data from model-files for viscoelastic simulation */ + +#include "fd.h" + +void readmod_vti(float ** rho, float ** pi, float ** u, float **delta, float **epsilon, float **vshor, float **taus, float **taup, float * eta){ + + extern float DT, *FL, TAU; + extern int NX, NY, NXG, NYG, POS[3], MYID, PARAMETERIZATION, WAVETYPE, L; + extern char MFILE[STRING_SIZE]; + extern FILE *FP; + + + /* local variables */ + float rhov, vp = 0.0, vs, deltav, epsilonv, vshorv, qp, qs, *pts; + int i, j, ii, jj, l, sw_Qp=1, sw_Qs=1; + FILE *fp_vs, *fp_vp, *fp_rho, *fp_epsilon, *fp_delta, *fp_vshor, *fp_qp, *fp_qs; + char filename[STRING_SIZE]; + + /* vector for maxwellbodies */ + pts=vector(1,L); + for (l=1;l<=L;l++) { + pts[l]=1.0/(2.0*PI*FL[l]); + eta[l]=DT/pts[l]; + } + + + + + fprintf(FP,"\n...reading model information from model-files...\n"); + /* ----------------------------------- */ + /* read density and seismic velocities */ + /* ----------------------------------- */ + if(PARAMETERIZATION==1){ + + if(WAVETYPE==1||WAVETYPE==3){ + fprintf(FP,"\t Vp:\n\t %s.vp\n\n",MFILE); + sprintf(filename,"%s.vp",MFILE); + fp_vp=fopen(filename,"r"); + if (fp_vp==NULL) declare_error(" Could not open model file for Vp ! "); + + fprintf(FP,"\t Epsilon:\n\t %s.epsilon\n\n",MFILE); + sprintf(filename,"%s.epsilon",MFILE); + fp_epsilon=fopen(filename,"r"); + if (fp_epsilon==NULL) declare_error(" Could not open model file for epsilon ! "); + + fprintf(FP,"\t Delta:\n\t %s.delta\n\n",MFILE); + sprintf(filename,"%s.delta",MFILE); + fp_delta=fopen(filename,"r"); + if (fp_delta==NULL) declare_error(" Could not open model file for delta ! "); + + fprintf(FP,"\t Qp:\n\t %s.qp\n\n",MFILE); + sprintf(filename,"%s.qp",MFILE); + fp_qp=fopen(filename,"r"); + if (fp_qp==NULL){ + if (MYID==0){ + printf(" Could not open model file for Qp-values ! \n"); + printf(" Uses input file value for tau! \n");} + sw_Qp=0; + } + } + + + if(WAVETYPE==2){ + fprintf(FP,"\t Vshor:\n\t %s.vshor\n\n",MFILE); + sprintf(filename,"%s.vshor",MFILE); + fp_vshor=fopen(filename,"r"); + if (fp_vshor==NULL) declare_error(" Could not open model file for vshor ! "); + } + + fprintf(FP,"\t Vs:\n\t %s.vs\n\n",MFILE); + sprintf(filename,"%s.vs",MFILE); + fp_vs=fopen(filename,"r"); + if (fp_vs==NULL) declare_error(" Could not open model file for Vs ! "); + + fprintf(FP,"\t Density:\n\t %s.rho\n\n",MFILE); + sprintf(filename,"%s.rho",MFILE); + fp_rho=fopen(filename,"r"); + if (fp_rho==NULL) declare_error(" Could not open model file for densities ! "); + + fprintf(FP,"\t Qs:\n\t %s.qs\n\n",MFILE); + sprintf(filename,"%s.qs",MFILE); + fp_qs=fopen(filename,"r"); + if (fp_qs==NULL){ + if (MYID==0){ + printf(" Could not open model file for Qs-values ! "); + printf(" Uses input file value for tau! \n");} + sw_Qs=0; + } + + + } else { + + /* read density and Lame parameters */ + /* ----------------------------------- */ + fprintf(FP,"\t Lame parameter lambda:\n\t %s.lam\n\n",MFILE); + sprintf(filename,"%s.lam",MFILE); + fp_vp=fopen(filename,"r"); + if (fp_vp==NULL) declare_error(" Could not open model file for Lame parameter lambda ! "); + + + fprintf(FP,"\t Lame parameter mu:\n\t %s.mu\n\n",MFILE); + sprintf(filename,"%s.mu",MFILE); + fp_vs=fopen(filename,"r"); + if (fp_vs==NULL) declare_error(" Could not open model file for Lame parameter mu ! "); + + fprintf(FP,"\t Density:\n\t %s.rho\n\n",MFILE); + sprintf(filename,"%s.rho",MFILE); + fp_rho=fopen(filename,"r"); + if (fp_rho==NULL) declare_error(" Could not open model file for densities ! "); + } + + + /* loop over global grid */ + for (i=1;i<=NXG;i++){ + for (j=1;j<=NYG;j++){ + + if(WAVETYPE==1||WAVETYPE==3){ + + if(feof(fp_vp)){ + declare_error("Model file VP is to small. Check dimensions NX*NY of file."); + } + if(feof(fp_epsilon) || feof(fp_delta)){ + declare_error("Model file EPSILON or DELTA is to small. Check dimensions NX*NY of file."); + } + + if (sw_Qp){ + + if(feof(fp_qp)){ + declare_error("Model file QP is to small. Check dimensions NX*NY of file."); + } + + fread(&qp, sizeof(float), 1, fp_qp); + } + + fread(&vp, sizeof(float), 1, fp_vp); + fread(&epsilonv, sizeof(float), 1, fp_epsilon); + fread(&deltav, sizeof(float), 1, fp_delta); + + } + + if(WAVETYPE==2){ + + if(feof(fp_vshor)){ + declare_error("Model file VSHOR is to small. Check dimensions NX*NY of file."); + } + + fread(&vshorv, sizeof(float), 1, fp_vshor); + } + + + + if(feof(fp_vs) || feof(fp_rho)){ + declare_error("Model file VS or RHO is to small. Check dimensions NX*NY of file."); + } + + if (sw_Qs){ + + if(feof(fp_vs)){ + declare_error("Model file QS is to small. Check dimensions NX*NY of file."); + } + + fread(&qs, sizeof(float), 1, fp_qs); + } + + fread(&vs, sizeof(float), 1, fp_vs); + fread(&rhov, sizeof(float), 1, fp_rho); + + + + + /* only the PE which belongs to the current global gridpoint + is saving model parameters in his local arrays */ + if ((POS[1]==((i-1)/NX)) && + (POS[2]==((j-1)/NY))){ + ii=i-POS[1]*NX; + jj=j-POS[2]*NY; + +// c33v=vp*vp*rhov; +// c55v=vs*vs*rhov; +// c11v=c33v*(1+2*epsilon); +// c13v=sqrt(2*delta*c33v*(c33v-c55v)+(c33v-c55v)*(c33v-c55v))-c55v; +// c66v=c55v*(2*gamma+1); + + u[jj][ii]=vs; + pi[jj][ii]=vp; + delta[jj][ii]=deltav; + epsilon[jj][ii]=epsilonv; + vshor[jj][ii]=vshorv; //horizontal SH-velocity + rho[jj][ii]=rhov; + + + if (sw_Qs){ + taus[jj][ii]=2.0/qs;} + else taus[jj][ii]=TAU; + if(WAVETYPE==1||WAVETYPE==3){ + if (sw_Qp){ + taup[jj][ii]=2.0/qp;} + else taup[jj][ii]=TAU; + } + + +// u[jj][ii]=vs; +// rho[jj][ii]=rhov; +// if(WAVETYPE==1||WAVETYPE==3){ +// // pi[jj][ii]=vp; +// } + + + + } + } + } + if(WAVETYPE==1||WAVETYPE==3){ + + fread(&vp, sizeof(float), 1, fp_vp); + if(!feof(fp_vp)){ + declare_error("Model file VP is to big. Check dimensions NX*NY of file."); + } + + fread(&epsilonv, sizeof(float), 1, fp_epsilon); + fread(&delta, sizeof(float), 1, fp_delta); + if(!feof(fp_epsilon) || !feof(fp_delta)){ + declare_error("Model file EPSILON or DELTA is to big. Check dimensions NX*NY of file."); + } + + if (sw_Qp) { + fread(&qp, sizeof(float), 1, fp_qp); + if(!feof(fp_qp)){ + declare_error("Model file QP is to big. Check dimensions NX*NY of file."); + } + fclose(fp_qp); + } + + fclose(fp_vp); + fclose(fp_epsilon); + fclose(fp_delta); + } + + if(WAVETYPE==2){ + + fread(&vshorv, sizeof(float), 1, fp_vshor); + if(!feof(fp_vshor)){ + declare_error("Model file VSHOR is to big. Check dimensions NX*NY of file."); + } + fclose(fp_vshor); + } + + fread(&vs, sizeof(float), 1, fp_vs); + fread(&rhov, sizeof(float), 1, fp_rho); + if(!feof(fp_vs) || !feof(fp_rho)){ + declare_error("Model file VS or RHO is to big. Check dimensions NX*NY of file."); + } + + if (sw_Qs){ + fread(&qs, sizeof(float), 1, fp_qs); + if(!feof(fp_qs)){ + declare_error("Model file QS is to big. Check dimensions NX*NY of file."); + } + fclose(fp_qs); + } + + fclose(fp_vs); + fclose(fp_rho); + + + + + + /* each PE writes his model to disk */ + if(WAVETYPE==1||WAVETYPE==3){ + if(PARAMETERIZATION==1) sprintf(filename,"%s.out.vp",MFILE); + if(PARAMETERIZATION==3) sprintf(filename,"%s.out.pi",MFILE); + write_matrix_disk(pi, filename); + + sprintf(filename,"%s.out.epsilon",MFILE); + write_matrix_disk(epsilon, filename); + + sprintf(filename,"%s.out.delta",MFILE); + write_matrix_disk(delta, filename); + + sprintf(filename,"%s.out.qp",MFILE); + write_matrix_disk(taup, filename); + } + + if(WAVETYPE==2){ + sprintf(filename,"%s.out.vshor",MFILE); + write_matrix_disk(vshor, filename); + } + + + if(PARAMETERIZATION==1) sprintf(filename,"%s.out.vs",MFILE); + if(PARAMETERIZATION==3) sprintf(filename,"%s.out.mu",MFILE); + write_matrix_disk(u, filename); + + sprintf(filename,"%s.out.rho",MFILE); + write_matrix_disk(rho, filename); + + sprintf(filename,"%s.out.qs",MFILE); + write_matrix_disk(taus, filename); + + free_vector(pts,1,L); + +} + + + + diff --git a/src/smooth.c b/src/smooth.c index 1d1df1cb9a2ad78f930006c5f1f6bb6933f2d5de..e58184ce5cdbbfc1aa1bedf1fa733796fb126814 100644 --- a/src/smooth.c +++ b/src/smooth.c @@ -61,6 +61,11 @@ void smooth(float ** mat, int sws, int filter, float Vs_avg, float F_LOW_PASS) write_matrix_disk(mat, jac_tmp); } + if(sws==7){ + sprintf(jac_tmp,"%s_g_vshor",JACOBIAN); + write_matrix_disk(mat, jac_tmp); + } + if(MYID==0){ switch (filter){ @@ -119,6 +124,14 @@ void smooth(float ** mat, int sws, int filter, float Vs_avg, float F_LOW_PASS) if(sws==6){ sprintf(jac_tmp,"%s_rho.bin",INV_MODELFILE);} + + if(sws==7){ + sprintf(jac_tmp,"%s_g_vshor.bin",JACOBIAN);} + + if(sws==8){ + sprintf(jac_tmp,"%s_vshor.bin",INV_MODELFILE);} + + model=fopen(jac_tmp,"rb"); if (model==NULL) declare_error(" Could not open file !"); @@ -193,6 +206,12 @@ void smooth(float ** mat, int sws, int filter, float Vs_avg, float F_LOW_PASS) if(sws==6){ sprintf(jac_tmp,"%s_rho_tmp.bin",INV_MODELFILE);} + + if(sws==7){ + sprintf(jac_tmp,"%s_tmp_g_vshor.bin",JACOBIAN);} + + if(sws==8){ + sprintf(jac_tmp,"%s_vshor_tmp.bin",INV_MODELFILE);} model=fopen(jac_tmp,"wb"); for (i=1;i<=NXG;i++){ @@ -248,6 +267,12 @@ void smooth(float ** mat, int sws, int filter, float Vs_avg, float F_LOW_PASS) if(sws==6){ sprintf(jac_tmp,"%s_rho_tmp.bin",INV_MODELFILE);} + + if(sws==7){ + sprintf(jac_tmp,"%s_tmp_g_vshor.bin",JACOBIAN);} + + if(sws==8){ + sprintf(jac_tmp,"%s_vshor_tmp.bin",INV_MODELFILE);} model=fopen(jac_tmp,"rb"); if (model==NULL) declare_error(" Could not open file! (distribute)"); diff --git a/src/spat_filt.c b/src/spat_filt.c index 6883ec875e1e73aed083a6a9cb8bd22a8cee2445..ca249a816c6479060fc996f1a2c4bc9e3327ae80 100644 --- a/src/spat_filt.c +++ b/src/spat_filt.c @@ -67,6 +67,9 @@ void spat_filt(float ** waveconv, int iter, int sws) if(sws==3){ sprintf(jac,"%s_g_rho.old",JACOBIAN);} /*sprintf(jac,"%s_g_rho.it%i",JACOBIAN,iter);}*/ + if(sws==4){ + sprintf(jac,"%s_g_vshor.old",JACOBIAN);} /*sprintf(jac,"%s_g_vshor.it%i",JACOBIAN,iter);}*/ + MPI_Barrier(MPI_COMM_WORLD); if(MYID==0){ diff --git a/src/surface_el_vti_PML.c b/src/surface_el_vti_PML.c new file mode 100644 index 0000000000000000000000000000000000000000..8391b6bf63070824cfb429c0f43f218d7b7c82b3 --- /dev/null +++ b/src/surface_el_vti_PML.c @@ -0,0 +1,128 @@ +/*----------------------------------------------------------------------------------------- + * Copyright (C) 2016 For the list of authors, see file AUTHORS. + * + * This file is part of IFOS. + * + * IFOS is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, version 2.0 of the License only. + * + * IFOS 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with IFOS. See file COPYING and/or . + -----------------------------------------------------------------------------------------*/ + +/*------------------------------------------------------------------------ + * stress free surface condition for vti modeling + * + * ----------------------------------------------------------------------*/ + +#include "fd.h" + +void surface_el_vti_PML(int ndepth, float ** vx, float ** vy, float ** sxx, float ** syy, + float ** sxy, float ** syz, float ** c11, float ** c13, float ** c33, + float ** rho, float * hc, float * K_x, float * a_x, float * b_x, float ** psi_vxx, + float ** ux, float ** uy, float ** uxy, float ** uyz,float ** sxz,float **uxz){ + + + int i,j,m,h,h1; + int fdoh; + float p, q, r; + float vxx, vyy; + float dh24, dthalbe; + extern float DT, DH; + extern int NX, PARAMETERIZATION; + extern int FW, BOUNDARY; + extern int NPROCX, NPROCY, POS[3], MYID; + extern int FDORDER, WAVETYPE; + + fdoh = FDORDER/2; + dthalbe=DT/2.0; + dh24=1.0/DH; + + j=ndepth; /* The free surface is located exactly in y=dh !! */ + if (WAVETYPE==1||WAVETYPE==3){ + for (i=1;i<=NX;i++){ + + /*Mirroring the components of the stress tensor to make + a stress free surface (method of imaging)*/ + syy[j][i]=0.0; + uy[j][i]=0.0; + + /*syy[j-1][i]=-syy[j+1][i]; + sxy[j-1][i]=-sxy[j][i];*/ + + vxx = 0.0; + vyy = 0.0; + for (m=1; m<=fdoh; m++) { + + /*Mirroring the components of the stress tensor to make + a stress free surface (method of imaging)*/ + syy[j-m][i]=-syy[j+m][i]; + sxy[j-m][i]=-sxy[j+m-1][i]; + + uy[j-m][i]=-uy[j+m][i]; + uxy[j-m][i]=-uxy[j+m-1][i]; + + vxx += hc[m]*(vx[j][i+m-1] -vx[j][i-m]); + vyy += hc[m]*(vy[j+m-1][i] -vy[j-m][i]); + } + vxx *= dh24; + vyy *= dh24; + + /* apply PML boundary */ + /* left boundary */ + if((!BOUNDARY) && (POS[1]==0) && (i<=FW)){ + + psi_vxx[j][i] = b_x[i] * psi_vxx[j][i] + a_x[i] * vxx; + vxx = vxx / K_x[i] + psi_vxx[j][i]; + } + + /* right boundary */ + if((!BOUNDARY) && (POS[1]==NPROCX-1) && (i>=NX-FW+1)){ + + h1 = (i-NX+2*FW); + h = i; + + psi_vxx[j][h1] = b_x[h1] * psi_vxx[j][h1] + a_x[h1] * vxx; + vxx = vxx / K_x[h1] + psi_vxx[j][h1]; + } + + +// if(PARAMETERIZATION==3){ +// fjm=u[j][i]*2.0; +// g=pi[j][i];} +// +// if(PARAMETERIZATION==1){ +// fjm=rho[j][i] * u[j][i] * u[j][i] * 2.0; +// g=rho[j][i] * ((pi[j][i] * pi[j][i]) - 2 * u[j][i] * u[j][i]);} + + p=c11[j][i]; + q=c13[j][i]; + r=c33[j][i]; + + + /*sxx[j][i]+= DT*((4.0*((g*fjm)+(fjm*fjm))/(g+2*fjm))*vxx);*/ + sxx[j][i]+= -DT*(q*q/r*vxx + q*vyy); + ux[j][i]=(p-q*q/r)*vxx; + + + } + } + if (WAVETYPE==2||WAVETYPE==3){ + for (i=1;i<=NX;i++){ + + syz[j][i]=0.0; + uyz[j][i]=0.0; + for (m=1; m<=fdoh; m++) { + syz[j-m][i]=-syz[j+m][i]; + + uyz[j-m][i]=-uyz[j+m][i]; + } + } + } +} diff --git a/src/surface_elastic_PML.c b/src/surface_elastic_PML.c index 0c147c80deeada526e5c209f85bb3483498476af..990d73bbd3febd20535349bd064b155c1c229621 100644 --- a/src/surface_elastic_PML.c +++ b/src/surface_elastic_PML.c @@ -42,7 +42,7 @@ void surface_elastic_PML(int ndepth, float ** vx, float ** vy, float ** sxx, flo dthalbe=DT/2.0; dh24=1.0/DH; - j=ndepth; /* The free surface is located exactly in y=1/2*dh !! */ + j=ndepth; /* The free surface is located exactly in y=dh !! */ if (WAVETYPE==1||WAVETYPE==3){ for (i=1;i<=NX;i++){ @@ -114,10 +114,10 @@ void surface_elastic_PML(int ndepth, float ** vx, float ** vy, float ** sxx, flo uyz[j][i]=0.0; for (m=1; m<=fdoh; m++) { syz[j-m][i]=-syz[j+m][i]; - sxz[j-m][i]=-sxz[j+m-1][i]; + // sxz[j-m][i]=-sxz[j+m-1][i]; uyz[j-m][i]=-uyz[j+m][i]; - uxz[j-m][i]=-uxz[j+m-1][i]; + // uxz[j-m][i]=-uxz[j+m-1][i]; } } } diff --git a/src/taper_grad.c b/src/taper_grad.c index 00d496b939de779289d4f6b0def5a132def0aba0..c8aec0864a1c7ecc05f20ce2db532d69f8a985f7 100644 --- a/src/taper_grad.c +++ b/src/taper_grad.c @@ -425,7 +425,7 @@ void taper_grad(float ** waveconv,float ** taper_coeff, float **srcpos, int nsho /* Read Taper from file */ /* ======================== */ - if((sws>=4)&&(sws<=6)){ + if((sws>=4)&&(sws<=7)){ if (MYID==0&&VERBOSE) { @@ -472,6 +472,19 @@ void taper_grad(float ** waveconv,float ** taper_coeff, float **srcpos, int nsho fp_taper=fopen(taper_file,"r"); } } + if(sws==7){ + if(USE_WORKFLOW){ + sprintf(taper_file,"%s_%i.vshor",TAPER_FILE_NAME,WORKFLOW_STAGE); + fp_taper=fopen(taper_file,"r"); + if(fp_taper==NULL){ + sprintf(taper_file,"%s.vshor",TAPER_FILE_NAME); + fp_taper=fopen(taper_file,"r"); + } + }else{ + sprintf(taper_file,"%s.vshor",TAPER_FILE_NAME); + fp_taper=fopen(taper_file,"r"); + } + } if(fp_taper==NULL) { declare_error("Taper file could not be opened"); diff --git a/src/taper_grad_shot.c b/src/taper_grad_shot.c index 103e0b290eef4f156b546ee2ec6c5af11d897d19..a4ac0aaa3b7acb1712e4eb21d8bf61afc6a8588c 100644 --- a/src/taper_grad_shot.c +++ b/src/taper_grad_shot.c @@ -212,7 +212,7 @@ void taper_grad_shot(float ** waveconv,float ** taper_coeff, float **srcpos, int /* Read Taper from file */ /* ======================== */ - if((sws>=2)&&(sws<=4)){ + if((sws>=2)&&(sws<=5)){ if (MYID==0&&VERBOSE) { @@ -259,6 +259,19 @@ void taper_grad_shot(float ** waveconv,float ** taper_coeff, float **srcpos, int fp_taper=fopen(taper_file,"r"); } } + if(sws==5){ + if(USE_WORKFLOW){ + sprintf(taper_file,"%s.shot%d_%i.vshor",TAPER_FILE_NAME,ishot,WORKFLOW_STAGE); + fp_taper=fopen(taper_file,"r"); + if(fp_taper==NULL){ + sprintf(taper_file,"%s.shot%d.vshor",TAPER_FILE_NAME,ishot); + fp_taper=fopen(taper_file,"r"); + } + }else{ + sprintf(taper_file,"%s.shot%d.vshor",TAPER_FILE_NAME,ishot); + fp_taper=fopen(taper_file,"r"); + } + } if(fp_taper==NULL) { declare_error("Taper file could not be opened"); diff --git a/src/update_s_el_vti_PML.c b/src/update_s_el_vti_PML.c new file mode 100644 index 0000000000000000000000000000000000000000..f80eefceb9fef6d6c6d4d9ace33bbff7c6eb2ba3 --- /dev/null +++ b/src/update_s_el_vti_PML.c @@ -0,0 +1,584 @@ +/*----------------------------------------------------------------------------------------- + * Copyright (C) 2016 For the list of authors, see file AUTHORS. + * + * This file is part of IFOS. + * + * IFOS is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, version 2.0 of the License only. + * + * IFOS 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with IFOS. See file COPYING and/or . +-----------------------------------------------------------------------------------------*/ + +/*------------------------------------------------------------------------ + * updating stress components at gridpoints [nx1...nx2][ny1...ny2] + * by a staggered grid finite difference scheme of arbitrary (FDORDER) order accuracy in space + * and second order accuracy in time + * + * for vertically transversely isotropic model + * + * ----------------------------------------------------------------------*/ + +#include "fd.h" + +void update_s_el_vti_PML(int nx1, int nx2, int ny1, int ny2, + float ** vx, float ** vy, float ** ux, float ** uy, float ** uxy, float ** uyx, float ** sxx, float ** syy, + float ** sxy, float ** c11, float ** c13, float ** c33, float ** c55, float ** absorb_coeff, float **rho, float *hc, int infoout, + float * K_x, float * a_x, float * b_x, float * K_x_half, float * a_x_half, float * b_x_half, + float * K_y, float * a_y, float * b_y, float * K_y_half, float * a_y_half, float * b_y_half, + float ** psi_vxx, float ** psi_vyy, float ** psi_vxy, float ** psi_vyx){ + + + int i,j, m, fdoh, h, h1; + float p = 0.0, q = 0.0, r=0.0, s=0.0; + float vxx, vyy, vxy, vyx; + float dhi; + extern float DT, DH; + extern int MYID, FDORDER, PARAMETERIZATION, FW; + extern int FREE_SURF, BOUNDARY; + extern int NPROCX, NPROCY, POS[3]; + extern FILE *FP; + double time1 = 0.0, time2; + + + + dhi = DT/DH; + fdoh = FDORDER/2; + + + if (infoout && (MYID==0)){ + time1=MPI_Wtime(); + fprintf(FP,"\n **Message from update_s (printed by PE %d):\n",MYID); + fprintf(FP," Updating stress components ..."); + } + + + + switch (FDORDER){ + + case 2: + for (j=ny1;j<=ny2;j++){ + for (i=nx1;i<=nx2;i++){ + vxx = ( hc[1]*(vx[j][i] -vx[j][i-1]))*dhi; + + vyx = ( hc[1]*(vy[j][i+1]-vy[j][i]))*dhi; + + vxy = ( hc[1]*(vx[j+1][i]-vx[j][i]))*dhi; + + vyy = ( hc[1]*(vy[j][i] -vy[j-1][i]))*dhi; + + /* left boundary */ + if((!BOUNDARY) && (POS[1]==0) && (i<=FW)){ + + psi_vxx[j][i] = b_x[i] * psi_vxx[j][i] + a_x[i] * vxx; + vxx = vxx / K_x[i] + psi_vxx[j][i]; + + psi_vyx[j][i] = b_x_half[i] * psi_vyx[j][i] + a_x_half[i] * vyx; + vyx = vyx / K_x_half[i] + psi_vyx[j][i]; + } + + /* right boundary */ + if((!BOUNDARY) && (POS[1]==NPROCX-1) && (i>=nx2-FW+1)){ + + h1 = (i-nx2+2*FW); + h = i; + + psi_vxx[j][h1] = b_x[h1] * psi_vxx[j][h1] + a_x[h1] * vxx; + vxx = vxx / K_x[h1] + psi_vxx[j][h1]; + + /*psi_vyx[j][h] = b_x_half[h] * psi_vyx[j][h] + a_x_half[h] * vyx; + vyx = vyx / K_x_half[h] + psi_vyx[j][h];*/ + + psi_vyx[j][h1] = b_x_half[h1] * psi_vyx[j][h1] + a_x_half[h1] * vyx; + vyx = vyx / K_x_half[h1] + psi_vyx[j][h1]; + + } + + /* top boundary */ + if((POS[2]==0) && (!(FREE_SURF)) && (j<=FW)){ + + psi_vyy[j][i] = b_y[j] * psi_vyy[j][i] + a_y[j] * vyy; + psi_vxy[j][i] = b_y_half[j] * psi_vxy[j][i] + a_y_half[j] * vxy; + + vyy = vyy / K_y[j] + psi_vyy[j][i]; + vxy = vxy / K_y_half[j] + psi_vxy[j][i]; + + } + + /* bottom boundary */ + if((POS[2]==NPROCY-1) && (j>=ny2-FW+1)){ + + h1 = (j-ny2+2*FW); + h = j; + + psi_vyy[h1][i] = b_y[h1] * psi_vyy[h1][i] + a_y[h1] * vyy; + vyy = vyy / K_y[h1] + psi_vyy[h1][i]; + + /*psi_vxy[j][i] = b_y_half[j] * psi_vxy[j][i] + a_y_half[j] * vxy; + vxy = vxy / K_y_half[j] + psi_vxy[j][i];*/ + + psi_vxy[h1][i] = b_y_half[h1] * psi_vxy[h1][i] + a_y_half[h1] * vxy; + vxy = vxy / K_y_half[h1] + psi_vxy[h1][i]; + + } + + p=c11[j][i]; + q=c13[j][i]; + r=c33[j][i]; + s=c55[j][i]; + + /* lambda - mu relationship*/ +// if (PARAMETERIZATION==3){ +// f = u[j][i]; +// g = pi[j][i];} +// +// if (PARAMETERIZATION==1){ +// f = rho[j][i] * u[j][i] * u[j][i]; +// g = rho[j][i] * ((pi[j][i] * pi[j][i]) - 2 * u[j][i] * u[j][i]);} + + sxy[j][i] += s*(vyx+vxy); + sxx[j][i]+= ( p*vxx ) + ( q*vyy ); + syy[j][i]+= ( q*vxx ) + ( r*vyy ); + + uxy[j][i] = (s/DT)*(vyx+vxy); + ux[j][i] = ( p/DT*vxx ) + ( q/DT*vyy ); + uy[j][i] = ( q/DT*vxx ) + ( r/DT*vyy ); + } + } + break; + + case 4: + for (j=ny1;j<=ny2;j++){ + for (i=nx1;i<=nx2;i++){ + vxx = ( hc[1]*(vx[j][i] -vx[j][i-1]) + + hc[2]*(vx[j][i+1]-vx[j][i-2]))*dhi; + + vyx = ( hc[1]*(vy[j][i+1]-vy[j][i]) + + hc[2]*(vy[j][i+2]-vy[j][i-1]))*dhi; + + vxy = ( hc[1]*(vx[j+1][i]-vx[j][i]) + + hc[2]*(vx[j+2][i]-vx[j-1][i]))*dhi; + + vyy = ( hc[1]*(vy[j][i] -vy[j-1][i]) + + hc[2]*(vy[j+1][i]-vy[j-2][i]))*dhi; + + /* left boundary */ + if((!BOUNDARY) && (POS[1]==0) && (i<=FW)){ + + psi_vxx[j][i] = b_x[i] * psi_vxx[j][i] + a_x[i] * vxx; + vxx = vxx / K_x[i] + psi_vxx[j][i]; + + psi_vyx[j][i] = b_x_half[i] * psi_vyx[j][i] + a_x_half[i] * vyx; + vyx = vyx / K_x_half[i] + psi_vyx[j][i]; + } + + /* right boundary */ + if((!BOUNDARY) && (POS[1]==NPROCX-1) && (i>=nx2-FW+1)){ + + h1 = (i-nx2+2*FW); + h = i; + + psi_vxx[j][h1] = b_x[h1] * psi_vxx[j][h1] + a_x[h1] * vxx; + vxx = vxx / K_x[h1] + psi_vxx[j][h1]; + + /*psi_vyx[j][h] = b_x_half[h] * psi_vyx[j][h] + a_x_half[h] * vyx; + vyx = vyx / K_x_half[h] + psi_vyx[j][h];*/ + + psi_vyx[j][h1] = b_x_half[h1] * psi_vyx[j][h1] + a_x_half[h1] * vyx; + vyx = vyx / K_x_half[h1] + psi_vyx[j][h1]; + + } + + /* top boundary */ + if((POS[2]==0) && (!(FREE_SURF)) && (j<=FW)){ + + psi_vyy[j][i] = b_y[j] * psi_vyy[j][i] + a_y[j] * vyy; + psi_vxy[j][i] = b_y_half[j] * psi_vxy[j][i] + a_y_half[j] * vxy; + + vyy = vyy / K_y[j] + psi_vyy[j][i]; + vxy = vxy / K_y_half[j] + psi_vxy[j][i]; + + } + + /* bottom boundary */ + if((POS[2]==NPROCY-1) && (j>=ny2-FW+1)){ + + h1 = (j-ny2+2*FW); + h = j; + + psi_vyy[h1][i] = b_y[h1] * psi_vyy[h1][i] + a_y[h1] * vyy; + vyy = vyy / K_y[h1] + psi_vyy[h1][i]; + + /*psi_vxy[j][i] = b_y_half[j] * psi_vxy[j][i] + a_y_half[j] * vxy; + vxy = vxy / K_y_half[j] + psi_vxy[j][i];*/ + + psi_vxy[h1][i] = b_y_half[h1] * psi_vxy[h1][i] + a_y_half[h1] * vxy; + vxy = vxy / K_y_half[h1] + psi_vxy[h1][i]; + + } + + p=c11[j][i]; + q=c13[j][i]; + r=c33[j][i]; + s=c55[j][i]; + + /* lambda - mu relationship*/ +// if (PARAMETERIZATION==3){ +// f = u[j][i]; +// g = pi[j][i];} +// +// if (PARAMETERIZATION==1){ +// f = rho[j][i] * u[j][i] * u[j][i]; +// g = rho[j][i] * ((pi[j][i] * pi[j][i]) - 2 * u[j][i] * u[j][i]);} + + sxy[j][i] += s*(vyx+vxy); + sxx[j][i]+= ( p*vxx ) + ( q*vyy ); + syy[j][i]+= ( q*vxx ) + ( r*vyy ); + + uxy[j][i] = (s/DT)*(vyx+vxy); + ux[j][i] = ( p/DT*vxx ) + ( q/DT*vyy ); + uy[j][i] = ( q/DT*vxx ) + ( r/DT*vyy ); + } + } + break; + + case 6: + for (j=ny1;j<=ny2;j++){ + for (i=nx1;i<=nx2;i++){ + vxx = ( hc[1]*(vx[j][i] -vx[j][i-1]) + + hc[2]*(vx[j][i+1]-vx[j][i-2]) + + hc[3]*(vx[j][i+2]-vx[j][i-3]))*dhi; + + vyx = ( hc[1]*(vy[j][i+1]-vy[j][i]) + + hc[2]*(vy[j][i+2]-vy[j][i-1]) + + hc[3]*(vy[j][i+3]-vy[j][i-2]))*dhi; + + vxy = ( hc[1]*(vx[j+1][i]-vx[j][i]) + + hc[2]*(vx[j+2][i]-vx[j-1][i]) + + hc[3]*(vx[j+3][i]-vx[j-2][i]))*dhi; + + vyy = ( hc[1]*(vy[j][i] -vy[j-1][i]) + + hc[2]*(vy[j+1][i]-vy[j-2][i]) + + hc[3]*(vy[j+2][i]-vy[j-3][i]))*dhi; + + /* left boundary */ + if((!BOUNDARY) && (POS[1]==0) && (i<=FW)){ + + psi_vxx[j][i] = b_x[i] * psi_vxx[j][i] + a_x[i] * vxx; + vxx = vxx / K_x[i] + psi_vxx[j][i]; + + psi_vyx[j][i] = b_x_half[i] * psi_vyx[j][i] + a_x_half[i] * vyx; + vyx = vyx / K_x_half[i] + psi_vyx[j][i]; + } + + /* right boundary */ + if((!BOUNDARY) && (POS[1]==NPROCX-1) && (i>=nx2-FW+1)){ + + h1 = (i-nx2+2*FW); + h = i; + + psi_vxx[j][h1] = b_x[h1] * psi_vxx[j][h1] + a_x[h1] * vxx; + vxx = vxx / K_x[h1] + psi_vxx[j][h1]; + + /*psi_vyx[j][h] = b_x_half[h] * psi_vyx[j][h] + a_x_half[h] * vyx; + vyx = vyx / K_x_half[h] + psi_vyx[j][h];*/ + + psi_vyx[j][h1] = b_x_half[h1] * psi_vyx[j][h1] + a_x_half[h1] * vyx; + vyx = vyx / K_x_half[h1] + psi_vyx[j][h1]; + + } + + /* top boundary */ + if((POS[2]==0) && (!(FREE_SURF)) && (j<=FW)){ + + psi_vyy[j][i] = b_y[j] * psi_vyy[j][i] + a_y[j] * vyy; + psi_vxy[j][i] = b_y_half[j] * psi_vxy[j][i] + a_y_half[j] * vxy; + + vyy = vyy / K_y[j] + psi_vyy[j][i]; + vxy = vxy / K_y_half[j] + psi_vxy[j][i]; + + } + + /* bottom boundary */ + if((POS[2]==NPROCY-1) && (j>=ny2-FW+1)){ + + h1 = (j-ny2+2*FW); + h = j; + + psi_vyy[h1][i] = b_y[h1] * psi_vyy[h1][i] + a_y[h1] * vyy; + vyy = vyy / K_y[h1] + psi_vyy[h1][i]; + + /*psi_vxy[j][i] = b_y_half[j] * psi_vxy[j][i] + a_y_half[j] * vxy; + vxy = vxy / K_y_half[j] + psi_vxy[j][i];*/ + + psi_vxy[h1][i] = b_y_half[h1] * psi_vxy[h1][i] + a_y_half[h1] * vxy; + vxy = vxy / K_y_half[h1] + psi_vxy[h1][i]; + + } + + p=c11[j][i]; + q=c13[j][i]; + r=c33[j][i]; + s=c55[j][i]; + + /* lambda - mu relationship*/ +// if (PARAMETERIZATION==3){ +// f = u[j][i]; +// g = pi[j][i];} +// +// if (PARAMETERIZATION==1){ +// f = rho[j][i] * u[j][i] * u[j][i]; +// g = rho[j][i] * ((pi[j][i] * pi[j][i]) - 2 * u[j][i] * u[j][i]);} + + sxy[j][i] += s*(vyx+vxy); + sxx[j][i]+= ( p*vxx ) + ( q*vyy ); + syy[j][i]+= ( q*vxx ) + ( r*vyy ); + + uxy[j][i] = (s/DT)*(vyx+vxy); + ux[j][i] = ( p/DT*vxx ) + ( q/DT*vyy ); + uy[j][i] = ( q/DT*vxx ) + ( r/DT*vyy ); + } + } + break; + + case 8: + + for (j=ny1;j<=ny2;j++){ + for (i=nx1;i<=nx2;i++){ + + vxx = ( hc[1]*(vx[j][i] -vx[j][i-1]) + + hc[2]*(vx[j][i+1]-vx[j][i-2]) + + hc[3]*(vx[j][i+2]-vx[j][i-3]) + + hc[4]*(vx[j][i+3]-vx[j][i-4]))*dhi; + + vyx = ( hc[1]*(vy[j][i+1]-vy[j][i]) + + hc[2]*(vy[j][i+2]-vy[j][i-1]) + + hc[3]*(vy[j][i+3]-vy[j][i-2]) + + hc[4]*(vy[j][i+4]-vy[j][i-3]))*dhi; + + vxy = ( hc[1]*(vx[j+1][i]-vx[j][i]) + + hc[2]*(vx[j+2][i]-vx[j-1][i]) + + hc[3]*(vx[j+3][i]-vx[j-2][i]) + + hc[4]*(vx[j+4][i]-vx[j-3][i]))*dhi; + + vyy = ( hc[1]*(vy[j][i] -vy[j-1][i]) + + hc[2]*(vy[j+1][i]-vy[j-2][i]) + + hc[3]*(vy[j+2][i]-vy[j-3][i]) + + hc[4]*(vy[j+3][i]-vy[j-4][i]))*dhi; + + /* left boundary */ + if((!BOUNDARY) && (POS[1]==0) && (i<=FW)){ + + psi_vxx[j][i] = b_x[i] * psi_vxx[j][i] + a_x[i] * vxx; + vxx = vxx / K_x[i] + psi_vxx[j][i]; + + psi_vyx[j][i] = b_x_half[i] * psi_vyx[j][i] + a_x_half[i] * vyx; + vyx = vyx / K_x_half[i] + psi_vyx[j][i]; + } + + /* right boundary */ + if((!BOUNDARY) && (POS[1]==NPROCX-1) && (i>=nx2-FW+1)){ + + h1 = (i-nx2+2*FW); + h = i; + + psi_vxx[j][h1] = b_x[h1] * psi_vxx[j][h1] + a_x[h1] * vxx; + vxx = vxx / K_x[h1] + psi_vxx[j][h1]; + + /*psi_vyx[j][h] = b_x_half[h] * psi_vyx[j][h] + a_x_half[h] * vyx; + vyx = vyx / K_x_half[h] + psi_vyx[j][h];*/ + + psi_vyx[j][h1] = b_x_half[h1] * psi_vyx[j][h1] + a_x_half[h1] * vyx; + vyx = vyx / K_x_half[h1] + psi_vyx[j][h1]; + + } + + /* top boundary */ + if((POS[2]==0) && (!(FREE_SURF)) && (j<=FW)){ + + psi_vyy[j][i] = b_y[j] * psi_vyy[j][i] + a_y[j] * vyy; + psi_vxy[j][i] = b_y_half[j] * psi_vxy[j][i] + a_y_half[j] * vxy; + + vyy = vyy / K_y[j] + psi_vyy[j][i]; + vxy = vxy / K_y_half[j] + psi_vxy[j][i]; + + } + + /* bottom boundary */ + if((POS[2]==NPROCY-1) && (j>=ny2-FW+1)){ + + h1 = (j-ny2+2*FW); + h = j; + + psi_vyy[h1][i] = b_y[h1] * psi_vyy[h1][i] + a_y[h1] * vyy; + vyy = vyy / K_y[h1] + psi_vyy[h1][i]; + + /*psi_vxy[j][i] = b_y_half[j] * psi_vxy[j][i] + a_y_half[j] * vxy; + vxy = vxy / K_y_half[j] + psi_vxy[j][i];*/ + + psi_vxy[h1][i] = b_y_half[h1] * psi_vxy[h1][i] + a_y_half[h1] * vxy; + vxy = vxy / K_y_half[h1] + psi_vxy[h1][i]; + + } + + p=c11[j][i]; + q=c13[j][i]; + r=c33[j][i]; + s=c55[j][i]; + + /* lambda - mu relationship*/ +// if (PARAMETERIZATION==3){ +// f = u[j][i]; +// g = pi[j][i];} +// +// if (PARAMETERIZATION==1){ +// f = rho[j][i] * u[j][i] * u[j][i]; +// g = rho[j][i] * ((pi[j][i] * pi[j][i]) - 2 * u[j][i] * u[j][i]);} + + sxy[j][i] += s*(vyx+vxy); + sxx[j][i]+= ( p*vxx ) + ( q*vyy ); + syy[j][i]+= ( q*vxx ) + ( r*vyy ); + + uxy[j][i] = (s/DT)*(vyx+vxy); + ux[j][i] = ( p/DT*vxx ) + ( q/DT*vyy ); + uy[j][i] = ( q/DT*vxx ) + ( r/DT*vyy ); + + } + } + break; + +// case 10: +// for (j=ny1;j<=ny2;j++){ +// for (i=nx1;i<=nx2;i++){ +// vxx = ( hc[1]*(vx[j][i] -vx[j][i-1]) +// + hc[2]*(vx[j][i+1]-vx[j][i-2]) +// + hc[3]*(vx[j][i+2]-vx[j][i-3]) +// + hc[4]*(vx[j][i+3]-vx[j][i-4]) +// + hc[5]*(vx[j][i+4]-vx[j][i-5]) +// )*dhi; +// vyy = ( hc[1]*(vy[j][i] -vy[j-1][i]) +// + hc[2]*(vy[j+1][i]-vy[j-2][i]) +// + hc[3]*(vy[j+2][i]-vy[j-3][i]) +// + hc[4]*(vy[j+3][i]-vy[j-4][i]) +// + hc[5]*(vy[j+4][i]-vy[j-5][i]) +// )*dhi; +// vyx = ( hc[1]*(vy[j][i+1]-vy[j][i]) +// + hc[2]*(vy[j][i+2]-vy[j][i-1]) +// + hc[3]*(vy[j][i+3]-vy[j][i-2]) +// + hc[4]*(vy[j][i+4]-vy[j][i-3]) +// + hc[5]*(vy[j][i+5]-vy[j][i-4]) +// )*dhi; +// vxy = ( hc[1]*(vx[j+1][i]-vx[j][i]) +// + hc[2]*(vx[j+2][i]-vx[j-1][i]) +// + hc[3]*(vx[j+3][i]-vx[j-2][i]) +// + hc[4]*(vx[j+4][i]-vx[j-3][i]) +// + hc[5]*(vx[j+5][i]-vx[j-4][i]) +// )*dhi; +// +// ux[j][i] += DT*vxx; +// uy[j][i] += DT*vyy; +// +// fipjp=uipjp[j][i]*DT; +// f=u[j][i]*DT; +// g=pi[j][i]*DT; +// +// sxy[j][i]+=(fipjp*(vxy+vyx)); +// sxx[j][i]+=(g*(vxx+vyy))-(2.0*f*vyy); +// syy[j][i]+=(g*(vxx+vyy))-(2.0*f*vxx); +// +// /* +// piv = pi[j][i]*(vxx+vyy); +// sxy[j][i]+=(uipjp[j][i]*(vxy+vyx)); +// sxx[j][i]+=piv-(2.0*u[j][i]*vyy); +// syy[j][i]+=piv-(2.0*u[j][i]*vxx); +// */ +// } +// } +// break; +// +// case 12: +// for (j=ny1;j<=ny2;j++){ +// for (i=nx1;i<=nx2;i++){ +// vxx = ( hc[1]*(vx[j][i] -vx[j][i-1]) +// + hc[2]*(vx[j][i+1]-vx[j][i-2]) +// + hc[3]*(vx[j][i+2]-vx[j][i-3]) +// + hc[4]*(vx[j][i+3]-vx[j][i-4]) +// + hc[5]*(vx[j][i+4]-vx[j][i-5]) +// + hc[6]*(vx[j][i+5]-vx[j][i-6]) +// )*dhi; +// vyy = ( hc[1]*(vy[j][i] -vy[j-1][i]) +// + hc[2]*(vy[j+1][i]-vy[j-2][i]) +// + hc[3]*(vy[j+2][i]-vy[j-3][i]) +// + hc[4]*(vy[j+3][i]-vy[j-4][i]) +// + hc[5]*(vy[j+4][i]-vy[j-5][i]) +// + hc[6]*(vy[j+5][i]-vy[j-6][i]) +// )*dhi; +// vyx = ( hc[1]*(vy[j][i+1]-vy[j][i]) +// + hc[2]*(vy[j][i+2]-vy[j][i-1]) +// + hc[3]*(vy[j][i+3]-vy[j][i-2]) +// + hc[4]*(vy[j][i+4]-vy[j][i-3]) +// + hc[5]*(vy[j][i+5]-vy[j][i-4]) +// + hc[6]*(vy[j][i+6]-vy[j][i-5]) +// )*dhi; +// vxy = ( hc[1]*(vx[j+1][i]-vx[j][i]) +// + hc[2]*(vx[j+2][i]-vx[j-1][i]) +// + hc[3]*(vx[j+3][i]-vx[j-2][i]) +// + hc[4]*(vx[j+4][i]-vx[j-3][i]) +// + hc[5]*(vx[j+5][i]-vx[j-4][i]) +// + hc[6]*(vx[j+6][i]-vx[j-5][i]) +// )*dhi; +// +// ux[j][i] += DT*vxx; +// uy[j][i] += DT*vyy; +// +// fipjp=uipjp[j][i]*DT; +// f=u[j][i]*DT; +// g=pi[j][i]*DT; +// +// sxy[j][i]+=(fipjp*(vxy+vyx)); +// sxx[j][i]+=(g*(vxx+vyy))-(2.0*f*vyy); +// syy[j][i]+=(g*(vxx+vyy))-(2.0*f*vxx); +// } +// } +// break; + + default: + for (j=ny1;j<=ny2;j++){ + for (i=nx1;i<=nx2;i++){ + vxx = 0.0; + vyy = 0.0; + vyx = 0.0; + vxy = 0.0; + for (m=1; m<=fdoh; m++) { + vxx += hc[m]*(vx[j][i+m-1] -vx[j][i-m] ); + vyy += hc[m]*(vy[j+m-1][i] -vy[j-m][i] ); + vyx += hc[m]*(vy[j][i+m] -vy[j][i-m+1]); + vxy += hc[m]*(vx[j+m][i] -vx[j-m+1][i]); + } + + p=c11[j][i]; + q=c13[j][i]; + r=c33[j][i]; + s=c55[j][i]; + + sxy[j][i] += s*(vyx+vxy); + sxx[j][i]+= ( p*vxx ) + ( q*vyy ); + syy[j][i]+= ( q*vxx ) + ( r*vyy ); + } + } + break; + + } /* end of switch(FDORDER) */ + + + if (infoout && (MYID==0)){ + time2=MPI_Wtime(); + fprintf(FP," finished (real time: %4.2f s).\n",time2-time1); + } +} diff --git a/src/update_s_el_vti_PML_SH.c b/src/update_s_el_vti_PML_SH.c new file mode 100644 index 0000000000000000000000000000000000000000..f8d0d416f0d05d80093ccc062eee7844a043d431 --- /dev/null +++ b/src/update_s_el_vti_PML_SH.c @@ -0,0 +1,422 @@ +/*----------------------------------------------------------------------------------------- + * Copyright (C) 2016 For the list of authors, see file AUTHORS. + * + * This file is part of IFOS. + * + * IFOS is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, version 2.0 of the License only. + * + * IFOS 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with IFOS. See file COPYING and/or . + -----------------------------------------------------------------------------------------*/ + +/*------------------------------------------------------------------------ + * updating stress components at gridpoints [nx1...nx2][ny1...ny2] + * by a staggered grid finite difference scheme of arbitrary (FDORDER) order accuracy in space + * and second order accuracy in time + * + * SH-Version + * Calculation for vertical transverse isotropy + * + * ----------------------------------------------------------------------*/ + +#include "fd.h" + +void update_s_el_vti_PML_SH(int nx1, int nx2, int ny1, int ny2, float ** vz, float ** sxz, float ** syz, float ** uxz, float ** uyz, float *hc, int infoout,float * K_x, float * a_x, float * b_x, float * K_x_half, float * a_x_half, float * b_x_half, + float * K_y, float * a_y, float * b_y, float * K_y_half, float * a_y_half, float * b_y_half,float ** psi_vzx, float ** psi_vzy, float ** c55,float ** c66ipjp, float ** rho){ + + int i,j, fdoh, h, h1; + float qipjp, p = 0.0; + float vzx, vzy; + + float dhi; + extern float DT, DH; + extern int MYID, FDORDER, FW, L,PARAMETERIZATION; + extern int FREE_SURF, BOUNDARY; + extern int NPROCX, NPROCY, POS[3]; + extern FILE *FP; + double time1 = 0.0, time2; + + + dhi = DT/DH; + fdoh = FDORDER/2; + + + if (infoout && (MYID==0)){ + time1=MPI_Wtime(); + fprintf(FP,"\n **Message from update_s_elastic_SH (printed by PE %d):\n",MYID); + fprintf(FP," Updating stress components ..."); + } + + + + switch (FDORDER){ + + case 2: + for (j=ny1;j<=ny2;j++){ + for (i=nx1;i<=nx2;i++){ + vzx = ( hc[1]*(vz[j][i+1]-vz[j][i]))*dhi; + + vzy = ( hc[1]*(vz[j][i]-vz[j-1][i]))*dhi; + + + /* left boundary */ + if((!BOUNDARY) && (POS[1]==0) && (i<=FW)){ + psi_vzx[j][i] = b_x_half[i] * psi_vzx[j][i] + a_x_half[i] * vzx; + vzx = vzx / K_x_half[i] + psi_vzx[j][i]; + } + + /* right boundary */ + if((!BOUNDARY) && (POS[1]==NPROCX-1) && (i>=nx2-FW+1)){ + h1 = (i-nx2+2*FW); + h = i; + psi_vzx[j][h1] = b_x_half[h1] * psi_vzx[j][h1] + a_x_half[h1] * vzx; + vzx = vzx / K_x_half[h1] + psi_vzx[j][h1]; + } + + /* top boundary */ + if((POS[2]==0) && (!(FREE_SURF)) && (j<=FW)){ + psi_vzy[j][i] = b_y[j] * psi_vzy[j][i] + a_y[j] * vzy; + vzy = vzy / K_y[j] + psi_vzy[j][i]; + } + + /* bottom boundary */ + if((POS[2]==NPROCY-1) && (j>=ny2-FW+1)){ + h1 = (j-ny2+2*FW); + h = j; + psi_vzy[h1][i] = b_y[h1] * psi_vzy[h1][i] + a_y[h1] * vzy; + vzy = vzy / K_y[h1] + psi_vzy[h1][i]; + } + + p=c55[j][i]; + qipjp=c66ipjp[j][i]; + +// /* lambda - mu relationship*/ +// if (PARAMETERIZATION==3) f = u[j][i]; +// if (PARAMETERIZATION==1) f = rho[j][i] * u[j][i] * u[j][i]; + + /* updating components of the stress tensor, partially */ + sxz[j][i]+=(qipjp*vzx); + syz[j][i]+=(p*vzy); + + uxz[j][i]=(qipjp*vzx)/DT; + uyz[j][i]=(p*vzy)/DT; + + } + } + + break; + + case 4: + for (j=ny1;j<=ny2;j++){ + for (i=nx1;i<=nx2;i++){ + vzx = ( hc[1]*(vz[j][i+1]-vz[j][i]) + + hc[2]*(vz[j][i+2]-vz[j][i-1]))*dhi; + + vzy = ( hc[1]*(vz[j][i]-vz[j-1][i]) + + hc[2]*(vz[j+1][i]-vz[j-2][i]))*dhi; + + + /* left boundary */ + if((!BOUNDARY) && (POS[1]==0) && (i<=FW)){ + psi_vzx[j][i] = b_x_half[i] * psi_vzx[j][i] + a_x_half[i] * vzx; + vzx = vzx / K_x_half[i] + psi_vzx[j][i]; + } + + /* right boundary */ + if((!BOUNDARY) && (POS[1]==NPROCX-1) && (i>=nx2-FW+1)){ + h1 = (i-nx2+2*FW); + h = i; + psi_vzx[j][h1] = b_x_half[h1] * psi_vzx[j][h1] + a_x_half[h1] * vzx; + vzx = vzx / K_x_half[h1] + psi_vzx[j][h1]; + } + + /* top boundary */ + if((POS[2]==0) && (!(FREE_SURF)) && (j<=FW)){ + psi_vzy[j][i] = b_y[j] * psi_vzy[j][i] + a_y[j] * vzy; + vzy = vzy / K_y[j] + psi_vzy[j][i]; + } + + /* bottom boundary */ + if((POS[2]==NPROCY-1) && (j>=ny2-FW+1)){ + h1 = (j-ny2+2*FW); + h = j; + psi_vzy[h1][i] = b_y[h1] * psi_vzy[h1][i] + a_y[h1] * vzy; + vzy = vzy / K_y[h1] + psi_vzy[h1][i]; + } + + p=c55[j][i]; + qipjp=c66ipjp[j][i]; + +// /* lambda - mu relationship*/ +// if (PARAMETERIZATION==3) f = u[j][i]; +// if (PARAMETERIZATION==1) f = rho[j][i] * u[j][i] * u[j][i]; + + /* updating components of the stress tensor, partially */ + sxz[j][i]+=(qipjp*vzx); + syz[j][i]+=(p*vzy); + + uxz[j][i]=(qipjp*vzx)/DT; + uyz[j][i]=(p*vzy)/DT; + + } + } + break; + + case 6: + for (j=ny1;j<=ny2;j++){ + for (i=nx1;i<=nx2;i++){ + vzx = ( hc[1]*(vz[j][i+1]-vz[j][i]) + + hc[2]*(vz[j][i+2]-vz[j][i-1]) + + hc[3]*(vz[j][i+3]-vz[j][i-2]))*dhi; + + vzy = ( hc[1]*(vz[j][i]-vz[j-1][i]) + + hc[2]*(vz[j+1][i]-vz[j-2][i]) + + hc[3]*(vz[j+2][i]-vz[j-3][i]))*dhi; + + + /* left boundary */ + if((!BOUNDARY) && (POS[1]==0) && (i<=FW)){ + psi_vzx[j][i] = b_x_half[i] * psi_vzx[j][i] + a_x_half[i] * vzx; + vzx = vzx / K_x_half[i] + psi_vzx[j][i]; + } + + /* right boundary */ + if((!BOUNDARY) && (POS[1]==NPROCX-1) && (i>=nx2-FW+1)){ + h1 = (i-nx2+2*FW); + h = i; + psi_vzx[j][h1] = b_x_half[h1] * psi_vzx[j][h1] + a_x_half[h1] * vzx; + vzx = vzx / K_x_half[h1] + psi_vzx[j][h1]; + } + + /* top boundary */ + if((POS[2]==0) && (!(FREE_SURF)) && (j<=FW)){ + psi_vzy[j][i] = b_y[j] * psi_vzy[j][i] + a_y[j] * vzy; + vzy = vzy / K_y[j] + psi_vzy[j][i]; + } + + /* bottom boundary */ + if((POS[2]==NPROCY-1) && (j>=ny2-FW+1)){ + h1 = (j-ny2+2*FW); + h = j; + psi_vzy[h1][i] = b_y[h1] * psi_vzy[h1][i] + a_y[h1] * vzy; + vzy = vzy / K_y[h1] + psi_vzy[h1][i]; + } + + p=c55[j][i]; + qipjp=c66ipjp[j][i]; + +// /* lambda - mu relationship*/ +// if (PARAMETERIZATION==3) f = u[j][i]; +// if (PARAMETERIZATION==1) f = rho[j][i] * u[j][i] * u[j][i]; + + /* updating components of the stress tensor, partially */ + sxz[j][i]+=(qipjp*vzx); + syz[j][i]+=(p*vzy); + + uxz[j][i]=(qipjp*vzx)/DT; + uyz[j][i]=(p*vzy)/DT; + + } + } + break; + + case 8: + for (j=ny1;j<=ny2;j++){ + for (i=nx1;i<=nx2;i++){ + vzx = ( hc[1]*(vz[j][i+1]-vz[j][i]) + + hc[2]*(vz[j][i+2]-vz[j][i-1]) + + hc[3]*(vz[j][i+3]-vz[j][i-2]) + + hc[4]*(vz[j][i+4]-vz[j][i-3]))*dhi; + + vzy = ( hc[1]*(vz[j][i]-vz[j-1][i]) + + hc[2]*(vz[j+1][i]-vz[j-2][i]) + + hc[3]*(vz[j+2][i]-vz[j-3][i]) + + hc[4]*(vz[j+3][i]-vz[j-4][i]))*dhi; + + + /* left boundary */ + if((!BOUNDARY) && (POS[1]==0) && (i<=FW)){ + psi_vzx[j][i] = b_x_half[i] * psi_vzx[j][i] + a_x_half[i] * vzx; + vzx = vzx / K_x_half[i] + psi_vzx[j][i]; + } + + /* right boundary */ + if((!BOUNDARY) && (POS[1]==NPROCX-1) && (i>=nx2-FW+1)){ + h1 = (i-nx2+2*FW); + h = i; + psi_vzx[j][h1] = b_x_half[h1] * psi_vzx[j][h1] + a_x_half[h1] * vzx; + vzx = vzx / K_x_half[h1] + psi_vzx[j][h1]; + } + + /* top boundary */ + if((POS[2]==0) && (!(FREE_SURF)) && (j<=FW)){ + psi_vzy[j][i] = b_y[j] * psi_vzy[j][i] + a_y[j] * vzy; + vzy = vzy / K_y[j] + psi_vzy[j][i]; + } + + /* bottom boundary */ + if((POS[2]==NPROCY-1) && (j>=ny2-FW+1)){ + h1 = (j-ny2+2*FW); + h = j; + psi_vzy[h1][i] = b_y[h1] * psi_vzy[h1][i] + a_y[h1] * vzy; + vzy = vzy / K_y[h1] + psi_vzy[h1][i]; + } + + p=c55[j][i]; + qipjp=c66ipjp[j][i]; + +// /* lambda - mu relationship*/ +// if (PARAMETERIZATION==3) f = u[j][i]; +// if (PARAMETERIZATION==1) f = rho[j][i] * u[j][i] * u[j][i]; + + /* updating components of the stress tensor, partially */ + sxz[j][i]+=(qipjp*vzx); + syz[j][i]+=(p*vzy); + + uxz[j][i]=(qipjp*vzx)/DT; + uyz[j][i]=(p*vzy)/DT; + + } + } + break; + + case 10: + for (j=ny1;j<=ny2;j++){ + for (i=nx1;i<=nx2;i++){ + vzx = ( hc[1]*(vz[j][i+1]-vz[j][i]) + + hc[2]*(vz[j][i+2]-vz[j][i-1]) + + hc[3]*(vz[j][i+3]-vz[j][i-2]) + + hc[4]*(vz[j][i+4]-vz[j][i-3]) + + hc[5]*(vz[j][i+5]-vz[j][i-4]))*dhi; + + vzy = ( hc[1]*(vz[j][i]-vz[j-1][i]) + + hc[2]*(vz[j+1][i]-vz[j-2][i]) + + hc[3]*(vz[j+2][i]-vz[j-3][i]) + + hc[4]*(vz[j+3][i]-vz[j-4][i]) + + hc[5]*(vz[j+4][i]-vz[j-5][i]))*dhi; + + + /* left boundary */ + if((!BOUNDARY) && (POS[1]==0) && (i<=FW)){ + psi_vzx[j][i] = b_x_half[i] * psi_vzx[j][i] + a_x_half[i] * vzx; + vzx = vzx / K_x_half[i] + psi_vzx[j][i]; + } + + /* right boundary */ + if((!BOUNDARY) && (POS[1]==NPROCX-1) && (i>=nx2-FW+1)){ + h1 = (i-nx2+2*FW); + h = i; + psi_vzx[j][h1] = b_x_half[h1] * psi_vzx[j][h1] + a_x_half[h1] * vzx; + vzx = vzx / K_x_half[h1] + psi_vzx[j][h1]; + } + + /* top boundary */ + if((POS[2]==0) && (!(FREE_SURF)) && (j<=FW)){ + psi_vzy[j][i] = b_y[j] * psi_vzy[j][i] + a_y[j] * vzy; + vzy = vzy / K_y[j] + psi_vzy[j][i]; + } + + /* bottom boundary */ + if((POS[2]==NPROCY-1) && (j>=ny2-FW+1)){ + h1 = (j-ny2+2*FW); + h = j; + psi_vzy[h1][i] = b_y[h1] * psi_vzy[h1][i] + a_y[h1] * vzy; + vzy = vzy / K_y[h1] + psi_vzy[h1][i]; + } + + p=c55[j][i]; + qipjp=c66ipjp[j][i]; + +// /* lambda - mu relationship*/ +// if (PARAMETERIZATION==3) f = u[j][i]; +// if (PARAMETERIZATION==1) f = rho[j][i] * u[j][i] * u[j][i]; + + /* updating components of the stress tensor, partially */ + sxz[j][i]+=(qipjp*vzx); + syz[j][i]+=(p*vzy); + + uxz[j][i]=(qipjp*vzx)/DT; + uyz[j][i]=(p*vzy)/DT; + + } + } + break; + + case 12: + for (j=ny1;j<=ny2;j++){ + for (i=nx1;i<=nx2;i++){ + vzx = ( hc[1]*(vz[j][i+1]-vz[j][i]) + + hc[2]*(vz[j][i+2]-vz[j][i-1]) + + hc[3]*(vz[j][i+3]-vz[j][i-2]) + + hc[4]*(vz[j][i+4]-vz[j][i-3]) + + hc[5]*(vz[j][i+5]-vz[j][i-4]) + + hc[6]*(vz[j][i+6]-vz[j][i-5]))*dhi; + + vzy = ( hc[1]*(vz[j][i]-vz[j-1][i]) + + hc[2]*(vz[j+1][i]-vz[j-2][i]) + + hc[3]*(vz[j+2][i]-vz[j-3][i]) + + hc[4]*(vz[j+3][i]-vz[j-4][i]) + + hc[5]*(vz[j+4][i]-vz[j-5][i]) + + hc[6]*(vz[j+5][i]-vz[j-6][i]))*dhi; + + + /* left boundary */ + if((!BOUNDARY) && (POS[1]==0) && (i<=FW)){ + psi_vzx[j][i] = b_x_half[i] * psi_vzx[j][i] + a_x_half[i] * vzx; + vzx = vzx / K_x_half[i] + psi_vzx[j][i]; + } + + /* right boundary */ + if((!BOUNDARY) && (POS[1]==NPROCX-1) && (i>=nx2-FW+1)){ + h1 = (i-nx2+2*FW); + h = i; + psi_vzx[j][h1] = b_x_half[h1] * psi_vzx[j][h1] + a_x_half[h1] * vzx; + vzx = vzx / K_x_half[h1] + psi_vzx[j][h1]; + } + + /* top boundary */ + if((POS[2]==0) && (!(FREE_SURF)) && (j<=FW)){ + psi_vzy[j][i] = b_y[j] * psi_vzy[j][i] + a_y[j] * vzy; + vzy = vzy / K_y[j] + psi_vzy[j][i]; + } + + /* bottom boundary */ + if((POS[2]==NPROCY-1) && (j>=ny2-FW+1)){ + h1 = (j-ny2+2*FW); + h = j; + psi_vzy[h1][i] = b_y[h1] * psi_vzy[h1][i] + a_y[h1] * vzy; + vzy = vzy / K_y[h1] + psi_vzy[h1][i]; + } + + p=c55[j][i]; + qipjp=c66ipjp[j][i]; + +// /* lambda - mu relationship*/ +// if (PARAMETERIZATION==3) f = u[j][i]; +// if (PARAMETERIZATION==1) f = rho[j][i] * u[j][i] * u[j][i]; + + /* updating components of the stress tensor, partially */ + sxz[j][i]+=(qipjp*vzx); + syz[j][i]+=(p*vzy); + + uxz[j][i]=(qipjp*vzx)/DT; + uyz[j][i]=(p*vzy)/DT; + + } + } + break; + } /* end of switch(FDORDER) */ + + + if (infoout && (MYID==0)){ + time2=MPI_Wtime(); + fprintf(FP," finished (real time: %4.2f s).\n",time2-time1); + } +} diff --git a/src/update_s_elastic_PML_SH.c b/src/update_s_elastic_PML_SH.c index 43966fed95c0b34aee24fb9ae0d007038bac4ec1..9f7894a30b3912ae01356b06342842b9537e52ce 100644 --- a/src/update_s_elastic_PML_SH.c +++ b/src/update_s_elastic_PML_SH.c @@ -103,8 +103,8 @@ void update_s_elastic_PML_SH(int nx1, int nx2, int ny1, int ny2, float ** vz, f sxz[j][i]+=(fipjp*vzx); syz[j][i]+=(f*vzy); - uxz[j][i]+=(fipjp*vzx)/DT; - uyz[j][i]+=(f*vzy)/DT; + uxz[j][i]=(fipjp*vzx)/DT; + uyz[j][i]=(f*vzy)/DT; } } @@ -159,8 +159,8 @@ void update_s_elastic_PML_SH(int nx1, int nx2, int ny1, int ny2, float ** vz, f sxz[j][i]+=(fipjp*vzx); syz[j][i]+=(f*vzy); - uxz[j][i]+=(fipjp*vzx)/DT; - uyz[j][i]+=(f*vzy)/DT; + uxz[j][i]=(fipjp*vzx)/DT; + uyz[j][i]=(f*vzy)/DT; } } @@ -216,8 +216,8 @@ void update_s_elastic_PML_SH(int nx1, int nx2, int ny1, int ny2, float ** vz, f sxz[j][i]+=(fipjp*vzx); syz[j][i]+=(f*vzy); - uxz[j][i]+=(fipjp*vzx)/DT; - uyz[j][i]+=(f*vzy)/DT; + uxz[j][i]=(fipjp*vzx)/DT; + uyz[j][i]=(f*vzy)/DT; } } @@ -275,8 +275,8 @@ void update_s_elastic_PML_SH(int nx1, int nx2, int ny1, int ny2, float ** vz, f sxz[j][i]+=(fipjp*vzx); syz[j][i]+=(f*vzy); - uxz[j][i]+=(fipjp*vzx)/DT; - uyz[j][i]+=(f*vzy)/DT; + uxz[j][i]=(fipjp*vzx)/DT; + uyz[j][i]=(f*vzy)/DT; } } @@ -336,8 +336,8 @@ void update_s_elastic_PML_SH(int nx1, int nx2, int ny1, int ny2, float ** vz, f sxz[j][i]+=(fipjp*vzx); syz[j][i]+=(f*vzy); - uxz[j][i]+=(fipjp*vzx)/DT; - uyz[j][i]+=(f*vzy)/DT; + uxz[j][i]=(fipjp*vzx)/DT; + uyz[j][i]=(f*vzy)/DT; } } @@ -399,8 +399,8 @@ void update_s_elastic_PML_SH(int nx1, int nx2, int ny1, int ny2, float ** vz, f sxz[j][i]+=(fipjp*vzx); syz[j][i]+=(f*vzy); - uxz[j][i]+=(fipjp*vzx)/DT; - uyz[j][i]+=(f*vzy)/DT; + uxz[j][i]=(fipjp*vzx)/DT; + uyz[j][i]=(f*vzy)/DT; } } diff --git a/src/update_s_visc_PML_SH.c b/src/update_s_visc_PML_SH.c index 42e90cbf978415d40a31fbf59b941abefd61f07c..2b501ef7e6ec9ea14be6303bcd272b5ea7a9158d 100644 --- a/src/update_s_visc_PML_SH.c +++ b/src/update_s_visc_PML_SH.c @@ -26,7 +26,7 @@ #include "fd.h" -void update_s_visc_PML_SH(int nx1, int nx2, int ny1, int ny2, float ** vz, float ** sxz, float ** syz, float ***t, float ***o, float *bip, float *bjm, float *cip, float *cjm, float ***d, float ***dip, float **fipjp, float **f, float *hc, int infoout,float * K_x, float * a_x, float * b_x, float * K_x_half, float * a_x_half, float * b_x_half,float * K_y, float * a_y, float * b_y, float * K_y_half, float * a_y_half, float * b_y_half,float ** psi_vzx, float ** psi_vzy){ +void update_s_visc_PML_SH(int nx1, int nx2, int ny1, int ny2, float ** vz, float ** uxz, float **uyz, float ** sxz, float ** syz, float ***t, float ***o, float *bip, float *bjm, float *cip, float *cjm, float ***d, float ***dip, float **fipjp, float **f, float *hc, int infoout,float * K_x, float * a_x, float * b_x, float * K_x_half, float * a_x_half, float * b_x_half,float * K_y, float * a_y, float * b_y, float * K_y_half, float * a_y_half, float * b_y_half,float ** psi_vzx, float ** psi_vzy){ int i,j, m, fdoh, h, h1, l; @@ -102,6 +102,9 @@ void update_s_visc_PML_SH(int nx1, int nx2, int ny1, int ny2, float ** vz, floa /* updating components of the stress tensor, partially */ sxz[j][i]+=(fipjp[j][i]*vzx)+(dthalbe*sumo); syz[j][i]+=(f[j][i]*vzy)+(dthalbe*sumt); + + uxz[j][i]=(fipjp[j][i]*vzx)/DT+(0.5*sumo); + uyz[j][i]=(f[j][i]*vzy)/DT+(0.5*sumt); /* now updating the memory-variables and sum them up*/ @@ -117,6 +120,9 @@ void update_s_visc_PML_SH(int nx1, int nx2, int ny1, int ny2, float ** vz, floa completely updated */ sxz[j][i]+=(dthalbe*sumo); syz[j][i]+=(dthalbe*sumt); + + uxz[j][i]+=(0.5*sumo); + uyz[j][i]+=(0.5*sumt); } } @@ -171,6 +177,9 @@ void update_s_visc_PML_SH(int nx1, int nx2, int ny1, int ny2, float ** vz, floa /* updating components of the stress tensor, partially */ sxz[j][i]+=(fipjp[j][i]*vzx)+(dthalbe*sumo); syz[j][i]+=(f[j][i]*vzy)+(dthalbe*sumt); + + uxz[j][i]=(fipjp[j][i]*vzx)/DT+(0.5*sumo); + uyz[j][i]=(f[j][i]*vzy)/DT+(0.5*sumt); /* now updating the memory-variables and sum them up*/ @@ -186,6 +195,9 @@ void update_s_visc_PML_SH(int nx1, int nx2, int ny1, int ny2, float ** vz, floa completely updated */ sxz[j][i]+=(dthalbe*sumo); syz[j][i]+=(dthalbe*sumt); + + uxz[j][i]+=(0.5*sumo); + uyz[j][i]+=(0.5*sumt); } } break; @@ -240,6 +252,9 @@ void update_s_visc_PML_SH(int nx1, int nx2, int ny1, int ny2, float ** vz, floa /* updating components of the stress tensor, partially */ sxz[j][i]+=(fipjp[j][i]*vzx)+(dthalbe*sumo); syz[j][i]+=(f[j][i]*vzy)+(dthalbe*sumt); + + uxz[j][i]=(fipjp[j][i]*vzx)/DT+(0.5*sumo); + uyz[j][i]=(f[j][i]*vzy)/DT+(0.5*sumt); /* now updating the memory-variables and sum them up*/ @@ -255,6 +270,9 @@ void update_s_visc_PML_SH(int nx1, int nx2, int ny1, int ny2, float ** vz, floa completely updated */ sxz[j][i]+=(dthalbe*sumo); syz[j][i]+=(dthalbe*sumt); + + uxz[j][i]+=(0.5*sumo); + uyz[j][i]+=(0.5*sumt); } } break; @@ -311,6 +329,9 @@ void update_s_visc_PML_SH(int nx1, int nx2, int ny1, int ny2, float ** vz, floa /* updating components of the stress tensor, partially */ sxz[j][i]+=(fipjp[j][i]*vzx)+(dthalbe*sumo); syz[j][i]+=(f[j][i]*vzy)+(dthalbe*sumt); + + uxz[j][i]=(fipjp[j][i]*vzx)/DT+(0.5*sumo); + uyz[j][i]=(f[j][i]*vzy)/DT+(0.5*sumt); /* now updating the memory-variables and sum them up*/ @@ -326,6 +347,9 @@ void update_s_visc_PML_SH(int nx1, int nx2, int ny1, int ny2, float ** vz, floa completely updated */ sxz[j][i]+=(dthalbe*sumo); syz[j][i]+=(dthalbe*sumt); + + uxz[j][i]+=(0.5*sumo); + uyz[j][i]+=(0.5*sumt); } } break; @@ -384,6 +408,9 @@ void update_s_visc_PML_SH(int nx1, int nx2, int ny1, int ny2, float ** vz, floa /* updating components of the stress tensor, partially */ sxz[j][i]+=(fipjp[j][i]*vzx)+(dthalbe*sumo); syz[j][i]+=(f[j][i]*vzy)+(dthalbe*sumt); + + uxz[j][i]=(fipjp[j][i]*vzx)/DT+(0.5*sumo); + uyz[j][i]=(f[j][i]*vzy)/DT+(0.5*sumt); /* now updating the memory-variables and sum them up*/ @@ -399,6 +426,9 @@ void update_s_visc_PML_SH(int nx1, int nx2, int ny1, int ny2, float ** vz, floa completely updated */ sxz[j][i]+=(dthalbe*sumo); syz[j][i]+=(dthalbe*sumt); + + uxz[j][i]+=(0.5*sumo); + uyz[j][i]+=(0.5*sumt); } } break; @@ -458,6 +488,9 @@ void update_s_visc_PML_SH(int nx1, int nx2, int ny1, int ny2, float ** vz, floa /* updating components of the stress tensor, partially */ sxz[j][i]+=(fipjp[j][i]*vzx)+(dthalbe*sumo); syz[j][i]+=(f[j][i]*vzy)+(dthalbe*sumt); + + uxz[j][i]=(fipjp[j][i]*vzx)/DT+(0.5*sumo); + uyz[j][i]=(f[j][i]*vzy)/DT+(0.5*sumt); /* now updating the memory-variables and sum them up*/ @@ -473,6 +506,9 @@ void update_s_visc_PML_SH(int nx1, int nx2, int ny1, int ny2, float ** vz, floa completely updated */ sxz[j][i]+=(dthalbe*sumo); syz[j][i]+=(dthalbe*sumt); + + uxz[j][i]+=(0.5*sumo); + uyz[j][i]+=(0.5*sumt); } } break; diff --git a/src/update_s_visc_vti_PML_SH.c b/src/update_s_visc_vti_PML_SH.c new file mode 100644 index 0000000000000000000000000000000000000000..dd43f5ac75d1d178ca4b2cbf195b7daff57ff11a --- /dev/null +++ b/src/update_s_visc_vti_PML_SH.c @@ -0,0 +1,527 @@ +/*----------------------------------------------------------------------------------------- + * Copyright (C) 2016 For the list of authors, see file AUTHORS. + * + * This file is part of IFOS. + * + * IFOS is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, version 2.0 of the License only. + * + * IFOS 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with IFOS. See file COPYING and/or . + -----------------------------------------------------------------------------------------*/ + +/*------------------------------------------------------------------------ + * updating stress components at gridpoints [nx1...nx2][ny1...ny2] + * by a staggered grid finite difference scheme of arbitrary (FDORDER) order accuracy in space + * and second order accuracy in time + * + * SH-Version + * Calculation for vertical transverse isotropy + * + * ----------------------------------------------------------------------*/ + +#include "fd.h" + +void update_s_visc_vti_PML_SH(int nx1, int nx2, int ny1, int ny2, float ** vz, float ** uxz, float ** uyz, float ** sxz, float ** syz, + float ***t, float ***o, float *bip, float *bjm, float *cip, float *cjm, float ***d, float ***dip, float **fipjp, float **f, + float *hc, int infoout,float * K_x, float * a_x, float * b_x, float * K_x_half, float * a_x_half, float * b_x_half, + float * K_y, float * a_y, float * b_y, float * K_y_half, float * a_y_half, float * b_y_half,float ** psi_vzx, float ** psi_vzy, float ** c55,float ** c66ipjp, float ** rho){ + + int i,j, fdoh, h, h1, l; + float qipjp, p = 0.0; + float vzx, vzy; + + float dhi, dthalbe; + extern float DT, DH; + extern int MYID, FDORDER, FW, L,PARAMETERIZATION; + extern int FREE_SURF, BOUNDARY; + extern int NPROCX, NPROCY, POS[3]; + extern FILE *FP; + double time1 = 0.0, time2; + float sumo=0.0, sumt=0.0; + + dhi=1.0/DH; + fdoh = FDORDER/2; + dthalbe = DT/2.0; + + + if (infoout && (MYID==0)){ + time1=MPI_Wtime(); + fprintf(FP,"\n **Message from update_s_elastic_SH (printed by PE %d):\n",MYID); + fprintf(FP," Updating stress components ..."); + } + + + + switch (FDORDER){ + + case 2: + for (j=ny1;j<=ny2;j++){ + for (i=nx1;i<=nx2;i++){ + vzx = ( hc[1]*(vz[j][i+1]-vz[j][i]))*dhi; + + vzy = ( hc[1]*(vz[j][i]-vz[j-1][i]))*dhi; + + + /* left boundary */ + if((!BOUNDARY) && (POS[1]==0) && (i<=FW)){ + psi_vzx[j][i] = b_x_half[i] * psi_vzx[j][i] + a_x_half[i] * vzx; + vzx = vzx / K_x_half[i] + psi_vzx[j][i]; + } + + /* right boundary */ + if((!BOUNDARY) && (POS[1]==NPROCX-1) && (i>=nx2-FW+1)){ + h1 = (i-nx2+2*FW); + h = i; + psi_vzx[j][h1] = b_x_half[h1] * psi_vzx[j][h1] + a_x_half[h1] * vzx; + vzx = vzx / K_x_half[h1] + psi_vzx[j][h1]; + } + + /* top boundary */ + if((POS[2]==0) && (!(FREE_SURF)) && (j<=FW)){ + psi_vzy[j][i] = b_y[j] * psi_vzy[j][i] + a_y[j] * vzy; + vzy = vzy / K_y[j] + psi_vzy[j][i]; + } + + /* bottom boundary */ + if((POS[2]==NPROCY-1) && (j>=ny2-FW+1)){ + h1 = (j-ny2+2*FW); + h = j; + psi_vzy[h1][i] = b_y[h1] * psi_vzy[h1][i] + a_y[h1] * vzy; + vzy = vzy / K_y[h1] + psi_vzy[h1][i]; + } + + /* computing sums of the old memory variables */ + sumt=sumo=0.0; + for (l=1;l<=L;l++){ + sumo+=o[j][i][l]; + sumt+=t[j][i][l]; + } + + /* updating components of the stress tensor, partially */ + sxz[j][i]+=(fipjp[j][i]*vzx)+(dthalbe*sumo); + syz[j][i]+=(f[j][i]*vzy)+(dthalbe*sumt); + + uxz[j][i]=(fipjp[j][i]*vzx)/DT+(0.5*sumo); + uyz[j][i]=(f[j][i]*vzy)/DT+(0.5*sumt); + + /* now updating the memory-variables and sum them up*/ + sumt=sumo=0.0; + for (l=1;l<=L;l++){ + o[j][i][l]=bip[l]*(o[j][i][l]*cip[l]-(dip[j][i][l]*vzx)); + t[j][i][l]=bjm[l]*(t[j][i][l]*cjm[l]-(d[j][i][l]*vzy)); + sumt+=t[j][i][l]; + sumo+=o[j][i][l]; + } + + /* and now the components of the stress tensor are + completely updated */ + sxz[j][i]+=(dthalbe*sumo); + syz[j][i]+=(dthalbe*sumt); + + uxz[j][i]+=(0.5*sumo); + uyz[j][i]+=(0.5*sumt); + + } + } + + break; + + case 4: + for (j=ny1;j<=ny2;j++){ + for (i=nx1;i<=nx2;i++){ + vzx = ( hc[1]*(vz[j][i+1]-vz[j][i]) + + hc[2]*(vz[j][i+2]-vz[j][i-1]))*dhi; + + vzy = ( hc[1]*(vz[j][i]-vz[j-1][i]) + + hc[2]*(vz[j+1][i]-vz[j-2][i]))*dhi; + + + /* left boundary */ + if((!BOUNDARY) && (POS[1]==0) && (i<=FW)){ + psi_vzx[j][i] = b_x_half[i] * psi_vzx[j][i] + a_x_half[i] * vzx; + vzx = vzx / K_x_half[i] + psi_vzx[j][i]; + } + + /* right boundary */ + if((!BOUNDARY) && (POS[1]==NPROCX-1) && (i>=nx2-FW+1)){ + h1 = (i-nx2+2*FW); + h = i; + psi_vzx[j][h1] = b_x_half[h1] * psi_vzx[j][h1] + a_x_half[h1] * vzx; + vzx = vzx / K_x_half[h1] + psi_vzx[j][h1]; + } + + /* top boundary */ + if((POS[2]==0) && (!(FREE_SURF)) && (j<=FW)){ + psi_vzy[j][i] = b_y[j] * psi_vzy[j][i] + a_y[j] * vzy; + vzy = vzy / K_y[j] + psi_vzy[j][i]; + } + + /* bottom boundary */ + if((POS[2]==NPROCY-1) && (j>=ny2-FW+1)){ + h1 = (j-ny2+2*FW); + h = j; + psi_vzy[h1][i] = b_y[h1] * psi_vzy[h1][i] + a_y[h1] * vzy; + vzy = vzy / K_y[h1] + psi_vzy[h1][i]; + } + + /* computing sums of the old memory variables */ + sumt=sumo=0.0; + for (l=1;l<=L;l++){ + sumo+=o[j][i][l]; + sumt+=t[j][i][l]; + } + + /* updating components of the stress tensor, partially */ + sxz[j][i]+=(fipjp[j][i]*vzx)+(dthalbe*sumo); + syz[j][i]+=(f[j][i]*vzy)+(dthalbe*sumt); + + uxz[j][i]=(fipjp[j][i]*vzx)/DT+(0.5*sumo); + uyz[j][i]=(f[j][i]*vzy)/DT+(0.5*sumt); + + /* now updating the memory-variables and sum them up*/ + sumt=sumo=0.0; + for (l=1;l<=L;l++){ + o[j][i][l]=bip[l]*(o[j][i][l]*cip[l]-(dip[j][i][l]*vzx)); + t[j][i][l]=bjm[l]*(t[j][i][l]*cjm[l]-(d[j][i][l]*vzy)); + sumt+=t[j][i][l]; + sumo+=o[j][i][l]; + } + + /* and now the components of the stress tensor are + completely updated */ + sxz[j][i]+=(dthalbe*sumo); + syz[j][i]+=(dthalbe*sumt); + + uxz[j][i]+=(0.5*sumo); + uyz[j][i]+=(0.5*sumt); + + } + } + break; + + case 6: + for (j=ny1;j<=ny2;j++){ + for (i=nx1;i<=nx2;i++){ + vzx = ( hc[1]*(vz[j][i+1]-vz[j][i]) + + hc[2]*(vz[j][i+2]-vz[j][i-1]) + + hc[3]*(vz[j][i+3]-vz[j][i-2]))*dhi; + + vzy = ( hc[1]*(vz[j][i]-vz[j-1][i]) + + hc[2]*(vz[j+1][i]-vz[j-2][i]) + + hc[3]*(vz[j+2][i]-vz[j-3][i]))*dhi; + + + /* left boundary */ + if((!BOUNDARY) && (POS[1]==0) && (i<=FW)){ + psi_vzx[j][i] = b_x_half[i] * psi_vzx[j][i] + a_x_half[i] * vzx; + vzx = vzx / K_x_half[i] + psi_vzx[j][i]; + } + + /* right boundary */ + if((!BOUNDARY) && (POS[1]==NPROCX-1) && (i>=nx2-FW+1)){ + h1 = (i-nx2+2*FW); + h = i; + psi_vzx[j][h1] = b_x_half[h1] * psi_vzx[j][h1] + a_x_half[h1] * vzx; + vzx = vzx / K_x_half[h1] + psi_vzx[j][h1]; + } + + /* top boundary */ + if((POS[2]==0) && (!(FREE_SURF)) && (j<=FW)){ + psi_vzy[j][i] = b_y[j] * psi_vzy[j][i] + a_y[j] * vzy; + vzy = vzy / K_y[j] + psi_vzy[j][i]; + } + + /* bottom boundary */ + if((POS[2]==NPROCY-1) && (j>=ny2-FW+1)){ + h1 = (j-ny2+2*FW); + h = j; + psi_vzy[h1][i] = b_y[h1] * psi_vzy[h1][i] + a_y[h1] * vzy; + vzy = vzy / K_y[h1] + psi_vzy[h1][i]; + } + + /* computing sums of the old memory variables */ + sumt=sumo=0.0; + for (l=1;l<=L;l++){ + sumo+=o[j][i][l]; + sumt+=t[j][i][l]; + } + + /* updating components of the stress tensor, partially */ + sxz[j][i]+=(fipjp[j][i]*vzx)+(dthalbe*sumo); + syz[j][i]+=(f[j][i]*vzy)+(dthalbe*sumt); + + uxz[j][i]=(fipjp[j][i]*vzx)/DT+(0.5*sumo); + uyz[j][i]=(f[j][i]*vzy)/DT+(0.5*sumt); + + /* now updating the memory-variables and sum them up*/ + sumt=sumo=0.0; + for (l=1;l<=L;l++){ + o[j][i][l]=bip[l]*(o[j][i][l]*cip[l]-(dip[j][i][l]*vzx)); + t[j][i][l]=bjm[l]*(t[j][i][l]*cjm[l]-(d[j][i][l]*vzy)); + sumt+=t[j][i][l]; + sumo+=o[j][i][l]; + } + + /* and now the components of the stress tensor are + completely updated */ + sxz[j][i]+=(dthalbe*sumo); + syz[j][i]+=(dthalbe*sumt); + + uxz[j][i]+=(0.5*sumo); + uyz[j][i]+=(0.5*sumt); + + } + } + break; + + case 8: + for (j=ny1;j<=ny2;j++){ + for (i=nx1;i<=nx2;i++){ + vzx = ( hc[1]*(vz[j][i+1]-vz[j][i]) + + hc[2]*(vz[j][i+2]-vz[j][i-1]) + + hc[3]*(vz[j][i+3]-vz[j][i-2]) + + hc[4]*(vz[j][i+4]-vz[j][i-3]))*dhi; + + vzy = ( hc[1]*(vz[j][i]-vz[j-1][i]) + + hc[2]*(vz[j+1][i]-vz[j-2][i]) + + hc[3]*(vz[j+2][i]-vz[j-3][i]) + + hc[4]*(vz[j+3][i]-vz[j-4][i]))*dhi; + + + /* left boundary */ + if((!BOUNDARY) && (POS[1]==0) && (i<=FW)){ + psi_vzx[j][i] = b_x_half[i] * psi_vzx[j][i] + a_x_half[i] * vzx; + vzx = vzx / K_x_half[i] + psi_vzx[j][i]; + } + + /* right boundary */ + if((!BOUNDARY) && (POS[1]==NPROCX-1) && (i>=nx2-FW+1)){ + h1 = (i-nx2+2*FW); + h = i; + psi_vzx[j][h1] = b_x_half[h1] * psi_vzx[j][h1] + a_x_half[h1] * vzx; + vzx = vzx / K_x_half[h1] + psi_vzx[j][h1]; + } + + /* top boundary */ + if((POS[2]==0) && (!(FREE_SURF)) && (j<=FW)){ + psi_vzy[j][i] = b_y[j] * psi_vzy[j][i] + a_y[j] * vzy; + vzy = vzy / K_y[j] + psi_vzy[j][i]; + } + + /* bottom boundary */ + if((POS[2]==NPROCY-1) && (j>=ny2-FW+1)){ + h1 = (j-ny2+2*FW); + h = j; + psi_vzy[h1][i] = b_y[h1] * psi_vzy[h1][i] + a_y[h1] * vzy; + vzy = vzy / K_y[h1] + psi_vzy[h1][i]; + } + + /* computing sums of the old memory variables */ + sumt=sumo=0.0; + for (l=1;l<=L;l++){ + sumo+=o[j][i][l]; + sumt+=t[j][i][l]; + } + + /* updating components of the stress tensor, partially */ + sxz[j][i]+=(fipjp[j][i]*vzx)+(dthalbe*sumo); + syz[j][i]+=(f[j][i]*vzy)+(dthalbe*sumt); + + uxz[j][i]=(fipjp[j][i]*vzx)/DT+(0.5*sumo); + uyz[j][i]=(f[j][i]*vzy)/DT+(0.5*sumt); + + /* now updating the memory-variables and sum them up*/ + sumt=sumo=0.0; + for (l=1;l<=L;l++){ + o[j][i][l]=bip[l]*(o[j][i][l]*cip[l]-(dip[j][i][l]*vzx)); + t[j][i][l]=bjm[l]*(t[j][i][l]*cjm[l]-(d[j][i][l]*vzy)); + sumt+=t[j][i][l]; + sumo+=o[j][i][l]; + } + + /* and now the components of the stress tensor are + completely updated */ + sxz[j][i]+=(dthalbe*sumo); + syz[j][i]+=(dthalbe*sumt); + + uxz[j][i]+=(0.5*sumo); + uyz[j][i]+=(0.5*sumt); + + } + } + break; + + case 10: + for (j=ny1;j<=ny2;j++){ + for (i=nx1;i<=nx2;i++){ + vzx = ( hc[1]*(vz[j][i+1]-vz[j][i]) + + hc[2]*(vz[j][i+2]-vz[j][i-1]) + + hc[3]*(vz[j][i+3]-vz[j][i-2]) + + hc[4]*(vz[j][i+4]-vz[j][i-3]) + + hc[5]*(vz[j][i+5]-vz[j][i-4]))*dhi; + + vzy = ( hc[1]*(vz[j][i]-vz[j-1][i]) + + hc[2]*(vz[j+1][i]-vz[j-2][i]) + + hc[3]*(vz[j+2][i]-vz[j-3][i]) + + hc[4]*(vz[j+3][i]-vz[j-4][i]) + + hc[5]*(vz[j+4][i]-vz[j-5][i]))*dhi; + + + /* left boundary */ + if((!BOUNDARY) && (POS[1]==0) && (i<=FW)){ + psi_vzx[j][i] = b_x_half[i] * psi_vzx[j][i] + a_x_half[i] * vzx; + vzx = vzx / K_x_half[i] + psi_vzx[j][i]; + } + + /* right boundary */ + if((!BOUNDARY) && (POS[1]==NPROCX-1) && (i>=nx2-FW+1)){ + h1 = (i-nx2+2*FW); + h = i; + psi_vzx[j][h1] = b_x_half[h1] * psi_vzx[j][h1] + a_x_half[h1] * vzx; + vzx = vzx / K_x_half[h1] + psi_vzx[j][h1]; + } + + /* top boundary */ + if((POS[2]==0) && (!(FREE_SURF)) && (j<=FW)){ + psi_vzy[j][i] = b_y[j] * psi_vzy[j][i] + a_y[j] * vzy; + vzy = vzy / K_y[j] + psi_vzy[j][i]; + } + + /* bottom boundary */ + if((POS[2]==NPROCY-1) && (j>=ny2-FW+1)){ + h1 = (j-ny2+2*FW); + h = j; + psi_vzy[h1][i] = b_y[h1] * psi_vzy[h1][i] + a_y[h1] * vzy; + vzy = vzy / K_y[h1] + psi_vzy[h1][i]; + } + + /* computing sums of the old memory variables */ + sumt=sumo=0.0; + for (l=1;l<=L;l++){ + sumo+=o[j][i][l]; + sumt+=t[j][i][l]; + } + + /* updating components of the stress tensor, partially */ + sxz[j][i]+=(fipjp[j][i]*vzx)+(dthalbe*sumo); + syz[j][i]+=(f[j][i]*vzy)+(dthalbe*sumt); + + uxz[j][i]=(fipjp[j][i]*vzx)/DT+(0.5*sumo); + uyz[j][i]=(f[j][i]*vzy)/DT+(0.5*sumt); + + /* now updating the memory-variables and sum them up*/ + sumt=sumo=0.0; + for (l=1;l<=L;l++){ + o[j][i][l]=bip[l]*(o[j][i][l]*cip[l]-(dip[j][i][l]*vzx)); + t[j][i][l]=bjm[l]*(t[j][i][l]*cjm[l]-(d[j][i][l]*vzy)); + sumt+=t[j][i][l]; + sumo+=o[j][i][l]; + } + + /* and now the components of the stress tensor are + completely updated */ + sxz[j][i]+=(dthalbe*sumo); + syz[j][i]+=(dthalbe*sumt); + + uxz[j][i]+=(0.5*sumo); + uyz[j][i]+=(0.5*sumt); + + } + } + break; + + case 12: + for (j=ny1;j<=ny2;j++){ + for (i=nx1;i<=nx2;i++){ + vzx = ( hc[1]*(vz[j][i+1]-vz[j][i]) + + hc[2]*(vz[j][i+2]-vz[j][i-1]) + + hc[3]*(vz[j][i+3]-vz[j][i-2]) + + hc[4]*(vz[j][i+4]-vz[j][i-3]) + + hc[5]*(vz[j][i+5]-vz[j][i-4]) + + hc[6]*(vz[j][i+6]-vz[j][i-5]))*dhi; + + vzy = ( hc[1]*(vz[j][i]-vz[j-1][i]) + + hc[2]*(vz[j+1][i]-vz[j-2][i]) + + hc[3]*(vz[j+2][i]-vz[j-3][i]) + + hc[4]*(vz[j+3][i]-vz[j-4][i]) + + hc[5]*(vz[j+4][i]-vz[j-5][i]) + + hc[6]*(vz[j+5][i]-vz[j-6][i]))*dhi; + + + /* left boundary */ + if((!BOUNDARY) && (POS[1]==0) && (i<=FW)){ + psi_vzx[j][i] = b_x_half[i] * psi_vzx[j][i] + a_x_half[i] * vzx; + vzx = vzx / K_x_half[i] + psi_vzx[j][i]; + } + + /* right boundary */ + if((!BOUNDARY) && (POS[1]==NPROCX-1) && (i>=nx2-FW+1)){ + h1 = (i-nx2+2*FW); + h = i; + psi_vzx[j][h1] = b_x_half[h1] * psi_vzx[j][h1] + a_x_half[h1] * vzx; + vzx = vzx / K_x_half[h1] + psi_vzx[j][h1]; + } + + /* top boundary */ + if((POS[2]==0) && (!(FREE_SURF)) && (j<=FW)){ + psi_vzy[j][i] = b_y[j] * psi_vzy[j][i] + a_y[j] * vzy; + vzy = vzy / K_y[j] + psi_vzy[j][i]; + } + + /* bottom boundary */ + if((POS[2]==NPROCY-1) && (j>=ny2-FW+1)){ + h1 = (j-ny2+2*FW); + h = j; + psi_vzy[h1][i] = b_y[h1] * psi_vzy[h1][i] + a_y[h1] * vzy; + vzy = vzy / K_y[h1] + psi_vzy[h1][i]; + } + + /* computing sums of the old memory variables */ + sumt=sumo=0.0; + for (l=1;l<=L;l++){ + sumo+=o[j][i][l]; + sumt+=t[j][i][l]; + } + + /* updating components of the stress tensor, partially */ + sxz[j][i]+=(fipjp[j][i]*vzx)+(dthalbe*sumo); + syz[j][i]+=(f[j][i]*vzy)+(dthalbe*sumt); + + uxz[j][i]=(fipjp[j][i]*vzx)/DT+(0.5*sumo); + uyz[j][i]=(f[j][i]*vzy)/DT+(0.5*sumt); + + /* now updating the memory-variables and sum them up*/ + sumt=sumo=0.0; + for (l=1;l<=L;l++){ + o[j][i][l]=bip[l]*(o[j][i][l]*cip[l]-(dip[j][i][l]*vzx)); + t[j][i][l]=bjm[l]*(t[j][i][l]*cjm[l]-(d[j][i][l]*vzy)); + sumt+=t[j][i][l]; + sumo+=o[j][i][l]; + } + + /* and now the components of the stress tensor are + completely updated */ + sxz[j][i]+=(dthalbe*sumo); + syz[j][i]+=(dthalbe*sumt); + + uxz[j][i]+=(0.5*sumo); + uyz[j][i]+=(0.5*sumt); + + } + } + break; + } /* end of switch(FDORDER) */ + + + if (infoout && (MYID==0)){ + time2=MPI_Wtime(); + fprintf(FP," finished (real time: %4.2f s).\n",time2-time1); + } +} diff --git a/src/update_v_PML_SH.c b/src/update_v_PML_SH.c index f88f06761268bba247ade8034e2155ac7b0cd0cb..6a704060f74c2f017790a7fc9e1e831f90b13ac9 100644 --- a/src/update_v_PML_SH.c +++ b/src/update_v_PML_SH.c @@ -95,7 +95,22 @@ void update_v_PML_SH(int nx1, int nx2, int ny1, int ny2, int nt, syz_y = syz_y / K_y_half[h1] + psi_syz_y[h1][i]; } - vzp1[j][i] = vz[j][i]; + + /* forward propagation */ + if(sw==0){ + vzp1[j][i] = rjp[j][i]*(sxz_x+syz_y)/DH; /* derivative of velocity */ + } + + /* backward propagation */ + if(sw==1){ + if(VELOCITY==0){ + vzp1[j][i] += vz[j][i]*DT; /* displacement */ + } + else{ + vzp1[j][i] = vz[j][i]; /* velocity */ + } + } + vz[j][i] += rjp[j][i]*DT*(sxz_x+syz_y)/(DH); @@ -139,7 +154,20 @@ void update_v_PML_SH(int nx1, int nx2, int ny1, int ny2, int nt, syz_y = syz_y / K_y_half[h1] + psi_syz_y[h1][i]; } - vzp1[j][i] = vz[j][i]; + /* forward propagation */ + if(sw==0){ + vzp1[j][i] = rjp[j][i]*(sxz_x+syz_y)/DH; /* derivative of velocity */ + } + + /* backward propagation */ + if(sw==1){ + if(VELOCITY==0){ + vzp1[j][i] += vz[j][i]*DT; /* displacement */ + } + else{ + vzp1[j][i] = vz[j][i]; /* velocity */ + } + } vz[j][i] += rjp[j][i]*DT*(sxz_x+syz_y)/(DH); @@ -183,7 +211,20 @@ void update_v_PML_SH(int nx1, int nx2, int ny1, int ny2, int nt, syz_y = syz_y / K_y_half[h1] + psi_syz_y[h1][i]; } - vzp1[j][i] = vz[j][i]; + /* forward propagation */ + if(sw==0){ + vzp1[j][i] = rjp[j][i]*(sxz_x+syz_y)/DH; /* derivative of velocity */ + } + + /* backward propagation */ + if(sw==1){ + if(VELOCITY==0){ + vzp1[j][i] += vz[j][i]*DT; /* displacement */ + } + else{ + vzp1[j][i] = vz[j][i]; /* velocity */ + } + } vz[j][i] += rjp[j][i]*DT*(sxz_x+syz_y)/(DH); @@ -226,7 +267,20 @@ void update_v_PML_SH(int nx1, int nx2, int ny1, int ny2, int nt, syz_y = syz_y / K_y_half[h1] + psi_syz_y[h1][i]; } - vzp1[j][i] = vz[j][i]; + /* forward propagation */ + if(sw==0){ + vzp1[j][i] = rjp[j][i]*(sxz_x+syz_y)/DH; /* derivative of velocity */ + } + + /* backward propagation */ + if(sw==1){ + if(VELOCITY==0){ + vzp1[j][i] += vz[j][i]*DT; /* displacement */ + } + else{ + vzp1[j][i] = vz[j][i]; /* velocity */ + } + } vz[j][i] += rjp[j][i]*DT*(sxz_x+syz_y)/(DH); @@ -269,7 +323,20 @@ void update_v_PML_SH(int nx1, int nx2, int ny1, int ny2, int nt, syz_y = syz_y / K_y_half[h1] + psi_syz_y[h1][i]; } - vzp1[j][i] = vz[j][i]; + /* forward propagation */ + if(sw==0){ + vzp1[j][i] = rjp[j][i]*(sxz_x+syz_y)/DH; /* derivative of velocity */ + } + + /* backward propagation */ + if(sw==1){ + if(VELOCITY==0){ + vzp1[j][i] += vz[j][i]*DT; /* displacement */ + } + else{ + vzp1[j][i] = vz[j][i]; /* velocity */ + } + } vz[j][i] += rjp[j][i]*DT*(sxz_x+syz_y)/(DH); @@ -312,7 +379,20 @@ void update_v_PML_SH(int nx1, int nx2, int ny1, int ny2, int nt, syz_y = syz_y / K_y_half[h1] + psi_syz_y[h1][i]; } - vzp1[j][i] = vz[j][i]; + /* forward propagation */ + if(sw==0){ + vzp1[j][i] = rjp[j][i]*(sxz_x+syz_y)/DH; /* derivative of velocity */ + } + + /* backward propagation */ + if(sw==1){ + if(VELOCITY==0){ + vzp1[j][i] += vz[j][i]*DT; /* displacement */ + } + else{ + vzp1[j][i] = vz[j][i]; /* velocity */ + } + } vz[j][i] += rjp[j][i]*DT*(sxz_x+syz_y)/(DH); diff --git a/src/wolfe_condition.c b/src/wolfe_condition.c index 75ec40d3d279df48c29f759642d1b42e6351e2e3..2d4ed53d9bfb47761e83fe2c1cfcf9b254ae945a 100644 --- a/src/wolfe_condition.c +++ b/src/wolfe_condition.c @@ -21,10 +21,11 @@ * 0: Wolfe Condition fullfilled */ #include "fd.h" -int check_wolfe(float steplength, float misfit_old, float misfit_new, float ** grad_old_vs, float ** grad_new_vs, float ** update_vs, float ** grad_old_rho, float ** grad_new_rho, float ** update_rho, float ** grad_old_vp, float ** grad_new_vp, float ** update_vp, float c1, float c2, int NPAR_LBFGS){ +int check_wolfe(float steplength, float misfit_old, float misfit_new, float ** grad_old_vs, float ** grad_new_vs, float ** update_vs, float ** grad_old_rho, float ** grad_new_rho, float ** update_rho, float ** grad_old_vp, float ** grad_new_vp, float ** update_vp, + float **grad_old_vshor, float **grad_new_vshor, float **update_vshor,float c1, float c2, int NPAR_LBFGS){ /* global */ - extern int NX,NY,MYID; + extern int NX,NY,MYID,VTI,WAVETYPE; extern FILE *FP; extern int ACOUSTIC; @@ -51,11 +52,20 @@ int check_wolfe(float steplength, float misfit_old, float misfit_new, float ** g } if(NPAR_LBFGS>2) { - temp=matrix_product(grad_old_vp, update_vp); - grad_dot_p_old+=temp; - temp2=global_maximum(grad_old_vp); - if(fabs(temp2)>0) grad_dot_p_old_norm+=temp/temp2; - grad_dot_p_new+=matrix_product(grad_new_vp, update_vp); + if(WAVETYPE!=2){ + temp=matrix_product(grad_old_vp, update_vp); + grad_dot_p_old+=temp; + temp2=global_maximum(grad_old_vp); + if(fabs(temp2)>0) grad_dot_p_old_norm+=temp/temp2; + grad_dot_p_new+=matrix_product(grad_new_vp, update_vp); + } + else if (VTI){ + temp=matrix_product(grad_old_vshor, update_vshor); + grad_dot_p_old+=temp; + temp2=global_maximum(grad_old_vshor); + if(fabs(temp2)>0) grad_dot_p_old_norm+=temp/temp2; + grad_dot_p_new+=matrix_product(grad_new_vshor, update_vshor); + } } fprintf(FP,"\n\n ------- Wolfe condition -------- "); diff --git a/src/write_par.c b/src/write_par.c index 3bce45666abbb13b993b86002776a4c50a6e36c7..a935161e76fb1a9d6e833c110502b1b767e9f64d 100644 --- a/src/write_par.c +++ b/src/write_par.c @@ -27,7 +27,7 @@ void write_par(FILE *fp){ /* declaration of extern variables */ extern int NX, NY, NT, SOURCE_SHAPE, SOURCE_TYPE, FDORDER, MAXRELERROR; - extern int SNAP, SNAP_FORMAT, ACOUSTIC, L, SRCREC, TAPER; + extern int SNAP, SNAP_FORMAT, ACOUSTIC, VTI, L, SRCREC, TAPER; extern float DH, TIME, DT, TS, *FL, TAU, VPPML, PLANE_WAVE_DEPTH, PHI, FPML, npower, k_max_PML, F_REF; extern float REC_ARRAY_DEPTH, REC_ARRAY_DIST; extern float XREC1, XREC2, YREC1, YREC2; @@ -249,6 +249,12 @@ void write_par(FILE *fp){ for (l=1;l<=L;l++) fprintf(fp,"\t %1i. relaxation frequencies: %s.f%1i\n",l,MFILE,l); } + if (VTI){ + fprintf(fp,"\n"); + fprintf(fp," ------------------------- ANISOTROPY --------------------\n"); + fprintf(fp," Vertically transversely isotropic model is used.\n"); + } + if(L){ fprintf(fp,"\n"); fprintf(fp," ------------------------- Q-APROXIMATION --------------------\n");