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

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

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

    clock_t tstart,tend;
    double duration;

    int shtcur;

    sf_complex *sendbuf, *recvbuf;

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

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

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

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

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

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

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

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

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

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

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

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

    } /*shot iteration*/

    MPI_Barrier(MPI_COMM_WORLD);

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

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

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

    return 0;
}
Example #2
0
/* main function */
int main(int argc, char* argv[])
{
    clock_t tstart,tend;
    double duration;

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

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

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

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

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

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

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

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

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

    /*tmp*/
    int tmpint;

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

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

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

    sf_init(argc, argv);

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

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

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

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

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

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

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

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

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

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

    }

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

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

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

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

    /* output RSF files */

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

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

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

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

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

    tstart = clock();

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

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

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

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

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

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

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

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

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

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

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

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

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

    MPI_Finalize();
    exit(0);
}
Example #3
0
int main(int argc, char* argv[]) 
{
    clock_t tstart,tend;
    double duration;

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

    sf_axis at, ax, az;

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

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

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

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

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

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

    /*memoray*/
    int tmpint;

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

    /*Set I/O file*/

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    tend = clock();
    duration=(double)(tend-tstart)/CLOCKS_PER_SEC;
    sf_warning(">> The CPU time of single shot migration is: %f seconds << ", duration);
    exit(0);
}
Example #4
0
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);

}