コード例 #1
0
ファイル: Mmpilsrtmcg.c プロジェクト: Seislet/src
int psrtm(sf_complex*** record, sf_complex** imgsum, geopar geop)
    /*< low-rank one-step pre-stack RTM linear operator >*/
{
    /*geopar variables*/
    int nx, nz;
    int nxb, nzb;
    float dx, dz, ox, oz;
    int spx, spz, gpz, gpx, gpl; /*source/geophone location*/
    int snpint;
    int top, bot, lft, rht; /*abc boundary*/
    int nt;
    float dt;
    float trunc; 
    bool adj; /* migration(adjoint) flag */
    bool verb; /* verbosity flag */
    bool illum; /* source illumination flag*/
    int m2, m2b, pad1;
    /*pointers*/
    float *rr;
    /*extras*/
    bool roll; /* survey strategy */
    int rectz,rectx,repeat; /*refl smoothing parameters*/
    int sht0,shtbgn,shtend,shtnum,shtnum0,shtint;
    /*mpi*/
    int cpuid, numprocs;

    sf_complex ***wvfld;
    sf_complex **tmprec, **img;
    float **sill;

    /*misc*/
    int ix, iz, is;
    int wfnt;
    float wfdt;

    clock_t tstart,tend;
    double duration;

    int shtcur;

    sf_complex *sendbuf, *recvbuf;

    /* passing variables */
    nx = geop->nx; nz = geop->nz;
    nxb = geop->nxb; nzb = geop->nzb;
    /*spx = geop->spx;*/
    spz = geop->spz;
    gpz = geop->gpz; 
    /*gpx = geop->gpx;*/
    gpl = geop->gpl;
    dx = geop->dx; dz = geop->dz; ox = geop->ox; oz = geop->oz; /*not acutally used*/
    snpint = geop->snpint;
    top = geop->top; bot = geop->bot; lft = geop->lft; rht = geop->rht;
    nt = geop->nt;
    dt = geop->dt;
    trunc = geop->trunc;
    adj = geop->adj; verb = geop->verb; illum = geop->illum;
    m2 = geop->m2; m2b = geop->m2b; pad1 = geop->pad1;
    rr = geop->rr;
    roll = geop->roll;
    rectz=geop->rectz;
    rectx=geop->rectx;
    repeat=geop->repeat;
    sht0=geop->sht0;
    shtbgn=geop->shtbgn;
    shtend=geop->shtend;
    shtnum=geop->shtnum;
    shtnum0=geop->shtnum0;
    shtint=geop->shtint;
    cpuid=geop->cpuid;
    numprocs=geop->numprocs;

    wfnt = (int)(nt-1)/snpint+1;
    wfdt = dt*snpint;

    /*allocate memory*/
    tmprec = sf_complexalloc2(nt, gpl);
    wvfld = sf_complexalloc3(nz, nx, wfnt);
    if (illum) sill = sf_floatalloc2(nz, nx);
    else sill = NULL;
    img = sf_complexalloc2(nz, nx);
    if (adj) { /*migration - initialize image*/
#ifdef _OPENMP
#pragma omp parallel for private(ix,iz)
#endif
        for (ix=0; ix<nx; ix++)
            for (iz=0; iz<nz; iz++)
                imgsum[ix][iz] = sf_cmplx(0.,0.);
    } else { /*modeling - initalize reflectivity*/
#ifdef _OPENMP
#pragma omp parallel for private(ix,iz)
#endif
        for (ix=0; ix<nx; ix++)
            for (iz=0; iz<nz; iz++)
                img[ix][iz] = imgsum[ix][iz];
    }

    /* start the work */
    tstart = clock();

    for (is=0; is*numprocs<shtnum; is++){

        shtcur = is*numprocs+cpuid; // current shot index

        if (shtcur<shtnum0) {
            spx = shtbgn + shtint*(shtcur);
            if (roll)
                gpx = spx - (int)(gpl/2);
            else
                gpx = 0;
            geop->spx = spx;
            geop->gpx = gpx;

            if (verb) {
                sf_warning("============================");
                sf_warning("processing shot #%d", shtcur);
                sf_warning("nx=%d nz=%d nt=%d", geop->nx, geop->nz, geop->nt);
                sf_warning("nxb=%d nzb=%d ", geop->nxb, geop->nzb);
                sf_warning("dx=%f dz=%f dt=%f", geop->dx, geop->dz, geop->dt);
                sf_warning("top=%d bot=%d lft=%d rht=%d", geop->top, geop->bot, geop->lft, geop->rht);
                sf_warning("rectz=%d rectx=%d repeat=%d srctrunc=%f",rectz,rectx,repeat,geop->trunc);
                sf_warning("spz=%d spx=%d gpz=%d gpx=%d gpl=%d", spz, spx, gpz, gpx, gpl);
                sf_warning("snpint=%d wfdt=%f wfnt=%d ", snpint, wfdt, wfnt);
                sf_warning("sht0=%d shtbgn=%d shtend=%d shtnum0=%d shtnum=%d", sht0, shtbgn, shtend, shtnum0, shtnum);
                if (roll) sf_warning("Rolling survey!");
                else sf_warning("Global survey (gpl=nx)!");
                if (illum) sf_warning("Using source illumination!");
                else sf_warning("No source illumination!");
                sf_warning("============================");
            }

            /*generate reflectivity map*/
            reflgen(nzb, nxb, spz+top, spx+lft, rectz, rectx, repeat, rr);

            lrosfor2(wvfld, sill, tmprec, geop);
        }

        if (shtcur<shtnum0) {
            lrosback2(img, wvfld, sill, record[shtcur], geop);
            if (adj) { /*local image reduction*/
#ifdef _OPENMP
#pragma omp parallel for private(ix,iz)
#endif
                for (ix=0; ix<nx; ix++) {
                    for (iz=0; iz<nz; iz++) {
#ifdef SF_HAS_COMPLEX_H
                        imgsum[ix][iz] += img[ix][iz];
#else
                        imgsum[ix][iz] = sf_cadd(imgsum[ix][iz],img[ix][iz]);
#endif
                    }
                }
            }
        }

        if (!adj) {
            recvbuf = record[is*numprocs][0];
            sendbuf = tmprec[0];
            MPI_Allgather(sendbuf, gpl*nt, MPI_COMPLEX, recvbuf, gpl*nt, MPI_COMPLEX, MPI_COMM_WORLD); // record[is][ix][it] = tmprec[ix][it];
            /*Note that redundant shots will be received, but not outputed*/
        }

    } /*shot iteration*/

    MPI_Barrier(MPI_COMM_WORLD);

    /*image reduction*/
    if (adj) {
#if MPI_VERSION >= 2
        sendbuf = (sf_complex *) MPI_IN_PLACE;
#else /* will fail */
        sendbuf = NULL;
#endif 
        recvbuf = imgsum[0];
        MPI_Allreduce(sendbuf, recvbuf, nx*nz, MPI_COMPLEX, MPI_SUM, MPI_COMM_WORLD);
    }

    tend = clock();
    duration=(double)(tend-tstart)/CLOCKS_PER_SEC;
    if (verb)
        sf_warning(">> The CPU time of single shot migration is: %f seconds << ", duration);

    free(**wvfld); free(*wvfld); free(wvfld);
    free(*tmprec); free(tmprec);
    free(*img); free(img);
    if (illum) { free(*sill); free(sill);}

    return 0;
}
コード例 #2
0
ファイル: Mmpilrrtm_ts.c プロジェクト: yunzhishi/src
int main(int argc, char *argv[])
{
	bool wantwf, verb;

	int ix, iz, is, it, wfit, im, ik, i, j, itau;
    int ns, nx, nz, nt, wfnt, rnx, rnz, nzx, rnzx, vnx, ntau, htau, nds;
	int scalet, snap, snapshot, fnx, fnz, fnzx, nk, nb;
	int rectx, rectz, repeat, gpz, n, m, pad1, trunc, spx, spz;

	float dt, t0, z0, dz, x0, dx, s0, ds, wfdt, srctrunc;
    float dtau, tau0, tau;

	int nr, ndr, nr0;

	char *path1, *path2, number[5], *left, *right;

	double tstart, tend;
	struct timeval tim;

	/*wavenumber domain tapering*/
	int taper;
	float *ktp;
	float ktmp,kx_trs,kz_trs,thresh;
	float dkx,dkz,kx0,kz0;
	float kx,kz;
	int nkz;

	sf_complex c, **lt, **rt;
	sf_complex *ww, **dd, ***dd3;
	float ***img1, **img2, ***mig1, **mig2;
    float *rr, **ccr, **sill, ***fwf, ***bwf;
	sf_complex *cwave, *cwavem, **wave, *curr;

	sf_axis at, ax, az, atau;

	sf_file Fdat, Fsrc, Fimg1, Fimg2;
	sf_file Ffwf, Fbwf, Fvel;
	sf_file Fleft, Fright;

	int cpuid, numprocs, nth, nspad, iturn;
    float *sendbuf, *recvbuf;
	sf_complex *sendbufc, *recvbufc;
	MPI_Comm comm=MPI_COMM_WORLD;

	MPI_Init(&argc, &argv);
	MPI_Comm_rank(comm, &cpuid);
	MPI_Comm_size(comm, &numprocs);

	sf_init(argc, argv);

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

	gettimeofday(&tim, NULL);
	tstart=tim.tv_sec+(tim.tv_usec/1000000.0);

	if (!sf_getint("taper",&taper)) taper=0; /* tapering in the frequency domain */
	if (!sf_getfloat("thresh",&thresh)) thresh=0.92; /* tapering threshold */

	if(!sf_getbool("wantwf", &wantwf)) wantwf=false;
    if(!sf_getbool("verb", &verb)) verb=false;
	if(!sf_getint("pad1", &pad1)) pad1=1;
	/* padding factor on the first axis */

	if(!sf_getint("nb", &nb)) sf_error("Need nb= ");
	if(!sf_getfloat("srctrunc", &srctrunc)) srctrunc=0.4;
	if(!sf_getint("rectx", &rectx)) rectx=2;
	if(!sf_getint("rectz", &rectz)) rectz=2;
	if(!sf_getint("repeat", &repeat)) repeat=2;

	if(!sf_getint("scalet", &scalet)) scalet=1;
	if(!sf_getint("snap", &snap)) snap=100;
	/* interval of the output wavefield */
	if(!sf_getint("snapshot", &snapshot)) snapshot=0;
	/* print out the wavefield snapshots of this shot */
    if(!sf_getint("nds", &nds)) sf_error("Need nds=!");
    
    /* source and receiver positions */
	if(!sf_getint("gpz", &gpz)) sf_error("Need gpz=");
	if(!sf_getint("spx", &spx)) sf_error("Need spx=");
	if(!sf_getint("spz", &spz)) sf_error("Need spz=");
    
    /* tau parameters */
    if(!sf_getint("ntau", &ntau)) sf_error("Need ntau=");
    if(!sf_getfloat("dtau", &dtau)) sf_error("Need dtau=");
    if(!sf_getfloat("tau0", &tau0)) sf_error("Need tau0=");

	/* geometry parameters */
	if(!sf_getint("rnx", &rnx)) sf_error("Need rnx=");
	if(!sf_getint("ndr", &ndr)) ndr=1;
	if(!sf_getint("nr0", &nr0)) nr0=0;

	/* input/output files */
	Fdat=sf_input("--input");
	Fimg1=sf_output("--output");
    Fimg2=sf_output("Fimg2");
    Fsrc=sf_input("Fsrc");
    Fvel=sf_input("Fpadvel");

	if(wantwf){
		Ffwf=sf_output("Ffwf");
        Fbwf=sf_output("Fbwf");
	}

	at=sf_iaxa(Fsrc, 1); nt=sf_n(at); dt=sf_d(at); t0=sf_o(at);
    ax=sf_iaxa(Fvel, 2); vnx=sf_n(ax); dx=sf_d(ax); x0=sf_o(ax);
	az=sf_iaxa(Fvel, 1); rnz=sf_n(az); dz=sf_d(az); z0=sf_o(az);
    if(!sf_histint(Fdat, "n2", &nr)) sf_error("Need n2= in input!");
    if(!sf_histint(Fdat, "n3", &ns)) sf_error("Need n3= in input!");
    if(!sf_histfloat(Fdat, "d3", &ds)) sf_error("Need d3= in input!");
    if(!sf_histfloat(Fdat, "o3", &s0)) sf_error("Need o3= in input!");
    
    wfnt=(nt-1)/scalet+1;
    wfdt=dt*scalet;
    
    /* double check the geometry parameters */
    if(nds != (int)(ds/dx)) sf_error("Need ds/dx= %d", nds);
	//sf_warning("s0=%g, x0+(rnx-1)*dx/2=%g", s0, x0+(rnx-1)*dx/2);
    //if(s0 != x0+(rnx-1)*dx/2) sf_error("Wrong origin information!");
    if(vnx != nds*(ns-1)+rnx) sf_error("Wrong dimension in x axis!");

    /* set up the output files */
    atau=sf_iaxa(Fsrc, 1);
    sf_setn(atau, ntau);
    sf_setd(atau, dtau);
    sf_seto(atau, tau0);
    sf_setlabel(atau, "Tau");
    sf_setunit(atau, "s");
    
    sf_oaxa(Fimg1, az, 1);
    sf_oaxa(Fimg1, ax, 2);
    sf_oaxa(Fimg1, atau, 3);
    sf_oaxa(Fimg2, az, 1);
    sf_oaxa(Fimg2, ax, 2);
    sf_putint(Fimg2, "n3", 1);
    sf_settype(Fimg1, SF_FLOAT);
    sf_settype(Fimg2, SF_FLOAT);
    
    if(wantwf){
		sf_setn(ax, rnx);
        sf_seto(ax, -(rnx-1)*dx/2.0);
        sf_oaxa(Ffwf, az, 1);
        sf_oaxa(Ffwf, ax, 2);
        sf_putint(Ffwf, "n3", (wfnt-1)/snap+1);
        sf_putfloat(Ffwf, "d3", snap*wfdt);
        sf_putfloat(Ffwf, "o3", t0);
        sf_putstring(Ffwf, "label3", "Time");
        sf_putstring(Ffwf, "unit3", "s");
        sf_settype(Ffwf, SF_FLOAT);
        
        sf_oaxa(Fbwf, az, 1);
        sf_oaxa(Fbwf, ax, 2);
        sf_putint(Fbwf, "n3", (wfnt-1)/snap+1);
        sf_putfloat(Fbwf, "d3", -snap*wfdt);
        sf_putfloat(Fbwf, "o3", (wfnt-1)*wfdt);
        sf_putstring(Fbwf, "label3", "Time");
        sf_putstring(Fbwf, "unit3", "s");
        sf_settype(Fbwf, SF_FLOAT);
	}
	
    nx=rnx+2*nb; nz=rnz+2*nb;
	nzx=nx*nz; rnzx=rnz*rnx;
    nk=cfft2_init(pad1, nz, nx, &fnz, &fnx);
	fnzx=fnz*fnx;

	if(ns%numprocs==0) nspad=ns;
	else nspad=(ns/numprocs+1)*numprocs;
    
	/* print axies parameters for double check */
    sf_warning("cpuid=%d, numprocs=%d, nspad=%d", cpuid, numprocs, nspad);
	sf_warning("nt=%d, dt=%g, scalet=%d, wfnt=%d, wfdt=%g",nt, dt, scalet, wfnt, wfdt);
	sf_warning("vnx=%d, nx=%d, dx=%g, nb=%d, rnx=%d", vnx, nx, dx, nb, rnx);
	sf_warning("nr=%d, ndr=%d, nr0=%g", nr, ndr, nr0);
	sf_warning("nz=%d, rnz=%d, dz=%g, z0=%g", nz, rnz, dz, z0);
	sf_warning("spx=%d, spz=%d, gpz=%d", spx, spz, gpz);
	sf_warning("ns=%d, ds=%g, s0=%g", ns, ds, s0);
    sf_warning("ntau=%d, dtau=%g, tau0=%g", ntau, dtau, tau0);
    sf_warning("nzx=%d, fnzx=%d, nk=%d", nzx, fnzx, nk);

	/* allocate storage and read data */
	ww=sf_complexalloc(nt);
	sf_complexread(ww, nt, Fsrc);
	sf_fileclose(Fsrc);
	
    gpz=gpz+nb;
    spz=spz+nb;
    spx=spx+nb;
	nr0=nr0+nb;
    trunc=srctrunc/dt+0.5;
    
	dd=sf_complexalloc2(nt, nr);
	if(cpuid==0) dd3=sf_complexalloc3(nt, nr, numprocs);
	rr=sf_floatalloc(nzx);
	reflgen(nz, nx, spz, spx, rectz, rectx, repeat, rr);
    
    fwf=sf_floatalloc3(rnz, rnx, wfnt);
    bwf=sf_floatalloc3(rnz, rnx, wfnt);
    img1=sf_floatalloc3(rnz, vnx, ntau);
    img2=sf_floatalloc2(rnz, vnx);
    mig1=sf_floatalloc3(rnz, rnx, ntau);
    mig2=sf_floatalloc2(rnz, rnx);
    
    ccr=sf_floatalloc2(rnz, rnx);
    sill=sf_floatalloc2(rnz, rnx);
    
    curr=sf_complexalloc(fnzx);
	cwave=sf_complexalloc(nk);
	cwavem=sf_complexalloc(nk);
	icfft2_allocate(cwavem);

	if (taper!=0) {
		dkz = 1./(fnz*dz); kz0 = -0.5/dz;
		dkx = 1./(fnx*dx); kx0 = -0.5/dx;
		nkz = fnz;

		sf_warning("dkz=%f,dkx=%f,kz0=%f,kx0=%f",dkz,dkx,kz0,kx0);
		sf_warning("nk=%d,nkz=%d,nkx=%d",nk,nkz,fnx);

		kx_trs = thresh*fabs(0.5/dx);
		kz_trs = thresh*fabs(0.5/dz);
		sf_warning("Applying kz tapering below %f",kz_trs);
		sf_warning("Applying kx tapering below %f",kx_trs);
		ktp = sf_floatalloc(nk);
		/* constructing the tapering op */
		for (ix=0; ix < fnx; ix++) {
			kx = kx0+ix*dkx;
			for (iz=0; iz < nkz; iz++) {
				kz = kz0+iz*dkz;
				ktmp = 1.;
				if (fabs(kx) > kx_trs)
					ktmp *= powf((2*kx_trs - fabs(kx))/(kx_trs),2);
				if (fabs(kz) > kz_trs)
					ktmp *= powf((2*kz_trs - fabs(kz))/(kz_trs),2);
				ktp[iz+ix*nkz] = ktmp;
			}
		}
	}

	/* initialize image tables that would be used for summing images */
#ifdef _OPENMP
#pragma omp parallel for private(ix, iz, itau)
#endif
    for(ix=0; ix<vnx; ix++){
        for(iz=0; iz<rnz; iz++){
            img2[ix][iz]=0.;
            for(itau=0; itau<ntau; itau++){
                img1[itau][ix][iz]=0.;
            }
        }
    }

	path1=sf_getstring("path1");
	path2=sf_getstring("path2");
	if(path1==NULL) path1="./mat/left";
	if(path2==NULL) path2="./mat/right";

	/* shot loop */
	for (iturn=0; iturn*numprocs<nspad; iturn++){
		is=iturn*numprocs+cpuid;
        
        /* read data */
		if(cpuid==0){
			sf_seek(Fdat, ((off_t) is)*((off_t) nr)*((off_t) nt)*sizeof(float complex), SEEK_SET);

			if((iturn+1)*numprocs<=ns){
				sf_complexread(dd3[0][0], nr*nt*numprocs, Fdat);
			}else{
				sf_complexread(dd3[0][0], nr*nt*(ns-iturn*numprocs), Fdat);
				for(is=ns; is<nspad; is++)
					for(ix=0; ix<nr; ix++)
						for(it=0; it<nt; it++)
							dd3[is-iturn*numprocs][ix][it]=sf_cmplx(0.,0.);
				is=iturn*numprocs;
			}

			sendbufc=dd3[0][0];
			recvbufc=dd[0];
		}else{
			sendbufc=NULL;
			recvbufc=dd[0];
		}
		MPI_Scatter(sendbufc, nt*nr, MPI_COMPLEX, recvbufc, nt*nr, MPI_COMPLEX, 0, comm);

		if(is<ns){ /* effective shot loop */

			/* construct the names of left and right matrices */
			left=sf_charalloc(strlen(path1));
			right=sf_charalloc(strlen(path2));
			strcpy(left, path1);
			strcpy(right, path2);
			sprintf(number, "%d", is+1);
			strcat(left, number);
			strcat(right, number);

			Fleft=sf_input(left);
			Fright=sf_input(right);

			if(!sf_histint(Fleft, "n1", &n) || n != nzx) sf_error("Need n1=%d in Fleft", nzx);
			if(!sf_histint(Fleft, "n2", &m)) sf_error("No n2 in Fleft");
			if(!sf_histint(Fright, "n1", &n) || n != m) sf_error("Need n1=%d in Fright", m);
			if(!sf_histint(Fright, "n2", &n) || n != nk) sf_error("Need n2=%d in Fright", nk);

			/* allocate storage for each shot migration */
			lt=sf_complexalloc2(nzx, m);
			rt=sf_complexalloc2(m, nk);
			sf_complexread(lt[0], nzx*m, Fleft);
			sf_complexread(rt[0], m*nk, Fright);
			sf_fileclose(Fleft);
			sf_fileclose(Fright);

			/* initialize curr and imaging variables */
#ifdef _OPENMP
#pragma omp parallel for private(iz)
#endif
			for(iz=0; iz<fnzx; iz++){
				curr[iz]=sf_cmplx(0.,0.);
			}
#ifdef _OPENMP
#pragma omp parallel for private(ix, iz, itau)
#endif
			for(ix=0; ix<rnx; ix++){
				for(iz=0; iz<rnz; iz++){
					mig2[ix][iz]=0.;
					ccr[ix][iz]=0.;
					sill[ix][iz]=0.;
					for(itau=0; itau<ntau; itau++){
						mig1[itau][ix][iz]=0.;
					}
				}
			}

			/* wave */
			wave=sf_complexalloc2(fnzx, m);

			/* snapshot */
			if(wantwf && is==snapshot) wantwf=true;
			else wantwf=false;

			/* forward propagation */
			wfit=0;
			for(it=0; it<nt; it++){
				if(verb) sf_warning("Forward propagation it=%d/%d",it+1, nt);

				cfft2(curr, cwave);
				for(im=0; im<m; im++){
#ifdef _OPENMP
#pragma omp parallel for private(ik)
#endif
					for(ik=0; ik<nk; ik++){
#ifdef SF_HAS_COMPLEX_H
						cwavem[ik]=cwave[ik]*rt[ik][im];
#else
						cwavem[ik]=sf_cmul(cwave[ik],rt[ik][im]);
#endif
					}
					icfft2(wave[im],cwavem);
				}

#ifdef _OPENMP
#pragma omp parallel for private(ix, iz, i, j, im, c) shared(curr, it)
#endif
				for(ix=0; ix<nx; ix++){
					for(iz=0; iz<nz; iz++){
						i=iz+ix*nz;
						j=iz+ix*fnz;

						if(it<trunc){
#ifdef SF_HAS_COMPLEX_H
							c=ww[it]*rr[i];
#else
							c=sf_crmul(ww[it],rr[i]);
#endif
						}else{
							c=sf_cmplx(0.,0.);
						}

						//                    c += curr[j];

						for(im=0; im<m; im++){
#ifdef SF_HAS_COMPLEX_H
							c += lt[im][i]*wave[im][j];
#else
							c += sf_cmul(lt[im][i], wave[im][j]);
#endif
						}
						curr[j]=c;
					}
				}

				if (taper!=0) {
					if (it%taper == 0) {
						cfft2(curr,cwave);
						for (ik = 0; ik < nk; ik++) {
#ifdef SF_HAS_COMPLEX_H
							cwavem[ik] = cwave[ik]*ktp[ik];
#else
							cwavem[ik] = sf_crmul(cwave[ik],ktp[ik]);
#endif
						}
						icfft2(curr,cwavem);
					}
				}

				if(it%scalet==0){
#ifdef _OPENMP
#pragma omp parallel for private(ix, iz)
#endif
					for(ix=0; ix<rnx; ix++){
						for(iz=0; iz<rnz; iz++){
							fwf[wfit][ix][iz]=crealf(curr[(ix+nb)*fnz+(iz+nb)]);
						}
					}
					wfit++;
				}
			} //end of it

			/* check wfnt */
			if(wfit != wfnt) sf_error("At this point, wfit should be equal to wfnt");

			/* backward propagation starts from here... */
#ifdef _OPENMP
#pragma omp parallel for private(iz)
#endif
			for(iz=0; iz<fnzx; iz++){
				curr[iz]=sf_cmplx(0.,0.);
			}

			wfit=wfnt-1;
			for(it=nt-1; it>=0; it--){
				if(verb) sf_warning("Backward propagation it=%d/%d",it+1, nt);
#ifdef _OPENMP
#pragma omp parallel for private(ix)
#endif
				for(ix=0; ix<nr; ix++){
					curr[(nr0+ix*ndr)*fnz+gpz]+=dd[ix][it];
				}

				cfft2(curr, cwave);

				for(im=0; im<m; im++){
#ifdef _OPENMP
#pragma omp parallel for private(ik)
#endif
					for(ik=0; ik<nk; ik++){
#ifdef SF_HAS_COMPLEX_H
						cwavem[ik]=cwave[ik]*conjf(rt[ik][im]);
#else
						cwavem[ik]=sf_cmul(cwave[ik],conjf(rt[ik][im]));
#endif
					}
					icfft2(wave[im],cwavem);
				}

#ifdef _OPENMP
#pragma omp parallel for private(ix, iz, i, j, im, c) shared(curr, it)
#endif
				for(ix=0; ix<nx; ix++){
					for(iz=0; iz<nz; iz++){
						i=iz+ix*nz;
						j=iz+ix*fnz;

						//                    c=curr[j];
						c=sf_cmplx(0.,0.);

						for(im=0; im<m; im++){
#ifdef SF_HAS_COMPLEX_H
							c += conjf(lt[im][i])*wave[im][j];
#else
							c += sf_cmul(conjf(lt[im][i]), wave[im][j]);
#endif
						}
						curr[j]=c;
					}
				}

				if (taper!=0) {
					if (it%taper == 0) {
						cfft2(curr,cwave);
						for (ik = 0; ik < nk; ik++) {
#ifdef SF_HAS_COMPLEX_H
							cwavem[ik] = cwave[ik]*ktp[ik];
#else
							cwavem[ik] = sf_crmul(cwave[ik],ktp[ik]);
#endif
						}
						icfft2(curr,cwavem);
					}
				}

				if(it%scalet==0){
#ifdef _OPENMP
#pragma omp parallel for private(ix, iz)
#endif
					for(ix=0; ix<rnx; ix++){
						for(iz=0; iz<rnz; iz++){
							bwf[wfit][ix][iz]=crealf(curr[(ix+nb)*fnz+(iz+nb)]);
							ccr[ix][iz] += fwf[wfit][ix][iz]*bwf[wfit][ix][iz];
							sill[ix][iz] += fwf[wfit][ix][iz]*fwf[wfit][ix][iz];
						}
					}
					wfit--;
				}
			} //end of it
			if(wfit != -1) sf_error("Check program! The final wfit should be -1!");

			/* free storage */
			free(*rt); free(rt);
			free(*lt); free(lt);
			free(*wave); free(wave);
			free(left); free(right);

			/* normalized image */
#ifdef _OPENMP
#pragma omp parallel for private(ix, iz)
#endif
			for (ix=0; ix<rnx; ix++){
				for(iz=0; iz<rnz; iz++){
					mig2[ix][iz]=ccr[ix][iz]/(sill[ix][iz]+SF_EPS);
					//		sill[ix][iz]=0.;
				}
			}

			/* time-shift imaging condition */
			for(itau=0; itau<ntau; itau++){
				//sf_warning("itau/ntau=%d/%d", itau+1, ntau);
				tau=itau*dtau+tau0;
				htau=tau/wfdt;

				for(it=abs(htau); it<wfnt-abs(htau); it++){
#ifdef _OPENMP
#pragma omp parallel for private(ix, iz)
#endif
					for(ix=0; ix<rnx; ix++){
						for(iz=0; iz<rnz; iz++){
							mig1[itau][ix][iz]+=fwf[it+htau][ix][iz]*bwf[it-htau][ix][iz];
							//	sill[ix][iz]+=fwf[it+htau][ix][iz]*fwf[it+htau][ix][iz];
						} // end of iz
					} // end of ix
				} // end of it


				//#ifdef _OPENMP
				//#pragma omp parallel for private(ix, iz)
				//#endif 
				/* source illumination */
				//	for(ix=0; ix<rnx; ix++){
				//		for(iz=0; iz<rnz; iz++){
				//			mig1[itau][ix][iz] = mig1[itau][ix][iz]/(sill[ix][iz]+SF_EPS);
				//		}
				//	} 
			} //end of itau

			/* output wavefield snapshot */
			if(wantwf){
				for(it=0; it<wfnt; it++){
					if(it%snap==0){
						sf_floatwrite(fwf[it][0], rnzx, Ffwf);
						sf_floatwrite(bwf[wfnt-1-it][0], rnzx, Fbwf);
					}
				}
				sf_fileclose(Ffwf);
				sf_fileclose(Fbwf);
			}

			/* add all the shot images that are on the same node */
#ifdef _OPENMP
#pragma omp parallel for private(itau, ix, iz)
#endif
			for(itau=0; itau<ntau; itau++){
				for(ix=0; ix<rnx; ix++){
					for(iz=0; iz<rnz; iz++){
						img1[itau][ix+is*nds][iz] += mig1[itau][ix][iz];
					}
				}
			}

#ifdef _OPENMP
#pragma omp parallel for private(ix, iz)
#endif
			for(ix=0; ix<rnx; ix++){
				for(iz=0; iz<rnz; iz++){
					img2[ix+is*nds][iz] += mig2[ix][iz];
				}
			}
		} // end of is<ns
	} // end of iturn
	////////////////end of ishot
	MPI_Barrier(comm);

	cfft2_finalize();
    sf_fileclose(Fdat);
    
    free(ww); free(rr);
	free(*dd); free(dd);
	if(cpuid==0) {free(**dd3); free(*dd3); free(dd3);}
	free(cwave); free(cwavem); free(curr);
    free(*ccr); free(ccr);
    free(*sill); free(sill);
    free(**fwf); free(*fwf); free(fwf);
    free(**bwf); free(*bwf); free(bwf);
    free(**mig1); free(*mig1); free(mig1);
    free(*mig2); free(mig2);
    
    /* sum image */
    if(cpuid==0){
        sendbuf=(float *)MPI_IN_PLACE;
        recvbuf=img1[0][0];
    }else{
        sendbuf=img1[0][0];
        recvbuf=NULL;
    }
    MPI_Reduce(sendbuf, recvbuf, ntau*vnx*rnz, MPI_FLOAT, MPI_SUM, 0, comm);
    
    if(cpuid==0){
        sendbuf=MPI_IN_PLACE;
        recvbuf=img2[0];
    }else{
        sendbuf=img2[0];
        recvbuf=NULL;
    }
    MPI_Reduce(sendbuf, recvbuf, vnx*rnz, MPI_FLOAT, MPI_SUM, 0, comm);
    
    /* output image */
    if(cpuid==0){
        sf_floatwrite(img1[0][0], ntau*vnx*rnz, Fimg1);
        sf_floatwrite(img2[0], vnx*rnz, Fimg2);
    }
	MPI_Barrier(comm);

	sf_fileclose(Fimg1);
    sf_fileclose(Fimg2);
    free(**img1); free(*img1); free(img1);
    free(*img2); free(img2);
    
	gettimeofday(&tim, NULL);
	tend=tim.tv_sec+(tim.tv_usec/1000000.0);
	sf_warning(">> The computing time is %.3lf minutes <<", (tend-tstart)/60.);

	MPI_Finalize();
	exit(0);
}
コード例 #3
0
ファイル: Mlroslsrtm2.c プロジェクト: 1014511134/src
int main(int argc, char* argv[]) 
{
    clock_t tstart,tend;
    double duration;

    /*flag*/
    bool verb, adj; /* migration(adjoint) flag */
    bool wantwf;
    bool wantrecord; /* actually means "need record" */
    
    /*I/O*/
    sf_file Fvel;
    sf_file left, right, leftb, rightb;
    sf_file Fsrc, Frcd/*source and record*/;
    sf_file Ftmpwf, Ftmpbwf;
    sf_file Fimg;

    sf_axis at, ax, az;

    /*grid index variables*/
    int nx, nz, nt, wfnt;
    int nzx, nx2, nz2, n2, m2, pad1, nk;
    int ix, it;
    int nxb, nzb;
    float dt, dx, dz, wfdt;
    float ox, oz;

    /*source/geophone location*/
    float slx, slz;
    int   spx, spz;
    float gdep;
    int   gpz,gpx,gpl; /*geophone depth/x-crd/length*/

    /*Model*/
    sf_complex **lt, **rt;
    sf_complex **ltb, **rtb;

    /*Data*/
    sf_complex ***wavefld, ***wavefld2;
    sf_complex **record, **img;
    float **sill;
    int snpint;

    /*source*/
    sf_complex *ww;
    float *rr;
    int rectz,rectx,repeat; /*smoothing parameters*/
    float trunc;

    /*abc boundary*/
    int top,bot,lft,rht;

    /*memoray*/
    int tmpint;

    tstart = clock();
    sf_init(argc, argv);
    if (!sf_getbool("verb", &verb)) verb=false; /*verbosity*/
    if (!sf_getbool("adj", &adj)) adj=true; /*migration*/
    if (!sf_getbool("wantwf", &wantwf)) wantwf=false; /*output forward and backward wavefield*/
    if (!sf_getbool("wantrecord", &wantrecord)) wantrecord=true; /*if n, using record data generated by this program */

    /*Set I/O file*/

    if (adj) { /* migration */
      if (wantrecord) {
	Frcd = sf_input("in"); /*record from elsewhere*/
	Fsrc  = sf_input("src");   /*source wavelet*/      
      } else {
	Frcd = sf_output("rec"); /*record produced by forward modeling*/
	Fsrc = sf_input("in");   /*source wavelet*/
      }
      Fimg  = sf_output("out");
    } else { /* modeling */
      Fimg = sf_input("in");
      Frcd = sf_output("out");
      Fsrc  = sf_input("src");   /*source wavelet*/      
    }

    Fvel  = sf_input("vel");  /*velocity - just for model dimension*/
    if (wantwf) {
	Ftmpwf  = sf_output("tmpwf");/*wavefield snap*/
	Ftmpbwf = sf_output("tmpbwf");
    }

    /*--- Axes parameters ---*/
    at = sf_iaxa(Fsrc, 1); nt = sf_n(at);  dt = sf_d(at);      
    az = sf_iaxa(Fvel, 1); nzb = sf_n(az); dz = sf_d(az); oz = sf_o(az);
    ax = sf_iaxa(Fvel, 2); nxb = sf_n(ax); dx = sf_d(ax); ox = sf_o(ax);
    nzx = nzb*nxb;

    /*--- parameters of source ---*/
    if (!sf_getfloat("srctrunc", &trunc)) trunc=0.4;
    if (!sf_getint("rectz", &rectz)) rectz=1;
    if (!sf_getint("rectx", &rectx)) rectx=1;
    if (!sf_getint("repeat", &repeat)) repeat=0;
    ww=sf_complexalloc(nt);
    rr=sf_floatalloc(nzx);

    /* propagator matrices */
    left  = sf_input("left");
    right = sf_input("right");
    leftb  = sf_input("leftb");
    rightb = sf_input("rightb");

    if (!sf_getint("pad1",&pad1)) pad1=1; /* padding factor on the first axis */
    nz2 = kiss_fft_next_fast_size(nzb*pad1);
    nx2 = kiss_fft_next_fast_size(nxb);
    nk = nz2*nx2; /*wavenumber*/

    if (!sf_histint(left,"n1",&n2) || n2 != nzx) sf_error("Need n1=%d in left",nzx);
    if (!sf_histint(left,"n2",&m2))  sf_error("Need n2= in left");
    
    if (!sf_histint(right,"n1",&n2) || n2 != m2) sf_error("Need n1=%d in right",m2);
    if (!sf_histint(right,"n2",&n2) || n2 != nk) sf_error("Need n2=%d in right",nk);
  
    lt = sf_complexalloc2(nzx,m2);
    rt = sf_complexalloc2(m2,nk);
    sf_complexread(lt[0],nzx*m2,left);
    sf_complexread(rt[0],m2*nk,right);

    ltb = sf_complexalloc2(nzx,m2);
    rtb = sf_complexalloc2(m2,nk);
    sf_complexread(ltb[0],nzx*m2,leftb);
    sf_complexread(rtb[0],m2*nk,rightb);

    sf_fileclose(left);
    sf_fileclose(right);
    sf_fileclose(leftb);
    sf_fileclose(rightb);

    /* abc parameters */
    if (!sf_getint("top", &top)) top=40;
    if (!sf_getint("bot", &bot)) bot=40;
    if (!sf_getint("lft", &lft)) lft=40;
    if (!sf_getint("rht", &rht)) rht=40;
    /* Width of abc layer */

    nz = nzb - top - bot;
    nx = nxb - lft - rht;

    /*Geometry parameters*/
    geopar geop;
    geop = creategeo();
 
    /*source loaction parameters*/

    if (!sf_getfloat("slx", &slx)) slx=-1.0; 
    /*source location x */
    if (!sf_getint("spx", &spx)) spx=-1;
    /*source location x (index)*/
    if((slx<0 && spx <0) || (slx>=0 && spx >=0 ))  sf_error("Need src location");
    if (slx >= 0 )    spx = (int)((slx-ox)/dx+0.5);
    
    if (!sf_getfloat("slz", &slz)) slz=-1.0;
    /* source location z */
    if (!sf_getint("spz", &spz)) spz=-1;
    /*source location z (index)*/
    if((slz<0 && spz <0) || (slz>=0 && spz >=0 ))  sf_error("Need src location");
    if (slz >= 0 )    spz = (int)((slz-ox)/dz+0.5);
    
    if (!sf_getfloat("gdep", &gdep)) gdep=-1.0;
    /* recorder depth on grid*/
    if (!sf_getint("gpz", &gpz)) gpz=0;
    /* recorder depth on index*/
    if (!sf_getint("gpx", &gpx)) sf_error("Need receiver starting location");
    /* recorder starting location on index*/   
    if (!sf_getint("gpl", &gpl)) sf_error("Need receiver length");
    /* recorder length on index*/
    if ( gdep>=oz) { gpz = (int)((gdep-oz)/dz+0.5);}
    if (gpz < 0.0) sf_error("gdep need to be >=oz");
    /*source and receiver location*/

    if (!sf_getint("snapinter", &snpint)) snpint=10;
    /* snap interval */

    /*load source wavelet and reflectivity map*/
    ww=sf_complexalloc(nt);  
    sf_complexread(ww,nt,Fsrc);
    sf_fileclose(Fsrc);
    reflgen(nzb, nxb, spz+top, spx+lft, rectz, rectx, repeat, rr);
    /*check record data*/
    if (adj && wantrecord){
	sf_histint(Frcd,"n1", &tmpint);
	if (tmpint != nt ) sf_error("Error parameter n1 in record!");
	sf_histint(Frcd,"n2", &tmpint);
	if (tmpint != gpl ) sf_error("Error parameter n2 in record!");
    }
    
    geop->nx  = nx;
    geop->nz  = nz;
    geop->nxb = nxb;
    geop->nzb = nzb;
    geop->dx  = dx;
    geop->dz  = dz;
    geop->ox  = ox;
    geop->oz  = oz;
    geop->snpint = snpint;
    geop->spx = spx;
    geop->spz = spz;
    geop->gpz = gpz;
    geop->gpx = gpx;
    geop->gpl = gpl;
    geop->top = top;
    geop->bot = bot;
    geop->lft = lft;
    geop->rht = rht;
    geop->nt = nt;
    geop->dt = dt;
    geop->trunc = trunc;

    /* wavefield and record  */
    wfnt = (int)(nt-1)/snpint+1;
    wfdt = dt*snpint;
    record = sf_complexalloc2(nt, gpl);
    wavefld = sf_complexalloc3(nz, nx, wfnt);
    sill = sf_floatalloc2(nz, nx);
    if (wantwf)
	wavefld2= sf_complexalloc3(nz, nx, wfnt);
    else
	wavefld2=NULL;

    /*image*/
    img = sf_complexalloc2(nz, nx);

    if (verb) {
	sf_warning("============================");
	sf_warning("nx=%d nz=%d nt=%d", geop->nx, geop->nz, geop->nt);
	sf_warning("nxb=%d nzb=%d ", geop->nxb, geop->nzb);
	sf_warning("dx=%f dz=%f dt=%f", geop->dx, geop->dz, geop->dt);
	sf_warning("top=%d bot=%d lft=%d rht=%d", geop->top, geop->bot, geop->lft, geop->rht);
	sf_warning("rectz=%d rectx=%d repeat=%d srctrunc=%f",rectz,rectx,repeat,geop->trunc);
	sf_warning("spx=%d spz=%d gpz=%d gpx=%d gpl=%d snpint=%d", spx, spz, gpz, gpx, gpl, snpint);
	sf_warning("wfdt=%f wfnt=%d ", wfdt, wfnt);
	sf_warning("============================");
    }

    /* write record */
    sf_setn(ax, gpl);
    sf_setn(az, nz);

    if (adj) { /* migration */
      if(!wantrecord) {
	sf_oaxa(Frcd, at, 1);
	sf_oaxa(Frcd, ax, 2);
	sf_settype(Frcd,SF_COMPLEX);	
      }
      sf_setn(ax, nx);
      /*write image*/
      sf_oaxa(Fimg, az, 1);
      sf_oaxa(Fimg, ax, 2);
      sf_settype(Fimg,SF_COMPLEX);
    } else { /* modeling */
      sf_oaxa(Frcd, at, 1);
      sf_oaxa(Frcd, ax, 2);
      sf_settype(Frcd,SF_COMPLEX);
    }

    if (wantwf) {
      sf_setn(ax, nx);
      /*write temp wavefield */
      sf_setn(at, wfnt);
      sf_setd(at, wfdt);
      
      sf_oaxa(Ftmpwf, az, 1);
      sf_oaxa(Ftmpwf, ax, 2);
      sf_oaxa(Ftmpwf, at, 3);
      sf_settype(Ftmpwf,SF_COMPLEX);
      
      /*write temp wavefield */
      sf_oaxa(Ftmpbwf, az, 1);
      sf_oaxa(Ftmpbwf, ax, 2);
      sf_oaxa(Ftmpbwf, at, 3);
      sf_settype(Ftmpbwf,SF_COMPLEX);
    }
    
    if (!adj) sf_complexread(img[0],nx*nz,Fimg);

    lrosfor2(wavefld, sill, record, verb, lt, rt, m2, geop, ww, rr, pad1);

    if(adj && wantrecord) sf_complexread(record[0], gpl*nt, Frcd);

    lrosback2(img, wavefld, sill, record, adj, verb, wantwf, ltb, rtb, m2, geop, pad1, wavefld2);

    if (!wantrecord || !adj) {
      for (ix=0; ix<gpl; ix++) {
	sf_complexwrite(record[ix], nt, Frcd);
      }
    }
    if (adj) {
      for (ix=0; ix<nx; ix++) 
	sf_complexwrite(img[ix], nz, Fimg);
    }

    if (wantwf) {
	for (it=0; it<wfnt; it++)
	    for ( ix=0; ix<nx; ix++) {
		sf_complexwrite(wavefld[it][ix], nz, Ftmpwf);
		sf_complexwrite(wavefld2[it][ix],nz, Ftmpbwf);
	    }
    }

    tend = clock();
    duration=(double)(tend-tstart)/CLOCKS_PER_SEC;
    sf_warning(">> The CPU time of single shot migration is: %f seconds << ", duration);
    exit(0);
}
コード例 #4
0
ファイル: Mmpilrrtm.c プロジェクト: marscfeng/src
/* main function */
int main(int argc, char* argv[])
{
    clock_t tstart,tend;
    double duration;

    /*flags*/
    bool verb, adj; /* migration(adjoint) flag */
    bool wantwf; /* outputs wavefield snapshots */
    bool wantrecord; /* actually means "need record" */
    bool illum; /* source illumination flag */
    bool roll; /* survey strategy */
    bool fm; /* forward modeling */

    /*I/O*/
    sf_file Fvel;
    sf_file left, right, leftb, rightb;
    sf_file Fsrc, Frcd/*source and record*/;
    sf_file Ftmpwf;
    sf_file Fimg;
    sf_file mask;

    /*axis*/
    sf_axis at, ax, az, as;

    /*grid index variables*/
    int nx, nz, nt, wfnt;
    int nzx, nx2, nz2, n2, m2, pad1, nk;
    int ix, iz, it, is;
    int nxb, nzb;
    int snpint, wfint;
    float dt, dx, dz, wfdt;
    float ox, oz;

    /*source/geophone location*/
    int   spx, spz;
    int   gpz,gpx,gpl; /*geophone depth/x-crd/length*/

    /*Model*/
    sf_complex **lt, **rt;
    sf_complex **ltb, **rtb;

    /*Data*/
    sf_complex ***wavefld;
    sf_complex ***record, **tmprec, **img, **imgsum;
    float **sill;

    /*source*/
    sf_complex *ww;
    float **rr;
    int **kill=NULL;
    int rectz,rectx,repeat; /*smoothing parameters*/
    float trunc;
    int sht0,shtbgn,shtend,shtnum,shtint;

    /*abc boundary*/
    int top,bot,lft,rht;

    /*tmp*/
    int tmpint;

    /*parameter structs*/
    geopar geop;
    mpipar mpip;

    /*MPI*/
    int rank, nodes;
    sf_complex *sendbuf, *recvbuf;

    MPI_Init(&argc, &argv);
    MPI_Comm_rank(MPI_COMM_WORLD, &rank);
    MPI_Comm_size(MPI_COMM_WORLD, &nodes);

    sf_init(argc, argv);

    if(rank==0) sf_warning("nodes=%d",nodes);

    if (!sf_getbool("verb", &verb)) verb=false; /*verbosity*/
    if (!sf_getbool("adj", &adj)) adj=true; /*migration*/
    if (!sf_getbool("wantwf", &wantwf)) wantwf=false; /*output forward and backward wavefield*/
    if (!sf_getbool("wantrecord", &wantrecord)) wantrecord=true; /*if n, using record data generated by this program */
    if (!sf_getbool("illum", &illum)) illum=false; /*if n, no source illumination applied */
    if (!sf_getbool("roll", &roll)) roll=true; /*if n, receiver is independent of source location and gpl=nx*/
    if (!sf_getbool("fm", &fm)) fm=false; /* if n, Born modelling  */
    if (!sf_getbool("incom", &incom)) incom=false; /* if n, use complete data */
    /* source/receiver info */
    if (!sf_getint("shtbgn", &shtbgn)) sf_error("Need shot starting location on grid!");
    if (!sf_getint("sht0", &sht0)) sht0=shtbgn; /*actual shot origin on grid*/
    if (!sf_getint("shtend", &shtend)) sf_error("Need shot ending location on grid!");
    if (!sf_getint("shtint", &shtint)) sf_error("Need shot interval on grid!");
    shtnum = (int)((shtend-shtbgn)/shtint) + 1;
    if (!sf_getint("spz", &spz)) sf_error("Need source depth!");
    if (!sf_getint("gpz", &gpz)) sf_error("Need receiver depth!");
    if (roll) if (!sf_getint("gpl", &gpl)) sf_error("Need receiver length");
    if (!sf_getint("snapinter", &snpint)) snpint=1;     /* snap interval */
    if (!sf_getint("wfint", &wfint)) wfint=50;     /* snap interval */
    /*--- parameters of source ---*/
    if (!sf_getfloat("srctrunc", &trunc)) trunc=0.4;
    if (!sf_getint("rectz", &rectz)) rectz=2;
    if (!sf_getint("rectx", &rectx)) rectx=2;
    if (!sf_getint("repeat", &repeat)) repeat=2;
    /* abc parameters */
    if (!sf_getint("top", &top)) top=40;
    if (!sf_getint("bot", &bot)) bot=40;
    if (!sf_getint("lft", &lft)) lft=40;
    if (!sf_getint("rht", &rht)) rht=40;
    /* simultaneous sources parameter */
    if (!sf_getint("nsource", &nsource)) nsource=1;
    if (!sf_getint("dsource", &dsource)) dsource=0;
    if (!sf_getfloat("tdelay", &tdelay)) tdelay=0;
    if (!sf_getint("choose", &choose)) choose=nsource;

    /*Set I/O file*/
    if (adj) { /* migration */
        if (wantrecord) {
            Frcd = sf_input("input"); /*record from elsewhere*/
            Fsrc  = sf_input("src");   /*source wavelet*/
        } else {
            Frcd = sf_output("rec"); /*record produced by forward modeling*/
            Fsrc = sf_input("input");   /*source wavelet*/
        }

        Fimg  = sf_output("output");
    } else { /* modeling */
        Fimg = sf_input("input");
        Frcd = sf_output("output");
        Fsrc  = sf_input("src");   /*source wavelet*/
    }

    left  = sf_input("left");
    right = sf_input("right");
    leftb  = sf_input("leftb");
    rightb = sf_input("rightb");
    Fvel  = sf_input("vel");  /*velocity - just for model dimension*/
    if (wantwf) {
        Ftmpwf  = sf_output("tmpwf");/*wavefield snap*/
    }
    if (incom) {
        mask=sf_input("mask"); /*mask operator*/
    }

    /*--- Axes parameters ---*/
    at = sf_iaxa(Fsrc, 1);
    nt = sf_n(at);
    dt = sf_d(at);
    az = sf_iaxa(Fvel, 1);
    nzb = sf_n(az);
    dz = sf_d(az);
    oz = sf_o(az);
    ax = sf_iaxa(Fvel, 2);
    nxb = sf_n(ax);
    dx = sf_d(ax);
    ox = sf_o(ax);
    nzx = nzb*nxb;
    nz = nzb - top - bot;
    nx = nxb - lft - rht;
    if (!roll) gpl = nx; /* global survey setting */
    /* wavefield axis */
    wfnt = (int)(nt-1)/snpint+1;
    wfdt = dt*snpint;
    ndelay=tdelay/dt;

    /* propagator matrices */
    if (!sf_getint("pad1",&pad1)) pad1=1; /* padding factor on the first axis */
    nz2 = kiss_fft_next_fast_size(nzb*pad1);
    nx2 = kiss_fft_next_fast_size(nxb);
    nk = nz2*nx2; /*wavenumber*/
    if (!sf_histint(left,"n1",&n2) || n2 != nzx) sf_error("Need n1=%d in left",nzx);
    if (!sf_histint(left,"n2",&m2))  sf_error("Need n2= in left");
    if (!sf_histint(right,"n1",&n2) || n2 != m2) sf_error("Need n1=%d in right",m2);
    if (!sf_histint(right,"n2",&n2) || n2 != nk) sf_error("Need n2=%d in right",nk);

    /*check record data*/
    if (adj && wantrecord) {
        sf_histint(Frcd,"n1", &tmpint);
        if (tmpint != nt ) sf_error("Error parameter n1 in record!");
        sf_histint(Frcd,"n2", &tmpint);
        if (tmpint != gpl ) sf_error("Error parameter n2 in record!");
        sf_histint(Frcd,"n3", &tmpint);
        if (tmpint != shtnum ) sf_error("Error parameter n3 in record!");
    }

    /*allocate memory*/
    ww=sf_complexalloc(nt);
    rr=sf_floatalloc2(nzx,nsource);
    lt = sf_complexalloc2(nzx,m2);
    rt = sf_complexalloc2(m2,nk);
    ltb = sf_complexalloc2(nzx,m2);
    rtb = sf_complexalloc2(m2,nk);
    geop = (geopar) sf_alloc(1, sizeof(*geop));
    mpip = (mpipar) sf_alloc(1, sizeof(*mpip));
    tmprec = sf_complexalloc2(nt, gpl);
    record = sf_complexalloc3(nt, gpl, shtnum);
    if (incom) {
        kill = sf_intalloc2(gpl, shtnum);
        sf_intread(kill[0],gpl*shtnum,mask);
    }
    wavefld = sf_complexalloc3(nz, nx, wfnt);
    if (illum ) sill = sf_floatalloc2(nz, nx);
    else sill = NULL;
    img = sf_complexalloc2(nz, nx);

    if (adj) {
        imgsum = sf_complexalloc2(nz, nx);
#ifdef _OPENMP
        #pragma omp parallel for private(ix,iz)
#endif
        for (ix=0; ix<nx; ix++)
            for (iz=0; iz<nz; iz++) {
                imgsum[ix][iz] = sf_cmplx(0.,0.);
            }

    }

    /*read from files*/
    sf_complexread(ww,nt,Fsrc);
    sf_complexread(lt[0],nzx*m2,left);
    sf_complexread(rt[0],m2*nk,right);
    sf_complexread(ltb[0],nzx*m2,leftb);
    sf_complexread(rtb[0],m2*nk,rightb);
    if(!adj) sf_complexread(img[0],nx*nz,Fimg);

    if(adj && wantrecord) {
        sf_complexread(record[0][0], shtnum*gpl*nt, Frcd);
        if(incom) {
            for (is=0; is<shtnum; is++)
                for (ix=0; ix<gpl; ix++)
                    if(kill[is][ix]==0)
                        for (it=0; it<nt; it++)
                            record[is][ix][it]=sf_cmplx(0.,0.);
        }
    } else {
#ifdef _OPENMP
        #pragma omp parallel for private(is,ix,it)
#endif
        for (is=0; is<shtnum; is++)
            for (ix=0; ix<gpl; ix++)
                for (it=0; it<nt; it++)
                    record[is][ix][it] = sf_cmplx(0.,0.);
    }

    /*close RSF files*/
    sf_fileclose(Fsrc);
    sf_fileclose(left);
    sf_fileclose(right);
    sf_fileclose(leftb);
    sf_fileclose(rightb);

    /*load constant geopar elements*/
    mpip->cpuid=rank;
    mpip->numprocs=nodes;
    /*load constant geopar elements*/
    geop->nx  = nx;
    geop->nz  = nz;
    geop->nxb = nxb;
    geop->nzb = nzb;
    geop->dx  = dx;
    geop->dz  = dz;
    geop->ox  = ox;
    geop->oz  = oz;
    geop->snpint = snpint;
    geop->spz = spz;
    geop->gpz = gpz;
    geop->gpl = gpl;
    geop->top = top;
    geop->bot = bot;
    geop->lft = lft;
    geop->rht = rht;
    geop->nt = nt;
    geop->dt = dt;
    geop->trunc = trunc;
    geop->shtnum = shtnum;

    /* output RSF files */

    if (rank==0) {
        sf_setn(ax, gpl);
        sf_setn(az, nz);
        as = sf_iaxa(Fvel, 2);
        sf_setn(as,shtnum);
        sf_setd(as,shtint*dx);
        sf_seto(as,shtbgn*dx+ox);

        if (adj) { /* migration */
            if(!wantrecord) {
                sf_oaxa(Frcd, at, 1);
                sf_oaxa(Frcd, ax, 2);
                sf_oaxa(Frcd, as, 3);
                sf_settype(Frcd,SF_COMPLEX);
            }
            sf_setn(ax, nx);
            /*write image*/
            sf_oaxa(Fimg, az, 1);
            sf_oaxa(Fimg, ax, 2);
            sf_settype(Fimg,SF_COMPLEX);

        } else { /* modeling */
            sf_oaxa(Frcd, at, 1);
            sf_oaxa(Frcd, ax, 2);
            sf_oaxa(Frcd, as ,3);
            sf_settype(Frcd,SF_COMPLEX);
        }

        if (wantwf) {
            sf_setn(ax, nx);
            /*write temp wavefield */
            sf_setn(at, (wfnt-1)/wfint+1);
            sf_setd(at, wfdt*wfint);

            sf_oaxa(Ftmpwf, az, 1);
            sf_oaxa(Ftmpwf, ax, 2);
            sf_oaxa(Ftmpwf, at, 3);
            sf_settype(Ftmpwf,SF_COMPLEX);
        }
    }

    tstart = clock();

    for (is=rank; is<shtnum; is+=nodes) {
        spx = shtbgn + shtint*is;
        if (roll)
            gpx = spx - (int)(gpl/2);
        else
            gpx = 0;
        geop->spx = spx;
        geop->gpx = gpx;

        if (verb) {
            sf_warning("============================");
            sf_warning("processing shot #%d", is);
            sf_warning("nx=%d nz=%d nt=%d", geop->nx, geop->nz, geop->nt);
            sf_warning("nxb=%d nzb=%d ", geop->nxb, geop->nzb);
            sf_warning("dx=%f dz=%f dt=%f", geop->dx, geop->dz, geop->dt);
            sf_warning("top=%d bot=%d lft=%d rht=%d", geop->top, geop->bot, geop->lft, geop->rht);
            sf_warning("rectz=%d rectx=%d repeat=%d srctrunc=%f",rectz,rectx,repeat,geop->trunc);
            sf_warning("spz=%d spx=%d gpz=%d gpx=%d gpl=%d", spz, spx, gpz, gpx, gpl);
            sf_warning("snpint=%d wfdt=%f wfnt=%d ", snpint, wfdt, wfnt);
            sf_warning("sht0=%d shtbgn=%d shtend=%d shtnum=%d", sht0, shtbgn, shtend, shtnum);
            if (roll) sf_warning("Rolling survey!");
            else sf_warning("Global survey (gpl=nx)!");
            if (illum) sf_warning("Using source illumination!");
            else sf_warning("No source illumination!");
            sf_warning("============================");
        }

        /*generate reflectivity map*/
        reflgen(nzb, nxb, spz+top, spx+lft, rectz, rectx, repeat, rr);

        lrosfor2(wavefld, sill, tmprec, verb, lt, rt, m2, geop, ww, rr, pad1, illum);

        if(adj && wantrecord)
#ifdef _OPENMP
            #pragma omp parallel for private(ix,it)
#endif
            for (ix=0; ix<gpl; ix++)
                for (it=0; it<nt; it++)
                    tmprec[ix][it] = record[is][ix][it];

        if(!fm) {
            lrosback2(img, wavefld, sill, tmprec, adj, verb, wantwf, ltb, rtb, m2, geop, pad1, illum);
        }

        if (adj) {
#ifdef _OPENMP
            #pragma omp parallel for private(ix,iz)
#endif
            for (ix=0; ix<nx; ix++)
                for (iz=0; iz<nz; iz++)
                    imgsum[ix][iz] += img[ix][iz];
        }

        if (!adj || !wantrecord)
#ifdef _OPENMP
            #pragma omp parallel for private(ix,it)
#endif
            for (ix=0; ix<gpl; ix++)
                for (it=0; it<nt; it++)
                    record[is][ix][it] = tmprec[ix][it];

        if (wantwf && is==0)
            for (it=0; it<wfnt; it++) {
                if (it%wfint == 0) {
                    sf_complexwrite(wavefld[it][0], nx*nz, Ftmpwf);
                }
            }
    } /*shot iteration*/

    MPI_Barrier(MPI_COMM_WORLD);
    /*write record/image*/
    if (adj) {
        if (rank==0) {
            sendbuf = (sf_complex *) MPI_IN_PLACE;
            recvbuf = imgsum[0];
        } else {
            sendbuf = imgsum[0];
            recvbuf = NULL;
        }
        MPI_Reduce(sendbuf, recvbuf, nx*nz, MPI_COMPLEX, MPI_SUM, 0, MPI_COMM_WORLD);
        if (rank==0)
            sf_complexwrite(imgsum[0], nx*nz, Fimg);
    }

    if (!adj || !wantrecord) {
        if (rank==0) {
            sendbuf = (sf_complex *) MPI_IN_PLACE;
            recvbuf = record[0][0];
        } else {
            sendbuf = record[0][0];
            recvbuf = NULL;
        }
        MPI_Reduce(sendbuf, recvbuf, shtnum*gpl*nt, MPI_COMPLEX, MPI_SUM, 0, MPI_COMM_WORLD);
        if (rank==0) {
            if(incom) {
                for (is=0; is<shtnum; is++)
                    for (ix=0; ix<gpl; ix++)
                        if(kill[is][ix]==0)
                            for (it=0; it<nt; it++)
                                record[is][ix][it]=sf_cmplx(0.,0.);
            }
            sf_complexwrite(record[0][0], shtnum*gpl*nt, Frcd);
        }
    }

    /*free memory*/
    free(ww);
    free(rr);
    free(*lt);
    free(lt);
    free(*rt);
    free(rt);
    free(*ltb);
    free(ltb);
    free(*rtb);
    free(rtb);
    free(geop);
    free(mpip);
    free(*tmprec);
    free(tmprec);
    free(**record);
    free(*record);
    free(record);
    free(**wavefld);
    free(*wavefld);
    free(wavefld);
    if (illum) {
        free(*sill);
        free(sill);
    }
    free(*img);
    free(img);
    if (adj) {
        free(*imgsum);
        free(imgsum);
    }
    if (incom) {
        free(* kill);
        free(kill);
    }

    tend = clock();
    duration=(double)(tend-tstart)/CLOCKS_PER_SEC;
    sf_warning(">> The CPU time of single shot migration is: %f seconds << ", duration);

    MPI_Finalize();
    exit(0);
}