📄 sudmovz.c
字号:
qn[it].r = -qn[it].r; qn[it].i = -qn[it].i; } pfacc(1,ntfft,qn); /* accumulate into q0 for slopes near -p */ for (iw=iwhm; iw<=iwlm; ++iw) { q0[iw].r += qn[iw].r; q0[iw].i += qn[iw].i; } /* accumulate into q0 for slopes near +p */ for (iw=iwlp; iw<=iwhp; ++iw) { q0[iw].r += qn[iw].r; q0[iw].i += qn[iw].i; } } /* roll ray parameters */ pl = p; p = ph; } /* Fourier transform w to t, with w centered */ /* (including FFT scaling and division by 2 for plane filling) */ pfacc(-1,ntfft,q0); scale = 0.5/ntfft; for (it=0; it<nt; it+=2) { qq[it].r = q0[it].r*scale; qq[it].i = q0[it].i*scale; } for (it=1; it<nt; it+=2) { qq[it].r = -q0[it].r*scale; qq[it].i = -q0[it].i*scale; } /* free workspace */ free1complex(qn); free1complex(q0); } float tmute (float *vrms, int nt, float dt, float ft, float h, float smute)/***************************************************************************Returns MUTE Time for given rms velocity function and half-offset.****************************************************************************Input:vrms array[nt] of rms velocity as a function of NMO timent number of timesdt time sampling intervalft first timeh source-receiver half-offsetsmute maximum allowable NMO stretch t/tn [(100+stretch_percentage)/100]Return: gretest time that is subject to given NMO stretch mute****************************************************************************Author: Craig Artley, Colorado School of Mines, 09/28/91****************************************************************************/{ int it; float tn,*t; /* allocate space */ t = ealloc1float(nt); for (it=0,tn=ft; it<nt; ++it,tn+=dt) t[it] = sqrt(tn*tn+4.0*h*h/(vrms[it]*vrms[it])); /* find greatest nmo time that is subject to stretch mute */ for (it=nt-1; it>0; --it) if (dt/(t[it]-t[it-1])>smute) break; /* free space */ free1float(t); return ft+it*dt;}void getX (float tsg, float h, float p0, float v, float *vars)/***************************************************************************GET trial solution X to system of equations assuming constant velocity.****************************************************************************Input:tsg recording time (from source to receiver)h source-receiver half-offsetp0 ray parameter of zero-offset rayv constant velocityOutput:vars array[5] of variables that satisfies the system for const. v****************************************************************************Author: Craig Artley, Colorado School of Mines, 09/21/91****************************************************************************/{ float x,z,a2,b2,h2,x0,ps,pg,tg,t0,sine,tangent; /* compute constants that determine prestack migration ellipse */ h2 = h*h; a2 = v*v*tsg*tsg/4.0; b2 = MAX(a2-h2,0.0); /* compute sine and tangent of propagation angle */ sine = 0.5*p0*v; tangent = sine/sqrt(MAX(1.0-sine*sine,0.0)); /* find reflection point (x,z) on prestack migration ellipse */ x = tangent*sqrt(a2/(b2+tangent*tangent)); z = sqrt(b2*MAX(1.0-x*x/a2,0.0)); /* find zero-offset location */ x0 = h2/a2*x; /* find times along receiver and zero-offset rays */ tg = sqrt((h-x)*(h-x)+z*z)/v; t0 = sqrt((x0-x)*(x0-x)+z*z)*2.0/v; /* find ray parameters for source and receiver rays */ ps = (x+h)/(v*v*(tsg-tg)); pg = (x-h)/(v*v*tg); /* load trial solution into the variables array */ vars[0] = x0; vars[1] = ps; vars[2] = pg; vars[3] = tg; vars[4] = t0;}void getFJ (float **x, float **a, float **tau, int nt, int np, float dt, float dp, float tsg, float h, float p0, float *vars, float *eqns, float **jacob)/***************************************************************************Compute equation array and Jacobian matrix for system of equations fora given set of parameters.****************************************************************************Input:x array[np][nt] of horizontal location of tabled raysa array[np][nt] of propagation angle of tabled raystau array[np][nt] of travel-time depth of tabled raysnt number of times in ray tablesnp number of ray parameters in ray tablesdt time sampling interval in tablesdp ray parameter sampling interval in tablestsg recording time (from source to receiver)h source-receiver half offsetp0 zero-offset ray parametervars array[5] of variables of system of equationsOutput:eqns array[5] of right-hand-sides of equationsjacob pointer to array[5][5] of Jacobian partial derivatives****************************************************************************Author: Craig Artley, Colorado School of Mines, 09/21/91****************************************************************************/{ int i,j,neqns=5; float x0,ps,pg,ts,tg,t0,ft=0.0,fp=0.0,ftp,dfdt,dfdp,sign; /* extract parameters from variables array */ x0 = vars[0]; ps = vars[1]; pg = vars[2]; tg = vars[3]; t0 = vars[4]; ts = MAX(tsg-tg,0.0); /* zero out F and J */ for (i=0; i<neqns; ++i) eqns[i] = 0.0; for (j=0; j<neqns; ++j) for (i=0; i<neqns; ++i) jacob[j][i] = 0.0; /* insert constant terms into equations */ eqns[0] += 2.0*h; eqns[1] += h-x0; jacob[0][1] -= 1.0; /* get x(ps,2*ts) and partial derivatives, load into equations */ intder(x,nt,dt,ft,np,dp,fp,2.0*ts,ABS(ps),&ftp,&dfdt,&dfdp); sign = SGN(ps); eqns[0] -= sign*ftp; jacob[1][0] -= dfdp; jacob[3][0] += 2.0*sign*dfdt; /* get x(pg,2*tg) and partial derivatives, load into equations */ intder(x,nt,dt,ft,np,dp,fp,2.0*tg,ABS(pg),&ftp,&dfdt,&dfdp); sign = SGN(pg); eqns[0] += sign*ftp; eqns[1] += sign*ftp; jacob[2][0] += dfdp; jacob[2][1] += dfdp; jacob[3][0] += 2.0*sign*dfdt; jacob[3][1] += 2.0*sign*dfdt; /* get x(p0,t0) and partial derivatives, load into equations */ intder(x,nt,dt,ft,np,dp,fp,t0,ABS(p0),&ftp,&dfdt,&dfdp); sign = SGN(p0); eqns[1] -= sign*ftp; jacob[4][1] -= sign*dfdt; /* get tau(ps,2*ts) and partial derivatives, load into equations */ intder(tau,nt,dt,ft,np,dp,fp,2.0*ts,ABS(ps),&ftp,&dfdt,&dfdp); sign = SGN(ps); eqns[2] -= ftp; jacob[1][2] -= sign*dfdp; jacob[3][2] += 2.0*dfdt; /* get tau(pg,2*tg) and partial derivatives, load into equations */ intder(tau,nt,dt,ft,np,dp,fp,2.0*tg,ABS(pg),&ftp,&dfdt,&dfdp); sign = SGN(pg); eqns[2] += ftp; eqns[3] += ftp; jacob[2][2] += sign*dfdp; jacob[2][3] += sign*dfdp; jacob[3][2] += 2.0*dfdt; jacob[3][3] += 2.0*dfdt; /* get tau(p0,t0) and partial derivatives, load into equations */ intder(tau,nt,dt,ft,np,dp,fp,t0,ABS(p0),&ftp,&dfdt,&dfdp); sign = SGN(p0); eqns[3] -= ftp; jacob[4][3] -= dfdt; /* get a(ps,2*ts) and partial derivatives, load into equations */ intder(a,nt,dt,ft,np,dp,fp,2.0*ts,ABS(ps),&ftp,&dfdt,&dfdp); sign = SGN(ps); eqns[4] += sign*ftp; jacob[1][4] += dfdp; jacob[3][4] -= 2.0*sign*dfdt; /* get a(pg,2*tg) and partial derivatives, load into equations */ intder(a,nt,dt,ft,np,dp,fp,2.0*tg,ABS(pg),&ftp,&dfdt,&dfdp); sign = SGN(pg); eqns[4] += sign*ftp; jacob[2][4] += dfdp; jacob[3][4] += 2.0*sign*dfdt; /* get a(p0,t0) and partial derivatives, load into equations */ intder(a,nt,dt,ft,np,dp,fp,t0,ABS(p0),&ftp,&dfdt,&dfdp); sign = SGN(p0); eqns[4] -= 2.0*sign*ftp; jacob[4][4] -= 2.0*sign*dfdt;}void intder (float **f, int nx, float dx, float fx, int ny, float dy, float fy, float x, float y, float *fxy, float *dfdx, float *dfdy)/***************************************************************************Finds f(x,y), df/dx, df/dy given function values on a mesh f[iy][ix],via linear interpolation and finite differencing.****************************************************************************Input:f array[ny][nx] of sampled function valuesnx number of samples in x direction (fast dimension)dx x sampling intervalfx first sample in x directionny number of samples in y direction (slow dimension)dy y sampling intervalfy first sample in y directionx x value at which to evaluate functionsy y value at which to evaluate functionsOutput:fxy interpolated function value f(x,y)dfdx partial derivative df/dx evaluated at (x,y)dfdy partial derivative df/dy evaluated at (x,y)****************************************************************************Note: Constant extrapolation of function and zero derivatives for points outside the table. This is desirable, but somewhat awkward.****************************************************************************Author: Craig Artley, Colorado School of Mines, 08/31/91****************************************************************************/{ int ix0,ix1,iy0,iy1; float x0i,y0i,fracx,fracy,lx,ly,f00,f10,f01,f11; /* compute x and y extent of table */ lx = fx+(nx-1)*dx; ly = fy+(ny-1)*dy; if (x<=fx) { ix0 = ix1 = 0; fracx = 0.0; } else if (x>=lx) { ix0 = ix1 = nx-1; fracx = 1.0; } else { x0i = (x-fx)/dx; ix0 = x0i; ix1 = ix0+1; fracx = x0i-ix0; } if (y<=fy) { iy0 = iy1 = 0; fracy = 0; } else if (y>=ly) { iy0 = iy1 = ny-1; fracy = 1.0; } else { y0i = (y-fy)/dy; iy0 = y0i; iy1 = iy0+1; fracy = y0i-iy0; } /* get tabled function values nearest (x,y) */ f00 = f[iy0][ix0]; f01 = f[iy1][ix0]; f10 = f[iy0][ix1]; f11 = f[iy1][ix1]; /* linear interpolation to find f(x,y) */ *fxy = (1-fracx)*(1-fracy)*f00 + (1-fracx)*fracy*f01 + fracx*(1-fracy)*f10 + fracx*fracy*f11; /* interpolate and finite difference to find partial derivatives */ *dfdx = ((1-fracy)*(f10-f00) + fracy*(f11-f01))/dx; *dfdy = ((1-fracx)*(f01-f00) + fracx*(f11-f10))/dy;}void rayvt (float p, int nt, float dt, float v[], float tau[], float x[], float a[]) /*****************************************************************************trace ray for v = v(tau), tau=ONE-way vertical time******************************************************************************Input:p ray parameternt number of times (including t=0.0)dt time sampling intervalv array[nt] of velocities (v = v(tau))Output:tau array[nt] of vertical times tau(t)x array[nt] of horizontal distances x(t)a array[nt] of propagation angles a(t)******************************************************************************Notes:Ray tracing begins at tau=x=t=0.0. If the ray turns and reaches tau=0.0at some time index it, then tau[it+1:nt-1] = tau[it], x[it+1:nt-1] = x[it],and a[it+1:nt-1] = a[it]. In other words, constant extrapolation is usedto fill the remaining values in the output arrays.******************************************************************************Author: Dave Hale, Colorado School of Mines, 08/30/90Modified: Craig Artley, Colorado School of Mines, 09/25/90 Fixed bug in calculating propagation angles. Added linear interpolation between velocity samples.******************************************************************************/{ int it,jt,itau; float vt,dvt,at,taut,xt,cosat,taui,frac; /* initialize ray tracing parameters */ vt = v[0]; dvt = v[1]-v[0]; at = asin(MIN(1.0,p*vt)); taut = xt = 0.0; tau[0] = taut; x[0] = xt; a[0] = at; /* loop over times t */ for (it=1; it<nt; ++it) { /* compute cosine of propagation angle */ cosat = cos(at); /* update vertical time */ tau[it] = tau[it-1]+dt*cosat; /* if ray has returned to surface, break */ if (tau[it]<=0.0) break; /* update horizontal distance */ x[it] = x[it-1]+dt*p*vt*vt; /* update angle */ at += p*dvt; a[it] = at; /* update velocity and derivative */ if (it<nt-1) { taui = tau[it]/dt; itau = taui; frac = taui-itau; vt = (1.0-frac)*v[itau] + frac*v[itau+1]; dvt = v[itau+1]-v[itau]; } } /* if ray returned to surface, extrapolate with surface values */ for (jt=it; jt<nt; ++jt) { tau[jt] = tau[jt-1]; x[jt] = x[jt-1]; a[jt] = a[jt-1]; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -