void gradient_init(sf_file Fdat, sf_mpi *mpipar, sf_sou soupar, sf_acqui acpar, sf_vec_s array, sf_fwi_s fwipar, bool verb1) /*< initialize >*/ { int iturn, is; verb=verb1; first=true; // only at the first iteration (for calculating the gradient scaling parameter) cpuid=mpipar->cpuid; numprocs=mpipar->numprocs; nz=acpar->nz; nx=acpar->nx; nzx=nz*nx; padnz=acpar->padnz; padnx=acpar->padnx; padnzx=padnz*padnx; nb=acpar->nb; nt=acpar->nt; ns=acpar->ns; ds_v=acpar->ds_v; s0_v=acpar->s0_v; sz=acpar->sz; nr=acpar->nr; dr_v=acpar->dr_v; rz=acpar->rz; nr2=acpar->nr2; r02=acpar->r02; r0_v=acpar->r0_v; frectx=soupar->frectx; frectz=soupar->frectz; interval=acpar->interval; wnt=(nt-1)/interval+1; dt=acpar->dt; dt2=dt*dt; wdt=dt*interval; wdt2=wdt*wdt; dx2=acpar->dx*acpar->dx; dz2=acpar->dz*acpar->dz; /* smoothing kernel parameters */ drectx=fwipar->drectx; drectz=fwipar->drectz; nrepeat=fwipar->nrepeat; ider=fwipar->ider; /* gradient preconditioning */ waterz=fwipar->waterz; grectx=fwipar->grectx; grectz=fwipar->grectz; /* data residual weighting */ gain=fwipar->gain; wt1=fwipar->wt1; wt2=fwipar->wt2; woff1=fwipar->woff1; woff2=fwipar->woff2; wtn1=(wt1-acpar->t0)/dt+0.5; wtn2=(wt2-acpar->t0)/dt+0.5; woffn1=(woff1-acpar->r0)/acpar->dr+0.5; woffn2=(woff2-acpar->r0)/acpar->dr+0.5; weight=sf_floatalloc2(nt, nr); residual_weighting(weight, nt, nr, wtn1, wtn2, woffn1, woffn2, gain); ww=array->ww; bc=acpar->bc; /* read data */ if(ns%numprocs==0) nturn=ns/numprocs; else nturn=ns/numprocs+1; dd=sf_floatalloc3(nt, nr, nturn); memset(dd[0][0], 0., nt*nr*nturn*sizeof(float)); for(iturn=0; iturn<nturn; iturn++){ is=iturn*numprocs+cpuid; if(is<ns){ sf_seek(Fdat, is*nr*nt*sizeof(float), SEEK_SET); sf_floatread(dd[iturn][0], nr*nt, Fdat); } } /* padding and convert vector to 2-d array */ vv = sf_floatalloc2(padnz, padnx); pad2d(array->vv, vv, nz, nx, nb); /* hard thresholding */ threshold[0]=fwipar->v1; threshold[1]=fwipar->v2; return; }
/* for passive source and fwi */ void gradient_pas_init(sf_file Fdat, sf_file Fsrc, sf_file Fmwt, sf_mpi *mpipar, sf_sou soupar, sf_acqui acpar, sf_vec array, sf_fwi fwipar, sf_pas paspar, bool verb1) /*< initialize >*/ { float **dwt=NULL,***mwt,***wwt; int it,ix,iz,iturn,is,rdn; char filename[20]="tempbin",srdn[10]; FILE *temp; verb=verb1; first=true; // only at the first iteration, need to calculate the gradient scaling parameter cpuid=mpipar->cpuid; numprocs=mpipar->numprocs; nz=acpar->nz; nx=acpar->nx; nzx=nz*nx; padnz=acpar->padnz; padnx=acpar->padnx; padnzx=padnz*padnx; nb=acpar->nb; nt=acpar->nt; ns=acpar->ns; nr=acpar->nr; dr_v=acpar->dr_v; r0_v=acpar->r0_v; rz=acpar->rz; grectx=fwipar->rectx; grectz=fwipar->rectz; interval=acpar->interval; wnt=(nt-1)/interval+1; dt=acpar->dt; idt=1./dt; dt2=dt*dt; wdt=dt*interval; wdt2=wdt*wdt; dx2=acpar->dx*acpar->dx; dz2=acpar->dz*acpar->dz; wt1=fwipar->wt1; wt2=fwipar->wt2; woff1=fwipar->woff1; woff2=fwipar->woff2; waterz=fwipar->waterz; waterzb=fwipar->waterzb; bc=acpar->bc; if (cpuid==0) { srand(time(NULL)); rdn = rand()%1000000000; sprintf(srdn,"%d",rdn); strcat(filename,srdn); } MPI_Bcast(filename, 20, MPI_CHAR, 0, comm); if(verb && cpuid==0) sf_warning("filename=%s",filename); temp=fopen(filename, "wb+"); if(ns%numprocs==0) nturn=ns/numprocs; else nturn=ns/numprocs+1; /* allocate data/source/weight */ dd = sf_floatalloc3(nt, nx, nturn); ww3 = sf_floatalloc4(nz, nx, nt, nturn); gwt = sf_floatalloc4(nz, nx, nt, nturn); wwt = sf_floatalloc3(nz, nx, nt); /* temporary output var */ if (!paspar->onlyvel) { mwt = sf_floatalloc3(nz, nx, nt); /* src model weight */ /* dwt = sf_floatalloc2(acpar->nt, acpar->nx); wtn1=(fwipar->wt1-acpar->t0)/acpar->dt+0.5; wtn2=(fwipar->wt2-acpar->t0)/acpar->dt+0.5; woffn1=(fwipar->woff1-acpar->r0)/acpar->dr+0.5; woffn2=(fwipar->woff2-acpar->r0)/acpar->dr+0.5; residual_weighting(dwt, acpar->nt, acpar->nx, wtn1, wtn2, woffn1, woffn2, !fwipar->oreo); */ } else { mwt=NULL; dwt=NULL; } /* read data/source */ for(iturn=0; iturn<nturn; iturn++){ is=iturn*numprocs+cpuid; if(is<ns){ /* read data */ sf_seek(Fdat, is*nt*nx*sizeof(float), SEEK_SET); sf_floatread(dd[iturn][0], nt*nx, Fdat); if (paspar->onlyvel) { /* read source */ sf_seek(Fsrc, is*nz*nx*nt*sizeof(float), SEEK_SET); sf_floatread(ww3[iturn][0][0], nz*nx*nt, Fsrc); } else { /* linear inversion of source */ lstri_op(dd[iturn], dwt, ww3[iturn], mwt, acpar, array, paspar, verb); /* write source */ fseeko(temp, is*nz*nx*nt*sizeof(float), SEEK_SET); fwrite(ww3[iturn][0][0], sizeof(float), nz*nx*nt, temp); if (NULL!=Fmwt && is==0) sf_floatwrite(mwt[0][0], nz*nx*nt, Fmwt); } /* calculate gradient mask */ if (!paspar->onlyvel && paspar->prec && paspar->hidesrc) { #ifdef _OPENMP #pragma omp parallel for default(shared) private(it,ix,iz) #endif for (it=0; it<nt; it++) for (ix=0; ix<nx; ix++) for (iz=0; iz<nz; iz++) gwt[iturn][it][ix][iz] = mwt[it][ix][iz]; threshold(true, nz*nx*nt, paspar->hard, gwt[iturn][0][0]); #ifdef _OPENMP #pragma omp parallel for default(shared) private(it,ix,iz) #endif for (it=0; it<nt; it++) for (ix=0; ix<nx; ix++) for (iz=0; iz<nz; iz++) gwt[iturn][it][ix][iz] = 1.-gwt[iturn][it][ix][iz]; } else { #ifdef _OPENMP #pragma omp parallel for default(shared) private(it,ix,iz) #endif for (it=0; it<nt; it++) for (ix=0; ix<nx; ix++) for (iz=0; iz<nz; iz++) gwt[iturn][it][ix][iz] = 1.; } } /* if is<ns */ } fclose(temp); MPI_Barrier(comm); if(!paspar->onlyvel && cpuid==0) { temp=fopen(filename, "rb"); for(is=0; is<ns; is++){ fseeko(temp, is*nz*nx*nt*sizeof(float), SEEK_SET); fread(wwt[0][0], sizeof(float), nz*nx*nt, temp); sf_floatwrite(wwt[0][0], nz*nx*nt, Fsrc); } fclose(temp); remove(filename); } MPI_Barrier(comm); /* data residual weights */ wtn1=(wt1-acpar->t0)/dt+0.5; wtn2=(wt2-acpar->t0)/dt+0.5; woffn1=(woff1-acpar->r0)/acpar->dr+0.5; woffn2=(woff2-acpar->r0)/acpar->dr+0.5; weight=sf_floatalloc2(nt, nr); residual_weighting(weight, nt, nr, wtn1, wtn2, woffn1, woffn2, fwipar->oreo); /* padding and convert vector to 2-d array */ vv = sf_floatalloc2(padnz, padnx); tau= sf_floatalloc2(padnz, padnx); taus=sf_floatalloc2(padnz, padnx); pad2d(array->vv, vv, nz, nx, nb); pad2d(array->tau, tau, nz, nx, nb); pad2d(array->taus, taus, nz, nx, nb); /* multiscale gradient */ if(soupar->flo > 0.0001) blo=sf_butter_init(false, soupar->flo, 3); if(soupar->fhi < 0.5-0.0001) bhi=sf_butter_init(true, soupar->fhi, 3); free(**wwt); free(*wwt); free(wwt); if (NULL!=mwt) { free(**mwt); free(*mwt); free(mwt); } return; }