📄 sufdmod2.c
字号:
/* if densities constant, free space and set NULL pointer */ if (dmin==dmax) { free2float(od); od = NULL; } /* if verbose, print parameters */ if (verbose) { fprintf(stderr,"nx = %d\n",nx); fprintf(stderr,"dx = %g\n",dx); fprintf(stderr,"nz = %d\n",nz); fprintf(stderr,"dz = %g\n",dz); fprintf(stderr,"nt = %d\n",nt); fprintf(stderr,"dt = %g\n",dt); fprintf(stderr,"tmax = %g\n",tmax); fprintf(stderr,"fmax = %g\n",fmax); fprintf(stderr,"fpeak = %g\n",fpeak); fprintf(stderr,"vmin = %g\n",vmin); fprintf(stderr,"vmax = %g\n",vmax); fprintf(stderr,"mt = %d\n",mt); if (dmin==dmax) { fprintf(stderr,"constant density\n"); } else { fprintf(stderr,"dfile=%s\n",dfile); fprintf(stderr,"dmin = %g\n",dmin); fprintf(stderr,"dmax = %g\n",dmax); } } /* loop over time steps */ for (it=0,t=0.0; it<nt; ++it,t+=dt) { /* if verbose, print time step */ if (verbose>1) fprintf(stderr,"it=%d t=%g\n",it,t); /* update source function */ if (ns==1) ptsrc(sstrength,xs[0],zs[0],nx,dx,fx,nz,dz,fz,dt,t, fmax,fpeak,tdelay,s); else exsrc(ns,xs,zs,nx,dx,fx,nz,dz,fz,dt,t,fmax,s); /* do one time step */ tstep2(nx,dx,nz,dz,dt,dvv,od,s,pm,p,pp,abs); /* write waves */ /* if (it%mt==0) fwrite(pp[0],sizeof(float),nx*nz,stdout); */ if (it%mt==0) { cubetr.sx = xs[0]; cubetr.sdepth = zs[0]; cubetr.trid = 30 ; cubetr.ns = nz ; cubetr.d1 = dz ; cubetr.d2 = dx ; /* account for delay in source starting time */ cubetr.delrt = - 1000.0 * tdelay; tracl = 0 ; for (ix=0 ; ix < nx ; ++ix) { ++tracl; ++tracr; cubetr.offset = ix * dx - xs[0]; cubetr.gx = ix * dx ; cubetr.tracl = (int) tracl; cubetr.tracr = (int) tracr; for (iz=0 ; iz < nz ; ++iz) { cubetr.data[iz] = pp[ix][iz]; } fputtr(stdout, &cubetr); } } /* if requested, save horizontal line of seismograms */ if (hs!=NULL) { for (ix=0; ix<nx; ++ix) hs[ix][it] = pp[ix][hs1]; } /* if requested, save vertical line of seismograms */ if (vs!=NULL) { for (iz=0; iz<nz; ++iz) vs[iz][it] = pp[vs2][iz]; } /* if requested, save seismograms at source locations */ if (ss!=NULL) { for (is=0; is<ns; ++is) ss[is][it] = pp[ixs[is]][izs[is]]; } /* roll time slice pointers */ ptemp = pm; pm = p; p = pp; pp = ptemp; } /* if requested, write horizontal line of seismograms */ if (hs!=NULL) { horiztr.sx = xs[0]; horiztr.sdepth = zs[0]; horiztr.trid = 1; horiztr.ns = nt ; horiztr.dt = 1000000 * dt ; horiztr.d2 = dx ; /* account for delay in source starting time */ horiztr.delrt = -1000.0 * tdelay ; tracl = tracr = 0; for (ix=0 ; ix < nx ; ++ix){ ++tracl; ++tracr; /* offset from first source location */ horiztr.offset = ix * dx - xs[0]; horiztr.gx = ix * dx; horiztr.tracl = (int) tracl; horiztr.tracr = (int) tracr; for (it = 0 ; it < nt ; ++it){ horiztr.data[it] = hs[ix][it]; } fputtr(hseisfp , &horiztr); } fclose(hseisfp); } /* if requested, write vertical line of seismograms */ if (vs!=NULL) { verttr.trid = 1; verttr.ns = nt ; verttr.sx = xs[0]; verttr.sdepth = zs[0]; verttr.dt = 1000000 * dt ; verttr.d2 = dx ; /* account for delay source starting time */ verttr.delrt = -1000.0 * tdelay ; tracl = tracr = 0; for (iz=0 ; iz < nz ; ++iz){ ++tracl; ++tracr; /* vertical line implies offset in z */ verttr.offset = iz * dz - zs[0]; verttr.tracl = (int) tracl; verttr.tracr = (int) tracr; for (it = 0 ; it < nt ; ++it){ verttr.data[it] = vs[iz][it]; } fputtr(vseisfp , &verttr); } fclose(vseisfp); } /* if requested, write seismogram at source position */ if (ss!=NULL) { srctr.trid = 1; srctr.ns = nt ; srctr.dt = 1000000 * dt ; srctr.d2 = dx ; srctr.delrt = -1000.0 * tdelay ; tracl = tracr = 0; for (is=0 ; is < ns ; ++is){ ++tracl; ++tracr; srctr.sx = xs[is]; srctr.sdepth = zs[is]; srctr.tracl = (int) tracl; srctr.tracr = (int) tracr; for (it = 0 ; it < nt ; ++it){ srctr.data[it] = ss[is][it]; } fputtr(sseisfp , &srctr); } fclose(sseisfp); } /* free space before returning */ free2float(s); free2float(dvv); free2float(pm); free2float(p); free2float(pp); if (od!=NULL) free2float(od); if (hs!=NULL) free2float(hs); if (vs!=NULL) free2float(vs); if (ss!=NULL) free2float(ss); return(CWP_Exit());}void exsrc (int ns, float *xs, float *zs, int nx, float dx, float fx, int nz, float dz, float fz, float dt, float t, float fmax, float **s)/*****************************************************************************update source pressure function for an extended source******************************************************************************Input:ns number of x,z coordinates for extended sourcexs array[ns] of x coordinates of extended sourcezs array[ns] of z coordinates of extended sourcenx number of x samplesdx x sampling intervalfx first x samplenz number of z samplesdz z sampling intervalfz first z sampledt time step (ignored)t time at which to compute source functionfmax maximum frequencyOutput:s array[nx][nz] of source pressure at time t+dt******************************************************************************Author: Dave Hale, Colorado School of Mines, 03/01/90******************************************************************************/{ int ix,iz,ixv,izv,is; float sigma,tbias,ascale,tscale,ts,xn,zn, v,xv,zv,dxdv,dzdv,xvn,zvn,amp,dv,dist,distprev; static float *vs,(*xsd)[4],(*zsd)[4]; static int made=0; /* if not already made, make spline coefficients */ if (!made) { vs = alloc1float(ns); xsd = (float(*)[4])alloc1float(ns*4); zsd = (float(*)[4])alloc1float(ns*4); for (is=0; is<ns; ++is) vs[is] = is; cmonot(ns,vs,xs,xsd); cmonot(ns,vs,zs,zsd); made = 1; } /* zero source array */ for (ix=0; ix<nx; ++ix) for (iz=0; iz<nz; ++iz) s[ix][iz] = 0.0 *dt ; /* compute time-dependent part of source function */ sigma = 0.25/fmax; tbias = 3.0*sigma; ascale = -exp(0.5)/sigma; tscale = 0.5/(sigma*sigma); if (t>2.0*tbias) return; ts = ascale*(t-tbias)*exp(-tscale*(t-tbias)*(t-tbias)); /* loop over extended source locations */ for (v=vs[0],distprev=0.0,dv=1.0; dv!=0.0; distprev=dist,v+=dv) { /* determine x(v), z(v), dx/dv, and dz/dv along source */ intcub(0,ns,vs,xsd,1,&v,&xv); intcub(0,ns,vs,zsd,1,&v,&zv); intcub(1,ns,vs,xsd,1,&v,&dxdv); intcub(1,ns,vs,zsd,1,&v,&dzdv); /* determine increment along extended source */ if (dxdv==0.0) dv = dz/ABS(dzdv); else if (dzdv==0.0) dv = dx/ABS(dxdv); else dv = MIN(dz/ABS(dzdv),dx/ABS(dxdv)); if (v+dv>vs[ns-1]) dv = vs[ns-1]-v; dist = dv*sqrt(dzdv*dzdv+dxdv*dxdv)/sqrt(dx*dx+dz*dz); /* determine source amplitude */ amp = (dist+distprev)/2.0; /* let source contribute within limited distance */ xvn = (xv-fx)/dx; zvn = (zv-fz)/dz; ixv = NINT(xvn); izv = NINT(zvn); for (ix=MAX(0,ixv-3); ix<=MIN(nx-1,ixv+3); ++ix) { for (iz=MAX(0,izv-3); iz<=MIN(nz-1,izv+3); ++iz) { xn = ix-xvn; zn = iz-zvn; s[ix][iz] += ts*amp*exp(-xn*xn-zn*zn); } } }}static float ricker (float t, float fpeak);void ptsrc (float sstrength, float xs, float zs, int nx, float dx, float fx, int nz, float dz, float fz, float dt, float t, float fmax, float fpeak, float tdelay, float **s)/*****************************************************************************update source pressure function for a point source******************************************************************************Input:xs x coordinate of point sourcezs z coordinate of point sourcenx number of x samplesdx x sampling intervalfx first x samplenz number of z samplesdz z sampling intervalfz first z sampledt time step (ignored)t time at which to compute source functionfmax maximum frequency (ignored)fpeak peak frequencyOutput:tdelay time delay of beginning of source functions array[nx][nz] of source pressure at time t+dt******************************************************************************Author: Dave Hale, Colorado School of Mines, 03/01/90******************************************************************************/{ int ix,iz,ixs,izs; float ts,xn,zn,xsn,zsn; /* zero source array */ for (ix=0; ix<nx; ++ix) for (iz=0; iz<nz; ++iz) s[ix][iz] = 0.0 * dt*fmax; /* compute time-dependent part of source function */ /* fpeak = 0.5*fmax; this is now getparred */ tdelay = 1.0/fpeak; if (t>2.0*tdelay) return; ts = ricker(t-tdelay,fpeak); /* let source contribute within limited distance */ xsn = (xs-fx)/dx; zsn = (zs-fz)/dz; ixs = NINT(xsn); izs = NINT(zsn); for (ix=MAX(0,ixs-3); ix<=MIN(nx-1,ixs+3); ++ix) { for (iz=MAX(0,izs-3); iz<=MIN(nz-1,izs+3); ++iz) { xn = ix-xsn; zn = iz-zsn; s[ix][iz] = sstrength*ts*exp(-xn*xn-zn*zn); } }}static float ricker (float t, float fpeak)/*****************************************************************************Compute Ricker wavelet as a function of time******************************************************************************Input:t time at which to evaluate Ricker waveletfpeak peak (dominant) frequency of wavelet
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -