📄 sufdmod2.c
字号:
******************************************************************************Notes:The amplitude of the Ricker wavelet at a frequency of 2.5*fpeak is approximately 4 percent of that at the dominant frequency fpeak.The Ricker wavelet effectively begins at time t = -1.0/fpeak. Therefore,for practical purposes, a causal wavelet may be obtained by a time delayof 1.0/fpeak.The Ricker wavelet has the shape of the second derivative of a Gaussian.******************************************************************************Author: Dave Hale, Colorado School of Mines, 04/29/90******************************************************************************/{ float x,xx; x = PI*fpeak*t; xx = x*x; /* return (-6.0+24.0*xx-8.0*xx*xx)*exp(-xx); */ /* return PI*fpeak*(4.0*xx*x-6.0*x)*exp(-xx); */ return exp(-xx)*(1.0-2.0*xx);}/* 2D finite differencing subroutine *//* functions declared and used internally */static void star1 (int nx, float dx, int nz, float dz, float dt, float **dvv, float **od, float **s, float **pm, float **p, float **pp);static void star2 (int nx, float dx, int nz, float dz, float dt, float **dvv, float **od, float **s, float **pm, float **p, float **pp);static void star3 (int nx, float dx, int nz, float dz, float dt, float **dvv, float **od, float **s, float **pm, float **p, float **pp);static void star4 (int nx, float dx, int nz, float dz, float dt, float **dvv, float **od, float **s, float **pm, float **p, float **pp);static void absorb (int nx, float dx, int nz, float dz, float dt, float **dvv, float **od, float **pm, float **p, float **pp, int *abs);void tstep2 (int nx, float dx, int nz, float dz, float dt, float **dvv, float **od, float **s, float **pm, float **p, float **pp, int *abs)/*****************************************************************************One time step of FD solution (2nd order in space) to acoustic wave equation******************************************************************************Input:nx number of x samplesdx x sampling intervalnz number of z samplesdz z sampling intervaldt time stepdvv array[nx][nz] of density*velocity^2od array[nx][nz] of 1/density (NULL for constant density=1.0)s array[nx][nz] of source pressure at time t+dtpm array[nx][nz] of pressure at time t-dtp array[nx][nz] of pressure at time tOutput:pp array[nx][nz] of pressure at time t+dt******************************************************************************Notes:This function is optimized for special cases of constant density=1 and/orequal spatial sampling intervals dx=dz. The slowest case is variabledensity and dx!=dz. The fastest case is density=1.0 (od==NULL) and dx==dz.******************************************************************************Author: Dave Hale, Colorado School of Mines, 03/13/90******************************************************************************/{ /* convolve with finite-difference star (special cases for speed) */ if (od!=NULL && dx!=dz) { star1(nx,dx,nz,dz,dt,dvv,od,s,pm,p,pp); } else if (od!=NULL && dx==dz) { star2(nx,dx,nz,dz,dt,dvv,od,s,pm,p,pp); } else if (od==NULL && dx!=dz) { star3(nx,dx,nz,dz,dt,dvv,od,s,pm,p,pp); } else { star4(nx,dx,nz,dz,dt,dvv,od,s,pm,p,pp); } /* absorb along boundaries */ absorb(nx,dx,nz,dz,dt,dvv,od,pm,p,pp,abs);}/* convolve with finite-difference star for variable density and dx!=dz */static void star1 (int nx, float dx, int nz, float dz, float dt, float **dvv, float **od, float **s, float **pm, float **p, float **pp){ int ix,iz; float xscale1,zscale1,xscale2,zscale2; /* determine constants */ xscale1 = (dt*dt)/(dx*dx); zscale1 = (dt*dt)/(dz*dz); xscale2 = 0.25*xscale1; zscale2 = 0.25*zscale1; /* do the finite-difference star */ for (ix=1; ix<nx-1; ++ix) { for (iz=1; iz<nz-1; ++iz) { pp[ix][iz] = 2.0*p[ix][iz]-pm[ix][iz] + dvv[ix][iz]*( od[ix][iz]*( xscale1*( p[ix+1][iz]+ p[ix-1][iz]- 2.0*p[ix][iz] ) + zscale1*( p[ix][iz+1]+ p[ix][iz-1]- 2.0*p[ix][iz] ) ) + ( xscale2*( (od[ix+1][iz]- od[ix-1][iz]) * (p[ix+1][iz]- p[ix-1][iz]) ) + zscale2*( (od[ix][iz+1]- od[ix][iz-1])* (p[ix][iz+1]- p[ix][iz-1]) ) ) ) + s[ix][iz]; } }}/* convolve with finite-difference star for variable density and dx==dz */static void star2 (int nx, float dx, int nz, float dz, float dt, float **dvv, float **od, float **s, float **pm, float **p, float **pp){ int ix,iz; float scale1,scale2; if ( dx != dz ) fprintf(stderr,"ASSERT FAILED: dx != dz in star2\n"); /* determine constants */ scale1 = (dt*dt)/(dx*dx); scale2 = 0.25*scale1; /* do the finite-difference star */ for (ix=1; ix<nx-1; ++ix) { for (iz=1; iz<nz-1; ++iz) { pp[ix][iz] = 2.0*p[ix][iz]-pm[ix][iz] + dvv[ix][iz]*( od[ix][iz]*( scale1*( p[ix+1][iz]+ p[ix-1][iz]+ p[ix][iz+1]+ p[ix][iz-1]- 4.0*p[ix][iz] ) ) + ( scale2*( (od[ix+1][iz]- od[ix-1][iz]) * (p[ix+1][iz]- p[ix-1][iz]) + (od[ix][iz+1]- od[ix][iz-1]) * (p[ix][iz+1]- p[ix][iz-1]) ) ) ) + s[ix][iz]; } }}/* convolve with finite-difference star for density==1.0 and dx!=dz */static void star3 (int nx, float dx, int nz, float dz, float dt, float **dvv, float **od, float **s, float **pm, float **p, float **pp){ int ix,iz; float xscale,zscale; if ( od != ((float **) NULL) ) fprintf(stderr,"ASSERT FAILED: od != NULL in star3\n"); /* determine constants */ xscale = (dt*dt)/(dx*dx); zscale = (dt*dt)/(dz*dz); /* do the finite-difference star */ for (ix=1; ix<nx-1; ++ix) { for (iz=1; iz<nz-1; ++iz) { pp[ix][iz] = 2.0*p[ix][iz]-pm[ix][iz] + dvv[ix][iz]*( xscale*( p[ix+1][iz]+ p[ix-1][iz]- 2.0*p[ix][iz] ) + zscale*( p[ix][iz+1]+ p[ix][iz-1]- 2.0*p[ix][iz] ) ) + s[ix][iz]; } }}/* convolve with finite-difference star for density==1.0 and dx==dz */static void star4 (int nx, float dx, int nz, float dz, float dt, float **dvv, float **od, float **s, float **pm, float **p, float **pp){ int ix,iz; float scale; /* determine constants */ if ( od != ((float **) NULL) ) fprintf(stderr,"ASSERT FAILED: od != NULL in star4\n"); if ( dz != dx ) fprintf(stderr,"ASSERT FAILED: dz != dx in star4\n"); scale = (dt*dt)/(dx*dz); /* do the finite-difference star */ for (ix=1; ix<nx-1; ++ix) { for (iz=1; iz<nz-1; ++iz) { pp[ix][iz] = 2.0*p[ix][iz]-pm[ix][iz] + scale*dvv[ix][iz]*( p[ix+1][iz]+ p[ix-1][iz]+ p[ix][iz+1]+ p[ix][iz-1]- 4.0*p[ix][iz] ) + s[ix][iz]; } }}static void absorb (int nx, float dx, int nz, float dz, float dt, float **dvv, float **od, float **pm, float **p, float **pp, int *abs){ int ix,iz; float ov,ovs,cosa,beta,gamma,dpdx,dpdz,dpdt,dpdxs,dpdzs,dpdts; /* solve for upper boundary */ iz = 1; for (ix=0; ix<nx; ++ix) { if (abs[0]!=0) { if (od!=NULL) ovs = 1.0/(od[ix][iz]*dvv[ix][iz]); else ovs = 1.0/dvv[ix][iz]; ov = sqrt(ovs); if (ix==0) dpdx = (p[1][iz]-p[0][iz])/dx; else if (ix==nx-1) dpdx = (p[nx-1][iz]-p[nx-2][iz])/dx; else dpdx = (p[ix+1][iz]-p[ix-1][iz])/(2.0*dx); dpdt = (pp[ix][iz]-pm[ix][iz])/(2.0*dt); dpdxs = dpdx*dpdx; dpdts = dpdt*dpdt; if (ovs*dpdts>dpdxs) cosa = sqrt(1.0-dpdxs/(ovs*dpdts)); else cosa = 0.0; beta = ov*dz/dt*cosa; gamma = (1.0-beta)/(1.0+beta); pp[ix][iz-1] = gamma*(pp[ix][iz]-p[ix][iz-1])+p[ix][iz]; } else { pp[ix][iz-1] = 0.0; } } /* extrapolate along left boundary */ ix = 1; for (iz=0; iz<nz; ++iz) { if (abs[1]!=0) { if (od!=NULL) ovs = 1.0/(od[ix][iz]*dvv[ix][iz]); else ovs = 1.0/dvv[ix][iz]; ov = sqrt(ovs); if (iz==0) dpdz = (p[ix][1]-p[ix][0])/dz; else if (iz==nz-1) dpdz = (p[ix][nz-1]-p[ix][nz-2])/dz; else dpdz = (p[ix][iz+1]-p[ix][iz-1])/(2.0*dz); dpdt = (pp[ix][iz]-pm[ix][iz])/(2.0*dt); dpdzs = dpdz*dpdz; dpdts = dpdt*dpdt; if (ovs*dpdts>dpdzs) cosa = sqrt(1.0-dpdzs/(ovs*dpdts)); else cosa = 0.0; beta = ov*dx/dt*cosa; gamma = (1.0-beta)/(1.0+beta); pp[ix-1][iz] = gamma*(pp[ix][iz]-p[ix-1][iz])+p[ix][iz]; } else { pp[ix-1][iz] = 0.0; } } /* extrapolate along lower boundary */ iz = nz-2; for (ix=0; ix<nx; ++ix) { if (abs[2]!=0) { if (od!=NULL) ovs = 1.0/(od[ix][iz]*dvv[ix][iz]); else ovs = 1.0/dvv[ix][iz]; ov = sqrt(ovs); if (ix==0) dpdx = (p[1][iz]-p[0][iz])/dx; else if (ix==nx-1) dpdx = (p[nx-1][iz]-p[nx-2][iz])/dx; else dpdx = (p[ix+1][iz]-p[ix-1][iz])/(2.0*dx); dpdt = (pp[ix][iz]-pm[ix][iz])/(2.0*dt); dpdxs = dpdx*dpdx; dpdts = dpdt*dpdt; if (ovs*dpdts>dpdxs) cosa = sqrt(1.0-dpdxs/(ovs*dpdts)); else cosa = 0.0; beta = ov*dz/dt*cosa; gamma = (1.0-beta)/(1.0+beta); pp[ix][iz+1] = gamma*(pp[ix][iz]-p[ix][iz+1])+p[ix][iz]; } else { pp[ix][iz+1] = 0.0; } } /* extrapolate along right boundary */ ix = nx-2; for (iz=0; iz<nz; ++iz) { if (abs[3]!=0) { if (od!=NULL) ovs = 1.0/(od[ix][iz]*dvv[ix][iz]); else ovs = 1.0/dvv[ix][iz]; ov = sqrt(ovs); if (iz==0) dpdz = (p[ix][1]-p[ix][0])/dz; else if (iz==nz-1) dpdz = (p[ix][nz-1]-p[ix][nz-2])/dz; else dpdz = (p[ix][iz+1]-p[ix][iz-1])/(2.0*dz); dpdt = (pp[ix][iz]-pm[ix][iz])/(2.0*dt); dpdzs = dpdz*dpdz; dpdts = dpdt*dpdt; if (ovs*dpdts>dpdzs) cosa = sqrt(1.0-dpdzs/(ovs*dpdts)); else cosa = 0.0; beta = ov*dx/dt*cosa; gamma = (1.0-beta)/(1.0+beta); pp[ix+1][iz] =gamma*(pp[ix][iz]-p[ix+1][iz])+p[ix][iz]; } else { pp[ix+1][iz] = 0.0; } }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -