diff --git a/user/pyang/Mlsprtm2d.c b/user/pyang/Mlsprtm2d.c index 48460f2309..103d87f918 100644 --- a/user/pyang/Mlsprtm2d.c +++ b/user/pyang/Mlsprtm2d.c @@ -1,5 +1,4 @@ -/* least-squares prestack RTM in 2-D - */ +/* least-squares prestack RTM in 2-D */ /* Copyright (C) - 2014 Xi'an Jiaotong University, UT Austin (Pengliang Yang) @@ -26,145 +25,145 @@ int main(int argc, char* argv[]) { - bool verb, fromBoundary; - int nb, nz, nx, nt, ns, ng, niter, csd, sxbeg, szbeg, jsx, jsz, gxbeg, gzbeg, jgx, jgz; - float dz, dx, dt, fm, o1, o2, amp; - float **v0, *mod, *dat; - int testadj; + bool verb, fromBoundary; + int nb, nz, nx, nt, ns, ng, niter, csd, sxbeg, szbeg, jsx, jsz, gxbeg, gzbeg, jgx, jgz; + float dz, dx, dt, fm, o1, o2, amp; + float **v0, *mod, *dat; + int testadj; - sf_file shots, imglsm, imgrtm, velo;/* I/O files */ + sf_file shots, imglsm, imgrtm, velo;/* I/O files */ - /* initialize Madagascar */ - sf_init(argc,argv); + /* initialize Madagascar */ + sf_init(argc,argv); - shots = sf_input ("in"); /* shot records, data */ - velo = sf_input ("vel"); /* velocity */ - imglsm = sf_output("out"); /* output LSRTM imglsme, model */ - imgrtm = sf_output("imgrtm"); /* output RTM imglsme */ + shots = sf_input ("in"); /* shot records, data */ + velo = sf_input ("vel"); /* velocity */ + imglsm = sf_output("out"); /* output LSRTM imglsme, model */ + imgrtm = sf_output("imgrtm"); /* output RTM imglsme */ - if (!sf_histint(velo,"n1",&nz)) sf_error("n1"); - /* 1st dimension size */ - if (!sf_histint(velo,"n2",&nx)) sf_error("n2"); - /* 2nd dimension size */ - if (!sf_histfloat(velo,"d1",&dz)) sf_error("d1"); - /* d1 */ - if (!sf_histfloat(velo,"d2",&dx)) sf_error("d2"); - /* d2 */ - if (!sf_histfloat(velo,"o1",&o1)) sf_error("o1"); - /* o1 */ - if (!sf_histfloat(velo,"o2",&o2)) sf_error("o2"); - /* o2 */ - if (!sf_getbool("verb",&verb)) verb=true; - /* verbosity */ - if (!sf_getint("niter",&niter)) niter=10; - /* totol number of least-squares iteration*/ - if (!sf_getint("nb",&nb)) nb=20; - /* number (thickness) of ABC on each side */ - if (!sf_getbool("fromBoundary",&fromBoundary)) fromBoundary=true; - /* if fromBoundary=true, reconstruct source wavefield from stored boundary */ - if (!sf_getint("testadj",&testadj)) testadj=0; - /* if testadj = 1 then program only testadj without calculating */ + if (!sf_histint(velo,"n1",&nz)) sf_error("n1"); + /* 1st dimension size */ + if (!sf_histint(velo,"n2",&nx)) sf_error("n2"); + /* 2nd dimension size */ + if (!sf_histfloat(velo,"d1",&dz)) sf_error("d1"); + /* d1 */ + if (!sf_histfloat(velo,"d2",&dx)) sf_error("d2"); + /* d2 */ + if (!sf_histfloat(velo,"o1",&o1)) sf_error("o1"); + /* o1 */ + if (!sf_histfloat(velo,"o2",&o2)) sf_error("o2"); + /* o2 */ + if (!sf_getbool("verb",&verb)) verb=true; + /* verbosity */ + if (!sf_getint("niter",&niter)) niter=10; + /* totol number of least-squares iteration*/ + if (!sf_getint("nb",&nb)) nb=20; + /* number (thickness) of ABC on each side */ + if (!sf_getbool("fromBoundary",&fromBoundary)) fromBoundary=true; + /* if fromBoundary=true, reconstruct source wavefield from stored boundary */ + if (!sf_getint("testadj",&testadj)) testadj=0; + /* if testadj = 1 then program only testadj without calculating */ - if (!sf_histint(shots,"n1",&nt)) sf_error("no nt"); - /* total modeling time steps */ - if (!sf_histint(shots,"n2",&ng)) sf_error("no ng"); - /* total receivers in each shot */ - if (!sf_histint(shots,"n3",&ns)) sf_error("no ns"); - /* number of shots */ - if (!sf_histfloat(shots,"d1",&dt)) sf_error("no dt"); - /* time sampling interval */ - if (!sf_histfloat(shots,"amp",&)) sf_error("no amp"); - /* maximum amplitude of ricker */ - if (!sf_histfloat(shots,"fm",&fm)) sf_error("no fm"); - /* dominant freq of ricker */ - if (!sf_histint(shots,"sxbeg",&sxbeg)) sf_error("no sxbeg"); - /* x-begining index of sources, starting from 0 */ - if (!sf_histint(shots,"szbeg",&szbeg)) sf_error("no szbeg"); - /* x-begining index of sources, starting from 0 */ - if (!sf_histint(shots,"gxbeg",&gxbeg)) sf_error("no gxbeg"); - /* x-begining index of receivers, starting from 0 */ - if (!sf_histint(shots,"gzbeg",&gzbeg)) sf_error("no gzbeg"); - /* x-begining index of receivers, starting from 0 */ - if (!sf_histint(shots,"jsx",&jsx)) sf_error("no jsx"); - /* source x-axis jump interval */ - if (!sf_histint(shots,"jsz",&jsz)) sf_error("no jsz"); - /* source z-axis jump interval */ - if (!sf_histint(shots,"jgx",&jgx)) sf_error("no jgx"); - /* receiver x-axis jump interval */ - if (!sf_histint(shots,"jgz",&jgz)) sf_error("no jgz"); - /* receiver z-axis jump interval */ - if (!sf_histint(shots,"csdgather",&csd)) sf_error("csdgather or not required"); - /* default, common shot-gather; if n, record at every point*/ - - sf_putint(imglsm,"n1",nz); - sf_putint(imglsm,"n2",nx); - sf_putint(imglsm,"n3",1); - sf_putfloat(imglsm,"d1",dz); - sf_putfloat(imglsm,"d2",dx); - sf_putfloat(imglsm,"o1",o1); - sf_putfloat(imglsm,"o2",o2); - sf_putstring(imglsm,"label1","Depth"); - sf_putstring(imglsm,"label2","Distance"); - - sf_putint(imgrtm,"n1",nz); - sf_putint(imgrtm,"n2",nx); - sf_putint(imgrtm,"n3",1); - sf_putfloat(imgrtm,"d1",dz); - sf_putfloat(imgrtm,"d2",dx); - sf_putfloat(imgrtm,"o1",o1); - sf_putfloat(imgrtm,"o2",o2); - sf_putstring(imgrtm,"label1","Depth"); - sf_putstring(imgrtm,"label2","Distance"); - - /* In rtm, vv is the velocity model [modl], which is input parameter; - mod is the imglsme/reflectivity [imglsm]; dat is seismogram [data]! */ - v0=sf_floatalloc2(nz,nx); - mod=sf_floatalloc(nz*nx); - dat=sf_floatalloc(nt*ng*ns); - - /* initialize velocity, model and data */ - sf_floatread(v0[0], nz*nx, velo); - memset(mod, 0, nz*nx*sizeof(float)); - sf_floatread(dat, nt*ng*ns, shots); - prtm2d_init(verb, csd, fromBoundary, dz, dx, dt, amp, fm, nz, nx, nb, nt, ns, ng, - sxbeg, szbeg, jsx, jsz, gxbeg, gzbeg, jgx, jgz, v0, mod, dat); - - // run adjoint test first. - sf_warning("adjoint test \n"); - if (testadj){ - prtm2d_adjtest(); - sf_warning("exiting after testadj\n"); - mod=NULL; - sf_floatwrite(mod,nz*nx,imgrtm); - sf_floatwrite(mod,nz*nx,imglsm); + if (!sf_histint(shots,"n1",&nt)) sf_error("no nt"); + /* total modeling time steps */ + if (!sf_histint(shots,"n2",&ng)) sf_error("no ng"); + /* total receivers in each shot */ + if (!sf_histint(shots,"n3",&ns)) sf_error("no ns"); + /* number of shots */ + if (!sf_histfloat(shots,"d1",&dt)) sf_error("no dt"); + /* time sampling interval */ + if (!sf_histfloat(shots,"amp",&)) sf_error("no amp"); + /* maximum amplitude of ricker */ + if (!sf_histfloat(shots,"fm",&fm)) sf_error("no fm"); + /* dominant freq of ricker */ + if (!sf_histint(shots,"sxbeg",&sxbeg)) sf_error("no sxbeg"); + /* x-begining index of sources, starting from 0 */ + if (!sf_histint(shots,"szbeg",&szbeg)) sf_error("no szbeg"); + /* x-begining index of sources, starting from 0 */ + if (!sf_histint(shots,"gxbeg",&gxbeg)) sf_error("no gxbeg"); + /* x-begining index of receivers, starting from 0 */ + if (!sf_histint(shots,"gzbeg",&gzbeg)) sf_error("no gzbeg"); + /* x-begining index of receivers, starting from 0 */ + if (!sf_histint(shots,"jsx",&jsx)) sf_error("no jsx"); + /* source x-axis jump interval */ + if (!sf_histint(shots,"jsz",&jsz)) sf_error("no jsz"); + /* source z-axis jump interval */ + if (!sf_histint(shots,"jgx",&jgx)) sf_error("no jgx"); + /* receiver x-axis jump interval */ + if (!sf_histint(shots,"jgz",&jgz)) sf_error("no jgz"); + /* receiver z-axis jump interval */ + if (!sf_histint(shots,"csdgather",&csd)) sf_error("csdgather or not required"); + /* default, common shot-gather; if n, record at every point*/ + + sf_putint(imglsm,"n1",nz); + sf_putint(imglsm,"n2",nx); + sf_putint(imglsm,"n3",1); + sf_putfloat(imglsm,"d1",dz); + sf_putfloat(imglsm,"d2",dx); + sf_putfloat(imglsm,"o1",o1); + sf_putfloat(imglsm,"o2",o2); + sf_putstring(imglsm,"label1","Depth"); + sf_putstring(imglsm,"label2","Distance"); + + sf_putint(imgrtm,"n1",nz); + sf_putint(imgrtm,"n2",nx); + sf_putint(imgrtm,"n3",1); + sf_putfloat(imgrtm,"d1",dz); + sf_putfloat(imgrtm,"d2",dx); + sf_putfloat(imgrtm,"o1",o1); + sf_putfloat(imgrtm,"o2",o2); + sf_putstring(imgrtm,"label1","Depth"); + sf_putstring(imgrtm,"label2","Distance"); + + /* In rtm, vv is the velocity model [modl], which is input parameter; + mod is the imglsme/reflectivity [imglsm]; dat is seismogram [data]! */ + v0=sf_floatalloc2(nz,nx); + mod=sf_floatalloc(nz*nx); + dat=sf_floatalloc(nt*ng*ns); + + /* initialize velocity, model and data */ + sf_floatread(v0[0], nz*nx, velo); + memset(mod, 0, nz*nx*sizeof(float)); + sf_floatread(dat, nt*ng*ns, shots); + prtm2d_init(verb, csd, fromBoundary, dz, dx, dt, amp, fm, nz, nx, nb, nt, ns, ng, + sxbeg, szbeg, jsx, jsz, gxbeg, gzbeg, jgx, jgz, v0, mod, dat); + + // run adjoint test first. + sf_warning("adjoint test \n"); + if (testadj){ + prtm2d_adjtest(); + sf_warning("exiting after testadj\n"); + mod=NULL; + sf_floatwrite(mod,nz*nx,imgrtm); + sf_floatwrite(mod,nz*nx,imglsm); + prtm2d_close(); + free(*v0); free(v0); + free(mod); + free(dat); + exit (0); + } + + sf_warning("start migration\n"); + /* original RTM is simply applying adjoint of prtm2d_lop once!*/ + prtm2d_lop(true, false, nz*nx, nt*ng*ns, mod, dat); + sf_floatwrite(mod, nz*nx, imgrtm);/* output RTM image */ + sf_warning("migration ends"); + + if (niter>0){ + memset(mod, 0, nz*nx*sizeof(float)); + + sf_warning("inside LS loop niter= %d\n",niter); + /* least squares migration */ + sf_solver(prtm2d_lop, sf_cgstep, nz*nx, nt*ng*ns, mod, dat, niter, "verb", verb, "end"); + sf_floatwrite(mod, nz*nx, imglsm); /* output inverted image */ + sf_cgstep_close(); + } + prtm2d_close(); free(*v0); free(v0); free(mod); - free(dat); - exit (0); - } - - sf_warning("start migration\n"); - /* original RTM is simply applying adjoint of prtm2d_lop once!*/ - prtm2d_lop(true, false, nz*nx, nt*ng*ns, mod, dat); - sf_floatwrite(mod, nz*nx, imgrtm);/* output RTM image */ - sf_warning("migration ends"); - - if (niter>0){ - memset(mod, 0, nz*nx*sizeof(float)); - - sf_warning("inside LS loop niter= %d\n",niter); - /* least squares migration */ - sf_solver(prtm2d_lop, sf_cgstep, nz*nx, nt*ng*ns, mod, dat, niter, "verb", verb, "end"); - sf_floatwrite(mod, nz*nx, imglsm); /* output inverted image */ - sf_cgstep_close(); - } - - prtm2d_close(); - free(*v0); free(v0); - free(mod); - free(dat); + free(dat); - exit(0); + exit(0); } diff --git a/user/pyang/SConstruct b/user/pyang/SConstruct index 45262a8578..301ad67880 100644 --- a/user/pyang/SConstruct +++ b/user/pyang/SConstruct @@ -6,7 +6,7 @@ import bldutil ###################################################################### # 1. C main programs progs = ''' -cohn checkptdemo fwi2d fbrec2d istseislet lsrtm2d +cohn checkptdemo fwi2d fbrec2d istseislet lsrtm2d lsprtm2d mythresh mshots mcaseislet modeling2d mysnr pocsseislet rtm2d rtmadcig rtmodcig rtmva2d Testfd2d Testfd3d Testeb Testelastic2d Testaniso Testspml diff --git a/user/pyang/prtm2d.c b/user/pyang/prtm2d.c index 262adeb404..062ad5a830 100644 --- a/user/pyang/prtm2d.c +++ b/user/pyang/prtm2d.c @@ -17,115 +17,156 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + Comments: + Operator modified to pass the adjoint. Added adjoint tests as well. + Daniel Trad, Uinversity of Calgary, 2017 */ #include +#include +#include #ifdef _OPENMP #include #endif #include "prtm2d.h" - +static float ***sp0array; +static bool fromBoundary; static bool csdgather, verb; static int nzpad, nxpad, nb, nz, nx, nt, ns, ng, sxbeg, szbeg, jsx, jsz, gxbeg, gzbeg, jgx, jgz, distx, distz; static int *sxz, *gxz; static float c0, c11, c21, c12, c22; static float *wlt, *bndr,*rwbndr, *mod, *dat; static float **sp0, **sp1, **gp0, **gp1, **vv, **ptr=NULL; +int getTime(struct timeval t1, struct timeval t2){ + // return time in milliseconds; + return ((t2.tv_sec - t1.tv_sec)* 1000 + (t2.tv_usec - t1.tv_usec)/1000); +} +float compareWavefields(int it, float **u){ + ///*< compare current wavefield with true wavefield saved in sp0array >*/ + float sum =0; + for (int ix=nb;ix*/ { - int i1, i2; + int i1, i2; - if(adj){ + if(adj){ #ifdef _OPENMP #pragma omp parallel for default(none) \ - private(i2,i1) \ - shared(nzpad,nxpad,u1,vv,u0,c0,c11,c12,c21,c22) + private(i2,i1) \ + shared(nzpad,nxpad,u1,vv,u0,c0,c11,c12,c21,c22) #endif - for (i2=2; i2*/ { - int ix,iz,ib,ibx,ibz; - float w; + int ix,iz,ib,ibx,ibz; + float w; - for(ib=0; ib*/ { - int is, sz, sx; + int is, sz, sx; - for(is=0; is*/ { - int is, sx, sz; + int is, sx, sz; - if(add){/* add sources*/ + if(add){/* add sources*/ #ifdef _OPENMP #pragma omp parallel for default(none) \ - private(is,sx,sz) \ - shared(p,source,sxz,nb,ns,nz) + private(is,sx,sz) \ + shared(p,source,sxz,nb,ns,nz) #endif - for(is=0;isdestination(b) >*/ { - int iz,ix; + int iz,ix; #ifdef _OPENMP #pragma omp parallel for default(none) \ - private(ix,iz) \ - shared(b,a,nb,nz,nx) + private(ix,iz) \ + shared(b,a,nb,nz,nx) #endif - for (ix=0;ixdestination(a) >*/ { - int iz,ix; + int iz,ix; #ifdef _OPENMP #pragma omp parallel for default(none) \ - private(ix,iz) \ - shared(b,a,nb,nz,nx) + private(ix,iz) \ + shared(b,a,nb,nz,nx) #endif - for (ix=0;ix*/ { #ifdef _OPENMP - omp_init(); /* initialize OpenMP support */ + omp_init(); /* initialize OpenMP support */ #endif - float t; - int i1, i2, it,ib; - t = 1.0/(dz_*dz_); - c11 = 4.0*t/3.0; - c12= -t/12.0; - - t = 1.0/(dx_*dx_); - c21 = 4.0*t/3.0; - c22= -t/12.0; - c0=-2.0*(c11+c12+c21+c22); - - verb=verb_; - csdgather=csdgather_; - ns=ns_; - ng=ng_; - nb=nb_; - nz=nz_; - nx=nx_; - nt=nt_; - sxbeg=sxbeg_; - szbeg=szbeg_; - jsx=jsx_; - jsz=jsz_; - gxbeg=gxbeg_; - gzbeg=gzbeg_; - jgx=jgx_; - jgz=jgz_; - - nzpad=nz+2*nb; - nxpad=nx+2*nb; - - /* allocate temporary arrays */ - bndr=sf_floatalloc(nb); - sp0=sf_floatalloc2(nzpad,nxpad); - sp1=sf_floatalloc2(nzpad,nxpad); - gp0=sf_floatalloc2(nzpad,nxpad); - gp1=sf_floatalloc2(nzpad,nxpad); - vv=sf_floatalloc2(nzpad,nxpad); - wlt=sf_floatalloc(nt); - sxz=sf_intalloc(ns); - gxz=sf_intalloc(ng); - rwbndr=sf_floatalloc(nt*4*(nx+nz)); - - /* initialized sponge ABC coefficients */ - for(ib=0;ib=0 && szbeg>=0 && sxbeg+(ns-1)*jsx=0 && szbeg>=0 && sxbeg+(ns-1)*jsx=0 && gzbeg>=0 && gxbeg+(ng-1)*jgx=0 && gzbeg>=0 && gxbeg+(ng-1)*jgx*/ { - free(bndr); - free(*sp0); free(sp0); - free(*sp1); free(sp1); - free(*gp0); free(gp0); - free(*gp1); free(gp1); - free(*vv); free(vv); - free(wlt); - free(sxz); - free(gxz); + free(bndr); + if (!fromBoundary){ free(**sp0array);free(*sp0array);free(sp0array);} + free(*sp0); free(sp0); + free(*sp1); free(sp1); + free(*gp0); free(gp0); + free(*gp1); free(gp1); + free(*vv); free(vv); + free(wlt); + free(sxz); + free(gxz); +} + +void prtm2d_shotwav(int is) +/*< prtm2d shot wavefield generated at front >*/ +{ + int it; + + /* initialize is-th source wavefield Ps[] */ + memset(sp0[0], 0, nzpad*nxpad*sizeof(float)); + memset(sp1[0], 0, nzpad*nxpad*sizeof(float)); + memset(gp0[0], 0, nzpad*nxpad*sizeof(float)); + memset(gp1[0], 0, nzpad*nxpad*sizeof(float)); + + for(it=0; it*/ { - int i1,i2,it,is,ig, gx, gz; - if(nm!=nx*nz) sf_error("model size mismatch: %d!=%d",nm, nx*nz); - if(nd!=nt*ng*ns) sf_error("data size mismatch: %d!=%d",nd,nt*ng*ns); - sf_adjnull(adj, add, nm, nd, mod, dat); - - for(is=0; is-1; it--) { + /* reverse time order, Img[]+=Ps[]* Pg[]; */ + + /* backpropagate receiver wavefield */ + for(ig=0;ig-1; it--) { - /* reverse time order, Img[]+=Ps[]* Pg[]; */ - if(verb) sf_warning("%d;",it); - - /* reconstruct source wavefield Ps[] */ - boundary_rw(sp0, &rwbndr[it*4*(nx+nz)], true); - ptr=sp0; sp0=sp1; sp1=ptr; - step_forward(sp0, sp1, vv, false); - add_source(&sxz[is], sp1, 1, &wlt[it], false); - - /* backpropagate receiver wavefield */ - for(ig=0;ig*/ +{ + unsigned int i; + float dotdata,dotmodel; + + unsigned int datasize =ng*nt*ns; + unsigned int modelsize=nx*nz; + float* m1=sf_floatalloc(modelsize); + float* m2=sf_floatalloc(modelsize); + float* d1=sf_floatalloc(datasize); + float* d2=sf_floatalloc(datasize); + + for (i=0;i