Beispiel #1
0
/*---------------------------------------------------------------------------*/
void
polite_close(struct polite_conn *c)
{
  abc_close(&c->c);
  ctimer_stop(&c->t);
  if(c->q != NULL) {
    queuebuf_free(c->q);
    c->q = NULL;
  }
}
/*---------------------------------------------------------------------------*/
void p_broadcast_close(struct p_broadcast_conn *c)
{

	if (c == NULL)
	{
		PRINTF("[pbroadcast.c] Error: Broadcast Connection is NULL\n");
		return;
	}

	abc_close(&(c->abc));
}
   PROCESS_THREAD( contiki_ext_radio_process, ev, data )
   {
      PROCESS_EXITHANDLER( abc_close(&wiselib::contiki::contiki_extdata_radio_conn) );

      PROCESS_BEGIN();

      abc_open( &wiselib::contiki::contiki_extdata_radio_conn, 128, &wiselib::contiki::abc_call );

      while(1)
      {
         static struct etimer et;
         etimer_set( &et, CLOCK_SECOND );

         PROCESS_WAIT_EVENT_UNTIL( etimer_expired(&et) );
      }

      PROCESS_END();
   }
Beispiel #4
0
PROCESS_THREAD(example_abc_process, ev, data)
{
   static struct etimer et;
   PROCESS_EXITHANDLER(abc_close(&abc);)
Beispiel #5
0
int main(int argc, char* argv[])
{
    bool verb,pas,adj,abc;          /* execution flags */
    int ix, iz, it;                 /* index variables */
    int nt, nx, nz, depth, nzxpad, nb, n2, snap;
    float ox, oz, dx, dz, dt, dt2, idz2, idx2, cb;

    int nxpad, nzpad;
    float **vvpad;
    
    float **dd, **mm, **vv, ***ww;
    float **u0, **u1, **u2, **tmp;  /* temporary arrays */

    sf_file in, out, vel, wave;     /* I/O files */

    /* initialize Madagascar */
    sf_init(argc,argv);
    
    /* initialize OpenMP support */
#ifdef _OPENMP
    omp_init();
#endif

    if(!sf_getbool("verb", &verb)) verb=false;
    /* verbosity flag */
    if(!sf_getbool("adj", &adj)) adj=false;
    /* adjoint flag, 0: modeling, 1: migration */
    if(!sf_getbool("pas", &pas)) pas=false;
    /* passive flag, 0: exploding reflector rtm, 1: passive seismic imaging */
    if(!sf_getbool("abc",&abc)) abc = false;
    /* absorbing boundary condition */
    if(!sf_getint("snap", &snap)) snap=0;
    /* wavefield snapshot flag */
    if(!sf_getint("depth", &depth)) depth=0;
    /* surface */
	
    /* setup I/O files */
    in  = sf_input("in");
    out = sf_output("out");
    vel = sf_input("velocity");
    /* velocity model */
    
    /* Dimensions */
    if(!sf_histint  (vel, "n1", &nz)) sf_error("No n1= in velocity");
    if(!sf_histint  (vel, "n2", &nx)) sf_error("No n2= in velocity");
    if(!sf_histfloat(vel, "o1", &oz)) sf_error("No o1= in velocity");
    if(!sf_histfloat(vel, "o2", &ox)) sf_error("No o2= in velocity");
    if(!sf_histfloat(vel, "d1", &dz)) sf_error("No d1= in velocity");
    if(!sf_histfloat(vel, "d2", &dx)) sf_error("No d2= in velocity");

    if(adj){ /* migration */
        if(!sf_histint(in, "n1", &nt)) sf_error("No n1= in data");
        if(!sf_histfloat(in, "d1", &dt)) sf_error("No d1= in data");
        if(!sf_histint(in, "n2", &n2) || n2!=nx) sf_error("Need n2=%d in data", nx);

        sf_putint   (out, "n1", nz);
        sf_putfloat (out, "o1", oz);
        sf_putfloat (out, "d1", dz);
        sf_putstring(out, "label1", "Depth");
        sf_putstring(out, "unit1" , "km");
        sf_putint   (out, "n2", nx);
        sf_putfloat (out, "o2", ox);
        sf_putfloat (out, "d2", dx);
        sf_putstring(out, "label2", "Distance");
        sf_putstring(out, "unit2" , "km");
        if (pas) {
            sf_putint   (out, "n3", nt);
            sf_putfloat (out, "d3", dt);
            sf_putfloat (out, "o3", 0.0f);
            sf_putstring(out, "label3", "Time");
            sf_putstring(out, "unit3" , "s");
        }
    }else{ /* modeling */
        if(!sf_getint("nt", &nt)) sf_error("Need nt=");
        if(!sf_getfloat("dt", &dt)) sf_error("Need dt=");
        
        sf_putint   (out, "n1", nt);
        sf_putfloat (out, "d1", dt);
        sf_putfloat (out, "o1", 0.0);
        sf_putstring(out, "label1", "Time");
        sf_putstring(out, "unit1" , "s");
        sf_putint   (out, "n2", nx);
        sf_putfloat (out, "o2", ox);
        sf_putfloat (out, "d2", dx);
        sf_putstring(out, "label2", "Distance");
        sf_putstring(out, "unit2" , "km");
        if (pas) {
            sf_putint   (out, "n3", 1);
        }
    }
    
    /* dimension of padded boundary */
    if(!sf_getint("nb", &nb) || nb<NOP) nb = NOP;
    if(!sf_getfloat("cb", &cb)) cb = 0.0f;
    nxpad = nx+2*nb;
    nzpad = nz+2*nb;
    nzxpad = nzpad*nxpad;
    depth = depth+nb;

    /* set Laplacian coefficients */
    idz2 = 1.0f/(dz*dz);
    idx2 = 1.0f/(dx*dx);
    
    /* wavefield snapshot */
    if(snap){
        wave = sf_output("wave");
        
        sf_putint(wave, "n1", nzpad);
        sf_putfloat(wave, "d1", dz);
        sf_putfloat(wave, "o1", oz-nb*dz);
            
        sf_putint(wave, "n2", nxpad);
        sf_putfloat(wave, "d2", dx);
        sf_putfloat(wave, "o2", ox-nb*dx);
        
        sf_putint(wave, "n3", 1+(nt-1)/snap);
        if(adj){
            sf_putfloat(wave, "d3", -snap*dt);
            sf_putfloat(wave, "o3", (nt-1)*dt);
        }else{
            sf_putfloat(wave, "d3", snap*dt);
            sf_putfloat(wave, "o3", 0.0f);
        }
    }
        
    /* allocate arrays */
    vv    = sf_floatalloc2(nz, nx);
    dd    = sf_floatalloc2(nt, nx);
    vvpad = sf_floatalloc2(nzpad, nxpad);
    u0    = sf_floatalloc2(nzpad, nxpad);
    u1    = sf_floatalloc2(nzpad, nxpad);
    u2    = sf_floatalloc2(nzpad, nxpad);
    if (pas) {
        mm = NULL;
        ww = sf_floatalloc3(nz, nx, nt);
    } else {
        mm = sf_floatalloc2(nz, nx);
        ww = NULL;
    }
    
    /* read velocity */
    sf_floatread(vv[0], nz*nx, vel);
    
    /* pad boundary */
    dt2 = dt*dt;
    for     (ix=0; ix<nx; ix++)
        for (iz=0; iz<nz; iz++)
            vvpad[ix+nb][iz+nb] = vv[ix][iz]*vv[ix][iz]*dt2;
    for     (ix=0; ix<nxpad; ix++){
        for (iz=0; iz<nb;    iz++){
            vvpad[ix][      iz  ] = vvpad[ix][      nb  ];
            vvpad[ix][nzpad-iz-1] = vvpad[ix][nzpad-nb-1];
        }
    }
    for     (ix=0; ix<nb;    ix++){
        for (iz=0; iz<nzpad; iz++){
            vvpad[      ix  ][iz]=vvpad[      nb  ][iz];
            vvpad[nxpad-ix-1][iz]=vvpad[nxpad-nb-1][iz];
        }
    }

    memset(u0[0], 0.0f, nzxpad*sizeof(float));
    memset(u1[0], 0.0f, nzxpad*sizeof(float));
    memset(u2[0], 0.0f, nzxpad*sizeof(float));

    /* absorbing boundary condition */
    if (abc) {
        if (verb) sf_warning("absorbing boundary condition");
        abc_init(nzpad,nxpad,nzpad,nxpad,nb,nb,nb,nb,cb,cb,cb,cb);
    }

    if(adj){ /* migration */
        
        /* read data */
        sf_floatread(dd[0], nt*nx, in);
        
        for (it=nt-1; it>-1; it--){
            if (verb) sf_warning("Migration: %d/%d;", it, 0);
            
            /* time stepping */
#ifdef _OPENMP
#pragma omp parallel for default(shared) private(ix, iz)
#endif
            for     (ix=NOP; ix<nxpad-NOP; ix++){
                for (iz=NOP; iz<nzpad-NOP; iz++){
                    u2[ix][iz] = LapT(u1,ix,iz,idx2,idz2,vvpad) + 2.0f*u1[ix][iz] - u0[ix][iz];
                }
            }
            /* rotate pointers */
            tmp=u0; u0=u1; u1=u2; u2=tmp;
            if (abc) abc_apply(u1[0]);
            if (abc) abc_apply(u0[0]);

            /* inject data */
#ifdef _OPENMP
#pragma omp parallel for default(shared) private(ix)
#endif
            for (ix=nb; ix<nb+nx; ix++)
                u1[ix][depth] += dd[ix-nb][it];
            
            if (pas) {
                /* image source */
#ifdef _OPENMP
#pragma omp parallel for default(shared) private(ix, iz)
#endif
                for     (ix=0; ix<nx; ix++)
                    for (iz=0; iz<nz; iz++)
                        ww[it][ix][iz] = u1[ix+nb][iz+nb];
            }
            if (snap && it%snap==0) sf_floatwrite(u1[0], nzxpad, wave);
        }
        if (verb) sf_warning(".");

        if (!pas) {
            /* output image */
#ifdef _OPENMP
#pragma omp parallel for default(shared) private(ix, iz)
#endif
            for     (ix=0; ix<nx; ix++)
                for (iz=0; iz<nz; iz++)
                    mm[ix][iz] = u1[ix+nb][iz+nb];
            sf_floatwrite(mm[0], nz*nx, out);
        } else {
            /* output source */
            sf_floatwrite(ww[0][0], nz*nx*nt, out);
        }
    
    }else{/* modeling */
    	
        if (pas) { 
            /* read source */
            sf_floatread(ww[0][0], nz*nx*nt, in);
        } else { 
            /* read image */
            sf_floatread(mm[0], nz*nx, in);
#ifdef _OPENMP
#pragma omp parallel for default(shared) private(ix, iz)
#endif
            for     (ix=0; ix<nx; ix++)
                for (iz=0; iz<nz; iz++)
                    u1[ix+nb][iz+nb] = mm[ix][iz];
        }

    	for (it=0; it<nt; it++){
            if (verb) sf_warning("Modeling: %d/%d;", it, nt-1);
            
            if(snap && it%snap==0) sf_floatwrite(u1[0], nzxpad, wave);
            if (pas){
                /* inject source */
#ifdef _OPENMP
#pragma omp parallel for default(shared) private(ix, iz)
#endif
                for     (ix=0; ix<nx; ix++)
                    for (iz=0; iz<nz; iz++)
                        u1[ix+nb][iz+nb] += ww[it][ix][iz];
            }

            /* record data */
#ifdef _OPENMP
#pragma omp parallel for default(shared) private(ix)
#endif
            for (ix=nb; ix<nb+nx; ix++)
	        dd[ix-nb][it] = u1[ix][depth];
            
            if (abc) abc_apply(u0[0]);
            if (abc) abc_apply(u1[0]);
            /* time stepping */
#ifdef _OPENMP
#pragma omp parallel for default(shared) private(ix, iz)
#endif
            for     (ix=NOP; ix<nxpad-NOP; ix++){
                for (iz=NOP; iz<nzpad-NOP; iz++){
                    u2[ix][iz] = Lap (u1,ix,iz,idx2,idz2,vvpad) + 2.0f*u1[ix][iz] - u0[ix][iz];
                }
            }
            /* rotate pointers */
            tmp=u0; u0=u1; u1=u2; u2=tmp;
        }
    	if (verb) sf_warning(".");
        
    	/* output data */
    	sf_floatwrite(dd[0], nt*nx, out);
    }

    if(pas) {
        free(**ww); free(*ww); free(ww);
    } else {
        free(*mm); free(mm);
    }

    if (abc) abc_close();
    free(*vvpad); free(vvpad); free(*vv); free(vv);
    free(*dd); free(dd); 
    free(*u0); free(u0); free(*u1); free(u1); free(*u2); free(u2);
    exit (0);
}
Beispiel #6
0
/*---------------------------------------------------------------------------*/
void
broadcast_close(struct broadcast_conn *c)
{
  abc_close(&c->c);
}
Beispiel #7
0
int psp4(float **wvfld, float **wvfld0, float **dat, float **dat_v, float *vel, pspar par)
/*< pseudo-spectral wave extrapolation using wavefield injection >*/
{
    /*survey parameters*/
    int   nx, nz;
    float dx, dz;
    int   n_srcs;
    int   *spx, *spz;
    int   gpz, gpx, gpl;
    int   gpz_v, gpx_v, gpl_v;
    int   snap;
    /*fft related*/
    bool  cmplx;
    int   pad1;
    /*absorbing boundary*/
    bool abc;
    int nbt, nbb, nbl, nbr;
    float ct,cb,cl,cr;
    /*source parameters*/
    int src; /*source type*/
    int nt;
    float dt,*f0,*t0,*A;
    /*misc*/
    bool verb, ps;
    float vref;
    
    int nx1, nz1; /*domain of interest*/
    int it,iz,ik,ix,i,j;     /* index variables */
    int nk,nzx,nz2,nx2,nzx2,nkz,nth;
    int it1, it2, its;
    float dkx,dkz,kx0,kz0,vref2,kx,kz,k,t;
    float c, old;

    /*wave prop arrays*/
    float *vv;
    sf_complex *cwave,*cwavem;
    float *wave,*curr,*prev,*lapl;

    /*source*/
    float **rick;
    float freq;
    int fft_size;

    /*passing the parameters*/
    nx    = par->nx;
    nz    = par->nz;
    dx    = par->dx;
    dz    = par->dz;
    n_srcs= par->n_srcs;
    spx   = par->spx;
    spz   = par->spz;
    gpz   = par->gpz;
    gpx   = par->gpx;
    gpl   = par->gpl;
    gpz_v = par->gpz_v;
    gpx_v = par->gpx_v;
    gpl_v = par->gpl_v;
    snap  = par->snap;
    cmplx = par->cmplx;
    pad1  = par->pad1;
    abc   = par->abc;
    nbt   = par->nbt;
    nbb   = par->nbb;
    nbl   = par->nbl;
    nbr   = par->nbr;
    ct    = par->ct;
    cb    = par->cb;
    cl    = par->cl;
    cr    = par->cr;
    src   = par->src;
    nt    = par->nt;
    dt    = par->dt;
    f0    = par->f0;
    t0    = par->t0;
    A     = par->A;
    verb  = par->verb;
    ps    = par->ps;
    vref  = par->vref;
    

#ifdef _OPENMP
#pragma omp parallel
    {
      nth = omp_get_num_threads();
    }
#else
    nth = 1;
#endif
    if (verb) sf_warning(">>>> Using %d threads <<<<<", nth);

    nz1 = nz-nbt-nbb;
    nx1 = nx-nbl-nbr;

    nk = fft2_init(cmplx,pad1,nz,nx,&nz2,&nx2);
    nzx = nz*nx;
    nzx2 = nz2*nx2;
    
    dkz = 1./(nz2*dz); kz0 = (cmplx)? -0.5/dz:0.;
    dkx = 1./(nx2*dx); kx0 = -0.5/dx;
    nkz = (cmplx)? nz2:(nz2/2+1);
    if(nk!=nx2*nkz) sf_error("wavenumber dimension mismatch!");
    sf_warning("dkz=%f,dkx=%f,kz0=%f,kx0=%f",dkz,dkx,kz0,kx0);
    sf_warning("nk=%d,nkz=%d,nz2=%d,nx2=%d",nk,nkz,nz2,nx2);

    if(abc)
      abc_init(nz,nx,nz2,nx2,nbt,nbb,nbl,nbr,ct,cb,cl,cr);

    /* allocate and read/initialize arrays */
    vv     = sf_floatalloc(nzx); 
    lapl   = sf_floatalloc(nk);
    wave   = sf_floatalloc(nzx2);
    curr   = sf_floatalloc(nzx2);
    prev   = sf_floatalloc(nzx2);
    cwave  = sf_complexalloc(nk);
    cwavem = sf_complexalloc(nk);
    if (src==0) {
      rick = sf_floatalloc2(nt,n_srcs);
      for (i=0; i<n_srcs; i++) {
	for (it=0; it<nt; it++) {
	  rick[i][it] = 0.f;
	}
	rick[i][(int)(t0[i]/dt)] = A[i]; /*time delay*/
	freq = f0[i]*dt;           /*peak frequency*/
	fft_size = 2*kiss_fft_next_fast_size((nt+1)/2);
	ricker_init(fft_size, freq, 0);
	sf_freqfilt(nt,rick[i]);
	ricker_close();
      }
    } else rick = NULL;

    for (iz=0; iz < nzx; iz++) {
        vv[iz] = vel[iz]*vel[iz]*dt*dt;
    }
    vref *= dt;
    vref2 = vref*vref;
    for (iz=0; iz < nzx2; iz++) {
	curr[iz] = 0.;
	prev[iz] = 0.;
    }

    /* constructing the pseudo-analytical op */
    for (ix=0; ix < nx2; ix++) {
	kx = kx0+ix*dkx;
	for (iz=0; iz < nkz; iz++) {
	    kz = kz0+iz*dkz;
	    k = 2*SF_PI*hypot(kx,kz);
	    if (ps) lapl[iz+ix*nkz] = -k*k;
	    else lapl[iz+ix*nkz] = 2.*(cos(vref*k)-1.)/vref2;
	}
    }

    /* modeling */
    /* step forward in time */
    it1 = 0;
    it2 = nt;
    its = +1;

    /* MAIN LOOP */
    for (it=it1; it!=it2; it+=its) {
      
        if(verb) sf_warning("it=%d/%d;",it,nt);
	
	/* matrix multiplication */
	fft2(curr,cwave);

	for (ik = 0; ik < nk; ik++) {
#ifdef SF_HAS_COMPLEX_H
	  cwavem[ik] = cwave[ik]*lapl[ik];
#else
	  cwavem[ik] = sf_cmul(cwave[ik],lapl[ik]);
#endif
	}
	
	ifft2(wave,cwavem);

#ifdef _OPENMP
#pragma omp parallel for default(shared) private(ix,iz,i,j,old,c)
#endif
	for (ix = 0; ix < nx; ix++) {
	    for (iz=0; iz < nz; iz++) {
		i = iz+ix*nz;  /* original grid */
		j = iz+ix*nz2; /* padded grid */

		old = c = curr[j];
		c += c - prev[j];
		prev[j] = old;
		c += wave[j]*vv[i];
		curr[j] = c;
	    }
	}

        if (NULL!=wvfld0) { /* wavefield injection */
          if (snap > 0 && it%snap==0) {
#ifdef _OPENMP
#pragma omp parallel for default(shared) private(ix,iz,i,j,ik)
#endif
            for (ix=0; ix<nx1; ix++) {
              for (iz=0; iz<nz1; iz++) {
                i = iz + nz1*ix;
                j = iz+nbt + (ix+nbl)*nz2; /* padded grid */
                ik = iz+nbt + (ix+nbl)*nz; /* padded grid */
                curr[j] += vv[ik]*wvfld0[it/snap][i];
              }
            }
          }
        } else { /* source injection */
          t = it*dt;
          for (i=0; i<n_srcs; i++) {
            for(ix=-1;ix<=1;ix++) {
              for(iz=-1;iz<=1;iz++) {
                ik = spz[i]+iz+nz*(spx[i]+ix);
                j = spz[i]+iz+nz2*(spx[i]+ix);
                if (src==0) {
                  curr[j] += vv[ik]*rick[i][it]/(abs(ix)+abs(iz)+1);
                } else {
                  curr[j] += vv[ik]*Ricker(t, f0[i], t0[i], A[i])/(abs(ix)+abs(iz)+1);
                }
              }
            }
          }
        }

	/*apply abc*/
	if (abc) {
	  abc_apply(curr);
	  abc_apply(prev);
	}

        /* record data */
        if (NULL!=dat) {
#ifdef _OPENMP
#pragma omp parallel for default(shared) private(ix)
#endif
            for (ix = 0; ix < gpl; ix++) {
                dat[ix][it] = curr[gpz+(ix+gpx)*nz2];
            }
        }
        if (NULL!=dat_v) {
#ifdef _OPENMP
#pragma omp parallel for default(shared) private(iz)
#endif
            for (iz = 0; iz < gpl_v; iz++) {
                dat_v[iz][it] = curr[gpz_v+iz+(gpx_v)*nz2];
            }
        }

	/* save wavefield */
	if (snap > 0 && it%snap==0) {
#ifdef _OPENMP
#pragma omp parallel for default(shared) private(ix,iz,i,j)
#endif
	  for (ix=0; ix<nx1; ix++) {
	    for (iz=0; iz<nz1; iz++) {
	      i = iz + nz1*ix;
	      j = iz+nbt + (ix+nbl)*nz2; /* padded grid */
	      wvfld[it/snap][i] = curr[j];
	    }
	  }
	}
    }
    if(verb) sf_warning(".");

    /*free up memory*/
    fft2_finalize();
    if (abc) abc_close();
    free(vv);
    free(lapl);   
    free(wave);
    free(curr);
    free(prev);
    free(cwave);
    free(cwavem);
    
    return 0;
}
Beispiel #8
0
int psp3(float **wvfld, float **wvfld1, float **dat, float **dat1, float *img, float *vel, pspar par)
/*< pseudo-spectral back propagation of two receiver wavefields >*/
{
    /*survey parameters*/
    int   nx, nz;
    float dx, dz;
    int   n_srcs;
    int   *spx, *spz;
    int   gpz, gpx, gpl;
    int   gpz_v, gpx_v, gpl_v;
    int   snap;
    /*fft related*/
    bool  cmplx;
    int   pad1;
    /*absorbing boundary*/
    bool abc;
    int nbt, nbb, nbl, nbr;
    float ct,cb,cl,cr;
    /*source parameters*/
    int src; /*source type*/
    int nt;
    float dt,*f0,*t0,*A;
    /*misc*/
    bool verb, ps;
    float vref;
    
    int nx1, nz1; /*domain of interest*/
    int it,iz,ik,ix,i,j;     /* index variables */
    int nk,nzx,nz2,nx2,nzx2,nkz,nth;
    int it1, it2, its;
    float dkx,dkz,kx0,kz0,vref2,kx,kz,k;
    float c, old;

    /*wave prop arrays*/
    float *vv;
    sf_complex *cwave,*cwavem;
    float *wave,*curr,*curr1,*prev,*prev1,*lapl;

    /*passing the parameters*/
    nx    = par->nx;
    nz    = par->nz;
    dx    = par->dx;
    dz    = par->dz;
    n_srcs= par->n_srcs;
    spx   = par->spx;
    spz   = par->spz;
    gpz   = par->gpz;
    gpx   = par->gpx;
    gpl   = par->gpl;
    gpz_v = par->gpz_v;
    gpx_v = par->gpx_v;
    gpl_v = par->gpl_v;
    snap  = par->snap;
    cmplx = par->cmplx;
    pad1  = par->pad1;
    abc   = par->abc;
    nbt   = par->nbt;
    nbb   = par->nbb;
    nbl   = par->nbl;
    nbr   = par->nbr;
    ct    = par->ct;
    cb    = par->cb;
    cl    = par->cl;
    cr    = par->cr;
    src   = par->src;
    nt    = par->nt;
    dt    = par->dt;
    f0    = par->f0;
    t0    = par->t0;
    A     = par->A;
    verb  = par->verb;
    ps    = par->ps;
    vref  = par->vref;
    

#ifdef _OPENMP
#pragma omp parallel
    {
      nth = omp_get_num_threads();
    }
#else
    nth = 1;
#endif
    if (verb) sf_warning(">>>> Using %d threads <<<<<", nth);

    nz1 = nz-nbt-nbb;
    nx1 = nx-nbl-nbr;

    nk = fft2_init(cmplx,pad1,nz,nx,&nz2,&nx2);
    nzx = nz*nx;
    nzx2 = nz2*nx2;
    
    dkz = 1./(nz2*dz); kz0 = (cmplx)? -0.5/dz:0.;
    dkx = 1./(nx2*dx); kx0 = -0.5/dx;
    nkz = (cmplx)? nz2:(nz2/2+1);
    if(nk!=nx2*nkz) sf_error("wavenumber dimension mismatch!");
    sf_warning("dkz=%f,dkx=%f,kz0=%f,kx0=%f",dkz,dkx,kz0,kx0);
    sf_warning("nk=%d,nkz=%d,nz2=%d,nx2=%d",nk,nkz,nz2,nx2);

    if(abc)
      abc_init(nz,nx,nz2,nx2,nbt,nbb,nbl,nbr,ct,cb,cl,cr);

    /* allocate and read/initialize arrays */
    vv     = sf_floatalloc(nzx); 
    lapl   = sf_floatalloc(nk);
    wave   = sf_floatalloc(nzx2);
    curr   = sf_floatalloc(nzx2);
    curr1  = sf_floatalloc(nzx2);
    prev   = sf_floatalloc(nzx2);
    prev1  = sf_floatalloc(nzx2);
    cwave  = sf_complexalloc(nk);
    cwavem = sf_complexalloc(nk);

    for (iz=0; iz < nzx; iz++) {
        vv[iz] = vel[iz]*vel[iz]*dt*dt;
    }
    vref *= dt;
    vref2 = vref*vref;
    for (iz=0; iz < nzx2; iz++) {
	curr[iz] = 0.;
	curr1[iz] = 0.;
	prev[iz] = 0.;
	prev1[iz] = 0.;
    }
    for (iz=0; iz < nz1*nx1; iz++) {
        img[iz] = 0.;
    }

    /* constructing the pseudo-analytical op */
    for (ix=0; ix < nx2; ix++) {
	kx = kx0+ix*dkx;
	for (iz=0; iz < nkz; iz++) {
	    kz = kz0+iz*dkz;
	    k = 2*SF_PI*hypot(kx,kz);
	    if (ps) lapl[iz+ix*nkz] = -k*k;
	    else lapl[iz+ix*nkz] = 2.*(cos(vref*k)-1.)/vref2;
	}
    }

    /* step backward in time */
    it1 = nt-1;
    it2 = -1;
    its = -1;	

    /* MAIN LOOP */
    for (it=it1; it!=it2; it+=its) {
      
        if(verb) sf_warning("it=%d/%d;",it,nt);
	
        /* first receiver wavefield */
	/* matrix multiplication */
	fft2(curr,cwave);

	for (ik = 0; ik < nk; ik++) {
#ifdef SF_HAS_COMPLEX_H
	  cwavem[ik] = cwave[ik]*lapl[ik];
#else
	  cwavem[ik] = sf_cmul(cwave[ik],lapl[ik]);
#endif
	}
	
	ifft2(wave,cwavem);

#ifdef _OPENMP
#pragma omp parallel for default(shared) private(ix,iz,i,j,old,c)
#endif
	for (ix = 0; ix < nx; ix++) {
	    for (iz=0; iz < nz; iz++) {
		i = iz+ix*nz;  /* original grid */
		j = iz+ix*nz2; /* padded grid */

		old = c = curr[j];
		c += c - prev[j];
		prev[j] = old;
		c += wave[j]*vv[i];
		curr[j] = c;
	    }
	}

	/* inject data */
	if (NULL!=dat) {
#ifdef _OPENMP
#pragma omp parallel for default(shared) private(ix)
#endif
	    for (ix = 0; ix < gpl; ix++) {
	        curr[gpz+(ix+gpx)*nz2] += vv[gpz+(ix+gpx)*nz]*dat[ix][it];
	    }
	}

	/*apply abc*/
	if (abc) {
	  abc_apply(curr);
	  abc_apply(prev);
	}
	
	/* second receiver wavefield */
	/* matrix multiplication */
	fft2(curr1,cwave);

	for (ik = 0; ik < nk; ik++) {
#ifdef SF_HAS_COMPLEX_H
	  cwavem[ik] = cwave[ik]*lapl[ik];
#else
	  cwavem[ik] = sf_cmul(cwave[ik],lapl[ik]);
#endif
	}
	
	ifft2(wave,cwavem);

#ifdef _OPENMP
#pragma omp parallel for default(shared) private(ix,iz,i,j,old,c)
#endif
	for (ix = 0; ix < nx; ix++) {
	    for (iz=0; iz < nz; iz++) {
		i = iz+ix*nz;  /* original grid */
		j = iz+ix*nz2; /* padded grid */

		old = c = curr1[j];
		c += c - prev1[j];
		prev1[j] = old;
		c += wave[j]*vv[i];
		curr1[j] = c;
	    }
	}

	/* inject data */
	if (NULL!=dat1) {
#ifdef _OPENMP
#pragma omp parallel for default(shared) private(ix)
#endif
	    for (ix = 0; ix < gpl; ix++) {
	        curr1[gpz+(ix+gpx)*nz2] += vv[gpz+(ix+gpx)*nz]*dat1[ix][it];
	    }
	}

	/*apply abc*/
	if (abc) {
	  abc_apply(curr1);
	  abc_apply(prev1);
	}

	/* cross-correlation imaging condition */
	if (snap > 0 && it%snap==0) {
#ifdef _OPENMP
#pragma omp parallel for default(shared) private(ix,iz,i,j)
#endif
	    for (ix = 0; ix < nx1; ix++) {
	        for (iz = 0; iz < nz1; iz++) {
		    i = iz + nz1*ix;
		    j = iz+nbt + (ix+nbl)*nz2; /* padded grid */
		    img[i] += curr[j]*curr1[j]; //!!!IMPORTANT!!!
		}
	    }
	}
	
	/* save wavefield */
	if (snap > 0 && it%snap==0) {
#ifdef _OPENMP
#pragma omp parallel for default(shared) private(ix,iz,i,j)
#endif
	  for (ix=0; ix<nx1; ix++) {
	    for (iz=0; iz<nz1; iz++) {
	      i = iz + nz1*ix;
	      j = iz+nbt + (ix+nbl)*nz2; /* padded grid */
	      wvfld[it/snap][i] = curr[j];
              wvfld1[it/snap][i] = curr1[j];
	    }
	  }
	}
    }
    if(verb) sf_warning(".");

    /*free up memory*/
    fft2_finalize();
    if (abc) abc_close();
    free(vv);
    free(lapl);   
    free(wave);
    free(curr);
    free(curr1);
    free(prev);
    free(prev1);
    free(cwave);
    free(cwavem);
    
    return 0;
}
Beispiel #9
0
/*---------------------------------------------------------------------------*/
PROCESS_THREAD(output_process, ev, data)
{
  static struct etimer et, et2;
  
  PROCESS_EXITHANDLER(abc_close(&abc);)