void gradient_standard(float *x, float *fcost, float *grad) /*< standard velocity gradient >*/ { int ix, iz, is, ir, it, wit, iturn; int sx, rx; float temp, dmax; float **p0, **p1, **p2, **term, **tmparray, *rr, ***wave, **pp; float *sendbuf, *recvbuf; /* residual file */ sf_file Fres; Fres=sf_output("Fres"); sf_putint(Fres,"n1",nt); sf_putint(Fres,"n2",nr); /* initialize fcost */ *fcost=0.; /* update velocity */ pad2d(x, vv, nz, nx, nb); /* initialize gradient */ memset(grad, 0., nzx*sizeof(float)); /* initialize data misfit */ swap=0.; /* memory allocation */ p0=sf_floatalloc2(padnz, padnx); p1=sf_floatalloc2(padnz, padnx); p2=sf_floatalloc2(padnz, padnx); term=sf_floatalloc2(padnz, padnx); rr=sf_floatalloc(padnzx); wave=sf_floatalloc3(nz, nx, wnt); pp=sf_floatalloc2(nt, nr); iturn=0; for(is=cpuid; is<ns; is+=numprocs){ if(cpuid==0) sf_warning("###### is=%d ######", is+1); memset(p0[0], 0., padnzx*sizeof(float)); memset(p1[0], 0., padnzx*sizeof(float)); memset(p2[0], 0., padnzx*sizeof(float)); memset(pp[0], 0., nr*nt*sizeof(float)); sx=s0_v+is*ds_v; source_map(sx, sz, frectx, frectz, padnx, padnz, padnzx, rr); wit=0; /* forward propagation */ for(it=0; it<nt; it++){ if(verb) sf_warning("Forward propagation is=%d; it=%d;", is+1, it); /* output predicted data */ for(ir=0; ir<nr2[is]; ir++){ rx=r0_v[is]+ir*dr_v; pp[r02[is]+ir][it]=p1[rx][rz]; } /* save wavefield */ if(it%interval==0){ #ifdef _OPENMP #pragma omp parallel for \ private(ix,iz) \ shared(wave,p1,wit,nb,nx,nz) #endif for(ix=0; ix<nx; ix++) for(iz=0; iz<nz; iz++) wave[wit][ix][iz]=p1[ix+nb][iz+nb]; wit++; } /* laplacian operator */ laplace(p1, term, padnx, padnz, dx2, dz2); /* load source */ #ifdef _OPENMP #pragma omp parallel for \ private(ix,iz) \ shared(term,rr,padnx,padnz,ww,it) #endif for(ix=0; ix<padnx; ix++){ for(iz=0; iz<padnz; iz++){ term[ix][iz] += rr[ix*padnz+iz]*ww[it]; } } /* update */ #ifdef _OPENMP #pragma omp parallel for \ private(ix,iz) \ shared(p0,p1,p2,vv,term,padnx,padnz,dt2) #endif for(ix=4; ix<padnx-4; ix++){ for(iz=4; iz<padnz-4; iz++){ p2[ix][iz]=2*p1[ix][iz]-p0[ix][iz]+vv[ix][iz]*vv[ix][iz]*dt2*term[ix][iz]; } } /* swap wavefield pointer of different time steps */ tmparray=p0; p0=p1; p1=p2; p2=tmparray; /* boundary condition */ apply_sponge(p0, bc, padnx, padnz, nb); apply_sponge(p1, bc, padnx, padnz, nb); } // end of time loop /* check */ if(wit != wnt) sf_error("Incorrect number of wavefield snapshots"); wit--; /* calculate data residual and data misfit */ for(ir=0; ir<nr; ir++){ for(it=0; it<nt; it++){ pp[ir][it]=dd[iturn][ir][it]-pp[ir][it]; pp[ir][it] *= weight[ir][it]; swap += 0.5*pp[ir][it]*pp[ir][it]; } } smooth_misfit(pp, fcost, nr, nt, drectx, drectz, nrepeat, ider); iturn++; /* check the data residual */ if(is==ns/2) sf_floatwrite(pp[0], nr*nt, Fres); sf_fileclose(Fres); /* initialization */ memset(p0[0], 0., padnzx*sizeof(float)); memset(p1[0], 0., padnzx*sizeof(float)); memset(p2[0], 0., padnzx*sizeof(float)); memset(term[0], 0., padnzx*sizeof(float)); /* backward propagation */ for(it=nt-1; it>=0; it--){ if(verb) sf_warning("Backward propagation is=%d; it=%d;", is+1, it); /* laplacian operator */ laplace(p1, term, padnx, padnz, dx2, dz2); /* load data residual */ for(ir=0; ir<nr2[is]; ir++){ rx=r0_v[is]+ir*dr_v; term[rx][rz] += pp[r02[is]+ir][it]; } /* update */ #ifdef _OPENMP #pragma omp parallel for \ private(ix,iz) \ shared(p0,p1,p2,vv,term,padnx,padnz,dt2) #endif for(ix=4; ix<padnx-4; ix++){ for(iz=4; iz<padnz-4; iz++){ p2[ix][iz]=2*p1[ix][iz]-p0[ix][iz]+vv[ix][iz]*vv[ix][iz]*dt2*term[ix][iz]; } } /* calculate gradient */ if(it%interval==0){ if(wit != wnt-1 && wit != 0){ // avoid the first and last time step #ifdef _OPENMP #pragma omp parallel for \ private(ix,iz,temp) \ shared(nx,nz,vv,wave,p1,wit,wdt2,grad) #endif for(ix=0; ix<nx; ix++){ for(iz=0; iz<nz; iz++){ temp=vv[ix+nb][iz+nb]; temp=temp*temp*temp; temp=-2./temp; grad[ix*nz+iz] += (wave[wit+1][ix][iz]-2.*wave[wit][ix][iz]+wave[wit-1][ix][iz])/wdt2*p1[ix+nb][iz+nb]*temp; } } } wit--; } /* swap wavefield pointer of different time steps */ tmparray=p0; p0=p1; p1=p2; p2=tmparray; /* boundary condition */ apply_sponge(p0, bc, padnx, padnz, nb); apply_sponge(p1, bc, padnx, padnz, nb); } // end of time loop }// end of shot loop MPI_Barrier(comm); /* misfit reduction */ //MPI_ALLreduce(sendbuf, recvbuf, 1, MPI_FLOAT, MPI_SUM, comm); if(cpuid==0){ sendbuf=MPI_IN_PLACE; recvbuf=fcost; }else{ sendbuf=fcost; recvbuf=NULL; } MPI_Reduce(sendbuf, recvbuf, 1, MPI_FLOAT, MPI_SUM, 0, comm); MPI_Bcast(fcost, 1, MPI_FLOAT, 0, comm); if(cpuid==0){ sendbuf=MPI_IN_PLACE; recvbuf=&swap; }else{ sendbuf=&swap; recvbuf=NULL; } MPI_Reduce(sendbuf, recvbuf, 1, MPI_FLOAT, MPI_SUM, 0, comm); MPI_Bcast(&swap, 1, MPI_FLOAT, 0, comm); /* gradient reduction */ //MPI_ALLreduce(sendbuf, recvbuf, nzx, MPI_FLOAT, MPI_SUM, comm); if(cpuid==0){ sendbuf=MPI_IN_PLACE; recvbuf=grad; }else{ sendbuf=grad; recvbuf=NULL; } MPI_Reduce(sendbuf, recvbuf, nzx, MPI_FLOAT, MPI_SUM, 0, comm); MPI_Bcast(grad, nzx, MPI_FLOAT, 0, comm); /* scaling gradient */ if(first){ dmax=0.; for(ix=0; ix<nzx; ix++) if(fabsf(grad[ix])>dmax) dmax=fabsf(grad[ix]); scaling=0.1/dmax; first=false; } /* smooth gradient */ gradient_smooth2(grectx, grectz, nx, nz, waterz, scaling, grad); /* free allocated memory */ free(*p0); free(p0); free(*p1); free(p1); free(*p2); free(p2); free(*pp); free(pp); free(**wave); free(*wave); free(wave); free(rr); free(*term); free(term); }
void rtm(sf_file Fdat, sf_file Fimg, sf_mpi *mpipar, sf_sou soupar, sf_acqui acpar, sf_vec_s array, bool verb) /*< acoustic rtm >*/ { int ix, iz, is, ir, it, wit; int sx, rx, sz, rz, frectx, frectz; int nz, nx, nzx, padnz, padnx, padnzx, nt, nr, nb, wnt; float dx2, dz2, dt2, dt; float **vv, **dd, **mm; float **p0, **p1, **p2, **term, **tmparray, *rr, ***wave; float *sendbuf, *recvbuf; //sf_file Fwfl1, Fwfl2; //Fwfl1=sf_output("Fwfl1"); //Fwfl2=sf_output("Fwfl2"); MPI_Comm comm=MPI_COMM_WORLD; nz=acpar->nz; nx=acpar->nx; nzx=nz*nx; padnz=acpar->padnz; padnx=acpar->padnx; padnzx=padnz*padnx; nr=acpar->nr; nb=acpar->nb; sz=acpar->sz; rz=acpar->rz; frectx=soupar->frectx; frectz=soupar->frectz; nt=acpar->nt; wnt=(nt-1)/acpar->interval+1; dx2=acpar->dx*acpar->dx; dz2=acpar->dz*acpar->dz; dt2=acpar->dt*acpar->dt; dt=acpar->dt; //sf_putint(Fwfl1, "n1", padnz); //sf_putint(Fwfl1, "n2",padnx); //sf_putint(Fwfl1, "n3",(nt-1)/50+1); //sf_putint(Fwfl2, "n1", padnz); //sf_putint(Fwfl2, "n2",padnx); //sf_putint(Fwfl2, "n3",(nt-1)/50+1); /* memory allocation */ vv = sf_floatalloc2(padnz, padnx); dd=sf_floatalloc2(nt, nr); mm=sf_floatalloc2(nz, nx); p0=sf_floatalloc2(padnz, padnx); p1=sf_floatalloc2(padnz, padnx); p2=sf_floatalloc2(padnz, padnx); term=sf_floatalloc2(padnz, padnx); rr=sf_floatalloc(padnzx); wave=sf_floatalloc3(nz, nx, wnt); /* padding and convert vector to 2-d array */ pad2d(array->vv, vv, nz, nx, nb); memset(mm[0], 0., nzx*sizeof(float)); for(is=mpipar->cpuid; is<acpar->ns; is+=mpipar->numprocs){ sf_warning("###### is=%d ######", is+1); memset(p0[0], 0., padnzx*sizeof(float)); memset(p1[0], 0., padnzx*sizeof(float)); memset(p2[0], 0., padnzx*sizeof(float)); sx=acpar->s0_v+is*acpar->ds_v; source_map(sx, sz, frectx, frectz, padnx, padnz, padnzx, rr); wit=0; /* forward propagation */ for(it=0; it<nt; it++){ if(verb) sf_warning("Forward propagation is=%d; it=%d;", is+1, it); /* save wavefield */ if(it%acpar->interval==0){ #ifdef _OPENMP #pragma omp parallel for \ private(ix,iz) \ shared(wave,p1,wit,nb,nx,nz) #endif for(ix=0; ix<nx; ix++) for(iz=0; iz<nz; iz++) wave[wit][ix][iz]=p1[ix+nb][iz+nb]; wit++; } //if(is==acpar->ns/2 && it%50==0) sf_floatwrite(p1[0],padnzx, Fwfl1); /* laplacian operator */ laplace(p1, term, padnx, padnz, dx2, dz2); /* load source */ #ifdef _OPENMP #pragma omp parallel for \ private(ix,iz) \ shared(term,rr,padnx,padnz,it) #endif for(ix=0; ix<padnx; ix++){ for(iz=0; iz<padnz; iz++){ term[ix][iz] += rr[ix*padnz+iz]*array->ww[it]; } } /* update */ #ifdef _OPENMP #pragma omp parallel for \ private(ix,iz) \ shared(p0,p1,p2,vv,term,padnx,padnz,dt2) #endif for(ix=4; ix<padnx-4; ix++){ for(iz=4; iz<padnz-4; iz++){ p2[ix][iz]=2*p1[ix][iz]-p0[ix][iz]+vv[ix][iz]*vv[ix][iz]*dt2*term[ix][iz]; } } /* swap wavefield pointer of different time steps */ tmparray=p0; p0=p1; p1=p2; p2=tmparray; /* boundary condition */ apply_sponge(p0, acpar->bc, padnx, padnz, nb); apply_sponge(p1, acpar->bc, padnx, padnz, nb); } // end of time loop /* check */ if(wit != wnt) sf_error("Incorrect number of wavefield snapshots"); wit--; /* read data */ sf_seek(Fdat, is*nr*nt*sizeof(float), SEEK_SET); sf_floatread(dd[0], nr*nt, Fdat); /* initialization */ memset(p0[0], 0., padnzx*sizeof(float)); memset(p1[0], 0., padnzx*sizeof(float)); memset(p2[0], 0., padnzx*sizeof(float)); memset(term[0], 0., padnzx*sizeof(float)); /* backward propagation */ for(it=nt-1; it>=0; it--){ if(verb) sf_warning("Backward propagation is=%d; it=%d;", is+1, it); /* laplacian operator */ laplace(p1, term, padnx, padnz, dx2, dz2); /* load data */ for(ir=0; ir<acpar->nr2[is]; ir++){ rx=acpar->r0_v[is]+ir*acpar->dr_v; term[rx][rz] += dd[acpar->r02[is]+ir][it]; } /* update */ #ifdef _OPENMP #pragma omp parallel for \ private(ix,iz) \ shared(p0,p1,p2,vv,term,padnx,padnz,dt2) #endif for(ix=4; ix<padnx-4; ix++){ for(iz=4; iz<padnz-4; iz++){ p2[ix][iz]=2*p1[ix][iz]-p0[ix][iz]+vv[ix][iz]*vv[ix][iz]*dt2*term[ix][iz]; } } //if(is==acpar->ns/2 && it%50==0) sf_floatwrite(p1[0],padnzx, Fwfl2); /* calculate image */ if(it%acpar->interval==0){ #ifdef _OPENMP #pragma omp parallel for \ private(ix,iz) \ shared(p1,wave,nx,nz,wit,mm,nb) #endif for(ix=0; ix<nx; ix++) for(iz=0; iz<nz; iz++) mm[ix][iz] += wave[wit][ix][iz]*p1[ix+nb][iz+nb]; wit--; } /* swap wavefield pointer of different time steps */ tmparray=p0; p0=p1; p1=p2; p2=tmparray; /* boundary condition */ apply_sponge(p0, acpar->bc, padnx, padnz, nb); apply_sponge(p1, acpar->bc, padnx, padnz, nb); } // end of time loop }// end of shot loop MPI_Barrier(comm); //sf_fileclose(Fwfl1); //sf_fileclose(Fwfl2); if(mpipar->cpuid==0){ sendbuf=MPI_IN_PLACE; recvbuf=mm[0]; }else{ sendbuf=mm[0]; recvbuf=NULL; } MPI_Reduce(sendbuf, recvbuf, nzx, MPI_FLOAT, MPI_SUM, 0, comm); if(mpipar->cpuid==0) sf_floatwrite(mm[0], nzx, Fimg); MPI_Barrier(comm); /* release allocated memory */ free(*p0); free(p0); free(*p1); free(p1); free(*p2); free(p2); free(*vv); free(vv); free(*dd); free(dd); free(*mm); free(mm); free(rr); free(*term); free(term); free(**wave); free(*wave); free(wave); }
void forward_modeling_a(sf_file Fdat, sf_mpi *mpipar, sf_sou soupar, sf_acqui acpar, sf_vec array, bool verb) /*< acoustic forward modeling >*/ { int ix, iz, is, ir, it; int sx, rx, sz, rz, rectx, rectz; int nz, nx, padnz, padnx, padnzx, nt, nr, nb; float dx2, dz2, dt2, dt; float **vv, **dd; float **p0, **p1, **p2, **term, **tmparray, *rr; FILE *swap; MPI_Comm comm=MPI_COMM_WORLD; swap=fopen("temswap.bin", "wb+"); padnz=acpar->padnz; padnx=acpar->padnx; padnzx=padnz*padnx; nz=acpar->nz; nx=acpar->nx; nt=acpar->nt; nr=acpar->nr; nb=acpar->nb; sz=acpar->sz; rz=acpar->rz; rectx=soupar->rectx; rectz=soupar->rectz; dx2=acpar->dx*acpar->dx; dz2=acpar->dz*acpar->dz; dt2=acpar->dt*acpar->dt; dt=acpar->dt; vv = sf_floatalloc2(padnz, padnx); dd=sf_floatalloc2(nt, nr); p0=sf_floatalloc2(padnz, padnx); p1=sf_floatalloc2(padnz, padnx); p2=sf_floatalloc2(padnz, padnx); term=sf_floatalloc2(padnz, padnx); rr=sf_floatalloc(padnzx); /* padding and convert vector to 2-d array */ pad2d(array->vv, vv, nz, nx, nb); for(is=mpipar->cpuid; is<acpar->ns; is+=mpipar->numprocs){ sf_warning("###### is=%d ######", is+1); memset(dd[0], 0., nr*nt*sizeof(float)); memset(p0[0], 0., padnzx*sizeof(float)); memset(p1[0], 0., padnzx*sizeof(float)); memset(p2[0], 0., padnzx*sizeof(float)); sx=acpar->s0_v+is*acpar->ds_v; source_map(sx, sz, rectx, rectz, padnx, padnz, padnzx, rr); for(it=0; it<nt; it++){ if(verb) sf_warning("Modeling is=%d; it=%d;", is+1, it); /* output data */ for(ir=0; ir<acpar->nr2[is]; ir++){ rx=acpar->r0_v[is]+ir*acpar->dr_v; dd[acpar->r02[is]+ir][it]=p1[rx][rz]; } /* laplacian operator */ laplace(p1, term, padnx, padnz, dx2, dz2); /* load source */ for(ix=0; ix<padnx; ix++){ for(iz=0; iz<padnz; iz++){ term[ix][iz] += rr[ix*padnz+iz]*array->ww[it]; } } /* update */ for(ix=0; ix<padnx; ix++){ for(iz=0; iz<padnz; iz++){ p2[ix][iz]=2*p1[ix][iz]-p0[ix][iz]+vv[ix][iz]*vv[ix][iz]*dt2*term[ix][iz]; } } /* swap wavefield pointer of different time steps */ tmparray=p0; p0=p1; p1=p2; p2=tmparray; /* boundary condition */ apply_sponge(p0, acpar->bc, padnx, padnz, nb); apply_sponge(p1, acpar->bc, padnx, padnz, nb); } // end of time loop fseeko(swap, is*nr*nt*sizeof(float), SEEK_SET); fwrite(dd[0], sizeof(float), nr*nt, swap); }// end of shot loop fclose(swap); MPI_Barrier(comm); /* transfer data to Fdat */ if(mpipar->cpuid==0){ swap=fopen("temswap.bin", "rb"); for(is=0; is<acpar->ns; is++){ fseeko(swap, is*nr*nt*sizeof(float), SEEK_SET); fread(dd[0], sizeof(float), nr*nt, swap); sf_floatwrite(dd[0], nr*nt, Fdat); } fclose(swap); remove("temswap.bin"); } MPI_Barrier(comm); /* release allocated memory */ free(*p0); free(p0); free(*p1); free(p1); free(*p2); free(p2); free(*vv); free(vv); free(*dd); free(dd); free(rr); free(*term); free(term); }
void rtm_q(sf_file Fdat, sf_file Fimg, sf_mpi *mpipar, sf_sou soupar, sf_acqui acpar, sf_vec_q array, bool verb) /*< visco-acoustic rtm >*/ { int ix, iz, is, ir, it, wit; int sx, rx, sz, rz, frectx, frectz; int nz, nx, nzx, padnz, padnx, padnzx, nt, nr, nb, wnt; float dx2, dz2, dt2, dt; float **vv, **tau, **taus, **dd, **mm; float **p0, **p1, **p2, **r1, **r2, **term, **tmparray, *rr, ***wave; float *sendbuf, *recvbuf; MPI_Comm comm=MPI_COMM_WORLD; nz=acpar->nz; nx=acpar->nx; nzx=nz*nx; padnz=acpar->padnz; padnx=acpar->padnx; padnzx=padnz*padnx; nr=acpar->nr; nb=acpar->nb; sz=acpar->sz; rz=acpar->rz; frectx=soupar->frectx; frectz=soupar->frectz; nt=acpar->nt; wnt=(nt-1)/acpar->interval+1; dx2=acpar->dx*acpar->dx; dz2=acpar->dz*acpar->dz; dt2=acpar->dt*acpar->dt; dt=acpar->dt; /* memory allocation */ vv = sf_floatalloc2(padnz, padnx); tau= sf_floatalloc2(padnz, padnx); taus=sf_floatalloc2(padnz, padnx); dd=sf_floatalloc2(nt, nr); mm=sf_floatalloc2(nz, nx); p0=sf_floatalloc2(padnz, padnx); p1=sf_floatalloc2(padnz, padnx); p2=sf_floatalloc2(padnz, padnx); r1=sf_floatalloc2(padnz, padnx); r2=sf_floatalloc2(padnz, padnx); term=sf_floatalloc2(padnz, padnx); rr=sf_floatalloc(padnzx); wave=sf_floatalloc3(nz, nx, wnt); /* padding and convert vector to 2-d array */ pad2d(array->vv, vv, nz, nx, nb); pad2d(array->tau, tau, nz, nx, nb); pad2d(array->taus, taus, nz, nx, nb); memset(mm[0], 0., nzx*sizeof(float)); for(is=mpipar->cpuid; is<acpar->ns; is+=mpipar->numprocs){ sf_warning("###### is=%d ######", is+1); memset(p0[0], 0., padnzx*sizeof(float)); memset(p1[0], 0., padnzx*sizeof(float)); memset(p2[0], 0., padnzx*sizeof(float)); memset(r1[0], 0., padnzx*sizeof(float)); memset(r2[0], 0., padnzx*sizeof(float)); memset(term[0], 0., padnzx*sizeof(float)); sx=acpar->s0_v+is*acpar->ds_v; source_map(sx, sz, frectx, frectz, padnx, padnz, padnzx, rr); wit=0; /* forward propagation */ for(it=0; it<nt; it++){ if(verb) sf_warning("Forward propagation is=%d; it=%d;", is+1, it); /* save wavefield */ if(it%acpar->interval==0){ for(ix=0; ix<nx; ix++) for(iz=0; iz<nz; iz++) wave[wit][ix][iz]=p1[ix+nb][iz+nb]; wit++; } /* load source */ for(ix=0; ix<padnx; ix++){ for(iz=0; iz<padnz; iz++){ p1[ix][iz] += rr[ix*padnz+iz]*array->ww[it]; } } /* laplacian operator */ laplace(p1, term, padnx, padnz, dx2, dz2); /* update */ for(ix=4; ix<padnx-4; ix++){ for(iz=4; iz<padnz-4; iz++){ r2[ix][iz]= (-tau[ix][iz]/taus[ix][iz]*term[ix][iz] + (1./dt-0.5/taus[ix][iz])*r1[ix][iz]) /(1./dt+0.5/taus[ix][iz]); term[ix][iz]=term[ix][iz]*(1.+tau[ix][iz])+(r2[ix][iz]+r1[ix][iz])*0.5; p2[ix][iz]=2*p1[ix][iz]-p0[ix][iz]+vv[ix][iz]*vv[ix][iz]*dt2*term[ix][iz]; } } /* swap wavefield pointer of different time steps */ tmparray=p0; p0=p1; p1=p2; p2=tmparray; tmparray=r1; r1=r2; r2=tmparray; /* boundary condition */ apply_sponge(p0, acpar->bc, padnx, padnz, nb); apply_sponge(p1, acpar->bc, padnx, padnz, nb); apply_sponge(r1, acpar->bc, padnx, padnz, nb); } // end of time loop /* check */ if(wit != wnt) sf_error("Incorrect number of wavefield snapshots"); /* read data */ sf_seek(Fdat, is*nr*nt*sizeof(float), SEEK_SET); sf_floatread(dd[0], nr*nt, Fdat); /* initialization */ memset(p0[0], 0., padnzx*sizeof(float)); memset(p1[0], 0., padnzx*sizeof(float)); memset(p2[0], 0., padnzx*sizeof(float)); memset(r1[0], 0., padnzx*sizeof(float)); memset(r2[0], 0., padnzx*sizeof(float)); memset(term[0], 0., padnzx*sizeof(float)); /* backward propagation */ for(it=nt-1; it>=0; it--){ if(verb) sf_warning("Backward propagation is=%d; it=%d;", is+1, it); /* load data */ for(ir=0; ir<acpar->nr2[is]; ir++){ rx=acpar->r0_v[is]+ir*acpar->dr_v; p1[rx][rz]=dd[acpar->r02[is]+ir][it]; } /* laplacian operator */ laplace(p1, term, padnx, padnz, dx2, dz2); /* update */ for(ix=4; ix<padnx-4; ix++){ for(iz=4; iz<padnz-4; iz++){ r2[ix][iz]= (-tau[ix][iz]/taus[ix][iz]*term[ix][iz] + (1./dt-0.5/taus[ix][iz])*r1[ix][iz]) /(1./dt+0.5/taus[ix][iz]); term[ix][iz]=term[ix][iz]*(1.+tau[ix][iz])+(r2[ix][iz]+r1[ix][iz])*0.5; p2[ix][iz]=2*p1[ix][iz]-p0[ix][iz]+vv[ix][iz]*vv[ix][iz]*dt2*term[ix][iz]; } } /* calculate image */ if(it%acpar->interval==0){ for(ix=0; ix<nx; ix++) for(iz=0; iz<nz; iz++) mm[ix][iz] += wave[wit-1][ix][iz]*p2[ix+nb][iz+nb]; wit--; } /* swap wavefield pointer of different time steps */ tmparray=p0; p0=p1; p1=p2; p2=tmparray; tmparray=r1; r1=r2; r2=tmparray; /* boundary condition */ apply_sponge(p0, acpar->bc, padnx, padnz, nb); apply_sponge(p1, acpar->bc, padnx, padnz, nb); apply_sponge(r1, acpar->bc, padnx, padnz, nb); } // end of time loop }// end of shot loop MPI_Barrier(comm); if(mpipar->cpuid==0){ sendbuf=MPI_IN_PLACE; recvbuf=mm[0]; }else{ sendbuf=mm[0]; recvbuf=NULL; } MPI_Reduce(sendbuf, recvbuf, nzx, MPI_FLOAT, MPI_SUM, 0, comm); if(mpipar->cpuid==0) sf_floatwrite(mm[0], nzx, Fimg); MPI_Barrier(comm); }