📄 par_upweik.c
字号:
float uc[], float wc[], float sc[], float un[], float wn[], float sn[])/*****************************************************************************ray_theoretic_sigma - difference equation extrapolation of "ray_theoretic_sigma" in polar coordinates******************************************************************************Input:na number of a samplesda a sampling intervalr current radial distance rdr radial distance to extrapolateuc array[na] of dt/dr at current rwc array[na] of dt/da at current rsc array[na] of ray_theoretic_sigma at current run array[na] of dt/dr at next rwn array[na] of dt/da at next rOutput:sn array[na] of ray_theoretic_sigma at next r ******************************************************************************This function implements the Crank-Nicolson finite-difference method withboundary conditions dray_theoretic_sigma/da=0.******************************************************************************Author: Zhenyue Liu, Colorado School of Mines, 07/8/92******************************************************************************/{ int i; float r1,*d,*b,*c,*e; /* allocate workspace */ d = alloc1float(na-2); b = alloc1float(na-2); c = alloc1float(na-2); e = alloc1float(na-2); r1 = r+dr; /* Crank-Nicolson */ for (i=0; i<na-2; ++i) { d[i] = (uc[i+1]+un[i+1])/(2.0f*dr); e[i] = (wn[i+1]/(r1*r1)+wc[i+1]/(r*r))/(8.0f*da); b[i] = 1.0f-(sc[i+2]-sc[i])*e[i] +d[i]*sc[i+1]; c[i] = -e[i]; } d[0] += c[0]; d[na-3] += e[na-3]; tripp(na-2,d,e,c,b); for(i=0;i<na-2; ++i) sn[i+1]=b[i]; sn[0] = sn[1]; sn[na-1] = sn[na-2]; /* free workspace */ free1float(d); free1float(c); free1float(e); free1float(b);}void ray_theoretic_beta (int na, float da, float r, float dr, float uc[], float wc[], float bc[], float un[], float wn[], float bn[])/*****************************************************************************ray_theoretic_beta - difference equation extrapolation of "ray_theoretic_beta" in polar coordinates******************************************************************************Input:na number of a samplesda a sampling intervalr current radial distance rdr radial distance to extrapolateuc array[na] of dt/dr at current rwc array[na] of dt/da at current rbc array[na] of ray_theoretic_beta at current run array[na] of dt/dr at next rwn array[na] of dt/da at next rOutput:bn array[na] of ray_theoretic_beta at next r ******************************************************************************Notes: This function implements the Crank-Nicolson finite-difference method, with boundary conditions dray_theoretic_beta/da=1. ******************************************************************************author: Zhenyue Liu, Colorado School of Mines, 07/8/92******************************************************************************/{ int i; float r1,*d,*b,*c,*e; /* allocate workspace */ d = alloc1float(na-2); b = alloc1float(na-2); c = alloc1float(na-2); e = alloc1float(na-2); r1 = r+dr; /* Crank-Nicolson */ for (i=0; i<na-2; ++i) { d[i] = uc[i+1]*r*r+un[i+1]*r1*r1; e[i] = (wn[i+1]+wc[i+1])*dr/(4.0f*da); b[i] = -(bc[i+2]-bc[i])*e[i] +d[i]*bc[i+1]; c[i] = -e[i]; } d[0] += c[0]; d[na-3] += e[na-3]; b[0] += da*c[0]; b[na-3] -= da*e[na-3]; tripp(na-2,d,e,c,b); for(i=0;i<na-2; ++i) bn[i+1]=b[i]; bn[0] = bn[1]-da; bn[na-1] = bn[na-2]+da; /* free workspace */ free1float(d); free1float(c); free1float(e); free1float(b);}/* functions defined and used internally */void eiktam (float xs, float zs, int nz, float dz, float fz, int nx, float dx, float fx, float **vel, float **time, float **angle, float **sig, float **bet)/*****************************************************************************eiktam - Compute traveltimes t(x,z) and propagation angle a(x,z) via eikonal equation, and ray_theoretic_sigma sig(x,z), incident angle bet(x,z) via Crank-Nicolson Method******************************************************************************Input:xs x coordinate of source (must be within x samples)zs z coordinate of source (must be within z samples)nz number of z samplesdz z sampling intervalfz first z samplenx number of x samplesdx x sampling intervalfx first x samplevel array[nx][nz] containing velocitiesOutput:time array[nx][nz] containing first-arrival timesangle array[nx][nz] containing propagation anglessig array[nx][nz] containing ray_theoretic_sigmasbet array[nx][nz] containing ray_theoretic_betas******************************************************************************Notes:The actual computation of times and ray_theoretic_sigmas is done in polar coordinates,with bilinear interpolation used to map to/from rectangular coordinates.******************************************************************************Revisor: Zhenyue Liu, Colorado School of Mines, 7/8/92******************************************************************************/{ int ix,iz,ia,ir,na,nr; float ss,a,r,da,dr,fa,fr,ex,ez,ea,rmax,rmaxs, **s,**sp,**tp,**up,**wp,**ap; /* shift coordinates so source is at (x=0,z=0) */ fx -= xs; fz -= zs; ex = fx+(nx-1)*dx; ez = fz+(nz-1)*dz; /* determine polar coordinate sampling */ rmaxs = fx*fx+fz*fz; rmaxs = MAX(rmaxs,fx*fx+ez*ez); rmaxs = MAX(rmaxs,ex*ex+ez*ez); rmaxs = MAX(rmaxs,ex*ex+fz*fz); rmax = (float)sqrt(rmaxs); dr = MIN(ABS(dx),ABS(dz)); nr = 1+NINT(rmax/dr); dr = rmax/(nr-1); fr = 0.0; if (fx==0.0 && fz==0.0) { fa = 0.0; ea = (float)(PI/2.0); } else if (fx<0.0 && fz==0.0) { fa = (float)(-PI/2.0); ea = (float)(PI/2.0); } else if (fx==0.0 && fz<0.0) { fa = 0.0; ea = (float)PI; } else { fa = (float)(-PI); ea = (float)PI; } da = dr/rmax; na = 1+NINT((ea-fa)/da); da = (ea-fa)/(na-1); if (fa==-PI && ea==PI) na = na-1; /* allocate space */ s = alloc2float(nz,nx); sp = alloc2float(na,nr); tp = alloc2float(na,nr); up = alloc2float(na,nr); wp = alloc2float(na,nr); ap = alloc2float(na,nr); /* compute slownesses */ for (ix=0; ix<nx; ++ix) for (iz=0; iz<nz; ++iz) s[ix][iz] = 1.0f/vel[ix][iz]; /* convert from rectangular to polar coordinates */ recttopolar(nz,dz,fz,nx,dx,fx,s,na,da,fa,nr,dr,fr,sp); /* average the slownesses in source region */ for (ir=0,ss=0.0; ir<2; ++ir) for (ia=0; ia<na; ++ia) ss += sp[ir][ia]; ss /= 2*na; /* compute traveltimes and derivatives in source region */ for (ir=0,r=0; ir<2; ++ir,r+=dr) { for (ia=0; ia<na; ++ia) { up[ir][ia] = ss; wp[ir][ia] = 0.0; tp[ir][ia] = r*ss; } }/* tt=cpusec(); */ /* solve eikonal equation for remaining times and derivatives */ for (ir=1,r=dr; ir<nr-1; ++ir,r+=dr) { eikpex(na,da,r,dr, sp[ir],up[ir],wp[ir],tp[ir], sp[ir+1],up[ir+1],wp[ir+1],tp[ir+1]); } /* convert times from polar to rectangular coordinates */ polartorect(na,da,fa,nr,dr,fr,tp,nz,dz,fz,nx,dx,fx,time);/* fprintf(stderr,"\t CPU time for traveltimes= %f \n",cpusec()-tt); tt=cpusec(); */ /* compute propagation angles in polar and convert */ for (ia=0,a=fa; ia<na; ++ia,a+=da) ap[0][ia] = a; for (ir=1,r=fr+dr; ir<nr; ++ir,r+=dr) for (ia=0,a=fa; ia<na; ++ia,a+=da){ ap[ir][ia] = (float)(a+asin(wp[ir][ia]/(sp[ir][ia]*r))); } polartorect(na,da,fa,nr,dr,fr,ap,nz,dz,fz,nx,dx,fx,angle);/* fprintf(stderr,"\t CPU time for propagation angles= %f\n", cpusec()-tt); tt=cpusec(); */ /* compute ray_theoretic_sigmas for initial values */ for (ir=0,r=0; ir<2; ++ir,r+=dr) for (ia=0; ia<na; ++ia) tp[ir][ia] = r/ss; /* solve diffrence equation for remaining ray_theoretic_sigmas */ for (ir=1,r=dr; ir<nr-1; ++ir,r+=dr) ray_theoretic_sigma(na,da,r,dr,up[ir],wp[ir],tp[ir], up[ir+1],wp[ir+1],tp[ir+1]); polartorect(na,da,fa,nr,dr,fr,tp,nz,dz,fz,nx,dx,fx,sig);/* fprintf(stderr,"\t CPU time for sigmas= %f \n",cpusec()-tt); tt=cpusec(); */ /* compute ray_theoretic_betas for initial values */ for (ir=0; ir<2; ++ir) for (ia=0,a=fa; ia<na; ++ia,a+=da) tp[ir][ia] = a; /* solve diffrence equation for remaining ray_theoretic_betas */ for (ir=1,r=dr; ir<nr-1; ++ir,r+=dr) ray_theoretic_beta(na,da,r,dr,up[ir],wp[ir],tp[ir], up[ir+1],wp[ir+1],tp[ir+1]); polartorect(na,da,fa,nr,dr,fr,tp,nz,dz,fz,nx,dx,fx,bet); /* fprintf(stderr,"\t CPU time for incident angles= %f \n", cpusec()-tt); */ /* free space */ free2float(s); free2float(sp); free2float(tp); free2float(up); free2float(wp); free2float(ap);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -