📄 sudmofk.c
字号:
make uniformly sampled vrms(t) for DMO******************************************************************************Input:ndmo number of tdmo,vdmo pairstdmo array[ndmo] of timesvdmo array[ndmo] of rms velocitiesnt number of time samplesdt time sampling intervalft first time sampleOutput:vrms array[nt] of rms velocities******************************************************************************Author: Dave Hale, Colorado School of Mines, 10/03/91*****************************************************************************/{ int it; float t,(*vdmod)[4]; vdmod = (float(*)[4])ealloc1float(ndmo*4); cmonot(ndmo,tdmo,vdmo,vdmod); for (it=0,t=ft; it<nt; ++it,t+=dt) intcub(0,ndmo,tdmo,vdmod,1,&t,&vrms[it]); free1float((float*)vdmod);}static void dmooff (float offset, float fmax, float sdmo, int nx, float dx, int nt, float dt, float ft, float *vrms, float **ptx)/*****************************************************************************perform dmo in f-k domain for one offset******************************************************************************Input:offset source receiver offsetfmax maximum frequencysdmo DMO stretch factornx number of midpointsdx midpoint sampling intervalnt number of time samplesdt time sampling intervalft first timevrms array[nt] of rms velocities ptx array[nx][nt] for p(t,x), zero-padded for fft (see notes)Output:ptx array[nx][nt] for dmo-corrected p(t,x)******************************************************************************Notes:To avoid having to allocate a separate work space that is larger than thearray ptx[nx][nt], ptx must be zero-padded to enable Fourier transform from xto k via prime factor FFT. nxpad (nx after zero-padding) can be estimated by nxpad = 2+npfar(nx+(int)(0.5*ABS(offset/dx)));where npfar() is a function that returns a valid length for real-to-complex prime factor FFT. ptx[nx] to ptx[nxfft-1] must point to zeros.******************************************************************************Author: Dave Hale, Colorado School of Mines, 08/08/91*****************************************************************************/{ int nxfft,itmin,nu,nufft,nw,nk,ix,iu,iw,ik,it,iwn, iwmin,iwmax,nupad,ikmax; float dw,dk,tcon,wwscl,scale,scales,kmax, amp,phase,fr,fi,pwr,pwi, wmin,wmax,fftscl,du,fu,w,k,osdmo,*uoft,*tofu; complex czero=cmplx(0.0,0.0),**ptk,*pu,*pw; /* number of cdps after padding for fft */ nxfft = npfar(nx+(int)(0.5*ABS(offset/dx))); /* get minimum time of first non-zero sample */ for (ix=0,itmin=nt; ix<nx; ++ix) { for (it=0; it<itmin && ptx[ix][it]==0.0; ++it); itmin = it; } /* if all zeros, simply return */ if (itmin>=nt) return; /* make stretch and compress functions t(u) and u(t) */ maketu(offset,itmin,fmax,nt,dt,ft,vrms,&uoft,&nu,&du,&fu,&tofu,&tcon); /* adjust DMO stretch factor for nominal error in log stretch; */ /* solve sdmo*(sqrt(1-a/sdmo)-1) = 0.5*log(1-a), where a=0.5 */ sdmo *= .62; /* inverse of dmo stretch factor */ osdmo = 1.0/sdmo; /* maximum DMO shift (in samples) for any wavenumber k */ nupad = 1.5*sdmo*tcon/du; /* frequency sampling */ nufft = npfa(nu+nupad); nw = nufft; dw = 2.0*PI/(nufft*du); /* allocate workspace */ pu = pw = ealloc1complex(nufft); /* wavenumber sampling and maximum wavenumber to apply dmo */ nk = nxfft/2+1; dk = 2.0*PI/ABS(nxfft*dx); kmax = PI/ABS(dx); ikmax = NINT(kmax/dk); /* pointers to complex p(t,k) */ ptk = (complex**)ealloc1(nk,sizeof(complex*)); for (ik=0; ik<nk; ++ik) ptk[ik] = (complex*)ptx[0]+ik*nt; /* fft scale factor */ fftscl = (float)nk/(float)(ikmax+1)/(nufft*nxfft); /* Fourier transform p(t,x) to p(t,k) */ pfa2rc(-1,2,nt,nxfft,ptx[0],ptk[0]); /* loop over wavenumbers less than maximum */ for (ik=0,k=0.0; ik<=ikmax; ++ik,k+=dk) { /* stretch p(t;k) to p(u) */ ints8c(nt,dt,ft,ptk[ik],czero,czero,nu,tofu,pu); /* pad with zeros and Fourier transform p(u) to p(w) */ for (iu=nu; iu<nufft; ++iu) pu[iu].r = pu[iu].i = 0.0; pfacc(1,nufft,pu); /* minimum and maximum frequencies to process */ wmin = ABS(0.5*vrms[0]*k); wmax = ABS(PI/du); iwmin = MAX(1,MIN((nw-1)/2,NINT(wmin/dw))); iwmax = MAX(0,MIN((nw-1)/2,NINT(wmax/dw))); /* constant independent of w */ wwscl = osdmo*pow(k*0.5*offset/tcon,2.0); /* zero dc (should be zero anyway) */ pw[0].r = pw[0].i = 0.0; /* zero frequencies below minimum */ for (iw=1,iwn=nw-iw; iw<iwmin; ++iw,--iwn) pw[iw].r = pw[iw].i = pw[iwn].r = pw[iwn].i = 0.0; /* do dmo between minimum and maximum frequencies */ for (iw=iwmin,iwn=nw-iwmin,w=iwmin*dw; iw<=iwmax; ++iw,--iwn,w+=dw) { scales = 1.0+wwscl/(w*w); scale = sqrt(scales); phase = sdmo*w*tcon*(scale-1.0); amp = fftscl*(1.0-sdmo+sdmo/scale); fr = amp*cos(phase); fi = amp*sin(phase); pwr = pw[iw].r; pwi = pw[iw].i; pw[iw].r = pwr*fr-pwi*fi; pw[iw].i = pwr*fi+pwi*fr; pwr = pw[iwn].r; pwi = pw[iwn].i; pw[iwn].r = pwr*fr+pwi*fi; pw[iwn].i = pwi*fr-pwr*fi; } /* zero frequencies above maximum to Nyquist (if present) */ for (iw=iwmax+1,iwn=nw-iw; iw<=nw/2; ++iw,--iwn) pw[iw].r = pw[iw].i = pw[iwn].r = pw[iwn].i = 0.0; /* Fourier transform p(w) to p(u) */ pfacc(-1,nufft,pu); /* compress p(u) to p(t;k) */ ints8c(nu,du,fu,pu,czero,czero,nt,uoft,ptk[ik]); } /* zero wavenumber between maximum and Nyquist */ for (; ik<nk; ++ik) for (it=0; it<nt; ++it) ptk[ik][it].r = ptk[ik][it].i = 0.0; /* Fourier transform p(t,k) to p(t,x) */ pfa2cr(1,2,nt,nxfft,ptk[0],ptx[0]); /* free workspace */ free1float(tofu); free1float(uoft); free1complex(pu); free1(ptk);}static void maketu (float offset, int itmin, float fmax, int nt, float dt, float ft, float *vrms, float **uoftp, int *nup, float *dup, float *fup, float **tofup, float *tconp)/*****************************************************************************make stretch and compress functions t(u) and u(t)******************************************************************************Input:offset source receiver offsetitmin index of minimum first non-zero sample for this offsetfmax maximum frequencynt number of time samplesdt time sampling intervalft first timevrms array[nt] of rms velocitiesOutput:uoftp array[nt] of u(t)nup number of u (stretched t) samplesdup u sampling intervalfup first utofup array[nu] of t(u)tconp time constant relating t(u) and u(t)******************************************************************************Author: Dave Hale, Colorado School of Mines, 08/08/91*****************************************************************************/{ int it,numax,nu; float tmin,dumin,et,eu,t1,t2, v2,v22,v44,gamma, v2m,v22m,v44m,gammam,t,dv2,vi2,vi4,v24, *uoft,du,fu,*tofu,tcon; /* determine maximum number of u */ numax = 500+log((float)nt)*(float)(nt-1); /* allocate space for u(t) */ uoft = ealloc1float(nt); /* determine t1 and t2, rounded to nearest sampled times */ tmin = ft+itmin*dt; et = ft+(nt-1)*dt; t1 = MIN(et,MAX(ft+dt,tmin)); if (offset!=0.0) t2 = MAX(t1,1.0/(1.0/et+0.2*dt*vrms[0]*vrms[0]/ (offset*offset))); else t2 = t1; t1 = ft+NINT(t1/dt)*dt; t2 = ft+NINT(t2/dt)*dt; /* compute u(t) */ v2 = vrms[0]; v22 = v2*v2; v44 = v22*v22; gamma = 1.0; for (it=0,t=ft; it<nt; ++it,t+=dt) { v2m = v2; v22m = v22; v44m = v44; gammam = gamma; if (t>0.0) { v2 = vrms[it]; v22 = v2*v2; vi2 = (t*v22-(t-dt)*v22m)/dt; vi4 = vi2*vi2; v44 = (dt*vi4+(t-dt)*v44m)/t; } else { v2 = v2m; v22 = v22m; v44 = v44m; } dv2 = (v2-v2m)/dt; v24 = v22*v22; gamma = 1.5*v44/v24-t*dv2/v2-0.5; if (t<=t1) { uoft[it] = t-t1; } else if (t>t1 && t<=t2) { du = t1*(gamma*log(t/(t-0.5*dt)) - gammam*log((t-dt)/(t-0.5*dt))); dumin = 0.1*dt*t1/t; uoft[it] = uoft[it-1]+MAX(dumin,du); } else if (t>t2) { uoft[it] = 2.0*uoft[it-1]-uoft[it-2]; } } /* determine minimum u(t)-u(t-dt) */ dumin = uoft[1]-uoft[0]; for (it=1; it<nt; ++it) dumin = MIN(dumin,uoft[it]-uoft[it-1]); /* determine u sampling for t(u) to avoid aliasing */ fu = 0.0; eu = uoft[nt-1]; du = dumin/MIN(1.0,2.0*fmax*dt); nu = 1+NINT((eu-fu)/du); if (nu>numax) { nu = numax; du = (eu-fu)/(nu-1); } /* allocate space for t(u) */ tofu = ealloc1float(nu); /* compute t(u) by inverse linear interpolation of u(t) */ yxtoxy(nt,dt,ft,uoft,nu,du,fu,ft,et,tofu); /* set time constant */ tcon = t1; /* set returned values */ *uoftp = uoft; *nup = nu; *dup = du; *fup = fu; *tofup = tofu; *tconp = tcon;}/* for graceful interrupt termination */static void closefiles(void){ efclose(headerfp); eremove(headerfile); exit(EXIT_FAILURE);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -