📄 rayt2dan.c
字号:
dxdn = (da1111dn*pxt*g11+(da1133dn+da1313dn)*pzt*g13+ da3313dn*pzt*g33+da1113dn*(pzt*g11+2*pxt*g13)+ da1313dn*g33*pxt); dzdn = (da3333dn*pzt*g33+(da1133dn+da1313dn)*pxt*g13+ da1113dn*pxt*g11+da3313dn*(pxt*g33+2*pzt*g13)+ da1313dn*g11*pzt); ddcdpn = dxdn*c-dzdn*s-.5*dxt*sxfactor*cc+ .5*(dxt*szfactor+dzt*sxfactor)*s*c-.5*dzt*szfactor*ss +ddxdn*c-ddzdn*s; snfactor = dda1111dndn*px2*g11+dda3333dndn*pz2*g33+ 2*(dda1133dndn+dda1313dndn)*pxz*g13+ dda1313dndn*(px2*g33+pz2*g11)+ 2*dda3313dndn*(pz2*g13+pxz*g33)+ 2*dda1113dndn*(pxz*g11+px2*g13); ddcdnn = 0.5*snfactor-.25*sxfactor*sxfactor*cc+ .5*sxfactor*szfactor*s*c-.25*szfactor*szfactor*ss +.5*dsnfactordn; dp1t = -ddcdnn*q1t-ddcdpn*p1t; dq1t = ddcdqq*p1t+ddcdpn*q1t; dp2t = -ddcdnn*q2t-ddcdpn*p2t; dq2t = ddcdqq*p2t+ddcdpn*q2t; dxx = hsixth*(dx+dxt+2.0*dxm); dzz = hsixth*(dz+dzt+2.0*dzm); x += dxx; z += dzz; px += hsixth*(dpx+dpxt+2.0*dpxm); pz += hsixth*(dpz+dpzt+2.0*dpzm); p1 += hsixth*(dp1+dp1t+2.0*dp1m); q1 += hsixth*(dq1+dq1t+2.0*dq1m); p2 += hsixth*(dp2+dp2t+2.0*dp2m); q2 += hsixth*(dq2+dq2t+2.0*dq2m); vp = 1/sqrt(px*px+pz*pz); s = px*vp; c = pz*vp; ss = s*s; cc = c*c; vel2Interp(a11112,x,z,&a1111,&da1111dx,&da1111dz,&dda1111dxdx, &dda1111dxdz,&dda1111dzdz); da1111dn = da1111dx*c-da1111dz*s; dda1111dndn = dda1111dxdx*cc-2.0*dda1111dxdz*s*c+dda1111dzdz*ss; vel2Interp(a33332,x,z,&a3333,&da3333dx,&da3333dz,&dda3333dxdx, &dda3333dxdz,&dda3333dzdz); da3333dn = da3333dx*c-da3333dz*s; dda3333dndn = dda3333dxdx*cc-2.0*dda3333dxdz*s*c+dda3333dzdz*ss; vel2Interp(a11332,x,z,&a1133,&da1133dx,&da1133dz,&dda1133dxdx, &dda1133dxdz,&dda1133dzdz); da1133dn = da1133dx*c-da1133dz*s; dda1133dndn = dda1133dxdx*cc-2.0*dda1133dxdz*s*c+dda1133dzdz*ss; vel2Interp(a13132,x,z,&a1313,&da1313dx,&da1313dz,&dda1313dxdx, &dda1313dxdz,&dda1313dzdz); da1313dn = da1313dx*c-da1313dz*s; dda1313dndn = dda1313dxdx*cc-2.0*dda1313dxdz*s*c+dda1313dzdz*ss; vel2Interp(a11132,x,z,&a1113,&da1113dx,&da1113dz,&dda1113dxdx, &dda1113dxdz,&dda1113dzdz); da1113dn = da1113dx*c-da1113dz*s; dda1113dndn = dda1113dxdx*cc-2.0*dda1113dxdz*s*c+dda1113dzdz*ss; vel2Interp(a33132,x,z,&a3313,&da3313dx,&da3313dz,&dda3313dxdx, &dda3313dxdz,&dda3313dzdz); da3313dn = da3313dx*c-da3313dz*s; dda3313dndn = dda3313dxdx*cc-2.0*dda3313dxdz*s*c+dda3313dzdz*ss; /* update time */ t += dt; /* update kmah index */ if ((q2<=0.0 && q2old>0.0) || (q2>=0.0 && q2old<0.0)) kmah++; /* save ray parameters */ rs[it].t = t; rs[it].x = x; rs[it].z = z; rs[it].c = c; rs[it].s = s; rs[it].q1 = q1; rs[it].p1 = p1; rs[it].q2 = q2; rs[it].p2 = p2; rs[it].kmah = kmah; rs[it].v = vp; rs[it].dvdx = .5*da3333dx*vp/a3333; rs[it].dvdz = .5*da3333dz*vp/a3333; /*printf("%d %f %f %f %f %f %f %f \n",it,t,x,z,fx,fz,lx,lz);*/ } /* free velocity interpolator */ vel2Free(a11112); vel2Free(a33332); vel2Free(a11332); vel2Free(a13132); vel2Free(a11132); vel2Free(a33132); /* return ray */ ray->nrs = it; ray->rs = rs; ray->nc = 0; ray->c = NULL; return ray;}void freeRay (Ray *ray)/*****************************************************************************Free a ray.******************************************************************************Input:ray ray to be freed*****************************************************************************/{ if (ray->c!=NULL) free1((void*)ray->c); free1((void*)ray->rs); free1((void*)ray);}/*****************************************************************************Functions to support interpolation of velocity and its derivatives.******************************************************************************Functions:vel2Alloc allocate and initialize an interpolator for v(x,z)vel2Interp interpolate v(x,z) and its derivatives******************************************************************************Notes:Interpolation is performed by piecewise cubic Hermite polynomials,so that velocity and first derivatives are continuous. Therefore,velocity v, first derivatives dv/dx and dv/dz, and the mixedderivative ddv/dxdz are continuous. However, second derivativesddv/dxdx and ddv/dzdz are discontinuous.*****************************************************************************Technical Reference: Hale, D., 1992, Migration by the Kirchhoff, slant stack, and Gaussian beam methods: Colorado School of Mines.***************************************************************************** Credits: CWP: Dave Hale*****************************************************************************//* number of pre-computed, tabulated interpolators */#define NTABLE 101/* length of each interpolator in table (4 for piecewise cubic) */#define LTABLE 4/* table of pre-computed interpolators, for 0th, 1st, and 2nd derivatives */static float tbl[3][NTABLE][LTABLE];/* constants */static int ix=1-LTABLE/2-LTABLE,iz=1-LTABLE/2-LTABLE;static float ltable=LTABLE,ntblm1=NTABLE-1;/* indices for 0th, 1st, and 2nd derivatives */static int kx[6]={0,1,0,2,1,0};static int kz[6]={0,0,1,0,1,2};/* function to build interpolator tables; sets tabled=1 when built */static void buildTables (void);static int tabled=0;/* interpolator for velocity function v(x,z) of two variables */typedef struct Vel2Struct { int nx; /* number of x samples */ int nz; /* number of z samples */ int nxm; /* number of x samples minus LTABLE */ int nzm; /* number of x samples minus LTABLE */ float xs,xb,zs,zb,sx[3],sz[3],**vu;} Vel2;void* vel2Alloc (int nx, float dx, float fx, int nz, float dz, float fz, float **v)/*****************************************************************************Allocate and initialize an interpolator for v(x,z) and its derivatives.******************************************************************************Input:nx number of x samplesdx x sampling intervalfx first x samplenz number of z samplesdz z sampling intervalfz first z samplev array[nx][nz] of uniformly sampled v(x,z)*****************************************************************************Returned: pointer to interpolator*****************************************************************************/{ Vel2 *vel2; /* allocate space */ vel2 = (Vel2*)alloc1(1,sizeof(Vel2)); /* set state variables used for interpolation */ vel2->nx = nx; vel2->nxm = nx-LTABLE; vel2->xs = 1.0/dx; vel2->xb = ltable-fx*vel2->xs; vel2->sx[0] = 1.0; vel2->sx[1] = vel2->xs; vel2->sx[2] = vel2->xs*vel2->xs; vel2->nz = nz; vel2->nzm = nz-LTABLE; vel2->zs = 1.0/dz; vel2->zb = ltable-fz*vel2->zs; vel2->sz[0] = 1.0; vel2->sz[1] = vel2->zs; vel2->sz[2] = vel2->zs*vel2->zs; vel2->vu = v; /* if necessary, build interpolator coefficient tables */ if (!tabled) buildTables(); return vel2;}void vel2Free (void *vel2)/*****************************************************************************Free an interpolator for v(x,z) and its derivatives.******************************************************************************Input:vel2 pointer to interpolator as returned by vel2Alloc()*****************************************************************************/{ free1(vel2);}void vel2Interp (void *vel2, float x, float z, float *v, float *vx, float *vz, float *vxx, float *vxz, float *vzz)/*****************************************************************************Interpolation of a velocity function v(x,z) and its derivatives.******************************************************************************Input:vel2 pointer to interpolator as returned by vel2Alloc()x x coordinate at which to interpolate v(x,z) and derivativesz z coordinate at which to interpolate v(x,z) and derivatives*****************************************************************************Output:v v(x,z)vx dv/dxvz dv/dzvxx ddv/dxdxvxz ddv/dxdzvzz ddv/dzdz*****************************************************************************/{ Vel2 *v2=vel2; int nx=v2->nx,nz=v2->nz,nxm=v2->nxm,nzm=v2->nzm; float xs=v2->xs,xb=v2->xb,zs=v2->zs,zb=v2->zb, *sx=v2->sx,*sz=v2->sz,**vu=v2->vu; int i,jx,lx,mx,jz,lz,mz,jmx,jmz,mmx,mmz; float ax,bx,*px,az,bz,*pz,sum,vd[6]; /* determine offsets into vu and interpolation coefficients */ ax = xb+x*xs; jx = (int)ax; bx = ax-jx; lx = (bx>=0.0)?bx*ntblm1+0.5:(bx+1.0)*ntblm1-0.5; lx *= LTABLE; mx = ix+jx; az = zb+z*zs; jz = (int)az; bz = az-jz; lz = (bz>=0.0)?bz*ntblm1+0.5:(bz+1.0)*ntblm1-0.5; lz *= LTABLE; mz = iz+jz; /* if totally within input array, use fast method */ if (mx>=0 && mx<=nxm && mz>=0 && mz<=nzm) { for (i=0; i<6; ++i) { px = &(tbl[kx[i]][0][0])+lx; pz = &(tbl[kz[i]][0][0])+lz; vd[i] = sx[kx[i]]*sz[kz[i]]*( vu[mx][mz]*px[0]*pz[0]+ vu[mx][mz+1]*px[0]*pz[1]+ vu[mx][mz+2]*px[0]*pz[2]+ vu[mx][mz+3]*px[0]*pz[3]+ vu[mx+1][mz]*px[1]*pz[0]+ vu[mx+1][mz+1]*px[1]*pz[1]+ vu[mx+1][mz+2]*px[1]*pz[2]+ vu[mx+1][mz+3]*px[1]*pz[3]+ vu[mx+2][mz]*px[2]*pz[0]+ vu[mx+2][mz+1]*px[2]*pz[1]+ vu[mx+2][mz+2]*px[2]*pz[2]+ vu[mx+2][mz+3]*px[2]*pz[3]+ vu[mx+3][mz]*px[3]*pz[0]+ vu[mx+3][mz+1]*px[3]*pz[1]+ vu[mx+3][mz+2]*px[3]*pz[2]+ vu[mx+3][mz+3]*px[3]*pz[3]); } /* else handle end effects with constant extrapolation */ } else { for (i=0; i<6; ++i) { px = &(tbl[kx[i]][0][0])+lx; pz = &(tbl[kz[i]][0][0])+lz; for (jx=0,jmx=mx,sum=0.0; jx<4; ++jx,++jmx) { mmx = jmx; if (mmx<0) mmx = 0; else if (mmx>=nx) mmx = nx-1; for (jz=0,jmz=mz; jz<4; ++jz,++jmz) { mmz = jmz; if (mmz<0) mmz = 0; else if (mmz>=nz) mmz = nz-1; sum += vu[mmx][mmz]*px[jx]*pz[jz]; } } vd[i] = sx[kx[i]]*sz[kz[i]]*sum; } } /* set output variables */ *v = vd[0]; *vx = vd[1]; *vz = vd[2]; *vxx = vd[3]; *vxz = vd[4]; *vzz = vd[5];}/* hermite polynomials */static float h00 (float x) {return 2.0*x*x*x-3.0*x*x+1.0;}static float h01 (float x) {return 6.0*x*x-6.0*x;}static float h02 (float x) {return 12.0*x-6.0;}static float h10 (float x) {return -2.0*x*x*x+3.0*x*x;}static float h11 (float x) {return -6.0*x*x+6.0*x;}static float h12 (float x) {return -12.0*x+6.0;}static float k00 (float x) {return x*x*x-2.0*x*x+x;}static float k01 (float x) {return 3.0*x*x-4.0*x+1.0;}static float k02 (float x) {return 6.0*x-4.0;}static float k10 (float x) {return x*x*x-x*x;}static float k11 (float x) {return 3.0*x*x-2.0*x;}static float k12 (float x) {return 6.0*x-2.0;}/* function to build interpolation tables */static void buildTables(void){ int i; float x; /* tabulate interpolator for 0th derivative */ for (i=0; i<NTABLE; ++i) { x = (float)i/(NTABLE-1.0); tbl[0][i][0] = -0.5*k00(x); tbl[0][i][1] = h00(x)-0.5*k10(x); tbl[0][i][2] = h10(x)+0.5*k00(x); tbl[0][i][3] = 0.5*k10(x); tbl[1][i][0] = -0.5*k01(x); tbl[1][i][1] = h01(x)-0.5*k11(x); tbl[1][i][2] = h11(x)+0.5*k01(x); tbl[1][i][3] = 0.5*k11(x); tbl[2][i][0] = -0.5*k02(x); tbl[2][i][1] = h02(x)-0.5*k12(x); tbl[2][i][2] = h12(x)+0.5*k02(x); tbl[2][i][3] = 0.5*k12(x); } /* remember that tables have been built */ tabled = 1;}#ifdef TEST2#include "cwp.h"#define NZ 2#define NX 2#define NXOUT 21#define NZOUT 21main(){ int nx=NX,nz=NZ,nxout=NXOUT,nzout=NZOUT,i,j; float dx=2.0,fx=-1.0,dxout=0.2,fxout=-2.0; float dz=4.0,fz=-2.0,dzout=0.4,fzout=-4.0; float x,z,v,vx,vz,vxx,vxz,vzz,**vu,**vo; void *vel2; vu = alloc2float(nz,nx); vo = alloc2float(nzout,nxout); vu[0][0] = 1.0; vu[1][0] = 2.0; vu[0][1] = 1.0; vu[1][1] = 2.0; vel2 = vel2Alloc(nx,dx,fx,nz,dz,fz,vu); for (i=0; i<nxout; ++i) { x = fxout+i*dxout; for (j=0; j<nzout; ++j) { z = fzout+j*dzout; vel2Interp(vel2,x,z,&v,&vx,&vz,&vxx,&vxz,&vzz); vo[i][j] = vz; } } vel2Free(vel2); fwrite(vo[0],sizeof(float),nxout*nzout,stdout);}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -