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; sf_axis as = NULL, ar = NULL; int nbd; /* ABC boundary size */ int fdorder; /* finite difference spatial accuracy order */ int nzpad,nxpad; /* boundary padded model size */ int ix,it,nx,nz,nt,ns,nr; float dx,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; pt2d* src2d=NULL; /* source position */ pt2d* rec2d=NULL; /*receiver position*/ scoef2d cssinc = NULL, crsinc = NULL; lint2d cslint = NULL, crlint = NULL; /* FDM structure */ fdm2d fdm = NULL; abcone2d abc = NULL; sponge spo = NULL; double wall_clock_time_s, wall_clock_time_e; sf_axis acz = NULL, acx = NULL; int nqz, nqx; float oqz, oqx, dqz, dqx; int nop; const int OMP_CHUNK_SIZE = 1; const int SECOND_DERIV = 2; const int FIRST_DERIV = 1; float* fdcoef_d2; float* fdcoef_d1; float** oslice = NULL; /* windowed wavefield */ float** tmp_array; #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_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("den")) { 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 */ 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); 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_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("dqz",&dqz)) dqz=sf_d(az); /* Saved wfld window dz */ if (!sf_getfloat("dqx",&dqx)) dqx=sf_d(ax); /* Saved wfld window dx */ acz = sf_maxa(nqz,oqz,dqz); if (verb) sf_raxa(acz); acx = sf_maxa(nqx,oqx,dqx); if (verb) sf_raxa(acx); /* 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,at,3); } /* 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 = fdutil_init(verb,fsrf,az,ax,nbd,OMP_CHUNK_SIZE); 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); /* Precompute coefficients */ dt2 = dt*dt; nzpad = nz+2*nbd; nxpad = nx+2*nbd; fdcoef_d2 = compute_fdcoef(nop,dz,dx,optfd,SECOND_DERIV); fdcoef_d1 = compute_fdcoef(nop,dz,dx,optfd,FIRST_DERIV); /* Allocate memories */ if (expl) ws = sf_floatalloc(1); else ws = sf_floatalloc(ns); vel = sf_floatalloc2(nzpad,nxpad); if (!cden) rho = sf_floatalloc2(nzpad,nxpad); u_dat = sf_floatalloc(nr); src2d = pt2dalloc1(ns); rec2d = pt2dalloc1(nr); if (snap) oslice = sf_floatalloc2(sf_n(acz),sf_n(acx)); /* source and receiver position */ pt2dread1(file_src,src2d,ns,2); /* read format: (x,z) */ if (sinc) cssinc = sinc2d_make(ns,src2d,fdm); else cslint = lint2d_make(ns,src2d,fdm); pt2dread1(file_rec,rec2d,nr,2); /* read format: (x,z) */ if (sinc) crsinc = sinc2d_make(nr,rec2d,fdm); else crlint = lint2d_make(nr,rec2d,fdm); /* temperary array */ tmp_array = sf_floatalloc2(nz,nx); /* read velocity and pad */ sf_floatread(tmp_array[0],nz*nx,file_vel); expand(tmp_array,vel,fdm); /* read density and pad */ if (!cden) { sf_floatread(tmp_array[0],nz*nx,file_den); expand(tmp_array,rho,fdm); } free(*tmp_array); free(tmp_array); /* A1 one-way ABC implicit scheme coefficients */ if (dabc) { abc = abcone2d_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_floatalloc2(nzpad,nxpad); u1 = sf_floatalloc2(nzpad,nxpad); /* initialize variables */ memset(u0[0],0,sizeof(float)*nzpad*nxpad); memset(u1[0],0,sizeof(float)*nzpad*nxpad); memset(u_dat,0,sizeof(float)*nr); /* v = (v*dt)^2 */ for (ix=0;ix<nzpad*nxpad;ix++) *(vel[0]+ix) *= *(vel[0]+ix)*dt2; if (fsrf && !hybrid) { for (ix=0; ix<nxpad; ix++) memset(vel[ix],0,sizeof(float)*(fdm->nb+1)); } 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_2d(u0,u1,vel,rho,fdcoef_d2,fdcoef_d1,nop,nzpad,nxpad); 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); if (sinc) sinc2d_inject1_with_vv(u0,ws[0],cssinc,vel); else lint2d_inject1_with_vv(u0,ws[0],cslint,vel); } else { sf_seek(file_wav,(off_t)(nt-it-1)*ns*sizeof(float),SEEK_SET); sf_floatread(ws,ns,file_wav); if (sinc) sinc2d_inject_with_vv(u0,ws,cssinc,vel); else lint2d_inject_with_vv(u0,ws,cslint,vel); } } else { /* forward inject source wavelet */ if (expl) { sf_floatread(ws,1,file_wav); if (sinc) sinc2d_inject1_with_vv(u0,ws[0],cssinc,vel); else lint2d_inject1_with_vv(u0,ws[0],cslint,vel); } else { sf_floatread(ws,ns,file_wav); if (sinc) sinc2d_inject_with_vv(u0,ws,cssinc,vel); else lint2d_inject_with_vv(u0,ws,cslint,vel); } } /* apply abc */ if (dabc) { if (hybrid) apply_abc(u0,u1,nz,nx,nbd,abc,nop,damp); else { abcone2d_apply(u0,u1,nop,abc,fdm); sponge2d_apply(u0,spo,fdm); sponge2d_apply(u1,spo,fdm); } } /* loop over pointers */ ptr_tmp = u0; u0 = u1; u1 = ptr_tmp; /* extract snapshot */ if (snap && it%jsnap==0) { cut2d(u0,oslice,fdm,acz,acx); sf_floatwrite(oslice[0],sf_n(acz)*sf_n(acx),file_wfl); } /* extract receiver data */ if (sinc) sinc2d_extract(u0,u_dat,crsinc); else lint2d_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(*u1); free(u1); 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); } if (hybrid) free(damp); free(src2d); free(rec2d); return 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 */ 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; int nx,nz,nc,ic,iz,ix; int ind=0; float tmp; float dx,dz,ox,oz; pt2d *cc=NULL; float **eps=NULL,**del,***out=NULL; float x,y,lambda0,lambda1,lambda2,twoA; float lm00,lm01,lm02,lm10,lm11,lm12,lm20,lm21,lm22; float *a=NULL,*b=NULL,**llm=NULL; sf_axis ax,az,ac; sf_file Fin=NULL,Fdel=NULL, Fc=NULL,Fout=NULL; /* init RSF */ sf_init(argc,argv); if(! sf_getbool("verb",&verb)) verb=false; Fin = sf_input ("in" ); Fdel= sf_input ("del" ); Fout = sf_output ("out" ); Fc = sf_input ("cc" ); /* sample locations */ /* input axes */ az = sf_iaxa(Fin,1); sf_setlabel(az,"z"); if(verb) sf_raxa(az); ax = sf_iaxa(Fin,2); sf_setlabel(ax,"x"); if(verb) sf_raxa(ax); nz = sf_n(az); dz = sf_d(az); oz = sf_o(az); nx = sf_n(ax); dx = sf_d(ax); ox = sf_o(ax); eps = sf_floatalloc2(nz,nx); del = sf_floatalloc2(nz,nx); sf_floatread(eps[0],nz*nx,Fin); sf_floatread(del[0],nz*nx,Fdel); /* CIP coordinates */ ac = sf_iaxa(Fc,2); sf_setlabel(ac,"cc"); sf_setunit(ac,""); if(verb) sf_raxa(ac); nc = sf_n(ac); cc= (pt2d*) sf_alloc(nc,sizeof(*cc)); pt2dread1(Fc,cc,nc,2); /* read coordinates */ /* nc=3*/ /* output files*/ out = sf_floatalloc3(nz,nx,nc); sf_oaxa(Fout,az,1); sf_oaxa(Fout,ax,2); sf_oaxa(Fout,ac,3); nc=3; a = sf_floatalloc(nc); b = sf_floatalloc(nc); llm = sf_floatalloc2(2,nc); /*find sample indexes*/ for(ic=0; ic<nc; ic++) { b[ic]=cc[ic].z; /*delta*/ a[ic]=cc[ic].x; /*epsilon*/ sf_warning("x%d=%f,z%d=%f: epsilon=%f delta=%f",ic,cc[ic].x,ic,cc[ic].z,a[ic],b[ic]); } /* a[0]=0.0; b[0]=0.0;*/ /* a[2]=0.65; b[2]=0.0; */ /* a[1]=0.0; b[1]=0.35;*/ /*matrix*/ twoA=(a[0]-a[2])*(b[1]-b[2])-(a[1]-a[2])*(b[0]-b[2]); /* if(twoA<0) { */ /* tmp=a[1];a[1]=a[2];a[2]=tmp; */ /* tmp=b[1];b[1]=b[2];b[2]=tmp; */ /* } */ sf_warning("a=%f %f %f",a[0],a[1],a[2]); sf_warning("b=%f %f %f",b[0],b[1],b[2]); twoA=(a[0]-a[2])*(b[1]-b[2])-(a[1]-a[2])*(b[0]-b[2]); llm[0][0]=a[1]*b[2]-a[2]*b[1]; llm[0][1]=b[1]-b[2]; llm[0][2]=a[2]-a[1]; llm[1][0]=a[2]*b[0]-a[0]*b[2]; llm[1][1]=b[2]-b[0]; llm[1][2]=a[0]-a[2]; llm[2][0]=a[0]*b[1]-a[1]*b[0]; llm[2][1]=b[0]-b[1]; llm[2][2]=a[1]-a[0]; sf_warning(""); sf_warning("%f %f %f",llm[0][0], llm[0][1], llm[0][2]); sf_warning("%f %f %f",llm[1][0], llm[1][1], llm[1][2]); sf_warning("%f %f %f",llm[2][0], llm[2][1], llm[2][2]); sf_warning("area=%f",twoA); lm00=a[1]*b[2]-a[2]*b[1]; lm01=b[1]-b[2]; lm02=a[2]-a[1]; lm10=a[2]*b[0]-a[0]*b[2]; lm11=b[2]-b[0]; lm12=a[0]-a[2]; lm20=a[0]*b[1]-a[1]*b[0]; lm21=b[0]-b[1]; lm22=a[1]-a[0]; sf_warning(""); sf_warning("%f %f %f",lm00, lm01, lm02); sf_warning("%f %f %f",lm10, lm11, lm12); sf_warning("%f %f %f",lm20, lm21, lm22); /* find shape functions */ for (ic=0; ic<nc; ic++) { for (ix=0; ix<nx; ix++) { for(iz=0; iz<nz; iz++) { out[ic][ix][iz]=0.; } } } if(twoA!=0){ for (ix=0; ix<nx; ix++) { for(iz=0; iz<nz; iz++) { x=eps[ix][iz]; y=del[ix][iz]; lambda0=lm00 + lm01*x + lm02*y; lambda1=lm10 + lm11*x + lm12*y; lambda2=lm20 + lm21*x + lm22*y; out[0][ix][iz]=lambda0/twoA; out[1][ix][iz]=lambda1/twoA; out[2][ix][iz]=lambda2/twoA; } } } sf_floatwrite(out[0][0],nz*nx*nc,Fout); }
int main (int argc, char* argv[]) { /* ----------------------------------------------------------------------------------*/ // Variable declaration // ------------------------ // logical variables bool source, verb; // axes sf_axis awx,awz,awt; /* wavefield axes */ sf_axis atau; /* eic axes: time-lag and extended images */ sf_axis ar; /* coordinate file */ int nr,nx,nz,nt; // integer int i1, i2,i3,it, itau,itaux; /* integer var for loops */ int ix,iz; /*integers for extracting windowed wavefield */ float tmin, tmax,taumin,taumax,t,tau,tbmin,tbmax; float *uaux; // arrays float ***uo; /* wavefield array */ float *tgathers; /* time lag gathers */ float **adjsrc; /* adjoint source [nt] */ // coordinate arrays pt2d *rr=NULL; /* extended images coordinates */ /* ----------------------*/ /* I/O files */ sf_file Feic=NULL; sf_file Fxcr=NULL; sf_file Fadj=NULL; sf_file Fwfl=NULL; /* ----------------------*/ // End of variables declaration /* ----------------------------------------------------------------------------------*/ /* ----------------------*/ // init RSF argument parsing sf_init (argc,argv); // end of init RSF argument parsing /* ------- I/O declaration ---------------*/ Fwfl = sf_input("in"); /* Wavefield used for the adjoint computation, for adj */ /* source side pass the receiver wavefield, for receiver */ /* side pass the source wavefield */ Feic = sf_input("eic"); /* Penalized extended image (apply P(\tau) twice) */ Fxcr = sf_input("coord"); /* coordinates of every extended image, in 2d */ /* should be organized in (x1,z1),(x2,z2),...,(xn,zn) */ Fadj = sf_output("out"); /* adjoint source to be injected on each coordinate */ /* --------------------------------------- */ //Get parameters from command line: if (! sf_getbool("source",&source)) source=true; /* Source side [default] or receiver side adjoint? */ if (! sf_getbool("verb",&verb)) verb=true; /* verbosity flag, mainly debug printout */ /* at this time */ if(verb) sf_warning("===================================================="); if(verb) sf_warning("====== Calculating adjoint source ======="); if(source) { if(verb) sf_warning("====== source side joint source ======="); } else { if(verb) sf_warning("====== receiver side joint source ======="); } if(verb) sf_warning("===================================================="); // ------------------------------------------------- // Some file type checking if (SF_FLOAT != sf_gettype(Fwfl)) sf_error("Need float input for wavefield"); if (SF_FLOAT != sf_gettype(Feic)) sf_error("Need float input for eic"); if (SF_FLOAT != sf_gettype(Fxcr)) sf_error("Need float input for coordinates"); // ------------------------------------------------- // -------------------------------------------------------------------------------------- // Axes geometry loading and writing // -------------------------------------------------------------------------------------- // From wavefield awz = sf_iaxa(Fwfl,1); awx = sf_iaxa(Fwfl,2); awt = sf_iaxa(Fwfl,3); // From coordinates ar = sf_iaxa(Fxcr,2); // From extended images atau = sf_iaxa(Feic,1); taumin = SF_MIN(sf_o(atau),(sf_n(atau)-1)*sf_d(atau)+sf_o(atau)); taumax = SF_MAX(sf_o(atau),(sf_n(atau)-1)*sf_d(atau)+sf_o(atau)); // To adjoint source sf_oaxa(Fadj,awt,1); sf_oaxa(Fadj,ar,2); sf_putint(Fadj,"n3",1); nr=sf_n(ar); /*-------------------------------------------------------------------------------------*/ /* setup source/receiver coordinates */ /*-------------------------------------------------------------------------------------*/ rr = pt2dalloc1(nr); pt2dread1(Fxcr,rr,nr,2); if(verb) sf_warning("===================================================="); if(verb) sf_warning("reading %d extended image coordinates points",nr); if(verb) sf_warning("===================================================="); if(verb) sf_warning("allocating and reading wavefield"); if(verb) sf_warning("z axis: n1=%-10d o1=%-10.3f d1=%-10.3f",sf_n(awz),sf_o(awz),sf_d(awz)); if(verb) sf_warning("x axis: n2=%-10d o2=%-10.3f d2=%-10.3f",sf_n(awx),sf_o(awx),sf_d(awx)); if(verb) sf_warning("t axis: n3=%-10d o3=%-10.3f d3=%-10.3f",sf_n(awt),sf_o(awt),sf_d(awt)); if(verb) sf_warning("===================================================="); // allocate wavefield space uo = sf_floatalloc3(sf_n(awz),sf_n(awx),sf_n(awt)); if(uo==NULL) sf_error("not enough memory to read wavefield"); uaux = sf_floatalloc(1); nz=sf_n(awz); nx=sf_n(awx); nt=sf_n(awt); // read wavefield for (i3=0 ; i3<nt; i3++) { ; for (i2=0 ; i2<nx; i2++) { ; for (i1=0 ; i1<nz; i1++) { sf_floatread(uaux,1,Fwfl); uo[i3][i2][i1]=uaux[0]; } } } //------------------------------------------------------------------------------------- // reading extended images //------------------------------------------------------------------------------------- if(verb) sf_warning("reading %d extended images points",nr); if(verb) sf_warning("====================================================="); if(verb) sf_warning(""); tgathers = sf_floatalloc(sf_n(atau)); adjsrc = sf_floatalloc2(sf_n(awt),1); if(source) { for (i1=0; i1<sf_n(ar); i1++) { sf_floatread(tgathers,sf_n(atau),Feic); ix= 0.5+(rr[i1].x - sf_o(awx))/sf_d(awx); iz= 0.5+(rr[i1].z - sf_o(awz))/sf_d(awz); if (verb) if(verb) fprintf(stderr,"\b\b\b\b\b%d",i1+1); for (it=0; it<sf_n(awt); it++) { adjsrc[0][it]=0.0; // get the limits of tau such that we avoid // segmentation fault on the wavefield uo: // 0 < t-2*tau < tmax //Lower tau bound t=it*sf_d(awt)+sf_o(awt); tmin = SF_MIN(t+2*taumax,t+2*taumin); tmin = SF_MAX(tmin,0); //Upper tau bound tmax = SF_MAX(t+2*taumax,t+2*taumin); tmax = SF_MIN(tmax,sf_o(awt)+sf_d(awt)*(sf_n(awt)-1) ); tbmin =SF_MIN( -(t - tmax)*0.5,-(t - tmin)*0.5); tbmax =SF_MAX( -(t - tmax)*0.5,-(t - tmin)*0.5); for (itau = 1.5 + (tbmin - sf_o(atau))/sf_d(atau) ; itau< (tbmax - sf_o(atau))/sf_d(atau) ; itau++) { tau=itau*sf_d(atau)+sf_o(atau) ; itaux = 0.5 + ((t + 2*tau)-sf_o(awt))/sf_d(awt); adjsrc[0][it] += tgathers[itau]*uo[itaux][ix][iz]; } } sf_floatwrite(adjsrc[0],nt,Fadj); } } else { for (i1=0; i1<sf_n(ar); i1++) { sf_floatread(tgathers,sf_n(atau),Feic); ix= 0.5+(rr[i1].x - sf_o(awx))/sf_d(awx); iz= 0.5+(rr[i1].z - sf_o(awz))/sf_d(awz); if (verb) if(verb) fprintf(stderr,"\b\b\b\b\b%d",i1+1); //if (verb) if(verb) fprintf(stderr,"\b\b\b\b\b%03d/%03d",i1+1,sf_n(ar)); for (it=0; it<sf_n(awt); it++) { adjsrc[0][it]=0.0; // get the limits of tau such that we avoid // segmentation fault on the wavefield uo: // 0 < t-2*tau < tmax //Lower tau bound t=it*sf_d(awt)+sf_o(awt); tmin = SF_MIN(t-2*taumax,t-2*taumin); tmin = SF_MAX(tmin,0); //Upper tau bound tmax = SF_MAX(t-2*taumax,t-2*taumin); tmax = SF_MIN(tmax,sf_o(awt)+sf_d(awt)*(sf_n(awt)-1) ); tbmin =SF_MIN( (t - tmax)*0.5,(t - tmin)*0.5); tbmax =SF_MAX( (t - tmax)*0.5,(t - tmin)*0.5); for (itau = 1.5 + (tbmin - sf_o(atau))/sf_d(atau) ; itau< (tbmax - sf_o(atau))/sf_d(atau) ; itau++) { tau=itau*sf_d(atau)+sf_o(atau) ; itaux = 0.5 + ((t - 2*tau)-sf_o(awt))/sf_d(awt); adjsrc[0][it] += tgathers[itau]*uo[itaux][ix][iz]; } } sf_floatwrite(adjsrc[0],nt,Fadj); } } if (verb) if(verb) fprintf(stderr,"\n"); free(**uo); free(*uo); free(uo); free(*adjsrc); free(adjsrc); free(tgathers); exit(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[]) { 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 Fmag=NULL; /* magnetic permitivity */ sf_file Fele=NULL; /* electric susceptibility */ sf_file Fcdt=NULL; /* conductivity */ 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; /* 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 **vel=NULL; /* velocity */ float **mag=NULL; float **ele=NULL; float **cdt=NULL; float **cdtele=NULL; /* temporary cdt*dt/2*ele */ float **magele=NULL; /* temporary dt*dt/mag*ele */ /*------------------------------------------------------------*/ /*------------------------------------------------------------*/ 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; /* FD operator size */ float co,cax,cbx,caz,cbz; /* wavefield cut params */ sf_axis acz=NULL,acx=NULL; int nqz,nqx; float oqz,oqx; float dqz,dqx; float **uc=NULL; /*------------------------------------------------------------*/ /* 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 */ Fsou = sf_input ("sou"); /* sources */ Frec = sf_input ("rec"); /* receivers */ Fwfl = sf_output("wfl"); /* wavefield */ Fdat = sf_output("out"); /* data */ /*------------------------------------------------------------*/ Fmag = sf_input ("mag"); /* magnetic permitivity */ Fele = sf_input ("ele"); /* electric susceptibility */ Fcdt = sf_input ("cdt"); /* conductivity */ /*------------------------------------------------------------*/ /*------------------------------------------------------------*/ /* axes */ at = sf_iaxa(Fwav,2); sf_setlabel(at,"t"); if(verb) sf_raxa(at); /* time */ az = sf_iaxa(Fmag,1); sf_setlabel(az,"z"); if(verb) sf_raxa(az); /* depth */ ax = sf_iaxa(Fmag,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 we exclude some of the code to maintain the same size of velocity model*/ 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 */ 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); vel = sf_floatalloc2(fdm->nzpad,fdm->nxpad); mag = sf_floatalloc2(fdm->nzpad,fdm->nxpad); ele = sf_floatalloc2(fdm->nzpad,fdm->nxpad); cdt = sf_floatalloc2(fdm->nzpad,fdm->nxpad); cdtele =sf_floatalloc2(fdm->nzpad,fdm->nxpad); magele =sf_floatalloc2(fdm->nzpad,fdm->nxpad); /*------------------------------------------------------------*/ /*------------------------------------------------------------*/ /* input magnetic susceptibility*/ sf_floatread(tt[0],nz*nx,Fmag ); expand(tt,mag,fdm); /* input electric susceptibility*/ sf_floatread(tt[0],nz*nx,Fele ); expand(tt,ele,fdm); /* input conductivity*/ sf_floatread(tt[0],nz*nx,Fcdt ); expand(tt,cdt,fdm); /*------------------------------------------------------------*/ /* cdtele = sigma*dt/2*epsilon */ /* magele = dt*dt/mu*epsilon */ for (ix=0; ix<fdm->nxpad; ix++) { for(iz=0; iz<fdm->nzpad; iz++) { cdtele[ix][iz] = cdt[ix][iz]*dt/(2*(ele[ix][iz])); magele[ix][iz] = dt*dt/(mag[ix][iz]*ele[ix][iz]); vel[ix][iz] = 1./(sqrt(mag[ix][iz]*ele[ix][iz])); } } if(fsrf) { /* free surface */ for (ix=0; ix<fdm->nxpad; ix++) { for(iz=0; iz<fdm->nb; iz++) { cdtele[ix][iz]=0; magele[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(dabc) { /* one-way abc setup */ abc = abcone2d_make(NOP,dt,vel,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) \ shared(fdm,ua,uo,co,cax,caz,cbx,cbz,idx,idz) #endif 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 ] + cax*(uo[ix-1][iz ] + uo[ix+1][iz ]) + cbx*(uo[ix-2][iz ] + uo[ix+2][iz ]) + caz*(uo[ix ][iz-1] + uo[ix ][iz+1]) + cbz*(uo[ix ][iz-2] + uo[ix ][iz+2]); } } /* inject acceleration source */ 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 */ #ifdef _OPENMP #pragma omp parallel for \ schedule(dynamic,fdm->ompchunk) \ private(ix,iz) \ shared(fdm,ua,uo,um,up,cdtele,magele) #endif for (ix=0; ix<fdm->nxpad; ix++) { for(iz=0; iz<fdm->nzpad; iz++) { up[ix][iz] = (2*uo[ix][iz] - (1-cdtele[ix][iz])*um[ix][iz] + ua[ix][iz]*(magele[ix][iz]))/(1+cdtele[ix][iz]); } } /* circulate wavefield arrays */ ut=um; um=uo; uo=up; up=ut; if(dabc) { /* one-way abc apply */ abcone2d_apply(uo,um,NOP,abc,fdm); sponge2d_apply(um,spo,fdm); sponge2d_apply(uo,spo,fdm); sponge2d_apply(up,spo,fdm); } /* extract data */ 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); free(*uc); free(uc); free(*mag); free(mag); free(*ele); free(ele); free(*cdt); free(cdt); free(*vel); free(vel); free(*cdtele); free(cdtele); free(*magele); free(magele); /*------------------------------------------------------------*/ free(ww); free(ss); free(rr); free(dd); /*------------------------------------------------------------*/ sf_close(); 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[]) { 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,isreversed; sf_file Fs,Fr,Fi,Fc; /* I/O files */ sf_axis az,ax,at,ac,aa; /* cube axes */ int nz,nx,nt, nhx, nhz, nht,nc; int it, ihx, ihz, iht,ic; int nhx2,nhz2,nht2; off_t iseek; float ***us=NULL,***ur=NULL,****ii=NULL; pt2d *cc=NULL; bool *ccin=NULL; float cxmin,czmin; float cxmax,czmax; int icx, icz; int mcx, mcz, mct; int pcx, pcz, pct; int **mcxall, **pcxall; int **mczall, **pczall; int *mctall, *pctall; int lht; float scale; /* gaussian taper */ bool gaus; float gsx,gsz,gst; /* std dev */ float gx, gz, gt; /*------------------------------------------------------------*/ /* init RSF */ sf_init(argc,argv); /* OMP parameters */ #ifdef _OPENMP omp_init(); #endif if(! sf_getbool("verb",&verb)) verb=false; /* verbosity flag */ if(! sf_getbool("isreversed",&isreversed)) isreversed=false; /* reversed rec wfld? */ Fs = sf_input ("in" ); /* source wavefield */ Fr = sf_input ("ur" ); /* receiver wavefield */ Fc = sf_input ("cc" ); /* CIP coordinates */ Fi = sf_output("out"); /* image */ /*------------------------------------------------------------*/ /* read axes */ az=sf_iaxa(Fs,1); nz = sf_n(az); ax=sf_iaxa(Fs,2); nx = sf_n(ax); at=sf_iaxa(Fs,3); nt = sf_n(at); /* CIP coordinates */ ac = sf_iaxa(Fc,2); sf_setlabel(ac,"cc"); sf_setunit(ac,""); nc = sf_n(ac); if(! sf_getint("nhz",&nhz)) nhz=0; nhz2=2*nhz+1; /* z lags */ if(! sf_getint("nhx",&nhx)) nhx=0; nhx2=2*nhx+1; /* x lags */ if(! sf_getint("nht",&nht)) nht=0; nht2=2*nht+1; /* t lags */ lht=2*nht; if(verb) { sf_warning("nhx=%3d nhz=%3d nht=%3d",nhx2,nhz2,nht2); sf_raxa(az); sf_raxa(ax); sf_raxa(at); sf_raxa(ac); } /* set output axes */ aa=sf_maxa(nhz2,-nhz*sf_d(az),sf_d(az)); sf_setlabel(aa,"hz"); sf_setunit(aa,""); if(verb) sf_raxa(aa); sf_oaxa(Fi,aa,1); aa=sf_maxa(nhx2,-nhx*sf_d(ax),sf_d(ax)); sf_setlabel(aa,"hx"); sf_setunit(aa,""); if(verb) sf_raxa(aa); sf_oaxa(Fi,aa,2); aa=sf_maxa(nht2,-nht*sf_d(at),sf_d(at)); sf_setlabel(aa,"ht"); sf_setunit(aa,""); if(verb) sf_raxa(aa); sf_oaxa(Fi,aa,3); sf_oaxa(Fi,ac,4); if(! sf_getbool("gaus",&gaus)) gaus=false; /* Gaussian taper flag */ if(gaus) { if(! sf_getfloat("gsx",&gsx)) gsx=nhx*sf_d(ax); gsx=1./(2*gsx*gsx); if(! sf_getfloat("gsz",&gsz)) gsz=nhz*sf_d(az); gsz=1./(2*gsz*gsz); if(! sf_getfloat("gst",&gst)) gst=nht*sf_d(at); gst=1./(2*gst*gst); } /*------------------------------------------------------------*/ /* allocate work arrays */ us=sf_floatalloc3(nz,nx,nht2); ur=sf_floatalloc3(nz,nx,nht2); ii=sf_floatalloc4(nhz2,nhx2,nht2,nc); /* zero output */ for(ic=0; ic<nc; ic++) { for (iht=0; iht<nht2; iht++) { for (ihx=0; ihx<nhx2; ihx++) { for(ihz=0; ihz<nhz2; ihz++) { ii[ic][iht][ihx][ihz] = 0; } } } } /*------------------------------------------------------------*/ /* CIP coordinates */ cc= (pt2d*) sf_alloc(nc,sizeof(*cc)); pt2dread1(Fc,cc,nc,2); mcxall=sf_intalloc2(nhx2,nc); pcxall=sf_intalloc2(nhx2,nc); mczall=sf_intalloc2(nhz2,nc); pczall=sf_intalloc2(nhz2,nc); ccin=sf_boolalloc(nc); cxmin = sf_o(ax) + nhx *sf_d(ax); cxmax = sf_o(ax) + (sf_n(ax)-1-nhx)*sf_d(ax); czmin = sf_o(az) + nhz *sf_d(az); czmax = sf_o(az) + (sf_n(az)-1-nhz)*sf_d(az); if(verb) { sf_warning("cxmin=%f,cxmax=%f",cxmin,cxmax); sf_warning("czmin=%f,czmax=%f",czmin,czmax); } for(ic=0; ic<nc; ic++) { ccin[ic]=(cc[ic].x>=cxmin && cc[ic].x<=cxmax && cc[ic].z>=czmin && cc[ic].z<=czmax)?true:false; if(ccin[ic]) { icx = 0.5+(cc[ic].x-sf_o(ax))/sf_d(ax); for(ihx=-nhx; ihx<nhx+1; ihx++) { mcxall[ic][nhx+ihx] = icx-ihx; pcxall[ic][nhx+ihx] = icx+ihx; } icz = 0.5+(cc[ic].z-sf_o(az))/sf_d(az); for(ihz=-nhz; ihz<nhz+1; ihz++) { mczall[ic][nhz+ihz] = icz-ihz; pczall[ic][nhz+ihz] = icz+ihz; } } } mctall=sf_intalloc(nht2); pctall=sf_intalloc(nht2); for (iht=0; iht<nht2; iht++) { mctall[iht]=iht; pctall[iht]=2*nht-iht; } /*------------------------------------------------------------*/ if(isreversed) { /* receiver wavefield is reversed */ /* read wavefield @ [0...2nht-1]*/ for(iht=0;iht<2*nht;iht++) { sf_floatread(us[iht][0],nz*nx,Fs); sf_floatread(ur[iht][0],nz*nx,Fr); } if(verb) fprintf(stderr,"nt\n"); for(it=nht;it<nt-nht;it++) { if(verb) fprintf(stderr,"\b\b\b\b\b\b\b\b\b\b%04d",it); /* read wavefield @ [2nht]*/ sf_floatread(us[ lht ][0],nz*nx,Fs); sf_floatread(ur[ lht ][0],nz*nx,Fr); #ifdef _OPENMP #pragma omp parallel for schedule(dynamic) \ private(ic, \ ihx,ihz,iht, \ mcx,mcz,mct, \ pcx,pcz,pct) \ shared (nc,ii,us,ur, \ nhx2, nhz2, nht2, \ mcxall,mczall,mctall, \ pcxall,pczall,pctall,ccin) #endif for(ic=0; ic<nc; ic++) { if(ccin[ic]) { for (iht=0; iht<nht2; iht++) { mct=mctall [iht]; pct=pctall [iht]; for (ihx=0; ihx<nhx2; ihx++) { mcx=mcxall[ic][ihx]; pcx=pcxall[ic][ihx]; for(ihz=0; ihz<nhz2; ihz++) { mcz=mczall[ic][ihz]; pcz=pczall[ic][ihz]; ii[ic][iht][ihx][ihz] += us[mct][mcx][mcz]*ur[pct][pcx][pcz]; } /* ihz */ } /* ihx */ } /* iht */ } } /* ic */ /* update wavefield index (cycle) */ for(iht=0;iht<nht2;iht++) { mctall[iht] = (mctall[iht]+1) % nht2; pctall[iht] = (pctall[iht]+1) % nht2; } lht = (lht+1) % nht2; } /* it */ if(verb) fprintf(stderr,"\n"); } else { /* receiver wavefield is NOT reversed */ /* read wavefield @ [0...2nht-1]*/ for(iht=0;iht<2*nht;iht++) { sf_floatread(us[iht][0],nz*nx,Fs); iseek = (off_t)(nt-1-iht)*nz*nx*sizeof(float); sf_seek(Fr,iseek,SEEK_SET); sf_floatread(ur[iht][0],nz*nx,Fr); } if(verb) fprintf(stderr,"nt\n"); for(it=nht;it<nt-nht;it++) { if(verb) fprintf(stderr,"\b\b\b\b\b\b\b\b\b\b%04d",nt-nht-1-it); /* read wavefield @ [2nht]*/ sf_floatread(us[ lht ][0],nz*nx,Fs); iseek=(off_t)(nt-nht-1-it)*nz*nx*sizeof(float); sf_seek(Fr,iseek,SEEK_SET); sf_floatread(ur[ lht ][0],nz*nx,Fr); #ifdef _OPENMP #pragma omp parallel for schedule(dynamic) \ private(ic, \ ihx,ihz,iht, \ mcx,mcz,mct, \ pcx,pcz,pct) \ shared (nc,ii,us,ur, \ nhx2, nhz2, nht2, \ mcxall,mczall,mctall, \ pcxall,pczall,pctall,ccin) #endif for(ic=0; ic<nc; ic++) { if(ccin[ic]) { for (iht=0; iht<nht2; iht++) { mct=mctall [iht]; pct=pctall [iht]; for (ihx=0; ihx<nhx2; ihx++) { mcx=mcxall[ic][ihx]; pcx=pcxall[ic][ihx]; for(ihz=0; ihz<nhz2; ihz++) { mcz=mczall[ic][ihz]; pcz=pczall[ic][ihz]; ii[ic][iht][ihx][ihz] += us[mct][mcx][mcz]*ur[pct][pcx][pcz]; } /* ihz */ } /* ihx */ } /* iht */ } } /* ic */ /* update wavefield index (cycle) */ for(iht=0;iht<nht2;iht++) { mctall[iht] = (mctall[iht]+1) % nht2; pctall[iht] = (pctall[iht]+1) % nht2; } lht = (lht+1) % nht2; } /* it */ if(verb) fprintf(stderr,"\n"); } /* end "is reversed" */ /*------------------------------------------------------------*/ /*------------------------------------------------------------*/ /* scale image */ scale = 1./nt; for(ic=0; ic<nc; ic++) { for (iht=0; iht<nht2; iht++) { for (ihx=0; ihx<nhx2; ihx++) { for(ihz=0; ihz<nhz2; ihz++) { ii[ic][iht][ihx][ihz] *= scale; } } } } /*------------------------------------------------------------*/ /* apply Gaussian taper */ if(gaus) { for(ic=0; ic<nc; ic++) { for (iht=0;iht<nht2;iht++) { gt=(iht-nht)*sf_d(at); gt*=gt; for (ihx=0;ihx<nhx2;ihx++) { gx=(ihx-nhx)*sf_d(ax); gx*=gx; for(ihz=0;ihz<nhz2;ihz++) { gz=(ihz-nhz)*sf_d(az); gz*=gz; ii[ic][iht][ihx][ihz] *= exp(-gt*gst - gx*gsx - gz*gsz); } } } } } /*------------------------------------------------------------*/ /* write image */ sf_floatwrite(ii[0][0][0],nc*(nhx2)*(nhz2)*(nht2),Fi); /*------------------------------------------------------------*/ /* deallocate arrays */ free(***ii); free(**ii); free(*ii); free(ii); free(*us); free(us); free(*ur); free(ur); free(cc); free(ccin); free(*mcxall); free(mcxall); free(*pcxall); free(pcxall); free(*mczall); free(mczall); free(*pczall); free(pczall); /*------------------------------------------------------------*/ 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[]) { bool verb,adj; /* I/O files */ sf_file Ftrc=NULL; /* traces */ sf_file Fcoo=NULL; /* coordinates */ sf_file Fwfl=NULL; /* wavefield */ /* cube axes */ sf_axis at,az,ax,aa,ac; /* I/O arrays */ float *wco=NULL; /* traces */ pt2d *coo=NULL; /* coordinates */ lint2d cow; /* weights/indices */ float **wfl=NULL; /* wavefield */ fdm2d fdm=NULL; int iz,ix,it; int nz,nx; float dz,dx; float oz,ox; /*------------------------------------------------------------*/ /* init RSF */ sf_init(argc,argv); /*------------------------------------------------------------*/ if(! sf_getbool("verb",&verb)) verb=false; /* verbosity flag */ if(! sf_getbool("adj", &adj)) adj=false; /* adjoint flag */ /*------------------------------------------------------------*/ /* setup I/O */ Fcoo = sf_input("coo"); /* coordinates */ ac = sf_iaxa(Fcoo,2); sf_setlabel(ac,"c"); sf_setunit(ac,""); coo = (pt2d*) sf_alloc(sf_n(ac),sizeof(*coo)); pt2dread1(Fcoo,coo,sf_n(ac),2); /* read (x,z) coordinates */ if(adj) { Fwfl = sf_input ("in"); /* wavefield */ Ftrc = sf_output("out"); /* traces */ az = sf_iaxa(Fwfl,1); sf_setlabel(az,"z"); ax = sf_iaxa(Fwfl,2); sf_setlabel(ax,"x"); at = sf_iaxa(Fwfl,3); sf_setlabel(at,"t"); aa = sf_maxa(1,0,1); sf_oaxa(Ftrc,ac,1); sf_oaxa(Ftrc,at,2); sf_oaxa(Ftrc,aa,3); } else { Ftrc = sf_input ("in" ); /* traces */ Fwfl = sf_output("out"); /* wavefield */ at = sf_iaxa(Ftrc,2); sf_setlabel(at,"t"); if(!sf_getint ("nz",&nz)) nz=1; if(!sf_getfloat("oz",&oz)) oz=0.0; if(!sf_getfloat("dz",&dz)) dz=1.0; az = sf_maxa(nz,oz,dz); sf_setlabel(az,"z"); if(!sf_getint ("nx",&nx)) nx=1; if(!sf_getfloat("ox",&ox)) ox=0.0; if(!sf_getfloat("dx",&dx)) dx=1.0; ax = sf_maxa(nx,ox,dx); sf_setlabel(ax,"x"); sf_oaxa(Fwfl,az,1); sf_oaxa(Fwfl,ax,2); sf_oaxa(Fwfl,at,3); } if(verb) { sf_raxa(az); sf_raxa(ax); sf_raxa(at); sf_raxa(ac); } /* allocate wavefield arrays */ wco = sf_floatalloc (sf_n(ac)); wfl = sf_floatalloc2(sf_n(az),sf_n(ax)); /* interpolation coefficients */ fdm = fdutil_init(verb,'n',az,ax,0,1); cow = lint2d_make(sf_n(ac),coo,fdm); /*------------------------------------------------------------*/ /* * MAIN LOOP */ /*------------------------------------------------------------*/ if(verb) fprintf(stderr,"\n"); for (it=0; it<sf_n(at); it++) { if(verb) fprintf(stderr,"\b\b\b\b\b%d",it); if(adj) { sf_floatread(wfl[0],sf_n(az)*sf_n(ax),Fwfl); lint2d_extract(wfl,wco,cow); sf_floatwrite(wco,sf_n(ac),Ftrc); } else { sf_floatread(wco,sf_n(ac),Ftrc); for (ix=0; ix<sf_n(ax); ix++) for(iz=0; iz<sf_n(az); iz++) wfl[ix][iz]=0; lint2d_inject(wfl,wco,cow); sf_floatwrite(wfl[0],sf_n(az)*sf_n(ax),Fwfl); } } /* end time loop */ if(verb) fprintf(stderr,"\n"); /*------------------------------------------------------------*/ /* deallocate arrays */ free(*wfl); free(wfl); free(wco); free(coo); /*------------------------------------------------------------*/ /* close files */ if (Ftrc!=NULL) sf_fileclose(Ftrc); if (Fwfl!=NULL) sf_fileclose(Fwfl); if (Fcoo!=NULL) sf_fileclose(Fcoo); exit (0); }
int main (int argc, char *argv[]) { bool verb, snap; bool abc, adj; int nz, nx, nt, ns, nr; float dz, dx, dt, oz, ox; int nz0, nx0, nb; float oz0, ox0; int nkz, nkx; int nzpad, nxpad; float **u1, **u0; float *ws, *wr; sf_file file_src = NULL, file_rec = NULL; sf_file file_inp = NULL, file_out = NULL; sf_file file_mdl = NULL; sf_axis az = NULL, ax = NULL, at = NULL, as = NULL, ar = NULL; pt2d *src2d = NULL; pt2d *rec2d = NULL; scoef2d cssinc = NULL; scoef2d crsinc = NULL; float *wi = NULL, *wo = NULL; sf_axis ai = NULL, ao = NULL; scoef2d cisinc = NULL, cosinc = NULL; bool spt = false, rpt = false; bool ipt = false, opt = false; sf_init(argc, argv); if (!sf_getbool("verb", &verb)) verb = false; if (!sf_getbool("snap", &snap)) snap = false; if (!sf_getbool("adj", &adj)) adj = false; if (!sf_getint("nb", &nb)) nb = 4; if (sf_getstring("sou") != NULL) { spt = true; if (adj) opt = true; else ipt = true; } if (sf_getstring("rec") != NULL) { rpt = true; if (adj) ipt = true; else opt = true; } file_inp = sf_input("in"); file_mdl = sf_input("model"); if (spt) file_src = sf_input("sou"); if (rpt) file_rec = sf_input("rec"); file_out = sf_output("out"); if (ipt) at = sf_iaxa(file_inp, 2); else at = sf_iaxa(file_inp, 3); if (spt) as = sf_iaxa(file_src, 2); if (rpt) ar = sf_iaxa(file_rec, 2); az = sf_iaxa(file_mdl, 1); ax = sf_iaxa(file_mdl, 2); nt = sf_n(at); dt = sf_d(at); //ot = sf_o(at); nz0 = sf_n(az); dz = sf_d(az); oz0 = sf_o(az); nx0 = sf_n(ax); dx = sf_d(ax); ox0 = sf_o(ax); if (spt) ns = sf_n(as); if (rpt) nr = sf_n(ar); nz = nz0 + 2 * nb; nx = nx0 + 2 * nb; oz = oz0 - nb * dz; ox = ox0 - nb * dx; abc = nb ? true : false; // sf_error("ox=%f ox0=%f oz=%f oz0=%f",ox,ox0,oz,oz0); nzpad = kiss_fft_next_fast_size( ((nz+1)>>1)<<1 ); nkx = nxpad = kiss_fft_next_fast_size(nx); nkz = nzpad / 2 + 1; /* float okx = - 0.5f / dx; */ float okx = 0.f; float okz = 0.f; float dkx = 1.f / (nxpad * dx); float dkz = 1.f / (nzpad * dz); float **vp, **eps, **del; vp = sf_floatalloc2(nz, nx); eps = sf_floatalloc2(nz, nx); del = sf_floatalloc2(nz, nx); float **tmparray = sf_floatalloc2(nz0, nx0); sf_floatread(tmparray[0], nz0*nx0, file_mdl); expand2d(vp[0], tmparray[0], nz, nx, nz0, nx0); sf_floatread(tmparray[0], nz0*nx0, file_mdl); expand2d(eps[0], tmparray[0], nz, nx, nz0, nx0); sf_floatread(tmparray[0], nz0*nx0, file_mdl); expand2d(del[0], tmparray[0], nz, nx, nz0, nx0); float **vn, **vh; float **eta, **lin_eta; lin_eta = NULL, vh = NULL; vn = sf_floatalloc2(nz, nx); vh = sf_floatalloc2(nz, nx); eta = sf_floatalloc2(nz, nx); lin_eta = sf_floatalloc2(nz, nx); for (int ix=0; ix<nx; ix++) { for (int iz=0; iz<nz; iz++){ vp[ix][iz] *= vp[ix][iz]; vn[ix][iz] = vp[ix][iz] * (1.f + 2.f * del[ix][iz]); vh[ix][iz] = vp[ix][iz] * (1.f + 2.f * eps[ix][iz]); eta[ix][iz] = (eps[ix][iz] - del[ix][iz]) / (1.f + 2.f * del[ix][iz]); lin_eta[ix][iz] = eta[ix][iz] * (1.f + 2.f * del[ix][iz]); } } float *kx = sf_floatalloc(nkx); float *kz = sf_floatalloc(nkz); for (int ikx=0; ikx<nkx; ++ikx) { kx[ikx] = okx + ikx * dkx; /* if (ikx >= nkx/2) kx[ikx] = (nkx - ikx) * dkx; */ if (ikx >= nkx/2) kx[ikx] = (ikx - nkx) * dkx; kx[ikx] *= 2 * SF_PI; kx[ikx] *= kx[ikx]; } for (int ikz=0; ikz<nkz; ++ikz) { kz[ikz] = okz + ikz * dkz; kz[ikz] *= 2 * SF_PI; kz[ikz] *= kz[ikz]; } if (adj) { ai = ar; ao = as; } else { ai = as; ao = ar; } if (opt) { sf_oaxa(file_out, ao, 1); sf_oaxa(file_out, at, 2); } else { sf_oaxa(file_out, az, 1); sf_oaxa(file_out, ax, 2); sf_oaxa(file_out, at, 3); } sf_fileflush(file_out, NULL); if (spt) { src2d = pt2dalloc1(ns); pt2dread1(file_src, src2d, ns, 2); cssinc = sinc2d_make(ns, src2d, nz, nx, dz, dx, oz, ox); ws = sf_floatalloc(ns); if (adj) { cosinc = cssinc; wo = ws; } else { cisinc = cssinc; wi = ws; } } if (rpt) { rec2d = pt2dalloc1(nr); pt2dread1(file_rec, rec2d, nr, 2); crsinc = sinc2d_make(nr, rec2d, nz, nx, dz, dx, oz, ox); wr = sf_floatalloc(nr); if (adj) { cisinc = crsinc; wi = wr; } else { cosinc = crsinc; wo = wr; } } u0 = sf_floatalloc2(nz, nx); u1 = sf_floatalloc2(nz, nx); float *rwave = (float *) fftwf_malloc(nzpad*nxpad*sizeof(float)); float *rwavem = (float *) fftwf_malloc(nzpad*nxpad*sizeof(float)); fftwf_complex *cwave = (fftwf_complex *) fftwf_malloc(nkz*nkx*sizeof(fftwf_complex)); fftwf_complex *cwavem = (fftwf_complex *) fftwf_malloc(nkz*nkx*sizeof(fftwf_complex)); /* float *rwavem = (float *) fftwf_malloc(nzpad*nxpad*sizeof(float)); fftwf_complex *cwave = (fftwf_complex *) fftwf_malloc(nkz*nkx*sizeof(fftwf_complex)); fftwf_complex *cwavem = (fftwf_complex *) fftwf_malloc(nkz*nkx*sizeof(fftwf_complex)); */ /* boundary conditions */ float **ucut = NULL; float *damp = NULL; if (!(ipt &&opt)) ucut = sf_floatalloc2(nz0, nx0); damp = damp_make(nb); float wt = 1./(nxpad * nzpad); wt *= dt * dt; fftwf_plan forward_plan; fftwf_plan inverse_plan; #ifdef _OPENMP #ifdef SF_HAS_FFTW_OMP fftwf_init_threads(); fftwf_plan_with_nthreads(omp_get_max_threads()); #endif #endif forward_plan = fftwf_plan_dft_r2c_2d(nxpad, nzpad, rwave, cwave, FFTW_MEASURE); #ifdef _OPENMP #ifdef SF_HAS_FFTW_OMP fftwf_plan_with_nthreads(omp_get_max_threads()); #endif #endif inverse_plan = fftwf_plan_dft_c2r_2d(nxpad, nzpad, cwavem, rwavem, FFTW_MEASURE); int itb, ite, itc; if (adj) { itb = nt -1; ite = -1; itc = -1; } else { itb = 0; ite = nt; itc = 1; } if (adj) { for (int it=0; it<nt; it++) { if (opt) sf_floatwrite(wo, sf_n(ao), file_out); else sf_floatwrite(ucut[0], nz0*nx0, file_out); } sf_seek(file_out, 0, SEEK_SET); } float **ptrtmp = NULL; memset(u0[0], 0, sizeof(float)*nz*nx); memset(u1[0], 0, sizeof(float)*nz*nx); memset(rwave, 0, sizeof(float)*nzpad*nxpad); memset(rwavem, 0, sizeof(float)*nzpad*nxpad); memset(cwave, 0, sizeof(float)*nkz*nkx*2); memset(cwavem, 0, sizeof(float)*nkz*nkx*2); for (int it=itb; it!=ite; it+=itc) { if (verb) sf_warning("it = %d;",it); #ifdef _OPENMP double tic = omp_get_wtime(); #endif if (ipt) { if (adj) sf_seek(file_inp, (off_t)(it)*sizeof(float)*sf_n(ai), SEEK_SET); sf_floatread(wi, sf_n(ai), file_inp); for (int i=0; i<sf_n(ai); i++) wi[i] *= dt* dt; } else { if (adj) sf_seek(file_inp, (off_t)(it)*sizeof(float)*nz0*nx0, SEEK_SET); sf_floatread(ucut[0], nz0*nx0, file_inp); for (int j=0; j<nx0; j++) for (int i=0; i<nz0; i++) ucut[j][i] *= dt * dt; } /* apply absorbing boundary condition: E \times u@n-1 */ damp2d_apply(u0, damp, nz, nx, nb); fft_stepforward(u0, u1, rwave, rwavem, cwave, cwavem, vp, vn, eta, vh, eps, lin_eta, kz, kx, forward_plan, inverse_plan, nz, nx, nzpad, nxpad, nkz, nkx, wt, adj); // sinc2d_inject1(u0, ws[it][s_idx], cssinc[s_idx]); if (ipt) sinc2d_inject(u0, wi, cisinc); else wfld2d_inject(u0, ucut, nz0, nx0, nb); /* apply absorbing boundary condition: E \times u@n+1 */ damp2d_apply(u0, damp, nz, nx, nb); /* loop over pointers */ ptrtmp = u0; u0 = u1; u1 = ptrtmp; if (opt) { if (adj) sf_seek(file_out, (off_t)(it)*sizeof(float)*sf_n(ao),SEEK_SET); sinc2d_extract(u0, wo, cosinc); sf_floatwrite(wo, sf_n(ao), file_out); } else { if (adj) sf_seek(file_out, (off_t)(it)*sizeof(float)*nz0*nx0,SEEK_SET); wwin2d(ucut, u0, nz0, nx0, nb); sf_floatwrite(ucut[0], nz0*nx0, file_out); } #ifdef _OPENMP double toc = omp_get_wtime(); if (verb) fprintf(stderr," clock = %lf;", toc-tic); #endif } /* END OF TIME LOOP */ return 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); } }