int main(int argc, char* argv[]) { bool verb; /* verbosity flag */ bool abc; /* absorbing boundary conditions flag */ bool free; /* free surface flag*/ bool snap; /* wavefield snapshots flag */ int jsnap;/* save wavefield every *jsnap* time steps */ /* cube axes */ sf_axis at,az,ax,as,ar,bt; int it,iz,ix,is,ir, iop; int nt,nz,nx,ns,nr,nz2,nx2; float z0,x0,dt,dx,dz, idx,idz,dt2; /* Laplacian */ int nop=2; /* Laplacian operator size */ float c0, c1, c2; /* Laplacian operator coefficients */ float co,c1x,c2x,c1z,c2z; int nbz,nbx; /* boundary size */ float tz, tx; /* sponge boundary decay coefficients */ float dp; float ws; /* injected data */ /* linear interpolation */ float *fzs,*fxs, *fzr,*fxr; int *jzs,*jxs, *jzr,*jxr; float *ws00,*ws01,*ws10,*ws11; float *wr00,*wr01,*wr10,*wr11; /* boundary */ float *bzl,*bzh,*bxl,*bxh; /* I/O files */ sf_file Fw,Fs,Fr; float *ww; /* wavelet */ pt2d *ss, *rr; /* source/receiver locations */ float **tt; /* taper */ /* background */ sf_file Bv,Bd,Bu; /* velocity, data, wavefield */ float **bvv,**bvo; /* velocity */ float *bdd; /* data */ float **bum,**buo,**bup,**bud; /* wavefields */ /* perturbation */ sf_file Pv,Pd,Pu; float **pvv,**pvo; float *pdd; float **pum,**puo,**pup,**pud; int ompchunk; /* OpenMP data chunk size */ /*------------------------------------------------------------*/ /* init RSF */ sf_init(argc,argv); if(! sf_getint("ompchunk",&ompchunk)) ompchunk=1; if(! sf_getbool("verb",&verb)) verb=false; if(! sf_getbool( "abc",&abc )) abc=false; if(! sf_getbool("snap",&snap)) snap=false; if(! sf_getbool("free",&free)) free=false; Fw = sf_input ("in" ); /* wavelet */ Fs = sf_input ("sou"); /* sources */ Fr = sf_input ("rec"); /* receivers */ Bv = sf_input ("vel"); /* velocity */ Bu = sf_output("wfl"); /* wavefield */ Bd = sf_output("out"); /* data */ Pv = sf_input ("ref"); /* velocity */ Pu = sf_output("liw"); /* linearized wavefield */ Pd = sf_output("lid"); /* linearized data */ /* read axes*/ at=sf_iaxa(Fw,1); sf_setlabel(at,"t"); nt=sf_n(at); dt=sf_d(at); if(verb) sf_raxa(at); /* time */ as=sf_iaxa(Fs,2); sf_setlabel(as,"s"); ns=sf_n(as); if(verb) sf_raxa(as); /* sources */ ar=sf_iaxa(Fr,2); sf_setlabel(ar,"r"); nr=sf_n(ar); if(verb) sf_raxa(ar); /* receivers */ az=sf_iaxa(Bv,1); sf_setlabel(az,"z"); nz=sf_n(az); dz=sf_d(az); if(verb) sf_raxa(az); /* depth */ ax=sf_iaxa(Bv,2); sf_setlabel(ax,"x"); nx=sf_n(ax); dx=sf_d(ax); if(verb) sf_raxa(ax); /* space */ /* configure wavefield snapshots */ if(snap) { if(! sf_getint("jsnap",&jsnap)) jsnap=nt; } /*------------------------------------------------------------*/ /* expand domain for absorbing boundary conditions */ if(abc) { if(! sf_getint("nbz",&nbz)) nbz=nop; if(nbz<nop) nbz=nop; if(! sf_getint("nbx",&nbx)) nbx=nop; if(nbx<nop) nbx=nop; if(! sf_getfloat("tz",&tz)) tz=0.025; if(! sf_getfloat("tx",&tx)) tx=0.025; } else { nbz=nop; nbx=nop; } /* expanded domain ( az+2 nz, ax+2 nx ) */ nz2=nz+2*nbz; z0=sf_o(az)-nbz*dz; nx2=nx+2*nbx; x0=sf_o(ax)-nbx*dx; sf_setn(az,nz2); sf_seto(az,z0); if(verb) sf_raxa(az); sf_setn(ax,nx2); sf_seto(ax,x0); if(verb) sf_raxa(ax); /*------------------------------------------------------------*/ /* setup output wavefield header */ if(snap) { bt = sf_maxa(nt/jsnap,sf_o(at),dt*jsnap); sf_setlabel(bt,"t"); sf_oaxa(Bu,az,1); sf_oaxa(Bu,ax,2); sf_oaxa(Bu,bt,3); sf_oaxa(Pu,az,1); sf_oaxa(Pu,ax,2); sf_oaxa(Pu,bt,3); } /* setup output data header */ sf_oaxa(Bd,ar,1); sf_oaxa(Bd,at,2); sf_oaxa(Pd,ar,1); sf_oaxa(Pd,at,2); dt2 = dt*dt; idz = 1/(dz*dz); idx = 1/(dx*dx); /* Laplacian coefficients */ c0=-30./12.; c1=+16./12.; c2=- 1./12.; co = c0 * (idx+idz); c1x= c1 * idx; c2x= c2 * idx; c1z= c1 * idz; c2z= c2 * idz; /*------------------------------------------------------------*/ /* allocate arrays */ ww=sf_floatalloc (nt); sf_floatread(ww ,nt ,Fw); bvv=sf_floatalloc2(nz,nx); sf_floatread(bvv[0],nz*nx,Bv); pvv=sf_floatalloc2(nz,nx); sf_floatread(pvv[0],nz*nx,Pv); /* allocate source/receiver point arrays */ ss = (pt2d*) sf_alloc(ns,sizeof(*ss)); rr = (pt2d*) sf_alloc(nr,sizeof(*rr)); pt2dread1(Fs,ss,ns,3); /* read 3 elements (x,z,v) */ pt2dread1(Fr,rr,nr,2); /* read 2 elements (x,z) */ bdd=sf_floatalloc(nr); pdd=sf_floatalloc(nr); jzs=sf_intalloc(ns); fzs=sf_floatalloc(ns); jzr=sf_intalloc(nr); fzr=sf_floatalloc(nr); jxs=sf_intalloc(ns); fxs=sf_floatalloc(ns); jxr=sf_intalloc(nr); fxr=sf_floatalloc(nr); ws00 = sf_floatalloc(ns); wr00 = sf_floatalloc(nr); ws01 = sf_floatalloc(ns); wr01 = sf_floatalloc(nr); ws10 = sf_floatalloc(ns); wr10 = sf_floatalloc(nr); ws11 = sf_floatalloc(ns); wr11 = sf_floatalloc(nr); /*------------------------------------------------------------*/ for (is=0;is<ns;is++) { if(ss[is].z >= z0 && ss[is].z < z0 + (nz2-1)*dz && ss[is].x >= x0 && ss[is].x < x0 + (nx2-1)*dx) { jzs[is] = (int)( (ss[is].z-z0)/dz); fzs[is] = (ss[is].z-z0)/dz - jzs[is]; jxs[is] = (int)( (ss[is].x-x0)/dx); fxs[is] = (ss[is].x-x0)/dx - jxs[is]; } else { jzs[is] = 0; jxs[is] = 0; fzs[is] = 1; fxs[is] = 0; ss[is].v= 0; } ws00[is] = (1-fzs[is])*(1-fxs[is]); ws01[is] = ( fzs[is])*(1-fxs[is]); ws10[is] = (1-fzs[is])*( fxs[is]); ws11[is] = ( fzs[is])*( fxs[is]); } for (ir=0;ir<nr;ir++) { if(rr[ir].z >= z0 && rr[ir].z < z0 + (nz2-1)*dz && rr[ir].x >= x0 && rr[ir].x < x0 + (nx2-1)*dx) { jzr[ir] = (int)( (rr[ir].z-z0)/dz); fzr[ir] = (rr[ir].z-z0)/dz - jzr[ir]; jxr[ir] = (int)( (rr[ir].x-x0)/dx); fxr[ir] = (rr[ir].x-x0)/dx - jxr[ir]; rr[ir].v=1; } else { jzr[ir] = 0; fzr[ir] = 1; rr[ir].v= 0; } wr00[ir] = (1-fzr[ir])*(1-fxr[ir]); wr01[ir] = ( fzr[ir])*(1-fxr[ir]); wr10[ir] = (1-fzr[ir])*( fxr[ir]); wr11[ir] = ( fzr[ir])*( fxr[ir]); } /*------------------------------------------------------------*/ /* allocate temporary arrays */ bum=sf_floatalloc2(nz2,nx2); buo=sf_floatalloc2(nz2,nx2); bup=sf_floatalloc2(nz2,nx2); bud=sf_floatalloc2(nz2,nx2); pum=sf_floatalloc2(nz2,nx2); puo=sf_floatalloc2(nz2,nx2); pup=sf_floatalloc2(nz2,nx2); pud=sf_floatalloc2(nz2,nx2); tt=sf_floatalloc2(nz2,nx2); #ifdef _OPENMP #pragma omp parallel for schedule(dynamic,ompchunk) private(iz,ix) shared(nx2,nz2,bum,buo,bup,bud,pum,puo,pup,pud,tt) #endif for (iz=0; iz<nz2; iz++) { for (ix=0; ix<nx2; ix++) { bum[ix][iz]=pum[ix][iz]=0; buo[ix][iz]=puo[ix][iz]=0; bup[ix][iz]=pup[ix][iz]=0; bud[ix][iz]=pud[ix][iz]=0; tt[ix][iz]=1; } } /*------------------------------------------------------------*/ /* velocity in the expanded domain (vo=vv^2)*/ bvo=sf_floatalloc2(nz2,nx2); pvo=sf_floatalloc2(nz2,nx2); #ifdef _OPENMP #pragma omp parallel for schedule(dynamic,ompchunk) private(iz,ix) shared(nz,nx,bvv,pvv,bvo,pvo) #endif for (iz=0; iz<nz; iz++) { for (ix=0; ix<nx; ix++) { bvo[nbx+ix][nbz+iz] = bvv[ix][iz] * bvv[ix][iz]; pvo[nbx+ix][nbz+iz] = pvv[ix][iz]; } } /* fill boundaries */ for (iz=0; iz<nbz; iz++) { for (ix=0; ix<nx2; ix++) { bvo[ix][ iz ] = bvo[ix][ nbz ]; bvo[ix][nz2-iz-1] = bvo[ix][nz2-nbz-1]; pvo[ix][ iz ] = pvo[ix][ nbz ]; pvo[ix][nz2-iz-1] = pvo[ix][nz2-nbz-1]; } } for (iz=0; iz<nz2; iz++) { for (ix=0; ix<nbx; ix++) { bvo[ ix ][iz] = bvo[ nbx ][iz]; bvo[nx2-ix-1][iz] = bvo[nx2-nbx-1][iz]; pvo[ ix ][iz] = pvo[ nbx ][iz]; pvo[nx2-ix-1][iz] = pvo[nx2-nbx-1][iz]; } } /*------------------------------------------------------------*/ /* free surface */ if(abc && free) { for (iz=0; iz<nbz; iz++) { for (ix=0; ix<nx2; ix++) { bvo[ix][iz]=0; pvo[ix][iz]=0; } } } /*------------------------------------------------------------*/ /* sponge ABC setup */ if(abc) { for (iz=0; iz<nbz; iz++) { for (ix=0; ix<nx2; ix++) { tt[ix][ iz ] = exp( - (tz*(nbz-iz))*(tz*(nbz-iz)) ); tt[ix][nz2-iz-1] = tt[ix][iz]; } } for (iz=0; iz<nz2; iz++) { for (ix=0; ix<nbx; ix++) { tt[ ix ][iz] = exp( - (tx*(nbx-ix))*(tx*(nbx-ix)) ); tt[nx2-ix-1][iz] = tt[ix][iz]; } } } /* one-way ABC setup */ bzl=sf_floatalloc(nx2); bzh=sf_floatalloc(nx2); bxl=sf_floatalloc(nz2); bxh=sf_floatalloc(nz2); for (ix=0;ix<nx2;ix++) { dp = bvo[ix][ nop ] *dt/dz; bzl[ix] = (1-dp)/(1+dp); dp = bvo[ix][nz2-nop-1] *dt/dz; bzh[ix] = (1-dp)/(1+dp); } for (iz=0;iz<nz2;iz++) { dp = bvo[ nop ][iz] *dt/dx; bxl[iz] = (1-dp)/(1+dp); dp = bvo[nx2-nop-1][iz] *dt/dx; bxh[iz] = (1-dp)/(1+dp); } /*------------------------------------------------------------*/ /* * MAIN LOOP */ if(verb) fprintf(stderr,"\n"); for (it=0; it<nt; it++) { if(verb) fprintf(stderr,"\b\b\b\b\b%d",it); /* 4th order Laplacian operator */ #ifdef _OPENMP #pragma omp parallel for schedule(dynamic,ompchunk) private(iz,ix) shared(nop,nx2,nz2,bud,buo,pud,puo,co,c1x,c1z,c2x,c2z,idx,idz) #endif for (ix=nop; ix<nx2-nop; ix++) { for (iz=nop; iz<nz2-nop; iz++) { bud[ix][iz] = co * buo[ix ][iz ] + c1x*(buo[ix-1][iz ] + buo[ix+1][iz ]) + c2x*(buo[ix-2][iz ] + buo[ix+2][iz ]) + c1z*(buo[ix ][iz-1] + buo[ix ][iz+1]) + c2z*(buo[ix ][iz-2] + buo[ix ][iz+2]); pud[ix][iz] = co * puo[ix ][iz ] + c1x*(puo[ix-1][iz ] + puo[ix+1][iz ]) + c2x*(puo[ix-2][iz ] + puo[ix+2][iz ]) + c1z*(puo[ix ][iz-1] + puo[ix ][iz+1]) + c2z*(puo[ix ][iz-2] + puo[ix ][iz+2]); } } /* inject source */ for (is=0;is<ns;is++) { ws = ww[it] * ss[is].v; bud[ jxs[is] ][ jzs[is] ] -= ws * ws00[is]; bud[ jxs[is] ][ jzs[is]+1] -= ws * ws01[is]; bud[ jxs[is]+1][ jzs[is] ] -= ws * ws10[is]; bud[ jxs[is]+1][ jzs[is]+1] -= ws * ws11[is]; } #ifdef _OPENMP #pragma omp parallel for schedule(dynamic,ompchunk) private(ix,iz) shared(nx2,nz2,pud,bud,pvo) #endif for (ix=0; ix<nx2; ix++) { for (iz=0; iz<nz2; iz++) { pud[ix][iz] -= bud[ix][iz] * 2*pvo[ix][iz]; } } /* velocity scale */ #ifdef _OPENMP #pragma omp parallel for schedule(dynamic,ompchunk) private(ix,iz) shared(nx2,nz2,bud,pud,bvo) #endif for (ix=0; ix<nx2; ix++) { for (iz=0; iz<nz2; iz++) { bud[ix][iz] *= bvo[ix][iz]; pud[ix][iz] *= bvo[ix][iz]; } } /* time step */ #ifdef _OPENMP #pragma omp parallel for schedule(dynamic,ompchunk) private(ix,iz) shared(nx2,nz2,bud,buo,bum,bup,pud,puo,pum,pup,dt2) #endif for (ix=0; ix<nx2; ix++) { for (iz=0; iz<nz2; iz++) { bup[ix][iz] = 2*buo[ix][iz] - bum[ix][iz] + bud[ix][iz] * dt2; bum[ix][iz] = buo[ix][iz]; buo[ix][iz] = bup[ix][iz]; pup[ix][iz] = 2*puo[ix][iz] - pum[ix][iz] + pud[ix][iz] * dt2; pum[ix][iz] = puo[ix][iz]; puo[ix][iz] = pup[ix][iz]; } } /* one-way ABC apply */ if(abc) { #ifdef _OPENMP #pragma omp parallel for schedule(dynamic,ompchunk) private(ix,iz,iop) shared(nx2,nz2,nop,buo,bum,puo,pum,bzl,bzh) #endif for(ix=0;ix<nx2;ix++) { for(iop=0;iop<nop;iop++) { iz = nop-iop; buo [ix][iz ] = bum[ix][iz+1] +(bum[ix][iz ] - buo[ix][iz+1]) * bzl[ix]; puo [ix][iz ] = pum[ix][iz+1] +(pum[ix][iz ] - puo[ix][iz+1]) * bzl[ix]; iz = nz2-nop+iop-1; buo [ix][iz ] = bum[ix][iz-1] +(bum[ix][iz ] - buo[ix][iz-1]) * bzh[ix]; puo [ix][iz ] = pum[ix][iz-1] +(pum[ix][iz ] - puo[ix][iz-1]) * bzh[ix]; } } #ifdef _OPENMP #pragma omp parallel for schedule(dynamic,1) private(ix,iz,iop) shared(nx2,nz2,nop,buo,bum,puo,pum,bzl,bzh) #endif for(iop=0;iop<nop;iop++) { for(iz=0;iz<nz2;iz++) { ix = nop-iop; buo [ix ][iz] = bum[ix+1][iz] +(bum[ix ][iz] - buo[ix+1][iz]) * bxl[iz]; puo [ix ][iz] = pum[ix+1][iz] +(pum[ix ][iz] - puo[ix+1][iz]) * bxl[iz]; ix = nx2-nop+iop-1; buo [ix ][iz] = bum[ix-1][iz] +(bum[ix ][iz] - buo[ix-1][iz]) * bxh[iz]; puo [ix ][iz] = pum[ix-1][iz] +(pum[ix ][iz] - puo[ix-1][iz]) * bxh[iz]; } } } /* sponge ABC apply */ if(abc) { #ifdef _OPENMP #pragma omp parallel for schedule(dynamic,ompchunk) private(ix,iz) shared(nx2,nz2,buo,bum,bud,puo,pum,pud,tt) #endif for (ix=0; ix<nx2; ix++) { for (iz=0; iz<nz2; iz++) { buo[ix][iz] *= tt[ix][iz]; bum[ix][iz] *= tt[ix][iz]; bud[ix][iz] *= tt[ix][iz]; puo[ix][iz] *= tt[ix][iz]; pum[ix][iz] *= tt[ix][iz]; bud[ix][iz] *= tt[ix][iz]; } } } /* write wavefield */ if(snap && it%jsnap==0) { sf_floatwrite(buo[0],nz2*nx2,Bu); sf_floatwrite(puo[0],nz2*nx2,Pu); } /* write data */ #ifdef _OPENMP #pragma omp parallel for schedule(dynamic,1) private(ir) shared(bdd,pdd,rr,buo,puo,jzr,wr00,wr01,wr10,wr11) #endif for (ir=0;ir<nr;ir++) { bdd[ir] = buo[ jxr[ir] ][ jzr[ir] ] * wr00[ir] + buo[ jxr[ir] ][ jzr[ir]+1] * wr01[ir] + buo[ jxr[ir]+1][ jzr[ir] ] * wr10[ir] + buo[ jxr[ir]+1][ jzr[ir]+1] * wr11[ir]; bdd[ir] *= rr[ir].v; pdd[ir] = puo[ jxr[ir] ][ jzr[ir] ] * wr00[ir] + puo[ jxr[ir] ][ jzr[ir]+1] * wr01[ir] + puo[ jxr[ir]+1][ jzr[ir] ] * wr10[ir] + puo[ jxr[ir]+1][ jzr[ir]+1] * wr11[ir]; pdd[ir] *= rr[ir].v; } /* write data */ sf_floatwrite(bdd,nr,Bd); sf_floatwrite(pdd,nr,Pd); } if(verb) fprintf(stderr,"\n"); exit (0); }
int main(int argc, char** argv) { bool verb, fsrf, snap, expl, dabc, cden, adj; bool optfd, hybrid, sinc; int jsnap, jdata; /* I/O files */ sf_file file_wav=NULL; /* wavelet */ sf_file file_vel=NULL; /* velocity */ sf_file file_den=NULL; /* density */ sf_file file_wfl=NULL; /* wavefield */ sf_file file_dat=NULL; /* data */ sf_file file_src=NULL; /* sources */ sf_file file_rec=NULL; /* receivers */ /* cube axes */ sf_axis at = NULL, az = NULL, ax = NULL, ay = NULL; sf_axis as = NULL, ar = NULL; int nbd; /* ABC boundary size */ int fdorder; /* finite difference spatial accuracy order */ int nzpad,nxpad,nypad; /* boundary padded model size */ int ix,iy,it,is,nx,ny,nz,nt,ns,nr; float dx,dy,dz,dt,dt2; float* damp=NULL; /* damping profile for hybrid bc */ float* ws; /* wavelet */ float*** vel=NULL; /* velocity */ float*** rho=NULL; /* density */ float*** u0=NULL; /* wavefield array u@t-1 (u@t+1) */ float*** u1=NULL; /* wavefield array u@t */ float* u_dat=NULL; /* output data */ float*** ptr_tmp=NULL; pt3d* src3d=NULL; /* source position */ pt3d* rec3d=NULL; /*receiver position*/ scoef3d cssinc = NULL, crsinc = NULL; lint3d cslint = NULL, crlint = NULL; /* FDM structure */ fdm3d fdm = NULL; abcone3d abc = NULL; sponge spo = NULL; int nbell; float* fdcoef_d2; float* fdcoef_d1; sf_axis acz = NULL, acx = NULL, acy = NULL; int nqz, nqx, nqy; float oqz, oqx, oqy, dqz, dqx, dqy; float** oslice = NULL; /* output 3D wavefield slice-by-slice */ float*** tmp_array; double wall_clock_time_s, wall_clock_time_e; const int SECOND_DERIV = 2; const int FIRST_DERIV = 1; int nop; #if defined _OPENMP && _DEBUG double tic; double toc; #endif /* init RSF */ sf_init(argc,argv); #ifdef _OPENMP omp_init(); wall_clock_time_s = omp_get_wtime(); #else wall_clock_time_s = (double) clock() / CLOCKS_PER_SEC; #endif if (!sf_getbool("verb",&verb)) verb=false; /* Verbosity flag */ if (!sf_getbool("snap",&snap)) snap=false; /* Wavefield snapshots flag */ if (!sf_getbool("expl",&expl)) expl=false; /* Multiple sources, one wvlt*/ if (!sf_getbool("dabc",&dabc)) dabc=false; /* Absorbing BC */ if (!sf_getbool("cden",&cden)) cden=false; /* Constant density */ if (!sf_getbool("adj",&adj)) adj=false; /* adjoint flag */ if (!sf_getbool("free",&fsrf) && !sf_getbool("fsrf",&fsrf)) fsrf=false; /* Free surface flag */ if (!sf_getint("nbell",&nbell)) nbell=5; /* gaussian for source injection */ if (!sf_getbool("optfd",&optfd)) optfd=false; /* optimized FD coefficients flag */ if (!sf_getint("fdorder",&fdorder)) fdorder=4; /* spatial FD order */ if (!sf_getbool("hybridbc",&hybrid)) hybrid=false; /* hybrid Absorbing BC */ if (!sf_getbool("sinc",&sinc)) sinc=false; /* sinc source injection */ /* Initialize variables */ file_wav = sf_input("in"); /* wavelet */ file_vel = sf_input("vel"); /* velocity */ file_src = sf_input("sou"); /* sources */ file_rec = sf_input("rec"); /* receivers */ file_dat = sf_output("out"); /* data */ if (snap) file_wfl = sf_output("wfl"); /* wavefield */ if (!cden) { if (sf_getstring("cden")) { file_den = sf_input ("den"); /* density */ } else { cden = true; if (verb) sf_warning("No density file provided, running with constant density"); } } at = sf_iaxa(file_wav,2); sf_setlabel(at,"t"); if(verb) sf_raxa(at); /* time */ az = sf_iaxa(file_vel,1); sf_setlabel(az,"z"); if(verb) sf_raxa(az); /* depth */ ax = sf_iaxa(file_vel,2); sf_setlabel(ax,"x"); if(verb) sf_raxa(ax); /* space */ ay = sf_iaxa(file_vel,3); sf_setlabel(ay,"y"); if(verb) sf_raxa(ay); /* space */ as = sf_iaxa(file_src,2); sf_setlabel(as,"s"); if(verb) sf_raxa(as); /* sources */ ar = sf_iaxa(file_rec,2); sf_setlabel(ar,"r"); if(verb) sf_raxa(ar); /* receivers */ nt = sf_n(at); dt = sf_d(at); nz = sf_n(az); dz = sf_d(az); nx = sf_n(ax); dx = sf_d(ax); ny = sf_n(ay); dy = sf_d(ay); ns = sf_n(as); nr = sf_n(ar); /* other execution parameters */ if (snap) { if (!sf_getint("jsnap",&jsnap)) jsnap=nt; /* # of t steps at which to save wavefield */ } if (!sf_getint("jdata",&jdata)) jdata=1; /* # of t steps at which to save receiver data */ /* setup output data header */ sf_oaxa(file_dat,ar,1); sf_setn(at,(nt-1)/jdata+1); sf_setd(at,dt*jdata); sf_oaxa(file_dat,at,2); /* wavefield cut params */ /* setup output wavefield header */ if (snap) { if (!sf_getint ("nqz",&nqz)) nqz=sf_n(az); /* Saved wfld window nz */ if (!sf_getint ("nqx",&nqx)) nqx=sf_n(ax); /* Saved wfld window nx */ if (!sf_getint ("nqy",&nqy)) nqy=sf_n(ay); /* Saved wfld window ny */ if (!sf_getfloat("oqz",&oqz)) oqz=sf_o(az); /* Saved wfld window oz */ if (!sf_getfloat("oqx",&oqx)) oqx=sf_o(ax); /* Saved wfld window ox */ if (!sf_getfloat("oqy",&oqy)) oqy=sf_o(ay); /* Saved wfld window oy */ if (!sf_getfloat("dqz",&dqz)) dqz=sf_d(az); /* Saved wfld window dz */ if (!sf_getfloat("dqx",&dqx)) dqx=sf_d(ax); /* Saved wfld window dx */ if (!sf_getfloat("dqy",&dqy)) dqy=sf_d(ay); /* Saved wfld window dy */ acz = sf_maxa(nqz,oqz,dqz); if (verb) sf_raxa(acz); acx = sf_maxa(nqx,oqx,dqx); if (verb) sf_raxa(acx); acy = sf_maxa(nqy,oqy,dqy); if (verb) sf_raxa(acy); /* check if the imaging window fits in the wavefield domain */ sf_setn(at,(nt-1)/jsnap+1); sf_setd(at,dt*jsnap); if (verb) sf_raxa(at); sf_oaxa(file_wfl,acz,1); sf_oaxa(file_wfl,acx,2); sf_oaxa(file_wfl,acy,3); sf_oaxa(file_wfl,at,4); } /* 2-2N finite difference coefficient */ nop = fdorder/2; /* fd half-length stencil */ if (!sf_getint("nb",&nbd) || nbd<nop) nbd=nop; if (dabc && hybrid && nbd<=nop) nbd = 2*nop; /* expand domain for FD operators and ABC */ fdm = fdutil3d_init(verb,fsrf,az,ax,ay,nbd,1); sf_setn(az,fdm->nzpad); sf_seto(az,fdm->ozpad); if (verb) sf_raxa(az); sf_setn(ax,fdm->nxpad); sf_seto(ax,fdm->oxpad); if (verb) sf_raxa(ax); sf_setn(ay,fdm->nypad); sf_seto(ay,fdm->oypad); if (verb) sf_raxa(ay); /* Precompute coefficients */ dt2 = dt*dt; nzpad = nz+2*nbd; nxpad = nx+2*nbd; nypad = ny+2*nbd; fdcoef_d2 = compute_fdcoef(nop,dz,dx,dy,optfd,SECOND_DERIV); fdcoef_d1 = compute_fdcoef(nop,dz,dx,dy,optfd,FIRST_DERIV); /* Allocate memories */ if (expl) ws = sf_floatalloc(1); else ws = sf_floatalloc(ns); vel = sf_floatalloc3(nzpad,nxpad,nypad); if (!cden) rho = sf_floatalloc3(nzpad,nxpad,nypad); u_dat = sf_floatalloc(nr); src3d = pt3dalloc1(ns); rec3d = pt3dalloc1(nr); if (snap) oslice = sf_floatalloc2(sf_n(acz),sf_n(acx)); /* source and receiver position */ pt3dread1(file_src,src3d,ns,3); /* read format: (x,y,z) */ if (sinc) cssinc = sinc3d_make(ns,src3d,fdm); else cslint = lint3d_make(ns,src3d,fdm); pt3dread1(file_rec,rec3d,nr,3); /* read format: (x,y,z) */ if (sinc) crsinc = sinc3d_make(nr,rec3d,fdm); else crlint = lint3d_make(nr,rec3d,fdm); if (!sinc) fdbell3d_init(nbell); /* temperary array */ tmp_array = sf_floatalloc3(nz,nx,ny); /* read velocity and pad */ sf_floatread(tmp_array[0][0],nz*nx*ny,file_vel); expand3d(tmp_array,vel,fdm); /* read density and pad */ if (!cden) { sf_floatread(tmp_array[0][0],nz*nx*ny,file_den); expand3d(tmp_array,rho,fdm); } free(**tmp_array); free(*tmp_array); free(tmp_array); /* A1 one-way ABC implicit scheme coefficients */ if (dabc) { abc = abcone3d_make(nbd,dt,vel,fsrf,fdm); if (hybrid) damp = damp_make(nbd-nop); /* compute damping profiles for hybrid bc */ else spo = sponge_make(fdm->nb); } /* allocate memory for wavefield variables */ u0 = sf_floatalloc3(nzpad,nxpad,nypad); u1 = sf_floatalloc3(nzpad,nxpad,nypad); /* initialize variables */ memset(u0[0][0],0,sizeof(float)*nzpad*nxpad*nypad); memset(u1[0][0],0,sizeof(float)*nzpad*nxpad*nypad); memset(u_dat,0,sizeof(float)*nr); /* v = (v*dt)^2 */ for (ix=0;ix<nzpad*nxpad*nypad;ix++) *(vel[0][0]+ix) *= *(vel[0][0]+ix)*dt2; if (fsrf && !hybrid) { for (iy=0; iy<nypad; iy++) for (ix=0; ix<nxpad; ix++) memset(vel[iy][ix],0,sizeof(float)*fdm->nb); } for (it=0; it<nt; it++) { if (verb) sf_warning("it=%d;",it+1); #if defined _OPENMP && _DEBUG tic=omp_get_wtime(); #endif step_forward(u0,u1,vel,rho,fdcoef_d2,fdcoef_d1,nop,nzpad,nxpad,nypad); if (adj) { /* backward inject source wavelet */ if (expl) { sf_seek(file_wav,(off_t)(nt-it-1)*sizeof(float),SEEK_SET); sf_floatread(ws,1,file_wav); ws[0] *= dt2; if (sinc) sinc3d_inject1(u0,ws[0],cssinc); else lint3d_inject1(u0,ws[0],cslint); } else { sf_seek(file_wav,(off_t)(nt-it-1)*ns*sizeof(float),SEEK_SET); sf_floatread(ws,ns,file_wav); for (is=0; is<ns; is++) ws[is] *= dt2; if (sinc) sinc3d_inject(u0,ws,cssinc); else lint3d_inject(u0,ws,cslint); } } else { /* forward inject source wavelet */ if (expl) { sf_floatread(ws,1,file_wav); ws[0] *= dt2; if (sinc) sinc3d_inject1(u0,ws[0],cssinc); else lint3d_inject1(u0,ws[0],cslint); } else { sf_floatread(ws,ns,file_wav); for (is=0; is<ns; is++) ws[is] *= dt2; if (sinc) sinc3d_inject(u0,ws,cssinc); else lint3d_inject(u0,ws,cslint); } } /* apply abc */ if (dabc) { if (hybrid) apply_abc(u0,u1,nz,nx,ny,nbd,abc,nop,damp); else { abcone3d_apply(u0,u1,nop,abc,fdm); sponge3d_apply(u0,spo,fdm); sponge3d_apply(u1,spo,fdm); } } /* loop over pointers */ ptr_tmp = u0; u0 = u1; u1 = ptr_tmp; /* extract snapshot */ if (snap && it%jsnap==0) { int fy = (floor)((sf_o(acy)-fdm->oypad)/fdm->dy); int jy = floor(sf_d(acy)/fdm->dy); float **ptr_slice; for (iy=0; iy<sf_n(acy); iy++) { ptr_slice = u0[fy+iy*jy]; cut3d_slice(ptr_slice,oslice,fdm,acz,acx); sf_floatwrite(oslice[0],sf_n(acz)*sf_n(acx),file_wfl); } } /* extract receiver data */ if (sinc) sinc3d_extract(u0,u_dat,crsinc); else lint3d_extract(u0,u_dat,crlint); sf_floatwrite(u_dat,nr,file_dat); #if defined _OPENMP && _DEBUG toc=omp_get_wtime(); fprintf(stderr,"%5.2gs",(float)(toc-tic)); #endif } #ifdef _OPENMP wall_clock_time_e = omp_get_wtime(); #else wall_clock_time_e = (double) clock() / CLOCKS_PER_SEC; #endif if (verb) fprintf(stderr,"\nElapsed time: %lf s\n",wall_clock_time_e-wall_clock_time_s); free(**u0); free(*u0); free(u0); free(**u1); free(*u1); free(u1); free(**vel); free(*vel); free(vel); free(u_dat); free(ws); free(fdcoef_d2); free(fdcoef_d1); if (snap) { free(*oslice); free(oslice); } if(!cden) { free(**rho); free(*rho); free(rho); } if (hybrid) free(damp); free(src3d); free(rec3d); return 0; }
int main(int argc, char* argv[]) { bool verb,fsrf,snap,expl; int jsnap,ntsnap; int jdata; /* I/O files */ sf_file Fwav=NULL; /* wavelet */ sf_file Fsou=NULL; /* sources */ sf_file Frec=NULL; /* receivers */ sf_file Fvel=NULL; /* velocity */ sf_file Fref=NULL; /* reflectivity */ sf_file Fden=NULL; /* density */ sf_file Fdat=NULL; /* data (background) */ sf_file Fwfl=NULL; /* wavefield (background) */ sf_file Flid=NULL; /* data (scattered) */ sf_file Fliw=NULL; /* wavefield (scattered) */ /* I/O arrays */ float *ww=NULL; /* wavelet */ pt2d *ss=NULL; /* sources */ pt2d *rr=NULL; /* receivers */ float **vpin=NULL; /* velocity */ float **roin=NULL; /* density */ float **rfin=NULL; /* reflectivity */ float **vp=NULL; /* velocity in expanded domain */ float **ro=NULL; /* density in expanded domain */ float **ro1=NULL; /* normalized 1st derivative of density on axis 1 */ float **ro2=NULL; /* normalized 1st derivative of density on axis 2 */ float **rf=NULL; /* reflectivity in expanded domain */ float *bdd=NULL; /* data (background) */ float *sdd=NULL; /* data (scattered) */ float **vt=NULL; /* temporary vp*vp * dt*dt */ float **bum,**buo,**bup,**bua,**but; /* wavefield: um = U @ t-1; uo = U @ t; up = U @ t+1 */ float **sum,**suo,**sup,**sua,**sut; /* wavefield: um = U @ t-1; uo = U @ t; up = U @ t+1 */ /* cube axes */ sf_axis at,a1,a2,as,ar; int nt,n1,n2,ns,nr,nb; int it,i1,i2; float dt,d1,d2,id1,id2,dt2; /* linear interpolation weights/indices */ lint2d cs,cr; fdm2d fdm; abcone2d abc; /* abc */ sponge spo; /* FD operator size */ float co,ca2,cb2,ca1,cb1; int ompchunk; #ifdef _OPENMP int ompnth,ompath; #endif sf_axis ac1=NULL,ac2=NULL; int nqz,nqx; float oqz,oqx; float dqz,dqx; float **uc=NULL; /*------------------------------------------------------------*/ /* init RSF */ sf_init(argc,argv); if(! sf_getint("ompchunk",&ompchunk)) ompchunk=1; /* OpenMP data chunk size */ #ifdef _OPENMP if(! sf_getint("ompnth", &ompnth)) ompnth=0; /* OpenMP available threads */ #pragma omp parallel ompath=omp_get_num_threads(); if(ompnth<1) ompnth=ompath; omp_set_num_threads(ompnth); sf_warning("using %d threads of a total of %d",ompnth,ompath); #endif if(! sf_getbool("verb",&verb)) verb=false; /* verbosity flag */ if(! sf_getbool("snap",&snap)) snap=false; /* wavefield snapshots flag */ if(! sf_getbool("free",&fsrf)) fsrf=false; /* free surface flag */ if(! sf_getbool("expl",&expl)) expl=false; /* "exploding reflector" */ Fwav = sf_input ("in" ); /* wavelet */ Fsou = sf_input ("sou"); /* sources */ Frec = sf_input ("rec"); /* receivers */ Fvel = sf_input ("vel"); /* velocity */ Fden = sf_input ("den"); /* density */ Fref = sf_input ("ref"); /* reflectivity */ Fwfl = sf_output("wfl"); /* wavefield */ Fdat = sf_output("out"); /* data */ Fliw = sf_output("liw"); /* wavefield (scattered) */ Flid = sf_output("lid"); /* data (scattered) */ /* axes */ at = sf_iaxa(Fwav,2); sf_setlabel(at,"t"); if(verb) sf_raxa(at); /* time */ as = sf_iaxa(Fsou,2); sf_setlabel(as,"s"); if(verb) sf_raxa(as); /* sources */ ar = sf_iaxa(Frec,2); sf_setlabel(ar,"r"); if(verb) sf_raxa(ar); /* receivers */ a1 = sf_iaxa(Fvel,1); sf_setlabel(a1,"z"); if(verb) sf_raxa(a1); /* depth */ a2 = sf_iaxa(Fvel,2); sf_setlabel(a2,"x"); if(verb) sf_raxa(a2); /* space */ nt = sf_n(at); dt = sf_d(at); ns = sf_n(as); nr = sf_n(ar); n1 = sf_n(a1); d1 = sf_d(a1); n2 = sf_n(a2); d2 = sf_d(a2); if(! sf_getint("jdata",&jdata)) jdata=1; if(snap) { /* save wavefield every *jsnap* time steps */ if(! sf_getint("jsnap",&jsnap)) jsnap=nt; } /*------------------------------------------------------------*/ /* setup output data header */ sf_oaxa(Fdat,ar,1); sf_oaxa(Flid,ar,1); sf_setn(at,nt/jdata); sf_setd(at,dt*jdata); sf_oaxa(Fdat,at,2); sf_oaxa(Flid,at,2); /* setup output wavefield header */ if(snap) { if(!sf_getint ("nqz",&nqz)) nqz=sf_n(a1); if(!sf_getint ("nqx",&nqx)) nqx=sf_n(a2); if(!sf_getfloat("oqz",&oqz)) oqz=sf_o(a1); if(!sf_getfloat("oqx",&oqx)) oqx=sf_o(a2); dqz=sf_d(a1); dqx=sf_d(a2); ac1 = sf_maxa(nqz,oqz,dqz); ac2 = sf_maxa(nqx,oqx,dqx); /* check if the imaging window fits in the wavefield domain */ uc=sf_floatalloc2(sf_n(ac1),sf_n(ac2)); ntsnap=0; for(it=0; it<nt; it++) { if(it%jsnap==0) ntsnap++; } sf_setn(at, ntsnap); sf_setd(at,dt*jsnap); if(verb) sf_raxa(at); /* sf_setn(at,nt/jsnap); sf_setd(at,dt*jsnap); */ sf_oaxa(Fwfl,ac1,1); sf_oaxa(Fwfl,ac2,2); sf_oaxa(Fwfl,at, 3); sf_oaxa(Fliw,ac1,1); sf_oaxa(Fliw,ac2,2); sf_oaxa(Fliw,at, 3); } /*------------------------------------------------------------*/ /* expand domain for FD operators and ABC */ if( !sf_getint("nb",&nb) || nb<NOP) nb=NOP; fdm=fdutil_init(verb,fsrf,a1,a2,nb,ompchunk); sf_setn(a1,fdm->nzpad); sf_seto(a1,fdm->ozpad); if(verb) sf_raxa(a1); sf_setn(a2,fdm->nxpad); sf_seto(a2,fdm->oxpad); if(verb) sf_raxa(a2); /*------------------------------------------------------------*/ if(expl) ww = sf_floatalloc( 1); else ww = sf_floatalloc(ns); bdd =sf_floatalloc(nr); sdd =sf_floatalloc(nr); /*------------------------------------------------------------*/ /* setup source/receiver coordinates */ ss = (pt2d*) sf_alloc(ns,sizeof(*ss)); rr = (pt2d*) sf_alloc(nr,sizeof(*rr)); pt2dread1(Fsou,ss,ns,2); /* read (x,z) coordinates */ pt2dread1(Frec,rr,nr,2); /* read (x,z) coordinates */ cs = lint2d_make(ns,ss,fdm); cr = lint2d_make(nr,rr,fdm); /*------------------------------------------------------------*/ /* setup FD coefficients */ dt2 = dt*dt; id1 = 1/d1; id2 = 1/d2; co = C0 * (id2*id2+id1*id1); ca2= CA * id2*id2; cb2= CB * id2*id2; ca1= CA * id1*id1; cb1= CB * id1*id1; /*------------------------------------------------------------*/ /* input density */ roin=sf_floatalloc2(n1, n2 ); ro =sf_floatalloc2(fdm->nzpad,fdm->nxpad); ro1 =sf_floatalloc2(fdm->nzpad,fdm->nxpad); ro2 =sf_floatalloc2(fdm->nzpad,fdm->nxpad); sf_floatread(roin[0],n1*n2,Fden); expand(roin,ro,fdm); /* normalized density derivatives */ for (i2=NOP; i2<fdm->nxpad-NOP; i2++) { for(i1=NOP; i1<fdm->nzpad-NOP; i1++) { ro1[i2][i1] = D1(ro,i2,i1,id1) / ro[i2][i1]; ro2[i2][i1] = D2(ro,i2,i1,id2) / ro[i2][i1]; } } free(*roin); free(roin); /*------------------------------------------------------------*/ /* input velocity */ vpin=sf_floatalloc2(n1, n2 ); vp =sf_floatalloc2(fdm->nzpad,fdm->nxpad); vt =sf_floatalloc2(fdm->nzpad,fdm->nxpad); sf_floatread(vpin[0],n1*n2,Fvel); expand(vpin,vp,fdm); free(*vpin); free(vpin); /*------------------------------------------------------------*/ /* input reflectivity */ rfin=sf_floatalloc2(n1, n2 ); rf =sf_floatalloc2(fdm->nzpad,fdm->nxpad); sf_floatread(rfin[0],n1*n2,Fref); expand(rfin,rf,fdm); free(*rfin); free(rfin); for (i2=0; i2<fdm->nxpad; i2++) { for(i1=0; i1<fdm->nzpad; i1++) { vt[i2][i1] = vp[i2][i1] * vp[i2][i1] * dt2; } } /* free surface */ if(fsrf) { for (i2=0; i2<fdm->nxpad; i2++) { for(i1=0; i1<fdm->nb; i1++) { vt[i2][i1]=0; } } } /*------------------------------------------------------------*/ /* allocate wavefield arrays */ bum=sf_floatalloc2(fdm->nzpad,fdm->nxpad); buo=sf_floatalloc2(fdm->nzpad,fdm->nxpad); bup=sf_floatalloc2(fdm->nzpad,fdm->nxpad); bua=sf_floatalloc2(fdm->nzpad,fdm->nxpad); sum=sf_floatalloc2(fdm->nzpad,fdm->nxpad); suo=sf_floatalloc2(fdm->nzpad,fdm->nxpad); sup=sf_floatalloc2(fdm->nzpad,fdm->nxpad); sua=sf_floatalloc2(fdm->nzpad,fdm->nxpad); for (i2=0; i2<fdm->nxpad; i2++) { for(i1=0; i1<fdm->nzpad; i1++) { bum[i2][i1]=0; buo[i2][i1]=0; bup[i2][i1]=0; bua[i2][i1]=0; sum[i2][i1]=0; suo[i2][i1]=0; sup[i2][i1]=0; sua[i2][i1]=0; } } /*------------------------------------------------------------*/ /* one-way abc setup */ abc = abcone2d_make(NOP,dt,vp,fsrf,fdm); /* sponge abc setup */ spo = sponge_make(fdm->nb); /*------------------------------------------------------------*/ /* * MAIN LOOP */ /*------------------------------------------------------------*/ if(verb) fprintf(stderr,"\n"); for (it=0; it<nt; it++) { if(verb) fprintf(stderr,"\b\b\b\b\b%d",it); #ifdef _OPENMP #pragma omp parallel for schedule(dynamic,fdm->ompchunk) private(i2,i1) shared(fdm,bua,buo,sua,suo,co,ca2,ca1,cb2,cb1,id2,id1) #endif for (i2=NOP; i2<fdm->nxpad-NOP; i2++) { for(i1=NOP; i1<fdm->nzpad-NOP; i1++) { /* 4th order Laplacian operator */ bua[i2][i1] = co * buo[i2 ][i1 ] + ca2*(buo[i2-1][i1 ] + buo[i2+1][i1 ]) + cb2*(buo[i2-2][i1 ] + buo[i2+2][i1 ]) + ca1*(buo[i2 ][i1-1] + buo[i2 ][i1+1]) + cb1*(buo[i2 ][i1-2] + buo[i2 ][i1+2]); sua[i2][i1] = co * suo[i2 ][i1 ] + ca2*(suo[i2-1][i1 ] + suo[i2+1][i1 ]) + cb2*(suo[i2-2][i1 ] + suo[i2+2][i1 ]) + ca1*(suo[i2 ][i1-1] + suo[i2 ][i1+1]) + cb1*(suo[i2 ][i1-2] + suo[i2 ][i1+2]); /* density term */ bua[i2][i1] -= ( D1(buo,i2,i1,id1) * ro1[i2][i1] + D2(buo,i2,i1,id2) * ro2[i2][i1] ); sua[i2][i1] -= ( D1(suo,i2,i1,id1) * ro1[i2][i1] + D2(suo,i2,i1,id2) * ro2[i2][i1] ); } } /* inject acceleration source */ if(expl) { sf_floatread(ww, 1,Fwav); lint2d_inject1(bua,ww[0],cs); } else { sf_floatread(ww,ns,Fwav); lint2d_inject(bua,ww,cs); } /* single scattering */ #ifdef _OPENMP #pragma omp parallel for schedule(dynamic,ompchunk) private(i2,i1) shared(fdm,buo,sua,rf) #endif for (i2=0; i2<fdm->nxpad; i2++) { for (i1=0; i1<fdm->nzpad; i1++) { sua[i2][i1] -= bua[i2][i1] * 2*rf[i2][i1]; } } /* step forward in time */ #ifdef _OPENMP #pragma omp parallel for schedule(dynamic,fdm->ompchunk) private(i2,i1) shared(fdm,bua,buo,bum,bup,sua,suo,sum,sup,vt,dt2) #endif for (i2=0; i2<fdm->nxpad; i2++) { for(i1=0; i1<fdm->nzpad; i1++) { bup[i2][i1] = 2*buo[i2][i1] - bum[i2][i1] + bua[i2][i1] * vt[i2][i1]; sup[i2][i1] = 2*suo[i2][i1] - sum[i2][i1] + sua[i2][i1] * vt[i2][i1]; } } /* circulate wavefield arrays */ but=bum; bum=buo; buo=bup; bup=but; sut=sum; sum=suo; suo=sup; sup=sut; /* one-way abc apply*/ abcone2d_apply(buo,bum,NOP,abc,fdm); sponge2d_apply(bum, spo,fdm); sponge2d_apply(buo, spo,fdm); abcone2d_apply(suo,sum,NOP,abc,fdm); sponge2d_apply(sum, spo,fdm); sponge2d_apply(suo, spo,fdm); /* extract data at receivers */ lint2d_extract(buo,bdd,cr); lint2d_extract(suo,sdd,cr); if( it%jdata==0) { sf_floatwrite(bdd,nr,Fdat); sf_floatwrite(sdd,nr,Flid); } /* extract wavefield in the "box" */ if(snap && it%jsnap==0) { cut2d(buo,uc,fdm,ac1,ac2); sf_floatwrite(uc[0],sf_n(ac1)*sf_n(ac2),Fwfl); cut2d(suo,uc,fdm,ac1,ac2); sf_floatwrite(uc[0],sf_n(ac1)*sf_n(ac2),Fliw); } } if(verb) fprintf(stderr,"\n"); exit (0); }
int main(int argc, char *argv[]) { clock_t tstart, tend; double duration; int numprocs, rank; float *sendbuf, *recvbuf; MPI_Comm Comm=MPI_COMM_WORLD; bool verb, wantrecord, wantwf, onlyrecord; sf_file Ffvel, Ffden, Fbvel, Fbden; sf_file Fsrc, Frcd, Fimg1, Fimg2; sf_file FGx, FGz, Fsxx, Fsxz, Fszx, Fszz; sf_file Ftmpfwf, Ftmpbwf; sf_axis at, ax, az, atau; int shtbgn, shtinv, shtnmb, shtpad, shtnmb0; int snapturn, tmpint; float **fvel, **bvel; float ***fwf, ***record, **localrec; float ***img1, **img2, ***mig1, **mig2; float *tmpsxx, *tmpsxz, *tmpszx, *tmpszz; sf_init(argc, argv); MPI_Init(&argc, &argv); MPI_Comm_size(Comm, &numprocs); MPI_Comm_rank(Comm, &rank); tstart=clock(); if(rank==0) sf_warning("numprocs=%d", numprocs); if(!sf_getbool("verb", &verb)) verb=true; if(!sf_getbool("wantrecord", &wantrecord)) wantrecord=false; if(!sf_getbool("wantwf", &wantwf)) wantwf=false; if(!sf_getbool("onlyrecord", &onlyrecord)) onlyrecord=false; Fsrc=sf_input("-input"); Fimg1=sf_output("-output"); Fimg2=sf_output("img2"); Ffvel=sf_input("fvel"); Ffden=sf_input("fden"); Fbvel=sf_input("bvel"); Fbden=sf_input("bden"); if(wantrecord) Frcd=sf_input("record"); else Frcd=sf_output("record"); if(wantwf){ Ftmpfwf=sf_output("tmpfwf"); Ftmpbwf=sf_output("tmpbwf"); } FGx=sf_input("Gx"); FGz=sf_input("Gz"); Fsxx=sf_input("sxx"); Fsxz=sf_input("sxz"); Fszx=sf_input("szx"); Fszz=sf_input("szz"); at=sf_iaxa(Fsrc, 1); nt=sf_n(at); dt=sf_d(at); if(!sf_getbool("srcdecay", &srcdecay)) srcdecay=true; if(!sf_getint("srcrange", &srcrange)) srcrange=3; if(!sf_getfloat("srctrunc", &srctrunc)) srctrunc=0.2; if(!sf_getfloat("srcalpha", &srcalpha)) srcalpha=0.5; wavelet=sf_floatalloc(nt); sf_floatread(wavelet, nt, Fsrc); if(!sf_getint("pmlsize", &pmlsize)) pmlsize=30; if(!sf_getint("nfd", &nfd)) sf_error("Need half of the FD order!"); if(!sf_getfloat("pmld0", &pmld0)) pmld0=200; if(!sf_getint("shtnmb", &shtnmb)) sf_error("Need shot number!"); if(!sf_getint("shtinv", &shtinv)) sf_error("Need shot interval!"); if(!sf_getint("shtbgn", &shtbgn)) shtbgn=0; shtpad=numprocs-shtnmb%numprocs; shtnmb0=shtnmb+shtpad; az=sf_iaxa(Ffvel, 1); nzb=sf_n(az); ax=sf_iaxa(Ffvel, 2); nxb=sf_n(ax); nxzb=nxb*nzb; nz=nzb-2*nfd-2*pmlsize; nx=nxb-2*nfd-2*pmlsize; if(!sf_getint("snapturn", &snapturn)) snapturn=1; if(!sf_getint("ginv", &ginv)) ginv=1; if(!sf_getint("wfinv", &wfinv)) wfinv=1; if(!sf_getint("spz", &spz)) spz=6; if(!sf_getint("gp", &gp)) gp=0; ng=(nx-1)/ginv+1; wfnt=(nt-1)/wfinv+1; wfdt=dt*wfinv; if(!sf_getint("ntau", &ntau)) ntau=1; if(!sf_getfloat("dtau", &dtau)) dtau=wfdt; if(!sf_getfloat("tau0", &tau0)) tau0=0; atau=sf_iaxa(Fsrc, 1); sf_setn(atau, ntau); sf_setd(atau, dtau); sf_seto(atau, tau0); if(!sf_histint(FGx, "n1", &nxz)) sf_error("No n1= in FGx!"); if(nxz != nxzb) sf_error("Dimension error!"); if(!sf_histint(FGx, "n2", &lenx)) sf_error("No n2= in FGx!"); if(!sf_histint(FGz, "n2", &lenz)) sf_error("No n2= in FGz!"); Gx=sf_floatalloc3(nzb, nxb, lenx); Gz=sf_floatalloc3(nzb, nxb, lenz); sxx=sf_intalloc(lenx); sxz=sf_intalloc(lenx); szx=sf_intalloc(lenz); szz=sf_intalloc(lenz); tmpsxx=sf_floatalloc(lenx); tmpsxz=sf_floatalloc(lenx); tmpszx=sf_floatalloc(lenz); tmpszz=sf_floatalloc(lenz); sf_floatread(Gx[0][0], nxzb*lenx, FGx); sf_floatread(Gz[0][0], nxzb*lenz, FGz); sf_floatread(tmpsxx, lenx, Fsxx); sf_floatread(tmpsxz, lenx, Fsxz); sf_floatread(tmpszx, lenz, Fszx); sf_floatread(tmpszz, lenz, Fszz); for (ix=0; ix<lenx; ix++){ sxx[ix]=(int)tmpsxx[ix]; sxz[ix]=(int)tmpsxz[ix]; } for (iz=0; iz<lenz; iz++){ szx[iz]=(int)tmpszx[iz]; szz[iz]=(int)tmpszz[iz]; } fvel=sf_floatalloc2(nzb, nxb); fden=sf_floatalloc2(nzb, nxb); fc11=sf_floatalloc2(nzb, nxb); bvel=sf_floatalloc2(nzb, nxb); bden=sf_floatalloc2(nzb, nxb); bc11=sf_floatalloc2(nzb, nxb); sf_floatread(fvel[0], nxzb, Ffvel); sf_floatread(fden[0], nxzb, Ffden); sf_floatread(bvel[0], nxzb, Fbvel); sf_floatread(bden[0], nxzb, Fbden); for (ix=0; ix<nxb; ix++){ for (iz=0; iz<nzb; iz++){ fc11[ix][iz]=fden[ix][iz]*fvel[ix][iz]*fvel[ix][iz]; bc11[ix][iz]=bden[ix][iz]*bvel[ix][iz]*bvel[ix][iz]; } } if(wantrecord){ /* check record data */ sf_histint(Frcd, "n1", &tmpint); if(tmpint != nt) sf_error("Not matched dimensions!"); sf_histint(Frcd, "n2", &tmpint); if(tmpint != ng) sf_error("Not matched dimensions!"); sf_histint(Frcd, "n3", &tmpint); if(tmpint != shtnmb) sf_error("Not matched dimensions!"); } if(rank==0){ record=sf_floatalloc3(nt, ng, shtnmb0); if(wantrecord){ sf_floatread(record[0][0], nt*ng*shtnmb, Frcd); for(is=shtnmb; is<shtnmb0; is++) for(ix=0; ix<ng; ix++) for(it=0; it<nt; it++) record[is][ix][it]=0.0; } } img1=sf_floatalloc3(nz, nx, ntau); mig1=sf_floatalloc3(nz, nx, ntau); img2=sf_floatalloc2(nz, nx); mig2=sf_floatalloc2(nz, nx); zero3(img1, nz, nx, ntau); zero2(img2, nz, nx); sf_setn(az, nz); sf_setn(ax, ng); if(!wantrecord){ sf_oaxa(Frcd, at, 1); sf_oaxa(Frcd, ax, 2); sf_putint(Frcd, "n3", shtnmb); sf_putint(Frcd, "d3", shtinv); sf_putint(Frcd, "o3", shtbgn); } sf_setn(ax, nx); if(wantwf){ sf_setn(at, wfnt); sf_setd(at, wfdt); sf_oaxa(Ftmpfwf, az, 1); sf_oaxa(Ftmpfwf, ax, 2); sf_oaxa(Ftmpfwf, at, 3); sf_oaxa(Ftmpbwf, az, 1); sf_oaxa(Ftmpbwf, ax, 2); sf_oaxa(Ftmpbwf, at, 3); } sf_oaxa(Fimg1, az, 1); sf_oaxa(Fimg1, ax, 2); sf_oaxa(Fimg1, atau, 3); sf_oaxa(Fimg2, az, 1); sf_oaxa(Fimg2, ax, 2); fwf=sf_floatalloc3(nz, nx, wfnt); localrec=sf_floatalloc2(nt, ng); if(verb){ sf_warning("=================================="); sf_warning("nx=%d nz=%d nt=%d", nx, nz, nt); sf_warning("wfnt=%d wfdt=%f wfinv=%d dt=%f", wfnt, wfdt, wfinv, dt); sf_warning("nxb=%d nzb=%d pmlsize=%d nfd=%d", nxb, nzb, pmlsize, nfd); sf_warning("ntau=%d dtau=%f tau0=%f", ntau, dtau, tau0); sf_warning("shtnmb=%d shtbgn=%d shtinv=%d", shtnmb, shtbgn, shtinv); sf_warning("lenx=%d lenz=%d spz=%d gp=%d", lenx, lenz, spz, gp); sf_warning("=================================="); } init(); for(iturn=0; iturn*numprocs<shtnmb; iturn++){ is=iturn*numprocs+rank; if(is<shtnmb){ sf_warning("ishot/nshot: %d/%d", is+1, shtnmb); spx=is*shtinv+shtbgn; sglfdfor2(fwf, localrec, verb); } if(wantrecord){ recvbuf=localrec[0]; if(rank==0) sendbuf=record[iturn*numprocs][0]; else sendbuf=NULL; MPI_Scatter(sendbuf, ng*nt, MPI_FLOAT, recvbuf, ng*nt, MPI_FLOAT, 0, Comm); }else{ sendbuf=localrec[0]; if(rank==0) recvbuf=record[iturn*numprocs][0]; else recvbuf=NULL; MPI_Gather(sendbuf, ng*nt, MPI_FLOAT, recvbuf, ng*nt, MPI_FLOAT, 0, Comm); } if(wantwf && rank==0 && iturn==snapturn-1) wantwf=true; else wantwf=false; if(wantwf) sf_floatwrite(fwf[0][0], wfnt*nx*nz, Ftmpfwf); if(!onlyrecord && is<shtnmb){ sglfdback2(mig1, mig2, fwf, localrec, verb, wantwf, Ftmpbwf); for(itau=0; itau<ntau; itau++){ for(ix=0; ix<nx; ix++){ for(iz=0; iz<nz; iz++){ img1[itau][ix][iz]+=mig1[itau][ix][iz]; } } } for(ix=0; ix<nx; ix++){ for(iz=0; iz<nz; iz++){ img2[ix][iz]+=mig2[ix][iz]; } } } MPI_Barrier(Comm); } //end of iturn if(!onlyrecord){ if(rank==0){ sendbuf=(float *)MPI_IN_PLACE; recvbuf=img1[0][0]; }else{ sendbuf=img1[0][0]; recvbuf=NULL; } MPI_Reduce(sendbuf, recvbuf, ntau*nx*nz, MPI_FLOAT, MPI_SUM, 0, Comm); if(rank==0){ sendbuf=MPI_IN_PLACE; recvbuf=img2[0]; }else{ sendbuf=img2[0]; recvbuf=NULL; } MPI_Reduce(sendbuf, recvbuf, nx*nz, MPI_FLOAT, MPI_SUM, 0, Comm); } if(rank==0){ if(!wantrecord){ sf_floatwrite(record[0][0], shtnmb*ng*nt, Frcd); } sf_floatwrite(img1[0][0], ntau*nx*nz, Fimg1); sf_floatwrite(img2[0], nx*nz, Fimg2); } tend=clock(); duration=(double)(tend-tstart)/CLOCKS_PER_SEC; sf_warning(">>The CPU time of sfmpilfdrtm2 is: %f seconds<<", duration); MPI_Finalize(); exit(0); }
int main (int argc, char* argv[]) { bool verb, fsrf, snap, expl, dabc; int jsnap, ntsnap, jdata; /* I/O files */ sf_file Fwav = NULL; /* wavelet */ sf_file Fsou = NULL; /* sources */ sf_file Frec = NULL; /* receivers */ sf_file Fvel = NULL; /* velocity */ sf_file Fden = NULL; /* density */ sf_file Fdat = NULL; /* data */ sf_file Fwfl = NULL; /* wavefield */ /* cube axes */ sf_axis at, az, ax; sf_axis as, ar; int cpuid; int nt, nz, nx, ns, nr; int it, ia; float dt, dz, dx; /* FDM structure */ /* Wee keep these structures for compatibility, as soon as PETSC version is finished, this will be removed */ fdm2d fdm = NULL; /* I/O arrays */ float *ww = NULL; /* wavelet */ pt2d *ss = NULL; /* sources */ pt2d *rr = NULL; /* receivers */ float *dd = NULL; /* data */ float **u,**v; /* linear interpolation weights/indices */ lint2d cs,cr; /* wavefield cut params */ sf_axis acz = NULL, acx = NULL; int nqz, nqx; float oqz, oqx; float dqz, dqx; float **uc = NULL; sf_petsc_aimplfd2 aimplfd; PetscErrorCode ierr; /* PETSc Initialization */ ierr = PetscInitialize (&argc, &argv, 0, 0); CHKERRQ(ierr); MPI_Comm_rank (MPI_COMM_WORLD, &cpuid); /*------------------------------------------------------------*/ /* init RSF */ sf_init (argc, argv); /*------------------------------------------------------------*/ if (!sf_getbool ("verb", &verb)) verb = false; /* verbosity flag */ if (!sf_getbool ("snap", &snap)) snap = false; /* wavefield snapshots flag */ if (!sf_getbool ("free", &fsrf)) fsrf = false; /* free surface flag */ if (!sf_getbool ("expl", &expl)) expl = false; /* "exploding reflector" */ if (!sf_getbool ("dabc", &dabc)) dabc = false; /* absorbing BC */ /*------------------------------------------------------------*/ /*------------------------------------------------------------*/ /* I/O files */ Fwav = sf_input ("in" ); /* wavelet */ Fvel = sf_input ("vel"); /* velocity */ Fsou = sf_input ("sou"); /* sources */ Frec = sf_input ("rec"); /* receivers */ Fwfl = sf_output("wfl"); /* wavefield */ Fdat = sf_output("out"); /* data */ Fden = sf_input ("den"); /* density */ /*------------------------------------------------------------*/ /* axes */ at = sf_iaxa (Fwav,2); sf_setlabel (at,"t"); if (verb && 0 == cpuid) sf_raxa (at); /* time */ az = sf_iaxa (Fvel,1); sf_setlabel (az,"z"); if (verb && 0 == cpuid) sf_raxa (az); /* depth */ ax = sf_iaxa (Fvel,2); sf_setlabel (ax,"x"); if (verb && 0 == cpuid) sf_raxa (ax); /* space */ as = sf_iaxa (Fsou, 2); sf_setlabel (as, "s"); if (verb && 0 == cpuid) sf_raxa (as); /* sources */ ar = sf_iaxa (Frec, 2); sf_setlabel (ar, "r"); if (verb && 0 == cpuid) sf_raxa (ar); /* receivers */ nt = sf_n (at); dt = sf_d (at); nz = sf_n (az); dz = sf_d (az); nx = sf_n (ax); dx = sf_d (ax); ns = sf_n (as); nr = sf_n (ar); /*------------------------------------------------------------*/ /*------------------------------------------------------------*/ /* other execution parameters */ if (!sf_getint ("jdata", &jdata)) jdata = 1; if (snap) { /* save wavefield every *jsnap* time steps */ if (!sf_getint ("jsnap", &jsnap)) jsnap = nt; } /*------------------------------------------------------------*/ /*------------------------------------------------------------*/ /* expand domain for FD operators and ABC */ /*if (!sf_getint("nb",&nb) || nb<NOP) nb=NOP;*/ fdm = fdutil_init (verb, true, az, ax, 0, 1); /*------------------------------------------------------------*/ if (0 == cpuid) { sf_setn (az, fdm->nzpad); sf_seto (az, fdm->ozpad); if(verb) sf_raxa (az); sf_setn (ax, fdm->nxpad); sf_seto (ax, fdm->oxpad); if(verb) sf_raxa (ax); /*------------------------------------------------------------*/ /*------------------------------------------------------------*/ /* setup output data header */ sf_oaxa (Fdat, ar, 1); sf_setn (at, nt/jdata); sf_setd (at, dt*jdata); sf_oaxa (Fdat, at, 2); } /* setup output wavefield header */ if (snap && 0 == cpuid) { if (!sf_getint ("nqz", &nqz)) nqz = sf_n (az); if (!sf_getint ("nqx", &nqx)) nqx = sf_n (ax); if (!sf_getfloat ("oqz", &oqz)) oqz = sf_o (az); if (!sf_getfloat ("oqx", &oqx)) oqx = sf_o (ax); dqz = sf_d (az); dqx = sf_d (ax); acz = sf_maxa (nqz, oqz, dqz); sf_raxa (acz); acx = sf_maxa (nqx, oqx, dqx); sf_raxa (acx); /* check if the imaging window fits in the wavefield domain */ uc = sf_floatalloc2 (sf_n (acz), sf_n (acx)); ntsnap = 0; for (it = 0; it < nt; it++) { if (it % jsnap == 0) ntsnap++; } sf_setn (at, ntsnap); sf_setd (at, dt*jsnap); if (verb) sf_raxa(at); sf_oaxa (Fwfl, acz, 1); sf_oaxa (Fwfl, acx, 2); sf_oaxa (Fwfl, at, 3); } if (expl) { ww = sf_floatalloc (1); } else { ww = sf_floatalloc (ns); } dd = sf_floatalloc (nr); /*------------------------------------------------------------*/ /* setup source/receiver coordinates */ ss = (pt2d*) sf_alloc (ns, sizeof (*ss)); rr = (pt2d*) sf_alloc (nr, sizeof (*rr)); pt2dread1 (Fsou, ss, ns, 2); /* read (x,z) coordinates */ pt2dread1 (Frec, rr, nr, 2); /* read (x,z) coordinates */ cs = lint2d_make (ns, ss, fdm); cr = lint2d_make (nr, rr, fdm); v = sf_floatalloc2 (nz, nx); u = sf_floatalloc2 (nz, nx); /* input velocity */ sf_floatread (v[0], nz*nx, Fvel); /*------------------------------------------------------------*/ PetscFPrintf (MPI_COMM_WORLD, stderr, "Initializing GMRES solver\n"); aimplfd = sf_petsc_aimplfd2_init (nz, nx, dz, dx, dt, &v[0][0], 100, true); /*------------------------------------------------------------*/ /* * MAIN LOOP */ /*------------------------------------------------------------*/ for (it = 0; it < nt; it++) { PetscFPrintf (MPI_COMM_WORLD, stderr, "Timestep #%d, t=%f\n", it, it*dt); sf_petsc_aimplfd2_next_step (aimplfd); /* inject acceleration source */ if (expl) { sf_floatread (ww, 1, Fwav); for (ia = 0; ia < cs->n; ia++) { sf_petsc_aimplfd2_add_source_ut1 (aimplfd, ww[0], cs->jz[ia], cs->jx[ia]); } } else { sf_floatread (ww, ns, Fwav); for (ia = 0; ia < cs->n; ia++) { /* PetscFPrintf (MPI_COMM_WORLD, stderr, "Source #%d [%d, %d], f=%f\n", ia, cs->jz[ia], cs->jx[ia], ww[0]); */ sf_petsc_aimplfd2_add_source_ut1 (aimplfd, ww[ia], cs->jz[ia], cs->jx[ia]); } } sf_petsc_aimplfd2_get_wavefield_ut2 (aimplfd, &u[0][0]); /* extract data */ /* lint2d_extract (u, dd, cr); */ for (ia = 0; ia < cr->n; ia++) { dd[ia] = u[cr->jx[ia]][cr->jz[ia]]; } if (snap && it % jsnap == 0 && 0 == cpuid) { cut2d (u, uc, fdm, acz, acx); sf_floatwrite (uc[0], sf_n(acz)*sf_n(acx), Fwfl); } if (it % jdata == 0 && 0 == cpuid) sf_floatwrite (dd, nr, Fdat); } exit (0); }
int main(int argc, char* argv[]) { /*------------------------------------------------------------*/ /* Execution control, I/O files and geometry */ /*------------------------------------------------------------*/ bool verb,fsrf,snap,back,esou; /* execution flags */ int jsnap,ntsnap,jdata; /* jump along axes */ int shft; /* time shift for wavefield matching in RTM */ /* I/O files */ sf_file Fwav=NULL; /* wavelet */ sf_file Fdat=NULL; /* data */ sf_file Fsou=NULL; /* sources */ sf_file Frec=NULL; /* receivers */ sf_file Fccc=NULL; /* velocity */ sf_file Frkp=NULL; /* app. rank */ sf_file Fltp=NULL; /* left mat */ sf_file Frtp=NULL; /* right mat */ sf_file Fwfp=NULL; /* wavefield */ sf_file Frks=NULL; /* app. rank */ sf_file Flts=NULL; /* left mat */ sf_file Frts=NULL; /* right mat */ sf_file Fwfs=NULL; /* wavefield */ /* cube axes */ sf_axis at,ax,ay,az; /* time, x, y, z */ sf_axis asx,asy,arx,ary,ac; /* sou, rec-x, rec-y, component */ /* dimension, index and interval */ int nt,nz,nx,ny,ns,nr,nc,nb; int it,iz,ix,iy; float dt,dz,dx,dy; int nxyz, nk; /* FDM and KSP structure */ //!!!JS fdm3d fdm=NULL; dft3d dft=NULL; clr3d clr_p=NULL, clr_s=NULL; /* I/O arrays for sou & rec */ sf_complex***ww=NULL; /* wavelet */ pt3d *ss=NULL; /* sources */ pt3d *rr=NULL; /* receivers */ sf_complex **dd=NULL; /* data */ /*------------------------------------------------------------*/ /* displacement: uo = U @ t; up = U @ t+1 */ /*------------------------------------------------------------*/ sf_complex ***uox, ***uoy, ***uoz, **uo; sf_complex ***uox_p, ***uoy_p, ***uoz_p, **uo_p; sf_complex ***uox_s, ***uoy_s, ***uoz_s, **uo_s; /*sf_complex ***upx, ***upy, ***upz, **up;*/ /*------------------------------------------------------------*/ /* lowrank decomposition arrays */ /*------------------------------------------------------------*/ int ntmp, *n2s_p, *n2s_s; sf_complex **lt_p, **rt_p, **lt_s, **rt_s; /*------------------------------------------------------------*/ /* linear interpolation weights/indices */ /*------------------------------------------------------------*/ lint3d cs,cr; /* for injecting source and extracting data */ /* Gaussian bell */ int nbell; /*------------------------------------------------------------*/ /* wavefield cut params */ /*------------------------------------------------------------*/ sf_axis acz=NULL,acx=NULL,acy=NULL; int nqz,nqx,nqy; float oqz,oqx,oqy; float dqz,dqx,dqy; sf_complex***uc=NULL; /* tmp array for output wavefield snaps */ /*------------------------------------------------------------*/ /* init RSF */ /*------------------------------------------------------------*/ sf_init(argc,argv); /*------------------------------------------------------------*/ /* OMP parameters */ /*------------------------------------------------------------*/ #ifdef _OPENMP omp_init(); #endif /*------------------------------------------------------------*/ /* read execution flags */ /*------------------------------------------------------------*/ if(! sf_getbool("verb",&verb)) verb=false; /* verbosity flag */ if(! sf_getbool("snap",&snap)) snap=false; /* wavefield snapshots flag */ if(! sf_getbool("free",&fsrf)) fsrf=false; /* free surface flag */ if(! sf_getbool("back",&back)) back=false; /* backward extrapolation flag (for rtm) */ if(! sf_getbool("esou",&esou)) esou=false; /* explosive force source */ /*------------------------------------------------------------*/ /* I/O files */ /*------------------------------------------------------------*/ Fwav = sf_input ("in" ); /* wavelet */ Fdat = sf_output("out"); /* data */ Fsou = sf_input ("sou"); /* sources */ Frec = sf_input ("rec"); /* receivers */ Fccc = sf_input ("ccc"); /* stiffness */ Frkp = sf_input ("rkp"); /* app. rank */ Fltp = sf_input ("ltp"); /* left mat */ Frtp = sf_input ("rtp"); /* right mat */ Fwfp = sf_output("wfp"); /* wavefield */ Frks = sf_input ("rks"); /* app. rank */ Flts = sf_input ("lts"); /* left mat */ Frts = sf_input ("rts"); /* right mat */ Fwfs = sf_output("wfs"); /* wavefield */ /*------------------------------------------------------------*/ /* axes */ /*------------------------------------------------------------*/ at = sf_iaxa(Fwav,4); sf_setlabel(at,"t"); if(verb) sf_raxa(at); /* time */ az = sf_iaxa(Fccc,1); sf_setlabel(az,"z"); if(verb) sf_raxa(az); /* depth */ ax = sf_iaxa(Fccc,2); sf_setlabel(ax,"x"); if(verb) sf_raxa(ax); /* space x */ ay = sf_iaxa(Fccc,3); sf_setlabel(ay,"y"); if(verb) sf_raxa(ay); /* space y */ asx = sf_iaxa(Fsou,2); sf_setlabel(asx,"sx"); if(verb) sf_raxa(asx); /* sources x */ asy = sf_iaxa(Fsou,3); sf_setlabel(asy,"sy"); if(verb) sf_raxa(asy); /* sources y */ arx = sf_iaxa(Frec,2); sf_setlabel(arx,"rx"); if(verb) sf_raxa(arx); /* receivers x */ ary = sf_iaxa(Frec,3); sf_setlabel(ary,"ry"); if(verb) sf_raxa(ary); /* receivers y */ nt = sf_n(at); dt = sf_d(at); nz = sf_n(az); dz = sf_d(az); nx = sf_n(ax); dx = sf_d(ax); ny = sf_n(ay); dy = sf_d(ay); ns = sf_n(asx)*sf_n(asy); nr = sf_n(arx)*sf_n(ary); /*------------------------------------------------------------*/ /* other execution parameters */ /*------------------------------------------------------------*/ if(! sf_getint("nbell",&nbell)) nbell=NOP; /* bell size */ if(verb) sf_warning("nbell=%d",nbell); if(! sf_getint("jdata",&jdata)) jdata=1; if(snap) { /* save wavefield every *jsnap* time steps */ if(! sf_getint("jsnap",&jsnap)) jsnap=nt; } if(back) { shft = (nt-1)%jsnap; sf_warning("For backward extrapolation, make sure nbell(%d)=0",nbell); } else shft = 0; /*------------------------------------------------------------*/ /* expand domain for FD operators and ABC */ /*------------------------------------------------------------*/ if( !sf_getint("nb",&nb)) nb=NOP; fdm=fdutil3d_init(verb,fsrf,az,ax,ay,nb,1); if(nbell) fdbell3d_init(nbell); sf_setn(az,fdm->nzpad); sf_seto(az,fdm->ozpad); if(verb) sf_raxa(az); sf_setn(ax,fdm->nxpad); sf_seto(ax,fdm->oxpad); if(verb) sf_raxa(ax); sf_setn(ay,fdm->nypad); sf_seto(ay,fdm->oypad); if(verb) sf_raxa(ay); /*------------------------------------------------------------*/ /* 3D vector components */ /*------------------------------------------------------------*/ nc=3; ac=sf_maxa(nc,0,1); /* output 3 cartesian components */ /*------------------------------------------------------------*/ /* setup output data header */ /*------------------------------------------------------------*/ sf_settype(Fdat,SF_COMPLEX); sf_oaxa(Fdat,arx,1); sf_oaxa(Fdat,ary,2); sf_oaxa(Fdat,ac,3); sf_setn(at,nt/jdata); sf_setd(at,dt*jdata); sf_oaxa(Fdat,at,4); /* setup output wavefield header */ if(snap) { if(!sf_getint ("nqz",&nqz)) nqz=sf_n(az); if(!sf_getint ("nqx",&nqx)) nqx=sf_n(ax); if(!sf_getint ("nqy",&nqy)) nqy=sf_n(ay); if(!sf_getfloat("oqz",&oqz)) oqz=sf_o(az); if(!sf_getfloat("oqx",&oqx)) oqx=sf_o(ax); if(!sf_getfloat("oqy",&oqy)) oqy=sf_o(ay); dqz=sf_d(az); dqx=sf_d(ax); dqy=sf_d(ay); acz = sf_maxa(nqz,oqz,dqz); sf_raxa(acz); acx = sf_maxa(nqx,oqx,dqx); sf_raxa(acx); acy = sf_maxa(nqy,oqy,dqy); sf_raxa(acy); uc=sf_complexalloc3(sf_n(acz),sf_n(acx),sf_n(acy)); ntsnap=0; /* ntsnap = it/jsnap+1; */ for(it=0; it<nt; it++) { if(it%jsnap==0) ntsnap++; } sf_setn(at, ntsnap); sf_setd(at,dt*jsnap); if(verb) sf_raxa(at); sf_settype(Fwfp,SF_COMPLEX); sf_oaxa(Fwfp,acz,1); sf_oaxa(Fwfp,acx,2); sf_oaxa(Fwfp,acy,3); sf_oaxa(Fwfp,ac, 4); sf_oaxa(Fwfp,at, 5); sf_settype(Fwfs,SF_COMPLEX); sf_oaxa(Fwfs,acz,1); sf_oaxa(Fwfs,acx,2); sf_oaxa(Fwfs,acy,3); sf_oaxa(Fwfs,ac, 4); sf_oaxa(Fwfs,at, 5); } /*------------------------------------------------------------*/ /* source and data array */ /*------------------------------------------------------------*/ ww=sf_complexalloc3(ns,nc,nt); /* Fast axis: n_sou > n_comp > n_time */ sf_complexread(ww[0][0],nt*nc*ns,Fwav); dd=sf_complexalloc2(nr,nc); /*------------------------------------------------------------*/ /* setup source/receiver coordinates */ /*------------------------------------------------------------*/ ss = (pt3d*) sf_alloc(ns,sizeof(*ss)); rr = (pt3d*) sf_alloc(nr,sizeof(*rr)); pt3dread1(Fsou,ss,ns,3); /* read (x,y,z) coordinates */ pt3dread1(Frec,rr,nr,3); /* read (x,y,z) coordinates */ /* calculate 3d linear interpolation coef for sou & rec */ cs = lint3d_make(ns,ss,fdm); cr = lint3d_make(nr,rr,fdm); /*------------------------------------------------------------*/ /* allocate and initialize wavefield arrays */ /*------------------------------------------------------------*/ /* z-component */ uoz=sf_complexalloc3(fdm->nzpad,fdm->nxpad,fdm->nypad); uoz_p=sf_complexalloc3(fdm->nzpad,fdm->nxpad,fdm->nypad); uoz_s=sf_complexalloc3(fdm->nzpad,fdm->nxpad,fdm->nypad); /*upz=sf_complexalloc3(fdm->nzpad,fdm->nxpad,fdm->nypad);*/ /* x-component */ uox=sf_complexalloc3(fdm->nzpad,fdm->nxpad,fdm->nypad); uox_p=sf_complexalloc3(fdm->nzpad,fdm->nxpad,fdm->nypad); uox_s=sf_complexalloc3(fdm->nzpad,fdm->nxpad,fdm->nypad); /*upx=sf_complexalloc3(fdm->nzpad,fdm->nxpad,fdm->nypad);*/ /* y-component */ uoy=sf_complexalloc3(fdm->nzpad,fdm->nxpad,fdm->nypad); uoy_p=sf_complexalloc3(fdm->nzpad,fdm->nxpad,fdm->nypad); uoy_s=sf_complexalloc3(fdm->nzpad,fdm->nxpad,fdm->nypad); /*upy=sf_complexalloc3(fdm->nzpad,fdm->nxpad,fdm->nypad);*/ /* wavefield vector */ uo = (sf_complex**) sf_alloc(3,sizeof(sf_complex*)); uo[0] = uox[0][0]; uo[1] = uoy[0][0]; uo[2] = uoz[0][0]; uo_p = (sf_complex**) sf_alloc(3,sizeof(sf_complex*)); uo_p[0] = uox_p[0][0]; uo_p[1] = uoy_p[0][0]; uo_p[2] = uoz_p[0][0]; uo_s = (sf_complex**) sf_alloc(3,sizeof(sf_complex*)); uo_s[0] = uox_s[0][0]; uo_s[1] = uoy_s[0][0]; uo_s[2] = uoz_s[0][0]; /*up = (sf_complex**) sf_alloc(3,sizeof(sf_complex*));*/ /*up[0] = upx[0][0]; up[1] = upy[0][0]; up[2] = upz[0][0];*/ /* initialize fft and lrk */ dft = dft3d_init(1,false,false,fdm); nxyz= fdm->nypad*fdm->nxpad*fdm->nzpad; nk = dft->nky *dft->nkx *dft->nkz; /*------------------------------------------------------------*/ /* allocation I/O arrays */ /*------------------------------------------------------------*/ n2s_p = sf_intalloc(9); sf_intread(n2s_p,9,Frkp); clr_p = clr3d_make2(n2s_p,fdm); n2s_s = sf_intalloc(9); sf_intread(n2s_s,9,Frks); clr_s = clr3d_make2(n2s_s,fdm); if (clr_p->n2_max > clr_s->n2_max) clr3d_init(fdm,dft,clr_p); else clr3d_init(fdm,dft,clr_s); /* check the dimension */ if (!sf_histint(Fltp,"n1",&ntmp) || ntmp != nxyz) sf_error("Need n1=%d in left",nxyz); if (!sf_histint(Fltp,"n2",&ntmp) || ntmp != clr_p->n2_sum) sf_error("Need n2=%d in left",clr_p->n2_sum); if (!sf_histint(Frtp,"n1",&ntmp) || ntmp != nk) sf_error("Need n1=%d in right",nk); if (!sf_histint(Frtp,"n2",&ntmp) || ntmp != clr_p->n2_sum) sf_error("Need n2=%d in right",clr_p->n2_sum); lt_p = sf_complexalloc2(nxyz,clr_p->n2_sum); rt_p = sf_complexalloc2(nk ,clr_p->n2_sum); sf_complexread(lt_p[0],nxyz*clr_p->n2_sum,Fltp); sf_complexread(rt_p[0],nk *clr_p->n2_sum,Frtp); if (!sf_histint(Flts,"n1",&ntmp) || ntmp != nxyz) sf_error("Need n1=%d in left",nxyz); if (!sf_histint(Flts,"n2",&ntmp) || ntmp != clr_s->n2_sum) sf_error("Need n2=%d in left",clr_s->n2_sum); if (!sf_histint(Frts,"n1",&ntmp) || ntmp != nk) sf_error("Need n1=%d in right",nk); if (!sf_histint(Frts,"n2",&ntmp) || ntmp != clr_s->n2_sum) sf_error("Need n2=%d in right",clr_s->n2_sum); lt_s = sf_complexalloc2(nxyz,clr_s->n2_sum); rt_s = sf_complexalloc2(nk ,clr_s->n2_sum); sf_complexread(lt_s[0],nxyz*clr_s->n2_sum,Flts); sf_complexread(rt_s[0],nk *clr_s->n2_sum,Frts); /* initialize to zero */ #ifdef _OPENMP #pragma omp parallel for \ schedule(dynamic,1) \ private(iy,ix,iz) \ shared(fdm,uoz,uox,uoy,uoz_p,uox_p,uoy_p,uoz_s,uox_s,uoy_s) #endif for (iy=0; iy<fdm->nypad; iy++) { for (ix=0; ix<fdm->nxpad; ix++) { for(iz=0; iz<fdm->nzpad; iz++) { uoz [iy][ix][iz]=sf_cmplx(0.,0.); uox [iy][ix][iz]=sf_cmplx(0.,0.); uoy [iy][ix][iz]=sf_cmplx(0.,0.); uoz_p[iy][ix][iz]=sf_cmplx(0.,0.); uox_p[iy][ix][iz]=sf_cmplx(0.,0.); uoy_p[iy][ix][iz]=sf_cmplx(0.,0.); uoz_s[iy][ix][iz]=sf_cmplx(0.,0.); uox_s[iy][ix][iz]=sf_cmplx(0.,0.); uoy_s[iy][ix][iz]=sf_cmplx(0.,0.); /*upz[iy][ix][iz]=sf_cmplx(0.,0.); upx[iy][ix][iz]=sf_cmplx(0.,0.); upy[iy][ix][iz]=sf_cmplx(0.,0.);*/ } } } /*------------------------------------------------------------*/ /*------------------------ MAIN LOOP -------------------------*/ /*------------------------------------------------------------*/ if(verb) fprintf(stderr,"\n"); for (it=0; it<nt; it++) { if(verb) sf_warning("it=%d/%d;",it,nt); /*fprintf(stderr,"\b\b\b\b\b%d",it);*/ /*------------------------------------------------------------*/ /* apply lowrank matrix to wavefield vector */ /*------------------------------------------------------------*/ clr3d_apply(uo_p, uo, lt_p, rt_p, fdm, dft, clr_p); clr3d_apply(uo_s, uo, lt_s, rt_s, fdm, dft, clr_s); /*------------------------------------------------------------*/ /* combine P and S wave modes */ /*------------------------------------------------------------*/ #ifdef _OPENMP #pragma omp parallel for \ schedule(dynamic,1) \ private(iy,ix,iz) \ shared(fdm,uoz,uox,uoy,uoz_p,uox_p,uoy_p,uoz_s,uox_s,uoy_s) #endif for (iy=0; iy<fdm->nypad; iy++) { for (ix=0; ix<fdm->nxpad; ix++) { for(iz=0; iz<fdm->nzpad; iz++) { uoz[iy][ix][iz] = uoz_p[iy][ix][iz] + uoz_s[iy][ix][iz]; uox[iy][ix][iz] = uox_p[iy][ix][iz] + uox_s[iy][ix][iz]; uoy[iy][ix][iz] = uoy_p[iy][ix][iz] + uoy_s[iy][ix][iz]; /*upz[iy][ix][iz]=sf_cmplx(0.,0.); upx[iy][ix][iz]=sf_cmplx(0.,0.); upy[iy][ix][iz]=sf_cmplx(0.,0.);*/ } } } /*------------------------------------------------------------*/ /* free surface */ /*------------------------------------------------------------*/ if(fsrf) { /* need to do something here */ } /*------------------------------------------------------------*/ /* inject displacement source */ /*------------------------------------------------------------*/ if(esou) { /* exploding force source */ lint3d_expl_complex(uoz,uox,uoy,ww[it],cs); } else { if(nbell) { lint3d_bell_complex(uoz,ww[it][0],cs); lint3d_bell_complex(uox,ww[it][1],cs); lint3d_bell_complex(uoy,ww[it][2],cs); } else { lint3d_inject_complex(uoz,ww[it][0],cs); lint3d_inject_complex(uox,ww[it][1],cs); lint3d_inject_complex(uoy,ww[it][2],cs); } } /*------------------------------------------------------------*/ /* cut wavefield and save */ /*------------------------------------------------------------*/ if(snap && (it-shft)%jsnap==0) { /* P wave */ cut3d_complex(uoz_p,uc,fdm,acz,acx,acy); sf_complexwrite(uc[0][0],sf_n(acx)*sf_n(acy)*sf_n(acz),Fwfp); cut3d_complex(uox_p,uc,fdm,acz,acx,acy); sf_complexwrite(uc[0][0],sf_n(acx)*sf_n(acy)*sf_n(acz),Fwfp); cut3d_complex(uoy_p,uc,fdm,acz,acx,acy); sf_complexwrite(uc[0][0],sf_n(acx)*sf_n(acy)*sf_n(acz),Fwfp); /* S wave */ cut3d_complex(uoz_s,uc,fdm,acz,acx,acy); sf_complexwrite(uc[0][0],sf_n(acx)*sf_n(acy)*sf_n(acz),Fwfs); cut3d_complex(uox_s,uc,fdm,acz,acx,acy); sf_complexwrite(uc[0][0],sf_n(acx)*sf_n(acy)*sf_n(acz),Fwfs); cut3d_complex(uoy_s,uc,fdm,acz,acx,acy); sf_complexwrite(uc[0][0],sf_n(acx)*sf_n(acy)*sf_n(acz),Fwfs); } lint3d_extract_complex(uoz,dd[0],cr); lint3d_extract_complex(uox,dd[1],cr); lint3d_extract_complex(uoy,dd[2],cr); if(it%jdata==0) sf_complexwrite(dd[0],nr*nc,Fdat); } if(verb) sf_warning("."); if(verb) fprintf(stderr,"\n"); /*------------------------------------------------------------*/ /* deallocate arrays */ free(dft); dft3d_finalize(); free(clr_p); free(clr_s); clr3d_finalize(); free(**ww); free(*ww); free(ww); free(ss); free(rr); free(*dd); free(dd); free(n2s_p); free(n2s_s); free(*lt_p); free(lt_p); free(*rt_p); free(rt_p); free(*lt_s); free(lt_s); free(*rt_s); free(rt_s); free(**uoz ); free(*uoz ); free(uoz) ; free(**uoz_p); free(*uoz_p); free(uoz_p); free(**uoz_s); free(*uoz_s); free(uoz_s); /*free(**upz); free(*upz); free(upz);*/ free(uo); free(uo_p); free(uo_s); /*free(up);*/ if (snap) { free(**uc); free(*uc); free(uc); } /*------------------------------------------------------------*/ exit (0); }
int main(int argc, char* argv[]) { bool verb,fsrf,snap,ssou,dabc,opot; int jsnap,ntsnap,jdata; /* I/O files */ sf_file Fwav=NULL; /* wavelet */ sf_file Fsou=NULL; /* sources */ sf_file Frec=NULL; /* receivers */ sf_file Fccc=NULL; /* velocity */ sf_file Fden=NULL; /* density */ sf_file Fdat=NULL; /* data */ sf_file Fwfl=NULL; /* wavefield */ /* cube axes */ sf_axis at,ax,ay,az; sf_axis as,ar,ac; int nt,nz,nx,ny,ns,nr,nc,nb; int it,iz,ix,iy; float dt,dz,dx,dy,idz,idx,idy; /* FDM structure */ fdm3d fdm=NULL; abcone3d /* abcp=NULL, */ abcs=NULL; sponge spo=NULL; /* I/O arrays */ float***ww=NULL; /* wavelet */ pt3d *ss=NULL; /* sources */ pt3d *rr=NULL; /* receivers */ float **dd=NULL; /* data */ /*------------------------------------------------------------*/ float ***tt=NULL; float ***ro=NULL; /* density */ /* orthorombic footprint - 9 coefficients */ /* c11 c12 c13 . c22 c23 . . c33 c44 c55 c66 */ float ***c11=NULL; float ***c22=NULL; float ***c33=NULL; float ***c44=NULL; float ***c55=NULL; float ***c66=NULL; float ***c12=NULL; float ***c13=NULL; float ***c23=NULL; float ***vp,***vs; float ***qp=NULL,***qsx=NULL,***qsy=NULL,***qsz=NULL; /*------------------------------------------------------------*/ /* displacement: um = U @ t-1; uo = U @ t; up = U @ t+1 */ float ***umz,***uoz,***upz,***uaz,***utz; float ***umx,***uox,***upx,***uax,***utx; float ***umy,***uoy,***upy,***uay,***uty; /* stress/strain tensor */ float ***tzz,***txx,***tyy,***txy,***tyz,***tzx; float szz, sxx, syy, sxy, syz, szx; /*------------------------------------------------------------*/ /* linear interpolation weights/indices */ lint3d cs,cr; /* Gaussian bell */ int nbell; /* wavefield cut params */ sf_axis acz=NULL,acx=NULL,acy=NULL; int nqz,nqx,nqy; float oqz,oqx,oqy; float dqz,dqx,dqy; float ***uc=NULL; /*------------------------------------------------------------*/ /* init RSF */ sf_init(argc,argv); /*------------------------------------------------------------*/ /* OMP parameters */ #ifdef _OPENMP omp_init(); #endif /*------------------------------------------------------------*/ /*------------------------------------------------------------*/ /* execution flags */ if(! sf_getbool("verb",&verb)) verb=false; /* verbosity flag */ if(! sf_getbool("snap",&snap)) snap=false; /* wavefield snapshots flag */ if(! sf_getbool("free",&fsrf)) fsrf=false; /* free surface flag */ if(! sf_getbool("ssou",&ssou)) ssou=false; /* stress source */ if(! sf_getbool("dabc",&dabc)) dabc=false; /* absorbing BC */ if(! sf_getbool("opot",&opot)) opot=false; /* output potentials */ /*------------------------------------------------------------*/ /*------------------------------------------------------------*/ /* I/O files */ Fwav = sf_input ("in" ); /* wavelet */ Fccc = sf_input ("ccc"); /* stiffness */ Fden = sf_input ("den"); /* density */ Fsou = sf_input ("sou"); /* sources */ Frec = sf_input ("rec"); /* receivers */ Fwfl = sf_output("wfl"); /* wavefield */ Fdat = sf_output("out"); /* data */ /*------------------------------------------------------------*/ /*------------------------------------------------------------*/ /* axes */ at = sf_iaxa(Fwav,3); sf_setlabel(at,"t"); if(verb) sf_raxa(at); /* time */ az = sf_iaxa(Fccc,1); sf_setlabel(az,"z"); if(verb) sf_raxa(az); /* depth */ ax = sf_iaxa(Fccc,2); sf_setlabel(ax,"x"); if(verb) sf_raxa(ax); /* space x */ ay = sf_iaxa(Fccc,3); sf_setlabel(ay,"y"); if(verb) sf_raxa(ay); /* space y */ as = sf_iaxa(Fsou,2); sf_setlabel(as,"s"); if(verb) sf_raxa(as); /* sources */ ar = sf_iaxa(Frec,2); sf_setlabel(ar,"r"); if(verb) sf_raxa(ar); /* receivers */ nt = sf_n(at); dt = sf_d(at); nz = sf_n(az); dz = sf_d(az); nx = sf_n(ax); dx = sf_d(ax); ny = sf_n(ay); dy = sf_d(ay); ns = sf_n(as); nr = sf_n(ar); /*------------------------------------------------------------*/ /*------------------------------------------------------------*/ /* other execution parameters */ if(! sf_getint("nbell",&nbell)) nbell=5; /* bell size */ if(verb) sf_warning("nbell=%d",nbell); if(! sf_getint("jdata",&jdata)) jdata=1; if(snap) { /* save wavefield every *jsnap* time steps */ if(! sf_getint("jsnap",&jsnap)) jsnap=nt; } /*------------------------------------------------------------*/ /*------------------------------------------------------------*/ /* expand domain for FD operators and ABC */ if( !sf_getint("nb",&nb) || nb<NOP) nb=NOP; fdm=fdutil3d_init(verb,fsrf,az,ax,ay,nb,1); fdbell3d_init(nbell); sf_setn(az,fdm->nzpad); sf_seto(az,fdm->ozpad); if(verb) sf_raxa(az); sf_setn(ax,fdm->nxpad); sf_seto(ax,fdm->oxpad); if(verb) sf_raxa(ax); sf_setn(ay,fdm->nypad); sf_seto(ay,fdm->oypad); if(verb) sf_raxa(ay); /*------------------------------------------------------------*/ /* 3D vector components */ nc=3; if(opot) { ac=sf_maxa(nc+1,0,1); } else { ac=sf_maxa(nc ,0,1); } /*------------------------------------------------------------*/ /* setup output data header */ sf_oaxa(Fdat,ar,1); sf_oaxa(Fdat,ac,2); sf_setn(at,nt/jdata); sf_setd(at,dt*jdata); sf_oaxa(Fdat,at,3); /* setup output wavefield header */ if(snap) { if(!sf_getint ("nqz",&nqz)) nqz=sf_n(az); if(!sf_getint ("nqx",&nqx)) nqx=sf_n(ax); if(!sf_getint ("nqy",&nqy)) nqy=sf_n(ay); if(!sf_getfloat("oqz",&oqz)) oqz=sf_o(az); if(!sf_getfloat("oqx",&oqx)) oqx=sf_o(ax); if(!sf_getfloat("oqy",&oqy)) oqy=sf_o(ay); dqz=sf_d(az); dqx=sf_d(ax); dqy=sf_d(ay); acz = sf_maxa(nqz,oqz,dqz); sf_raxa(acz); acx = sf_maxa(nqx,oqx,dqx); sf_raxa(acx); acy = sf_maxa(nqy,oqy,dqy); sf_raxa(acy); /* TODO: check if the imaging window fits in the wavefield domain */ uc=sf_floatalloc3(sf_n(acz),sf_n(acx),sf_n(acy)); ntsnap=0; for(it=0; it<nt; it++) { if(it%jsnap==0) ntsnap++; } sf_setn(at, ntsnap); sf_setd(at,dt*jsnap); if(verb) sf_raxa(at); sf_oaxa(Fwfl,acz,1); sf_oaxa(Fwfl,acx,2); sf_oaxa(Fwfl,acy,3); sf_oaxa(Fwfl,ac, 4); sf_oaxa(Fwfl,at, 5); } /*------------------------------------------------------------*/ /* source array */ ww=sf_floatalloc3(ns,nc,nt); sf_floatread(ww[0][0],nt*nc*ns,Fwav); /* data array */ if(opot) { dd=sf_floatalloc2(nr,nc+1); } else { dd=sf_floatalloc2(nr,nc ); } /*------------------------------------------------------------*/ /* setup source/receiver coordinates */ ss = (pt3d*) sf_alloc(ns,sizeof(*ss)); rr = (pt3d*) sf_alloc(nr,sizeof(*rr)); pt3dread1(Fsou,ss,ns,3); /* read (x,y,z) coordinates */ pt3dread1(Frec,rr,nr,3); /* read (x,y,z) coordinates */ cs = lint3d_make(ns,ss,fdm); cr = lint3d_make(nr,rr,fdm); /*------------------------------------------------------------*/ /* setup FD coefficients */ /* idz = 2/dz;*/ /* idx = 2/dx;*/ /* idy = 2/dy;*/ idz = 1/dz; idx = 1/dx; idy = 1/dy; /*------------------------------------------------------------*/ tt = sf_floatalloc3(nz,nx,ny); ro =sf_floatalloc3(fdm->nzpad,fdm->nxpad,fdm->nypad); c11=sf_floatalloc3(fdm->nzpad,fdm->nxpad,fdm->nypad); c22=sf_floatalloc3(fdm->nzpad,fdm->nxpad,fdm->nypad); c33=sf_floatalloc3(fdm->nzpad,fdm->nxpad,fdm->nypad); c44=sf_floatalloc3(fdm->nzpad,fdm->nxpad,fdm->nypad); c55=sf_floatalloc3(fdm->nzpad,fdm->nxpad,fdm->nypad); c66=sf_floatalloc3(fdm->nzpad,fdm->nxpad,fdm->nypad); c12=sf_floatalloc3(fdm->nzpad,fdm->nxpad,fdm->nypad); c13=sf_floatalloc3(fdm->nzpad,fdm->nxpad,fdm->nypad); c23=sf_floatalloc3(fdm->nzpad,fdm->nxpad,fdm->nypad); /* input density */ sf_floatread(tt[0][0],nz*nx*ny,Fden); expand3d(tt,ro ,fdm); /* input stiffness */ sf_floatread(tt[0][0],nz*nx*ny,Fccc ); expand3d(tt,c11,fdm); sf_floatread(tt[0][0],nz*nx*ny,Fccc ); expand3d(tt,c22,fdm); sf_floatread(tt[0][0],nz*nx*ny,Fccc ); expand3d(tt,c33,fdm); sf_floatread(tt[0][0],nz*nx*ny,Fccc ); expand3d(tt,c44,fdm); sf_floatread(tt[0][0],nz*nx*ny,Fccc ); expand3d(tt,c55,fdm); sf_floatread(tt[0][0],nz*nx*ny,Fccc ); expand3d(tt,c66,fdm); sf_floatread(tt[0][0],nz*nx*ny,Fccc ); expand3d(tt,c12,fdm); sf_floatread(tt[0][0],nz*nx*ny,Fccc ); expand3d(tt,c13,fdm); sf_floatread(tt[0][0],nz*nx*ny,Fccc ); expand3d(tt,c23,fdm); free(**tt); free(*tt); free(tt); /*------------------------------------------------------------*/ if(dabc) { /* one-way abc setup */ vp = sf_floatalloc3(fdm->nzpad,fdm->nxpad,fdm->nypad); vs = sf_floatalloc3(fdm->nzpad,fdm->nxpad,fdm->nypad); for (iy=0; iy<fdm->nypad; iy++) { for (ix=0; ix<fdm->nxpad; ix++) { for(iz=0; iz<fdm->nzpad; iz++) { vp[iy][ix][iz] = sqrt( c11[iy][ix][iz]/ro[iy][ix][iz] ); vs[iy][ix][iz] = sqrt( c55[iy][ix][iz]/ro[iy][ix][iz] ); } } } /* abcp = abcone3d_make(NOP,dt,vp,fsrf,fdm); */ abcs = abcone3d_make(NOP,dt,vs,fsrf,fdm); free(**vp); free(*vp); free(vp); free(**vs); free(*vs); free(vs); /* sponge abc setup */ spo = sponge_make(fdm->nb); } /*------------------------------------------------------------*/ /* precompute 1/ro * dt^2 */ for (iy=0; iy<fdm->nypad; iy++) { for (ix=0; ix<fdm->nxpad; ix++) { for(iz=0; iz<fdm->nzpad; iz++) { ro[iy][ix][iz] = dt*dt/ro[iy][ix][iz]; } } } /*------------------------------------------------------------*/ /* allocate wavefield arrays */ umz=sf_floatalloc3(fdm->nzpad,fdm->nxpad,fdm->nypad); uoz=sf_floatalloc3(fdm->nzpad,fdm->nxpad,fdm->nypad); upz=sf_floatalloc3(fdm->nzpad,fdm->nxpad,fdm->nypad); uaz=sf_floatalloc3(fdm->nzpad,fdm->nxpad,fdm->nypad); umx=sf_floatalloc3(fdm->nzpad,fdm->nxpad,fdm->nypad); uox=sf_floatalloc3(fdm->nzpad,fdm->nxpad,fdm->nypad); upx=sf_floatalloc3(fdm->nzpad,fdm->nxpad,fdm->nypad); uax=sf_floatalloc3(fdm->nzpad,fdm->nxpad,fdm->nypad); umy=sf_floatalloc3(fdm->nzpad,fdm->nxpad,fdm->nypad); uoy=sf_floatalloc3(fdm->nzpad,fdm->nxpad,fdm->nypad); upy=sf_floatalloc3(fdm->nzpad,fdm->nxpad,fdm->nypad); uay=sf_floatalloc3(fdm->nzpad,fdm->nxpad,fdm->nypad); tzz=sf_floatalloc3(fdm->nzpad,fdm->nxpad,fdm->nypad); tyy=sf_floatalloc3(fdm->nzpad,fdm->nxpad,fdm->nypad); txx=sf_floatalloc3(fdm->nzpad,fdm->nxpad,fdm->nypad); txy=sf_floatalloc3(fdm->nzpad,fdm->nxpad,fdm->nypad); tyz=sf_floatalloc3(fdm->nzpad,fdm->nxpad,fdm->nypad); tzx=sf_floatalloc3(fdm->nzpad,fdm->nxpad,fdm->nypad); for (iy=0; iy<fdm->nypad; iy++) { for (ix=0; ix<fdm->nxpad; ix++) { for(iz=0; iz<fdm->nzpad; iz++) { umz[iy][ix][iz]=0; umx[iy][ix][iz]=0; umy[iy][ix][iz]=0; uoz[iy][ix][iz]=0; uox[iy][ix][iz]=0; uoy[iy][ix][iz]=0; upz[iy][ix][iz]=0; upx[iy][ix][iz]=0; upy[iy][ix][iz]=0; uaz[iy][ix][iz]=0; uax[iy][ix][iz]=0; uay[iy][ix][iz]=0; } } } if(opot) { qp =sf_floatalloc3(fdm->nzpad,fdm->nxpad,fdm->nypad); qsx=sf_floatalloc3(fdm->nzpad,fdm->nxpad,fdm->nypad); qsy=sf_floatalloc3(fdm->nzpad,fdm->nxpad,fdm->nypad); qsz=sf_floatalloc3(fdm->nzpad,fdm->nxpad,fdm->nypad); } /*------------------------------------------------------------*/ /* * MAIN LOOP */ /*------------------------------------------------------------*/ if(verb) fprintf(stderr,"\n"); for (it=0; it<nt; it++) { if(verb) fprintf(stderr,"\b\b\b\b\b%d",it); /*------------------------------------------------------------*/ /* from displacement to strain */ /*------------------------------------------------------------*/ /* * exx = Fx(ux) * eyy = Fy(uy) * ezz = Fz(uz) * exy = By(ux) + Bx(uy) * eyz = Bz(uy) + By(uz) * ezx = Bx(uz) + Bz(ux) */ #ifdef _OPENMP #pragma omp parallel for \ schedule(dynamic,fdm->ompchunk) \ private(ix,iy,iz) \ shared(fdm,txx,tyy,tzz,txy,tyz,tzx,uox,uoy,uoz,idx,idy,idz) #endif for (iy=NOP; iy<fdm->nypad-NOP; iy++) { for (ix=NOP; ix<fdm->nxpad-NOP; ix++) { for(iz=NOP; iz<fdm->nzpad-NOP; iz++) { txx[iy][ix][iz] = Dx(uox,ix,iy,iz,idx); tyy[iy][ix][iz] = Dy(uoy,ix,iy,iz,idy); tzz[iy][ix][iz] = Dz(uoz,ix,iy,iz,idz); txy[iy][ix][iz] = Dy(uox,ix,iy,iz,idy) + Dx(uoy,ix,iy,iz,idx); tyz[iy][ix][iz] = Dz(uoy,ix,iy,iz,idz) + Dy(uoz,ix,iy,iz,idy); tzx[iy][ix][iz] = Dx(uoz,ix,iy,iz,idx) + Dz(uox,ix,iy,iz,idz); } } } /*------------------------------------------------------------*/ /* from strain to stress */ /*------------------------------------------------------------*/ #ifdef _OPENMP #pragma omp parallel for \ schedule(dynamic,fdm->ompchunk) \ private(ix,iy,iz,sxx,syy,szz,sxy,syz,szx) \ shared(fdm,txx,tyy,tzz,txy,tyz,tzx,c11,c22,c33,c44,c55,c66,c12,c13,c23) #endif for (iy=0; iy<fdm->nypad; iy++) { for (ix=0; ix<fdm->nxpad; ix++) { for(iz=0; iz<fdm->nzpad; iz++) { sxx = c11[iy][ix][iz] * txx[iy][ix][iz] + c12[iy][ix][iz] * tyy[iy][ix][iz] + c13[iy][ix][iz] * tzz[iy][ix][iz]; syy = c12[iy][ix][iz] * txx[iy][ix][iz] + c22[iy][ix][iz] * tyy[iy][ix][iz] + c23[iy][ix][iz] * tzz[iy][ix][iz]; szz = c13[iy][ix][iz] * txx[iy][ix][iz] + c23[iy][ix][iz] * tyy[iy][ix][iz] + c33[iy][ix][iz] * tzz[iy][ix][iz]; sxy = c66[iy][ix][iz] * txy[iy][ix][iz]; syz = c44[iy][ix][iz] * tyz[iy][ix][iz]; szx = c55[iy][ix][iz] * tzx[iy][ix][iz]; txx[iy][ix][iz] = sxx; tyy[iy][ix][iz] = syy; tzz[iy][ix][iz] = szz; txy[iy][ix][iz] = sxy; tyz[iy][ix][iz] = syz; tzx[iy][ix][iz] = szx; } } } /*------------------------------------------------------------*/ /* free surface */ /*------------------------------------------------------------*/ if(fsrf) { #ifdef _OPENMP #pragma omp parallel for \ schedule(dynamic,fdm->ompchunk) \ private(ix,iy,iz) \ shared(fdm,txx,tyy,tzz,txy,tyz,tzx) #endif for (iy=0; iy<fdm->nypad; iy++) { for (ix=0; ix<fdm->nxpad; ix++) { for(iz=0; iz<fdm->nb; iz++) { txx[iy][ix][iz]=0; tyy[iy][ix][iz]=0; tzz[iy][ix][iz]=0; txy[iy][ix][iz]=0; tyz[iy][ix][iz]=0; tzx[iy][ix][iz]=0; } } } } /*------------------------------------------------------------*/ /* inject stress source */ /*------------------------------------------------------------*/ if(ssou) { lint3d_bell(tzz,ww[it][0],cs); lint3d_bell(txx,ww[it][1],cs); lint3d_bell(tyy,ww[it][2],cs); } /*------------------------------------------------------------*/ /* from stress to acceleration */ /*------------------------------------------------------------*/ /* * ax = Bx(txx) + Fy(txy) + Fz(txz) * ay = Fx(txy) + By(tyy) + Fz(tyz) * az = Fx(txz) + Fy(tyz) + Bz(tzz) */ #ifdef _OPENMP #pragma omp parallel for \ schedule(dynamic,fdm->ompchunk) \ private(ix,iy,iz) \ shared(fdm,txx,tyy,tzz,txy,tyz,tzx,uax,uay,uaz,idx,idy,idz) #endif for (iy=NOP; iy<fdm->nypad-NOP; iy++) { for (ix=NOP; ix<fdm->nxpad-NOP; ix++) { for(iz=NOP; iz<fdm->nzpad-NOP; iz++) { uax[iy][ix][iz] = Dx( txx,ix,iy,iz,idx ) + Dy( txy,ix,iy,iz,idy ) + Dz( tzx,ix,iy,iz,idz ) ; uay[iy][ix][iz] = Dx( txy,ix,iy,iz,idx ) + Dy( tyy,ix,iy,iz,idy ) + Dz( tyz,ix,iy,iz,idz ) ; uaz[iy][ix][iz] = Dx( tzx,ix,iy,iz,idx ) + Dy( tyz,ix,iy,iz,idy ) + Dz( tzz,ix,iy,iz,idz ) ; } } } /*------------------------------------------------------------*/ /* inject acceleration source */ /*------------------------------------------------------------*/ if(!ssou) { lint3d_bell(uaz,ww[it][0],cs); lint3d_bell(uax,ww[it][1],cs); lint3d_bell(uay,ww[it][2],cs); } /*------------------------------------------------------------*/ /* step forward in time */ /*------------------------------------------------------------*/ #ifdef _OPENMP #pragma omp parallel for \ schedule(dynamic,fdm->ompchunk) \ private(ix,iy,iz) \ shared(fdm,uox,uoy,uoz,umx,umy,umz,upx,upy,upz,uax,uay,uaz,ro) #endif for (iy=0; iy<fdm->nypad; iy++) { for (ix=0; ix<fdm->nxpad; ix++) { for(iz=0; iz<fdm->nzpad; iz++) { upx[iy][ix][iz] = 2*uox[iy][ix][iz] - umx[iy][ix][iz] + uax[iy][ix][iz] * ro[iy][ix][iz]; upy[iy][ix][iz] = 2*uoy[iy][ix][iz] - umy[iy][ix][iz] + uay[iy][ix][iz] * ro[iy][ix][iz]; upz[iy][ix][iz] = 2*uoz[iy][ix][iz] - umz[iy][ix][iz] + uaz[iy][ix][iz] * ro[iy][ix][iz]; } } } /* circulate wavefield arrays */ utz=umz; uty=umy; utx=umx; umz=uoz; umy=uoy; umx=uox; uoz=upz; uoy=upy; uox=upx; upz=utz; upy=uty; upx=utx; if(dabc) { /* one-way ABC */ /* abcone3d_apply(uoz,umz,NOP,abcp,fdm); */ /* abcone3d_apply(uox,umx,NOP,abcp,fdm); */ /* abcone3d_apply(uoy,umy,NOP,abcp,fdm); */ abcone3d_apply(uoz,umz,NOP,abcs,fdm); abcone3d_apply(uox,umx,NOP,abcs,fdm); abcone3d_apply(uoy,umy,NOP,abcs,fdm); /* sponge ABC */ sponge3d_apply(umz,spo,fdm); sponge3d_apply(uoz,spo,fdm); sponge3d_apply(umx,spo,fdm); sponge3d_apply(uox,spo,fdm); sponge3d_apply(umy,spo,fdm); sponge3d_apply(uoy,spo,fdm); } /*------------------------------------------------------------*/ /* cut wavefield and save */ /*------------------------------------------------------------*/ if(opot) { #ifdef _OPENMP #pragma omp parallel for \ schedule(dynamic,fdm->ompchunk) \ private(ix,iy,iz) \ shared(fdm,uox,uoy,uoz,idx,idy,idz) #endif for (iy=NOP; iy<fdm->nypad-NOP; iy++) { for (ix=NOP; ix<fdm->nxpad-NOP; ix++) { for(iz=NOP; iz<fdm->nzpad-NOP; iz++) { qp [iy][ix][iz] = Dx( uox,ix,iy,iz,idx ) + Dy( uoy,ix,iy,iz,idy ) + Dz( uoz,ix,iy,iz,idz ); qsx[iy][ix][iz] = Dy( uoz,ix,iy,iz,idy ) - Dz( uoy,ix,iy,iz,idz ); qsy[iy][ix][iz] = Dz( uox,ix,iy,iz,idz ) - Dx( uoz,ix,iy,iz,idx ); qsz[iy][ix][iz] = Dx( uoy,ix,iy,iz,idx ) - Dy( uox,ix,iy,iz,idy ); } } } if(snap && it%jsnap==0) { cut3d(qp ,uc,fdm,acz,acx,acy); sf_floatwrite(uc[0][0],sf_n(acx)*sf_n(acy)*sf_n(acz),Fwfl); cut3d(qsz,uc,fdm,acz,acx,acy); sf_floatwrite(uc[0][0],sf_n(acx)*sf_n(acy)*sf_n(acz),Fwfl); cut3d(qsx,uc,fdm,acz,acx,acy); sf_floatwrite(uc[0][0],sf_n(acx)*sf_n(acy)*sf_n(acz),Fwfl); cut3d(qsy,uc,fdm,acz,acx,acy); sf_floatwrite(uc[0][0],sf_n(acx)*sf_n(acy)*sf_n(acz),Fwfl); } lint3d_extract(qp , dd[0],cr); lint3d_extract(qsx, dd[1],cr); lint3d_extract(qsy, dd[2],cr); lint3d_extract(qsz, dd[3],cr); if(it%jdata==0) sf_floatwrite(dd[0],nr*(nc+1),Fdat); } else { if(snap && it%jsnap==0) { cut3d(uoz,uc,fdm,acz,acx,acy); sf_floatwrite(uc[0][0],sf_n(acx)*sf_n(acy)*sf_n(acz),Fwfl); cut3d(uox,uc,fdm,acz,acx,acy); sf_floatwrite(uc[0][0],sf_n(acx)*sf_n(acy)*sf_n(acz),Fwfl); cut3d(uoy,uc,fdm,acz,acx,acy); sf_floatwrite(uc[0][0],sf_n(acx)*sf_n(acy)*sf_n(acz),Fwfl); } lint3d_extract(uoz,dd[0],cr); lint3d_extract(uox,dd[1],cr); lint3d_extract(uoy,dd[2],cr); if(it%jdata==0) sf_floatwrite(dd[0],nr*nc,Fdat); } } if(verb) fprintf(stderr,"\n"); /*------------------------------------------------------------*/ /* deallocate arrays */ free(**ww); free(*ww); free(ww); free(ss); free(rr); free(*dd); free(dd); free(**ro); free(*ro); free(ro); free(**c11); free(*c11); free(c11); free(**c22); free(*c22); free(c22); free(**c33); free(*c33); free(c33); free(**c44); free(*c44); free(c44); free(**c55); free(*c55); free(c55); free(**c66); free(*c66); free(c66); free(**c12); free(*c12); free(c12); free(**c13); free(*c13); free(c13); free(**c23); free(*c23); free(c23); free(**umz); free(*umz); free(umz); free(**uoz); free(*uoz); free(uoz); free(**upz); free(*upz); free(upz); free(**uaz); free(*uaz); free(uaz); free(**umx); free(*umx); free(umx); free(**uox); free(*uox); free(uox); free(**upx); free(*upx); free(upx); free(**uax); free(*uax); free(uax); free(**umy); free(*umy); free(umy); free(**uoy); free(*uoy); free(uoy); free(**upy); free(*upy); free(upy); free(**uay); free(*uay); free(uay); free(**tzz); free(*tzz); free(tzz); free(**txx); free(*txx); free(txx); free(**tyy); free(*tyy); free(tyy); free(**txy); free(*txy); free(txy); free(**tyz); free(*tyz); free(tyz); free(**tzx); free(*tzx); free(tzx); if (snap) { free(**uc); free(*uc); free(uc); } if(opot) { free(**qp); free(*qp); free(qp); free(**qsx); free(*qsx); free(qsx); free(**qsy); free(*qsy); free(qsy); free(**qsz); free(*qsz); free(qsz); } /*------------------------------------------------------------*/ exit (0); }
int main(int argc, char *argv[]) { bool wantwf, verb; int ix, iz, is, it, wfit, im, ik, i, j, itau; int ns, nx, nz, nt, wfnt, rnx, rnz, nzx, rnzx, vnx, ntau, htau, nds; int scalet, snap, snapshot, fnx, fnz, fnzx, nk, nb; int rectx, rectz, repeat, gpz, n, m, pad1, trunc, spx, spz; float dt, t0, z0, dz, x0, dx, s0, ds, wfdt, srctrunc; float dtau, tau0, tau; int nr, ndr, nr0; char *path1, *path2, number[5], *left, *right; double tstart, tend; struct timeval tim; /*wavenumber domain tapering*/ int taper; float *ktp; float ktmp,kx_trs,kz_trs,thresh; float dkx,dkz,kx0,kz0; float kx,kz; int nkz; sf_complex c, **lt, **rt; sf_complex *ww, **dd, ***dd3; float ***img1, **img2, ***mig1, **mig2; float *rr, **ccr, **sill, ***fwf, ***bwf; sf_complex *cwave, *cwavem, **wave, *curr; sf_axis at, ax, az, atau; sf_file Fdat, Fsrc, Fimg1, Fimg2; sf_file Ffwf, Fbwf, Fvel; sf_file Fleft, Fright; int cpuid, numprocs, nth, nspad, iturn; float *sendbuf, *recvbuf; sf_complex *sendbufc, *recvbufc; MPI_Comm comm=MPI_COMM_WORLD; MPI_Init(&argc, &argv); MPI_Comm_rank(comm, &cpuid); MPI_Comm_size(comm, &numprocs); sf_init(argc, argv); #ifdef _OPENMP #pragma omp parallel { nth=omp_get_num_threads(); } sf_warning(">>> Using %d threads <<<", nth); #endif gettimeofday(&tim, NULL); tstart=tim.tv_sec+(tim.tv_usec/1000000.0); if (!sf_getint("taper",&taper)) taper=0; /* tapering in the frequency domain */ if (!sf_getfloat("thresh",&thresh)) thresh=0.92; /* tapering threshold */ if(!sf_getbool("wantwf", &wantwf)) wantwf=false; if(!sf_getbool("verb", &verb)) verb=false; if(!sf_getint("pad1", &pad1)) pad1=1; /* padding factor on the first axis */ if(!sf_getint("nb", &nb)) sf_error("Need nb= "); if(!sf_getfloat("srctrunc", &srctrunc)) srctrunc=0.4; if(!sf_getint("rectx", &rectx)) rectx=2; if(!sf_getint("rectz", &rectz)) rectz=2; if(!sf_getint("repeat", &repeat)) repeat=2; if(!sf_getint("scalet", &scalet)) scalet=1; if(!sf_getint("snap", &snap)) snap=100; /* interval of the output wavefield */ if(!sf_getint("snapshot", &snapshot)) snapshot=0; /* print out the wavefield snapshots of this shot */ if(!sf_getint("nds", &nds)) sf_error("Need nds=!"); /* source and receiver positions */ if(!sf_getint("gpz", &gpz)) sf_error("Need gpz="); if(!sf_getint("spx", &spx)) sf_error("Need spx="); if(!sf_getint("spz", &spz)) sf_error("Need spz="); /* tau parameters */ if(!sf_getint("ntau", &ntau)) sf_error("Need ntau="); if(!sf_getfloat("dtau", &dtau)) sf_error("Need dtau="); if(!sf_getfloat("tau0", &tau0)) sf_error("Need tau0="); /* geometry parameters */ if(!sf_getint("rnx", &rnx)) sf_error("Need rnx="); if(!sf_getint("ndr", &ndr)) ndr=1; if(!sf_getint("nr0", &nr0)) nr0=0; /* input/output files */ Fdat=sf_input("--input"); Fimg1=sf_output("--output"); Fimg2=sf_output("Fimg2"); Fsrc=sf_input("Fsrc"); Fvel=sf_input("Fpadvel"); if(wantwf){ Ffwf=sf_output("Ffwf"); Fbwf=sf_output("Fbwf"); } at=sf_iaxa(Fsrc, 1); nt=sf_n(at); dt=sf_d(at); t0=sf_o(at); ax=sf_iaxa(Fvel, 2); vnx=sf_n(ax); dx=sf_d(ax); x0=sf_o(ax); az=sf_iaxa(Fvel, 1); rnz=sf_n(az); dz=sf_d(az); z0=sf_o(az); if(!sf_histint(Fdat, "n2", &nr)) sf_error("Need n2= in input!"); if(!sf_histint(Fdat, "n3", &ns)) sf_error("Need n3= in input!"); if(!sf_histfloat(Fdat, "d3", &ds)) sf_error("Need d3= in input!"); if(!sf_histfloat(Fdat, "o3", &s0)) sf_error("Need o3= in input!"); wfnt=(nt-1)/scalet+1; wfdt=dt*scalet; /* double check the geometry parameters */ if(nds != (int)(ds/dx)) sf_error("Need ds/dx= %d", nds); //sf_warning("s0=%g, x0+(rnx-1)*dx/2=%g", s0, x0+(rnx-1)*dx/2); //if(s0 != x0+(rnx-1)*dx/2) sf_error("Wrong origin information!"); if(vnx != nds*(ns-1)+rnx) sf_error("Wrong dimension in x axis!"); /* set up the output files */ atau=sf_iaxa(Fsrc, 1); sf_setn(atau, ntau); sf_setd(atau, dtau); sf_seto(atau, tau0); sf_setlabel(atau, "Tau"); sf_setunit(atau, "s"); sf_oaxa(Fimg1, az, 1); sf_oaxa(Fimg1, ax, 2); sf_oaxa(Fimg1, atau, 3); sf_oaxa(Fimg2, az, 1); sf_oaxa(Fimg2, ax, 2); sf_putint(Fimg2, "n3", 1); sf_settype(Fimg1, SF_FLOAT); sf_settype(Fimg2, SF_FLOAT); if(wantwf){ sf_setn(ax, rnx); sf_seto(ax, -(rnx-1)*dx/2.0); sf_oaxa(Ffwf, az, 1); sf_oaxa(Ffwf, ax, 2); sf_putint(Ffwf, "n3", (wfnt-1)/snap+1); sf_putfloat(Ffwf, "d3", snap*wfdt); sf_putfloat(Ffwf, "o3", t0); sf_putstring(Ffwf, "label3", "Time"); sf_putstring(Ffwf, "unit3", "s"); sf_settype(Ffwf, SF_FLOAT); sf_oaxa(Fbwf, az, 1); sf_oaxa(Fbwf, ax, 2); sf_putint(Fbwf, "n3", (wfnt-1)/snap+1); sf_putfloat(Fbwf, "d3", -snap*wfdt); sf_putfloat(Fbwf, "o3", (wfnt-1)*wfdt); sf_putstring(Fbwf, "label3", "Time"); sf_putstring(Fbwf, "unit3", "s"); sf_settype(Fbwf, SF_FLOAT); } nx=rnx+2*nb; nz=rnz+2*nb; nzx=nx*nz; rnzx=rnz*rnx; nk=cfft2_init(pad1, nz, nx, &fnz, &fnx); fnzx=fnz*fnx; if(ns%numprocs==0) nspad=ns; else nspad=(ns/numprocs+1)*numprocs; /* print axies parameters for double check */ sf_warning("cpuid=%d, numprocs=%d, nspad=%d", cpuid, numprocs, nspad); sf_warning("nt=%d, dt=%g, scalet=%d, wfnt=%d, wfdt=%g",nt, dt, scalet, wfnt, wfdt); sf_warning("vnx=%d, nx=%d, dx=%g, nb=%d, rnx=%d", vnx, nx, dx, nb, rnx); sf_warning("nr=%d, ndr=%d, nr0=%g", nr, ndr, nr0); sf_warning("nz=%d, rnz=%d, dz=%g, z0=%g", nz, rnz, dz, z0); sf_warning("spx=%d, spz=%d, gpz=%d", spx, spz, gpz); sf_warning("ns=%d, ds=%g, s0=%g", ns, ds, s0); sf_warning("ntau=%d, dtau=%g, tau0=%g", ntau, dtau, tau0); sf_warning("nzx=%d, fnzx=%d, nk=%d", nzx, fnzx, nk); /* allocate storage and read data */ ww=sf_complexalloc(nt); sf_complexread(ww, nt, Fsrc); sf_fileclose(Fsrc); gpz=gpz+nb; spz=spz+nb; spx=spx+nb; nr0=nr0+nb; trunc=srctrunc/dt+0.5; dd=sf_complexalloc2(nt, nr); if(cpuid==0) dd3=sf_complexalloc3(nt, nr, numprocs); rr=sf_floatalloc(nzx); reflgen(nz, nx, spz, spx, rectz, rectx, repeat, rr); fwf=sf_floatalloc3(rnz, rnx, wfnt); bwf=sf_floatalloc3(rnz, rnx, wfnt); img1=sf_floatalloc3(rnz, vnx, ntau); img2=sf_floatalloc2(rnz, vnx); mig1=sf_floatalloc3(rnz, rnx, ntau); mig2=sf_floatalloc2(rnz, rnx); ccr=sf_floatalloc2(rnz, rnx); sill=sf_floatalloc2(rnz, rnx); curr=sf_complexalloc(fnzx); cwave=sf_complexalloc(nk); cwavem=sf_complexalloc(nk); icfft2_allocate(cwavem); if (taper!=0) { dkz = 1./(fnz*dz); kz0 = -0.5/dz; dkx = 1./(fnx*dx); kx0 = -0.5/dx; nkz = fnz; sf_warning("dkz=%f,dkx=%f,kz0=%f,kx0=%f",dkz,dkx,kz0,kx0); sf_warning("nk=%d,nkz=%d,nkx=%d",nk,nkz,fnx); kx_trs = thresh*fabs(0.5/dx); kz_trs = thresh*fabs(0.5/dz); sf_warning("Applying kz tapering below %f",kz_trs); sf_warning("Applying kx tapering below %f",kx_trs); ktp = sf_floatalloc(nk); /* constructing the tapering op */ for (ix=0; ix < fnx; ix++) { kx = kx0+ix*dkx; for (iz=0; iz < nkz; iz++) { kz = kz0+iz*dkz; ktmp = 1.; if (fabs(kx) > kx_trs) ktmp *= powf((2*kx_trs - fabs(kx))/(kx_trs),2); if (fabs(kz) > kz_trs) ktmp *= powf((2*kz_trs - fabs(kz))/(kz_trs),2); ktp[iz+ix*nkz] = ktmp; } } } /* initialize image tables that would be used for summing images */ #ifdef _OPENMP #pragma omp parallel for private(ix, iz, itau) #endif for(ix=0; ix<vnx; ix++){ for(iz=0; iz<rnz; iz++){ img2[ix][iz]=0.; for(itau=0; itau<ntau; itau++){ img1[itau][ix][iz]=0.; } } } path1=sf_getstring("path1"); path2=sf_getstring("path2"); if(path1==NULL) path1="./mat/left"; if(path2==NULL) path2="./mat/right"; /* shot loop */ for (iturn=0; iturn*numprocs<nspad; iturn++){ is=iturn*numprocs+cpuid; /* read data */ if(cpuid==0){ sf_seek(Fdat, ((off_t) is)*((off_t) nr)*((off_t) nt)*sizeof(float complex), SEEK_SET); if((iturn+1)*numprocs<=ns){ sf_complexread(dd3[0][0], nr*nt*numprocs, Fdat); }else{ sf_complexread(dd3[0][0], nr*nt*(ns-iturn*numprocs), Fdat); for(is=ns; is<nspad; is++) for(ix=0; ix<nr; ix++) for(it=0; it<nt; it++) dd3[is-iturn*numprocs][ix][it]=sf_cmplx(0.,0.); is=iturn*numprocs; } sendbufc=dd3[0][0]; recvbufc=dd[0]; }else{ sendbufc=NULL; recvbufc=dd[0]; } MPI_Scatter(sendbufc, nt*nr, MPI_COMPLEX, recvbufc, nt*nr, MPI_COMPLEX, 0, comm); if(is<ns){ /* effective shot loop */ /* construct the names of left and right matrices */ left=sf_charalloc(strlen(path1)); right=sf_charalloc(strlen(path2)); strcpy(left, path1); strcpy(right, path2); sprintf(number, "%d", is+1); strcat(left, number); strcat(right, number); Fleft=sf_input(left); Fright=sf_input(right); if(!sf_histint(Fleft, "n1", &n) || n != nzx) sf_error("Need n1=%d in Fleft", nzx); if(!sf_histint(Fleft, "n2", &m)) sf_error("No n2 in Fleft"); if(!sf_histint(Fright, "n1", &n) || n != m) sf_error("Need n1=%d in Fright", m); if(!sf_histint(Fright, "n2", &n) || n != nk) sf_error("Need n2=%d in Fright", nk); /* allocate storage for each shot migration */ lt=sf_complexalloc2(nzx, m); rt=sf_complexalloc2(m, nk); sf_complexread(lt[0], nzx*m, Fleft); sf_complexread(rt[0], m*nk, Fright); sf_fileclose(Fleft); sf_fileclose(Fright); /* initialize curr and imaging variables */ #ifdef _OPENMP #pragma omp parallel for private(iz) #endif for(iz=0; iz<fnzx; iz++){ curr[iz]=sf_cmplx(0.,0.); } #ifdef _OPENMP #pragma omp parallel for private(ix, iz, itau) #endif for(ix=0; ix<rnx; ix++){ for(iz=0; iz<rnz; iz++){ mig2[ix][iz]=0.; ccr[ix][iz]=0.; sill[ix][iz]=0.; for(itau=0; itau<ntau; itau++){ mig1[itau][ix][iz]=0.; } } } /* wave */ wave=sf_complexalloc2(fnzx, m); /* snapshot */ if(wantwf && is==snapshot) wantwf=true; else wantwf=false; /* forward propagation */ wfit=0; for(it=0; it<nt; it++){ if(verb) sf_warning("Forward propagation it=%d/%d",it+1, nt); cfft2(curr, cwave); for(im=0; im<m; im++){ #ifdef _OPENMP #pragma omp parallel for private(ik) #endif for(ik=0; ik<nk; ik++){ #ifdef SF_HAS_COMPLEX_H cwavem[ik]=cwave[ik]*rt[ik][im]; #else cwavem[ik]=sf_cmul(cwave[ik],rt[ik][im]); #endif } icfft2(wave[im],cwavem); } #ifdef _OPENMP #pragma omp parallel for private(ix, iz, i, j, im, c) shared(curr, it) #endif for(ix=0; ix<nx; ix++){ for(iz=0; iz<nz; iz++){ i=iz+ix*nz; j=iz+ix*fnz; if(it<trunc){ #ifdef SF_HAS_COMPLEX_H c=ww[it]*rr[i]; #else c=sf_crmul(ww[it],rr[i]); #endif }else{ c=sf_cmplx(0.,0.); } // c += curr[j]; for(im=0; im<m; im++){ #ifdef SF_HAS_COMPLEX_H c += lt[im][i]*wave[im][j]; #else c += sf_cmul(lt[im][i], wave[im][j]); #endif } curr[j]=c; } } if (taper!=0) { if (it%taper == 0) { cfft2(curr,cwave); for (ik = 0; ik < nk; ik++) { #ifdef SF_HAS_COMPLEX_H cwavem[ik] = cwave[ik]*ktp[ik]; #else cwavem[ik] = sf_crmul(cwave[ik],ktp[ik]); #endif } icfft2(curr,cwavem); } } if(it%scalet==0){ #ifdef _OPENMP #pragma omp parallel for private(ix, iz) #endif for(ix=0; ix<rnx; ix++){ for(iz=0; iz<rnz; iz++){ fwf[wfit][ix][iz]=crealf(curr[(ix+nb)*fnz+(iz+nb)]); } } wfit++; } } //end of it /* check wfnt */ if(wfit != wfnt) sf_error("At this point, wfit should be equal to wfnt"); /* backward propagation starts from here... */ #ifdef _OPENMP #pragma omp parallel for private(iz) #endif for(iz=0; iz<fnzx; iz++){ curr[iz]=sf_cmplx(0.,0.); } wfit=wfnt-1; for(it=nt-1; it>=0; it--){ if(verb) sf_warning("Backward propagation it=%d/%d",it+1, nt); #ifdef _OPENMP #pragma omp parallel for private(ix) #endif for(ix=0; ix<nr; ix++){ curr[(nr0+ix*ndr)*fnz+gpz]+=dd[ix][it]; } cfft2(curr, cwave); for(im=0; im<m; im++){ #ifdef _OPENMP #pragma omp parallel for private(ik) #endif for(ik=0; ik<nk; ik++){ #ifdef SF_HAS_COMPLEX_H cwavem[ik]=cwave[ik]*conjf(rt[ik][im]); #else cwavem[ik]=sf_cmul(cwave[ik],conjf(rt[ik][im])); #endif } icfft2(wave[im],cwavem); } #ifdef _OPENMP #pragma omp parallel for private(ix, iz, i, j, im, c) shared(curr, it) #endif for(ix=0; ix<nx; ix++){ for(iz=0; iz<nz; iz++){ i=iz+ix*nz; j=iz+ix*fnz; // c=curr[j]; c=sf_cmplx(0.,0.); for(im=0; im<m; im++){ #ifdef SF_HAS_COMPLEX_H c += conjf(lt[im][i])*wave[im][j]; #else c += sf_cmul(conjf(lt[im][i]), wave[im][j]); #endif } curr[j]=c; } } if (taper!=0) { if (it%taper == 0) { cfft2(curr,cwave); for (ik = 0; ik < nk; ik++) { #ifdef SF_HAS_COMPLEX_H cwavem[ik] = cwave[ik]*ktp[ik]; #else cwavem[ik] = sf_crmul(cwave[ik],ktp[ik]); #endif } icfft2(curr,cwavem); } } if(it%scalet==0){ #ifdef _OPENMP #pragma omp parallel for private(ix, iz) #endif for(ix=0; ix<rnx; ix++){ for(iz=0; iz<rnz; iz++){ bwf[wfit][ix][iz]=crealf(curr[(ix+nb)*fnz+(iz+nb)]); ccr[ix][iz] += fwf[wfit][ix][iz]*bwf[wfit][ix][iz]; sill[ix][iz] += fwf[wfit][ix][iz]*fwf[wfit][ix][iz]; } } wfit--; } } //end of it if(wfit != -1) sf_error("Check program! The final wfit should be -1!"); /* free storage */ free(*rt); free(rt); free(*lt); free(lt); free(*wave); free(wave); free(left); free(right); /* normalized image */ #ifdef _OPENMP #pragma omp parallel for private(ix, iz) #endif for (ix=0; ix<rnx; ix++){ for(iz=0; iz<rnz; iz++){ mig2[ix][iz]=ccr[ix][iz]/(sill[ix][iz]+SF_EPS); // sill[ix][iz]=0.; } } /* time-shift imaging condition */ for(itau=0; itau<ntau; itau++){ //sf_warning("itau/ntau=%d/%d", itau+1, ntau); tau=itau*dtau+tau0; htau=tau/wfdt; for(it=abs(htau); it<wfnt-abs(htau); it++){ #ifdef _OPENMP #pragma omp parallel for private(ix, iz) #endif for(ix=0; ix<rnx; ix++){ for(iz=0; iz<rnz; iz++){ mig1[itau][ix][iz]+=fwf[it+htau][ix][iz]*bwf[it-htau][ix][iz]; // sill[ix][iz]+=fwf[it+htau][ix][iz]*fwf[it+htau][ix][iz]; } // end of iz } // end of ix } // end of it //#ifdef _OPENMP //#pragma omp parallel for private(ix, iz) //#endif /* source illumination */ // for(ix=0; ix<rnx; ix++){ // for(iz=0; iz<rnz; iz++){ // mig1[itau][ix][iz] = mig1[itau][ix][iz]/(sill[ix][iz]+SF_EPS); // } // } } //end of itau /* output wavefield snapshot */ if(wantwf){ for(it=0; it<wfnt; it++){ if(it%snap==0){ sf_floatwrite(fwf[it][0], rnzx, Ffwf); sf_floatwrite(bwf[wfnt-1-it][0], rnzx, Fbwf); } } sf_fileclose(Ffwf); sf_fileclose(Fbwf); } /* add all the shot images that are on the same node */ #ifdef _OPENMP #pragma omp parallel for private(itau, ix, iz) #endif for(itau=0; itau<ntau; itau++){ for(ix=0; ix<rnx; ix++){ for(iz=0; iz<rnz; iz++){ img1[itau][ix+is*nds][iz] += mig1[itau][ix][iz]; } } } #ifdef _OPENMP #pragma omp parallel for private(ix, iz) #endif for(ix=0; ix<rnx; ix++){ for(iz=0; iz<rnz; iz++){ img2[ix+is*nds][iz] += mig2[ix][iz]; } } } // end of is<ns } // end of iturn ////////////////end of ishot MPI_Barrier(comm); cfft2_finalize(); sf_fileclose(Fdat); free(ww); free(rr); free(*dd); free(dd); if(cpuid==0) {free(**dd3); free(*dd3); free(dd3);} free(cwave); free(cwavem); free(curr); free(*ccr); free(ccr); free(*sill); free(sill); free(**fwf); free(*fwf); free(fwf); free(**bwf); free(*bwf); free(bwf); free(**mig1); free(*mig1); free(mig1); free(*mig2); free(mig2); /* sum image */ if(cpuid==0){ sendbuf=(float *)MPI_IN_PLACE; recvbuf=img1[0][0]; }else{ sendbuf=img1[0][0]; recvbuf=NULL; } MPI_Reduce(sendbuf, recvbuf, ntau*vnx*rnz, MPI_FLOAT, MPI_SUM, 0, comm); if(cpuid==0){ sendbuf=MPI_IN_PLACE; recvbuf=img2[0]; }else{ sendbuf=img2[0]; recvbuf=NULL; } MPI_Reduce(sendbuf, recvbuf, vnx*rnz, MPI_FLOAT, MPI_SUM, 0, comm); /* output image */ if(cpuid==0){ sf_floatwrite(img1[0][0], ntau*vnx*rnz, Fimg1); sf_floatwrite(img2[0], vnx*rnz, Fimg2); } MPI_Barrier(comm); sf_fileclose(Fimg1); sf_fileclose(Fimg2); free(**img1); free(*img1); free(img1); free(*img2); free(img2); gettimeofday(&tim, NULL); tend=tim.tv_sec+(tim.tv_usec/1000000.0); sf_warning(">> The computing time is %.3lf minutes <<", (tend-tstart)/60.); MPI_Finalize(); exit(0); }
/* main function */ int main(int argc, char* argv[]) { clock_t tstart,tend; double duration; /*flags*/ bool verb, adj; /* migration(adjoint) flag */ bool wantwf; /* outputs wavefield snapshots */ bool wantrecord; /* actually means "need record" */ bool illum; /* source illumination flag */ bool roll; /* survey strategy */ bool fm; /* forward modeling */ /*I/O*/ sf_file Fvel; sf_file left, right, leftb, rightb; sf_file Fsrc, Frcd/*source and record*/; sf_file Ftmpwf; sf_file Fimg; sf_file mask; /*axis*/ sf_axis at, ax, az, as; /*grid index variables*/ int nx, nz, nt, wfnt; int nzx, nx2, nz2, n2, m2, pad1, nk; int ix, iz, it, is; int nxb, nzb; int snpint, wfint; float dt, dx, dz, wfdt; float ox, oz; /*source/geophone location*/ int spx, spz; int gpz,gpx,gpl; /*geophone depth/x-crd/length*/ /*Model*/ sf_complex **lt, **rt; sf_complex **ltb, **rtb; /*Data*/ sf_complex ***wavefld; sf_complex ***record, **tmprec, **img, **imgsum; float **sill; /*source*/ sf_complex *ww; float **rr; int **kill=NULL; int rectz,rectx,repeat; /*smoothing parameters*/ float trunc; int sht0,shtbgn,shtend,shtnum,shtint; /*abc boundary*/ int top,bot,lft,rht; /*tmp*/ int tmpint; /*parameter structs*/ geopar geop; mpipar mpip; /*MPI*/ int rank, nodes; sf_complex *sendbuf, *recvbuf; MPI_Init(&argc, &argv); MPI_Comm_rank(MPI_COMM_WORLD, &rank); MPI_Comm_size(MPI_COMM_WORLD, &nodes); sf_init(argc, argv); if(rank==0) sf_warning("nodes=%d",nodes); if (!sf_getbool("verb", &verb)) verb=false; /*verbosity*/ if (!sf_getbool("adj", &adj)) adj=true; /*migration*/ if (!sf_getbool("wantwf", &wantwf)) wantwf=false; /*output forward and backward wavefield*/ if (!sf_getbool("wantrecord", &wantrecord)) wantrecord=true; /*if n, using record data generated by this program */ if (!sf_getbool("illum", &illum)) illum=false; /*if n, no source illumination applied */ if (!sf_getbool("roll", &roll)) roll=true; /*if n, receiver is independent of source location and gpl=nx*/ if (!sf_getbool("fm", &fm)) fm=false; /* if n, Born modelling */ if (!sf_getbool("incom", &incom)) incom=false; /* if n, use complete data */ /* source/receiver info */ if (!sf_getint("shtbgn", &shtbgn)) sf_error("Need shot starting location on grid!"); if (!sf_getint("sht0", &sht0)) sht0=shtbgn; /*actual shot origin on grid*/ if (!sf_getint("shtend", &shtend)) sf_error("Need shot ending location on grid!"); if (!sf_getint("shtint", &shtint)) sf_error("Need shot interval on grid!"); shtnum = (int)((shtend-shtbgn)/shtint) + 1; if (!sf_getint("spz", &spz)) sf_error("Need source depth!"); if (!sf_getint("gpz", &gpz)) sf_error("Need receiver depth!"); if (roll) if (!sf_getint("gpl", &gpl)) sf_error("Need receiver length"); if (!sf_getint("snapinter", &snpint)) snpint=1; /* snap interval */ if (!sf_getint("wfint", &wfint)) wfint=50; /* snap interval */ /*--- parameters of source ---*/ if (!sf_getfloat("srctrunc", &trunc)) trunc=0.4; if (!sf_getint("rectz", &rectz)) rectz=2; if (!sf_getint("rectx", &rectx)) rectx=2; if (!sf_getint("repeat", &repeat)) repeat=2; /* abc parameters */ if (!sf_getint("top", &top)) top=40; if (!sf_getint("bot", &bot)) bot=40; if (!sf_getint("lft", &lft)) lft=40; if (!sf_getint("rht", &rht)) rht=40; /* simultaneous sources parameter */ if (!sf_getint("nsource", &nsource)) nsource=1; if (!sf_getint("dsource", &dsource)) dsource=0; if (!sf_getfloat("tdelay", &tdelay)) tdelay=0; if (!sf_getint("choose", &choose)) choose=nsource; /*Set I/O file*/ if (adj) { /* migration */ if (wantrecord) { Frcd = sf_input("input"); /*record from elsewhere*/ Fsrc = sf_input("src"); /*source wavelet*/ } else { Frcd = sf_output("rec"); /*record produced by forward modeling*/ Fsrc = sf_input("input"); /*source wavelet*/ } Fimg = sf_output("output"); } else { /* modeling */ Fimg = sf_input("input"); Frcd = sf_output("output"); Fsrc = sf_input("src"); /*source wavelet*/ } left = sf_input("left"); right = sf_input("right"); leftb = sf_input("leftb"); rightb = sf_input("rightb"); Fvel = sf_input("vel"); /*velocity - just for model dimension*/ if (wantwf) { Ftmpwf = sf_output("tmpwf");/*wavefield snap*/ } if (incom) { mask=sf_input("mask"); /*mask operator*/ } /*--- Axes parameters ---*/ at = sf_iaxa(Fsrc, 1); nt = sf_n(at); dt = sf_d(at); az = sf_iaxa(Fvel, 1); nzb = sf_n(az); dz = sf_d(az); oz = sf_o(az); ax = sf_iaxa(Fvel, 2); nxb = sf_n(ax); dx = sf_d(ax); ox = sf_o(ax); nzx = nzb*nxb; nz = nzb - top - bot; nx = nxb - lft - rht; if (!roll) gpl = nx; /* global survey setting */ /* wavefield axis */ wfnt = (int)(nt-1)/snpint+1; wfdt = dt*snpint; ndelay=tdelay/dt; /* propagator matrices */ if (!sf_getint("pad1",&pad1)) pad1=1; /* padding factor on the first axis */ nz2 = kiss_fft_next_fast_size(nzb*pad1); nx2 = kiss_fft_next_fast_size(nxb); nk = nz2*nx2; /*wavenumber*/ if (!sf_histint(left,"n1",&n2) || n2 != nzx) sf_error("Need n1=%d in left",nzx); if (!sf_histint(left,"n2",&m2)) sf_error("Need n2= in left"); if (!sf_histint(right,"n1",&n2) || n2 != m2) sf_error("Need n1=%d in right",m2); if (!sf_histint(right,"n2",&n2) || n2 != nk) sf_error("Need n2=%d in right",nk); /*check record data*/ if (adj && wantrecord) { sf_histint(Frcd,"n1", &tmpint); if (tmpint != nt ) sf_error("Error parameter n1 in record!"); sf_histint(Frcd,"n2", &tmpint); if (tmpint != gpl ) sf_error("Error parameter n2 in record!"); sf_histint(Frcd,"n3", &tmpint); if (tmpint != shtnum ) sf_error("Error parameter n3 in record!"); } /*allocate memory*/ ww=sf_complexalloc(nt); rr=sf_floatalloc2(nzx,nsource); lt = sf_complexalloc2(nzx,m2); rt = sf_complexalloc2(m2,nk); ltb = sf_complexalloc2(nzx,m2); rtb = sf_complexalloc2(m2,nk); geop = (geopar) sf_alloc(1, sizeof(*geop)); mpip = (mpipar) sf_alloc(1, sizeof(*mpip)); tmprec = sf_complexalloc2(nt, gpl); record = sf_complexalloc3(nt, gpl, shtnum); if (incom) { kill = sf_intalloc2(gpl, shtnum); sf_intread(kill[0],gpl*shtnum,mask); } wavefld = sf_complexalloc3(nz, nx, wfnt); if (illum ) sill = sf_floatalloc2(nz, nx); else sill = NULL; img = sf_complexalloc2(nz, nx); if (adj) { imgsum = sf_complexalloc2(nz, nx); #ifdef _OPENMP #pragma omp parallel for private(ix,iz) #endif for (ix=0; ix<nx; ix++) for (iz=0; iz<nz; iz++) { imgsum[ix][iz] = sf_cmplx(0.,0.); } } /*read from files*/ sf_complexread(ww,nt,Fsrc); sf_complexread(lt[0],nzx*m2,left); sf_complexread(rt[0],m2*nk,right); sf_complexread(ltb[0],nzx*m2,leftb); sf_complexread(rtb[0],m2*nk,rightb); if(!adj) sf_complexread(img[0],nx*nz,Fimg); if(adj && wantrecord) { sf_complexread(record[0][0], shtnum*gpl*nt, Frcd); if(incom) { for (is=0; is<shtnum; is++) for (ix=0; ix<gpl; ix++) if(kill[is][ix]==0) for (it=0; it<nt; it++) record[is][ix][it]=sf_cmplx(0.,0.); } } else { #ifdef _OPENMP #pragma omp parallel for private(is,ix,it) #endif for (is=0; is<shtnum; is++) for (ix=0; ix<gpl; ix++) for (it=0; it<nt; it++) record[is][ix][it] = sf_cmplx(0.,0.); } /*close RSF files*/ sf_fileclose(Fsrc); sf_fileclose(left); sf_fileclose(right); sf_fileclose(leftb); sf_fileclose(rightb); /*load constant geopar elements*/ mpip->cpuid=rank; mpip->numprocs=nodes; /*load constant geopar elements*/ geop->nx = nx; geop->nz = nz; geop->nxb = nxb; geop->nzb = nzb; geop->dx = dx; geop->dz = dz; geop->ox = ox; geop->oz = oz; geop->snpint = snpint; geop->spz = spz; geop->gpz = gpz; geop->gpl = gpl; geop->top = top; geop->bot = bot; geop->lft = lft; geop->rht = rht; geop->nt = nt; geop->dt = dt; geop->trunc = trunc; geop->shtnum = shtnum; /* output RSF files */ if (rank==0) { sf_setn(ax, gpl); sf_setn(az, nz); as = sf_iaxa(Fvel, 2); sf_setn(as,shtnum); sf_setd(as,shtint*dx); sf_seto(as,shtbgn*dx+ox); if (adj) { /* migration */ if(!wantrecord) { sf_oaxa(Frcd, at, 1); sf_oaxa(Frcd, ax, 2); sf_oaxa(Frcd, as, 3); sf_settype(Frcd,SF_COMPLEX); } sf_setn(ax, nx); /*write image*/ sf_oaxa(Fimg, az, 1); sf_oaxa(Fimg, ax, 2); sf_settype(Fimg,SF_COMPLEX); } else { /* modeling */ sf_oaxa(Frcd, at, 1); sf_oaxa(Frcd, ax, 2); sf_oaxa(Frcd, as ,3); sf_settype(Frcd,SF_COMPLEX); } if (wantwf) { sf_setn(ax, nx); /*write temp wavefield */ sf_setn(at, (wfnt-1)/wfint+1); sf_setd(at, wfdt*wfint); sf_oaxa(Ftmpwf, az, 1); sf_oaxa(Ftmpwf, ax, 2); sf_oaxa(Ftmpwf, at, 3); sf_settype(Ftmpwf,SF_COMPLEX); } } tstart = clock(); for (is=rank; is<shtnum; is+=nodes) { spx = shtbgn + shtint*is; if (roll) gpx = spx - (int)(gpl/2); else gpx = 0; geop->spx = spx; geop->gpx = gpx; if (verb) { sf_warning("============================"); sf_warning("processing shot #%d", is); sf_warning("nx=%d nz=%d nt=%d", geop->nx, geop->nz, geop->nt); sf_warning("nxb=%d nzb=%d ", geop->nxb, geop->nzb); sf_warning("dx=%f dz=%f dt=%f", geop->dx, geop->dz, geop->dt); sf_warning("top=%d bot=%d lft=%d rht=%d", geop->top, geop->bot, geop->lft, geop->rht); sf_warning("rectz=%d rectx=%d repeat=%d srctrunc=%f",rectz,rectx,repeat,geop->trunc); sf_warning("spz=%d spx=%d gpz=%d gpx=%d gpl=%d", spz, spx, gpz, gpx, gpl); sf_warning("snpint=%d wfdt=%f wfnt=%d ", snpint, wfdt, wfnt); sf_warning("sht0=%d shtbgn=%d shtend=%d shtnum=%d", sht0, shtbgn, shtend, shtnum); if (roll) sf_warning("Rolling survey!"); else sf_warning("Global survey (gpl=nx)!"); if (illum) sf_warning("Using source illumination!"); else sf_warning("No source illumination!"); sf_warning("============================"); } /*generate reflectivity map*/ reflgen(nzb, nxb, spz+top, spx+lft, rectz, rectx, repeat, rr); lrosfor2(wavefld, sill, tmprec, verb, lt, rt, m2, geop, ww, rr, pad1, illum); if(adj && wantrecord) #ifdef _OPENMP #pragma omp parallel for private(ix,it) #endif for (ix=0; ix<gpl; ix++) for (it=0; it<nt; it++) tmprec[ix][it] = record[is][ix][it]; if(!fm) { lrosback2(img, wavefld, sill, tmprec, adj, verb, wantwf, ltb, rtb, m2, geop, pad1, illum); } if (adj) { #ifdef _OPENMP #pragma omp parallel for private(ix,iz) #endif for (ix=0; ix<nx; ix++) for (iz=0; iz<nz; iz++) imgsum[ix][iz] += img[ix][iz]; } if (!adj || !wantrecord) #ifdef _OPENMP #pragma omp parallel for private(ix,it) #endif for (ix=0; ix<gpl; ix++) for (it=0; it<nt; it++) record[is][ix][it] = tmprec[ix][it]; if (wantwf && is==0) for (it=0; it<wfnt; it++) { if (it%wfint == 0) { sf_complexwrite(wavefld[it][0], nx*nz, Ftmpwf); } } } /*shot iteration*/ MPI_Barrier(MPI_COMM_WORLD); /*write record/image*/ if (adj) { if (rank==0) { sendbuf = (sf_complex *) MPI_IN_PLACE; recvbuf = imgsum[0]; } else { sendbuf = imgsum[0]; recvbuf = NULL; } MPI_Reduce(sendbuf, recvbuf, nx*nz, MPI_COMPLEX, MPI_SUM, 0, MPI_COMM_WORLD); if (rank==0) sf_complexwrite(imgsum[0], nx*nz, Fimg); } if (!adj || !wantrecord) { if (rank==0) { sendbuf = (sf_complex *) MPI_IN_PLACE; recvbuf = record[0][0]; } else { sendbuf = record[0][0]; recvbuf = NULL; } MPI_Reduce(sendbuf, recvbuf, shtnum*gpl*nt, MPI_COMPLEX, MPI_SUM, 0, MPI_COMM_WORLD); if (rank==0) { if(incom) { for (is=0; is<shtnum; is++) for (ix=0; ix<gpl; ix++) if(kill[is][ix]==0) for (it=0; it<nt; it++) record[is][ix][it]=sf_cmplx(0.,0.); } sf_complexwrite(record[0][0], shtnum*gpl*nt, Frcd); } } /*free memory*/ free(ww); free(rr); free(*lt); free(lt); free(*rt); free(rt); free(*ltb); free(ltb); free(*rtb); free(rtb); free(geop); free(mpip); free(*tmprec); free(tmprec); free(**record); free(*record); free(record); free(**wavefld); free(*wavefld); free(wavefld); if (illum) { free(*sill); free(sill); } free(*img); free(img); if (adj) { free(*imgsum); free(imgsum); } if (incom) { free(* kill); free(kill); } tend = clock(); duration=(double)(tend-tstart)/CLOCKS_PER_SEC; sf_warning(">> The CPU time of single shot migration is: %f seconds << ", duration); MPI_Finalize(); exit(0); }
int main(int argc, char* argv[]) { bool verb,fsrf,snap,expl,dabc,sout,uses; int jsnap,ntsnap,jdata; char *atype; #ifdef _OPENMP int ompnth=1; #endif /* I/O files */ sf_file Fwav=NULL; /* wavelet */ sf_file Fsou=NULL; /* sources */ sf_file Frec=NULL; /* receivers */ sf_file Fvel=NULL; /* velocity */ sf_file Fang=NULL; /* angles */ sf_file Fdat=NULL; /* data */ sf_file Fwfl=NULL; /* wavefield */ /* cube axes */ sf_axis at,az,ax; sf_axis as,ar; int nt,nz,nx,ns,nr,nb; int it,iz,ix; float dt,dz,dx,dt2; /* FDM structure */ fdm2d fdm=NULL; abcone2d abc=NULL; sponge spo=NULL; /* I/O arrays */ float *ww=NULL; /* wavelet */ pt2d *ss=NULL; /* sources */ pt2d *rr=NULL; /* receivers */ float *dd=NULL; /* data */ float **tt=NULL; float **vp=NULL; /* velocity */ float **vpn=NULL; float **vpz=NULL; float **vpx=NULL; float **vsz=NULL; float **tht=NULL,**sit=NULL,**cot=NULL; float st,ct; float **pm=NULL,**po=NULL,**pp=NULL,**pa=NULL,**pt=NULL; /* main wavefield */ float **qm=NULL,**qo=NULL,**qp=NULL,**qa=NULL,**qt=NULL; /* auxiliary wavefield */ float **sf=NULL; /* "stress" field */ /* linear inteppolation weights/indices */ lint2d cs,cr; /* FD operator size */ float cox,cax,cbx,c1x,c2x; float coz,caz,cbz,c1z,c2z; /* wavefield cut params */ sf_axis acz=NULL,acx=NULL; int nqz,nqx; float oqz,oqx; float dqz,dqx; float **pc=NULL; float H1p,H2p,H1q,H2q; /*------------------------------------------------------------*/ /* init RSF */ sf_init(argc,argv); /* select anisotropy model */ if (NULL == (atype = sf_getstring("atype"))) atype = "i"; switch(atype[0]) { case 't': sf_warning("TTI model"); break; case 'v': sf_warning("VTI model"); break; case 'i': default: sf_warning("ISO model"); break; } /*------------------------------------------------------------*/ /* OMP parameters */ #ifdef _OPENMP ompnth=omp_init(); #endif /*------------------------------------------------------------*/ /*------------------------------------------------------------*/ if(! sf_getbool("verb",&verb)) verb=false; /* verbosity */ if(! sf_getbool("snap",&snap)) snap=false; /* wavefield snapshots */ if(! sf_getbool("free",&fsrf)) fsrf=false; /* free surface */ if(! sf_getbool("expl",&expl)) expl=false; /* "exploding reflector" */ if(! sf_getbool("dabc",&dabc)) dabc=false; /* absorbing BC */ if(! sf_getbool("sout",&sout)) sout=false; /* stress output */ if(! sf_getbool("uses",&uses)) uses=false; /* use vsz */ /*------------------------------------------------------------*/ /*------------------------------------------------------------*/ /* I/O files */ Fwav = sf_input ("in" ); /* wavelet */ Fvel = sf_input ("vel"); /* velocity */ Fsou = sf_input ("sou"); /* sources */ Frec = sf_input ("rec"); /* receivers */ Fang = sf_input ("ang"); /* angles */ Fwfl = sf_output("wfl"); /* wavefield */ Fdat = sf_output("out"); /* data */ /*------------------------------------------------------------*/ /* axes */ at = sf_iaxa(Fwav,2); sf_setlabel(at,"t"); if(verb) sf_raxa(at); /* time */ az = sf_iaxa(Fvel,1); sf_setlabel(az,"z"); if(verb) sf_raxa(az); /* depth */ ax = sf_iaxa(Fvel,2); sf_setlabel(ax,"x"); if(verb) sf_raxa(ax); /* space */ as = sf_iaxa(Fsou,2); sf_setlabel(as,"s"); if(verb) sf_raxa(as); /* sources */ ar = sf_iaxa(Frec,2); sf_setlabel(ar,"r"); if(verb) sf_raxa(ar); /* receivers */ nt = sf_n(at); dt = sf_d(at); nz = sf_n(az); dz = sf_d(az); nx = sf_n(ax); dx = sf_d(ax); ns = sf_n(as); nr = sf_n(ar); /*------------------------------------------------------------*/ /*------------------------------------------------------------*/ /* other execution parameters */ if(! sf_getint("jdata",&jdata)) jdata=1; if(snap) { /* save wavefield every *jsnap* time steps */ if(! sf_getint("jsnap",&jsnap)) jsnap=nt; } /*------------------------------------------------------------*/ /*------------------------------------------------------------*/ /* setup output data header */ sf_oaxa(Fdat,ar,1); sf_setn(at,nt/jdata); sf_setd(at,dt*jdata); sf_oaxa(Fdat,at,2); /* setup output wavefield header */ if(snap) { if(!sf_getint ("nqz",&nqz)) nqz=sf_n(az); if(!sf_getint ("nqx",&nqx)) nqx=sf_n(ax); if(!sf_getfloat("oqz",&oqz)) oqz=sf_o(az); if(!sf_getfloat("oqx",&oqx)) oqx=sf_o(ax); dqz=sf_d(az); dqx=sf_d(ax); acz = sf_maxa(nqz,oqz,dqz); sf_raxa(acz); acx = sf_maxa(nqx,oqx,dqx); sf_raxa(acx); /* check if the imaging window fits in the wavefield domain */ pc=sf_floatalloc2(sf_n(acz),sf_n(acx)); ntsnap=0; for(it=0; it<nt; it++) { if(it%jsnap==0) ntsnap++; } sf_setn(at, ntsnap); sf_setd(at,dt*jsnap); if(verb) sf_raxa(at); sf_oaxa(Fwfl,acz,1); sf_oaxa(Fwfl,acx,2); sf_oaxa(Fwfl,at, 3); } /*------------------------------------------------------------*/ /* expand domain for FD operators and ABC */ if( !sf_getint("nb",&nb) || nb<NOP) nb=NOP; fdm=fdutil_init(verb,fsrf,az,ax,nb,1); sf_setn(az,fdm->nzpad); sf_seto(az,fdm->ozpad); if(verb) sf_raxa(az); sf_setn(ax,fdm->nxpad); sf_seto(ax,fdm->oxpad); if(verb) sf_raxa(ax); /*------------------------------------------------------------*/ if(expl) { ww = sf_floatalloc( 1); } else { ww = sf_floatalloc(ns); } dd = sf_floatalloc(nr); /*------------------------------------------------------------*/ /* setup source/receiver coordinates */ ss = (pt2d*) sf_alloc(ns,sizeof(*ss)); rr = (pt2d*) sf_alloc(nr,sizeof(*rr)); pt2dread1(Fsou,ss,ns,2); /* read (x,z) coordinates */ pt2dread1(Frec,rr,nr,2); /* read (x,z) coordinates */ cs = lint2d_make(ns,ss,fdm); cr = lint2d_make(nr,rr,fdm); /*------------------------------------------------------------*/ /* setup FD coefficients */ cox = C0 / (dx*dx); cax = CA / (dx*dx); cbx = CB / (dx*dx); c1x = C1 / dx; c2x = C2 / dx; coz = C0 / (dz*dz); caz = CA / (dz*dz); cbz = CB / (dz*dz); c1z = C1 / dz; c2z = C2 / dz; /* precompute dt^2*/ dt2 = dt*dt; /*------------------------------------------------------------*/ tt = sf_floatalloc2(nz,nx); /*------------------------------------------------------------*/ /* input velocity */ vp =sf_floatalloc2(fdm->nzpad,fdm->nxpad); vpz =sf_floatalloc2(fdm->nzpad,fdm->nxpad); sf_floatread(tt[0],nz*nx,Fvel ); expand(tt,vpz,fdm); /* VPz */ for (ix=0; ix<fdm->nxpad; ix++) { for(iz=0; iz<fdm->nzpad; iz++) { vp [ix][iz] = vpz[ix][iz]; vpz[ix][iz] = vpz[ix][iz] * vpz[ix][iz]; } } if(fsrf) { /* free surface */ for (ix=0; ix<fdm->nxpad; ix++) { for(iz=0; iz<fdm->nb; iz++) { vpz[ix][iz]=0; } } } if(atype[0] != 'i') { vpn =sf_floatalloc2(fdm->nzpad,fdm->nxpad); sf_floatread(tt[0],nz*nx,Fvel ); expand(tt,vpn,fdm); /* VPn */ vpx =sf_floatalloc2(fdm->nzpad,fdm->nxpad); sf_floatread(tt[0],nz*nx,Fvel ); expand(tt,vpx,fdm); /* VPx */ for (ix=0; ix<fdm->nxpad; ix++) { for(iz=0; iz<fdm->nzpad; iz++) { vpn[ix][iz] = vpn[ix][iz] * vpn[ix][iz]; vpx[ix][iz] = vpx[ix][iz] * vpx[ix][iz]; } } if(fsrf) { /* free surface */ for (ix=0; ix<fdm->nxpad; ix++) { for(iz=0; iz<fdm->nb; iz++) { vpn[ix][iz]=0; vpx[ix][iz]=0; } } } if(uses) { vsz =sf_floatalloc2(fdm->nzpad,fdm->nxpad); sf_floatread(tt[0],nz*nx,Fvel ); expand(tt,vsz,fdm); /* VSz */ for (ix=0; ix<fdm->nxpad; ix++) { for(iz=0; iz<fdm->nzpad; iz++) { vsz[ix][iz] = vsz[ix][iz] * vsz[ix][iz]; } } } } /*------------------------------------------------------------*/ if( atype[0]=='t') { /* input tilt angle */ tht =sf_floatalloc2(fdm->nzpad,fdm->nxpad); sit =sf_floatalloc2(fdm->nzpad,fdm->nxpad); cot =sf_floatalloc2(fdm->nzpad,fdm->nxpad); sf_floatread(tt[0],nz*nx,Fang); expand(tt,tht,fdm); for (ix=0; ix<fdm->nxpad; ix++) { for(iz=0; iz<fdm->nzpad; iz++) { tht[ix][iz] *= SF_PI/180.; sit[ix][iz] = sinf(tht[ix][iz]); cot[ix][iz] = cosf(tht[ix][iz]); } } free(*tht); free(tht); } /*------------------------------------------------------------*/ free(*tt); free(tt); /*------------------------------------------------------------*/ /*------------------------------------------------------------*/ /* allocate wavefield arrays */ pm=sf_floatalloc2(fdm->nzpad,fdm->nxpad); po=sf_floatalloc2(fdm->nzpad,fdm->nxpad); pp=sf_floatalloc2(fdm->nzpad,fdm->nxpad); pa=sf_floatalloc2(fdm->nzpad,fdm->nxpad); for (ix=0; ix<fdm->nxpad; ix++) { for(iz=0; iz<fdm->nzpad; iz++) { pm[ix][iz]=0; po[ix][iz]=0; pp[ix][iz]=0; pa[ix][iz]=0; } } if(atype[0] != 'i') { qm=sf_floatalloc2(fdm->nzpad,fdm->nxpad); qo=sf_floatalloc2(fdm->nzpad,fdm->nxpad); qp=sf_floatalloc2(fdm->nzpad,fdm->nxpad); qa=sf_floatalloc2(fdm->nzpad,fdm->nxpad); for (ix=0; ix<fdm->nxpad; ix++) { for(iz=0; iz<fdm->nzpad; iz++) { qm[ix][iz]=0; qo[ix][iz]=0; qp[ix][iz]=0; qa[ix][iz]=0; } } if(sout) sf=sf_floatalloc2(fdm->nzpad,fdm->nxpad); } /*------------------------------------------------------------*/ if(dabc) { abc = abcone2d_make(NOP,dt,vp,fsrf,fdm); /* one-way */ spo = sponge_make(fdm->nb); /* sponge */ } /*------------------------------------------------------------*/ /* * MAIN LOOP */ /*------------------------------------------------------------*/ if(verb) fprintf(stderr,"\n"); for (it=0; it<nt; it++) { if(verb) fprintf(stderr,"\b\b\b\b\b%d",it); /* compute acceleration */ switch(atype[0]) { case 't': if(uses) { #ifdef _OPENMP #pragma omp parallel for \ schedule(dynamic,fdm->ompchunk) \ private(ix,iz,H1p,H2p,H1q,H2q,st,ct) \ shared(fdm,pa,po,qa,qo, \ cox,cax,cbx,c1x,c2x, \ coz,caz,cbz,c1z,c2z, \ vpn,vpz,vpx,vsz, \ sit,cot) #endif for (ix=NOP; ix<fdm->nxpad-NOP; ix++) { for(iz=NOP; iz<fdm->nzpad-NOP; iz++) { st=sit[ix][iz]; ct=cot[ix][iz]; H1p = H1(po,ix,iz, \ st,ct, \ cox,cax,cbx,c1x,c2x, \ coz,caz,cbz,c1z,c2z); H2p = H2(po,ix,iz, \ st,ct, \ cox,cax,cbx,c1x,c2x, \ coz,caz,cbz,c1z,c2z); H1q = H1(qo,ix,iz, \ st,ct, \ cox,cax,cbx,c1x,c2x, \ coz,caz,cbz,c1z,c2z); H2q = H2(qo,ix,iz, \ st,ct, \ cox,cax,cbx,c1x,c2x, \ coz,caz,cbz,c1z,c2z); /* p - main field */ pa[ix][iz] = H1p * vsz[ix][iz] + H2p * vpx[ix][iz] + H1q * vpz[ix][iz] - H1q * vsz[ix][iz]; /* q - auxiliary field */ qa[ix][iz] = H2p * vpn[ix][iz] - H2p * vsz[ix][iz] + H1q * vpz[ix][iz] + H2q * vsz[ix][iz]; } } } else { #ifdef _OPENMP #pragma omp parallel for \ schedule(dynamic,fdm->ompchunk) \ private(ix,iz,H2p,H1q,st,ct) \ shared(fdm,pa,po,qa,qo, \ cox,cax,cbx,c1x,c2x, \ coz,caz,cbz,c1z,c2z, \ vpn,vpz,vpx, \ sit,cot) #endif for (ix=NOP; ix<fdm->nxpad-NOP; ix++) { for(iz=NOP; iz<fdm->nzpad-NOP; iz++) { st=sit[ix][iz]; ct=cot[ix][iz]; H2p = H2(po,ix,iz, \ st,ct, \ cox,cax,cbx,c1x,c2x, \ coz,caz,cbz,c1z,c2z); H1q = H1(qo,ix,iz, \ st,ct, \ cox,cax,cbx,c1x,c2x, \ coz,caz,cbz,c1z,c2z); /* p - main field */ pa[ix][iz] = H2p * vpx[ix][iz] + H1q * vpz[ix][iz]; /* q - auxiliary field */ qa[ix][iz] = H2p * vpn[ix][iz] + H1q * vpz[ix][iz]; } } } break; case 'v': if(uses) { #ifdef _OPENMP #pragma omp parallel for \ schedule(dynamic,fdm->ompchunk) \ private(ix,iz,H1p,H2p,H1q,H2q) \ shared(fdm,pa,po,qa,qo, \ cox,cax,cbx, \ coz,caz,cbz, \ vpn,vpz,vpx,vsz) #endif for (ix=NOP; ix<fdm->nxpad-NOP; ix++) { for(iz=NOP; iz<fdm->nzpad-NOP; iz++) { H1p = Dzz(po,ix,iz,coz,caz,cbz); H1q = Dzz(qo,ix,iz,coz,caz,cbz); H2p = Dxx(po,ix,iz,cox,cax,cbx); H2q = Dxx(qo,ix,iz,cox,cax,cbx); /* p - main field */ pa[ix][iz] = H1p * vsz[ix][iz] + H2p * vpx[ix][iz] + H1q * vpz[ix][iz] - H1q * vsz[ix][iz]; /* q - auxiliary field */ qa[ix][iz] = H2p * vpn[ix][iz] - H2p * vsz[ix][iz] + H1q * vpz[ix][iz] + H2q * vsz[ix][iz]; } } } else { #ifdef _OPENMP #pragma omp parallel for \ schedule(dynamic,fdm->ompchunk) \ private(ix,iz,H2p,H1q) \ shared(fdm,pa,po,qa,qo, \ cox,cax,cbx, \ coz,caz,cbz, \ vpn,vpx,vpz) #endif for (ix=NOP; ix<fdm->nxpad-NOP; ix++) { for(iz=NOP; iz<fdm->nzpad-NOP; iz++) { H1q = Dzz(qo,ix,iz,coz,caz,cbz); H2p = Dxx(po,ix,iz,cox,cax,cbx); /* p - main field */ pa[ix][iz] = H2p * vpx[ix][iz] + H1q * vpz[ix][iz]; /* q - auxiliary field */ qa[ix][iz] = H2p * vpn[ix][iz] + H1q * vpz[ix][iz]; } } } break; case 'i': default: #ifdef _OPENMP #pragma omp parallel for \ schedule(dynamic,fdm->ompchunk) \ private(ix,iz) \ shared(fdm,pa,po, \ cox,cax,cbx, \ coz,caz,cbz, \ vpz) #endif for (ix=NOP; ix<fdm->nxpad-NOP; ix++) { for(iz=NOP; iz<fdm->nzpad-NOP; iz++) { pa[ix][iz] = ( Dxx(po,ix,iz,cox,cax,cbx) + Dzz(po,ix,iz,coz,caz,cbz) ) * vpz[ix][iz]; } } break; } /* inject acceleration source */ if(expl) { sf_floatread(ww, 1,Fwav); ; lint2d_inject1(pa,ww[0],cs); if(atype[0] != 'i') lint2d_inject1(qa,ww[0],cs); } else { sf_floatread(ww,ns,Fwav); ; lint2d_inject(pa,ww,cs); if(atype[0] != 'i') lint2d_inject(qa,ww,cs); } /* step forward in time */ #ifdef _OPENMP #pragma omp parallel for \ schedule(dynamic,fdm->ompchunk) \ private(ix,iz) \ shared(fdm,pa,po,pm,pp,dt2) #endif for (ix=0; ix<fdm->nxpad; ix++) { for(iz=0; iz<fdm->nzpad; iz++) { pp[ix][iz] = 2*po[ix][iz] - pm[ix][iz] + pa[ix][iz] * dt2; } } /* circulate wavefield arrays */ pt=pm; pm=po; po=pp; pp=pt; if(atype[0] != 'i') { #ifdef _OPENMP #pragma omp parallel for \ schedule(dynamic,fdm->ompchunk) \ private(ix,iz) \ shared(fdm,qa,qo,qm,qp,dt2) #endif for (ix=0; ix<fdm->nxpad; ix++) { for(iz=0; iz<fdm->nzpad; iz++) { qp[ix][iz] = 2*qo[ix][iz] - qm[ix][iz] + qa[ix][iz] * dt2; } } /* circulate wavefield arrays */ qt=qm; qm=qo; qo=qp; qp=qt; } /* one-way abc apply */ if(dabc) { abcone2d_apply(po,pm,NOP,abc,fdm); sponge2d_apply(pm,spo,fdm); sponge2d_apply(po,spo,fdm); if(atype[0] != 'i') { abcone2d_apply(qo,qm,NOP,abc,fdm); sponge2d_apply(qm,spo,fdm); sponge2d_apply(qo,spo,fdm); } } /* compute stress */ if(sout && (atype[0] != 'i')) { #ifdef _OPENMP #pragma omp parallel for \ schedule(dynamic,fdm->ompchunk) \ private(ix,iz) \ shared(fdm,po,qo,sf) #endif for (ix=0; ix<fdm->nxpad; ix++) { for(iz=0; iz<fdm->nzpad; iz++) { sf[ix][iz] = po[ix][iz] + qo[ix][iz]; } } } /* extract data at receivers */ if(sout && (atype[0] != 'i')) {lint2d_extract(sf,dd,cr); } else { lint2d_extract(po,dd,cr);} if(it%jdata==0) sf_floatwrite(dd,nr,Fdat); /* extract wavefield in the "box" */ if(snap && it%jsnap==0) { if(sout && (atype[0] != 'i')) {cut2d(sf,pc,fdm,acz,acx); } else { cut2d(po,pc,fdm,acz,acx);} sf_floatwrite(pc[0],sf_n(acz)*sf_n(acx),Fwfl); } } if(verb) fprintf(stderr,"\n"); /*------------------------------------------------------------*/ /* deallocate arrays */ free(*pm); free(pm); free(*pp); free(pp); free(*po); free(po); free(*pa); free(pa); free(*pc); free(pc); free(*vp); free(vp); free(*vpz); free(vpz); if(atype[0] != 'i') { free(*qm); free(qm); free(*qp); free(qp); free(*qo); free(qo); free(*qa); free(qa); free(*vpn); free(vpn); free(*vpx); free(vpx); if(uses){ free(*vsz); free(vsz); } if(sout){ free(*sf); free(sf); } } if(atype[0] == 't') { free(*sit); free(sit); free(*cot); free(cot); } free(ww); free(ss); free(rr); free(dd); /*------------------------------------------------------------*/ exit (0); }
int main(int argc, char* argv[]) { bool verb; /* verbosity flag */ bool abc; /* absorbing boundary conditions flag */ bool free; /* free surface flag*/ bool snap; /* wavefield snapshots flag */ bool dens; int jsnap;/* save wavefield every *jsnap* time steps */ /* I/O files */ sf_file Fw,Fs,Fr; sf_file Fd,Fu; sf_file Fv=NULL; /* velocity */ sf_file Fe=NULL; /* density */ /* cube axes */ sf_axis at,az,ax,as,ar; int it,iz,ix,is,ir, iop; int nt,nz,nx,ns,nr,nz2,nx2; float z0,dz,x0,dx,idx,idz,dt,dt2; /* arrays */ pt2d *ss, *rr; /* source/receiver locations */ float *ww=NULL; /* wavelet */ float *dd=NULL; /* data */ float **vv=NULL; /* velocity */ float **ee=NULL; /* density */ float *fzs,*fxs, *fzr,*fxr; int *jzs,*jxs, *jzr,*jxr; float *ws00,*ws01,*ws10,*ws11; float *wr00,*wr01,*wr10,*wr11; float **um,**uo,**up,**ud,**vp,**ro,**tt,**ut; float *bzl,*bzh,*bxl,*bxh; /* boundary */ int nop=2; /* Laplacian operator size */ float c0, c1, c2; /* Laplacian operator coefficients */ float co,c1x,c2x,c1z,c2z; int nbz,nbx; /* boundary size */ float tz, tx; /* sponge boundary decay coefficients */ float dp; float ws; /* injected data */ int ompchunk; /* OpenMP data chunk size */ /*------------------------------------------------------------*/ /* init RSF */ sf_init(argc,argv); if(! sf_getint("ompchunk",&ompchunk)) ompchunk=1; if(! sf_getbool("verb",&verb)) verb=false; if(! sf_getbool( "abc",&abc )) abc=false; if(! sf_getbool("snap",&snap)) snap=false; if(! sf_getbool("free",&free)) free=false; if(! sf_getbool("dens",&dens)) dens=false; Fw = sf_input ("in" ); /* wavelet */ Fv = sf_input ("vel"); /* velocity */ Fs = sf_input ("sou"); /* sources */ Fr = sf_input ("rec"); /* receivers */ Fu = sf_output("wfl"); /* wavefield */ Fd = sf_output("out"); /* data */ if(dens) Fe = sf_input("den"); /* density */ /* read axes*/ at=sf_iaxa(Fw,1); sf_setlabel(at,"t"); if(verb) sf_raxa(at); /* time */ az=sf_iaxa(Fv,1); sf_setlabel(az,"z"); if(verb) sf_raxa(az); /* depth */ ax=sf_iaxa(Fv,2); sf_setlabel(ax,"x"); if(verb) sf_raxa(ax); /* space */ as=sf_iaxa(Fs,2); sf_setlabel(as,"s"); if(verb) sf_raxa(as); /* source */ ar=sf_iaxa(Fr,2); sf_setlabel(ar,"r"); if(verb) sf_raxa(ar); /* receiver */ nt=sf_n(at); dt=sf_d(at); nz=sf_n(az); nx=sf_n(ax); ns=sf_n(as); nr=sf_n(ar); /* configure wavefield snapshots */ if(snap) { if(! sf_getint("jsnap",&jsnap)) jsnap=nt; } /*------------------------------------------------------------*/ /* expand domain for absorbing boundary conditions */ if(abc) { if(! sf_getint("nbz",&nbz)) nbz=nop; if(nbz<nop) nbz=nop; if(! sf_getint("nbx",&nbx)) nbx=nop; if(nbx<nop) nbx=nop; if(! sf_getfloat("tz",&tz)) tz=0.025; if(! sf_getfloat("tx",&tx)) tx=0.025; } else { nbz=nop; nbx=nop; } /* expanded domain ( az+2 nz, ax+2 nx ) */ nz2=nz+2*nbz; dz=sf_d(az); z0=sf_o(az)-nbz*dz; nx2=nx+2*nbx; dx=sf_d(ax); x0=sf_o(ax)-nbx*dx; sf_setn(az,nz2); sf_seto(az,z0); if(verb) sf_raxa(az); sf_setn(ax,nx2); sf_seto(ax,x0); if(verb) sf_raxa(ax); /*------------------------------------------------------------*/ /* setup output data header */ sf_oaxa(Fd,ar,1); sf_oaxa(Fd,at,2); /* setup output wavefield header */ if(snap) { sf_setn(at,nt/jsnap); sf_setd(at,dt*jsnap); sf_oaxa(Fu,az,1); sf_oaxa(Fu,ax,2); sf_oaxa(Fu,at,3); } /* Laplacian coefficients */ c0=-30./12.; c1=+16./12.; c2=- 1./12.; dt2 = dt*dt; idz = 1/dz; idx = 1/dx; co = c0 * (idx*idx+idz*idz); c1x= c1 * idx*idx; c2x= c2 * idx*idx; c1z= c1 * idz*idz; c2z= c2 * idz*idz; /*------------------------------------------------------------*/ /* allocate arrays */ ww=sf_floatalloc (nt); sf_floatread(ww ,nt ,Fw); vv=sf_floatalloc2(nz,nx); sf_floatread(vv[0],nz*nx,Fv); ee=sf_floatalloc2(nz,nx); if(dens) { sf_floatread(ee[0],nz*nx,Fe); } else { for (iz=0; iz<nz; iz++) { for (ix=0; ix<nx; ix++) { ee[ix][iz]=1; } } } /* allocate source/receiver point arrays */ ss = (pt2d*) sf_alloc(ns,sizeof(*ss)); rr = (pt2d*) sf_alloc(nr,sizeof(*rr)); pt2dread1(Fs,ss,ns,3); /* read 3 elements (x,z,v) */ pt2dread1(Fr,rr,nr,2); /* read 2 elements (x,z) */ dd=sf_floatalloc(nr); for(ir=0;ir<nr;ir++) { dd[ir]=0; } jzs=sf_intalloc(ns); fzs=sf_floatalloc(ns); jzr=sf_intalloc(nr); fzr=sf_floatalloc(nr); jxs=sf_intalloc(ns); fxs=sf_floatalloc(ns); jxr=sf_intalloc(nr); fxr=sf_floatalloc(nr); ws00 = sf_floatalloc(ns); wr00 = sf_floatalloc(nr); ws01 = sf_floatalloc(ns); wr01 = sf_floatalloc(nr); ws10 = sf_floatalloc(ns); wr10 = sf_floatalloc(nr); ws11 = sf_floatalloc(ns); wr11 = sf_floatalloc(nr); /*------------------------------------------------------------*/ for (is=0;is<ns;is++) { if(ss[is].z >= z0 && ss[is].z < z0 + (nz2-1)*dz && ss[is].x >= x0 && ss[is].x < x0 + (nx2-1)*dx) { jzs[is] = (int)( (ss[is].z-z0)/dz); fzs[is] = (ss[is].z-z0)/dz - jzs[is]; jxs[is] = (int)( (ss[is].x-x0)/dx); fxs[is] = (ss[is].x-x0)/dx - jxs[is]; } else { jzs[is] = 0; jxs[is] = 0; fzs[is] = 1; fxs[is] = 0; ss[is].v= 0; } ws00[is] = (1-fzs[is])*(1-fxs[is]); ws01[is] = ( fzs[is])*(1-fxs[is]); ws10[is] = (1-fzs[is])*( fxs[is]); ws11[is] = ( fzs[is])*( fxs[is]); } for (ir=0;ir<nr;ir++) { if(rr[ir].z >= z0 && rr[ir].z < z0 + (nz2-1)*dz && rr[ir].x >= x0 && rr[ir].x < x0 + (nx2-1)*dx) { jzr[ir] = (int)( (rr[ir].z-z0)/dz); fzr[ir] = (rr[ir].z-z0)/dz - jzr[ir]; jxr[ir] = (int)( (rr[ir].x-x0)/dx); fxr[ir] = (rr[ir].x-x0)/dx - jxr[ir]; rr[ir].v=1; } else { jzr[ir] = 0; fzr[ir] = 1; rr[ir].v= 0; } wr00[ir] = (1-fzr[ir])*(1-fxr[ir]); wr01[ir] = ( fzr[ir])*(1-fxr[ir]); wr10[ir] = (1-fzr[ir])*( fxr[ir]); wr11[ir] = ( fzr[ir])*( fxr[ir]); } /*------------------------------------------------------------*/ /* allocate temporary arrays */ um=sf_floatalloc2(nz2,nx2); uo=sf_floatalloc2(nz2,nx2); up=sf_floatalloc2(nz2,nx2); ud=sf_floatalloc2(nz2,nx2); tt=sf_floatalloc2(nz2,nx2); #ifdef _OPENMP #pragma omp parallel for schedule(dynamic,ompchunk) private(iz,ix) shared(nx2,nz2,um,uo,up,ud,tt) #endif for (iz=0; iz<nz2; iz++) { for (ix=0; ix<nx2; ix++) { um[ix][iz]=0; uo[ix][iz]=0; up[ix][iz]=0; ud[ix][iz]=0; tt[ix][iz]=1; } } /*------------------------------------------------------------*/ /* velocity in the expanded domain (vp=vv^2)*/ vp=sf_floatalloc2(nz2,nx2); ro=sf_floatalloc2(nz2,nx2); #ifdef _OPENMP #pragma omp parallel for schedule(dynamic,ompchunk) private(iz,ix) shared(nz,nx,vp,ro,vv,ee) #endif for (iz=0; iz<nz; iz++) { for (ix=0; ix<nx; ix++) { vp[nbx+ix][nbz+iz] = vv[ix][iz] * vv[ix][iz]; ro[nbx+ix][nbz+iz] = ee[ix][iz]; } } /* fill boundaries */ for (iz=0; iz<nbz; iz++) { for (ix=0; ix<nx2; ix++) { vp[ix][ iz ] = vp[ix][ nbz ]; vp[ix][nz2-iz-1] = vp[ix][nz2-nbz-1]; ro[ix][ iz ] = ro[ix][ nbz ]; ro[ix][nz2-iz-1] = ro[ix][nz2-nbz-1]; } } for (iz=0; iz<nz2; iz++) { for (ix=0; ix<nbx; ix++) { vp[ ix ][iz] = vp[ nbx ][iz]; vp[nx2-ix-1][iz] = vp[nx2-nbx-1][iz]; ro[ ix ][iz] = ro[ nbx ][iz]; ro[nx2-ix-1][iz] = ro[nx2-nbx-1][iz]; } } /*------------------------------------------------------------*/ /* free surface */ if(abc && free) { for (iz=0; iz<nbz; iz++) { for (ix=0; ix<nx2; ix++) { vp[ix][iz]=0; } } } /*------------------------------------------------------------*/ /* sponge ABC setup */ if(abc) { for (iz=0; iz<nbz; iz++) { for (ix=0; ix<nx2; ix++) { tt[ix][ iz ] = exp( - (tz*(nbz-iz))*(tz*(nbz-iz)) ); tt[ix][nz2-iz-1] = tt[ix][iz]; } } for (iz=0; iz<nz2; iz++) { for (ix=0; ix<nbx; ix++) { tt[ ix ][iz] = exp( - (tx*(nbx-ix))*(tx*(nbx-ix)) ); tt[nx2-ix-1][iz] = tt[ix][iz]; } } } /* one-way ABC setup */ bzl=sf_floatalloc(nx2); bzh=sf_floatalloc(nx2); bxl=sf_floatalloc(nz2); bxh=sf_floatalloc(nz2); for (ix=0;ix<nx2;ix++) { dp = vp[ix][ nop ] *dt/dz; bzl[ix] = (1-dp)/(1+dp); dp = vp[ix][nz2-nop-1] *dt/dz; bzh[ix] = (1-dp)/(1+dp); } for (iz=0;iz<nz2;iz++) { dp = vp[ nop ][iz] *dt/dx; bxl[iz] = (1-dp)/(1+dp); dp = vp[nx2-nop-1][iz] *dt/dx; bxh[iz] = (1-dp)/(1+dp); } /*------------------------------------------------------------*/ /* * MAIN LOOP */ if(verb) fprintf(stderr,"\n"); for (it=0; it<nt; it++) { if(verb) fprintf(stderr,"\b\b\b\b\b%d",it); if(dens) { /* variable density */ #ifdef _OPENMP #pragma omp parallel for schedule(dynamic,ompchunk) private(iz,ix) shared(nop,nx2,nz2,ud,uo,ro,co,c1x,c1z,c2x,c2z,idx,idz) #endif for( ix=nop; ix<nx2-nop; ix++) { for(iz=nop; iz<nz2-nop; iz++) { /* 4th order Laplacian operator */ ud[ix][iz] = co * uo[ix ][iz ] + c1x*(uo[ix-1][iz ] + uo[ix+1][iz ]) + c2x*(uo[ix-2][iz ] + uo[ix+2][iz ]) + c1z*(uo[ix ][iz-1] + uo[ix ][iz+1]) + c2z*(uo[ix ][iz-2] + uo[ix ][iz+2]); /* density terms */ ud[ix][iz] -= ( D1(uo,ix,iz,idz) * D1(ro,ix,iz,idz) + D2(uo,ix,iz,idx) * D2(ro,ix,iz,idx) ) / ro[ix][iz]; } } } else { /* constant density */ #ifdef _OPENMP #pragma omp parallel for schedule(dynamic,ompchunk) private(iz,ix) shared(nop,nx2,nz2,ud,uo,co,c1x,c1z,c2x,c2z) #endif for( ix=nop; ix<nx2-nop; ix++) { for(iz=nop; iz<nz2-nop; iz++) { /* 4th order Laplacian operator */ ud[ix][iz] = co * uo[ix ][iz ] + c1x*(uo[ix-1][iz ] + uo[ix+1][iz ]) + c2x*(uo[ix-2][iz ] + uo[ix+2][iz ]) + c1z*(uo[ix ][iz-1] + uo[ix ][iz+1]) + c2z*(uo[ix ][iz-2] + uo[ix ][iz+2]); } } } /* inject wavelet */ for (is=0;is<ns;is++) { ws = ww[it] * ss[is].v; ud[ jxs[is] ][ jzs[is] ] -= ws * ws00[is]; ud[ jxs[is] ][ jzs[is]+1] -= ws * ws01[is]; ud[ jxs[is]+1][ jzs[is] ] -= ws * ws10[is]; ud[ jxs[is]+1][ jzs[is]+1] -= ws * ws11[is]; } #ifdef _OPENMP #pragma omp parallel for schedule(dynamic,ompchunk) private(ix,iz) shared(nx2,nz2,ud,uo,um,up,vp,dt2) #endif for( ix=0; ix<nx2; ix++) { for(iz=0; iz<nz2; iz++) { /* time step and velocity scale*/ up[ix][iz] = 2*uo[ix][iz] - um[ix][iz] + ud[ix][iz] * vp[ix][iz] * dt2; } } /* circulate arrays */ ut=um; um=uo; uo=up; up=ut; /* one-way ABC apply */ if(abc) { #ifdef _OPENMP #pragma omp parallel for schedule(dynamic,ompchunk) private(ix,iz,iop) shared(nx2,nz2,nop,uo,um,bzl,bzh) #endif for(ix=0;ix<nx2;ix++) { for(iop=0;iop<nop;iop++) { iz = nop-iop; uo [ix][iz ] = um[ix][iz+1] +(um[ix][iz ] - uo[ix][iz+1]) * bzl[ix]; iz = nz2-nop+iop-1; uo [ix][iz ] = um[ix][iz-1] +(um[ix][iz ] - uo[ix][iz-1]) * bzh[ix]; } } #ifdef _OPENMP #pragma omp parallel for schedule(dynamic,1) private(ix,iz,iop) shared(nx2,nz2,nop,uo,um,bzl,bzh) #endif for(iop=0;iop<nop;iop++) { for(iz=0;iz<nz2;iz++) { ix = nop-iop; uo [ix ][iz] = um[ix+1][iz] +(um[ix ][iz] - uo[ix+1][iz]) * bxl[iz]; ix = nx2-nop+iop-1; uo [ix ][iz] = um[ix-1][iz] +(um[ix ][iz] - uo[ix-1][iz]) * bxh[iz]; } } } /* sponge ABC apply */ if(abc) { #ifdef _OPENMP #pragma omp parallel for schedule(dynamic,ompchunk) private(ix,iz) shared(nx2,nz2,uo,um,ud,tt) #endif for( ix=0; ix<nx2; ix++) { for(iz=0; iz<nz2; iz++) { uo[ix][iz] *= tt[ix][iz]; um[ix][iz] *= tt[ix][iz]; ud[ix][iz] *= tt[ix][iz]; } } } /* write wavefield */ if(snap && it%jsnap==0) { sf_floatwrite(uo[0],nz2*nx2,Fu); } /* collect data */ #ifdef _OPENMP #pragma omp parallel for schedule(dynamic,1) private(ir) shared(dd,rr,uo,jzr,wr00,wr01,wr10,wr11) #endif for (ir=0;ir<nr;ir++) { dd[ir] = uo[ jxr[ir] ][ jzr[ir] ] * wr00[ir] + uo[ jxr[ir] ][ jzr[ir]+1] * wr01[ir] + uo[ jxr[ir]+1][ jzr[ir] ] * wr10[ir] + uo[ jxr[ir]+1][ jzr[ir]+1] * wr11[ir]; dd[ir] *= rr[ir].v; } /* write data */ sf_floatwrite(dd,nr,Fd); } if(verb) fprintf(stderr,"\n"); exit (0); }
int main(int argc, char* argv[]) { bool verb,fsrf,snap,expl,dabc; int jsnap,ntsnap,jdata; /* OMP parameters */ #ifdef _OPENMP int ompnth; #endif /* I/O files */ sf_file Fwav=NULL; /* wavelet */ sf_file Fsou=NULL; /* sources */ sf_file Frec=NULL; /* receivers */ sf_file Fvel=NULL; /* velocity */ sf_file Fdat=NULL; /* data */ sf_file Fwfl=NULL; /* wavefield */ /* cube axes */ sf_axis at,az,ax; sf_axis as,ar; int nt,nz,nx,ns,nr,nb; int it,iz,ix; float dt,dz,dx,idz,idx,dt2; /* FDM structure */ fdm2d fdm=NULL; abcone2d abc=NULL; sponge spo=NULL; /* I/O arrays */ float *ww=NULL; /* wavelet */ pt2d *ss=NULL; /* sources */ pt2d *rr=NULL; /* receivers */ float *dd=NULL; /* data */ float **tt=NULL; float **vp=NULL; /* velocity */ float **vp2=NULL; float **vv2=NULL; float **vh2=NULL; float **rm,**ro,**rp,**ra,**rt; /* main wavefield */ float **qm,**qo,**qp,**qa,**qt; /* auxiliary wavefield */ /* linear interpolation weights/indices */ lint2d cs,cr; /* FD operator size */ float cox,coz,cax,cbx,caz,cbz; /* wavefield cut params */ sf_axis acz=NULL,acx=NULL; int nqz,nqx; float oqz,oqx; float dqz,dqx; float **qc=NULL; float H2q,H1r; /*------------------------------------------------------------*/ /* init RSF */ sf_init(argc,argv); /*------------------------------------------------------------*/ /* OMP parameters */ #ifdef _OPENMP ompnth=omp_init(); #endif /*------------------------------------------------------------*/ if(! sf_getbool("verb",&verb)) verb=false; /* verbosity flag */ if(! sf_getbool("snap",&snap)) snap=false; /* wavefield snapshots flag */ if(! sf_getbool("free",&fsrf)) fsrf=false; /* free surface flag */ if(! sf_getbool("expl",&expl)) expl=false; /* "exploding reflector" */ if(! sf_getbool("dabc",&dabc)) dabc=false; /* absorbing BC */ /*------------------------------------------------------------*/ /*------------------------------------------------------------*/ /* I/O files */ Fwav = sf_input ("in" ); /* wavelet */ Fvel = sf_input ("vel"); /* velocity */ Fsou = sf_input ("sou"); /* sources */ Frec = sf_input ("rec"); /* receivers */ Fwfl = sf_output("wfl"); /* wavefield */ Fdat = sf_output("out"); /* data */ /*------------------------------------------------------------*/ /* axes */ at = sf_iaxa(Fwav,2); sf_setlabel(at,"t"); if(verb) sf_raxa(at); /* time */ az = sf_iaxa(Fvel,1); sf_setlabel(az,"z"); if(verb) sf_raxa(az); /* depth */ ax = sf_iaxa(Fvel,2); sf_setlabel(ax,"x"); if(verb) sf_raxa(ax); /* space */ as = sf_iaxa(Fsou,2); sf_setlabel(as,"s"); if(verb) sf_raxa(as); /* sources */ ar = sf_iaxa(Frec,2); sf_setlabel(ar,"r"); if(verb) sf_raxa(ar); /* receivers */ nt = sf_n(at); dt = sf_d(at); nz = sf_n(az); dz = sf_d(az); nx = sf_n(ax); dx = sf_d(ax); ns = sf_n(as); nr = sf_n(ar); /*------------------------------------------------------------*/ /*------------------------------------------------------------*/ /* other execution parameters */ if(! sf_getint("jdata",&jdata)) jdata=1; if(snap) { /* save wavefield every *jsnap* time steps */ if(! sf_getint("jsnap",&jsnap)) jsnap=nt; } /*------------------------------------------------------------*/ /*------------------------------------------------------------*/ /* expand domain for FD operators and ABC */ if( !sf_getint("nb",&nb) || nb<NOP) nb=NOP; fdm=fdutil_init(verb,fsrf,az,ax,nb,1); sf_setn(az,fdm->nzpad); sf_seto(az,fdm->ozpad); if(verb) sf_raxa(az); sf_setn(ax,fdm->nxpad); sf_seto(ax,fdm->oxpad); if(verb) sf_raxa(ax); /*------------------------------------------------------------*/ /*------------------------------------------------------------*/ /* setup output data header */ sf_oaxa(Fdat,ar,1); sf_setn(at,nt/jdata); sf_setd(at,dt*jdata); sf_oaxa(Fdat,at,2); /* setup output wavefield header */ if(snap) { if(!sf_getint ("nqz",&nqz)) nqz=sf_n(az); if(!sf_getint ("nqx",&nqx)) nqx=sf_n(ax); if(!sf_getfloat("oqz",&oqz)) oqz=sf_o(az); if(!sf_getfloat("oqx",&oqx)) oqx=sf_o(ax); dqz=sf_d(az); dqx=sf_d(ax); acz = sf_maxa(nqz,oqz,dqz); sf_raxa(acz); acx = sf_maxa(nqx,oqx,dqx); sf_raxa(acx); /* check if the imaging window fits in the wavefield domain */ qc=sf_floatalloc2(sf_n(acz),sf_n(acx)); ntsnap=0; for(it=0; it<nt; it++) { if(it%jsnap==0) ntsnap++; } sf_setn(at, ntsnap); sf_setd(at,dt*jsnap); if(verb) sf_raxa(at); sf_oaxa(Fwfl,acz,1); sf_oaxa(Fwfl,acx,2); sf_oaxa(Fwfl,at, 3); } if(expl) { ww = sf_floatalloc( 1); } else { ww = sf_floatalloc(ns); } dd = sf_floatalloc(nr); /*------------------------------------------------------------*/ /* setup source/receiver coordinates */ ss = (pt2d*) sf_alloc(ns,sizeof(*ss)); rr = (pt2d*) sf_alloc(nr,sizeof(*rr)); pt2dread1(Fsou,ss,ns,2); /* read (x,z) coordinates */ pt2dread1(Frec,rr,nr,2); /* read (x,z) coordinates */ cs = lint2d_make(ns,ss,fdm); cr = lint2d_make(nr,rr,fdm); /*------------------------------------------------------------*/ /* setup FD coefficients */ idz = 1/dz; idx = 1/dx; cox= C0 * (idx*idx); cax= CA * idx*idx; cbx= CB * idx*idx; coz= C0 * (idz*idz); caz= CA * idz*idz; cbz= CB * idz*idz; /* precompute dt^2*/ dt2 = dt*dt; /*------------------------------------------------------------*/ tt = sf_floatalloc2(nz,nx); /*------------------------------------------------------------*/ /* input velocity */ vp =sf_floatalloc2(fdm->nzpad,fdm->nxpad); vp2 =sf_floatalloc2(fdm->nzpad,fdm->nxpad); vv2 =sf_floatalloc2(fdm->nzpad,fdm->nxpad); vh2 =sf_floatalloc2(fdm->nzpad,fdm->nxpad); sf_floatread(tt[0],nz*nx,Fvel ); expand(tt,vv2,fdm); /* vertical v */ sf_floatread(tt[0],nz*nx,Fvel ); expand(tt,vp2,fdm); /* NMO v */ sf_floatread(tt[0],nz*nx,Fvel ); expand(tt,vh2,fdm); /* horizontal v */ for (ix=0; ix<fdm->nxpad; ix++) { for(iz=0; iz<fdm->nzpad; iz++) { vp2[ix][iz] = vp2[ix][iz] * vp2[ix][iz]; vv2[ix][iz] = vv2[ix][iz] * vv2[ix][iz]; vh2[ix][iz] = vh2[ix][iz] * vh2[ix][iz]; } } if(fsrf) { /* free surface */ for (ix=0; ix<fdm->nxpad; ix++) { for(iz=0; iz<fdm->nb; iz++) { vp2[ix][iz]=0; vv2[ix][iz]=0; vh2[ix][iz]=0; } } } /*------------------------------------------------------------*/ free(*tt); free(tt); /*------------------------------------------------------------*/ /*------------------------------------------------------------*/ /* allocate wavefield arrays */ qm=sf_floatalloc2(fdm->nzpad,fdm->nxpad); qo=sf_floatalloc2(fdm->nzpad,fdm->nxpad); qp=sf_floatalloc2(fdm->nzpad,fdm->nxpad); qa=sf_floatalloc2(fdm->nzpad,fdm->nxpad); rm=sf_floatalloc2(fdm->nzpad,fdm->nxpad); ro=sf_floatalloc2(fdm->nzpad,fdm->nxpad); rp=sf_floatalloc2(fdm->nzpad,fdm->nxpad); ra=sf_floatalloc2(fdm->nzpad,fdm->nxpad); for (ix=0; ix<fdm->nxpad; ix++) { for(iz=0; iz<fdm->nzpad; iz++) { qm[ix][iz]=0; qo[ix][iz]=0; qp[ix][iz]=0; qa[ix][iz]=0; rm[ix][iz]=0; ro[ix][iz]=0; rp[ix][iz]=0; ra[ix][iz]=0; } } /*------------------------------------------------------------*/ if(dabc) { /* one-way abc setup */ abc = abcone2d_make(NOP,dt,vp,fsrf,fdm); /* sponge abc setup */ spo = sponge_make(fdm->nb); } /*------------------------------------------------------------*/ /* * MAIN LOOP */ /*------------------------------------------------------------*/ if(verb) fprintf(stderr,"\n"); for (it=0; it<nt; it++) { if(verb) fprintf(stderr,"\b\b\b\b\b%d",it); #ifdef _OPENMP #pragma omp parallel for \ schedule(dynamic,fdm->ompchunk) \ private(ix,iz,H2q,H1r) \ shared(fdm,ra,ro,qa,qo,cox,coz,cax,caz,cbx,cbz,idx,idz,vp2) #endif for (ix=NOP; ix<fdm->nxpad-NOP; ix++) { for(iz=NOP; iz<fdm->nzpad-NOP; iz++) { H2q = Dxx(qo,ix,iz,cox,cax,cbx); H1r = Dzz(ro,ix,iz,coz,caz,cbz); /* main field - q */ qa[ix][iz] = H2q * vh2[ix][iz] + H1r * vv2[ix][iz] ; /* auxiliary field - r */ ra[ix][iz] = H2q * vp2[ix][iz] + H1r * vv2[ix][iz] ; } } /* inject acceleration source */ if(expl) { sf_floatread(ww, 1,Fwav); lint2d_inject1(ra,ww[0],cs); lint2d_inject1(qa,ww[0],cs); } else { sf_floatread(ww,ns,Fwav); lint2d_inject(ra,ww,cs); lint2d_inject(qa,ww,cs); } /* step forward in time */ #ifdef _OPENMP #pragma omp parallel for \ schedule(dynamic,fdm->ompchunk) \ private(ix,iz) \ shared(fdm,ra,ro,rm,rp,qa,qo,qm,qp,dt2) #endif for (ix=0; ix<fdm->nxpad; ix++) { for(iz=0; iz<fdm->nzpad; iz++) { qp[ix][iz] = 2*qo[ix][iz] - qm[ix][iz] + qa[ix][iz] * dt2; rp[ix][iz] = 2*ro[ix][iz] - rm[ix][iz] + ra[ix][iz] * dt2; } } /* circulate wavefield arrays */ qt=qm; qm=qo; qo=qp; qp=qt; rt=rm; rm=ro; ro=rp; rp=rt; if(dabc) { /* one-way abc apply */ abcone2d_apply(qo,qm,NOP,abc,fdm); sponge2d_apply(qm,spo,fdm); sponge2d_apply(qo,spo,fdm); sponge2d_apply(qp,spo,fdm); /* one-way abc apply */ abcone2d_apply(ro,rm,NOP,abc,fdm); sponge2d_apply(rm,spo,fdm); sponge2d_apply(ro,spo,fdm); sponge2d_apply(rp,spo,fdm); } /* extract data */ lint2d_extract(qo,dd,cr); if(snap && it%jsnap==0) { cut2d(qo,qc,fdm,acz,acx); sf_floatwrite(qc[0],sf_n(acz)*sf_n(acx),Fwfl); } if( it%jdata==0) sf_floatwrite(dd,nr,Fdat); } if(verb) fprintf(stderr,"\n"); /*------------------------------------------------------------*/ /* deallocate arrays */ free(*rm); free(rm); free(*rp); free(rp); free(*ro); free(ro); free(*ra); free(ra); free(*qm); free(qm); free(*qp); free(qp); free(*qo); free(qo); free(*qa); free(qa); free(*qc); free(qc); free(*vp); free(vp); free(*vp2); free(vp2); free(*vh2); free(vh2); free(*vv2); free(vv2); free(ww); free(ss); free(rr); free(dd); exit (0); }
int main(int argc, char* argv[]) { int jt, jtm, is, st; /* index */ int nt, n1, n2, ns, ng, m[SF_MAX_DIM], nm; /* dimensions */ float ot, o1, d1; /* original */ sf_file in, dat, wfl, vel, sgrid, ggrid; /* I/O files */ float **wvlt; sf_axis ax; HVel hv; HCoord hs, hg; bool verb; sf_init(argc,argv); in = sf_input ("in"); /* source wavelet \n \t nt X 1: regular shot gather \t nt X ns: simultaneous source shotting */ vel = sf_input ("vel"); /* velocity field */ sgrid = sf_input ("sgrid"); /* source grid */ ggrid = sf_input ("ggrid"); /* geophone grid */ dat = sf_output("out"); /* seismic data */ if(sf_getstring("wfl")!=NULL) wfl = sf_output("wfl"); /* wavefield movie file */ else wfl=NULL; if (!sf_getint("jt",&jt)) jt=1; /* time interval in observation system */ if (!sf_getint("jtm",&jtm)) jtm=100; /* time interval of wave movie */ if (!sf_getfloat("ot", &ot)) ot = 0.0; /* time delay */ if (!sf_getbool("verb", &verb)) verb = false; /* verbosity */ /* velocity and observation system */ hv = obs_vel(vel); m[0] = sf_n(hv->z); nm = 1; if(hv->nd >= 2) {m[1] = sf_n(hv->x); nm=2;} if(hv->nd >= 3) {m[2] = sf_n(hv->y); nm=3;} hs = obs_coord(sgrid, m, nm); hg = obs_coord(ggrid, m, nm); ns = sf_n(hs->a2); ng = sf_n(hg->a2); /* waveform */ ax = sf_iaxa(in, 1); n1 = sf_n(ax); o1 = sf_o(ax); d1 = sf_d(ax); if(!sf_histint(in, "n2", &n2) || n2 != ns) n2=1; wvlt = sf_floatalloc2(n1, n2); sf_floatread(wvlt[0], n1*n2, in); if(ot<o1) ot=o1; st = (ot-o1)/d1; nt = (n1-st+1)/jt; sf_setn(ax, nt); sf_setd(ax, d1*jt); sf_seto(ax, ot); sf_oaxa(dat, ax, 1); sf_oaxa(dat, hg->a2, 2); if(n2==1) sf_oaxa(dat, hs->a2, 3); if(wfl!=NULL) { sf_oaxa(wfl, hv->z, 1); if(hv->nd >= 2) sf_oaxa(wfl, hv->x, 2); if(hv->nd >= 3) sf_oaxa(wfl, hv->y, 3); sf_setn(ax, (n1-st+1)/jtm); sf_setd(ax, d1*jtm); sf_seto(ax, ot); sf_oaxa(wfl, ax, hv->nd+1); if(n2==1) sf_oaxa(wfl, hs->a2, hv->nd+2); } wavmod_init(hv, d1, n1, st, jt, jtm, hg->p, ng, verb); if(n2==1) for (is=0; is < ns; is++) { wavmod_shot(dat, wfl, 1, hs->p+is, wvlt); if(verb) sf_warning("shot %d of %d", is, ns/n2); } else wavmod_shot(dat, wfl, ns, hs->p, wvlt); wavmod_close(); free(wvlt[0]); free(wvlt); return (0); }
int main(int argc, char* argv[]) { bool verb,fsrf,snap,dabc; int jsnap,ntsnap; int jdata; /* I/O files */ sf_file Fwav=NULL; /* wavelet */ sf_file Fsou=NULL; /* sources */ sf_file Frec=NULL; /* receivers */ sf_file Fvel=NULL; /* velocity */ sf_file Fref=NULL; /* reflectivity */ sf_file Fden=NULL; /* density */ sf_file Fdat=NULL; /* data (background) */ sf_file Fwfl=NULL; /* wavefield (background) */ sf_file Flid=NULL; /* data (scattered) */ sf_file Fliw=NULL; /* wavefield (scattered) */ /* I/O arrays */ float *ww=NULL; /* wavelet */ pt3d *ss=NULL; /* sources */ pt3d *rr=NULL; /* receivers */ float ***vpin=NULL; /* velocity */ float ***roin=NULL; /* density */ float ***rfin=NULL; /* reflectivity */ float ***vp=NULL; /* velocity in expanded domain */ float ***ro=NULL; /* density in expanded domain */ float ***iro=NULL; /* buoyancy in the expanded domain */ float ***rf=NULL; /* reflectivity in expanded domain */ float *bdd=NULL; /* data (background) */ float *sdd=NULL; /* data (scattered) */ float ***vt=NULL; /* temporary vp*vp * dt*dt */ float ***fsrfbck=NULL; /* ghost cells for free surface BC */ float ***fsrfsct=NULL; /* ghost cells for free surface BC */ float ***bum,***buo,***bup,***bua,***buat,***but; /* wavefield: um = U @ t-1; uo = U @ t; up = U @ t+1 */ float ***sum,***suo,***sup,***sua,***suat,***sut; /* wavefield: um = U @ t-1; uo = U @ t; up = U @ t+1 */ /* cube axes */ sf_axis at,a1,a2,a3,as,ar; int nt,n1,n2,n3,ns,nr,nb; int it,i1,i2,i3; float dt,d1,d2,d3,id1,id2,id3,dt2; /* linear interpolation weights/indices */ lint3d cs,cr; fdm3d fdm; abcone3d abc; /* abc */ sponge spo; /* FD coefficients */ float c1x,c1y,c1z, c2x,c2y,c2z, c3x,c3y,c3z; int ompchunk; #ifdef _OPENMP int ompnth,ompath; #endif sf_axis ac1=NULL,ac2=NULL,ac3=NULL; int nqz,nqx,nqy; float oqz,oqx,oqy; float dqz,dqx,dqy; float ***uc=NULL; /* for benchmarking */ clock_t start_t, end_t; float total_t; /*------------------------------------------------------------*/ /* init RSF */ sf_init(argc,argv); if(! sf_getint("ompchunk",&ompchunk)) ompchunk=1; /* OpenMP data chunk size */ #ifdef _OPENMP if(! sf_getint("ompnth", &ompnth)) ompnth=0; /* OpenMP available threads */ #pragma omp parallel ompath=omp_get_num_threads(); if(ompnth<1) ompnth=ompath; omp_set_num_threads(ompnth); sf_warning("using %d threads of a total of %d",ompnth,ompath); #endif if(! sf_getbool("verb",&verb)) verb=false; /* verbosity flag */ if(! sf_getbool("snap",&snap)) snap=false; /* wavefield snapshots flag */ if(! sf_getbool("dabc",&dabc)) dabc=false; /* Absorbing BC */ if(! sf_getbool("free",&fsrf)) fsrf=false; /* free surface flag */ Fwav = sf_input ("in" ); /* wavelet */ Fsou = sf_input ("sou"); /* sources */ Frec = sf_input ("rec"); /* receivers */ Fvel = sf_input ("vel"); /* velocity */ Fden = sf_input ("den"); /* density */ Fref = sf_input ("ref"); /* reflectivity */ Fwfl = sf_output("wfl"); /* wavefield */ Fdat = sf_output("out"); /* data */ Fliw = sf_output("liw"); /* wavefield (scattered) */ Flid = sf_output("lid"); /* data (scattered) */ /* axes */ at = sf_iaxa(Fwav,2); sf_setlabel(at,"t"); if(verb) sf_raxa(at); /* time */ as = sf_iaxa(Fsou,2); sf_setlabel(as,"s"); if(verb) sf_raxa(as); /* sources */ ar = sf_iaxa(Frec,2); sf_setlabel(ar,"r"); if(verb) sf_raxa(ar); /* receivers */ a1 = sf_iaxa(Fvel,1); sf_setlabel(a1,"z"); if(verb) sf_raxa(a1); /* z */ a2 = sf_iaxa(Fvel,2); sf_setlabel(a2,"x"); if(verb) sf_raxa(a2); /* x */ a3 = sf_iaxa(Fvel,3); sf_setlabel(a3,"y"); if(verb) sf_raxa(a3); /* y */ nt = sf_n(at); dt = sf_d(at); ns = sf_n(as); nr = sf_n(ar); n1 = sf_n(a1); d1 = sf_d(a1); n2 = sf_n(a2); d2 = sf_d(a2); n3 = sf_n(a3); d3 = sf_d(a3); if(! sf_getint("jdata",&jdata)) jdata=1; if(snap) { /* save wavefield every *jsnap* time steps */ if(! sf_getint("jsnap",&jsnap)) jsnap=nt; } /*------------------------------------------------------------*/ /* expand domain for FD operators and ABC */ if( !sf_getint("nb",&nb) || nb<NOP) nb=NOP; fdm=fdutil3d_init(verb,fsrf,a1,a2,a3,nb,ompchunk); sf_setn(a1,fdm->nzpad); sf_seto(a1,fdm->ozpad); if(verb) sf_raxa(a1); sf_setn(a2,fdm->nxpad); sf_seto(a2,fdm->oxpad); if(verb) sf_raxa(a2); sf_setn(a3,fdm->nypad); sf_seto(a3,fdm->oypad); if(verb) sf_raxa(a3); /*------------------------------------------------------------*/ /* setup output data header */ sf_oaxa(Fdat,ar,1); sf_oaxa(Flid,ar,1); sf_setn(at,nt/jdata); sf_setd(at,dt*jdata); sf_oaxa(Fdat,at,2); sf_oaxa(Flid,at,2); /* setup output wavefield header */ if(snap) { if(!sf_getint ("nqz",&nqz)) nqz=sf_n(a1); if(!sf_getint ("nqx",&nqx)) nqx=sf_n(a2); if(!sf_getint ("nqy",&nqy)) nqy=sf_n(a3); if(!sf_getfloat("oqz",&oqz)) oqz=sf_o(a1); if(!sf_getfloat("oqx",&oqx)) oqx=sf_o(a2); if(!sf_getfloat("oqy",&oqy)) oqy=sf_o(a3); dqz=sf_d(a1); dqx=sf_d(a2); dqy=sf_d(a3); ac1 = sf_maxa(nqz,oqz,dqz); ac2 = sf_maxa(nqx,oqx,dqx); ac3 = sf_maxa(nqy,oqy,dqy); /* check if the imaging window fits in the wavefield domain */ uc=sf_floatalloc3(sf_n(ac1),sf_n(ac2),sf_n(ac3)); ntsnap=0; for(it=0; it<nt; it++) { if(it%jsnap==0) ntsnap++; } sf_setn(at, ntsnap); sf_setd(at,dt*jsnap); if(verb) sf_raxa(at); /* sf_setn(at,nt/jsnap); sf_setd(at,dt*jsnap); */ sf_oaxa(Fwfl,ac1,1); sf_oaxa(Fwfl,ac2,2); sf_oaxa(Fwfl,ac3,3); sf_oaxa(Fwfl,at, 4); sf_oaxa(Fliw,ac1,1); sf_oaxa(Fliw,ac2,2); sf_oaxa(Fliw,ac3,3); sf_oaxa(Fliw,at, 4); } /* source wavelet array allocation */ ww = sf_floatalloc(ns); /* data array allocation*/ bdd = sf_floatalloc(nr); sdd = sf_floatalloc(nr); /*------------------------------------------------------------*/ /* setup source/receiver coordinates */ ss = (pt3d*) sf_alloc(ns,sizeof(*ss)); rr = (pt3d*) sf_alloc(nr,sizeof(*rr)); pt3dread1(Fsou,ss,ns,3); /* read (x,y,z) coordinates */ pt3dread1(Frec,rr,nr,3); /* read (x,y,z) coordinates */ cs = lint3d_make(ns,ss,fdm); cr = lint3d_make(nr,rr,fdm); fdbell3d_init(1); /*------------------------------------------------------------*/ /* setup FD coefficients */ dt2 = dt*dt; id1 = 1/d1; id2 = 1/d2; id3 = 1/d3; c1x = C1*id2; c1y = C1*id3; c1z = C1*id1; c2x = C2*id2; c2y = C2*id3; c2z = C2*id1; c3x = C3*id2; c3y = C3*id3; c3z = C3*id1; /*------------------------------------------------------------*/ /* input density */ roin = sf_floatalloc3(n1, n2, n3); ro = sf_floatalloc3(fdm->nzpad, fdm->nxpad, fdm->nypad); iro = sf_floatalloc3(fdm->nzpad, fdm->nxpad, fdm->nypad); sf_floatread(roin[0][0],n1*n2*n3,Fden); expand3d(roin,ro,fdm); /* inverse density to avoid computation on the fly */ /* there is 1 shell for i1=0 || i2=0 || i3=0 that is zero, no big deal but better to fix it */ for (i3=1; i3<fdm->nypad; i3++) { for (i2=1; i2<fdm->nxpad; i2++) { for (i1=1; i1<fdm->nzpad; i1++) { iro[i3][i2][i1] = 6./( 3*ro[i3 ][i2 ][i1 ] + ro[i3 ][i2 ][i1-1] + ro[i3 ][i2-1][i1 ] + ro[i3-1][i2 ][i1 ] ); } } } free(**roin); free(*roin); free(roin); /*------------------------------------------------------------*/ /* input velocity */ vpin = sf_floatalloc3(n1, n2, n3); vp = sf_floatalloc3(fdm->nzpad, fdm->nxpad, fdm->nypad); vt = sf_floatalloc3(fdm->nzpad, fdm->nxpad, fdm->nypad); sf_floatread(vpin[0][0],n1*n2*n3,Fvel); expand3d(vpin,vp,fdm); free(**vpin); free(*vpin); free(vpin); /*------------------------------------------------------------*/ /* input reflectivity */ rfin = sf_floatalloc3(n1, n2, n3); rf = sf_floatalloc3(fdm->nzpad, fdm->nxpad, fdm->nypad); sf_floatread(rfin[0][0],n1*n2*n3,Fref); expand3d(rfin,rf,fdm); free(**rfin); free(*rfin); free(rfin); for (i3=0; i3<fdm->nypad; i3++) { for (i2=0; i2<fdm->nxpad; i2++) { for (i1=0; i1<fdm->nzpad; i1++) { vt[i3][i2][i1] = vp[i3][i2][i1] * vp[i3][i2][i1] * dt2; } } } /* free surface */ if(fsrf) { fsrfbck = sf_floatalloc3(4*NOP, fdm->nxpad, fdm->nypad); fsrfsct = sf_floatalloc3(4*NOP, fdm->nxpad, fdm->nypad); } /*------------------------------------------------------------*/ /* allocate wavefield arrays */ bum = sf_floatalloc3(fdm->nzpad, fdm->nxpad, fdm->nypad); buo = sf_floatalloc3(fdm->nzpad, fdm->nxpad, fdm->nypad); bup = sf_floatalloc3(fdm->nzpad, fdm->nxpad, fdm->nypad); bua = sf_floatalloc3(fdm->nzpad, fdm->nxpad, fdm->nypad); buat = sf_floatalloc3(fdm->nzpad, fdm->nxpad, fdm->nypad); sum = sf_floatalloc3(fdm->nzpad, fdm->nxpad, fdm->nypad); suo = sf_floatalloc3(fdm->nzpad, fdm->nxpad, fdm->nypad); sup = sf_floatalloc3(fdm->nzpad, fdm->nxpad, fdm->nypad); sua = sf_floatalloc3(fdm->nzpad, fdm->nxpad, fdm->nypad); suat = sf_floatalloc3(fdm->nzpad, fdm->nxpad, fdm->nypad); for (i3=0; i3<fdm->nypad; i3++) { for (i2=0; i2<fdm->nxpad; i2++) { for (i1=0; i1<fdm->nzpad; i1++) { bum[i3][i2][i1]=0; buo[i3][i2][i1]=0; bup[i3][i2][i1]=0; bua[i3][i2][i1]=0; sum[i3][i2][i1]=0; suo[i3][i2][i1]=0; sup[i3][i2][i1]=0; sua[i3][i2][i1]=0; } } } /*------------------------------------------------------------*/ /* one-way abc setup */ abc = abcone3d_make(NOP,dt,vp,fsrf,fdm); /* sponge abc setup */ spo = sponge_make(fdm->nb); free(**vp); free(*vp); free(vp); /*--------------------------------------------------------------*/ /* */ /* MAIN LOOP */ /* */ /*--------------------------------------------------------------*/ if(verb) fprintf(stderr,"\nFORWARD BORN ACOUSTIC VARIABLE-DENSITY WAVE EXTRAPOLATION \n"); /* extrapolation */ start_t = clock(); for (it=0; it<nt; it++) { if(verb) fprintf(stderr,"%d/%d \r",it,nt); #ifdef _OPENMP #pragma omp parallel private(i3,i2,i1) #endif { if (fsrf) { /* free surface */ #ifdef _OPENMP #pragma omp for schedule(dynamic,fdm->ompchunk) #endif for (i3=0; i3<fdm->nypad; i3++) { for (i2=0; i2<fdm->nxpad; i2++) { for (i1=nb; i1<nb+2*NOP; i1++) { fsrfbck[i3][i2][2*NOP+(i1-nb) ] = buo[i3][i2][i1]; fsrfbck[i3][i2][2*NOP-(i1-nb)-1] = -buo[i3][i2][i1]; fsrfsct[i3][i2][2*NOP+(i1-nb) ] = suo[i3][i2][i1]; fsrfsct[i3][i2][2*NOP-(i1-nb)-1] = -suo[i3][i2][i1]; } } } } // spatial derivatives z #ifdef _OPENMP #pragma omp for schedule(dynamic,fdm->ompchunk) #endif for (i3=NOP; i3<fdm->nypad-NOP; i3++) { for (i2=NOP; i2<fdm->nxpad-NOP; i2++) { for (i1=NOP; i1<fdm->nzpad-NOP; i1++) { // gather buat[i3][i2][i1] = iro[i3][i2][i1]*( c3z*(buo[i3][i2][i1+2] - buo[i3][i2][i1-3]) + c2z*(buo[i3][i2][i1+1] - buo[i3][i2][i1-2]) + c1z*(buo[i3][i2][i1 ] - buo[i3][i2][i1-1]) ); suat[i3][i2][i1] = iro[i3][i2][i1]*( c3z*(suo[i3][i2][i1+2] - suo[i3][i2][i1-3]) + c2z*(suo[i3][i2][i1+1] - suo[i3][i2][i1-2]) + c1z*(suo[i3][i2][i1 ] - suo[i3][i2][i1-1]) ); } } } if (fsrf) { // free surface #ifdef _OPENMP #pragma omp for schedule(dynamic,fdm->ompchunk) #endif for (i3=NOP; i3<fdm->nypad-NOP; i3++) { for (i2=NOP; i2<fdm->nxpad-NOP; i2++) { for (i1=nb-NOP; i1<nb+NOP; i1++) { buat[i3][i2][i1] = iro[i3][i2][i1]*( c3z*(fsrfbck[i3][i2][2*NOP+(i1-nb)+2] - fsrfbck[i3][i2][2*NOP+(i1-nb)-3]) + c2z*(fsrfbck[i3][i2][2*NOP+(i1-nb)+1] - fsrfbck[i3][i2][2*NOP+(i1-nb)-2]) + c1z*(fsrfbck[i3][i2][2*NOP+(i1-nb) ] - fsrfbck[i3][i2][2*NOP+(i1-nb)-1]) ); suat[i3][i2][i1] = iro[i3][i2][i1]*( c3z*(fsrfsct[i3][i2][2*NOP+(i1-nb)+2] - fsrfsct[i3][i2][2*NOP+(i1-nb)-3]) + c2z*(fsrfsct[i3][i2][2*NOP+(i1-nb)+1] - fsrfsct[i3][i2][2*NOP+(i1-nb)-2]) + c1z*(fsrfsct[i3][i2][2*NOP+(i1-nb) ] - fsrfsct[i3][i2][2*NOP+(i1-nb)-1]) ); } } } } #ifdef _OPENMP #pragma omp for schedule(dynamic,fdm->ompchunk) #endif for (i3=NOP; i3<fdm->nypad-NOP; i3++) { for (i2=NOP; i2<fdm->nxpad-NOP; i2++) { for (i1=NOP; i1<fdm->nzpad-NOP; i1++) { // scatter bua[i3][i2][i1] = c1z*( buat[i3][i2][i1 ] - buat[i3][i2][i1+1]) + c2z*( buat[i3][i2][i1-1] - buat[i3][i2][i1+2]) + c3z*( buat[i3][i2][i1-2] - buat[i3][i2][i1+3]); sua[i3][i2][i1] = c1z*( suat[i3][i2][i1 ] - suat[i3][i2][i1+1]) + c2z*( suat[i3][i2][i1-1] - suat[i3][i2][i1+2]) + c3z*( suat[i3][i2][i1-2] - suat[i3][i2][i1+3]); } } } // spatial derivatives x #ifdef _OPENMP #pragma omp for schedule(dynamic,fdm->ompchunk) #endif for (i3=NOP; i3<fdm->nypad-NOP; i3++) { for (i2=NOP; i2<fdm->nxpad-NOP; i2++) { for (i1=NOP; i1<fdm->nzpad-NOP; i1++) { // gather buat[i3][i2][i1] = iro[i3][i2][i1]*( c3x*(buo[i3][i2+2][i1] - buo[i3][i2-3][i1]) + c2x*(buo[i3][i2+1][i1] - buo[i3][i2-2][i1]) + c1x*(buo[i3][i2 ][i1] - buo[i3][i2-1][i1]) ); suat[i3][i2][i1] = iro[i3][i2][i1]*( c3x*(suo[i3][i2+2][i1] - suo[i3][i2-3][i1]) + c2x*(suo[i3][i2+1][i1] - suo[i3][i2-2][i1]) + c1x*(suo[i3][i2 ][i1] - suo[i3][i2-1][i1]) ); } } } #ifdef _OPENMP #pragma omp for schedule(dynamic,fdm->ompchunk) #endif for (i3=NOP; i3<fdm->nypad-NOP; i3++) { for (i2=NOP; i2<fdm->nxpad-NOP; i2++) { for (i1=NOP; i1<fdm->nzpad-NOP; i1++) { // scatter bua[i3][i2 ][i1] += c1x*(buat[i3][i2 ][i1] - buat[i3][i2+1][i1]) + c2x*(buat[i3][i2-1][i1] - buat[i3][i2+2][i1]) + c3x*(buat[i3][i2-2][i1] - buat[i3][i2+3][i1]); sua[i3][i2 ][i1] += c1x*(suat[i3][i2 ][i1] - suat[i3][i2+1][i1]) + c2x*(suat[i3][i2-1][i1] - suat[i3][i2+2][i1]) + c3x*(suat[i3][i2-2][i1] - suat[i3][i2+3][i1]); } } } // spatial derivatives y #ifdef _OPENMP #pragma omp for schedule(dynamic,fdm->ompchunk) #endif for (i3=NOP; i3<fdm->nypad-NOP; i3++) { for (i2=NOP; i2<fdm->nxpad-NOP; i2++) { for (i1=NOP; i1<fdm->nzpad-NOP; i1++) { // gather buat[i3][i2][i1] = iro[i3][i2][i1]*( c3x*(buo[i3+2][i2][i1] - buo[i3-3][i2][i1]) + c2x*(buo[i3+1][i2][i1] - buo[i3-2][i2][i1]) + c1x*(buo[i3 ][i2][i1] - buo[i3-1][i2][i1]) ); suat[i3][i2][i1] = iro[i3][i2][i1]*( c3x*(suo[i3+2][i2][i1] - suo[i3-3][i2][i1]) + c2x*(suo[i3+1][i2][i1] - suo[i3-2][i2][i1]) + c1x*(suo[i3 ][i2][i1] - suo[i3-1][i2][i1]) ); } } } #ifdef _OPENMP #pragma omp for schedule(dynamic,fdm->ompchunk) #endif for (i3=NOP; i3<fdm->nypad-NOP; i3++) { for (i2=NOP; i2<fdm->nxpad-NOP; i2++) { for (i1=NOP; i1<fdm->nzpad-NOP; i1++) { // scatter bua[i3][i2][i1] += c1y*(buat[i3 ][i2][i1] - buat[i3+1][i2][i1]) + c2y*( buat[i3-1][i2][i1] - buat[i3+2][i2][i1]) + c3y*( buat[i3-2][i2][i1] - buat[i3+3][i2][i1]); sua[i3][i2][i1] += c1y*(suat[i3 ][i2][i1] - suat[i3+1][i2][i1]) + c2y*( suat[i3-1][i2][i1] - suat[i3+2][i2][i1]) + c3y*( suat[i3-2][i2][i1] - suat[i3+3][i2][i1]); } } } /* step forward in time */ #ifdef _OPENMP #pragma omp for schedule(dynamic,fdm->ompchunk) #endif for (i3=NOP; i3<fdm->nypad-NOP; i3++) { for (i2=NOP; i2<fdm->nxpad-NOP; i2++) { for (i1=NOP; i1<fdm->nzpad-NOP; i1++) { bup[i3][i2][i1] = 2*buo[i3][i2][i1] - bum[i3][i2][i1] - ro[i3][i2][i1]*vt[i3][i2][i1]*bua[i3][i2][i1]; sup[i3][i2][i1] = 2*suo[i3][i2][i1] - sum[i3][i2][i1] - ro[i3][i2][i1]*vt[i3][i2][i1]*sua[i3][i2][i1]; } } } /* single scattering */ #ifdef _OPENMP #pragma omp for schedule(dynamic,ompchunk) #endif for (i3=NOP; i3<fdm->nypad-NOP; i3++) { for (i2=NOP; i2<fdm->nxpad-NOP; i2++) { for (i1=NOP; i1<fdm->nzpad-NOP; i1++) { sup[i3][i2][i1] -= 2*rf[i3][i2][i1]*ro[i3][i2][i1]*bua[i3][i2][i1]*dt2; } } } } /* end of the parallel section */ /* inject acceleration source */ sf_floatread(ww,ns,Fwav); lint3d_bell(bup,ww,cs); /* extract data */ lint3d_extract(bup,bdd,cr); lint3d_extract(sup,sdd,cr); if(snap && it%jsnap==0) { cut3d(bup,uc,fdm,ac1,ac2,ac3); sf_floatwrite(uc[0][0],sf_n(ac1)*sf_n(ac2)*sf_n(ac3),Fwfl); cut3d(sup,uc,fdm,ac1,ac2,ac3); sf_floatwrite(uc[0][0],sf_n(ac1)*sf_n(ac2)*sf_n(ac3),Fliw); } if( it%jdata==0) { sf_floatwrite(bdd,nr,Fdat); sf_floatwrite(sdd,nr,Flid); } /* one-way abc apply*/ if (dabc) { abcone3d_apply(bup,buo,NOP,abc,fdm); sponge3d_apply(bup, spo,fdm); sponge3d_apply(buo, spo,fdm); abcone3d_apply(sup,suo,NOP,abc,fdm); sponge3d_apply(sup, spo,fdm); sponge3d_apply(suo, spo,fdm); } /* circulate wavefield arrays */ but=bum; bum=buo; buo=bup; bup=but; sut=sum; sum=suo; suo=sup; sup=sut; } /* end time loop */ end_t = clock(); if(verb) fprintf(stderr,"\n"); if (verb) { total_t = (float)(end_t - start_t) / CLOCKS_PER_SEC; fprintf(stderr,"Total time taken by CPU: %g\n", total_t ); fprintf(stderr,"Exiting of the program...\n"); } /*------------------------------------------------------------*/ /* deallocate arrays */ free(**bum); free(*bum); free(bum); free(**buo); free(*buo); free(buo); free(**bup); free(*bup); free(bup); free(**bua); free(*bua); free(bua); free(**buat); free(*buat); free(buat); free(**sum); free(*sum); free(sum); free(**suo); free(*suo); free(suo); free(**sup); free(*sup); free(sup); free(**sua); free(*sua); free(sua); free(**suat); free(*suat); free(suat); if(snap) { free(**uc); free(*uc); free(uc); } if (fsrf) { free(**fsrfbck); free(*fsrfbck); free(fsrfbck); free(**fsrfsct); free(*fsrfsct); free(fsrfsct); } free(**vt); free(*vt); free(vt); free(**ro); free(*ro); free(ro); free(**iro); free(*iro); free(iro); free(**rf); free(*rf); free(rf); free(ww); free(ss); free(rr); free(bdd); free(sdd); if (dabc) { free(spo); free(abc); } free(fdm); /* ------------------------------------------------------------------------------------------ */ /* CLOSE FILES AND EXIT */ if (Fwav!=NULL) sf_fileclose(Fwav); if (Fsou!=NULL) sf_fileclose(Fsou); if (Frec!=NULL) sf_fileclose(Frec); if (Fvel!=NULL) sf_fileclose(Fvel); if (Fden!=NULL) sf_fileclose(Fden); if (Fref!=NULL) sf_fileclose(Fref); if (Fdat!=NULL) sf_fileclose(Fdat); if (Fwfl!=NULL) sf_fileclose(Fwfl); if (Fliw!=NULL) sf_fileclose(Fliw); if (Flid!=NULL) sf_fileclose(Flid); exit (0); }
int main(int argc, char* argv[]) { bool verb,fsrf,snap,expl,dabc,abcone,is2D,cfl; bool ignore_interpolation = false; /* ignore interpolation for receivers - makes code faster, but only works when receivers are on grid points */ int jsnap,ntsnap,jdata; float fmax, safety; enum SourceType srctype; /* I/O files */ sf_file Fwav=NULL; /* wavelet */ sf_file Fsou=NULL; /* sources */ sf_file Frec=NULL; /* receivers */ sf_file Fvel=NULL; /* velocity */ sf_file Fden=NULL; /* density */ sf_file Fdat=NULL; /* data */ sf_file Fwfl=NULL; /* wavefield */ /*set all y variables to be either zero or null to avoid compiler warnings about being uninitialized */ /* cube axes */ sf_axis at,az,ax,ay=NULL; sf_axis as,ar; int nt,nz,nx,ny=0,ns,nr,nb; int it,iz,ix,iy=0; float dt,dz,dx,dy=0,idz,idx,idy=0; /* I/O arrays */ float *ww=NULL; /* wavelet */ float *dd=NULL; /* data */ /* FD operator size */ float co,cax,cbx,cay,cby,caz,cbz; /* wavefield cut params */ sf_axis acz=NULL,acx=NULL,acy=NULL; int nqz,nqx,nqy; float oqz,oqx,oqy; float dqz,dqx,dqy; /*------------------------------------------------------------*/ /* init RSF */ sf_init(argc,argv); /*------------------------------------------------------------*/ /* OMP parameters */ if( !sf_getbool("ignint",&ignore_interpolation)) ignore_interpolation = false; if(! sf_getbool("verb",&verb)) verb=false; /* verbosity flag */ if(! sf_getbool("snap",&snap)) snap=false; /* wavefield snapshots flag */ if(! sf_getbool("free",&fsrf)) fsrf=false; /* free surface flag */ if(! sf_getbool("expl",&expl)) expl=false; /* "exploding reflector" */ if(! sf_getbool("dabc",&dabc)) dabc=false; /* absorbing BC */ if(! sf_getbool("cfl",&cfl)) cfl=false; /* Use CFL check */ if(! sf_getbool("abcone",&abcone)) abcone=false; /* Use Zero-incident boundary condition*/ int ttype = 0; if(! sf_getint("srctype",&ttype)) ttype = 0; /* source type, see comments */ if(ttype < 0 || ttype > 1) sf_error("Invalid source type specified"); srctype = ttype; if (cfl) { if(! sf_getfloat("fmax",&fmax)) { /* max frequency for cfl check */ sf_error("CFL: Must specify fmax for CFL check"); } if(! sf_getfloat("safety",&safety) || safety < 0.0) safety= 0.8; /*safety factor for cfl check*/ } /*------------------------------------------------------------*/ /*------------------------------------------------------------*/ /* I/O files */ Fwav = sf_input ("in" ); /* wavelet */ Fvel = sf_input ("vel"); /* velocity */ Fsou = sf_input ("sou"); /* sources */ Frec = sf_input ("rec"); /* receivers */ Fwfl = sf_output("wfl"); /* wavefield */ Fdat = sf_output("out"); /* data */ Fden = sf_input ("den"); /* density */ /* Determine dimensionality, if 2D then axis 3 has n size of 1 */ sf_axis test = sf_iaxa(Fvel,3); if(sf_n(test) == 1) is2D = true; else is2D = false; /*------------------------------------------------------------*/ /* axes */ at = sf_iaxa(Fwav,2); sf_setlabel(at,"t"); if(verb) sf_raxa(at); /* time */ az = sf_iaxa(Fvel,1); sf_setlabel(az,"z"); if(verb) sf_raxa(az); /* depth */ ax = sf_iaxa(Fvel,2); sf_setlabel(ax,"x"); if(verb) sf_raxa(ax); /* space */ as = sf_iaxa(Fsou,2); sf_setlabel(as,"s"); if(verb) sf_raxa(as); /* sources */ ar = sf_iaxa(Frec,2); sf_setlabel(ar,"r"); if(verb) sf_raxa(ar); /* receivers */ nt = sf_n(at); dt = sf_d(at); nz = sf_n(az); dz = sf_d(az); nx = sf_n(ax); dx = sf_d(ax); ns = sf_n(as); nr = sf_n(ar); if(!is2D){ /*If 3D*/ ay=sf_iaxa(Fvel,3); sf_setlabel(ay,"y"); if(verb) sf_raxa(ay); /*space*/ ny=sf_n(ay); dy=sf_d(ay); } /*------------------------------------------------------------*/ /*------------------------------------------------------------*/ /* other execution parameters */ if(! sf_getint("jdata",&jdata)) jdata=1; if(snap) { /* save wavefield every *jsnap* time steps */ if(! sf_getint("jsnap",&jsnap)) jsnap=nt; } /*------------------------------------------------------------*/ if(is2D){ /* Begin 2d code */ /* FDM structure */ fdm2d fdm=NULL; abcone2d abc=NULL; sponge spo=NULL; pt2d *ss=NULL; /* sources */ pt2d *rr=NULL; /* receivers */ float **tt=NULL; float **ro=NULL; /* density */ float **roz=NULL; /* normalized 1st derivative of density on axis 1 */ float **rox=NULL; /* normalized 1st derivative of density on axis 2 */ float **vp=NULL; /* velocity */ float **vt=NULL; /* temporary vp*vp * dt*dt */ float **um,**uo,**up,**ua,**ut; /* wavefield: um = U @ t-1; uo = U @ t; up = U @ t+1 */ /* linear interpolation weights/indices */ lint2d cs,cr; float **uc=NULL; /*------------------------------------------------------------*/ /* expand domain for FD operators and ABC */ if( !sf_getint("nb",&nb) || nb<NOP) nb=NOP; fdm=fdutil_init(verb,fsrf,az,ax,nb,1); /*------------------------------------------------------------*/ /*------------------------------------------------------------*/ /* setup output data header */ sf_oaxa(Fdat,ar,1); sf_setn(at,nt/jdata); sf_setd(at,dt*jdata); sf_oaxa(Fdat,at,2); /* setup output wavefield header */ if(snap) { if(!sf_getint ("nqz",&nqz)) nqz=sf_n(az); if(!sf_getint ("nqx",&nqx)) nqx=sf_n(ax); if(!sf_getfloat("oqz",&oqz)) oqz=sf_o(az); if(!sf_getfloat("oqx",&oqx)) oqx=sf_o(ax); sf_setn(az,fdm->nzpad); sf_seto(az,fdm->ozpad); if(verb) sf_raxa(az); sf_setn(ax,fdm->nxpad); sf_seto(ax,fdm->oxpad); if(verb) sf_raxa(ax); dqz=sf_d(az); dqx=sf_d(ax); acz = sf_maxa(nqz,oqz,dqz); sf_raxa(acz); acx = sf_maxa(nqx,oqx,dqx); sf_raxa(acx); /* check if the imaging window fits in the wavefield domain */ uc=sf_floatalloc2(sf_n(acz),sf_n(acx)); ntsnap=0; for(it=0; it<nt; it++) { if(it%jsnap==0) ntsnap++; } sf_setn(at, ntsnap); sf_setd(at,dt*jsnap); if(verb) sf_raxa(at); sf_oaxa(Fwfl,acz,1); sf_oaxa(Fwfl,acx,2); sf_oaxa(Fwfl,at, 3); } if(expl) { ww = sf_floatalloc( 1); } else { ww = sf_floatalloc(ns); } dd = sf_floatalloc(nr); /*------------------------------------------------------------*/ /* setup source/receiver coordinates */ ss = (pt2d*) sf_alloc(ns,sizeof(*ss)); rr = (pt2d*) sf_alloc(nr,sizeof(*rr)); pt2dread1(Fsou,ss,ns,2); /* read (x,z) coordinates */ pt2dread1(Frec,rr,nr,2); /* read (x,z) coordinates */ cs = lint2d_make(ns,ss,fdm); cr = lint2d_make(nr,rr,fdm); /*------------------------------------------------------------*/ /* setup FD coefficients */ idz = 1/dz; idx = 1/dx; co = C0 * (idx*idx+idz*idz); cax= CA * idx*idx; cbx= CB * idx*idx; caz= CA * idz*idz; cbz= CB * idz*idz; /*------------------------------------------------------------*/ tt = sf_floatalloc2(nz,nx); ro =sf_floatalloc2(fdm->nzpad,fdm->nxpad); roz =sf_floatalloc2(fdm->nzpad,fdm->nxpad); rox =sf_floatalloc2(fdm->nzpad,fdm->nxpad); vp =sf_floatalloc2(fdm->nzpad,fdm->nxpad); vt =sf_floatalloc2(fdm->nzpad,fdm->nxpad); /* input density */ sf_floatread(tt[0],nz*nx,Fden); expand(tt,ro ,fdm); /* normalized density derivatives */ for (ix=NOP; ix<fdm->nxpad-NOP; ix++) { for(iz=NOP; iz<fdm->nzpad-NOP; iz++) { roz[ix][iz] = DZ(ro,ix,iz,idz) / ro[ix][iz]; rox[ix][iz] = DX(ro,ix,iz,idx) / ro[ix][iz]; } } free(*ro); free(ro); /* input velocity */ sf_floatread(tt[0],nz*nx,Fvel ); expand(tt,vp,fdm); float vpmax = 0.0; float vpmin = 10000000000000000; /* precompute vp^2 * dt^2 */ for (ix=0; ix<fdm->nxpad; ix++) { for(iz=0; iz<fdm->nzpad; iz++) { vt[ix][iz] = vp[ix][iz] * vp[ix][iz] * dt*dt; if (vp[ix][iz] < vpmin) vpmin = vp[ix][iz]; else if (vp[ix][iz] > vpmax) vpmax = vp[ix][iz]; } } if (cfl) cfl_acoustic(vpmin,vpmax,dx,-1.0f,dz,dt,fmax,safety,NUM_INTERVALS); if(fsrf) { /* free surface */ for (ix=0; ix<fdm->nxpad; ix++) { for(iz=0; iz<fdm->nb; iz++) { vt[ix][iz]=0; } } } free(*tt); free(tt); /*------------------------------------------------------------*/ /*------------------------------------------------------------*/ /* allocate wavefield arrays */ um=sf_floatalloc2(fdm->nzpad,fdm->nxpad); uo=sf_floatalloc2(fdm->nzpad,fdm->nxpad); up=sf_floatalloc2(fdm->nzpad,fdm->nxpad); ua=sf_floatalloc2(fdm->nzpad,fdm->nxpad); for (ix=0; ix<fdm->nxpad; ix++) { for(iz=0; iz<fdm->nzpad; iz++) { um[ix][iz]=0; uo[ix][iz]=0; up[ix][iz]=0; ua[ix][iz]=0; } } /*------------------------------------------------------------*/ if (abcone) abc = abcone2d_make(NOP,dt,vp,fsrf,fdm); if(dabc) { /* one-way abc setup */ /* sponge abc setup */ spo = sponge_make(fdm->nb); } /*------------------------------------------------------------*/ /* * MAIN LOOP */ /*------------------------------------------------------------*/ if(verb) fprintf(stderr,"\n"); for (it=0; it<nt; it++) { if(verb) fprintf(stderr,"%d/%d \r",it,nt); #pragma omp parallel for \ schedule(dynamic) \ private(ix,iz) \ shared(fdm,ua,uo,co,caz,cbz) for (ix=NOP; ix<fdm->nxpad-NOP; ix++) { for(iz=NOP; iz<fdm->nzpad-NOP; iz++) { /* 4th order Laplacian operator */ ua[ix][iz] = co * uo[ix ][iz ] + caz*(uo[ix ][iz-1] + uo[ix ][iz+1]) + cbz*(uo[ix ][iz-2] + uo[ix ][iz+2]) ; /* density term */ /*ua[ix][iz] -= ( DZ(uo,ix,iz,idz) * roz[ix][iz] + DX(uo,ix,iz,idx) * rox[ix][iz] ); */ } } #pragma omp parallel for \ schedule(dynamic) \ private(ix,iz) \ shared(fdm,ua,uo,co,cax,cbx) for (ix=NOP; ix<fdm->nxpad-NOP; ix++) { for(iz=NOP; iz<fdm->nzpad-NOP; iz++) { ua[ix][iz] = ua[ix][iz] + cax*(uo[ix-1][iz ] + uo[ix+1][iz ]) + cbx*(uo[ix-2][iz ] + uo[ix+2][iz ]); } } /* inject acceleration source */ if (srctype == ACCELERATION){ if(expl) { sf_floatread(ww, 1,Fwav); lint2d_inject1(ua,ww[0],cs); } else { sf_floatread(ww,ns,Fwav); lint2d_inject(ua,ww,cs); } } /* step forward in time */ #pragma omp parallel for \ schedule(dynamic) \ private(ix,iz) \ shared(fdm,ua,uo,um,up,vt) for (ix=0; ix<fdm->nxpad; ix++) { for(iz=0; iz<fdm->nzpad; iz++) { up[ix][iz] = 2*uo[ix][iz] - um[ix][iz] + ua[ix][iz] * vt[ix][iz]; } } if(srctype == DISPLACEMENT){ if(expl) { sf_floatread(ww, 1,Fwav); lint2d_inject1(up,ww[0],cs); } else { sf_floatread(ww,ns,Fwav); lint2d_inject(up,ww,cs); } } /* circulate wavefield arrays */ ut=um; um=uo; uo=up; up=ut; if (abcone) abcone2d_apply(uo,um,NOP,abc,fdm); if(dabc) { /* one-way abc apply */ sponge2d_apply(um,spo,fdm); sponge2d_apply(uo,spo,fdm); sponge2d_apply(up,spo,fdm); } /* extract data */ if(ignore_interpolation){ cut2d_extract(uo,dd,cr); } else { lint2d_extract(uo,dd,cr); } if(snap && it%jsnap==0) { cut2d(uo,uc,fdm,acz,acx); sf_floatwrite(uc[0],sf_n(acz)*sf_n(acx),Fwfl); } if( it%jdata==0) sf_floatwrite(dd,nr,Fdat); } if(verb) fprintf(stderr,"\n"); /*------------------------------------------------------------*/ /* deallocate arrays */ free(*um); free(um); free(*up); free(up); free(*uo); free(uo); free(*ua); free(ua); if(snap) { free(*uc); free(uc); } free(*rox); free(rox); free(*roz); free(roz); free(*vp); free(vp); free(*vt); free(vt); free(ww); free(ss); free(rr); free(dd); exit (0); } else { /* FDM structure */ fdm3d fdm=NULL; abcone3d abc=NULL; sponge spo=NULL; /* I/O arrays */ pt3d *ss=NULL; /* sources */ pt3d *rr=NULL; /* receivers */ /* Non-universal arrays */ float***tt=NULL; float***ro=NULL; /* density */ float***roz=NULL; /* normalized 1st derivative of density on axis 1 */ float***rox=NULL; /* normalized 1st derivative of density on axis 2 */ float***roy=NULL; /* normalized 1st derivative of density on axis 3 */ float***vp=NULL; /* velocity */ float***vt=NULL; /* temporary vp*vp * dt*dt */ float***um,***uo,***up,***ua,***ut; /* wavefield: um = U @ t-1; uo = U @ t; up = U @ t+1 */ /* linear interpolation weights/indices */ lint3d cs,cr; /* Wavefield cut params that are not universal */ float ***uc=NULL; /*------------------------------------------------------------*/ /* expand domain for FD operators and ABC */ if( !sf_getint("nb",&nb) || nb<NOP) nb=NOP; fdm=fdutil3d_init(verb,fsrf,az,ax,ay,nb,1); sf_setn(az,fdm->nzpad); sf_seto(az,fdm->ozpad); if(verb) sf_raxa(az); sf_setn(ax,fdm->nxpad); sf_seto(ax,fdm->oxpad); if(verb) sf_raxa(ax); sf_setn(ay,fdm->nypad); sf_seto(ay,fdm->oypad); if(verb) sf_raxa(ay); /*------------------------------------------------------------*/ /*------------------------------------------------------------*/ /* setup output data header */ sf_oaxa(Fdat,ar,1); sf_setn(at,nt/jdata); sf_setd(at,dt*jdata); sf_oaxa(Fdat,at,2); /* setup output wavefield header */ if(snap) { if(!sf_getint ("nqz",&nqz)) nqz=sf_n(az); if(!sf_getint ("nqx",&nqx)) nqx=sf_n(ax); if(!sf_getint ("nqy",&nqy)) nqy=sf_n(ay); if(!sf_getfloat("oqz",&oqz)) oqz=sf_o(az); if(!sf_getfloat("oqx",&oqx)) oqx=sf_o(ax); if(!sf_getfloat("oqy",&oqy)) oqy=sf_o(ay); dqz=sf_d(az); dqx=sf_d(ax); dqy=sf_d(ay); acz = sf_maxa(nqz,oqz,dqz); sf_raxa(acz); acx = sf_maxa(nqx,oqx,dqx); sf_raxa(acx); acy = sf_maxa(nqy,oqy,dqy); sf_raxa(acy); /* check if the imaging window fits in the wavefield domain */ uc=sf_floatalloc3(sf_n(acz),sf_n(acx),sf_n(acy)); ntsnap=0; for(it=0; it<nt; it++) { if(it%jsnap==0) ntsnap++; } sf_setn(at, ntsnap); sf_setd(at,dt*jsnap); if(verb) sf_raxa(at); sf_oaxa(Fwfl,acz,1); sf_oaxa(Fwfl,acx,2); sf_oaxa(Fwfl,acy,3); sf_oaxa(Fwfl,at, 4); } if(expl) { ww = sf_floatalloc( 1); } else { ww = sf_floatalloc(ns); } dd = sf_floatalloc(nr); /*------------------------------------------------------------*/ /* setup source/receiver coordinates */ ss = (pt3d*) sf_alloc(ns,sizeof(*ss)); rr = (pt3d*) sf_alloc(nr,sizeof(*rr)); pt3dread1(Fsou,ss,ns,3); /* read (x,y,z) coordinates */ pt3dread1(Frec,rr,nr,3); /* read (x,y,z) coordinates */ cs = lint3d_make(ns,ss,fdm); cr = lint3d_make(nr,rr,fdm); /*------------------------------------------------------------*/ /* setup FD coefficients */ idz = 1/dz; idx = 1/dx; idy = 1/dy; co = C0 * (idx*idx+idy*idy+idz*idz); cax= CA * idx*idx; cbx= CB * idx*idx; cay= CA * idy*idy; cby= CB * idy*idy; caz= CA * idz*idz; cbz= CB * idz*idz; /*------------------------------------------------------------*/ tt = sf_floatalloc3(nz,nx,ny); ro =sf_floatalloc3(fdm->nzpad,fdm->nxpad,fdm->nypad); roz =sf_floatalloc3(fdm->nzpad,fdm->nxpad,fdm->nypad); rox =sf_floatalloc3(fdm->nzpad,fdm->nxpad,fdm->nypad); roy =sf_floatalloc3(fdm->nzpad,fdm->nxpad,fdm->nypad); vp =sf_floatalloc3(fdm->nzpad,fdm->nxpad,fdm->nypad); vt =sf_floatalloc3(fdm->nzpad,fdm->nxpad,fdm->nypad); /* input density */ sf_floatread(tt[0][0],nz*nx*ny,Fden); expand3d(tt,ro ,fdm); /* normalized density derivatives */ for (iy=NOP; iy<fdm->nypad-NOP; iy++) { for (ix=NOP; ix<fdm->nxpad-NOP; ix++) { for(iz=NOP; iz<fdm->nzpad-NOP; iz++) { roz[iy][ix][iz] = DZ3(ro,ix,iy,iz,idz) / ro[iy][ix][iz]; rox[iy][ix][iz] = DX3(ro,ix,iy,iz,idx) / ro[iy][ix][iz]; roy[iy][ix][iz] = DY3(ro,ix,iy,iz,idy) / ro[iy][ix][iz]; } } } free(**ro); free(*ro); free(ro); /* input velocity */ sf_floatread(tt[0][0],nz*nx*ny,Fvel ); expand3d(tt,vp,fdm); /* precompute vp^2 * dt^2 */ float vpmin = 1000000000000; float vpmax = 0.0; for (iy=0; iy<fdm->nypad; iy++) { for (ix=0; ix<fdm->nxpad; ix++) { for(iz=0; iz<fdm->nzpad; iz++) { float vpt = vp[iy][ix][iz]; vt[iy][ix][iz] = vp[iy][ix][iz] * vp[iy][ix][iz] * dt*dt; if (vpt > vpmax) vpmax = vpt; else if (vpt < vpmin) vpmin = vpt; } } } if (cfl) cfl_acoustic(vpmin,vpmax,dx,dy,dz,dt,fmax,safety,NUM_INTERVALS); if(fsrf) { /* free surface */ for (iy=0; iy<fdm->nypad; iy++) { for (ix=0; ix<fdm->nxpad; ix++) { for(iz=0; iz<fdm->nb; iz++) { vt[iy][ix][iz]=0; } } } } free(**tt); free(*tt); free(tt); /*------------------------------------------------------------*/ /*------------------------------------------------------------*/ /* allocate wavefield arrays */ um=sf_floatalloc3(fdm->nzpad,fdm->nxpad,fdm->nypad); uo=sf_floatalloc3(fdm->nzpad,fdm->nxpad,fdm->nypad); up=sf_floatalloc3(fdm->nzpad,fdm->nxpad,fdm->nypad); ua=sf_floatalloc3(fdm->nzpad,fdm->nxpad,fdm->nypad); for (iy=0; iy<fdm->nypad; iy++) { for (ix=0; ix<fdm->nxpad; ix++) { for(iz=0; iz<fdm->nzpad; iz++) { um[iy][ix][iz]=0; uo[iy][ix][iz]=0; up[iy][ix][iz]=0; ua[iy][ix][iz]=0; } } } /*------------------------------------------------------------*/ if (abcone) abc = abcone3d_make(NOP,dt,vp,fsrf,fdm); if(dabc) { /* one-way abc setup */ /* sponge abc setup */ spo = sponge_make(fdm->nb); } /*------------------------------------------------------------*/ /* * MAIN LOOP */ /*------------------------------------------------------------*/ if(verb) fprintf(stderr,"\n"); for (it=0; it<nt; it++) { if(verb) fprintf(stderr,"%d/%d \r",it,nt); #pragma omp parallel for \ schedule(dynamic) \ private(ix,iy,iz) \ shared(fdm,ua,uo,co,cax,cay,caz,cbx,cby,cbz,idx,idy,idz) for (iy=NOP; iy<fdm->nypad-NOP; iy++) { for (ix=NOP; ix<fdm->nxpad-NOP; ix++) { for(iz=NOP; iz<fdm->nzpad-NOP; iz++) { /* 4th order Laplacian operator */ ua[iy][ix][iz] = co * uo[iy ][ix ][iz ] + caz*(uo[iy ][ix ][iz-1] + uo[iy ][ix ][iz+1]) + cbz*(uo[iy ][ix ][iz-2] + uo[iy ][ix ][iz+2]); /* density term */ /*ua[iy][ix][iz] -= ( DZ3(uo,ix,iy,iz,idz) * roz[iy][ix][iz] + DX3(uo,ix,iy,iz,idx) * rox[iy][ix][iz] + DY3(uo,ix,iy,iz,idy) * roy[iy][ix][iz] ); */ } } } #pragma omp parallel for \ schedule(dynamic) \ private(ix,iy,iz) \ shared(fdm,ua,uo,co,cax,cay,caz,cbx,cby,cbz,idx,idy,idz) for (iy=NOP; iy<fdm->nypad-NOP; iy++) { for (ix=NOP; ix<fdm->nxpad-NOP; ix++) { for(iz=NOP; iz<fdm->nzpad-NOP; iz++) { ua[iy][ix][iz] = ua[iy][ix][iz] + cax*(uo[iy ][ix-1][iz ] + uo[iy ][ix+1][iz ]) + cbx*(uo[iy ][ix-2][iz ] + uo[iy ][ix+2][iz ]) ; } } } #pragma omp parallel for \ schedule(dynamic) \ private(ix,iy,iz) \ shared(fdm,ua,uo,co,cax,cay,caz,cbx,cby,cbz,idx,idy,idz) for (iy=NOP; iy<fdm->nypad-NOP; iy++) { for (ix=NOP; ix<fdm->nxpad-NOP; ix++) { for(iz=NOP; iz<fdm->nzpad-NOP; iz++) { ua[iy][ix][iz] = ua[iy][ix][iz] + cay*(uo[iy-1][ix ][iz ] + uo[iy+1][ix ][iz ]) + cby*(uo[iy-2][ix ][iz ] + uo[iy+2][ix ][iz ]); } } } /* inject acceleration source */ if (srctype == ACCELERATION){ if(expl) { sf_floatread(ww, 1,Fwav); lint3d_inject1(ua,ww[0],cs); } else { sf_floatread(ww,ns,Fwav); lint3d_inject(ua,ww,cs); } } /* step forward in time */ #pragma omp parallel for \ schedule(static) \ private(ix,iy,iz) \ shared(fdm,ua,uo,um,up,vt) for (iy=0; iy<fdm->nypad; iy++) { for (ix=0; ix<fdm->nxpad; ix++) { for(iz=0; iz<fdm->nzpad; iz++) { up[iy][ix][iz] = 2*uo[iy][ix][iz] - um[iy][ix][iz] + ua[iy][ix][iz] * vt[iy][ix][iz]; } } } if (srctype == DISPLACEMENT) { if(expl) { sf_floatread(ww, 1,Fwav); lint3d_inject1(up,ww[0],cs); } else { sf_floatread(ww,ns,Fwav); lint3d_inject(up,ww,cs); } } /* circulate wavefield arrays */ ut=um; um=uo; uo=up; up=ut; if(abcone) abcone3d_apply(uo,um,NOP,abc,fdm); if(dabc) { /* one-way abc apply */ sponge3d_apply(um,spo,fdm); sponge3d_apply(uo,spo,fdm); sponge3d_apply(up,spo,fdm); } /* extract data */ if (ignore_interpolation) { cut3d_extract(uo,dd,cr); } else { lint3d_extract(uo,dd,cr); } if(snap && it%jsnap==0) { cut3d(uo,uc,fdm,acz,acx,acy); sf_floatwrite(uc[0][0],sf_n(acz)*sf_n(acx)*sf_n(acy),Fwfl); } if(it%jdata==0) sf_floatwrite(dd,nr,Fdat); } if(verb) fprintf(stderr,"\n"); /*------------------------------------------------------------*/ /* deallocate arrays */ free(**um); free(*um); free(um); free(**up); free(*up); free(up); free(**uo); free(*uo); free(uo); free(**ua); free(*ua); free(ua); if (snap) { free(**uc); free(*uc); free(uc); } free(**rox); free(*rox); free(rox); free(**roy); free(*roy); free(roy); free(**roz); free(*roz); free(roz); free(**vp); free(*vp); free(vp); free(**vt); free(*vt); free(vt); free(ss); free(rr); free(dd); free(ww); exit (0); } }