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