Esempio n. 1
1
  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;
}
Esempio n. 2
0
int main (int argc, char *argv[])
{
    bool verb;
    bool rays;

    sf_axis az,ax;  /* Cartesian coordinates */
    sf_axis at,ag;  /* Ray coordinates */
    int it,ig;
    int nz,nx,nt,ng;
    float dt,dg,ot,og;

    float xsou,zsou; /* source coordinates */

    sf_file Fv=NULL; /* velocity file */
    sf_file Fw=NULL; /* wavefronfs file */

    float **vv=NULL; /* velocity       */
    pt2d   *wm=NULL; /* wavefront it-1 */
    pt2d   *wo=NULL; /* wavefront it   */
    pt2d   *wp=NULL; /* wavefront it+1 */

    pt2d    Ro;    /* point  on wft it-1 */
    pt2d Pm,Po,Pp; /* points on wft it   */
    pt2d    Qo;    /* point  on wft it+1 */

    /*------------------------------------------------------------*/
    sf_init(argc,argv);
    if(! sf_getbool("verb",&verb)) verb=false;
    if(! sf_getbool("rays",&rays)) rays=false;

    /* velocity file */
    Fv = sf_input ("in");
    az = sf_iaxa(Fv,1); sf_setlabel(az,"z"); nz=sf_n(az); if(verb) sf_raxa(az);
    ax = sf_iaxa(Fv,2); sf_setlabel(ax,"x"); nx=sf_n(ax); if(verb) sf_raxa(ax);

    vv=sf_floatalloc2(nz,nx); 
    sf_floatread(vv[0],nz*nx,Fv);

    /* source location */
    if(! sf_getfloat("xsou",&xsou)) xsou=sf_o(ax) + nx*sf_d(ax)/2;
    if(! sf_getfloat("zsou",&zsou)) zsou=sf_o(az) + nz*sf_d(az)/2;
    if(verb) fprintf(stderr,"xsou=%f zsou=%f\n",xsou,zsou);

    /* time axis */
    if(! sf_getint  ("nt",&nt)) nt=100;
    if(! sf_getfloat("ot",&ot)) ot=0;
    if(! sf_getfloat("dt",&dt)) dt=0.001;
    at = sf_maxa(nt,ot,dt); sf_setlabel(at,"t");

    /* shooting angle axis */
    if(! sf_getint  ("ng",&ng)) ng= 360;
    if(! sf_getfloat("og",&og)) og=-180;
    if(! sf_getfloat("dg",&dg)) dg= 1;
    ag = sf_maxa(ng,og,dg); sf_setlabel(ag,"g");

    /*------------------------------------------------------------*/
    /* wavefronts file (g,t) */
    Fw = sf_output("out");
    sf_oaxa(Fw,ag,1); if(verb) sf_raxa(ag);
    sf_oaxa(Fw,at,2); if(verb) sf_raxa(at);

    /* set the output to complex */
    sf_putint(Fw,"esize",8);
    sf_settype(Fw,SF_COMPLEX);

    /*------------------------------------------------------------*/
    /* allocate wavefronts */
    wm = pt2dalloc1(ng);
    wo = pt2dalloc1(ng);
    wp = pt2dalloc1(ng);

    /* initialize wavefronts */
    for( ig=0; ig<ng; ig++) {
	wm[ig].x=wo[ig].x=wp[ig].x=0;
	wm[ig].z=wo[ig].z=wp[ig].z=0;
	wm[ig].v=wo[ig].v=wp[ig].v=0;
    }

    /*------------------------------------------------------------*/
    /* init HWT */
    hwt2d_init(vv,az,ax,at,ag);

    /*------------------------------------------------------------*/
    /* construct it=0 wavefront */
    it=0;
    for( ig=0; ig<ng; ig++) {
	wm[ig].x=xsou;
	wm[ig].z=zsou;
	wm[ig].v=hwt2d_getv(wm[ig]);
    }
    pt2dwrite1(Fw,wm,ng,2); /* write wavefront it=0 */

    /*------------------------------------------------------------*/
    /* construct it=1 wavefront */
    it=1;
    for( ig=0; ig<ng; ig++) {
	double d,g;

	d = dt * hwt2d_getv(wm[ig]);
	g = (og+ig*dg) * SF_PI/180;

	wo[ig].x=xsou + d*sin(g);
	wo[ig].z=zsou + d*cos(g);
	wo[ig].v=hwt2d_getv(wo[ig]);
    }
    pt2dwrite1(Fw,wo,ng,2); /* write wavefront it=1 */

    /*------------------------------------------------------------*/
    /* LOOP over time */
    for (it=2; it<nt; it++) {
	if(verb) fprintf(stderr,"it=%d\n",it);
	
	if(ng>3 && !rays) {
	    /* boundaries */
	    ig=0;      wp[ig] = hwt2d_raytr(wm[ig],wo[ig]);
	    ig=ng-1; wp[ig] = hwt2d_raytr(wm[ig],wo[ig]);

	    for (ig=1; ig<ng-1; ig++) {
		
		Pm = wo[ig-1];
		Po = wo[ig  ];  Qo = wm[ig];
		Pp = wo[ig+1];
		
		if(hwt2d_cusp(Qo,Pm,Po,Pp)) {
		    Ro = hwt2d_raytr(Qo,   Po   );
		} else {
		    Ro = hwt2d_wfttr(Qo,Pm,Po,Pp);
		}
		wp[ig] = Ro;
	    }
	} else {
	    for (ig=0; ig<ng; ig++) {
		Po = wo[ig];  
		Qo = wm[ig];
		Ro = hwt2d_raytr(Qo,Po);
		wp[ig] = Ro;
	    }
	}

	/* write wavefront it */
	pt2dwrite1(Fw,wp,ng,2);

	/* step in time */
	for( ig=0; ig<ng; ig++) {
	    wm[ig] = wo[ig];
	    wo[ig] = wp[ig];
	}
    } /* end it */

    /*------------------------------------------------------------*/

    exit (0);
}
Esempio n. 3
0
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);
}
Esempio n. 4
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;
}