Ejemplo n.º 1
0
/* Expand group-4 data */
void
g4expand(struct pagenode *pn, drawfunc df)
{
    int RunLength;		/* Length of current run */
    int a0;			/* reference element */
    int b1;			/* next change on previous line */
    int lastx = pn->size.width();/* copy line width to register */
    pixnum *run0, *run1;	/* run length arrays */
    pixnum *thisrun, *pa, *pb;	/* pointers into runs */
    t16bits *sp;		/* pointer into compressed data */
    t32bits BitAcc;		/* bit accumulator */
    int BitsAvail;		/* # valid bits in BitAcc */
    int	LineNum;		/* line number */
    int EOLcnt;
    struct tabent *TabEnt;

    sp = pn->data;
    BitAcc = 0;
    BitsAvail = 0;
    /* allocate space for 2 runlength arrays */
    run0 = (pixnum *) malloc(2 * ((lastx+5)&~1) * sizeof(pixnum));
    run1 = run0 + ((lastx+5)&~1);
    run1[0] = lastx;		/* initial reference line */
    run1[1] = 0;

    for (LineNum = 0; LineNum < pn->rowsperstrip; ) {
#ifdef DEBUG_FAX
	printf("\nBitAcc=%08lX, BitsAvail = %d\n", BitAcc, BitsAvail);
	printf("-------------------- %d\n", LineNum);
	fflush(stdout);
#endif
	RunLength = 0;
	if (LineNum & 1) {
	    pa = run1;
	    pb = run0;
	}
	else {
	    pa = run0;
	    pb = run1;
	}
	thisrun = pa;
	a0 = 0;
	b1 = *pb++;
	expand2d(EOFB);
	if (a0 < lastx) {
	    if ((pa - run0) & 1)
		SETVAL(0);
	    SETVAL(lastx - a0);
	}
	SETVAL(0);	/* imaginary change at end of line for reference */
	(*df)(thisrun, LineNum++, pn);
	continue;
    EOFB:
	NeedBits(13);
	if (GetBits(13) != 0x1001 && verbose)
            kError() << "Bad RTC\n";
	break;
    }
    free(run0);
}
Ejemplo n.º 2
0
int main(int argc, char* argv[])
{
	int it,kt,ia,is,i1,i2,tdmute,jsx,jsz,jgx,jgz,sxbeg,szbeg,gxbeg,gzbeg, distx, distz;
	int *sxz, *gxz;
	float tmp, amp, vmax;
	float *wlt, *d2x, *d1z, *bndr;
	float **v0, **vv, **dcal, **den;
	float **sp, **spz, **spx, **svz, **svx, **gp, **gpz, **gpx, **gvz, **gvx;
	float ***num, ***adcig;
    	sf_file vmodl, rtmadcig, vecx, vecz; /* I/O files */

    	sf_init(argc,argv);
#ifdef _OPENMP
    	omp_init();
#endif

    	/*< set up I/O files >*/
    	vmodl = sf_input ("in");   /* velocity model, unit=m/s */
    	rtmadcig = sf_output("out");  /* ADCIG obtained by Poynting vector */
	vecx=sf_output("vecx");
	vecz=sf_output("vecz");

    	/* get parameters for RTM */
    	if (!sf_histint(vmodl,"n1",&nz)) sf_error("no n1");
    	if (!sf_histint(vmodl,"n2",&nx)) sf_error("no n2");
    	if (!sf_histfloat(vmodl,"d1",&dz)) sf_error("no d1");
   	if (!sf_histfloat(vmodl,"d2",&dx)) sf_error("no d2");

    	if (!sf_getfloat("amp",&amp)) amp=1.e3;	
	/* maximum amplitude of ricker wavelet*/
    	if (!sf_getfloat("fm",&fm)) sf_error("no fm");	
	/* dominant freq of ricker */
    	if (!sf_getfloat("dt",&dt)) sf_error("no dt");	
	/* time interval */
    	if (!sf_getint("nt",&nt))   sf_error("no nt");	
	/* total modeling time steps */
    	if (!sf_getint("ns",&ns))   sf_error("no ns");	
	/* total shots */
    	if (!sf_getint("ng",&ng))   sf_error("no ng");	
	/* total receivers in each shot */
    	if (!sf_getint("nb",&nb))   nb=20; 
	/* thickness of split PML */
    	if (!sf_getint("na",&na)) na=30;
	/* number of angles*/
    	if (!sf_getint("kt",&kt))   kt=200;
	/* record poynting vector at kt */
	if (!sf_getint("jsx",&jsx))   sf_error("no jsx");
	/* source x-axis  jump interval  */
    	if (!sf_getint("jsz",&jsz))   jsz=0;
	/* source z-axis jump interval  */
    	if (!sf_getint("jgx",&jgx))   jgx=1;
	/* receiver x-axis jump interval */
    	if (!sf_getint("jgz",&jgz))   jgz=0;
	/* receiver z-axis jump interval */
    	if (!sf_getint("sxbeg",&sxbeg))   sf_error("no sxbeg");
	/* x-begining index of sources, starting from 0 */
    	if (!sf_getint("szbeg",&szbeg))   sf_error("no szbeg");
	/* z-begining index of sources, starting from 0 */
    	if (!sf_getint("gxbeg",&gxbeg))   sf_error("no gxbeg");
	/* x-begining index of receivers, starting from 0 */
    	if (!sf_getint("gzbeg",&gzbeg))   sf_error("no gzbeg");
	/* z-begining index of receivers, starting from 0 */
	if (!sf_getbool("csdgather",&csdgather)) csdgather=true;
	/* default, common shot-gather; if n, record at every point*/
	if (!sf_getfloat("vmute",&vmute))   vmute=1500;
	/* muting velocity to remove the low-freq noise, unit=m/s*/
	if (!sf_getint("tdmute",&tdmute))   tdmute=2./(fm*dt);
	/* number of deleyed time samples to mute */

	_dx=1./dx;
	_dz=1./dz;
	nzpad=nz+2*nb;
	nxpad=nx+2*nb;
	da=SF_PI/(float)na;/* angle unit, rad; */
	var=da/3.;
	var=2.0*var*var;

    	sf_putint(rtmadcig,"n1",nz);
    	sf_putint(rtmadcig,"n2",nx);
	sf_putfloat(rtmadcig,"n3",na);
    	sf_putfloat(rtmadcig,"d1",dz);
    	sf_putfloat(rtmadcig,"d2",dx);
	sf_putfloat(rtmadcig,"d3",90./(float)na);

	/* allocate variables */
	wlt=sf_floatalloc(nt);
	v0=sf_floatalloc2(nz,nx); 	
	vv=sf_floatalloc2(nzpad, nxpad);
	sp =sf_floatalloc2(nzpad, nxpad);
	spz=sf_floatalloc2(nzpad, nxpad);
	spx=sf_floatalloc2(nzpad, nxpad);
	svz=sf_floatalloc2(nzpad, nxpad);
	svx=sf_floatalloc2(nzpad, nxpad);
	gp =sf_floatalloc2(nzpad, nxpad);
	gpz=sf_floatalloc2(nzpad, nxpad);
	gpx=sf_floatalloc2(nzpad, nxpad);
	gvz=sf_floatalloc2(nzpad, nxpad);
	gvx=sf_floatalloc2(nzpad, nxpad);
	d1z=sf_floatalloc(nzpad);
	d2x=sf_floatalloc(nxpad);
	sxz=sf_intalloc(ns);
	gxz=sf_intalloc(ng);
	dcal=sf_floatalloc2(ng,nt);
	bndr=(float*)malloc(nt*8*(nx+nz)*sizeof(float));
	den=sf_floatalloc2(nz,nx);
	num=sf_floatalloc3(nz,nx,na);
	adcig=sf_floatalloc3(nz,nx,na);

	/* initialize variables */
	for(it=0;it<nt;it++){
		tmp=SF_PI*fm*(it*dt-1.0/fm);tmp*=tmp;
		wlt[it]=amp*(1.0-2.0*tmp)*expf(-tmp);
	}
	sf_floatread(v0[0],nz*nx,vmodl);
	expand2d(vv, v0);
	memset(sp [0],0,nzpad*nxpad*sizeof(float));
	memset(spx[0],0,nzpad*nxpad*sizeof(float));
	memset(spz[0],0,nzpad*nxpad*sizeof(float));
	memset(svx[0],0,nzpad*nxpad*sizeof(float));
	memset(svz[0],0,nzpad*nxpad*sizeof(float));
	memset(gp [0],0,nzpad*nxpad*sizeof(float));
	memset(gpx[0],0,nzpad*nxpad*sizeof(float));
	memset(gpz[0],0,nzpad*nxpad*sizeof(float));
	memset(gvx[0],0,nzpad*nxpad*sizeof(float));
	memset(gvz[0],0,nzpad*nxpad*sizeof(float));
	vmax=v0[0][0];
	for(i2=0; i2<nx; i2++)
	for(i1=0; i1<nz; i1++)
		vmax=SF_MAX(v0[i2][i1],vmax);
	pmlcoeff_init(d1z, d2x, vmax);
	if (!(sxbeg>=0 && szbeg>=0 && sxbeg+(ns-1)*jsx<nx && szbeg+(ns-1)*jsz<nz))	
	{ sf_error("sources exceeds the computing zone!"); exit(1);}
	sg_init(sxz, szbeg, sxbeg, jsz, jsx, ns);
	distx=sxbeg-gxbeg;
	distz=szbeg-gzbeg;
	if (csdgather)	{
		if (!(gxbeg>=0 && gzbeg>=0 && gxbeg+(ng-1)*jgx<nx && gzbeg+(ng-1)*jgz<nz &&
		(sxbeg+(ns-1)*jsx)+(ng-1)*jgx-distx <nx  && (szbeg+(ns-1)*jsz)+(ng-1)*jgz-distz <nz))	
		{ sf_error("geophones exceeds the computing zone!"); exit(1);}
	}else{
		if (!(gxbeg>=0 && gzbeg>=0 && gxbeg+(ng-1)*jgx<nx && gzbeg+(ng-1)*jgz<nz))	
		{ sf_error("geophones exceeds the computing zone!"); exit(1);}
	}
	sg_init(gxz, gzbeg, gxbeg, jgz, jgx, ng);
	memset(adcig[0][0], 0, na*nz*nx*sizeof(float));

	for(is=0; is<ns; is++)
	{
		wavefield_init(sp, spz, spx, svz, svx);
		if (csdgather)	{
			gxbeg=sxbeg+is*jsx-distx;
			sg_init(gxz, gzbeg, gxbeg, jgz, jgx, ng);
		}
		for(it=0; it<nt; it++)
		{
			add_source(&sxz[is], sp, 1, &wlt[it], true);
			step_forward(sp, spz, spx, svz, svx, vv, d1z, d2x);
			bndr_rw(false, svz, svx, &bndr[it*8*(nx+nz)]);
		
			record_seis(dcal[it], gxz, sp, ng);
			muting(dcal[it], gzbeg, szbeg, gxbeg, sxbeg+is*jsx, jgx, it, tdmute);
		}

		wavefield_init(gp, gpz, gpx, gvz, gvx);
		memset(num[0][0], 0, na*nz*nx*sizeof(float));
		memset(den[0], 0, nz*nx*sizeof(float));
		for(it=nt-1; it>-1; it--)
		{	
			add_source(gxz, gp, ng, dcal[it], true);
			step_forward(gp, gpz, gpx, gvz, gvx, vv, d1z, d2x);	

			if(it==kt)
			{
				window2d(v0,svx);
				sf_floatwrite(v0[0],nz*nx,vecx);
				window2d(v0,svz);
				sf_floatwrite(v0[0],nz*nx,vecz);
			}

			bndr_rw(true, svz, svx, &bndr[it*8*(nx+nz)]);	
			cross_correlation(num, den, sp, gp, svz, svx, gvz, gvx);

			step_backward(sp, svz, svx, vv);
			add_source(&sxz[is], sp, 1, &wlt[it], false);
		}	

		for(ia=0; ia<na; ia++)
		for(i2=0; i2<nx; i2++)
		for(i1=0; i1<nz; i1++)
			adcig[ia][i2][i1]+=num[ia][i2][i1]/(den[i2][i1]+SF_EPS);
	}
	sf_floatwrite(adcig[0][0], na*nz*nx,rtmadcig);

	free(wlt);
	free(*v0); free(v0);
	free(*vv); free(vv);
	free(*sp); free(sp);
	free(*spx); free(spx);
	free(*spz); free(spz);
	free(*svx); free(svx);
	free(*svz); free(svz);
	free(*gp); free(gp);
	free(*gpx); free(gpx);
	free(*gpz); free(gpz);
	free(*gvx); free(gvx);
	free(*gvz); free(gvz);
	free(d1z);
	free(d2x);
	free(sxz);
	free(gxz);
	free(bndr);
	free(*den); free(den);
	free(**num); free(*num); free(num);
	free(**adcig); free(*adcig); free(adcig);

    	exit(0);
}
Ejemplo n.º 3
0
/* Expand group-3 2-dimensional data */
void
g32expand(struct pagenode *pn, drawfunc df)
{
    int RunLength;		/* Length of current run */
    int a0;			/* reference element */
    int b1;			/* next change on previous line */
    int lastx = pn->size.width();/* copy line width to register */
    pixnum *run0, *run1;	/* run length arrays */
    pixnum *thisrun, *pa, *pb;	/* pointers into runs */
    t16bits *sp;		/* pointer into compressed data */
    t32bits BitAcc;		/* bit accumulator */
    int BitsAvail;		/* # valid bits in BitAcc */
    int EOLcnt;			/* number of consecutive EOLs */
    int	refline = 0;		/* 1D encoded reference line */
    int	LineNum;		/* line number */
    struct tabent *TabEnt;

    sp = pn->data;
    BitAcc = 0;
    BitsAvail = 0;
    /* allocate space for 2 runlength arrays */
    run0 = (pixnum *) malloc(2 * ((lastx+5)&~1) * sizeof(pixnum));
    run1 = run0 + ((lastx+5)&~1);
    run1[0] = lastx;
    run1[1] = 0;
    EOLcnt = 0;
    for (LineNum = 0; LineNum < pn->rowsperstrip; ) {
#ifdef DEBUG_FAX
	printf("\nBitAcc=%08lX, BitsAvail = %d\n", BitAcc, BitsAvail);
	printf("-------------------- %d\n", LineNum);
	fflush(stdout);
#endif
	if (EOLcnt == 0)
	    while (!EndOfData(pn)) {
		/* skip over garbage after a coding error */
		NeedBits(11);
		if (GetBits(11) == 0)
		    break;
		ClrBits(1);
	    }
	for (EOLcnt = 1; !EndOfData(pn); EOLcnt++) {
	    /* we have seen 11 zeros, which implies EOL,
	       skip possible fill bits too */
	    while (1) {
		NeedBits(8);
		if (GetBits(8))
		    break;
		ClrBits(8);
	    }
	    while (GetBits(1) == 0)
		ClrBits(1);
	    ClrBits(1);		/* the eol flag */
	    NeedBits(12);
	    refline = GetBits(1); /* 1D / 2D flag */
	    ClrBits(1);
	    if (GetBits(11))
		break;
	    ClrBits(11);
	}
	if (EOLcnt > 1 && EOLcnt != 6 && verbose)
            kError() << "Line " << LineNum << ": bad RTC (" << EOLcnt << " EOLs)\n";
	if (EOLcnt >= 6 || EndOfData(pn)) {
	    free(run0);
	    return;
	}
	if (LineNum == 0 && refline == 0 && verbose)
            kDebug() << "First line is 2-D encoded\n";
	RunLength = 0;
	if (LineNum & 1) {
	    pa = run1;
	    pb = run0;
	}
	else {
	    pa = run0;
	    pb = run1;
	}
	thisrun = pa;
	EOLcnt = 0;
	a0 = 0;
	b1 = *pb++;

	if (refline) {
	    expand1d();
	}
	else {
	    expand2d(EOL2);
	}
	if (RunLength)
	    SETVAL(0);
	if (a0 != lastx) {
	    if (verbose)
                kWarning() << "Line " << LineNum << ": length is "
			<< a0 << " (expected "<< lastx << ")\n";
	    while (a0 > lastx)
		a0 -= *--pa;
	    if (a0 < lastx) {
		if ((pa - run0) & 1)
		    SETVAL(0);
		SETVAL(lastx - a0);
	    }
	}
	SETVAL(0);	/* imaginary change at end of line for reference */
	(*df)(thisrun, LineNum++, pn);
    }
    free(run0);
}
Ejemplo 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;
}