コード例 #1
0
ファイル: Mmpilrrtm_ts.c プロジェクト: housian0724/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, gpz, n, m, pad1, trunc, spx, spz;

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

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

	double tstart, tend;
	struct timeval tim;
	
	sf_complex c, **lt, **rt;
	sf_complex *ww, **dd;
	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;
    float *sendbuf, *recvbuf;
	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_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("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=");

	/* input/output files */
	Fdat=sf_input("in");
	Fimg1=sf_output("out");
    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); 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", &rnx)) sf_error("Need n2= in input!");
    if(!sf_histfloat(Fdat, "d2", &dx)) sf_error("Need d2= 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;
    
	/* print axies parameters for double check */
    sf_warning("cpuid=%d, numprocs=%d", cpuid, numprocs);
	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("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;
    trunc=srctrunc/dt+0.5;
    
	dd=sf_complexalloc2(nt, rnx);
	rr=sf_floatalloc(nzx);
	reflgen(nz, nx, spz, spx, rectz, rectx, 0, 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);
    
#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 (is=cpuid; is<ns; is+=numprocs){
		/* 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);
        
        /* read data */
        sf_seek(Fdat, is*rnx*nt*sizeof(float complex), SEEK_SET);
        sf_complexread(dd[0], rnx*nt, Fdat);
        
        /* 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;
		
		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(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<rnx; ix++){
                curr[(ix+nb)*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(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.;
            }
        }
        
        /* calculate time shift gathers */
        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 ishot
	MPI_Barrier(comm);
    
    cfft2_finalize();
    sf_fileclose(Fdat);
    
    free(ww); free(rr);
	free(*dd); free(dd);
	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);
}
コード例 #2
0
ファイル: Mafmod.c プロジェクト: 1014511134/src
int main(int argc, char* argv[])
{
    bool verb; /* verbosity flag */
    bool abc;  /* absorbing boundary conditions flag */
    bool free; /* free surface flag*/
    bool snap; /* wavefield snapshots flag */
    bool dens;
    int  jsnap;/* save wavefield every *jsnap* time steps */

    /* I/O files */
    sf_file Fw,Fs,Fr;
    sf_file Fd,Fu;
    sf_file Fv=NULL; /* velocity */
    sf_file Fe=NULL; /* density */

    /* cube axes */
    sf_axis at,az,ax,as,ar;
    int it,iz,ix,is,ir, iop;
    int nt,nz,nx,ns,nr,nz2,nx2;
    float z0,dz,x0,dx,idx,idz,dt,dt2;

    /* arrays */
    pt2d   *ss, *rr; /* source/receiver locations */
    float  *ww=NULL; /* wavelet */
    float  *dd=NULL; /* data */
    float **vv=NULL; /* velocity */
    float **ee=NULL; /* density  */

    float *fzs,*fxs,    *fzr,*fxr;
    int   *jzs,*jxs,    *jzr,*jxr;

    float *ws00,*ws01,*ws10,*ws11;
    float *wr00,*wr01,*wr10,*wr11;

    float **um,**uo,**up,**ud,**vp,**ro,**tt,**ut;
    float  *bzl,*bzh,*bxl,*bxh;  /* boundary */

    int   nop=2;       /* Laplacian operator size */
    float c0, c1, c2;  /* Laplacian operator coefficients */
    float co,c1x,c2x,c1z,c2z;

    int  nbz,nbx; /* boundary size */
    float tz, tx; /* sponge boundary decay coefficients */
    float dp;
    float ws;     /* injected data */

    int ompchunk;  /* OpenMP data chunk size */

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

    /* init RSF */
    sf_init(argc,argv);

    if(! sf_getint("ompchunk",&ompchunk)) ompchunk=1;

    if(! sf_getbool("verb",&verb)) verb=false;
    if(! sf_getbool( "abc",&abc ))  abc=false;
    if(! sf_getbool("snap",&snap)) snap=false;
    if(! sf_getbool("free",&free)) free=false;
    if(! sf_getbool("dens",&dens)) dens=false;

    Fw = sf_input ("in" ); /* wavelet */
    Fv = sf_input ("vel"); /* velocity */
    Fs = sf_input ("sou"); /* sources */
    Fr = sf_input ("rec"); /* receivers */
    Fu = sf_output("wfl"); /* wavefield */
    Fd = sf_output("out"); /* data */

    if(dens) Fe = sf_input("den"); /* density */

    /* read axes*/
    at=sf_iaxa(Fw,1); sf_setlabel(at,"t"); if(verb) sf_raxa(at); /* time */
    az=sf_iaxa(Fv,1); sf_setlabel(az,"z"); if(verb) sf_raxa(az); /* depth */
    ax=sf_iaxa(Fv,2); sf_setlabel(ax,"x"); if(verb) sf_raxa(ax); /* space */
    as=sf_iaxa(Fs,2); sf_setlabel(as,"s"); if(verb) sf_raxa(as); /* source */
    ar=sf_iaxa(Fr,2); sf_setlabel(ar,"r"); if(verb) sf_raxa(ar); /* receiver */

    nt=sf_n(at); dt=sf_d(at);
    nz=sf_n(az);
    nx=sf_n(ax);
    ns=sf_n(as);
    nr=sf_n(ar);

    /* configure wavefield snapshots */
    if(snap) {
	if(! sf_getint("jsnap",&jsnap)) jsnap=nt;
    }

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

    /* expand domain for absorbing boundary conditions */
    if(abc) {
	if(! sf_getint("nbz",&nbz)) nbz=nop; if(nbz<nop) nbz=nop;
	if(! sf_getint("nbx",&nbx)) nbx=nop; if(nbx<nop) nbx=nop;
	
	if(! sf_getfloat("tz",&tz)) tz=0.025;
	if(! sf_getfloat("tx",&tx)) tx=0.025;
    } else {
	nbz=nop;
	nbx=nop;
    }
    /* expanded domain ( az+2 nz, ax+2 nx ) */
    nz2=nz+2*nbz; dz=sf_d(az); z0=sf_o(az)-nbz*dz; 
    nx2=nx+2*nbx; dx=sf_d(ax); x0=sf_o(ax)-nbx*dx; 

    sf_setn(az,nz2); sf_seto(az,z0); if(verb) sf_raxa(az);
    sf_setn(ax,nx2); sf_seto(ax,x0); if(verb) sf_raxa(ax);
    
/*------------------------------------------------------------*/

    /* setup output data header */
    sf_oaxa(Fd,ar,1);
    sf_oaxa(Fd,at,2);

    /* setup output wavefield header */
    if(snap) {
	sf_setn(at,nt/jsnap);
	sf_setd(at,dt*jsnap);

	sf_oaxa(Fu,az,1);
	sf_oaxa(Fu,ax,2);
	sf_oaxa(Fu,at,3);
    }

    /* Laplacian coefficients */
    c0=-30./12.; 
    c1=+16./12.;
    c2=- 1./12.;

    dt2 = dt*dt;
    idz = 1/dz;
    idx = 1/dx;

    co = c0 * (idx*idx+idz*idz);
    c1x= c1 *  idx*idx;
    c2x= c2 *  idx*idx;
    c1z= c1 *          idz*idz;
    c2z= c2 *          idz*idz;

/*------------------------------------------------------------*/
     
    /* allocate arrays */
    ww=sf_floatalloc (nt);    sf_floatread(ww   ,nt   ,Fw);
    vv=sf_floatalloc2(nz,nx); sf_floatread(vv[0],nz*nx,Fv);

    ee=sf_floatalloc2(nz,nx); 
    if(dens) {
	sf_floatread(ee[0],nz*nx,Fe); 
    } else {
	for (iz=0; iz<nz; iz++) {
	    for (ix=0; ix<nx; ix++) {
		ee[ix][iz]=1;
	    }
	}
    }
    
    /* allocate source/receiver point arrays */
    ss = (pt2d*) sf_alloc(ns,sizeof(*ss)); 
    rr = (pt2d*) sf_alloc(nr,sizeof(*rr)); 

    pt2dread1(Fs,ss,ns,3); /* read 3 elements (x,z,v) */
    pt2dread1(Fr,rr,nr,2); /* read 2 elements (x,z)   */

    dd=sf_floatalloc(nr);
    for(ir=0;ir<nr;ir++) {
	dd[ir]=0;
    }
    
    jzs=sf_intalloc(ns); fzs=sf_floatalloc(ns); 
    jzr=sf_intalloc(nr); fzr=sf_floatalloc(nr);
    jxs=sf_intalloc(ns); fxs=sf_floatalloc(ns);
    jxr=sf_intalloc(nr); fxr=sf_floatalloc(nr);

    ws00 = sf_floatalloc(ns); wr00 = sf_floatalloc(nr); 
    ws01 = sf_floatalloc(ns); wr01 = sf_floatalloc(nr);
    ws10 = sf_floatalloc(ns); wr10 = sf_floatalloc(nr);
    ws11 = sf_floatalloc(ns); wr11 = sf_floatalloc(nr);
/*------------------------------------------------------------*/

    for (is=0;is<ns;is++) {

	if(ss[is].z >= z0 && 
	   ss[is].z <  z0 + (nz2-1)*dz &&
	   ss[is].x >= x0 && 
	   ss[is].x <  x0 + (nx2-1)*dx) {
	    
	    jzs[is] = (int)( (ss[is].z-z0)/dz);
	    fzs[is] =        (ss[is].z-z0)/dz - jzs[is];	    
	    jxs[is] = (int)( (ss[is].x-x0)/dx);
	    fxs[is] =        (ss[is].x-x0)/dx - jxs[is];
	} else {
	    jzs[is] = 0; jxs[is] = 0;
	    fzs[is] = 1; fxs[is] = 0;
	    ss[is].v= 0;
	}

	ws00[is] = (1-fzs[is])*(1-fxs[is]);
	ws01[is] = (  fzs[is])*(1-fxs[is]);
	ws10[is] = (1-fzs[is])*(  fxs[is]);
	ws11[is] = (  fzs[is])*(  fxs[is]);

    }

    for (ir=0;ir<nr;ir++) {

	if(rr[ir].z >= z0 && 
	   rr[ir].z < z0 + (nz2-1)*dz &&
	   rr[ir].x >= x0 && 
	   rr[ir].x < x0 + (nx2-1)*dx) {
	    
	    jzr[ir] = (int)( (rr[ir].z-z0)/dz);
	    fzr[ir] =        (rr[ir].z-z0)/dz - jzr[ir];
	    jxr[ir] = (int)( (rr[ir].x-x0)/dx);
	    fxr[ir] =        (rr[ir].x-x0)/dx - jxr[ir];

	    rr[ir].v=1;
	} else {
	    jzr[ir] = 0;
	    fzr[ir] = 1;
	    rr[ir].v= 0;
	}

	wr00[ir] = (1-fzr[ir])*(1-fxr[ir]);
	wr01[ir] = (  fzr[ir])*(1-fxr[ir]);
	wr10[ir] = (1-fzr[ir])*(  fxr[ir]);
	wr11[ir] = (  fzr[ir])*(  fxr[ir]);
    }
    
/*------------------------------------------------------------*/
    
    /* allocate temporary arrays */
    um=sf_floatalloc2(nz2,nx2);
    uo=sf_floatalloc2(nz2,nx2);
    up=sf_floatalloc2(nz2,nx2);
    ud=sf_floatalloc2(nz2,nx2);
    tt=sf_floatalloc2(nz2,nx2);

#ifdef _OPENMP
#pragma omp parallel for schedule(dynamic,ompchunk) private(iz,ix) shared(nx2,nz2,um,uo,up,ud,tt)
#endif
    for (iz=0; iz<nz2; iz++) {
	for (ix=0; ix<nx2; ix++) {
	    um[ix][iz]=0;
	    uo[ix][iz]=0;
	    up[ix][iz]=0;
	    ud[ix][iz]=0;
	    tt[ix][iz]=1;
	}
    }

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

    /* velocity in the expanded domain (vp=vv^2)*/
    vp=sf_floatalloc2(nz2,nx2);
    ro=sf_floatalloc2(nz2,nx2);
    
#ifdef _OPENMP
#pragma omp parallel for schedule(dynamic,ompchunk) private(iz,ix) shared(nz,nx,vp,ro,vv,ee)
#endif
    for (iz=0; iz<nz; iz++) {
	for (ix=0; ix<nx; ix++) {
	    vp[nbx+ix][nbz+iz] = vv[ix][iz] * vv[ix][iz];
	    ro[nbx+ix][nbz+iz] = ee[ix][iz];
	}
    }
    /* fill boundaries */
    for (iz=0; iz<nbz; iz++) {
	for (ix=0; ix<nx2; ix++) {
	    vp[ix][    iz  ] = vp[ix][    nbz  ];
	    vp[ix][nz2-iz-1] = vp[ix][nz2-nbz-1];
	    
	    ro[ix][    iz  ] = ro[ix][    nbz  ];
	    ro[ix][nz2-iz-1] = ro[ix][nz2-nbz-1];
	}
    }
    for (iz=0; iz<nz2; iz++) {
	for (ix=0; ix<nbx; ix++) {
	    vp[    ix  ][iz] = vp[    nbx  ][iz];
	    vp[nx2-ix-1][iz] = vp[nx2-nbx-1][iz];

	    ro[    ix  ][iz] = ro[    nbx  ][iz];
	    ro[nx2-ix-1][iz] = ro[nx2-nbx-1][iz];
	}
    }

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

    /* free surface */
    if(abc && free) {
	for (iz=0; iz<nbz; iz++) {
	    for (ix=0; ix<nx2; ix++) {
		vp[ix][iz]=0;
	    }
	}
    }

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

    /* sponge ABC setup */
    if(abc) {
	for (iz=0; iz<nbz; iz++) {
	    for (ix=0; ix<nx2; ix++) {
		tt[ix][    iz  ] = exp( - (tz*(nbz-iz))*(tz*(nbz-iz)) );
		tt[ix][nz2-iz-1] = tt[ix][iz];
	    }
	}
	for (iz=0; iz<nz2; iz++) {
	    for (ix=0; ix<nbx; ix++) {
		tt[    ix  ][iz] = exp( - (tx*(nbx-ix))*(tx*(nbx-ix)) );
		tt[nx2-ix-1][iz] = tt[ix][iz];
	    }
	}
    }

    /* one-way ABC setup */
    bzl=sf_floatalloc(nx2);
    bzh=sf_floatalloc(nx2);
    bxl=sf_floatalloc(nz2);
    bxh=sf_floatalloc(nz2);
    
    for (ix=0;ix<nx2;ix++) {
	dp = vp[ix][    nop  ] *dt/dz; bzl[ix] = (1-dp)/(1+dp);
	dp = vp[ix][nz2-nop-1] *dt/dz; bzh[ix] = (1-dp)/(1+dp);
    }
    for (iz=0;iz<nz2;iz++) {
	dp = vp[    nop  ][iz] *dt/dx; bxl[iz] = (1-dp)/(1+dp);
	dp = vp[nx2-nop-1][iz] *dt/dx; bxh[iz] = (1-dp)/(1+dp);
    }
/*------------------------------------------------------------*/
    /* 
     *  MAIN LOOP
     */
    if(verb) fprintf(stderr,"\n");
    for (it=0; it<nt; it++) {
	if(verb) fprintf(stderr,"\b\b\b\b\b%d",it);
	
	if(dens) { 	/* variable density */
#ifdef _OPENMP
#pragma omp parallel for schedule(dynamic,ompchunk) private(iz,ix) shared(nop,nx2,nz2,ud,uo,ro,co,c1x,c1z,c2x,c2z,idx,idz)
#endif
	    for(    ix=nop; ix<nx2-nop; ix++) {
		for(iz=nop; iz<nz2-nop; iz++) {

		    /* 4th order Laplacian operator */
		    ud[ix][iz] = 
			co * uo[ix  ][iz  ] + 
			c1x*(uo[ix-1][iz  ] + uo[ix+1][iz  ]) +
			c2x*(uo[ix-2][iz  ] + uo[ix+2][iz  ]) +
			c1z*(uo[ix  ][iz-1] + uo[ix  ][iz+1]) +
			c2z*(uo[ix  ][iz-2] + uo[ix  ][iz+2]);	  

		    /* density terms */
		    ud[ix][iz] -= (
			D1(uo,ix,iz,idz) * D1(ro,ix,iz,idz) +
			D2(uo,ix,iz,idx) * D2(ro,ix,iz,idx) ) / ro[ix][iz];
		}
	    }   

	} else {	/* constant density */

#ifdef _OPENMP
#pragma omp parallel for schedule(dynamic,ompchunk) private(iz,ix) shared(nop,nx2,nz2,ud,uo,co,c1x,c1z,c2x,c2z)
#endif
	    for(    ix=nop; ix<nx2-nop; ix++) {
		for(iz=nop; iz<nz2-nop; iz++) {

		    /* 4th order Laplacian operator */
		    ud[ix][iz] = 
			co * uo[ix  ][iz  ] + 
			c1x*(uo[ix-1][iz  ] + uo[ix+1][iz  ]) +
			c2x*(uo[ix-2][iz  ] + uo[ix+2][iz  ]) +
			c1z*(uo[ix  ][iz-1] + uo[ix  ][iz+1]) +
			c2z*(uo[ix  ][iz-2] + uo[ix  ][iz+2]);	  
		}
	    }
	}
	
	/* inject wavelet */
	for (is=0;is<ns;is++) {
	    ws = ww[it] * ss[is].v;
	    ud[ jxs[is]  ][ jzs[is]  ] -= ws * ws00[is];
	    ud[ jxs[is]  ][ jzs[is]+1] -= ws * ws01[is];
	    ud[ jxs[is]+1][ jzs[is]  ] -= ws * ws10[is];
	    ud[ jxs[is]+1][ jzs[is]+1] -= ws * ws11[is];
	}

#ifdef _OPENMP
#pragma omp parallel for schedule(dynamic,ompchunk) private(ix,iz) shared(nx2,nz2,ud,uo,um,up,vp,dt2)
#endif
	for(    ix=0; ix<nx2; ix++) {
	    for(iz=0; iz<nz2; iz++) {

		/* time step and velocity scale*/
		up[ix][iz] = 2*uo[ix][iz] - 
		               um[ix][iz] + 
		               ud[ix][iz] * vp[ix][iz] * dt2; 
	    }
	}
	/* circulate arrays */
	ut=um;
	um=uo;
	uo=up;
	up=ut;


	/* one-way ABC apply */	
	if(abc) {
#ifdef _OPENMP
#pragma omp parallel for schedule(dynamic,ompchunk) private(ix,iz,iop) shared(nx2,nz2,nop,uo,um,bzl,bzh)
#endif
	    for(ix=0;ix<nx2;ix++) {
		for(iop=0;iop<nop;iop++) {
		    iz = nop-iop;
		    uo      [ix][iz  ] 
			= um[ix][iz+1] 
			+(um[ix][iz  ]
			- uo[ix][iz+1]) * bzl[ix];
		    
		    iz = nz2-nop+iop-1;
		    uo      [ix][iz  ] 
			= um[ix][iz-1]
			+(um[ix][iz  ]
			- uo[ix][iz-1]) * bzh[ix];
		}
	    }

#ifdef _OPENMP
#pragma omp parallel for schedule(dynamic,1) private(ix,iz,iop) shared(nx2,nz2,nop,uo,um,bzl,bzh)
#endif
	    for(iop=0;iop<nop;iop++) {
		for(iz=0;iz<nz2;iz++) {
		    ix = nop-iop;
		    uo      [ix  ][iz] 
			= um[ix+1][iz] 
			+(um[ix  ][iz]
			- uo[ix+1][iz]) * bxl[iz];
		    
		    ix = nx2-nop+iop-1;
		    uo      [ix  ][iz] 
			= um[ix-1][iz]
			+(um[ix  ][iz]
			- uo[ix-1][iz]) * bxh[iz];
		}
	    }
	}
	
	/* sponge ABC apply */
	if(abc) {
#ifdef _OPENMP
#pragma omp parallel for schedule(dynamic,ompchunk) private(ix,iz) shared(nx2,nz2,uo,um,ud,tt)
#endif
	    for(    ix=0; ix<nx2; ix++) {
		for(iz=0; iz<nz2; iz++) {
		    uo[ix][iz] *= tt[ix][iz];
		    um[ix][iz] *= tt[ix][iz];
		    ud[ix][iz] *= tt[ix][iz];
		}
	    }
	}
	
	/* write wavefield */
	if(snap && it%jsnap==0) {
	    sf_floatwrite(uo[0],nz2*nx2,Fu);
	}

	/* collect data */
#ifdef _OPENMP
#pragma omp parallel for schedule(dynamic,1) private(ir) shared(dd,rr,uo,jzr,wr00,wr01,wr10,wr11)
#endif
	for (ir=0;ir<nr;ir++) {
	    dd[ir] =
		uo[ jxr[ir]  ][ jzr[ir]  ] * wr00[ir] +
		uo[ jxr[ir]  ][ jzr[ir]+1] * wr01[ir] +
		uo[ jxr[ir]+1][ jzr[ir]  ] * wr10[ir] +
		uo[ jxr[ir]+1][ jzr[ir]+1] * wr11[ir];
	    dd[ir] *= rr[ir].v;
	}
	/* write data */
	sf_floatwrite(dd,nr,Fd);
    }
    if(verb) fprintf(stderr,"\n");

    exit (0);
}
コード例 #3
0
ファイル: Mwavmod.c プロジェクト: 1014511134/src
int main(int argc, char* argv[])
{
    int jt, jtm, is, st;			/* index */
    int nt, n1, n2, ns, ng, m[SF_MAX_DIM], nm;				 	/* dimensions */
    float ot, o1, d1;				/* original */
    sf_file in, dat, wfl, vel, sgrid, ggrid; /* I/O files */
    float **wvlt;
    sf_axis ax;
    HVel hv;
    HCoord hs, hg;
    bool verb;

    sf_init(argc,argv);

    in = sf_input ("in");   
/* source wavelet \n
   \t nt X 1: regular shot gather
   \t nt X ns: simultaneous source shotting
*/
    vel  = sf_input ("vel");  /* velocity field */
    sgrid  = sf_input ("sgrid");  /* source grid */
    ggrid  = sf_input ("ggrid");  /* geophone grid */
    dat = sf_output("out");  /* seismic data */
 
    if(sf_getstring("wfl")!=NULL) 
	wfl = sf_output("wfl"); /* wavefield movie file */
    else wfl=NULL;

    if (!sf_getint("jt",&jt)) jt=1; 
    /* time interval in observation system */
    if (!sf_getint("jtm",&jtm)) jtm=100; 
    /* time interval of wave movie */
    if (!sf_getfloat("ot", &ot)) ot = 0.0; 
    /* time delay */
    if (!sf_getbool("verb", &verb)) verb = false; 
    /* verbosity */

    /* velocity and observation system */
    hv = obs_vel(vel);
    m[0] = sf_n(hv->z);	nm = 1;
    if(hv->nd >= 2)	{m[1] = sf_n(hv->x); nm=2;}
    if(hv->nd >= 3)	{m[2] = sf_n(hv->y); nm=3;}
    hs = obs_coord(sgrid, m, nm);
    hg = obs_coord(ggrid, m, nm);
    ns = sf_n(hs->a2);
    ng = sf_n(hg->a2);

    /* waveform */
    ax = sf_iaxa(in, 1);
    n1 = sf_n(ax);	o1 = sf_o(ax);	d1 = sf_d(ax);
    if(!sf_histint(in, "n2", &n2) || n2 != ns) n2=1;
    wvlt = sf_floatalloc2(n1, n2);
    sf_floatread(wvlt[0], n1*n2, in);


    if(ot<o1) ot=o1;
    st = (ot-o1)/d1;
    nt = (n1-st+1)/jt;
    sf_setn(ax, nt);
    sf_setd(ax, d1*jt);
    sf_seto(ax, ot);
    sf_oaxa(dat, ax, 1);
    sf_oaxa(dat, hg->a2, 2);
    if(n2==1) sf_oaxa(dat, hs->a2, 3);

    if(wfl!=NULL)
    {
	sf_oaxa(wfl, hv->z, 1);
	if(hv->nd >= 2) sf_oaxa(wfl, hv->x, 2);
	if(hv->nd >= 3) sf_oaxa(wfl, hv->y, 3);
	sf_setn(ax, (n1-st+1)/jtm);
	sf_setd(ax, d1*jtm);
	sf_seto(ax, ot);
	sf_oaxa(wfl, ax, hv->nd+1);
	if(n2==1) sf_oaxa(wfl, hs->a2, hv->nd+2);
    }

    wavmod_init(hv, d1, n1, st, jt, jtm, hg->p, ng, verb);

    if(n2==1)
	for (is=0; is < ns; is++)
	{
	    wavmod_shot(dat, wfl, 1, hs->p+is, wvlt);
	    if(verb) sf_warning("shot %d of %d", is, ns/n2);
	}
    else 
	wavmod_shot(dat, wfl, ns, hs->p, wvlt);

    wavmod_close();

    free(wvlt[0]);
    free(wvlt);
    return (0);
}
コード例 #4
0
ファイル: Mvtimod.c プロジェクト: 1014511134/src
int main(int argc, char* argv[])
{
    bool verb,fsrf,snap,expl,dabc; 
    int  jsnap,ntsnap,jdata;

    /* OMP parameters */
#ifdef _OPENMP
    int ompnth;
#endif 

    /* I/O files */
    sf_file Fwav=NULL; /* wavelet   */
    sf_file Fsou=NULL; /* sources   */
    sf_file Frec=NULL; /* receivers */
    sf_file Fvel=NULL; /* velocity  */
    sf_file Fdat=NULL; /* data      */
    sf_file Fwfl=NULL; /* wavefield */

    /* cube axes */
    sf_axis at,az,ax;
    sf_axis as,ar;

    int     nt,nz,nx,ns,nr,nb;
    int     it,iz,ix;
    float   dt,dz,dx,idz,idx,dt2;

    /* FDM structure */
    fdm2d    fdm=NULL;
    abcone2d abc=NULL;
    sponge   spo=NULL;

    /* I/O arrays */
    float  *ww=NULL;           /* wavelet   */
    pt2d   *ss=NULL;           /* sources   */
    pt2d   *rr=NULL;           /* receivers */
    float  *dd=NULL;           /* data      */

    float **tt=NULL;
    float **vp=NULL;           /* velocity */

    float **vp2=NULL;
    float **vv2=NULL;
    float **vh2=NULL;

    float **rm,**ro,**rp,**ra,**rt; /*      main wavefield */
    float **qm,**qo,**qp,**qa,**qt; /* auxiliary wavefield */

    /* linear interpolation weights/indices */
    lint2d cs,cr;

    /* FD operator size */
    float cox,coz,cax,cbx,caz,cbz;

    /* wavefield cut params */
    sf_axis   acz=NULL,acx=NULL;
    int       nqz,nqx;
    float     oqz,oqx;
    float     dqz,dqx;
    float     **qc=NULL;

    float H2q,H1r;

    /*------------------------------------------------------------*/
    /* init RSF */
    sf_init(argc,argv);

    /*------------------------------------------------------------*/
    /* OMP parameters */
#ifdef _OPENMP
    ompnth=omp_init();
#endif
    /*------------------------------------------------------------*/

    if(! sf_getbool("verb",&verb)) verb=false; /* verbosity flag */
    if(! sf_getbool("snap",&snap)) snap=false; /* wavefield snapshots flag */
    if(! sf_getbool("free",&fsrf)) fsrf=false; /* free surface flag */
    if(! sf_getbool("expl",&expl)) expl=false; /* "exploding reflector" */
    if(! sf_getbool("dabc",&dabc)) dabc=false; /* absorbing BC */
    /*------------------------------------------------------------*/

    /*------------------------------------------------------------*/
    /* I/O files */
    Fwav = sf_input ("in" ); /* wavelet   */
    Fvel = sf_input ("vel"); /* velocity  */
    Fsou = sf_input ("sou"); /* sources   */
    Frec = sf_input ("rec"); /* receivers */
    Fwfl = sf_output("wfl"); /* wavefield */
    Fdat = sf_output("out"); /* data      */

    /*------------------------------------------------------------*/
    /* axes */
    at = sf_iaxa(Fwav,2); sf_setlabel(at,"t"); if(verb) sf_raxa(at); /* time */
    az = sf_iaxa(Fvel,1); sf_setlabel(az,"z"); if(verb) sf_raxa(az); /* depth */
    ax = sf_iaxa(Fvel,2); sf_setlabel(ax,"x"); if(verb) sf_raxa(ax); /* space */

    as = sf_iaxa(Fsou,2); sf_setlabel(as,"s"); if(verb) sf_raxa(as); /* sources */
    ar = sf_iaxa(Frec,2); sf_setlabel(ar,"r"); if(verb) sf_raxa(ar); /* receivers */

    nt = sf_n(at); dt = sf_d(at);
    nz = sf_n(az); dz = sf_d(az);
    nx = sf_n(ax); dx = sf_d(ax);

    ns = sf_n(as);
    nr = sf_n(ar);
    /*------------------------------------------------------------*/

    /*------------------------------------------------------------*/
    /* other execution parameters */
    if(! sf_getint("jdata",&jdata)) jdata=1;
    if(snap) {  /* save wavefield every *jsnap* time steps */
	if(! sf_getint("jsnap",&jsnap)) jsnap=nt;        
    }
    /*------------------------------------------------------------*/

    /*------------------------------------------------------------*/
    /* expand domain for FD operators and ABC */
    if( !sf_getint("nb",&nb) || nb<NOP) nb=NOP;

    fdm=fdutil_init(verb,fsrf,az,ax,nb,1);

    sf_setn(az,fdm->nzpad); sf_seto(az,fdm->ozpad); if(verb) sf_raxa(az);
    sf_setn(ax,fdm->nxpad); sf_seto(ax,fdm->oxpad); if(verb) sf_raxa(ax);
    /*------------------------------------------------------------*/

    /*------------------------------------------------------------*/
    /* setup output data header */
    sf_oaxa(Fdat,ar,1);

    sf_setn(at,nt/jdata);
    sf_setd(at,dt*jdata);
    sf_oaxa(Fdat,at,2);

    /* setup output wavefield header */
    if(snap) {
	if(!sf_getint  ("nqz",&nqz)) nqz=sf_n(az);
	if(!sf_getint  ("nqx",&nqx)) nqx=sf_n(ax);

	if(!sf_getfloat("oqz",&oqz)) oqz=sf_o(az);
	if(!sf_getfloat("oqx",&oqx)) oqx=sf_o(ax);

	dqz=sf_d(az);
	dqx=sf_d(ax);

	acz = sf_maxa(nqz,oqz,dqz); sf_raxa(acz);
	acx = sf_maxa(nqx,oqx,dqx); sf_raxa(acx);
	/* check if the imaging window fits in the wavefield domain */

	qc=sf_floatalloc2(sf_n(acz),sf_n(acx));

	ntsnap=0;
	for(it=0; it<nt; it++) {
	    if(it%jsnap==0) ntsnap++;
	}
	sf_setn(at,  ntsnap);
	sf_setd(at,dt*jsnap);
	if(verb) sf_raxa(at);

	sf_oaxa(Fwfl,acz,1);
	sf_oaxa(Fwfl,acx,2);
	sf_oaxa(Fwfl,at, 3);
    }

    if(expl) {
	ww = sf_floatalloc( 1);
    } else {
	ww = sf_floatalloc(ns);
    }
    dd = sf_floatalloc(nr);

    /*------------------------------------------------------------*/
    /* setup source/receiver coordinates */
    ss = (pt2d*) sf_alloc(ns,sizeof(*ss)); 
    rr = (pt2d*) sf_alloc(nr,sizeof(*rr)); 

    pt2dread1(Fsou,ss,ns,2); /* read (x,z) coordinates */
    pt2dread1(Frec,rr,nr,2); /* read (x,z) coordinates */

    cs = lint2d_make(ns,ss,fdm);
    cr = lint2d_make(nr,rr,fdm);

    /*------------------------------------------------------------*/
    /* setup FD coefficients */
    idz = 1/dz;
    idx = 1/dx;

    cox= C0 * (idx*idx);
    cax= CA *  idx*idx;
    cbx= CB *  idx*idx;

    coz= C0 * (idz*idz);
    caz= CA *  idz*idz;
    cbz= CB *  idz*idz;

    /* precompute dt^2*/
    dt2 = dt*dt;

    /*------------------------------------------------------------*/ 
    tt = sf_floatalloc2(nz,nx); 
    /*------------------------------------------------------------*/

    /* input velocity */

    vp  =sf_floatalloc2(fdm->nzpad,fdm->nxpad); 
    vp2 =sf_floatalloc2(fdm->nzpad,fdm->nxpad); 
    vv2 =sf_floatalloc2(fdm->nzpad,fdm->nxpad);     
    vh2 =sf_floatalloc2(fdm->nzpad,fdm->nxpad); 

    sf_floatread(tt[0],nz*nx,Fvel );    expand(tt,vv2,fdm); /* vertical v */
    sf_floatread(tt[0],nz*nx,Fvel );    expand(tt,vp2,fdm); /* NMO v */
    sf_floatread(tt[0],nz*nx,Fvel );    expand(tt,vh2,fdm); /* horizontal v */

    for    (ix=0; ix<fdm->nxpad; ix++) {
	for(iz=0; iz<fdm->nzpad; iz++) {	    
	    vp2[ix][iz] = vp2[ix][iz] * vp2[ix][iz];
	    vv2[ix][iz] = vv2[ix][iz] * vv2[ix][iz];
	    vh2[ix][iz] = vh2[ix][iz] * vh2[ix][iz];
	}
    }    
    if(fsrf) { /* free surface */
	for    (ix=0; ix<fdm->nxpad; ix++) {
	    for(iz=0; iz<fdm->nb; iz++) {
		vp2[ix][iz]=0;
		vv2[ix][iz]=0;
		vh2[ix][iz]=0;
	    }
	}
    }

    /*------------------------------------------------------------*/
    free(*tt); free(tt);    
    /*------------------------------------------------------------*/

    /*------------------------------------------------------------*/
    /* allocate wavefield arrays */
    qm=sf_floatalloc2(fdm->nzpad,fdm->nxpad);
    qo=sf_floatalloc2(fdm->nzpad,fdm->nxpad);
    qp=sf_floatalloc2(fdm->nzpad,fdm->nxpad);
    qa=sf_floatalloc2(fdm->nzpad,fdm->nxpad);

    rm=sf_floatalloc2(fdm->nzpad,fdm->nxpad);
    ro=sf_floatalloc2(fdm->nzpad,fdm->nxpad);
    rp=sf_floatalloc2(fdm->nzpad,fdm->nxpad);
    ra=sf_floatalloc2(fdm->nzpad,fdm->nxpad);

    for    (ix=0; ix<fdm->nxpad; ix++) {
	for(iz=0; iz<fdm->nzpad; iz++) {
	    qm[ix][iz]=0;
	    qo[ix][iz]=0;
	    qp[ix][iz]=0;
	    qa[ix][iz]=0;

	    rm[ix][iz]=0;
	    ro[ix][iz]=0;
	    rp[ix][iz]=0;
	    ra[ix][iz]=0;
	}
    }

    /*------------------------------------------------------------*/
    if(dabc) {
	/* one-way abc setup */
	abc = abcone2d_make(NOP,dt,vp,fsrf,fdm);
	/* sponge abc setup */
	spo = sponge_make(fdm->nb);
    }

    /*------------------------------------------------------------*/
    /* 
     *  MAIN LOOP
     */
    /*------------------------------------------------------------*/
    if(verb) fprintf(stderr,"\n");
    for (it=0; it<nt; it++) {
	if(verb) fprintf(stderr,"\b\b\b\b\b%d",it);

#ifdef _OPENMP
#pragma omp parallel for				\
    schedule(dynamic,fdm->ompchunk)			\
    private(ix,iz,H2q,H1r)					\
    shared(fdm,ra,ro,qa,qo,cox,coz,cax,caz,cbx,cbz,idx,idz,vp2)
#endif
	for    (ix=NOP; ix<fdm->nxpad-NOP; ix++) {
	    for(iz=NOP; iz<fdm->nzpad-NOP; iz++) {

		H2q = Dxx(qo,ix,iz,cox,cax,cbx);

		H1r = Dzz(ro,ix,iz,coz,caz,cbz);
		
		/* main field - q */
		qa[ix][iz] = H2q * vh2[ix][iz] + H1r * vv2[ix][iz] ;

		/* auxiliary field - r */
		ra[ix][iz] = H2q * vp2[ix][iz] + H1r * vv2[ix][iz] ;
		
	    }
	}   

	/* inject acceleration source */
	if(expl) {
	    sf_floatread(ww, 1,Fwav);
	    lint2d_inject1(ra,ww[0],cs);
	    lint2d_inject1(qa,ww[0],cs);
	} else {
	    sf_floatread(ww,ns,Fwav);	
	    lint2d_inject(ra,ww,cs);
	    lint2d_inject(qa,ww,cs);
	}

	/* step forward in time */
#ifdef _OPENMP
#pragma omp parallel for	    \
    schedule(dynamic,fdm->ompchunk) \
    private(ix,iz)		    \
    shared(fdm,ra,ro,rm,rp,qa,qo,qm,qp,dt2)
#endif
	for    (ix=0; ix<fdm->nxpad; ix++) {
	    for(iz=0; iz<fdm->nzpad; iz++) {
		qp[ix][iz] = 2*qo[ix][iz] 
		    -          qm[ix][iz] 
		    +          qa[ix][iz] * dt2;

		rp[ix][iz] = 2*ro[ix][iz] 
		    -          rm[ix][iz] 
		    +          ra[ix][iz] * dt2;
	    }
	}
	/* circulate wavefield arrays */
	qt=qm;
	qm=qo;
	qo=qp;
	qp=qt;

	rt=rm;
	rm=ro;
	ro=rp;
	rp=rt;
	
	if(dabc) {
	    /* one-way abc apply */
	    abcone2d_apply(qo,qm,NOP,abc,fdm);
	    sponge2d_apply(qm,spo,fdm);
	    sponge2d_apply(qo,spo,fdm);
	    sponge2d_apply(qp,spo,fdm);

	    /* one-way abc apply */
	    abcone2d_apply(ro,rm,NOP,abc,fdm);
	    sponge2d_apply(rm,spo,fdm);
	    sponge2d_apply(ro,spo,fdm);
	    sponge2d_apply(rp,spo,fdm);
	}

	/* extract data */
	lint2d_extract(qo,dd,cr);

	if(snap && it%jsnap==0) {
	    cut2d(qo,qc,fdm,acz,acx);
	    sf_floatwrite(qc[0],sf_n(acz)*sf_n(acx),Fwfl);
	}
	if(        it%jdata==0) 
	    sf_floatwrite(dd,nr,Fdat);
    }
    if(verb) fprintf(stderr,"\n");    

    /*------------------------------------------------------------*/
    /* deallocate arrays */
    free(*rm); free(rm);
    free(*rp); free(rp);
    free(*ro); free(ro);
    free(*ra); free(ra);

    free(*qm); free(qm);
    free(*qp); free(qp);
    free(*qo); free(qo);
    free(*qa); free(qa);
    free(*qc); free(qc);

    free(*vp);  free(vp);
    free(*vp2); free(vp2);
    free(*vh2); free(vh2);
    free(*vv2); free(vv2);

    free(ww);
    free(ss);
    free(rr);
    free(dd);

    exit (0);
}
コード例 #5
0
ファイル: Mpremig.c プロジェクト: 1014511134/src
int main(int argc, char* argv[])
{

    /*survey parameters*/
    int   nx, nz;
    float dx, dz;
    int   n_srcs=1;
    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, adj;
    float vref;

    bool born;
    pspar par;
    int nx1, nz1; /*domain of interest*/
    float *vel,***dat,***dat_v,**wvfld1,**wvfld,*img,*imgs; /*velocity profile*/
    sf_file Fi,Fo,Fv,Fd_v,snaps; /* I/O files */
    sf_axis az,ax; /* cube axes */
    int shtbgn,shtend,shtnum,shtint;
    int ix,iz,is,which;
    bool justrec;

    bool diff;
    sf_file Fi1;
    float ***dat1;

    sf_init(argc,argv);

    if (!sf_getint("snap",&snap)) snap=0; /* interval for snapshots */
    if (!sf_getbool("cmplx",&cmplx)) cmplx=true; /* use complex fft */
    if (!sf_getint("pad1",&pad1)) pad1=1; /* padding factor on the first axis */
    if(!sf_getbool("abc",&abc)) abc=false; /* absorbing flag */
    if(!sf_getbool("born",&born)) born=false; /* born modeling flag */
    if(!sf_getbool("diff",&diff)) diff=false; /* diffraction imaging flag */
    if(!sf_getbool("justrec",&justrec)) justrec=false; /* just need full waveform record (no born or rtdm) */
    if (abc) {
      if(!sf_getint("nbt",&nbt)) sf_error("Need nbt!");
      if(!sf_getint("nbb",&nbb)) nbb = nbt;
      if(!sf_getint("nbl",&nbl)) nbl = nbt;
      if(!sf_getint("nbr",&nbr)) nbr = nbt;
      if(!sf_getfloat("ct",&ct)) sf_error("Need ct!");
      if(!sf_getfloat("cb",&cb)) cb = ct;
      if(!sf_getfloat("cl",&cl)) cl = ct;
      if(!sf_getfloat("cr",&cr)) cr = ct;
    } else {
      nbt = 0; nbb = 0; nbl = 0; nbr = 0;
      ct = 0; cb = 0; cl = 0; cr = 0;
    }
    if (!sf_getbool("verb",&verb)) verb=false; /* verbosity */
    if (!sf_getbool("ps",&ps)) ps=false; /* use pseudo-spectral */
    if (ps) sf_warning("Using pseudo-spectral...");
    else sf_warning("Using pseudo-analytical...");
    if (!sf_getbool("adj",&adj)) adj=false; /* use pseudo-spectral */
    if (justrec && adj) sf_error("No migration in justrec mode!");
    if (adj) sf_warning("RTM");
    else sf_warning("RTDM");
    if (!sf_getfloat("vref",&vref)) vref=1500; /* reference velocity (default using water) */

    /* setup I/O files */
    Fi = sf_input ("in");
    Fo = sf_output("out");
    Fv = sf_input("vel");
    if (adj) {
      gpl = -1;
      gpl_v = -1;
      sf_histint(Fi,"n1",&nt);
      sf_histfloat(Fi,"d1",&dt);
      sf_histint(Fi,"n2",&gpl);
      if (NULL!=sf_getstring("dat_v")) {
	Fd_v = sf_input("dat_v");
	sf_histint(Fd_v,"n2",&gpl_v);
      } else Fd_v = NULL;
      if (diff) Fi1 = sf_input("dat_2"); 
      else Fi1 = NULL;  
    } else {
      if (!sf_getint("nt",&nt)) sf_error("Need nt!");
      if (!sf_getfloat("dt",&dt)) sf_error("Need dt!");
      if (!sf_getint("gpl",&gpl)) gpl = -1; /* geophone length */
      if (!sf_getint("gpl_v",&gpl_v)) gpl_v = -1; /* geophone height */
    }
    if (!sf_getint("src",&src)) src=0; /* source type */
    //if (!sf_getint("n_srcs",&n_srcs)) n_srcs=1; /* source type */
    spx = sf_intalloc(n_srcs);
    spz = sf_intalloc(n_srcs);
    f0  = sf_floatalloc(n_srcs);
    t0  = sf_floatalloc(n_srcs);
    A   = sf_floatalloc(n_srcs);
    //if (!sf_getints("spx",spx,n_srcs)) sf_error("Need spx!"); /* shot position x */
    if (!sf_getints("spz",spz,n_srcs)) sf_error("Need spz!"); /* shot position z */
    if (!sf_getfloats("f0",f0,n_srcs)) sf_error("Need f0! (e.g. 30Hz)");   /*  wavelet peak freq */
    if (!sf_getfloats("t0",t0,n_srcs)) sf_error("Need t0! (e.g. 0.04s)");  /*  wavelet time lag */
    if (!sf_getfloats("A",A,n_srcs)) sf_error("Need A! (e.g. 1)");     /*  wavelet amplitude */
    if (!sf_getint("shtbgn", &shtbgn)) sf_error("Need shot starting location 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("which", &which)) which = 0;

    if (!sf_getint("gpx",&gpx)) gpx = -1; /* geophone position x */
    if (!sf_getint("gpz",&gpz)) gpz = -1; /* geophone position z */
    if (!sf_getint("gpx_v",&gpx_v)) gpx_v = -1; /* geophone position x */
    if (!sf_getint("gpz_v",&gpz_v)) gpz_v = -1; /* geophone position z */

    if (SF_FLOAT != sf_gettype(Fv)) sf_error("Need float input");

    /* Read/Write axes */
    az = sf_iaxa(Fv,1); nz = sf_n(az); dz = sf_d(az);
    ax = sf_iaxa(Fv,2); nx = sf_n(ax); dx = sf_d(ax);
    nz1 = nz-nbt-nbb;
    nx1 = nx-nbl-nbr;
    if (gpx==-1) gpx = nbl;
    if (gpz==-1) gpz = nbt;
    if (gpl==-1) gpl = nx1;
    if (gpx_v==-1) gpx_v = nbl;
    if (gpz_v==-1) gpz_v = nbt;
    if (gpl_v==-1) gpl_v = nz1;

    if (adj) { /*output image*/
      sf_setn(az,nz1);
      sf_setn(ax,nx1);
      sf_oaxa(Fo,az,1);
      sf_oaxa(Fo,ax,2);
      sf_putint(Fo,"n3",1);
      sf_putfloat(Fo,"d3",shtint*dx);
      sf_putfloat(Fo,"o3",0.);
      sf_settype(Fo,SF_FLOAT);
    } else { /*output data*/
      sf_setn(ax,gpl);
      /*output horizontal data is mandatory*/
      sf_putint(Fo,"n1",nt);
      sf_putfloat(Fo,"d1",dt);
      sf_putfloat(Fo,"o1",0.);
      sf_putstring(Fo,"label1","Time");
      sf_putstring(Fo,"unit1","s");
      sf_oaxa(Fo,ax,2);
      sf_putint(Fo,"n3",shtnum);
      sf_putfloat(Fo,"d3",shtint*dx);
      sf_putfloat(Fo,"o3",0.);
      sf_putstring(Fo,"label3","Shot");
      sf_settype(Fo,SF_FLOAT);
      /*output vertical data is optional*/
      if (NULL!=sf_getstring("dat_v")) {
	Fd_v = sf_output("dat_v");
	sf_setn(ax,gpl_v);
	/*output horizontal data is mandatory*/
	sf_putint(Fd_v,"n1",nt);
	sf_putfloat(Fd_v,"d1",dt);
	sf_putfloat(Fd_v,"o1",0.);
	sf_putstring(Fd_v,"label1","Time");
	sf_putstring(Fd_v,"unit1","s");
	sf_oaxa(Fd_v,ax,2);
        sf_putint(Fd_v,"n3",shtnum);
        sf_putfloat(Fd_v,"d3",shtint*dx);
        sf_putfloat(Fd_v,"o3",0.);
        sf_putstring(Fd_v,"label3","Shot");
	sf_settype(Fd_v,SF_FLOAT);	
      } else Fd_v = NULL;
    }

    if (snap > 0) {
	snaps = sf_output("snaps");
	/* (optional) snapshot file */
	sf_setn(az,nz1);
	sf_setn(ax,nx1);
	sf_oaxa(snaps,az,1);
	sf_oaxa(snaps,ax,2);
	sf_putint(snaps,"n3",nt/snap);
	sf_putfloat(snaps,"d3",dt*snap);
	sf_putfloat(snaps,"o3",0.);
	sf_putstring(snaps,"label3","Time");
	sf_putstring(snaps,"unit3","s");
    } else snaps = NULL;
    
    par = (pspar) sf_alloc(1,sizeof(*par));
    vel = sf_floatalloc(nz*nx);
    dat = sf_floatalloc3(nt,gpl,shtnum);
    img = sf_floatalloc(nz1*nx1);
    if (adj) {
      imgs= sf_floatalloc(nz1*nx1);
      if (adj) {
        for (ix=0; ix<nx1; ix++)
          for (iz=0; iz<nz1; iz++)
            imgs[ix*nz1+iz] = 0.;
      }
    } else imgs = NULL;
    if (NULL!=Fd_v) dat_v = sf_floatalloc3(nt,gpl_v,shtnum);
    else dat_v = NULL;
    if (snap>0) {
      wvfld1 = sf_floatalloc2(nx1*nz1,nt/snap);
      wvfld  = sf_floatalloc2(nx1*nz1,nt/snap);
    }
    else { wvfld1 = NULL; wvfld = NULL; }
    if (adj && diff) dat1 = sf_floatalloc3(nt,gpl,shtnum);
    else dat1 = NULL;

    sf_floatread(vel,nz*nx,Fv);
    if (adj) {
      sf_floatread(dat[0][0],gpl*nt*shtnum,Fi);
      if (NULL!=Fd_v) sf_floatread(dat_v[0][0],gpl_v*nt*shtnum,Fd_v);
      if (diff) sf_floatread(dat1[0][0],gpl_v*nt*shtnum,Fi1);
    } else {
      sf_floatread(img,nz1*nx1,Fi);
    }

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

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

      *spx = shtbgn + shtint*is;
      //par->spx = spx; //pointer

      sf_warning("Processing shot # %d/%d",is,shtnum-1);

      if (adj && diff) {

      sf_warning("Simultaneously propagating two receiver wavefields...");
      psp3(wvfld, wvfld1, dat[is], dat1[is], img, vel, par);


      for (ix=0; ix<nx1; ix++)
        for (iz=0; iz<nz1; iz++)
          imgs[ix*nz1+iz] += img[ix*nz1+iz];

      } else {

      if (justrec) {

        if (NULL == dat_v)
          psp(wvfld, dat[is], NULL, NULL, vel, par, false);
        else
          psp(wvfld, dat[is], dat_v[is], NULL, vel, par, false);

      } else {

        sf_warning("Computing source wavefield ...");
	psp(wvfld1, NULL, NULL, NULL, vel, par, false);
	if (born) dt2v2(wvfld1, vel, par);
	sf_warning("Computing receiver wavefield ...");
	if (NULL == dat_v)
	  psp2(wvfld1, wvfld, dat[is], NULL, img, vel, par, adj);
	else
	  psp2(wvfld1, wvfld, dat[is], dat_v[is], img, vel, par, adj);

        if (adj) {
          for (ix=0; ix<nx1; ix++)
            for (iz=0; iz<nz1; iz++)
              imgs[ix*nz1+iz] += img[ix*nz1+iz];
        }

      }

      }

      if (snap>0 && is==which)
        sf_floatwrite(wvfld[0],nz1*nx1*nt/snap,snaps);
    }
    
    if (adj) {
      sf_floatwrite(imgs,nz1*nx1,Fo);
    } else {
      sf_floatwrite(dat[0][0],gpl*nt*shtnum,Fo);
      if (NULL!=Fd_v) sf_floatwrite(dat_v[0][0],gpl_v*nt*shtnum,Fd_v);
    }

    exit (0);
}
コード例 #6
0
ファイル: Mbvvvdwe3d.c プロジェクト: krushev36/src
int main(int argc, char* argv[])
{
    bool verb,fsrf,snap,dabc;
    int  jsnap,ntsnap;
    int  jdata;

    /* I/O files */
    sf_file Fwav=NULL; /* wavelet   */
    sf_file Fsou=NULL; /* sources   */
    sf_file Frec=NULL; /* receivers */

    sf_file Fvel=NULL; /* velocity  */
    sf_file Fref=NULL; /* reflectivity */
    sf_file Fden=NULL; /* density   */

    sf_file Fdat=NULL; /* data (background)      */
    sf_file Fwfl=NULL; /* wavefield (background) */

    sf_file Flid=NULL; /* data (scattered)      */
    sf_file Fliw=NULL; /* wavefield (scattered) */

    /* I/O arrays */
    float  *ww=NULL;           /* wavelet   */
    pt3d   *ss=NULL;           /* sources   */
    pt3d   *rr=NULL;           /* receivers */

    float ***vpin=NULL;         /* velocity  */
    float ***roin=NULL;         /* density   */
    float ***rfin=NULL;         /* reflectivity */

    float ***vp=NULL;           /* velocity     in expanded domain */
    float ***ro=NULL;           /* density      in expanded domain */
    float ***iro=NULL;          /* buoyancy     in the expanded domain */

    float ***rf=NULL;           /* reflectivity in expanded domain */

    float  *bdd=NULL;          /* data (background) */
    float  *sdd=NULL;          /* data (scattered)  */

    float ***vt=NULL;           /* temporary vp*vp * dt*dt */

    float ***fsrfbck=NULL;		/* ghost cells for free surface BC */
    float ***fsrfsct=NULL;		/* ghost cells for free surface BC */

    float ***bum,***buo,***bup,***bua,***buat,***but; /* wavefield: um = U @ t-1; uo = U @ t; up = U @ t+1 */
    float ***sum,***suo,***sup,***sua,***suat,***sut; /* wavefield: um = U @ t-1; uo = U @ t; up = U @ t+1 */

    /* cube axes */
    sf_axis at,a1,a2,a3,as,ar;
    int     nt,n1,n2,n3,ns,nr,nb;
    int     it,i1,i2,i3;
    float   dt,d1,d2,d3,id1,id2,id3,dt2;

    /* linear interpolation weights/indices */
    lint3d cs,cr;

    fdm3d    fdm;
    abcone3d abc;     /* abc */
    sponge spo;

    /* FD coefficients */
    float c1x,c1y,c1z,
          c2x,c2y,c2z,
          c3x,c3y,c3z;

    int ompchunk;
#ifdef _OPENMP
    int ompnth,ompath;
#endif

    sf_axis   ac1=NULL,ac2=NULL,ac3=NULL;
    int       nqz,nqx,nqy;
    float     oqz,oqx,oqy;
    float     dqz,dqx,dqy;
    float     ***uc=NULL;

    /* for benchmarking */
    clock_t start_t, end_t;
    float total_t;

    /*------------------------------------------------------------*/
    /* init RSF */
    sf_init(argc,argv);
    if(! sf_getint("ompchunk",&ompchunk)) ompchunk=1;

    /* OpenMP data chunk size */
#ifdef _OPENMP
    if(! sf_getint("ompnth",  &ompnth))     ompnth=0;
    /* OpenMP available threads */
    #pragma omp parallel
    ompath=omp_get_num_threads();
    if(ompnth<1) ompnth=ompath;
    omp_set_num_threads(ompnth);
    sf_warning("using %d threads of a total of %d",ompnth,ompath);
#endif

    if(! sf_getbool("verb",&verb)) verb=false; /* verbosity flag */
    if(! sf_getbool("snap",&snap)) snap=false; /* wavefield snapshots flag */
    if(! sf_getbool("dabc",&dabc)) dabc=false; /* Absorbing BC */
    if(! sf_getbool("free",&fsrf)) fsrf=false; /* free surface flag */

    Fwav = sf_input ("in" ); /* wavelet   */
    Fsou = sf_input ("sou"); /* sources   */
    Frec = sf_input ("rec"); /* receivers */

    Fvel = sf_input ("vel"); /* velocity  */
    Fden = sf_input ("den"); /* density   */
    Fref = sf_input ("ref"); /* reflectivity */

    Fwfl = sf_output("wfl"); /* wavefield */
    Fdat = sf_output("out"); /* data      */

    Fliw = sf_output("liw"); /* wavefield (scattered) */
    Flid = sf_output("lid"); /* data (scattered) */

    /* axes */
    at = sf_iaxa(Fwav,2);
    sf_setlabel(at,"t");
    if(verb) sf_raxa(at); /* time */
    as = sf_iaxa(Fsou,2);
    sf_setlabel(as,"s");
    if(verb) sf_raxa(as); /* sources */
    ar = sf_iaxa(Frec,2);
    sf_setlabel(ar,"r");
    if(verb) sf_raxa(ar); /* receivers */
    a1 = sf_iaxa(Fvel,1);
    sf_setlabel(a1,"z");
    if(verb) sf_raxa(a1); /* z */
    a2 = sf_iaxa(Fvel,2);
    sf_setlabel(a2,"x");
    if(verb) sf_raxa(a2); /* x */
    a3 = sf_iaxa(Fvel,3);
    sf_setlabel(a3,"y");
    if(verb) sf_raxa(a3); /* y */

    nt = sf_n(at);
    dt = sf_d(at);
    ns = sf_n(as);
    nr = sf_n(ar);
    n1 = sf_n(a1);
    d1 = sf_d(a1);
    n2 = sf_n(a2);
    d2 = sf_d(a2);
    n3 = sf_n(a3);
    d3 = sf_d(a3);

    if(! sf_getint("jdata",&jdata)) jdata=1;
    if(snap) {  /* save wavefield every *jsnap* time steps */
        if(! sf_getint("jsnap",&jsnap)) jsnap=nt;
    }

    /*------------------------------------------------------------*/
    /* expand domain for FD operators and ABC */
    if( !sf_getint("nb",&nb) || nb<NOP) nb=NOP;

    fdm=fdutil3d_init(verb,fsrf,a1,a2,a3,nb,ompchunk);

    sf_setn(a1,fdm->nzpad);
    sf_seto(a1,fdm->ozpad);
    if(verb) sf_raxa(a1);
    sf_setn(a2,fdm->nxpad);
    sf_seto(a2,fdm->oxpad);
    if(verb) sf_raxa(a2);
    sf_setn(a3,fdm->nypad);
    sf_seto(a3,fdm->oypad);
    if(verb) sf_raxa(a3);
    /*------------------------------------------------------------*/

    /* setup output data header */
    sf_oaxa(Fdat,ar,1);
    sf_oaxa(Flid,ar,1);

    sf_setn(at,nt/jdata);
    sf_setd(at,dt*jdata);
    sf_oaxa(Fdat,at,2);
    sf_oaxa(Flid,at,2);

    /* setup output wavefield header */
    if(snap) {
        if(!sf_getint  ("nqz",&nqz)) nqz=sf_n(a1);
        if(!sf_getint  ("nqx",&nqx)) nqx=sf_n(a2);
        if(!sf_getint  ("nqy",&nqy)) nqy=sf_n(a3);

        if(!sf_getfloat("oqz",&oqz)) oqz=sf_o(a1);
        if(!sf_getfloat("oqx",&oqx)) oqx=sf_o(a2);
        if(!sf_getfloat("oqy",&oqy)) oqy=sf_o(a3);

        dqz=sf_d(a1);
        dqx=sf_d(a2);
        dqy=sf_d(a3);

        ac1 = sf_maxa(nqz,oqz,dqz);
        ac2 = sf_maxa(nqx,oqx,dqx);
        ac3 = sf_maxa(nqy,oqy,dqy);

        /* check if the imaging window fits in the wavefield domain */

        uc=sf_floatalloc3(sf_n(ac1),sf_n(ac2),sf_n(ac3));

        ntsnap=0;
        for(it=0; it<nt; it++) {
            if(it%jsnap==0) ntsnap++;
        }
        sf_setn(at,  ntsnap);
        sf_setd(at,dt*jsnap);
        if(verb) sf_raxa(at);

        /*	sf_setn(at,nt/jsnap);
        sf_setd(at,dt*jsnap); */

        sf_oaxa(Fwfl,ac1,1);
        sf_oaxa(Fwfl,ac2,2);
        sf_oaxa(Fwfl,ac3,3);
        sf_oaxa(Fwfl,at, 4);

        sf_oaxa(Fliw,ac1,1);
        sf_oaxa(Fliw,ac2,2);
        sf_oaxa(Fliw,ac3,3);
        sf_oaxa(Fliw,at, 4);
    }


    /* source wavelet array allocation */
    ww = sf_floatalloc(ns);

    /* data array allocation*/
    bdd = sf_floatalloc(nr);
    sdd = sf_floatalloc(nr);

    /*------------------------------------------------------------*/
    /* setup source/receiver coordinates */
    ss = (pt3d*) sf_alloc(ns,sizeof(*ss));
    rr = (pt3d*) sf_alloc(nr,sizeof(*rr));

    pt3dread1(Fsou,ss,ns,3); /* read (x,y,z) coordinates */
    pt3dread1(Frec,rr,nr,3); /* read (x,y,z) coordinates */

    cs = lint3d_make(ns,ss,fdm);
    cr = lint3d_make(nr,rr,fdm);

    fdbell3d_init(1);
    /*------------------------------------------------------------*/
    /* setup FD coefficients */
    dt2 = dt*dt;
    id1 = 1/d1;
    id2 = 1/d2;
    id3 = 1/d3;

    c1x = C1*id2;
    c1y = C1*id3;
    c1z = C1*id1;

    c2x = C2*id2;
    c2y = C2*id3;
    c2z = C2*id1;

    c3x = C3*id2;
    c3y = C3*id3;
    c3z = C3*id1;

    /*------------------------------------------------------------*/
    /* input density */
    roin = sf_floatalloc3(n1, n2, n3);
    ro   = sf_floatalloc3(fdm->nzpad, fdm->nxpad, fdm->nypad);
    iro  = sf_floatalloc3(fdm->nzpad, fdm->nxpad, fdm->nypad);

    sf_floatread(roin[0][0],n1*n2*n3,Fden);
    expand3d(roin,ro,fdm);

    /* inverse density to avoid computation on the fly */
    /*
    there is 1 shell for i1=0 || i2=0 || i3=0 that is zero,
    no big deal but better to fix it
    */
    for 		(i3=1; i3<fdm->nypad; i3++) {
        for 	(i2=1; i2<fdm->nxpad; i2++) {
            for (i1=1; i1<fdm->nzpad; i1++) {
                iro[i3][i2][i1] = 6./(  3*ro[i3  ][i2  ][i1  ] +
                                        ro[i3  ][i2  ][i1-1] +
                                        ro[i3  ][i2-1][i1  ] +
                                        ro[i3-1][i2  ][i1  ] );
            }
        }
    }

    free(**roin);
    free(*roin);
    free(roin);

    /*------------------------------------------------------------*/
    /* input velocity */
    vpin = sf_floatalloc3(n1, n2, n3);
    vp   = sf_floatalloc3(fdm->nzpad, fdm->nxpad, fdm->nypad);
    vt   = sf_floatalloc3(fdm->nzpad, fdm->nxpad, fdm->nypad);
    sf_floatread(vpin[0][0],n1*n2*n3,Fvel);
    expand3d(vpin,vp,fdm);
    free(**vpin);
    free(*vpin);
    free(vpin);

    /*------------------------------------------------------------*/
    /* input reflectivity */
    rfin = sf_floatalloc3(n1, n2, n3);
    rf   = sf_floatalloc3(fdm->nzpad, fdm->nxpad, fdm->nypad);
    sf_floatread(rfin[0][0],n1*n2*n3,Fref);
    expand3d(rfin,rf,fdm);
    free(**rfin);
    free(*rfin);
    free(rfin);

    for 		(i3=0; i3<fdm->nypad; i3++) {
        for 	(i2=0; i2<fdm->nxpad; i2++) {
            for (i1=0; i1<fdm->nzpad; i1++) {
                vt[i3][i2][i1] = vp[i3][i2][i1] * vp[i3][i2][i1] * dt2;
            }
        }
    }

    /* free surface */
    if(fsrf) {
        fsrfbck = sf_floatalloc3(4*NOP, fdm->nxpad, fdm->nypad);
        fsrfsct = sf_floatalloc3(4*NOP, fdm->nxpad, fdm->nypad);
    }
    /*------------------------------------------------------------*/
    /* allocate wavefield arrays */
    bum  = sf_floatalloc3(fdm->nzpad, fdm->nxpad, fdm->nypad);
    buo  = sf_floatalloc3(fdm->nzpad, fdm->nxpad, fdm->nypad);
    bup  = sf_floatalloc3(fdm->nzpad, fdm->nxpad, fdm->nypad);
    bua  = sf_floatalloc3(fdm->nzpad, fdm->nxpad, fdm->nypad);
    buat = sf_floatalloc3(fdm->nzpad, fdm->nxpad, fdm->nypad);

    sum  = sf_floatalloc3(fdm->nzpad, fdm->nxpad, fdm->nypad);
    suo  = sf_floatalloc3(fdm->nzpad, fdm->nxpad, fdm->nypad);
    sup  = sf_floatalloc3(fdm->nzpad, fdm->nxpad, fdm->nypad);
    sua  = sf_floatalloc3(fdm->nzpad, fdm->nxpad, fdm->nypad);
    suat = sf_floatalloc3(fdm->nzpad, fdm->nxpad, fdm->nypad);

    for 		(i3=0; i3<fdm->nypad; i3++) {
        for 	(i2=0; i2<fdm->nxpad; i2++) {
            for (i1=0; i1<fdm->nzpad; i1++) {
                bum[i3][i2][i1]=0;
                buo[i3][i2][i1]=0;
                bup[i3][i2][i1]=0;
                bua[i3][i2][i1]=0;

                sum[i3][i2][i1]=0;
                suo[i3][i2][i1]=0;
                sup[i3][i2][i1]=0;
                sua[i3][i2][i1]=0;
            }
        }
    }

    /*------------------------------------------------------------*/
    /* one-way abc setup */
    abc = abcone3d_make(NOP,dt,vp,fsrf,fdm);
    /* sponge abc setup */
    spo = sponge_make(fdm->nb);

    free(**vp);
    free(*vp);
    free(vp);
    /*--------------------------------------------------------------*/
    /* 																*/
    /*						MAIN LOOP								*/
    /*																*/
    /*--------------------------------------------------------------*/
    if(verb) fprintf(stderr,"\nFORWARD BORN ACOUSTIC VARIABLE-DENSITY WAVE EXTRAPOLATION \n");
    /* extrapolation */
    start_t = clock();
    for (it=0; it<nt; it++) {
        if(verb) fprintf(stderr,"%d/%d  \r",it,nt);

#ifdef _OPENMP
        #pragma omp parallel private(i3,i2,i1)
#endif
        {

            if (fsrf) {
                /* free surface */
#ifdef _OPENMP
                #pragma omp for schedule(dynamic,fdm->ompchunk)
#endif
                for 		(i3=0; i3<fdm->nypad; i3++) {
                    for 	(i2=0; i2<fdm->nxpad; i2++) {
                        for (i1=nb; i1<nb+2*NOP; i1++) {
                            fsrfbck[i3][i2][2*NOP+(i1-nb)  ] =  buo[i3][i2][i1];
                            fsrfbck[i3][i2][2*NOP-(i1-nb)-1] = -buo[i3][i2][i1];

                            fsrfsct[i3][i2][2*NOP+(i1-nb)  ] =  suo[i3][i2][i1];
                            fsrfsct[i3][i2][2*NOP-(i1-nb)-1] = -suo[i3][i2][i1];
                        }
                    }
                }
            }


            // spatial derivatives z
#ifdef _OPENMP
            #pragma omp for schedule(dynamic,fdm->ompchunk)
#endif
            for 		(i3=NOP; i3<fdm->nypad-NOP; i3++) {
                for 	(i2=NOP; i2<fdm->nxpad-NOP; i2++) {
                    for (i1=NOP; i1<fdm->nzpad-NOP; i1++) {

                        // gather
                        buat[i3][i2][i1]  = iro[i3][i2][i1]*(
                                                c3z*(buo[i3][i2][i1+2] - buo[i3][i2][i1-3]) +
                                                c2z*(buo[i3][i2][i1+1] - buo[i3][i2][i1-2]) +
                                                c1z*(buo[i3][i2][i1  ] - buo[i3][i2][i1-1])
                                            );

                        suat[i3][i2][i1]  = iro[i3][i2][i1]*(
                                                c3z*(suo[i3][i2][i1+2] - suo[i3][i2][i1-3]) +
                                                c2z*(suo[i3][i2][i1+1] - suo[i3][i2][i1-2]) +
                                                c1z*(suo[i3][i2][i1  ] - suo[i3][i2][i1-1])
                                            );
                    }
                }
            }

            if (fsrf) {
                // free surface
#ifdef _OPENMP
                #pragma omp for schedule(dynamic,fdm->ompchunk)
#endif
                for 		(i3=NOP; i3<fdm->nypad-NOP; i3++) {
                    for 	(i2=NOP; i2<fdm->nxpad-NOP; i2++) {
                        for (i1=nb-NOP; i1<nb+NOP; i1++) {

                            buat[i3][i2][i1]  = iro[i3][i2][i1]*(
                                                    c3z*(fsrfbck[i3][i2][2*NOP+(i1-nb)+2] - fsrfbck[i3][i2][2*NOP+(i1-nb)-3]) +
                                                    c2z*(fsrfbck[i3][i2][2*NOP+(i1-nb)+1] - fsrfbck[i3][i2][2*NOP+(i1-nb)-2]) +
                                                    c1z*(fsrfbck[i3][i2][2*NOP+(i1-nb)  ] - fsrfbck[i3][i2][2*NOP+(i1-nb)-1])
                                                );

                            suat[i3][i2][i1]  = iro[i3][i2][i1]*(
                                                    c3z*(fsrfsct[i3][i2][2*NOP+(i1-nb)+2] - fsrfsct[i3][i2][2*NOP+(i1-nb)-3]) +
                                                    c2z*(fsrfsct[i3][i2][2*NOP+(i1-nb)+1] - fsrfsct[i3][i2][2*NOP+(i1-nb)-2]) +
                                                    c1z*(fsrfsct[i3][i2][2*NOP+(i1-nb)  ] - fsrfsct[i3][i2][2*NOP+(i1-nb)-1])
                                                );
                        }
                    }
                }
            }


#ifdef _OPENMP
            #pragma omp for schedule(dynamic,fdm->ompchunk)
#endif
            for 		(i3=NOP; i3<fdm->nypad-NOP; i3++) {
                for 	(i2=NOP; i2<fdm->nxpad-NOP; i2++) {
                    for (i1=NOP; i1<fdm->nzpad-NOP; i1++) {
                        // scatter
                        bua[i3][i2][i1] = c1z*(	buat[i3][i2][i1  ] -
                                                buat[i3][i2][i1+1]) +
                                          c2z*(	buat[i3][i2][i1-1] -
                                                  buat[i3][i2][i1+2]) +
                                          c3z*(	buat[i3][i2][i1-2] -
                                                  buat[i3][i2][i1+3]);

                        sua[i3][i2][i1] = c1z*(	suat[i3][i2][i1  ] -
                                                suat[i3][i2][i1+1]) +
                                          c2z*(	suat[i3][i2][i1-1] -
                                                  suat[i3][i2][i1+2]) +
                                          c3z*(	suat[i3][i2][i1-2] -
                                                  suat[i3][i2][i1+3]);
                    }
                }
            }

            // spatial derivatives x
#ifdef _OPENMP
            #pragma omp for schedule(dynamic,fdm->ompchunk)
#endif
            for 		(i3=NOP; i3<fdm->nypad-NOP; i3++) {
                for 	(i2=NOP; i2<fdm->nxpad-NOP; i2++) {
                    for (i1=NOP; i1<fdm->nzpad-NOP; i1++) {
                        // gather
                        buat[i3][i2][i1]  = iro[i3][i2][i1]*(
                                                c3x*(buo[i3][i2+2][i1] - buo[i3][i2-3][i1]) +
                                                c2x*(buo[i3][i2+1][i1] - buo[i3][i2-2][i1]) +
                                                c1x*(buo[i3][i2  ][i1] - buo[i3][i2-1][i1])
                                            );

                        suat[i3][i2][i1]  = iro[i3][i2][i1]*(
                                                c3x*(suo[i3][i2+2][i1] - suo[i3][i2-3][i1]) +
                                                c2x*(suo[i3][i2+1][i1] - suo[i3][i2-2][i1]) +
                                                c1x*(suo[i3][i2  ][i1] - suo[i3][i2-1][i1])
                                            );
                    }
                }
            }

#ifdef _OPENMP
            #pragma omp for schedule(dynamic,fdm->ompchunk)
#endif
            for 		(i3=NOP; i3<fdm->nypad-NOP; i3++) {
                for 	(i2=NOP; i2<fdm->nxpad-NOP; i2++) {
                    for (i1=NOP; i1<fdm->nzpad-NOP; i1++) {
                        // scatter
                        bua[i3][i2  ][i1] += c1x*(buat[i3][i2  ][i1] -
                                                  buat[i3][i2+1][i1]) +
                                             c2x*(buat[i3][i2-1][i1] -
                                                  buat[i3][i2+2][i1]) +
                                             c3x*(buat[i3][i2-2][i1] -
                                                  buat[i3][i2+3][i1]);

                        sua[i3][i2  ][i1] += c1x*(suat[i3][i2  ][i1] -
                                                  suat[i3][i2+1][i1]) +
                                             c2x*(suat[i3][i2-1][i1] -
                                                  suat[i3][i2+2][i1]) +
                                             c3x*(suat[i3][i2-2][i1] -
                                                  suat[i3][i2+3][i1]);
                    }
                }
            }

            // spatial derivatives y
#ifdef _OPENMP
            #pragma omp for schedule(dynamic,fdm->ompchunk)
#endif
            for 		(i3=NOP; i3<fdm->nypad-NOP; i3++) {
                for 	(i2=NOP; i2<fdm->nxpad-NOP; i2++) {
                    for (i1=NOP; i1<fdm->nzpad-NOP; i1++) {
                        // gather
                        buat[i3][i2][i1]  = iro[i3][i2][i1]*(
                                                c3x*(buo[i3+2][i2][i1] - buo[i3-3][i2][i1]) +
                                                c2x*(buo[i3+1][i2][i1] - buo[i3-2][i2][i1]) +
                                                c1x*(buo[i3  ][i2][i1] - buo[i3-1][i2][i1])
                                            );

                        suat[i3][i2][i1]  = iro[i3][i2][i1]*(
                                                c3x*(suo[i3+2][i2][i1] - suo[i3-3][i2][i1]) +
                                                c2x*(suo[i3+1][i2][i1] - suo[i3-2][i2][i1]) +
                                                c1x*(suo[i3  ][i2][i1] - suo[i3-1][i2][i1])
                                            );
                    }
                }
            }

#ifdef _OPENMP
            #pragma omp for schedule(dynamic,fdm->ompchunk)
#endif
            for 		(i3=NOP; i3<fdm->nypad-NOP; i3++) {
                for 	(i2=NOP; i2<fdm->nxpad-NOP; i2++) {
                    for (i1=NOP; i1<fdm->nzpad-NOP; i1++) {
                        // scatter
                        bua[i3][i2][i1] += c1y*(buat[i3  ][i2][i1] -
                                                buat[i3+1][i2][i1]) +
                                           c2y*(	buat[i3-1][i2][i1] -
                                                   buat[i3+2][i2][i1]) +
                                           c3y*(	buat[i3-2][i2][i1] -
                                                   buat[i3+3][i2][i1]);

                        sua[i3][i2][i1] += c1y*(suat[i3  ][i2][i1] -
                                                suat[i3+1][i2][i1]) +
                                           c2y*(	suat[i3-1][i2][i1] -
                                                   suat[i3+2][i2][i1]) +
                                           c3y*(	suat[i3-2][i2][i1] -
                                                   suat[i3+3][i2][i1]);
                    }
                }
            }

            /* step forward in time */
#ifdef _OPENMP
            #pragma omp for schedule(dynamic,fdm->ompchunk)
#endif
            for 		(i3=NOP; i3<fdm->nypad-NOP; i3++) {
                for 	(i2=NOP; i2<fdm->nxpad-NOP; i2++) {
                    for (i1=NOP; i1<fdm->nzpad-NOP; i1++) {
                        bup[i3][i2][i1] = 2*buo[i3][i2][i1]
                                          -					bum[i3][i2][i1]
                                          -					ro[i3][i2][i1]*vt[i3][i2][i1]*bua[i3][i2][i1];

                        sup[i3][i2][i1] = 2*suo[i3][i2][i1]
                                          -					sum[i3][i2][i1]
                                          -					ro[i3][i2][i1]*vt[i3][i2][i1]*sua[i3][i2][i1];

                    }
                }
            }

            /* single scattering */
#ifdef _OPENMP
            #pragma omp for schedule(dynamic,ompchunk)
#endif
            for 		(i3=NOP; i3<fdm->nypad-NOP; i3++) {
                for 	(i2=NOP; i2<fdm->nxpad-NOP; i2++) {
                    for (i1=NOP; i1<fdm->nzpad-NOP; i1++) {
                        sup[i3][i2][i1] -= 2*rf[i3][i2][i1]*ro[i3][i2][i1]*bua[i3][i2][i1]*dt2;
                    }
                }
            }



        }	/* end of the parallel section */

        /* inject acceleration source */
        sf_floatread(ww,ns,Fwav);
        lint3d_bell(bup,ww,cs);

        /* extract data */
        lint3d_extract(bup,bdd,cr);
        lint3d_extract(sup,sdd,cr);

        if(snap && it%jsnap==0) {
            cut3d(bup,uc,fdm,ac1,ac2,ac3);
            sf_floatwrite(uc[0][0],sf_n(ac1)*sf_n(ac2)*sf_n(ac3),Fwfl);

            cut3d(sup,uc,fdm,ac1,ac2,ac3);
            sf_floatwrite(uc[0][0],sf_n(ac1)*sf_n(ac2)*sf_n(ac3),Fliw);
        }
        if(        it%jdata==0) {
            sf_floatwrite(bdd,nr,Fdat);
            sf_floatwrite(sdd,nr,Flid);
        }

        /* one-way abc apply*/
        if (dabc) {
            abcone3d_apply(bup,buo,NOP,abc,fdm);
            sponge3d_apply(bup,        spo,fdm);
            sponge3d_apply(buo,        spo,fdm);

            abcone3d_apply(sup,suo,NOP,abc,fdm);
            sponge3d_apply(sup,        spo,fdm);
            sponge3d_apply(suo,        spo,fdm);
        }

        /* circulate wavefield arrays */
        but=bum;
        bum=buo;
        buo=bup;
        bup=but;

        sut=sum;
        sum=suo;
        suo=sup;
        sup=sut;

    } /* end time loop */
    end_t = clock();
    if(verb) fprintf(stderr,"\n");

    if (verb) {
        total_t = (float)(end_t - start_t) / CLOCKS_PER_SEC;
        fprintf(stderr,"Total time taken by CPU: %g\n", total_t  );
        fprintf(stderr,"Exiting of the program...\n");
    }


    /*------------------------------------------------------------*/
    /* deallocate arrays */
    free(**bum);
    free(*bum);
    free(bum);
    free(**buo);
    free(*buo);
    free(buo);
    free(**bup);
    free(*bup);
    free(bup);
    free(**bua);
    free(*bua);
    free(bua);
    free(**buat);
    free(*buat);
    free(buat);

    free(**sum);
    free(*sum);
    free(sum);
    free(**suo);
    free(*suo);
    free(suo);
    free(**sup);
    free(*sup);
    free(sup);
    free(**sua);
    free(*sua);
    free(sua);
    free(**suat);
    free(*suat);
    free(suat);

    if(snap) {
        free(**uc);
        free(*uc);
        free(uc);
    }

    if (fsrf) {
        free(**fsrfbck);
        free(*fsrfbck);
        free(fsrfbck);
        free(**fsrfsct);
        free(*fsrfsct);
        free(fsrfsct);
    }

    free(**vt);
    free(*vt);
    free(vt);

    free(**ro);
    free(*ro);
    free(ro);
    free(**iro);
    free(*iro);
    free(iro);

    free(**rf);
    free(*rf);
    free(rf);

    free(ww);
    free(ss);
    free(rr);

    free(bdd);
    free(sdd);

    if (dabc) {
        free(spo);
        free(abc);
    }
    free(fdm);
    /* ------------------------------------------------------------------------------------------ */
    /* CLOSE FILES AND EXIT */
    if (Fwav!=NULL) sf_fileclose(Fwav);

    if (Fsou!=NULL) sf_fileclose(Fsou);
    if (Frec!=NULL) sf_fileclose(Frec);

    if (Fvel!=NULL) sf_fileclose(Fvel);
    if (Fden!=NULL) sf_fileclose(Fden);

    if (Fref!=NULL) sf_fileclose(Fref);

    if (Fdat!=NULL) sf_fileclose(Fdat);

    if (Fwfl!=NULL) sf_fileclose(Fwfl);

    if (Fliw!=NULL) sf_fileclose(Fliw);
    if (Flid!=NULL) sf_fileclose(Flid);

    exit (0);
}
コード例 #7
0
ファイル: MG_autofocus_toto.c プロジェクト: ediaz/toto-stuff
	int main(int argc, char* argv[])
	{

		bool verb,conj,twin,Pf1,PG;
		
	    /* OMP parameters */
		#ifdef _OPENMP
	    int ompnth;
		#endif 	
		
		float	*F_arrival, *Refl, *G, *Gm, *Gp, *f1pS, *f1p, *F1pS, *F1p;
		float	*MS, *MS1, *F1m_0, *f1m_0, *F1m, *F1m1, *f1m, *ms, *gm, *gp;
    float *MS_0, *ms_0, *ms_2, *MS2;
    float *gp1, *gm1;
		float	*window, *taper, pi;
		int		*tw,allocated=0;

	    /* I/O files */
	    sf_file FF_arrival;
	    sf_file FRefl;
	    sf_file FGp;
	    sf_file FGm;
	    sf_file FG;
	    sf_file Ff1m;
	    sf_file Ff1p;
	    sf_file Ftwin;

		char *filename1, filename2[256], filename3[256];
		
		/* Cube axes */
	    sf_axis at,af,ax,at1;

	    int     nt,nf,ntr,mode,nshots,niter,len;
	    int     i,it,ix,ishot,iter,i0;
	    int		twc, twa, shift, n[2], rect[2], s[2], tap;
	    float   scale,eps,dt,df,dx,ot,of,a,b,c,d,e,f,r;

		sf_triangle tr;

	    /*------------------------------------------------------------*/
	    /* Initialize RSF parameters 								  */
	    /*------------------------------------------------------------*/
	    sf_init(argc,argv);	
		
	    /*------------------------------------------------------------*/
	    /* Initialize OMP parameters */
	    /*------------------------------------------------------------*/
		#ifdef _OPENMP
	    ompnth=omp_init();
		#endif	

		/*------------------------------------------------------------*/
		/* Flags 													  */
		/*------------------------------------------------------------*/
	    if(! sf_getbool("verb",&verb)) verb=false; /* verbosity flag */
	    if(! sf_getbool("conj",&conj)) conj=false; /* complex conjugation (time-reversal) flag */
	    if(! sf_getbool("twin",&twin)) twin=false; /* returns the timewindow as one of the outputs */
	    if(! sf_getbool("Pf1",&Pf1)) Pf1=false; /* Htot=true: returns H=Gp-Gm */
	    if(! sf_getbool("PG",&PG)) PG=false; /* Htot=true: returns H=Gp-Gm */
	    if(! sf_getint("niter",&niter)) niter=1; /* number of iterations */
	    if(! sf_getint("nshots",&nshots)) nshots=1; /* number of shots */
	    if(! sf_getfloat("r",&r)) r=-1; /* reflection coefficient if flux 
						normalised r=-1 */
	    if(! sf_getfloat("scale",&scale)) scale=1.0; /* scale factor */
		if(! sf_getfloat("eps",&eps)) eps=1e-4; /* threshold for the timewindow */
		if(! sf_getint("shift",&shift)) shift=5; /* shift in samples for the timewindow */
		if(! sf_getint("tap",&tap)) tap=20; /* taper of R */
	    
		if (verb) {
			fprintf(stderr,"This program was called with \"%s\".\n",argv[0]);
			/*fprintf(stderr,"Nr: %d Nx: %d Nt:%d\n",nr,nx,nt);*/
			
			if (argc > 1) {
				for (i = 1; i<argc; i++) {
					fprintf(stderr,"argv[%d] = %s\n", i, argv[i]);
				}
			}
			else {
				fprintf(stderr,"The command had no other arguments.\n");
		}	
		}

	    /*------------------------------------------------------------*/
	    /* I/O files 												  */
	    /*------------------------------------------------------------*/	
		/* "in" is the transposed version of p00plus_xxxx_xxxx.rsf
		   Dimensions of p00plus_xxxx_xxxx.rsf BEFORE sftransp: n1=ntr,n2=nt
		   Dimensions of p00plus_xxxx_xxxx.rsf BEFORE sftransp: n1=nt,n2=ntr */
		FF_arrival = sf_input("in");
		
		/* refl is REFL_000.rsf
		   It is used to read nf, df, of
		  Dimensions are: n1=nf,n2=ntr */
		/*FRefl = (sf_file)sf_alloc(1,sizeof(sf_file));*/	
		FRefl = sf_input("refl");

		FGp = sf_output("out");
		FGm = sf_output("Gm");
		
		if (PG) {
			FG  = sf_output("G");
		}
		if (Pf1) {
			Ff1p  = sf_output("f1p");
			Ff1m  = sf_output("f1m");
		}
		
		if (twin) {
			Ftwin = sf_output("window"); /* time window */
		}
		
		/*------------------------------------------------------------*/
		/* Axes */
		/*------------------------------------------------------------*/    
		at = sf_iaxa(FF_arrival,1); sf_setlabel(at,"Time"); if(verb) sf_raxa(at); /* time */
		at1 = sf_iaxa(FF_arrival,1); sf_setlabel(at,"Time"); if(verb) sf_raxa(at); /* time */
		af = sf_iaxa(FRefl,1); sf_setlabel(af,"Frequency"); if(verb) sf_raxa(af); /* frequency */
		ax = sf_iaxa(FF_arrival,2); sf_setlabel(ax,"r"); if(verb) sf_raxa(ax); /* space */
	    
		nt = sf_n(at); dt = sf_d(at); ot = sf_o(at);
		nf = sf_n(af); df = sf_d(af); of = sf_o(af);
		ntr = sf_n(ax); dx = sf_d(ax);

    int nt2=(nt/2);
    sf_setn(at1,nt2);


		if (verb) fprintf(stderr,"nt: %d nf: %d ntr:%d\n",nt,nf,ntr);

		sf_fileclose(FRefl);

	    /*------------------------------------------------------------*/
	    /* Setup output data and wavefield header					  */
	    /*------------------------------------------------------------*/
		sf_oaxa(FGp,at1,1);
		sf_oaxa(FGp,ax,2);
		sf_oaxa(FGm,at1,1);
		sf_oaxa(FGm,ax,2);
		
		if (PG) {
			sf_oaxa(FG,at1,1);
			sf_oaxa(FG,ax,2);
		}
		if (Pf1) {
			sf_oaxa(Ff1p,at,1);
			sf_oaxa(Ff1p,ax,2);
			sf_oaxa(Ff1m,at,1);
			sf_oaxa(Ff1m,ax,2);
		}
		if (twin) {
			sf_oaxa(Ftwin,at,1);
			sf_oaxa(Ftwin,ax,2);
		}

	    /*------------------------------------------------------------*/
	    /* Allocate arrays											  */
	    /*------------------------------------------------------------*/
		/* First arrival - Time */
		F_arrival = (float *)calloc(nt*ntr,sizeof(float)); allocated+=nt*ntr;
		sf_floatread(F_arrival,nt*ntr,FF_arrival);
		ms   = (float *)calloc(nt*ntr,sizeof(float));allocated+=nt*ntr;
		ms_0 = (float *)calloc(nt*ntr,sizeof(float));allocated+=nt*ntr;
		ms_2 = (float *)calloc(nt*ntr,sizeof(float));allocated+=nt*ntr;
		f1m_0= (float *)calloc(nt*ntr,sizeof(float));allocated+=nt*ntr;
		f1m  = (float *)calloc(nt*ntr,sizeof(float));allocated+=nt*ntr;
		f1pS = (float *)calloc(nt*ntr,sizeof(float));allocated+=nt*ntr;
		f1p  = (float *)calloc(nt*ntr,sizeof(float));allocated+=nt*ntr;
		memcpy(ms,F_arrival,nt*ntr*sizeof(float));allocated+=nt*ntr;

		/* Allocate for coda M of f2 - Frequency */
		MS   = (float *)calloc(2*nf*ntr,sizeof(float));allocated+=2*nf*ntr;
		MS_0 = (float *)calloc(2*nf*ntr,sizeof(float));allocated+=2*nf*ntr;
		MS1  = (float *)calloc(2*nf*ntr,sizeof(float));allocated+=2*nf*ntr;
		MS2  = (float *)calloc(2*nf*ntr,sizeof(float));allocated+=2*nf*ntr;
		F1m_0= (float *)calloc(2*nf*ntr,sizeof(float));allocated+=2*nf*ntr;
		F1m  = (float *)calloc(2*nf*ntr,sizeof(float));allocated+=2*nf*ntr;
		F1m1 = (float *)calloc(2*nf*ntr,sizeof(float));allocated+=2*nf*ntr;
		F1pS = (float *)calloc(2*nf*ntr,sizeof(float));allocated+=2*nf*ntr;
		F1p  = (float *)calloc(2*nf*ntr,sizeof(float));allocated+=2*nf*ntr;
		/* The three flags of fft1 are: inv, sym, and opt */

    fft1_init (nt, dt, ot, true, false);
    fft1_2D_fwd(F_arrival,MS,ntr);
    //sf_warning("passed fft? yes");
		//fft1(F_arrival,MS,FF_arrival,0,0,1);
	/*	memcpy(FA,2*nf*ntr*sizeof(float));*/

    fprintf(stderr,"nt2 is %d\n",nt2);
		/* Output wavefields */
		G = (float *)calloc(nt2*ntr,sizeof(float));allocated+=nt2*ntr;
		gp1= (float *)calloc(nt*ntr,sizeof(float));allocated+=nt*ntr;
		gp= (float *)calloc(nt2*ntr,sizeof(float));allocated+=nt2*ntr;
		gm1= (float *)calloc(nt*ntr,sizeof(float));allocated+=nt*ntr;
		gm= (float *)calloc(nt2*ntr,sizeof(float));allocated+=nt2*ntr;
		Gp= (float *)calloc(2*nf*ntr,sizeof(float));allocated+=nf*ntr;
		Gm= (float *)calloc(2*nf*ntr,sizeof(float));allocated+=nf*ntr;


		
		/* Time-reversal flag */
		if (conj) {
			mode = -1;
		}
		else {
			mode = +1;
		}
	    
		/* Load the reflection response into the memory */
		if (verb) fprintf(stderr,"Before loading R %d\n",2*nf*ntr);
		Refl = (float *)calloc(2*nf*ntr*nshots,sizeof(float));allocated+=2*nf*ntr*nshots;
		
		/* Read REFL_000.rsf */
    FRefl = sf_input("refl");
    sf_warning("reading refl");
    sf_floatread(Refl,2*nf*nshots*ntr,FRefl); 
    sf_warning("read refl");

		/* Build time-window */
		tw = (int *)calloc(ntr,sizeof(int)); allocated+=ntr;
		window = (float *)calloc(nt*ntr,sizeof(float));allocated+=nt*ntr;
		/*memset(window,0,nt*ntr*sizeof(float));*/
	    /* I am not sure why I set it to this value */
		/*for (ix=0; ix<ntr; ix++) {
			tw[ix] = nt*dt+ot+0.15; 
		}*/
		
		if (verb) fprintf(stderr,"---> Build time-window?\n");
    // checking time sample corresponding to muting time
		for (ix=0; ix<ntr; ix++) {
      for (it=0; it<nt; it++) {
        if ((F_arrival[it+ix*nt]*F_arrival[it+ix*nt])>eps*eps) {
          /*tw[ix] = it*dt+ot;*/
          tw[ix] = it;
          break;
        }
			}
		}

		if (verb) fprintf(stderr,"---> Build time-window1\n");
		for (ix=0; ix<ntr; ix++) {
			twc = (int)(tw[ix]-shift-10);
			twa = (int)(-twc+nt);
			/*if (verb) fprintf(stderr,"%d %d\n",twc,twa);*/
			for (it=0; it<nt; it++) {
			/*	if ((it>twa) || (it<twc)) {*/
				if ((it>twa) && (it<twc)) { 
					window[it+ix*nt] = 1.0; // building windowing function W from Filippo's paper
				}
			}
		}

		if (verb) fprintf(stderr,"---> Build time-window2\n");
		/* Smoothing of the window */
		/* Should I implement flags for rect and iter? */
		/* Look at Msmooth.c to understand below */
		n[0] = nt;
		n[1] = ntr;
		s[0] = 1;
		s[1] = nt;
		rect[0] = 5;
		rect[1] = 5;

		for (ix=0; ix <= 1; ix++) {
			if (rect[ix] <= 1) continue;
			tr = sf_triangle_init (rect[ix],n[ix],false);
			for (it=0; it < (nt*ntr/n[ix]); it++) {
				i0 = sf_first_index (ix,it,1+1,n,s);
				for (iter=0; iter < 2; iter++) {
					sf_smooth2 (tr,i0,s[ix],false,window );
				}
			}
			sf_triangle_close(tr);
		}
		if (verb) fprintf(stderr,"---> Here\n");
		
		/* Tapering */
		pi = 4.0*atan(1.0);
		
		taper = (float *)calloc(ntr,sizeof(float));allocated+=ntr;
    sf_warning("estimated memory: %f bytes",allocated*4.0f);

		memset(taper,0,ntr*sizeof(float));

		for (ix=0; ix<tap; ix++) {
			taper[ix] = (float)(0.5*(1.0-cos(2.0*pi*(ix-0.0)/(2*tap))));
			taper[ntr-ix-1] = taper[ix];
		}
		for (ix=tap; ix<(ntr-tap); ix++) {
			taper[ix] = 1.0;
		}
		if (verb) fprintf(stderr,"---> taper finish\n");
		
		FRefl = sf_input("refl");

		/*------------------------------------------------------------*/
		/* Loop over iterations */
		/*------------------------------------------------------------*/
		if (verb) fprintf(stderr,"---> Begin to iterative solve for f1p and f1m\n");
		/*starting iteration for f1m */
		memset(F1m_0,0,2*nf*ntr*sizeof(float));

			for (ishot=0; ishot<nshots; ishot++) {

				/* Loop over receivers (traces) */
				#ifdef _OPENMP
				#pragma omp parallel for private(ix,it,a,b,c,d) \
					shared(MS,taper,Refl,F1m_0,MS2)
				#endif
				for (ix=0; ix<ntr; ix++) {
					/* Loop over frequencies */
					#pragma ivdep
					for (it=0; it<2*nf; it=it+2) {

						/*(a + bi)(c + di) = (ac - bd) + (ad + bc)i*/
						a = Refl[ix*2*nf+it+ishot*2*nf*ntr]*taper[ishot];
						b = Refl[ix*2*nf+it+1+ishot*2*nf*ntr]*taper[ishot];
						c = MS[ishot*2*nf+it];
						d = MS[ishot*2*nf+it+1];

						F1m_0[ix*2*nf+it]   += (a*c - mode*b*d);
						F1m_0[ix*2*nf+it+1] += (mode*a*d + b*c);
						MS2  [ix*2*nf+it]   += r*(a*c - b*d); // rTd* R
						MS2  [ix*2*nf+it+1] += r*(a*d + b*c);

					} /* End of loop over frequencies */
				} /* End of loop over receivers (traces) */
			}

      fft1_2D_inv (F1m_0, f1m_0,ntr);
      fft1_2D_inv (MS2, ms_2,ntr);

			#ifdef _OPENMP
			#pragma omp parallel for private(ix,it) \
				shared(f1m, f1m_0, window,ms_2)
			#endif
			/* window to get f1m_0 */
			for (ix=0; ix<ntr; ix++) {
				#pragma ivdep
				for (it=0; it<nt; it++) {
					f1m_0[it+ix*nt] = scale*window[it+ix*nt]*f1m_0[it+ix*nt];  
					ms_2[it+ix*nt] = scale*window[it+ix*nt]*ms_2[it+ix*nt];  
					//f1m_0[it+ix*nt] = scale*f1m_0[it+ix*nt];  
					f1m[it+ix*nt] = f1m_0[it+ix*nt];
				}	
			}
		  fft1_2D_fwd(f1m,F1m,ntr);
	
			//fft1(f1m,F1m,FF_arrival,0,0,1);


	/* initialise MS the coda for f1+ */
		memset(MS_0,0,2*nf*ntr*sizeof(float));
		memset(MS,0,2*nf*ntr*sizeof(float));

			for (ishot=0; ishot<nshots; ishot++) {

				/* Loop over receivers (traces) */
				#ifdef _OPENMP
				#pragma omp parallel for private(ix,it,a,b,c,d) \
					shared(MS_0,taper,Refl,F1m)
				#endif
				for (ix=0; ix<ntr; ix++) {
					/* Loop over frequencies */
					#pragma ivdep
					for (it=0; it<2*nf; it=it+2) {

						/*(a + bi)(c + di) = (ac - bd) + (ad + bc)i*/
						a = Refl[ix*2*nf+it+ishot*2*nf*ntr]*taper[ishot];
						b = Refl[ix*2*nf+it+1+ishot*2*nf*ntr]*taper[ishot];
						c = F1m[ishot*2*nf+it];
						d = F1m[ishot*2*nf+it+1];

						MS_0[ix*2*nf+it]   += (a*c - mode*b*d);
						MS_0[ix*2*nf+it+1] += (mode*a*d + b*c);

					} /* End of loop over frequencies */
				} /* End of loop over receivers (traces) */
			}

		  fft1_2D_inv(MS_0,ms_0,ntr);
			//fft1(MS_0,ms_0,FRefl,1,0,1);

			#ifdef _OPENMP
			#pragma omp parallel for private(ix,it) \
				shared(ms, ms_0, window,ms_2)
			#endif
			/* window to get f1m_0 */
			for (ix=0; ix<ntr; ix++) {
				#pragma ivdep
				for (it=0; it<nt; it++) {
					ms[it+ix*nt] =-ms_2[it+ix*nt] +scale*window[it+ix*nt]*ms_0[it+ix*nt];  
					//f1m_0[it+ix*nt] = scale*f1m_0[it+ix*nt];  
				  //ms[it+ix*nt] = ms_0[it+ix*nt];
				}	
			}
			
		  fft1_2D_fwd(ms,MS,ntr);



	if (verb) fprintf(stderr,"---> Beginning Iteration\n");
		for (iter=0; iter<niter; iter++) {

	/* initialise MS1 and f1m1 the coda for f1+ */	
		memset(MS1,0,2*nf*ntr*sizeof(float));
		memset(F1m1,0,2*nf*ntr*sizeof(float));

			/*------------------------------------------------------------*/
			/* Loop over shot positions */
			/*------------------------------------------------------------*/
			for (ishot=0; ishot<nshots; ishot++) {
		
				/* Loop over receivers (traces) */
				#ifdef _OPENMP
				#pragma omp parallel for private(ix,it,a,b,c,d,e,f) \
					shared(MS,taper,Refl,F1m,F1m1)
				#endif 	
				for (ix=0; ix<ntr; ix++) {
					/* Loop over frequencies */
					#pragma ivdep
					for (it=0; it<2*nf; it=it+2) {
						
						/*(a + bi)(c + di) = (ac - bd) + (ad + bc)i*/
						/*(a + bi)(e + fi) = (ae - bf) + (af + be)i*/
						a = Refl[ix*2*nf+it+ishot*2*nf*ntr]*taper[ishot];
						b = Refl[ix*2*nf+it+1+ishot*2*nf*ntr]*taper[ishot];
						c = MS[ishot*2*nf+it];
						d = MS[ishot*2*nf+it+1];
						e = F1m[ishot*2*nf+it];
						f = F1m[ishot*2*nf+it+1];
						
						F1m1[ix*2*nf+it]   += (a*c - mode*b*d) - r*(a*e - b*f);
						F1m1[ix*2*nf+it+1] += (mode*a*d + b*c) - r*(a*f + b*e);
					
					} /* End of loop over frequencies */	
				} /* End of loop over receivers (traces) */
				
			} /* End of loop over shot positions */

			/* Get time domain output of f1m and ms */
		  fft1_2D_inv(F1m1,f1m,ntr);

			
			#ifdef _OPENMP
			#pragma omp parallel for private(ix,it) \
				shared(f1m, f1m_0, window)
			#endif
			for (ix=0; ix<ntr; ix++) {
				#pragma ivdep
				for (it=0; it<nt; it++) {
					f1m[it+ix*nt] = f1m_0[it+ix*nt] + scale*window[it+ix*nt]*(f1m[it+ix*nt]);  
				}	
			}
			
		  fft1_2D_fwd(f1m,F1m,ntr);

			for (ishot=0; ishot<nshots; ishot++) {
		
				/* Loop over receivers (traces) */
				#ifdef _OPENMP
				#pragma omp parallel for private(ix,it,a,b,c,d,e,f) \
					shared(MS,MS1,taper,Refl,F1m)
				#endif 	
				for (ix=0; ix<ntr; ix++) {
					/* Loop over frequencies */
					#pragma ivdep
					for (it=0; it<2*nf; it=it+2) {
						
						/*(a + bi)(c + di) = (ac - bd) + (ad + bc)i*/
						/*(a + bi)(e + fi) = (ae - bf) + (af + be)i*/
						a = Refl[ix*2*nf+it+ishot*2*nf*ntr]*taper[ishot];
						b = Refl[ix*2*nf+it+1+ishot*2*nf*ntr]*taper[ishot];
						c = MS[ishot*2*nf+it];
						d = MS[ishot*2*nf+it+1];
						e = F1m[ishot*2*nf+it];
						f = F1m[ishot*2*nf+it+1];

						MS1[ix*2*nf+it]    += (a*e - mode*b*f) - r*(a*c - b*d);
						MS1[ix*2*nf+it+1]  += (mode*a*f + b*e) - r*(a*d + b*c);
					
					} /* End of loop over frequencies */	
				} /* End of loop over receivers (traces) */
				
			} /* End of loop over shot positions */

			/* Get time domain output of f1m and ms */
		  fft1_2D_inv(MS1,ms,ntr);

			
			#ifdef _OPENMP
			#pragma omp parallel for private(ix,it) \
				shared(ms, window)
			#endif
			for (ix=0; ix<ntr; ix++) {
				#pragma ivdep
				for (it=0; it<nt; it++) {
					ms[it+ix*nt] =-ms_2[it+ix*nt]+ scale*window[it+ix*nt]*(ms[it+ix*nt]);  
				}	
			}
		  fft1_2D_fwd(ms,MS,ntr);

			if(iter%4==0) fprintf(stderr,"Iteration %d\n",iter);

		} /* End of loop over iterations */ 


		/* Build f1p* by adding Tinv to coda M */
		#ifdef _OPENMP
		#pragma omp parallel for private(ix,it) \
			shared(f1pS,F_arrival,ms)
		#endif
		for (ix=0; ix<ntr; ix++) {
			#pragma ivdep
			for (it=0; it<nt; it++) {
				f1pS[it+ix*nt] =  F_arrival[it+ix*nt] + ms[it+ix*nt];
				/* note  this is the time reverse version of f1p */
			}	
		}
		fft1_2D_fwd(f1pS,F1pS,ntr);


	/* to get G by looping over shots */
		memset(Gp,0,2*nf*ntr*sizeof(float));
		memset(Gm,0,2*nf*ntr*sizeof(float));
			for (ishot=0; ishot<nshots; ishot++) {

				/* Loop over receivers (traces) */
				#ifdef _OPENMP
				#pragma omp parallel for private(ix,it,a,b,c,d,e,f) \
					shared(F1pS, F1m, taper, Refl, Gp, Gm)
				#endif
				for (ix=0; ix<ntr; ix++) {
					/* Loop over frequencies */
					#pragma ivdep
					for (it=0; it<2*nf; it=it+2) {

						/*(a + bi)(c + di) = (ac - bd) + (ad + bc)i*/
						a = Refl[ix*2*nf+it+ishot*2*nf*ntr]*taper[ishot];
						b = Refl[ix*2*nf+it+1+ishot*2*nf*ntr]*taper[ishot];
						c = F1pS[ishot*2*nf+it];
						d = F1pS[ishot*2*nf+it+1];
						e = F1m[ishot*2*nf+it];
						f = F1m[ishot*2*nf+it+1];

						Gm[ix*2*nf+it]   += (a*c -mode* b*d) -r*(a*e - b*f);
						Gm[ix*2*nf+it+1] += (mode*a*d + b*c) -r*(a*f + b*e);

						Gp[ix*2*nf+it]   += -(a*e - mode*b*f) + r*(a*c - b*d);
						Gp[ix*2*nf+it+1] += -(mode*a*f + b*e) + r*(a*d + b*c);   
						

					} /* End of loop over frequencies */
				} /* End of loop over receivers (traces) */
			}
		  fft1_2D_inv(Gp,gp1,ntr);
		  fft1_2D_inv(Gp,gm1,ntr);
		if (Pf1) { 
			if (verb) fprintf(stderr,"---> Build f1p\n");
			for (ishot=0; ishot<nshots; ishot++) {

				/* Loop over receivers (traces) */
				#ifdef _OPENMP
				#pragma omp parallel for private(ix,it,c,d) \
					shared(F1pS, F1p)
				#endif
					#pragma ivdep
					for (it=0; it<2*nf; it=it+2) {

						/*(a + bi)(c + di) = (ac - bd) + (ad + bc)i*/
						c = F1pS[ishot*2*nf+it];
						d = F1pS[ishot*2*nf+it+1];

						F1p[ishot*2*nf+it]   =  c;
						F1p[ishot*2*nf+it+1] = -d;   
						

					} /* End of loop over frequencies */
			}
		}
		  fft1_2D_inv(F1p,f1p,ntr);
	 


			if (verb) fprintf(stderr,"Build Gp, Gm and G\n");

		#ifdef _OPENMP
		#pragma omp parallel for private(ix,it) \
			shared(f1m, f1pS, gp, gm, gp1, gm1, G)
		#endif
		for (ix=0; ix<ntr; ix++) {
			#pragma ivdep
			for (it=0; it<nt2; it++) {
				gm[it+ix*nt2] =  ((scale*gm1[it+nt2+ix*nt]) - f1m[ it+nt2+ix*nt])*(1.0 - window[it+nt2+ix*nt]); 	
				gp[it+ix*nt2] =  ((scale*gp1[it+nt2+ix*nt]) + f1pS[it+nt2+ix*nt])*(1.0 - window[it+nt2+ix*nt]); 	
				G[ it+ix*nt2] = 0.5*(gp[it+ix*nt2] +    gm[it+ix*nt2]);
			}
		}

		fprintf(stderr,"Build Gp, Gm and G\n");



		/* Write the final result */
	    /*FRefl = sf_input(argv[1]);*/
		/*fft1(Gp,,FRefl,1,0,0);
		fft1(Gm,,FRefl,1,0,0);*/
		
		sf_floatwrite(gp,nt2*ntr,FGp);
		sf_fileclose(FGp);
		sf_floatwrite(gm,nt2*ntr,FGm);
		sf_fileclose(FGm);
		if (PG) {
			sf_floatwrite(G,nt2*ntr,FG);
			sf_fileclose(FG);
		}
		if (Pf1) {
			sf_floatwrite(f1p,nt*ntr,Ff1p);
			sf_fileclose(Ff1p);
			sf_floatwrite(f1m,nt*ntr,Ff1m);
			sf_fileclose(Ff1m);
		}
		
		if (twin) {
			sf_floatwrite(window,nt*ntr,Ftwin);
		sf_fileclose(Ftwin);
	}
	sf_fileclose(FRefl);
	sf_fileclose(FF_arrival);
	
	free(G);
	free(Gm);
	free(Gp);
	free(Refl);
	free(f1pS);
	free(F1pS);
	free(f1p);
	free(F1p);
	free(tw);
	free(filename1);
	free(MS);
	free(MS_0);
	free(MS1);
	free(MS2);
	free(F1m);
	free(F1m1);
	free(f1m_0);
	free(F1m_0);
	free(f1m);
	free(gp);
	free(gp1);
	free(gm);
	free(gm1);
	free(ms);
	free(ms_0);
	free(ms_2);
	free(F_arrival);
	free(window);
	
    exit (0);
}
コード例 #8
0
ファイル: Mlrosrtm2dbg.c プロジェクト: 1014511134/src
int main(int argc, char* argv[]) 
{
    clock_t tstart,tend;
    double duration;

    /*flag*/
    bool verb;
    bool wantwf;
    bool wantrecord; // actually means "need record"
    
    /*I/O*/
    sf_file Fvel;
    sf_file left, right, leftb, rightb;
    sf_file Fsrc,/*wave field*/ Frcd/*record*/;
    sf_file Ftmpwf, Ftmpbwf;
    sf_file Fimg1, Fimg2;

    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   gp;

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

    /*Data*/
    float ***wavefld;
    sf_complex **record;
    float **img1, **img2;
    int snpint;

    /*source*/
    bool srcdecay;
    int srcrange;
    float srctrunc;
    
    /*abc boundary*/
    int top,bot,lft,rht;

    /*memoray*/
//    float memneed;
    int tmpint;

    tstart = clock();
    sf_init(argc, argv);
    if (!sf_getbool("verb", &verb)) verb=false; /*verbosity*/
    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*/
    Fvel  = sf_input("vel");  /*velocity - just for model dimension*/
    Fsrc  = sf_input("in");   /*source wavelet*/
    if (wantrecord) {
	Frcd   = sf_input("rec");   /*record from elsewhere*/
    } else {
	Frcd   = sf_output("rec");   /*record produced by forward modeling*/
    }
    Fimg1  = sf_output("out");   /*Imaging*/
    Fimg2  = sf_output("img2");  /*Imaging*/

    if (wantwf) {
	Ftmpwf  = sf_output("tmpwf");/*wavefield snap*/
	Ftmpbwf = sf_output("tmpbwf");
    } else {
	Ftmpwf  = NULL;
	Ftmpbwf = NULL;
    }

    /*--- parameters of source ---*/
    srcpar srcp;
    srcp = createsrc();
    at = sf_iaxa(Fsrc, 1); nt = sf_n(at);  dt = sf_d(at);      
    if (!sf_getbool("srcdecay", &srcdecay)) srcdecay=SRCDECAY;
    /*source decay*/
    if (!sf_getint("srcrange", &srcrange)) srcrange=SRCRANGE;
    /*source decay range*/
    if (!sf_getfloat("srctrunc", &srctrunc)) srctrunc=SRCTRUNC;
    /*trunc source after srctrunc time (s)*/
    srcp->nt = nt; srcp->dt = dt; 
    srcp->decay = srcdecay; srcp->range=srcrange; srcp->trunc=srctrunc;
    loadsrc(srcp, Fsrc);

    /*--- Model axes ---*/
    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);

    /* 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;

    nzx = nzb*nxb;
    /* nzx2 = nz2*nx2; */

    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);

    /* 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("gp", &gp)) gp=0;
    /* recorder depth on index*/
    if ( gdep>=oz) { gp = (int)((gdep-oz)/dz+0.5);}
    if (gp < 0.0) sf_error("gdep need to be >=oz");
    /*source and receiver location*/
    if (!sf_getint("snapinter", &snpint)) snpint=10;
    /* snap interval */

    /*check record data*/
    if (wantrecord){
	sf_histint(Frcd,"n1", &tmpint);
	if (tmpint != nt ) sf_error("Error parameter n1 in record!");
	sf_histint(Frcd,"n2", &tmpint);
	if (tmpint != nx ) 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->gp = gp;
    geop->top = top;
    geop->bot = bot;
    geop->lft = lft;
    geop->rht = rht;

    /* wavefield and record  */
    wfnt = (int)(nt-1)/snpint+1;
    sf_warning("nt=%d; snpint=%d; wfnt=%d!!!\n",nt,snpint,wfnt);
    wfdt = dt*snpint;
    record = sf_complexalloc2(nt, nx);
    sf_warning("fine!!!");

    wavefld = sf_floatalloc3(nz, nx, wfnt);

    sf_warning("fine!!!");

/*
    if (wantwf)
	wavefld2= sf_floatalloc3(nz, nx, wfnt);
    else
	wavefld2=NULL;
*/

    /*image*/
    img1 = sf_floatalloc2(nz, nx);
    img2 = sf_floatalloc2(nz, nx);

    if (verb) {
	sf_warning("============================");
	sf_warning("nx=%d nz=%d nt=%d", geop->nx, geop->nz, srcp->nt);
	sf_warning("nxb=%d nzb=%d ", geop->nxb, geop->nzb);
	sf_warning("dx=%f dz=%f dt=%f", geop->dx, geop->dz, srcp->dt);
	sf_warning("top=%d bot=%d lft=%d rht=%d", geop->top, geop->bot, geop->lft, geop->rht);
	sf_warning("srcdecay=%d srcrange=%d",srcp->decay,srcp->range);
	sf_warning("spx=%d spz=%d gp=%d snpint=%d", spx, spz, gp, snpint);
	sf_warning("wfdt=%f wfnt=%d ", wfdt, wfnt);
	sf_warning("============================");
    }

    /* write record */
    sf_setn(ax, nx);
    sf_setn(az, nz);
    
    if(!wantrecord) {
	sf_oaxa(Frcd, at, 1);
	sf_oaxa(Frcd, ax, 2);
	sf_settype(Frcd,SF_COMPLEX);
    }

    if (wantwf) {
	/*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_FLOAT);
	
	/*write temp wavefield */
	sf_oaxa(Ftmpbwf, az, 1);
	sf_oaxa(Ftmpbwf, ax, 2);
	sf_oaxa(Ftmpbwf, at, 3);
	sf_settype(Ftmpbwf,SF_FLOAT);
    }

    /*write image*/
    sf_oaxa(Fimg1, az, 1);
    sf_oaxa(Fimg1, ax, 2);
    sf_settype(Fimg1,SF_FLOAT);
    sf_oaxa(Fimg2, az, 1);
    sf_oaxa(Fimg2, ax, 2);
    sf_settype(Fimg2,SF_FLOAT);

    lrosfor2(wavefld, record, verb, lt, rt, m2, geop, srcp, pad1);
    if(wantrecord) {
	sf_complexread(record[0], nx*nt, Frcd);
    }
    //    lrosback2(img1, img2, wavefld, record, verb, wantwf, ltb, rtb, m2, geop, srcp, pad1, wavefld2);
    
    if (!wantrecord) {
	for (ix=0; ix<nx; ix++) 
	    sf_complexwrite(record[ix], nt, Frcd);
    }
    
    if (wantwf) {
	for (it=0; it<wfnt; it++)
	    for ( ix=0; ix<nx; ix++) {
		sf_floatwrite(wavefld[it][ix], nz, Ftmpwf);
		//		sf_floatwrite(wavefld2[it][ix],nz, Ftmpbwf);
	    }
    }

    for (ix=0; ix<nx; ix++) 
	sf_floatwrite(img1[ix], nz, Fimg1);
    for (ix=0; ix<nx; ix++) 
	sf_floatwrite(img2[ix], nz, Fimg2);
      
    tend = clock();
    duration=(double)(tend-tstart)/CLOCKS_PER_SEC;
    sf_warning(">> The CPU time of single shot migration is: %f seconds << ", duration);
    exit(0);

}
コード例 #9
0
ファイル: Mewefd3dtti.c プロジェクト: 1014511134/src
int main(int argc, char* argv[])
{
    bool verb,fsrf,snap,ssou,dabc;
    int  jsnap,ntsnap,jdata;

    /* I/O files */
    sf_file Fwav=NULL; /* wavelet   */
    sf_file Fsou=NULL; /* sources   */
    sf_file Frec=NULL; /* receivers */
    sf_file Fccc=NULL; /* velocity  */
    sf_file Fden=NULL; /* density   */
    sf_file Fdat=NULL; /* data      */
    sf_file Fwfl=NULL; /* wavefield */

    /* cube axes */
    sf_axis at,ax,ay,az;
    sf_axis as,ar,ac;

    int     nt,nz,nx,ny,ns,nr,nc,nb;
    int     it,iz,ix,iy;
    float   dt,dz,dx,dy,idz,idx,idy;
  

    /* FDM structure */
    fdm3d    fdm=NULL;
    abcone3d abcp=NULL,abcs=NULL;
    sponge1d  spo=NULL;

    /* I/O arrays */
    float***ww=NULL;           /* wavelet   */
    pt3d   *ss=NULL;           /* sources   */
    pt3d   *rr=NULL;           /* receivers */
    float **dd=NULL;           /* data      */

    /*------------------------------------------------------------*/
    float ***tt=NULL;
    float ***ro=NULL;           /* density */

    /* orthorombic stiffness - 9 coefficients */
    /* c11 c12 c13 
       .   c22 c23 
       .   .   c33 
                  c44
                     c55
                        c66 */
    float ***c11=NULL,***c12=NULL,***c13=NULL,***c14=NULL,***c15=NULL,***c16=NULL;
    float ***c22=NULL,***c23=NULL,***c24=NULL,***c25=NULL,***c26=NULL;
    float ***c33=NULL,***c34=NULL,***c35=NULL,***c36=NULL;
    float ***c44=NULL,***c45=NULL,***c46=NULL;
    float ***c55=NULL,***c56=NULL;
    float ***c66=NULL;
  
    float ***vp,***vs;

    /*------------------------------------------------------------*/
    /* displacement: um = U @ t-1; uo = U @ t; up = U @ t+1 */
    float ***umz,***uoz,***upz,***uaz,***utz; 
    float ***umx,***uox,***upx,***uax,***utx;
    float ***umy,***uoy,***upy,***uay,***uty;

    /* stress/strain tensor */ 
    float ***tzz,***txx,***tyy,***txy,***tyz,***tzx;       
    float    szz,   sxx,   syy,   sxy,   syz,   szx;

    /*------------------------------------------------------------*/
    /* linear interpolation weights/indices */
    lint3d cs,cr;

    /* */
    int nbell;
    
    /* wavefield cut params */
    sf_axis   acz=NULL,acx=NULL,acy=NULL;
    int       nqz,nqx,nqy;
    float     oqz,oqx,oqy;
    float     dqz,dqx,dqy;
    float     ***uc=NULL;

    /*------------------------------------------------------------*/
    /* init RSF */
    sf_init(argc,argv);

    /*------------------------------------------------------------*/
    /* OMP parameters */
#ifdef _OPENMP
    omp_init();
#endif
    /*------------------------------------------------------------*/

    /*------------------------------------------------------------*/
    /* execution flags */
    if(! sf_getbool("verb",&verb)) verb=false; /* verbosity flag */
    if(! sf_getbool("snap",&snap)) snap=false; /* wavefield snapshots flag */
    if(! sf_getbool("free",&fsrf)) fsrf=false; /* free surface flag */
    if(! sf_getbool("ssou",&ssou)) ssou=false; /* stress source */
    if(! sf_getbool("dabc",&dabc)) dabc=false; /* absorbing BC */
    /*------------------------------------------------------------*/

    /*------------------------------------------------------------*/
    /* I/O files */
    Fwav = sf_input ("in" ); /* wavelet   */
    Fccc = sf_input ("ccc"); /* stiffness */
    Fden = sf_input ("den"); /* density   */
    Fsou = sf_input ("sou"); /* sources   */
    Frec = sf_input ("rec"); /* receivers */
    Fwfl = sf_output("wfl"); /* wavefield */
    Fdat = sf_output("out"); /* data      */
    /*------------------------------------------------------------*/

    /*------------------------------------------------------------*/
    /* axes */
    at = sf_iaxa(Fwav,3); sf_setlabel(at,"time");     sf_setunit(at,"s"); if(verb) sf_raxa(at); /* time */
    az = sf_iaxa(Fccc,1); sf_setlabel(az,"space z");  sf_setunit(az,"km");if(verb) sf_raxa(az); /* depth */
    ax = sf_iaxa(Fccc,2); sf_setlabel(ax,"space x");  sf_setunit(ax,"km");if(verb) sf_raxa(ax); /* space x */
    ay = sf_iaxa(Fccc,3); sf_setlabel(ay,"space y");  sf_setunit(ay,"km");if(verb) sf_raxa(ay); /* space y */
    as = sf_iaxa(Fsou,2); sf_setlabel(as,"sources");  sf_setunit(as,"km");if(verb) sf_raxa(as); /* sources */
    ar = sf_iaxa(Frec,2); sf_setlabel(ar,"receivers");sf_setunit(ar,"km");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);
    ny = sf_n(ay); dy = sf_d(ay);

    ns = sf_n(as);
    nr = sf_n(ar);
    /*------------------------------------------------------------*/

    /*------------------------------------------------------------*/
    /* other execution parameters */
    if(! sf_getint("nbell",&nbell)) nbell=1;  /* bell size */
    if(verb) sf_warning("nbell=%d",nbell);
    if(! sf_getint("jdata",&jdata)) jdata=1;
    if(snap) {  /* save wavefield every *jsnap* time steps */
	if(! sf_getint("jsnap",&jsnap)) jsnap=nt;
    }


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

    /*------------------------------------------------------------*/
    /* expand domain for FD operators and ABC */
    if( !sf_getint("nb",&nb) || nb<NOP) nb=NOP;

    fdm=fdutil3d_init(verb,fsrf,az,ax,ay,nb,1);
    fdbell3d_init(nbell);

    sf_setn(az,fdm->nzpad); sf_seto(az,fdm->ozpad); sf_setlabel(az,"expanded z");sf_setunit(az,"km");if(verb) sf_raxa(az);
    sf_setn(ax,fdm->nxpad); sf_seto(ax,fdm->oxpad); sf_setlabel(ax,"expanded x");sf_setunit(ax,"km");if(verb) sf_raxa(ax);
    sf_setn(ay,fdm->nypad); sf_seto(ay,fdm->oypad); sf_setlabel(ay,"expanded y");sf_setunit(ay,"km");if(verb) sf_raxa(ay);
    /*------------------------------------------------------------*/

    /* 3D vector components */
    nc=3;
    ac=sf_maxa(nc,0,1);

    /*------------------------------------------------------------*/
    /* setup output data header */
    sf_oaxa(Fdat,ar,1);
    sf_oaxa(Fdat,ac,2);

    sf_setn(at,nt/jdata);
    sf_setd(at,dt*jdata);
    sf_oaxa(Fdat,at,3);

    /* setup output wavefield header */
    if(snap) {
	if(!sf_getint  ("nqz",&nqz)) nqz=sf_n(az);
	if(!sf_getint  ("nqx",&nqx)) nqx=sf_n(ax);
	if(!sf_getint  ("nqy",&nqy)) nqy=sf_n(ay);

	if(!sf_getfloat("oqz",&oqz)) oqz=sf_o(az);
	if(!sf_getfloat("oqx",&oqx)) oqx=sf_o(ax);
	if(!sf_getfloat("oqy",&oqy)) oqy=sf_o(ay);

	dqz=sf_d(az);
	dqx=sf_d(ax);
	dqy=sf_d(ay);

	acz = sf_maxa(nqz,oqz,dqz);  sf_setunit(acz,"km");sf_setlabel(acz,"snapshot z");sf_raxa(acz);
	acx = sf_maxa(nqx,oqx,dqx);  sf_setunit(acx,"km");sf_setlabel(acx,"snapshot x");sf_raxa(acx);
	acy = sf_maxa(nqy,oqy,dqy);  sf_setunit(acy,"km");sf_setlabel(acy,"snapshot y");sf_raxa(acy);
	/* check if the imaging window fits in the wavefield domain */

	uc=sf_floatalloc3(sf_n(acz),sf_n(acx),sf_n(acy));

	ntsnap=0;
	for(it=0; it<nt; it++) {
	    if(it%jsnap==0) ntsnap++;
	}
	sf_setn(at,  ntsnap);
	sf_setd(at,dt*jsnap);
	sf_setlabel(at,"snapshot frames");
	if(verb)  sf_raxa(at);

	sf_oaxa(Fwfl,acz,1);
	sf_oaxa(Fwfl,acx,2);
	sf_oaxa(Fwfl,acy,3);
	sf_oaxa(Fwfl,ac, 4);
	sf_oaxa(Fwfl,at, 5);
    }

    /*------------------------------------------------------------*/
    /* source array */
    ww=sf_floatalloc3(ns,nc,nt); 
    sf_floatread(ww[0][0],nt*nc*ns,Fwav);

    /* data array */
    dd=sf_floatalloc2(nr,nc);

    /*------------------------------------------------------------*/
    /* setup source/receiver coordinates */
    ss = (pt3d*) sf_alloc(ns,sizeof(*ss)); 
    rr = (pt3d*) sf_alloc(nr,sizeof(*rr)); 

    pt3dread1(Fsou,ss,ns,3); /* read (x,y,z) coordinates */
    pt3dread1(Frec,rr,nr,3); /* read (x,y,z) coordinates */
    
    cs = lint3d_make(ns,ss,fdm);
    cr = lint3d_make(nr,rr,fdm);

    /*------------------------------------------------------------*/
    /* setup FD coefficients */
    idz = 1/dz;
    idx = 1/dx;
    idy = 1/dy;

    /*------------------------------------------------------------*/ 
    tt = sf_floatalloc3(nz,nx,ny); 
    
    ro =sf_floatalloc3(fdm->nzpad,fdm->nxpad,fdm->nypad);
    c11=sf_floatalloc3(fdm->nzpad,fdm->nxpad,fdm->nypad); 
    c12=sf_floatalloc3(fdm->nzpad,fdm->nxpad,fdm->nypad); 
    c13=sf_floatalloc3(fdm->nzpad,fdm->nxpad,fdm->nypad); 
    c14=sf_floatalloc3(fdm->nzpad,fdm->nxpad,fdm->nypad); 
    c15=sf_floatalloc3(fdm->nzpad,fdm->nxpad,fdm->nypad); 
    c16=sf_floatalloc3(fdm->nzpad,fdm->nxpad,fdm->nypad); 
    c22=sf_floatalloc3(fdm->nzpad,fdm->nxpad,fdm->nypad); 
    c23=sf_floatalloc3(fdm->nzpad,fdm->nxpad,fdm->nypad); 
    c24=sf_floatalloc3(fdm->nzpad,fdm->nxpad,fdm->nypad);    
    c25=sf_floatalloc3(fdm->nzpad,fdm->nxpad,fdm->nypad); 
    c26=sf_floatalloc3(fdm->nzpad,fdm->nxpad,fdm->nypad); 
    c33=sf_floatalloc3(fdm->nzpad,fdm->nxpad,fdm->nypad); 
    c34=sf_floatalloc3(fdm->nzpad,fdm->nxpad,fdm->nypad); 
    c35=sf_floatalloc3(fdm->nzpad,fdm->nxpad,fdm->nypad); 
    c36=sf_floatalloc3(fdm->nzpad,fdm->nxpad,fdm->nypad); 
    c44=sf_floatalloc3(fdm->nzpad,fdm->nxpad,fdm->nypad); 
    c45=sf_floatalloc3(fdm->nzpad,fdm->nxpad,fdm->nypad); 
    c46=sf_floatalloc3(fdm->nzpad,fdm->nxpad,fdm->nypad);    
    c55=sf_floatalloc3(fdm->nzpad,fdm->nxpad,fdm->nypad); 
    c56=sf_floatalloc3(fdm->nzpad,fdm->nxpad,fdm->nypad); 
    c66=sf_floatalloc3(fdm->nzpad,fdm->nxpad,fdm->nypad);   

 

    /* input density */
    sf_floatread(tt[0][0],nz*nx*ny,Fden);     expand3d(tt,ro ,fdm);

    /* input stiffness */
    sf_floatread(tt[0][0],nz*nx*ny,Fccc );    expand3d(tt,c11,fdm);
    sf_floatread(tt[0][0],nz*nx*ny,Fccc );    expand3d(tt,c12,fdm);    
    sf_floatread(tt[0][0],nz*nx*ny,Fccc );    expand3d(tt,c13,fdm);    
    sf_floatread(tt[0][0],nz*nx*ny,Fccc );    expand3d(tt,c14,fdm);
    sf_floatread(tt[0][0],nz*nx*ny,Fccc );    expand3d(tt,c15,fdm);    
    sf_floatread(tt[0][0],nz*nx*ny,Fccc );    expand3d(tt,c16,fdm);
    sf_floatread(tt[0][0],nz*nx*ny,Fccc );    expand3d(tt,c22,fdm);
    sf_floatread(tt[0][0],nz*nx*ny,Fccc );    expand3d(tt,c23,fdm);
    sf_floatread(tt[0][0],nz*nx*ny,Fccc );    expand3d(tt,c24,fdm);
    sf_floatread(tt[0][0],nz*nx*ny,Fccc );    expand3d(tt,c25,fdm);
    sf_floatread(tt[0][0],nz*nx*ny,Fccc );    expand3d(tt,c26,fdm);    
    sf_floatread(tt[0][0],nz*nx*ny,Fccc );    expand3d(tt,c33,fdm);    
    sf_floatread(tt[0][0],nz*nx*ny,Fccc );    expand3d(tt,c34,fdm);
    sf_floatread(tt[0][0],nz*nx*ny,Fccc );    expand3d(tt,c35,fdm);    
    sf_floatread(tt[0][0],nz*nx*ny,Fccc );    expand3d(tt,c36,fdm);
    sf_floatread(tt[0][0],nz*nx*ny,Fccc );    expand3d(tt,c44,fdm);
    sf_floatread(tt[0][0],nz*nx*ny,Fccc );    expand3d(tt,c45,fdm);
    sf_floatread(tt[0][0],nz*nx*ny,Fccc );    expand3d(tt,c46,fdm);
    sf_floatread(tt[0][0],nz*nx*ny,Fccc );    expand3d(tt,c55,fdm);
    sf_floatread(tt[0][0],nz*nx*ny,Fccc );    expand3d(tt,c56,fdm);
    sf_floatread(tt[0][0],nz*nx*ny,Fccc );    expand3d(tt,c66,fdm);

    free(**tt); free(*tt); free(tt);

    /*------------------------------------------------------------*/
    if(dabc) {
	/* one-way abc setup   */
	vp = sf_floatalloc3(fdm->nzpad,fdm->nxpad,fdm->nypad); 
	vs = sf_floatalloc3(fdm->nzpad,fdm->nxpad,fdm->nypad); 
	for        (iy=0; iy<fdm->nypad; iy++) {
	    for    (ix=0; ix<fdm->nxpad; ix++) {
		for(iz=0; iz<fdm->nzpad; iz++) {
		    vp[iy][ix][iz] = sqrt( c11[iy][ix][iz]/ro[iy][ix][iz] );
		    vs[iy][ix][iz] = sqrt( c13[iy][ix][iz]/ro[iy][ix][iz] );
		}
	    }
	}
	abcp = abcone3d_make(NOP,dt,vp,fsrf,fdm);
	abcs = abcone3d_make(NOP,dt,vs,fsrf,fdm);
	free(**vp); free(*vp); free(vp);
	free(**vs); free(*vs); free(vs);

	/* sponge abc setup */
	spo = sponge_make(fdm->nb);
    }

    /*------------------------------------------------------------*/
    /* precompute 1/ro * dt^2 */    for        (iy=0; iy<fdm->nypad; iy++) {
	for    (ix=0; ix<fdm->nxpad; ix++) {
	    for(iz=0; iz<fdm->nzpad; iz++) {
		ro[iy][ix][iz] = dt*dt/ro[iy][ix][iz];
	    }
	}
     }

    /*------------------------------------------------------------*/
    /* allocate wavefield arrays */
    umz=sf_floatalloc3(fdm->nzpad,fdm->nxpad,fdm->nypad);
    uoz=sf_floatalloc3(fdm->nzpad,fdm->nxpad,fdm->nypad);
    upz=sf_floatalloc3(fdm->nzpad,fdm->nxpad,fdm->nypad);
    uaz=sf_floatalloc3(fdm->nzpad,fdm->nxpad,fdm->nypad);

    umx=sf_floatalloc3(fdm->nzpad,fdm->nxpad,fdm->nypad);
    uox=sf_floatalloc3(fdm->nzpad,fdm->nxpad,fdm->nypad);
    upx=sf_floatalloc3(fdm->nzpad,fdm->nxpad,fdm->nypad);
    uax=sf_floatalloc3(fdm->nzpad,fdm->nxpad,fdm->nypad);

    umy=sf_floatalloc3(fdm->nzpad,fdm->nxpad,fdm->nypad);
    uoy=sf_floatalloc3(fdm->nzpad,fdm->nxpad,fdm->nypad);
    upy=sf_floatalloc3(fdm->nzpad,fdm->nxpad,fdm->nypad);
    uay=sf_floatalloc3(fdm->nzpad,fdm->nxpad,fdm->nypad);

    tzz=sf_floatalloc3(fdm->nzpad,fdm->nxpad,fdm->nypad);
    tyy=sf_floatalloc3(fdm->nzpad,fdm->nxpad,fdm->nypad);
    txx=sf_floatalloc3(fdm->nzpad,fdm->nxpad,fdm->nypad);
    txy=sf_floatalloc3(fdm->nzpad,fdm->nxpad,fdm->nypad);
    tyz=sf_floatalloc3(fdm->nzpad,fdm->nxpad,fdm->nypad);
    tzx=sf_floatalloc3(fdm->nzpad,fdm->nxpad,fdm->nypad);

    for        (iy=0; iy<fdm->nypad; iy++) {
	for    (ix=0; ix<fdm->nxpad; ix++) {
	    for(iz=0; iz<fdm->nzpad; iz++) {
		umz[iy][ix][iz]=0; umx[iy][ix][iz]=0; umy[iy][ix][iz]=0;
		uoz[iy][ix][iz]=0; uox[iy][ix][iz]=0; uoy[iy][ix][iz]=0;
		upz[iy][ix][iz]=0; upx[iy][ix][iz]=0; upy[iy][ix][iz]=0;
		uaz[iy][ix][iz]=0; uax[iy][ix][iz]=0; uay[iy][ix][iz]=0;
	    }
	}
    }

    /*------------------------------------------------------------*/
    /* 
     *  MAIN LOOP
     */
    /*------------------------------------------------------------*/
    if(verb) fprintf(stderr,"\n");

    for (it=0; it<nt; it++) {
	if(verb) fprintf(stderr,"\b\b\b\b\b%d",it);

	/*------------------------------------------------------------*/
	/* from displacement to strain                                */
	/*------------------------------------------------------------*/	
	/* 
	 * exx = Dx(ux)
	 * eyy = Dy(uy)
	 * ezz = Dz(uz)
	 * exy = Dy(ux) + Dx(uy)
	 * eyz = Dz(uy) + Dy(uz)
	 * ezx = Dx(uz) + Dz(ux)
	 */
#ifdef _OPENMP
#pragma omp parallel for					\
    schedule(dynamic,fdm->ompchunk)				\
    private(ix,iy,iz)						\
    shared(fdm,txx,tyy,tzz,txy,tyz,tzx,uox,uoy,uoz,idx,idy,idz)
#endif
	for        (iy=NOP; iy<fdm->nypad-NOP; iy++) {
	    for    (ix=NOP; ix<fdm->nxpad-NOP; ix++) {
		for(iz=NOP; iz<fdm->nzpad-NOP; iz++) {
		    
		    txx[iy][ix][iz] = Dx(uox,ix,iy,iz,idx);
		    tyy[iy][ix][iz] = Dy(uoy,ix,iy,iz,idy);
		    tzz[iy][ix][iz] = Dz(uoz,ix,iy,iz,idz);
		    
		    txy[iy][ix][iz] = Dy(uox,ix,iy,iz,idy) + Dx(uoy,ix,iy,iz,idx);
		    tyz[iy][ix][iz] = Dz(uoy,ix,iy,iz,idz) + Dy(uoz,ix,iy,iz,idy);
		    tzx[iy][ix][iz] = Dx(uoz,ix,iy,iz,idx) + Dz(uox,ix,iy,iz,idz);
		}
	    }
	}
	
	/*------------------------------------------------------------*/
	/* from strain to stress                                      */
	/*------------------------------------------------------------*/
#ifdef _OPENMP
#pragma omp parallel for						\
    schedule(dynamic,fdm->ompchunk)					\
    private(ix,iy,iz,sxx,syy,szz,sxy,syz,szx)				\
    shared(fdm,txx,tyy,tzz,txy,tyz,tzx,c11,c12,c13,c14,c15,c16,c22,c23,c24,c25,c26,c33,c34,c35,c36,c44,c45,c46,c55,c56,c66)
#endif
	for        (iy=0; iy<fdm->nypad; iy++) {
	    for    (ix=0; ix<fdm->nxpad; ix++) {
		for(iz=0; iz<fdm->nzpad; iz++) {
		    
		    sxx = c11[iy][ix][iz] * txx[iy][ix][iz]
			+ c12[iy][ix][iz] * tyy[iy][ix][iz]
			+ c13[iy][ix][iz] * tzz[iy][ix][iz]
			+ c14[iy][ix][iz] * tyz[iy][ix][iz]
			+ c15[iy][ix][iz] * tzx[iy][ix][iz]
			+ c16[iy][ix][iz] * txy[iy][ix][iz];

		    syy = c12[iy][ix][iz] * txx[iy][ix][iz]
			+ c22[iy][ix][iz] * tyy[iy][ix][iz]
			+ c23[iy][ix][iz] * tzz[iy][ix][iz]
			+ c24[iy][ix][iz] * tyz[iy][ix][iz]
			+ c25[iy][ix][iz] * tzx[iy][ix][iz]
			+ c26[iy][ix][iz] * txy[iy][ix][iz];

		    szz = c13[iy][ix][iz] * txx[iy][ix][iz]
			+ c23[iy][ix][iz] * tyy[iy][ix][iz]
			+ c33[iy][ix][iz] * tzz[iy][ix][iz]
			+ c34[iy][ix][iz] * tyz[iy][ix][iz]
			+ c35[iy][ix][iz] * tzx[iy][ix][iz]
			+ c36[iy][ix][iz] * txy[iy][ix][iz];

		    syz = c14[iy][ix][iz] * txx[iy][ix][iz]
			+ c24[iy][ix][iz] * tyy[iy][ix][iz]
			+ c34[iy][ix][iz] * tzz[iy][ix][iz]
			+ c44[iy][ix][iz] * tyz[iy][ix][iz]
			+ c45[iy][ix][iz] * tzx[iy][ix][iz]
			+ c46[iy][ix][iz] * txy[iy][ix][iz];
		    
		    szx = c15[iy][ix][iz] * txx[iy][ix][iz]
			+ c25[iy][ix][iz] * tyy[iy][ix][iz]
			+ c35[iy][ix][iz] * tzz[iy][ix][iz]
			+ c45[iy][ix][iz] * tyz[iy][ix][iz]
			+ c55[iy][ix][iz] * tzx[iy][ix][iz]
			+ c56[iy][ix][iz] * txy[iy][ix][iz];

		    sxy = c16[iy][ix][iz] * txx[iy][ix][iz]
			+ c26[iy][ix][iz] * tyy[iy][ix][iz]
			+ c36[iy][ix][iz] * tzz[iy][ix][iz]
			+ c46[iy][ix][iz] * tyz[iy][ix][iz]
			+ c56[iy][ix][iz] * tzx[iy][ix][iz]
			+ c66[iy][ix][iz] * txy[iy][ix][iz];

 
		  


		    txx[iy][ix][iz] = sxx;
		    tyy[iy][ix][iz] = syy;
		    tzz[iy][ix][iz] = szz;
		    txy[iy][ix][iz] = sxy;
		    tyz[iy][ix][iz] = syz;
		    tzx[iy][ix][iz] = szx;
		}
	    }
	}

	/*------------------------------------------------------------*/
	/* free surface */
	/*------------------------------------------------------------*/
	if(fsrf) {
#ifdef _OPENMP
#pragma omp parallel for						\
    schedule(dynamic,fdm->ompchunk)					\
    private(ix,iy,iz)							\
    shared(fdm,txx,tyy,tzz,txy,tyz,tzx)
#endif
	    for        (iy=0; iy<fdm->nypad; iy++) {
		for    (ix=0; ix<fdm->nxpad; ix++) {
		    for(iz=0; iz<fdm->nb;    iz++) {
			txx[iy][ix][iz]=0;
			tyy[iy][ix][iz]=0;
			tzz[iy][ix][iz]=0;
			txy[iy][ix][iz]=0;
			tyz[iy][ix][iz]=0;
			tzx[iy][ix][iz]=0;
		    }
		}
	    }
	}


	/*------------------------------------------------------------*/
	/* inject stress source                                       */
	/*------------------------------------------------------------*/
	if(ssou) {
	    lint3d_bell(txx,ww[it][0],cs);
	    lint3d_bell(tyy,ww[it][1],cs);
	    lint3d_bell(tzz,ww[it][2],cs);
	}

	/*------------------------------------------------------------*/
	/* from stress to acceleration                                */
	/*------------------------------------------------------------*/
	/* 
	 * ax = Dx(txx) + Dy(txy) + Dz(txz)
	 * ay = Dx(txy) + Dy(tyy) + Dz(tyz)
	 * az = Dx(txz) + Dy(tyz) + Dz(tzz)
	 */	
#ifdef _OPENMP
#pragma omp parallel for					\
    schedule(dynamic,fdm->ompchunk)				\
    private(ix,iy,iz)						\
    shared(fdm,txx,tyy,tzz,txy,tyz,tzx,uax,uay,uaz,idx,idy,idz)
#endif
	for        (iy=NOP; iy<fdm->nypad-NOP; iy++) {
	    for    (ix=NOP; ix<fdm->nxpad-NOP; ix++) {
		for(iz=NOP; iz<fdm->nzpad-NOP; iz++) {		    
		    uax[iy][ix][iz] = Dx( txx,ix,iy,iz,idx) + Dy( txy,ix,iy,iz,idy) + Dz( tzx,ix,iy,iz,idz) ;
		    uay[iy][ix][iz] = Dx( txy,ix,iy,iz,idx) + Dy( tyy,ix,iy,iz,idy) + Dz( tyz,ix,iy,iz,idz) ;
		    uaz[iy][ix][iz] = Dx( tzx,ix,iy,iz,idx) + Dy( tyz,ix,iy,iz,idy) + Dz( tzz,ix,iy,iz,idz) ;		    
		}
	    }
	}

	/*------------------------------------------------------------*/
	/* inject acceleration source                                 */
	/*------------------------------------------------------------*/
	if(!ssou) {
	    lint3d_bell(uaz,ww[it][0],cs);
	    lint3d_bell(uax,ww[it][1],cs);
	    lint3d_bell(uay,ww[it][2],cs);
	}

	/*------------------------------------------------------------*/
	/* step forward in time                                       */
	/*------------------------------------------------------------*/
#ifdef _OPENMP
#pragma omp parallel for						\
    schedule(dynamic,fdm->ompchunk)					\
    private(ix,iy,iz)							\
    shared(fdm,uox,uoy,uoz,umx,umy,umz,upx,upy,upz,uax,uay,uaz,ro)
#endif
	for        (iy=0; iy<fdm->nypad; iy++) {
	    for    (ix=0; ix<fdm->nxpad; ix++) {
		for(iz=0; iz<fdm->nzpad; iz++) {
		    upx[iy][ix][iz] = 2*uox[iy][ix][iz] 
			-               umx[iy][ix][iz] 
			+               uax[iy][ix][iz] * ro[iy][ix][iz]; 

		    upy[iy][ix][iz] = 2*uoy[iy][ix][iz] 
			-               umy[iy][ix][iz] 
			+               uay[iy][ix][iz] * ro[iy][ix][iz]; 

		    upz[iy][ix][iz] = 2*uoz[iy][ix][iz] 
			-               umz[iy][ix][iz] 
			+               uaz[iy][ix][iz] * ro[iy][ix][iz]; 
		    
		}
	    }
	}
	/* circulate wavefield arrays */
	utz=umz; uty=umy; utx=umx;
	umz=uoz; umy=uoy; umx=uox;
	uoz=upz; uoy=upy; uox=upx;
	upz=utz; upy=uty; upx=utx;
	
	if(dabc) {
	    /* one-way ABC */
	    abcone3d_apply(uoz,umz,NOP,abcp,fdm);
	    abcone3d_apply(uox,umx,NOP,abcp,fdm);
	    abcone3d_apply(uoy,umy,NOP,abcp,fdm);
	    
	    abcone3d_apply(uoz,umz,NOP,abcs,fdm);
	    abcone3d_apply(uox,umx,NOP,abcs,fdm);
	    abcone3d_apply(uoy,umy,NOP,abcs,fdm);

	    /* sponge ABC */
	    sponge3d_apply(umz,spo,fdm);
	    sponge3d_apply(uoz,spo,fdm);
	    sponge3d_apply(upz,spo,fdm);
	    
	    sponge3d_apply(umx,spo,fdm);
	    sponge3d_apply(uox,spo,fdm);
	    sponge3d_apply(upx,spo,fdm);

	    sponge3d_apply(umy,spo,fdm);
	    sponge3d_apply(uoy,spo,fdm);
	    sponge3d_apply(upy,spo,fdm);
	}	    

	/*------------------------------------------------------------*/
	/* cut wavefield and save */
	/*------------------------------------------------------------*/
	lint3d_extract(uoz,dd[0],cr);
	lint3d_extract(uox,dd[1],cr);
	lint3d_extract(uoy,dd[2],cr);

	if(snap && it%jsnap==0) {
	    cut3d(uoz,uc,fdm,acz,acx,acy);
	    sf_floatwrite(uc[0][0],sf_n(acx)*sf_n(acy)*sf_n(acz),Fwfl);

	    cut3d(uox,uc,fdm,acz,acx,acy);
	    sf_floatwrite(uc[0][0],sf_n(acx)*sf_n(acy)*sf_n(acz),Fwfl);

	    cut3d(uoy,uc,fdm,acz,acx,acy);
	    sf_floatwrite(uc[0][0],sf_n(acx)*sf_n(acy)*sf_n(acz),Fwfl);
	}
	if(it%jdata==0) sf_floatwrite(dd[0],nr*nc,Fdat);

    }
    if(verb) fprintf(stderr,"\n");    
    
    /*------------------------------------------------------------*/
    /* deallocate arrays */
    
    free(**ww); free(*ww); free(ww);
    free(ss);
    free(rr);
    free(*dd);  free(dd);

    free(**ro);  free(*ro);  free(ro);
    free(**c11); free(*c11); free(c11);
    free(**c12); free(*c12); free(c12);
    free(**c13); free(*c13); free(c13);
    free(**c14); free(*c14); free(c14);
    free(**c15); free(*c15); free(c15);
    free(**c16); free(*c16); free(c16);
    free(**c22); free(*c22); free(c22);
    free(**c23); free(*c23); free(c23);
    free(**c24); free(*c24); free(c24);
    free(**c25); free(*c25); free(c25);
    free(**c26); free(*c26); free(c26);
    free(**c33); free(*c33); free(c33);
    free(**c34); free(*c34); free(c34);
    free(**c35); free(*c35); free(c35);
    free(**c36); free(*c36); free(c36);
    free(**c44); free(*c44); free(c44);
    free(**c45); free(*c45); free(c45);
    free(**c46); free(*c46); free(c46);
    free(**c55); free(*c55); free(c55);
    free(**c56); free(*c56); free(c56);
    free(**c66); free(*c66); free(c66);




    free(**umz); free(*umz); free(umz);
    free(**uoz); free(*uoz); free(uoz);
    free(**upz); free(*upz); free(upz);
    free(**uaz); free(*uaz); free(uaz);

    free(**umx); free(*umx); free(umx);
    free(**uox); free(*uox); free(uox);
    free(**upx); free(*upx); free(upx);
    free(**uax); free(*uax); free(uax);

    free(**umy); free(*umy); free(umy);
    free(**uoy); free(*uoy); free(uoy);
    free(**upy); free(*upy); free(upy);
    free(**uay); free(*uay); free(uay);

    free(**tzz); free(*tzz); free(tzz);
    free(**txx); free(*txx); free(txx);
    free(**tyy); free(*tyy); free(tyy);
    free(**txy); free(*txy); free(txy);
    free(**tyz); free(*tyz); free(tyz);
    free(**tzx); free(*tzx); free(tzx);

    free(**uc);  free(*uc);  free(uc);    

    exit (0);
}
コード例 #10
0
ファイル: Mawe_trick.c プロジェクト: psava/cwp12
int main(int argc, char* argv[])
{
    bool verb,fsrf,snap,expl,dabc,abcone,is2D,cfl; 
    bool ignore_interpolation = false; /* ignore interpolation for receivers - makes code faster, but only works when receivers are on grid points */
    int  jsnap,ntsnap,jdata;
    float fmax, safety;
    enum SourceType srctype;
    /* I/O files */
    sf_file Fwav=NULL; /* wavelet   */
    sf_file Fsou=NULL; /* sources   */
    sf_file Frec=NULL; /* receivers */
    sf_file Fvel=NULL; /* velocity  */
    sf_file Fden=NULL; /* density   */
    sf_file Fdat=NULL; /* data      */
    sf_file Fwfl=NULL; /* wavefield */
/*set all y variables to be either zero or null to avoid compiler warnings
about being uninitialized */
    /* cube axes */
    sf_axis at,az,ax,ay=NULL; 
    sf_axis as,ar;

    int     nt,nz,nx,ny=0,ns,nr,nb;
    int     it,iz,ix,iy=0;
    float   dt,dz,dx,dy=0,idz,idx,idy=0;

    
    /* I/O arrays */
    float  *ww=NULL;           /* wavelet   */
    float  *dd=NULL;           /* data      */

    
    /* FD operator size */
    float co,cax,cbx,cay,cby,caz,cbz;

    /* wavefield cut params */
    sf_axis   acz=NULL,acx=NULL,acy=NULL;
    int       nqz,nqx,nqy;
    float     oqz,oqx,oqy;
    float     dqz,dqx,dqy;

    /*------------------------------------------------------------*/
    /* init RSF */
    sf_init(argc,argv);

    /*------------------------------------------------------------*/
    /* OMP parameters */

    if( !sf_getbool("ignint",&ignore_interpolation)) ignore_interpolation = false;
    if(! sf_getbool("verb",&verb)) verb=false; /* verbosity flag */
    if(! sf_getbool("snap",&snap)) snap=false; /* wavefield snapshots flag */
    if(! sf_getbool("free",&fsrf)) fsrf=false; /* free surface flag */
    if(! sf_getbool("expl",&expl)) expl=false; /* "exploding reflector" */
    if(! sf_getbool("dabc",&dabc)) dabc=false; /* absorbing BC */
    if(! sf_getbool("cfl",&cfl)) cfl=false; /* Use CFL check */ 
    if(! sf_getbool("abcone",&abcone)) abcone=false; /* Use Zero-incident boundary condition*/ 
   
    int ttype = 0;
    if(! sf_getint("srctype",&ttype)) ttype = 0; /* source type, see comments */
    if(ttype < 0 || ttype > 1) sf_error("Invalid source type specified");
           srctype = ttype;
    if (cfl) {
        if(! sf_getfloat("fmax",&fmax)) { /* max frequency for cfl check */
            sf_error("CFL: Must specify fmax for CFL check");
        }
        if(! sf_getfloat("safety",&safety) || safety < 0.0) safety= 0.8; /*safety factor for cfl check*/
    }
    /*------------------------------------------------------------*/

    /*------------------------------------------------------------*/
    /* I/O files */
    Fwav = sf_input ("in" ); /* wavelet   */
    Fvel = sf_input ("vel"); /* velocity  */
    Fsou = sf_input ("sou"); /* sources   */
    Frec = sf_input ("rec"); /* receivers */
    Fwfl = sf_output("wfl"); /* wavefield */
    Fdat = sf_output("out"); /* data      */
    Fden = sf_input ("den"); /* density   */

	/* Determine dimensionality, if 2D then axis 3 has n size of 1 */
	sf_axis test = sf_iaxa(Fvel,3);
	if(sf_n(test) == 1) is2D = true;
	else is2D = false;

    /*------------------------------------------------------------*/
    /* axes */
    at = sf_iaxa(Fwav,2); sf_setlabel(at,"t"); if(verb) sf_raxa(at); /* time */
    az = sf_iaxa(Fvel,1); sf_setlabel(az,"z"); if(verb) sf_raxa(az); /* depth */
    ax = sf_iaxa(Fvel,2); sf_setlabel(ax,"x"); if(verb) sf_raxa(ax); /* space */

    as = sf_iaxa(Fsou,2); sf_setlabel(as,"s"); if(verb) sf_raxa(as); /* sources */
    ar = sf_iaxa(Frec,2); sf_setlabel(ar,"r"); if(verb) sf_raxa(ar); /* receivers */

    nt = sf_n(at); dt = sf_d(at);
    nz = sf_n(az); dz = sf_d(az);
    nx = sf_n(ax); dx = sf_d(ax);

    ns = sf_n(as);
    nr = sf_n(ar);

    if(!is2D){ /*If 3D*/
		ay=sf_iaxa(Fvel,3); sf_setlabel(ay,"y"); if(verb) sf_raxa(ay); /*space*/
		ny=sf_n(ay); dy=sf_d(ay);
	}
    /*------------------------------------------------------------*/

    /*------------------------------------------------------------*/
    /* other execution parameters */
    if(! sf_getint("jdata",&jdata)) jdata=1;
    if(snap) {  /* save wavefield every *jsnap* time steps */
    	if(! sf_getint("jsnap",&jsnap)) jsnap=nt;        
    }
    /*------------------------------------------------------------*/
if(is2D){
/* Begin 2d code */
    /* FDM structure */
    fdm2d    fdm=NULL;
    abcone2d abc=NULL;
    sponge   spo=NULL;
    pt2d   *ss=NULL;           /* sources   */
    pt2d   *rr=NULL;           /* receivers */
   
    float **tt=NULL;
    float **ro=NULL;           /* density */
    float **roz=NULL;          /* normalized 1st derivative of density on axis 1 */
    float **rox=NULL;          /* normalized 1st derivative of density on axis 2 */
    float **vp=NULL;           /* velocity */
    float **vt=NULL;           /* temporary vp*vp * dt*dt */

    float **um,**uo,**up,**ua,**ut; /* wavefield: um = U @ t-1; uo = U @ t; up = U @ t+1 */

    /* linear interpolation weights/indices */
    lint2d cs,cr;
    float     **uc=NULL;

    /*------------------------------------------------------------*/
    /* expand domain for FD operators and ABC */
    if( !sf_getint("nb",&nb) || nb<NOP) nb=NOP;

    fdm=fdutil_init(verb,fsrf,az,ax,nb,1);

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

    /*------------------------------------------------------------*/
    /* setup output data header */
    sf_oaxa(Fdat,ar,1);

    sf_setn(at,nt/jdata);
    sf_setd(at,dt*jdata);
    sf_oaxa(Fdat,at,2);

    /* setup output wavefield header */
    if(snap) {
	if(!sf_getint  ("nqz",&nqz)) nqz=sf_n(az);
	if(!sf_getint  ("nqx",&nqx)) nqx=sf_n(ax);

	if(!sf_getfloat("oqz",&oqz)) oqz=sf_o(az);
	if(!sf_getfloat("oqx",&oqx)) oqx=sf_o(ax);

    sf_setn(az,fdm->nzpad); sf_seto(az,fdm->ozpad); if(verb) sf_raxa(az);
    sf_setn(ax,fdm->nxpad); sf_seto(ax,fdm->oxpad); if(verb) sf_raxa(ax);
	dqz=sf_d(az);
	dqx=sf_d(ax);

	acz = sf_maxa(nqz,oqz,dqz); sf_raxa(acz);
	acx = sf_maxa(nqx,oqx,dqx); sf_raxa(acx);
	/* check if the imaging window fits in the wavefield domain */

	uc=sf_floatalloc2(sf_n(acz),sf_n(acx));

	ntsnap=0;
	for(it=0; it<nt; it++) {
	    if(it%jsnap==0) ntsnap++;
	}
	sf_setn(at,  ntsnap);
	sf_setd(at,dt*jsnap);
	if(verb) sf_raxa(at);

	sf_oaxa(Fwfl,acz,1);
	sf_oaxa(Fwfl,acx,2);
	sf_oaxa(Fwfl,at, 3);
    }

    if(expl) {
    	ww = sf_floatalloc( 1);
    } else {
    	ww = sf_floatalloc(ns);
    }
    dd = sf_floatalloc(nr);

    /*------------------------------------------------------------*/
    /* setup source/receiver coordinates */
    ss = (pt2d*) sf_alloc(ns,sizeof(*ss)); 
    rr = (pt2d*) sf_alloc(nr,sizeof(*rr)); 

    pt2dread1(Fsou,ss,ns,2); /* read (x,z) coordinates */
    pt2dread1(Frec,rr,nr,2); /* read (x,z) coordinates */

    cs = lint2d_make(ns,ss,fdm);
    cr = lint2d_make(nr,rr,fdm);

    /*------------------------------------------------------------*/
    /* setup FD coefficients */
    idz = 1/dz;
    idx = 1/dx;

    co = C0 * (idx*idx+idz*idz);
    cax= CA *  idx*idx;
    cbx= CB *  idx*idx;
    caz= CA *  idz*idz;
    cbz= CB *  idz*idz;

    /*------------------------------------------------------------*/ 
    tt = sf_floatalloc2(nz,nx); 

    ro  =sf_floatalloc2(fdm->nzpad,fdm->nxpad);
    roz =sf_floatalloc2(fdm->nzpad,fdm->nxpad);
    rox =sf_floatalloc2(fdm->nzpad,fdm->nxpad);
    vp  =sf_floatalloc2(fdm->nzpad,fdm->nxpad); 
    vt  =sf_floatalloc2(fdm->nzpad,fdm->nxpad); 

    /* input density */
    sf_floatread(tt[0],nz*nx,Fden);     expand(tt,ro ,fdm);
    /* normalized density derivatives */
    for    (ix=NOP; ix<fdm->nxpad-NOP; ix++) {
	for(iz=NOP; iz<fdm->nzpad-NOP; iz++) {
	    roz[ix][iz] = DZ(ro,ix,iz,idz) / ro[ix][iz];
	    rox[ix][iz] = DX(ro,ix,iz,idx) / ro[ix][iz];
	}
    }   
    free(*ro); free(ro);

    /* input velocity */
    sf_floatread(tt[0],nz*nx,Fvel );    expand(tt,vp,fdm);
    float vpmax = 0.0; float vpmin = 10000000000000000;
    /* precompute vp^2 * dt^2 */
    for    (ix=0; ix<fdm->nxpad; ix++) {
        for(iz=0; iz<fdm->nzpad; iz++) {
            vt[ix][iz] = vp[ix][iz] * vp[ix][iz] * dt*dt;
            if (vp[ix][iz] < vpmin) vpmin = vp[ix][iz];
            else if (vp[ix][iz] > vpmax) vpmax = vp[ix][iz];
        }
    }
    if (cfl) cfl_acoustic(vpmin,vpmax,dx,-1.0f,dz,dt,fmax,safety,NUM_INTERVALS);
    if(fsrf) { /* free surface */
        for    (ix=0; ix<fdm->nxpad; ix++) {
            for(iz=0; iz<fdm->nb; iz++) {
                vt[ix][iz]=0;
            }
        }
    }

    free(*tt); free(tt);    
    /*------------------------------------------------------------*/

    /*------------------------------------------------------------*/
    /* allocate wavefield arrays */
    um=sf_floatalloc2(fdm->nzpad,fdm->nxpad);
    uo=sf_floatalloc2(fdm->nzpad,fdm->nxpad);
    up=sf_floatalloc2(fdm->nzpad,fdm->nxpad);
    ua=sf_floatalloc2(fdm->nzpad,fdm->nxpad);

    for    (ix=0; ix<fdm->nxpad; ix++) {
	for(iz=0; iz<fdm->nzpad; iz++) {
	    um[ix][iz]=0;
	    uo[ix][iz]=0;
	    up[ix][iz]=0;
	    ua[ix][iz]=0;
	}
    }

    /*------------------------------------------------------------*/
	if (abcone) abc = abcone2d_make(NOP,dt,vp,fsrf,fdm);
    if(dabc) {
	/* one-way abc setup */
	/* sponge abc setup */
	spo = sponge_make(fdm->nb);
    }

    /*------------------------------------------------------------*/
    /* 
     *  MAIN LOOP
     */
    /*------------------------------------------------------------*/
    if(verb) fprintf(stderr,"\n");
    for (it=0; it<nt; it++) {
	if(verb) fprintf(stderr,"%d/%d \r",it,nt);

#pragma omp parallel for				\
    schedule(dynamic) \
    private(ix,iz)					\
    shared(fdm,ua,uo,co,caz,cbz)
	for    (ix=NOP; ix<fdm->nxpad-NOP; ix++) {
	    for(iz=NOP; iz<fdm->nzpad-NOP; iz++) {
		
		/* 4th order Laplacian operator */
		ua[ix][iz] = 
		    co * uo[ix  ][iz  ] + 
		    caz*(uo[ix  ][iz-1] + uo[ix  ][iz+1]) +
		    cbz*(uo[ix  ][iz-2] + uo[ix  ][iz+2]) ; 
		/* density term */
        /*ua[ix][iz] -= (
		    DZ(uo,ix,iz,idz) * roz[ix][iz] +
		    DX(uo,ix,iz,idx) * rox[ix][iz] );
        */
	    }
	}   

#pragma omp parallel for				\
    schedule(dynamic)			\
    private(ix,iz)					\
    shared(fdm,ua,uo,co,cax,cbx)
	for    (ix=NOP; ix<fdm->nxpad-NOP; ix++) {
	    for(iz=NOP; iz<fdm->nzpad-NOP; iz++) {
        ua[ix][iz] =  ua[ix][iz] + 
		    cax*(uo[ix-1][iz  ] + uo[ix+1][iz  ]) +
		    cbx*(uo[ix-2][iz  ] + uo[ix+2][iz  ]);
            }
    }

	/* inject acceleration source */
    if (srctype == ACCELERATION){
            if(expl) {
                sf_floatread(ww, 1,Fwav);
                lint2d_inject1(ua,ww[0],cs);
            } else {
                  sf_floatread(ww,ns,Fwav);
                  lint2d_inject(ua,ww,cs);
            }
    }

	/* step forward in time */
#pragma omp parallel for	    \
    schedule(dynamic) \
    private(ix,iz)		    \
    shared(fdm,ua,uo,um,up,vt)
	for    (ix=0; ix<fdm->nxpad; ix++) {
	    for(iz=0; iz<fdm->nzpad; iz++) {
		up[ix][iz] = 2*uo[ix][iz] 
		    -          um[ix][iz] 
		    +          ua[ix][iz] * vt[ix][iz];
	    }
	}

    if(srctype == DISPLACEMENT){
            if(expl) {
                sf_floatread(ww, 1,Fwav);
                lint2d_inject1(up,ww[0],cs);
            } else {
                  sf_floatread(ww,ns,Fwav);
                  lint2d_inject(up,ww,cs);
            }
    }

    
	/* circulate wavefield arrays */
	ut=um;
	um=uo;
	uo=up;
	up=ut;
    
    if (abcone) abcone2d_apply(uo,um,NOP,abc,fdm);
	if(dabc) {
	    /* one-way abc apply */
	    sponge2d_apply(um,spo,fdm);
	    sponge2d_apply(uo,spo,fdm);
	    sponge2d_apply(up,spo,fdm);
	}

	/* extract data */
    if(ignore_interpolation){
        cut2d_extract(uo,dd,cr);
    } else {
	    lint2d_extract(uo,dd,cr);
    }

	if(snap && it%jsnap==0) {
	    cut2d(uo,uc,fdm,acz,acx);
	    sf_floatwrite(uc[0],sf_n(acz)*sf_n(acx),Fwfl);
	}
	if(        it%jdata==0) 
	    sf_floatwrite(dd,nr,Fdat);
    }
    if(verb) fprintf(stderr,"\n");    

    /*------------------------------------------------------------*/
    /* deallocate arrays */
    free(*um); free(um);
    free(*up); free(up);
    free(*uo); free(uo);
    free(*ua); free(ua);
    if(snap) { free(*uc); free(uc); }

    free(*rox); free(rox);
    free(*roz); free(roz);
    free(*vp);  free(vp);
    free(*vt);  free(vt);

    free(ww);
    free(ss);
    free(rr);
    free(dd);


    exit (0);
} else {
    /* FDM structure */
    fdm3d    fdm=NULL;
    abcone3d abc=NULL;
    sponge   spo=NULL;

    /* I/O arrays */
    pt3d   *ss=NULL;           /* sources   */
    pt3d   *rr=NULL;           /* receivers */
	/* Non-universal arrays */
    float***tt=NULL;
    float***ro=NULL;           /* density */
    float***roz=NULL;          /* normalized 1st derivative of density on axis 1 */
    float***rox=NULL;          /* normalized 1st derivative of density on axis 2 */
    float***roy=NULL;          /* normalized 1st derivative of density on axis 3 */
    float***vp=NULL;           /* velocity */
    float***vt=NULL;           /* temporary vp*vp * dt*dt */

    float***um,***uo,***up,***ua,***ut; /* wavefield: um = U @ t-1; uo = U @ t; up = U @ t+1 */

    /* linear interpolation weights/indices */
    lint3d cs,cr;

	/* Wavefield cut params that are not universal */
    float     ***uc=NULL;


    /*------------------------------------------------------------*/
    /* expand domain for FD operators and ABC */
    if( !sf_getint("nb",&nb) || nb<NOP) nb=NOP;

    fdm=fdutil3d_init(verb,fsrf,az,ax,ay,nb,1);

    sf_setn(az,fdm->nzpad); sf_seto(az,fdm->ozpad); if(verb) sf_raxa(az);
    sf_setn(ax,fdm->nxpad); sf_seto(ax,fdm->oxpad); if(verb) sf_raxa(ax);
    sf_setn(ay,fdm->nypad); sf_seto(ay,fdm->oypad); if(verb) sf_raxa(ay);
    /*------------------------------------------------------------*/

    /*------------------------------------------------------------*/
    /* setup output data header */
    sf_oaxa(Fdat,ar,1);

    sf_setn(at,nt/jdata);
    sf_setd(at,dt*jdata);
    sf_oaxa(Fdat,at,2);

    /* setup output wavefield header */
    if(snap) {
	if(!sf_getint  ("nqz",&nqz)) nqz=sf_n(az);
	if(!sf_getint  ("nqx",&nqx)) nqx=sf_n(ax);
	if(!sf_getint  ("nqy",&nqy)) nqy=sf_n(ay);

	if(!sf_getfloat("oqz",&oqz)) oqz=sf_o(az);
	if(!sf_getfloat("oqx",&oqx)) oqx=sf_o(ax);
	if(!sf_getfloat("oqy",&oqy)) oqy=sf_o(ay);

	dqz=sf_d(az);
	dqx=sf_d(ax);
	dqy=sf_d(ay);

	acz = sf_maxa(nqz,oqz,dqz); sf_raxa(acz);
	acx = sf_maxa(nqx,oqx,dqx); sf_raxa(acx);
	acy = sf_maxa(nqy,oqy,dqy); sf_raxa(acy);
	/* check if the imaging window fits in the wavefield domain */

	uc=sf_floatalloc3(sf_n(acz),sf_n(acx),sf_n(acy));

	ntsnap=0;
	for(it=0; it<nt; it++) {
	    if(it%jsnap==0) ntsnap++;
	}
	sf_setn(at,  ntsnap);
	sf_setd(at,dt*jsnap);
	if(verb) sf_raxa(at);

	sf_oaxa(Fwfl,acz,1);
	sf_oaxa(Fwfl,acx,2);
	sf_oaxa(Fwfl,acy,3);
	sf_oaxa(Fwfl,at, 4);
    }

    if(expl) {
	ww = sf_floatalloc( 1);
    } else {
	ww = sf_floatalloc(ns);
    }
    dd = sf_floatalloc(nr);

    /*------------------------------------------------------------*/
    /* setup source/receiver coordinates */
    ss = (pt3d*) sf_alloc(ns,sizeof(*ss)); 
    rr = (pt3d*) sf_alloc(nr,sizeof(*rr)); 

    pt3dread1(Fsou,ss,ns,3); /* read (x,y,z) coordinates */
    pt3dread1(Frec,rr,nr,3); /* read (x,y,z) coordinates */

    cs = lint3d_make(ns,ss,fdm);
    cr = lint3d_make(nr,rr,fdm);

    /*------------------------------------------------------------*/
    /* setup FD coefficients */
    idz = 1/dz;
    idx = 1/dx;
    idy = 1/dy;

    co = C0 * (idx*idx+idy*idy+idz*idz);
    cax= CA *  idx*idx;
    cbx= CB *  idx*idx;
    cay= CA *  idy*idy;
    cby= CB *  idy*idy;
    caz= CA *  idz*idz;
    cbz= CB *  idz*idz;

    /*------------------------------------------------------------*/ 
    tt = sf_floatalloc3(nz,nx,ny); 

    ro  =sf_floatalloc3(fdm->nzpad,fdm->nxpad,fdm->nypad);
    roz =sf_floatalloc3(fdm->nzpad,fdm->nxpad,fdm->nypad);
    rox =sf_floatalloc3(fdm->nzpad,fdm->nxpad,fdm->nypad);
    roy =sf_floatalloc3(fdm->nzpad,fdm->nxpad,fdm->nypad);
    vp  =sf_floatalloc3(fdm->nzpad,fdm->nxpad,fdm->nypad); 
    vt  =sf_floatalloc3(fdm->nzpad,fdm->nxpad,fdm->nypad); 

    /* input density */
    sf_floatread(tt[0][0],nz*nx*ny,Fden);     expand3d(tt,ro ,fdm);

    /* normalized density derivatives */
    for        (iy=NOP; iy<fdm->nypad-NOP; iy++) {
	for    (ix=NOP; ix<fdm->nxpad-NOP; ix++) {
	    for(iz=NOP; iz<fdm->nzpad-NOP; iz++) {
		roz[iy][ix][iz] = DZ3(ro,ix,iy,iz,idz) / ro[iy][ix][iz];
		rox[iy][ix][iz] = DX3(ro,ix,iy,iz,idx) / ro[iy][ix][iz];
		roy[iy][ix][iz] = DY3(ro,ix,iy,iz,idy) / ro[iy][ix][iz];
	    }
	}   
    }
    free(**ro);  free(*ro); free(ro);  

    /* input velocity */
    sf_floatread(tt[0][0],nz*nx*ny,Fvel );    expand3d(tt,vp,fdm);
    /* precompute vp^2 * dt^2 */
    float vpmin = 1000000000000; float vpmax = 0.0;
    for        (iy=0; iy<fdm->nypad; iy++) {
        for    (ix=0; ix<fdm->nxpad; ix++) {
            for(iz=0; iz<fdm->nzpad; iz++) {
                float vpt = vp[iy][ix][iz];
                vt[iy][ix][iz] = vp[iy][ix][iz] * vp[iy][ix][iz] * dt*dt;
                if (vpt > vpmax) vpmax = vpt;
                else if (vpt < vpmin) vpmin = vpt;
            }
        }
    }

    if (cfl) cfl_acoustic(vpmin,vpmax,dx,dy,dz,dt,fmax,safety,NUM_INTERVALS);

    if(fsrf) { /* free surface */
	for        (iy=0; iy<fdm->nypad; iy++) {
	    for    (ix=0; ix<fdm->nxpad; ix++) {
		for(iz=0; iz<fdm->nb; iz++) {
		    vt[iy][ix][iz]=0;
		}
	    }
	}
    }

    free(**tt);  free(*tt); free(tt);    
    /*------------------------------------------------------------*/

    /*------------------------------------------------------------*/
    /* allocate wavefield arrays */
    um=sf_floatalloc3(fdm->nzpad,fdm->nxpad,fdm->nypad);
    uo=sf_floatalloc3(fdm->nzpad,fdm->nxpad,fdm->nypad);
    up=sf_floatalloc3(fdm->nzpad,fdm->nxpad,fdm->nypad);
    ua=sf_floatalloc3(fdm->nzpad,fdm->nxpad,fdm->nypad);

    for        (iy=0; iy<fdm->nypad; iy++) {
	for    (ix=0; ix<fdm->nxpad; ix++) {
	    for(iz=0; iz<fdm->nzpad; iz++) {
		um[iy][ix][iz]=0;
		uo[iy][ix][iz]=0;
		up[iy][ix][iz]=0;
		ua[iy][ix][iz]=0;
	    }
	}
    }

    /*------------------------------------------------------------*/
	if (abcone) abc = abcone3d_make(NOP,dt,vp,fsrf,fdm);
    if(dabc) {
	/* one-way abc setup */
	/* sponge abc setup */
	spo = sponge_make(fdm->nb);
    }

    /*------------------------------------------------------------*/
    /* 
     *  MAIN LOOP
     */
    /*------------------------------------------------------------*/
    if(verb) fprintf(stderr,"\n");
    for (it=0; it<nt; it++) {
	if(verb) fprintf(stderr,"%d/%d \r",it,nt);

#pragma omp parallel for					\
    schedule(dynamic) \
    private(ix,iy,iz)						\
    shared(fdm,ua,uo,co,cax,cay,caz,cbx,cby,cbz,idx,idy,idz)
	for        (iy=NOP; iy<fdm->nypad-NOP; iy++) {
	    for    (ix=NOP; ix<fdm->nxpad-NOP; ix++) {
		for(iz=NOP; iz<fdm->nzpad-NOP; iz++) {
		    
		    /* 4th order Laplacian operator */
		    ua[iy][ix][iz] = 
			co * uo[iy  ][ix  ][iz  ] + 
			caz*(uo[iy  ][ix  ][iz-1] + uo[iy  ][ix  ][iz+1]) +
			cbz*(uo[iy  ][ix  ][iz-2] + uo[iy  ][ix  ][iz+2]);
		    
		    /* density term */
		    /*ua[iy][ix][iz] -= (
			DZ3(uo,ix,iy,iz,idz) * roz[iy][ix][iz] +
			DX3(uo,ix,iy,iz,idx) * rox[iy][ix][iz] +
			DY3(uo,ix,iy,iz,idy) * roy[iy][ix][iz] );
            */
		 }
	    }   
	}

#pragma omp parallel for					\
    schedule(dynamic) \
    private(ix,iy,iz)						\
    shared(fdm,ua,uo,co,cax,cay,caz,cbx,cby,cbz,idx,idy,idz)
	for        (iy=NOP; iy<fdm->nypad-NOP; iy++) {
	    for    (ix=NOP; ix<fdm->nxpad-NOP; ix++) {
		    for(iz=NOP; iz<fdm->nzpad-NOP; iz++) {
		    ua[iy][ix][iz] = ua[iy][ix][iz] + 
			cax*(uo[iy  ][ix-1][iz  ] + uo[iy  ][ix+1][iz  ]) +
			cbx*(uo[iy  ][ix-2][iz  ] + uo[iy  ][ix+2][iz  ]) ;
            }
        }
    }

#pragma omp parallel for					\
    schedule(dynamic) \
    private(ix,iy,iz)						\
    shared(fdm,ua,uo,co,cax,cay,caz,cbx,cby,cbz,idx,idy,idz)
	for        (iy=NOP; iy<fdm->nypad-NOP; iy++) {
	    for    (ix=NOP; ix<fdm->nxpad-NOP; ix++) {
		    for(iz=NOP; iz<fdm->nzpad-NOP; iz++) {
		    ua[iy][ix][iz] = ua[iy][ix][iz] + 
			cay*(uo[iy-1][ix  ][iz  ] + uo[iy+1][ix  ][iz  ]) +
			cby*(uo[iy-2][ix  ][iz  ] + uo[iy+2][ix  ][iz  ]);
            }
        }
    }

	/* inject acceleration source */
    if (srctype == ACCELERATION){
        if(expl) {
            sf_floatread(ww, 1,Fwav);
            lint3d_inject1(ua,ww[0],cs);
        } else {
            sf_floatread(ww,ns,Fwav);	
            lint3d_inject(ua,ww,cs);
        }
   }

	/* step forward in time */
#pragma omp parallel for	    \
    schedule(static) \
    private(ix,iy,iz)		    \
    shared(fdm,ua,uo,um,up,vt)
	for        (iy=0; iy<fdm->nypad; iy++) {
	    for    (ix=0; ix<fdm->nxpad; ix++) {
		for(iz=0; iz<fdm->nzpad; iz++) {
		    up[iy][ix][iz] = 2*uo[iy][ix][iz] 
			-              um[iy][ix][iz] 
			+              ua[iy][ix][iz] * vt[iy][ix][iz];
		}
	    }
	}

    if (srctype == DISPLACEMENT) {
        if(expl) {
            sf_floatread(ww, 1,Fwav);
            lint3d_inject1(up,ww[0],cs);
        } else {
            sf_floatread(ww,ns,Fwav);	
            lint3d_inject(up,ww,cs);
        }
    }
	/* circulate wavefield arrays */
	ut=um;
	um=uo;
	uo=up;
	up=ut;

    if(abcone) abcone3d_apply(uo,um,NOP,abc,fdm);
	if(dabc) {
	    /* one-way abc apply */
	    sponge3d_apply(um,spo,fdm);
	    sponge3d_apply(uo,spo,fdm);
	    sponge3d_apply(up,spo,fdm);
	}

	/* extract data */
    if (ignore_interpolation) {
	    cut3d_extract(uo,dd,cr);
    } else {
	    lint3d_extract(uo,dd,cr);
    }

	if(snap && it%jsnap==0) {
	    cut3d(uo,uc,fdm,acz,acx,acy);
	    sf_floatwrite(uc[0][0],sf_n(acz)*sf_n(acx)*sf_n(acy),Fwfl);
	}
	if(it%jdata==0) 
	    sf_floatwrite(dd,nr,Fdat);
    }
    if(verb) fprintf(stderr,"\n");    

    /*------------------------------------------------------------*/
    /* deallocate arrays */
    free(**um); free(*um); free(um);
    free(**up); free(*up); free(up);
    free(**uo); free(*uo); free(uo);
    free(**ua); free(*ua); free(ua);
    if (snap) { free(**uc); free(*uc); free(uc); }

    free(**rox); free(*rox); free(rox);
    free(**roy); free(*roy); free(roy);
    free(**roz); free(*roz); free(roz);

    free(**vp); free(*vp); free(vp);
    free(**vt); free(*vt); free(vt);

    free(ss);
    free(rr);
    free(dd);
    free(ww);

    exit (0);
    }
}
コード例 #11
0
ファイル: Mmpilsrtm.c プロジェクト: 1014511134/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 */
    
    /*I/O*/
    sf_file Fvel;
    sf_file left, right, leftb, rightb;
    sf_file Fsrc, Frcd/*source and record*/;
    sf_file Ftmpwf;
    sf_file Fimg;

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

    /*grid index variables*/
    int nx, nz, nt, wfnt;
    int nzx, nx2, nz2, n2, m2, m2b, pad1, nk;
    int ix, iz, it, is;
    int nxb, nzb;
    int snpint;
    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 rectz,rectx,repeat; /*smoothing parameters*/
    float trunc;
    int sht0,shtbgn,shtend,shtnum,shtnum0,shtint,shtcur;

    /*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=false; /*if n, receiver is independent of source location and gpl=nx*/
    /* 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;
    shtnum0 = shtnum;
    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 */
    /*--- 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;
    /* 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;

    /*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*/
    } else {
	Ftmpwf  = NULL;
    }

    /*--- 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;

    /* 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);

    if (!sf_histint(leftb,"n1",&n2) || n2 != nzx) sf_error("Need n1=%d in left",nzx);
    if (!sf_histint(leftb,"n2",&m2b))  sf_error("Need n2= in left");
    if (!sf_histint(rightb,"n1",&n2) || n2 != m2b) sf_error("Need n1=%d in right",m2b);
    if (!sf_histint(rightb,"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 != shtnum0 ) sf_error("Error parameter n3 in record!");
    }

    /*allocate memory*/
    ww=sf_complexalloc(nt);
    rr=sf_floatalloc(nzx);
    lt = sf_complexalloc2(nzx,m2);
    rt = sf_complexalloc2(m2,nk);
    ltb = sf_complexalloc2(nzx,m2b);
    rtb = sf_complexalloc2(m2b,nk);
    geop = (geopar) sf_alloc(1, sizeof(*geop));
    mpip = (mpipar) sf_alloc(1, sizeof(*mpip));
    tmprec = sf_complexalloc2(nt, gpl);
    if (shtnum%nodes!=0) {
      shtnum += nodes-shtnum%nodes;
      if (verb) sf_warning("Total shot number is not divisible by total number of nodes! shunum padded to %d.", shtnum);
    }
    if (rank==0) {
      record = sf_complexalloc3(nt, gpl, shtnum);
    } else record = NULL;
    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*m2b,leftb);
    sf_complexread(rtb[0],m2b*nk,rightb);
    if(!adj) sf_complexread(img[0],nx*nz,Fimg);
    if (rank==0) {
      if(adj && wantrecord) {
	sf_complexread(record[0][0], shtnum0*gpl*nt, Frcd);
	if (shtnum0%nodes!=0) {
#ifdef _OPENMP
#pragma omp parallel for private(is,ix,it)
#endif
	  for (is=shtnum0; is<shtnum; is++)
	    for (ix=0; ix<gpl; ix++)
	      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,shtnum0);
      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);
	sf_setd(at, wfdt);
	
	sf_oaxa(Ftmpwf, az, 1);
	sf_oaxa(Ftmpwf, ax, 2);
	sf_oaxa(Ftmpwf, at, 3);
	sf_settype(Ftmpwf,SF_COMPLEX);
      }
    }
    
    tstart = clock();

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

      shtcur = is*nodes+rank; // 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(wavefld, sill, tmprec, verb, lt, rt, m2, geop, ww, rr, pad1, illum);
      }

      if(adj && wantrecord) {
	if (rank==0) sendbuf = record[is*nodes][0];
	else sendbuf = NULL;
	recvbuf = tmprec[0];
	MPI_Scatter(sendbuf, gpl*nt, MPI_COMPLEX, recvbuf, gpl*nt, MPI_COMPLEX, 0, MPI_COMM_WORLD); // tmprec[ix][it] = record[is][ix][it];
      }
      
      if (shtcur<shtnum0) {
	lrosback2(img, wavefld, sill, tmprec, adj, verb, wantwf, ltb, rtb, m2b, geop, pad1, illum);
	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 || !wantrecord) {
	//	MPI_Barrier(MPI_COMM_WORLD);
	if (rank==0) recvbuf = record[is*nodes][0];
	else recvbuf = NULL;
	sendbuf = tmprec[0];
	MPI_Gather(sendbuf, gpl*nt, MPI_COMPLEX, recvbuf, gpl*nt, MPI_COMPLEX, 0, MPI_COMM_WORLD); // record[is][ix][it] = tmprec[ix][it];
      }

      if (wantwf && shtcur==0)
	sf_complexwrite(wavefld[0][0], wfnt*nx*nz, Ftmpwf);
    } /*shot iteration*/

    MPI_Barrier(MPI_COMM_WORLD);
    /*write record/image*/
    if (adj) {
      if (rank==0) {
#if MPI_VERSION >= 2
	sendbuf = (sf_complex *) MPI_IN_PLACE;
#else /* will fail */
	sendbuf = NULL;
#endif 
	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)
	sf_complexwrite(record[0][0], shtnum0*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);
    if (rank==0) {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);
    }

    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);
}