📄 suinvvxzco.c
字号:
/* calculate velocities at shot and receiver */ temp = (xs-fx)/dx; ixd = temp; temp = temp-ixd; vs0 = (1-temp)*vold[ixd][0]+temp*vold[ixd+1][0]; temp = (xg-fx)/dx; ixd = temp; temp = temp-ixd; vg0 = (1-temp)*vold[ixd][0]+temp*vold[ixd+1][0]; /* calculate amplitude */ for(ix=0; ix<nx1; ++ix){ amp1[ix][nz0] = 0; for(iz=nz0+1; iz<nz; ++iz){ /* check operator aliasing */ if(ABS(sin(bas[ix][iz])/vs0+sin(bag[ix][iz])/vg0) >=smax) amp1[ix][iz] = 0.; /* dip filter for imaging */ else if(cos((as[ix][iz]+ag[ix][iz])*0.5)<cosa) amp1[ix][iz] = 0.; else { temp = sqrt(vs0*sgg[ix][iz]/(vg0*sgs[ix][iz])); amp1[ix][iz] = (cos(bas[ix][iz])*temp/vs0 +cos(bag[ix][iz])/(temp*vg0)) *ABS(cos((as[ix][iz]-ag[ix][iz])*0.5)); /* 2.5-D amplitude correction */ if(ls==0) amp1[ix][iz] *= sqrt(sgs[ix][iz]+sgg[ix][iz]); } } } /* interpolate quantities between two midpoints */ xm -= nxd1*dxm; for(i=1; i<=nxd1; ++i){ xm += dxm; xs = xm-0.5*offs; xg = xs+offs; fx1 = xm-nxb*dx; ex1 = MIN(ex+(nxd1-1)*dxm,xm+nxb*dx); nx1 = 1+NINT((ex1-fx1)/dx); temp = nxd1-i; temp1 = 1.0/(nxd1-i+1); for(ix=0;ix<nx1;++ix) for(iz=nz0;iz<nz;++iz){ ts[ix][iz] = (temp*ts[ix][iz] +ts1[ix][iz])*temp1; tg[ix][iz] = (temp*tg[ix][iz] +tg1[ix][iz])*temp1; amp[ix][iz] = (temp*amp[ix][iz] +amp1[ix][iz])*temp1; } /* set the right boundary for output traces */ ex1 = MIN(ex,xm+nxb*dx); /* loop over output points */ for (ixo=0,xo=fxo; ixo<nxo; ++ixo,xo+=dxo) for (izo=1,zo=fzo+dzo; izo<nzo; ++izo,zo+=dzo){ /* check range of output */ if(xo-fx1<0 || xo-ex1>=0 || zo-ez>=0) continue; /* determine sample indices */ xi = (xo-fx1)*odx; ix = xi; zi = zo*odz; iz = zi; /* bilinear interpolation */ sx = xi-ix; sz = zi-iz; tsd = (1.0-sz)*((1.0-sx)*ts[ix][iz] + sx*ts[ix+1][iz]) + sz*((1.0-sx)*ts[ix][iz+1] + sx*ts[ix+1][iz+1]); tgd = (1.0-sz)*((1.0-sx)*tg[ix][iz] + sx*tg[ix+1][iz]) + sz*((1.0-sx)*tg[ix][iz+1] + sx*tg[ix+1][iz+1]); samp = (tsd+tgd)*odt; nsamp = samp; if (nsamp>nt-2) continue; samp = samp-nsamp; ampd = (1.0-sz)*((1.0-sx)*amp[ix][iz] +sx*amp[ix+1][iz]) +sz*((1.0-sx)*amp[ix][iz+1] +sx*amp[ix+1][iz+1]); outtrace[ixo][izo] += ampd*(samp*tr.data[nsamp+1] +(1.0-samp)*tr.data[nsamp]); } /* read input trace */ if(ixm-nxd1+i<nxm-1) gettr(&tr); } } /* recount the skipping number for the last midpoint */ if(ixm<nxm-1 && ixm>nxm-1-nxd1) nxd1 = nxm-1-ixm; if(verbose) fprintf(stderr,"\tfinish midpoint %i\n",ixm+1); if(ierr) break; } /* write trace */ temp = 4/sqrt(PI)*dxm; for (ixo=0; ixo<nxo; ++ixo){ /* scale output traces */ for(izo=0; izo<nzo; ++izo) outtrace[ixo][izo] *= temp; /* make headers for output traces */ tro.offset = offs; tro.tracl = tro.tracr = 1+ixo; tro.ns = nzo; tro.d1 = dzo; tro.ns = nzo; tro.f1 = fzo; tro.f2 = fxo; tro.d2 = dxo; tro.cdp = ixo; tro.trid = 200; /* copy migrated data to output trace */ memcpy((void *) tro.data, (const void *) outtrace[ixo], nzo*sizeof(float)); puttr(&tro); } free2float(vold); free2float(ts); free2float(bas); free2float(sgs); free2float(as); free2float(v); free2float(tg); free2float(bag); free2float(sgg); free2float(ag); free2float(amp); if(pert) { free2float(vp); free2float(vpold); } if(nxd>1) { free2float(ts1); free2float(tg1); free2float(amp1); } return(CWP_Exit());}void delta_t (int na, float da, float r, float dr, float uc[], float wc[], float sc[], float bc[], float un[], float wn[], float sn[], float bn[])/*****************************************************************************difference equation extrapolation of "delta t" 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 run array[na] of dt/dr at next rwc array[na] of dt/da at current rwn array[na] of dt/da at next rsc array[na] of dt/dv at current rOutput:sn array[na] of dt/dv at next r ******************************************************************************This function implements the Crank-Nicolson finite-difference method withboundary conditions sn[1]=sn[0] and sn[na-1]=sn[na-2]. ******************************************************************************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.0*dr); e[i] = (wn[i+1]/(r1*r1)+wc[i+1]/(r*r))/(8.0*da); b[i] = (bc[i+1]+bn[i+1])*0.5-(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);}/* functions defined and used internally */void eiktam_pert (float xs, float zs, int nz, float dz, float fz, int nx, float dx, float fx, float **vel, float **vel_p, int pert, float **time, float **angle, float **sig, float **bet)/*****************************************************************************Compute traveltimes t(x,z) and propagation angle a(x,z) via eikonal equation,and 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 velocitiesvel_p array[nx][nz] containing velocity perturbationsOutput:time array[nx][nz] containing first-arrival timesangle array[nx][nz] containing propagation anglessig array[nx][nz] containing sigmasbet array[nx][nz] containing betas******************************************************************************Notes:The actual computation of times and sigmas is done in polar coordinates,with bilinear interpolation used to map to/from rectangular coordinates.This version includes a velocity perturbation.******************************************************************************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,**time_p; /* 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 = 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 = PI/2.0; } else if (fx<0.0 && fz==0.0) { fa = -PI/2.0; ea = PI/2.0; } else if (fx==0.0 && fz<0.0) { fa = 0.0; ea = PI; } else { fa = -PI; ea = 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); time_p = 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.0/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; } } 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]); if(ierr) { x_err = r_err*sin(ia_err*da+fa); z_err = r_err*cos(ia_err*da+fa); return; } } /* convert times from polar to rectangular coordinates */ polartorect(na,da,fa,nr,dr,fr,tp,nz,dz,fz,nx,dx,fx,time); /* 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] = a+asin(wp[ir][ia]/(sp[ir][ia]*r)); } polartorect(na,da,fa,nr,dr,fr,ap,nz,dz,fz,nx,dx,fx,angle); /* compute 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 difference equation for remaining 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); /* compute 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 difference equation for remaining 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); if(pert){ /* compute time perturbation by Crank-Nicolson scheme */ recttopolar(nz,dz,fz,nx,dx,fx,vel_p,na,da,fa,nr,dr,fr,sp); /* initial values */ for (ir=0,r=0; ir<2; ++ir,r+=dr) for (ia=0; ia<na; ++ia) tp[ir][ia] = r/ss*sp[ir][ia]; /* solve difference equation for remaining perturbed time */ for (ir=1,r=dr; ir<nr-1; ++ir,r+=dr) delta_t(na,da,r,dr,up[ir],wp[ir],tp[ir],sp[ir], up[ir+1],wp[ir+1],tp[ir+1],sp[ir+1]); polartorect(na,da,fa,nr,dr,fr,tp,nz,dz,fz,nx,dx,fx,time_p); /* sum the total time */ for (ix=0; ix<nx; ++ix) for (iz=0; iz<nz; ++iz) time[ix][iz] += time_p[ix][iz]; } /* free space */ free2float(s); free2float(time_p); free2float(sp); free2float(tp); free2float(up); free2float(wp); free2float(ap);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -