📄 susynvxzcs.c
字号:
} /* recount the skipping number for the last midpoint */ if(ixg<nxg-1 && ixg>nxg-1-nxd1) nxd1 = nxg-1-ixg; } warn("\t finish shot %f",xs); } free2float(vold); free2float(aold); free2float(told); free2float(sgold); free2float(ts); free2float(as); free2float(sgs); free2float(bas); free2float(v); free2float(tg); free2float(bag); free2float(sgg); free2float(ag); if(pert) { free2float(vp); free2float(vpold); } if(nxd>1) { free2float(sgg1); free2float(tg1); free2float(ag1); } return(CWP_Exit());}static void makeone (float **ts, float **as, float **sgs, float **tg, float **ag, float **sgg, float ex, float ez, float dx, float dz, float fx, float vs0, float vg0, int ls, Wavelet *w, int nr, Reflector *r, int nt, float dt, float ft, float *trace)/*****************************************************************************Make one synthetic seismogram ******************************************************************************Input:**ts array[nx][nz] containing traveltimes from shot**as array[nx][nz] containing propagation angles from shot **sgs array[nx][nz] containing sigmas from shot**tg array[nx][nz] containing traveltimes from receiver**ag array[nx][nz] containing propagation angles from receiver **sgg array[nx][nz] containing sigmas from receivernz number of z samplesdz z sampling intervalnx number of x samplesdx x sampling intervalfx first x sampleex last x sampleez last z samplels =1 for line source amplitudes; =0 for point sourcew wavelet to convolve with tracexs x coordinate of sourcexg x coordinate of receiver groupnr number of reflectorsr array[nr] of reflectorsnt number of time samplesdt time sampling intervalft first time sampleOutput:trace array[nt] containing synthetic seismogram*****************************************************************************/{ int it,ir,is,ns,ix,iz; float ar,ds,xd,zd,cd,sd,xi,zi,ci,cr,time,amp,sx,sz, tsd,asd,sgsd,tgd,agd,sggd, *temp; ReflectorSegment *rs; int lhd=LHD,nhd=NHD; static float hd[NHD]; static int madehd=0; /* if half-derivative filter not yet made, make it */ if (!madehd) { mkhdiff(dt,lhd,hd); madehd = 1; } /* zero trace */ for (it=0; it<nt; ++it) trace[it] = 0.0; /* loop over reflectors */ for (ir=0; ir<nr; ++ir) { /* amplitude, number of segments, segment length */ ar = r[ir].a; ns = r[ir].ns; ds = r[ir].ds; rs = r[ir].rs; /* loop over diffracting segments */ for (is=0; is<ns; ++is) { /* diffractor midpoint, unit-normal, and length */ xd = rs[is].x; zd = rs[is].z; cd = rs[is].c; sd = rs[is].s; /* check range of reflector */ if(xd<fx || xd>=ex || zd>=ez) continue; /* determine sample indices */ xi = (xd-fx)/dx; ix = xi; zi = zd/dz; 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]); asd = (1.0-sz)*((1.0-sx)*as[ix][iz] + sx*as[ix+1][iz]) + sz*((1.0-sx)*as[ix][iz+1] + sx*as[ix+1][iz+1]); sgsd = (1.0-sz)*((1.0-sx)*sgs[ix][iz] + sx*sgs[ix+1][iz]) + sz*((1.0-sx)*sgs[ix][iz+1] + sx*sgs[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]); agd = (1.0-sz)*((1.0-sx)*ag[ix][iz] + sx*ag[ix+1][iz]) + sz*((1.0-sx)*ag[ix][iz+1] + sx*ag[ix+1][iz+1]); sggd = (1.0-sz)*((1.0-sx)*sgg[ix][iz] + sx*sgg[ix+1][iz]) + sz*((1.0-sx)*sgg[ix][iz+1] + sx*sgg[ix+1][iz+1]); /* cosines of incidence and reflection angles */ ci = cd*cos(asd)+sd*sin(asd); cr = cd*cos(agd)+sd*sin(agd); /* two-way time and amplitude */ time = tsd+tgd; if (ls) amp = sqrt(vs0*vg0/(sgsd*sggd)); else amp = sqrt(vs0*vg0/(sgsd*sggd*(sgsd+sggd))); amp *= ABS(ci+cr)*ar*ds; /* add sinc wavelet to trace */ addsinc(time,amp,nt,dt,ft,trace); } } /* allocate workspace */ temp = ealloc1float(nt); /* apply half-derivative filter to trace */ conv(nhd,-lhd,hd,nt,0,trace,nt,0,temp); /* convolve wavelet with trace */ conv(w->lw,w->iw,w->wv,nt,0,temp,nt,0,trace); /* free workspace */ free1float(temp);}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 takes into account a perturbation in velocity.******************************************************************************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 */ time_p = alloc2float(nz,nx); 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.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; } }/* 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]); 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);/* 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] = 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 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 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 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 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]; }/* fprintf(stderr,"\t CPU time for incident angles= %f \n", cpusec()-tt); */ /* 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 + -