void model_elastic_TTI(float ** rho, float ** c11, float ** c13, float ** c33, float ** c44, float ** theta){ /*--------------------------------------------------------------------------*/ /* global variables */ extern int NX, NY, NXG, NYG, POS[3], MYID; extern char MFILE[STRING_SIZE], INV_MODELFILE[STRING_SIZE]; extern float DH; /* local variables */ int i, j, ii, jj; char filename[STRING_SIZE]; float y; /* anisotropic parameters in the layers */ float vp0, vsv, rhoh, delta, epsilon, thetah; /* 1st layer: isotropic acoustic water layer */ float vp01 = 1500.0, vsv1 = 0.0, rhoh1 = 1000.0, delta1 = 0.0, epsilon1 = 0.0, thetah1 = 0.0; /* 2nd layer: anisotropic VTI medium */ float vp02 = 1800.0, vsv2 = 1040.0, rhoh2 = 2000.0, delta2 = 0.0, epsilon2 = 0.0, thetah2 = 0.0; /* 3rd layer: anisotropic TTI medium */ float vp03 = 2200.0, vsv3 = 1270.0, rhoh3 = 2000.0, delta3 = 0.0, epsilon3 = 0.0, thetah3 = 0.0; /* 4th layer: anisotropic TTI medium */ float vp04 = 2800.0, vsv4 = 1620.0, rhoh4 = 2000.0, delta4 = 0.0, epsilon4 = 0.0, thetah4 = 0.0; /* transform Thomsen's parameters to elastic tensor components */ float c33h, c44h, c11h, c13h; float d1=300.0, d2=450.0, d3=1100.0; /*-----------------------------------------------------------------------*/ /* loop over global grid */ for (i=1;i<=NXG;i++){ for (j=1;j<=NYG;j++){ /* properties of the first layer */ vp0 = vp01; vsv = vsv1; rhoh = rhoh1; delta = delta1; epsilon = epsilon1; thetah = thetah1; /* calculate depth */ y = j*DH; if(y > d1){vp0 = vp02; vsv = vsv2; rhoh = rhoh2; delta = delta2; epsilon = epsilon2; thetah = thetah2;} if(y > d2){vp0 = vp03; vsv = vsv3; rhoh = rhoh3; delta = delta3; epsilon = epsilon3; thetah = thetah3;} if(y > d3){vp0 = vp04; vsv = vsv4; rhoh = rhoh4; delta = delta4; epsilon = epsilon4; thetah = thetah4;} /* transform Thomsen's parameters to elastic tensor components */ c33h = rhoh * vp0 * vp0; c44h = rhoh * vsv * vsv; c11h = c33h * (1 + 2.0 * epsilon); c13h = sqrt((c33h-c44h) * (c33h-c44h) + 2.0 * delta * c33h * (c33h - c44h)) - c44h; /* only the PE which belongs to the current global gridpoint is saving model parameters in his local arrays */ if ((POS[1]==((i-1)/NX)) && (POS[2]==((j-1)/NY))){ ii=i-POS[1]*NX; jj=j-POS[2]*NY; c11[jj][ii]=c11h; c13[jj][ii]=c13h; c33[jj][ii]=c33h; c44[jj][ii]=c44h; theta[jj][ii]=thetah * M_PI / 180.0; rho[jj][ii]=rhoh; } } } /* each PE writes his model to disk and PE 0 merges model files */ sprintf(filename,"%s.denise.c11",MFILE); writemod(filename,c11,3); MPI_Barrier(MPI_COMM_WORLD); if (MYID==0) mergemod(filename,3); sprintf(filename,"%s.denise.c13",MFILE); writemod(filename,c13,3); MPI_Barrier(MPI_COMM_WORLD); if (MYID==0) mergemod(filename,3); sprintf(filename,"%s.denise.c33",MFILE); writemod(filename,c33,3); MPI_Barrier(MPI_COMM_WORLD); if (MYID==0) mergemod(filename,3); sprintf(filename,"%s.denise.c44",MFILE); writemod(filename,c44,3); MPI_Barrier(MPI_COMM_WORLD); if (MYID==0) mergemod(filename,3); sprintf(filename,"%s.denise.theta",MFILE); writemod(filename,theta,3); MPI_Barrier(MPI_COMM_WORLD); if (MYID==0) mergemod(filename,3); /* clean up temporary files */ MPI_Barrier(MPI_COMM_WORLD); sprintf(filename,"%s.denise.c11.%i%i",MFILE,POS[1],POS[2]); remove(filename); sprintf(filename,"%s.denise.c13.%i%i",MFILE,POS[1],POS[2]); remove(filename); sprintf(filename,"%s.denise.c33.%i%i",MFILE,POS[1],POS[2]); remove(filename); sprintf(filename,"%s.denise.c44.%i%i",MFILE,POS[1],POS[2]); remove(filename); sprintf(filename,"%s.denise.theta.%i%i",MFILE,POS[1],POS[2]); remove(filename); }
float step_length_est(FILE *fprec, float ** waveconv, float ** waveconv_rho, float ** waveconv_u, float ** prho, float ** prhonp1, float ** ppi, float ** ppinp1, int iter, int nfstart, int nsrc, float ** puipjp, float ** prip, float ** prjp, float L2, int partest, float ** srcpos_loc, float ** srcpos, float ** srcpos1, float ** signals, int ns, int nd, float ** pvx, float ** pvy, float ** psxx, float ** psyy, float ** psxy, float ** ux, float ** uy, float ** pvxp1, float ** pvyp1, float ** psi_sxx_x, float ** psi_sxy_x, float ** psi_vxx, float ** psi_vyx, float ** psi_syy_y, float ** psi_sxy_y, float ** psi_vyy, float ** psi_vxy, float ** psi_vxxs, float ** pvxm1, float ** pvym1, float ** uttx, float ** utty, float ** absorb_coeff, float *hc, float * K_x, float * a_x, float * b_x, float * K_x_half, float * a_x_half, float * b_x_half, float * K_y, float * a_y, float * b_y, float * K_y_half, float * a_y_half, float * b_y_half, float ** uxy, float ** uyx, int ntr, int **recpos_loc, float **sectionvx, float **sectionvy, float **sectionp, float **sectioncurl, float **sectiondiv, float **sectionread, int ntr_glob, float ** sectionvxdata, float ** sectionvxdiff, float ** sectionvxdiffold, float ** sectionvydata, float ** sectionvydiff, float ** sectionvydiffold, float * epst1, float * L2t, float L2sum, float energy_sum, float ** bufferlef_to_rig, float ** bufferrig_to_lef, float ** buffertop_to_bot, float ** bufferbot_to_top, float **pu, float **punp1, int itest,int nsrc_glob, int nsrc_loc, MPI_Request * req_send, MPI_Request * req_rec, float ***pr, float ***pp, float ***pq, float **fipjp, float **f, float **g, float *bip, float *bjm, float *cip, float *cjm, float ***d, float ***e, float ***dip, float **ptaup, float **ptaus, float *etajm, float *peta, float *etaip, float **ptausipjp, int **recpos, int *step1, int *step3, float C_vp, float **gradg, float FC, int nxgrav, int nygrav, int ngrav, float **gravpos, float *gz_mod, int NZGRAV) { extern int MYID,MIN_ITER,TIME_FILT,STEPMAX, GRAVITY, IDX, IDY, NX, NY, NXG, NYG, POS[3], MYID; extern char JACOBIAN[STRING_SIZE]; extern float EPS_SCALE, SCALEFAC, LAM_GRAV, GAMMA_GRAV, L2_GRAV_IT1; float opteps_vp, ** rho_grav, ** rho_grav_ext; int h, i, j, n, nshots, ishot, nt, lsnap, lsamp, nsnap, infoout; /* Variables for step length calculation */ int step2, itests, iteste, stepmax, countstep; float scalefac, eps_scale, L2_grav, L2sum1; float * gz_res; char jac_grav[STRING_SIZE]; FILE *FP_GRAV; scalefac = SCALEFAC; /* scale factor for the step length */ stepmax = STEPMAX; /* number of maximum misfit calculations/steplength 2/3*/ *step1=0; step2=0; /* start with first guess for step length alpha */ eps_scale=EPS_SCALE; /* maximum model change = 1% of the maximum model value */ countstep=0; /* count number of forward calculations */ itests=2; iteste=2; while((step2!=1)||(*step1!=1)) { for (itest=itests; itest<=iteste; itest++) { /* calculate 3 L2 values */ forward_mod(fprec,waveconv,waveconv_rho,waveconv_u,prho,prhonp1,ppi,ppinp1,iter,eps_scale,nfstart,nsrc,puipjp,prip,prjp,L2,partest,srcpos_loc,srcpos,srcpos1,signals,ns, nd,pvx,pvy,psxx,psyy,psxy,ux,uy,pvxp1,pvyp1,psi_sxx_x,psi_sxy_x,psi_vxx,psi_vyx,psi_syy_y,psi_sxy_y,psi_vyy,psi_vxy,psi_vxxs,pvxm1,pvym1,uttx,utty,absorb_coeff,hc,K_x, a_x,b_x,K_x_half,a_x_half,b_x_half,K_y,a_y,b_y,K_y_half,a_y_half,b_y_half,uxy,uyx,ntr,recpos_loc,sectionvx,sectionvy,sectionp,sectioncurl,sectiondiv,sectionread,ntr_glob, sectionvxdata,sectionvxdiff,sectionvxdiffold,sectionvydata,sectionvydiff,sectionvydiffold,epst1,L2t,L2sum,energy_sum,bufferlef_to_rig,bufferrig_to_lef, buffertop_to_bot,bufferbot_to_top,pu,punp1,itest,nsrc_glob,nsrc_loc,req_send,req_rec,pr,pp,pq,fipjp,f,g,bip,bjm,cip,cjm,d,e,dip,ptaup,ptaus,etajm,peta,etaip,ptausipjp,recpos,FC); if(GRAVITY==2) { /* save seismic L2-norm of seismic data residuals */ L2sum1 = L2t[itest]; gz_res = vector(1,ngrav); /* global density model */ rho_grav = matrix(1,NYG,1,NXG); rho_grav_ext = matrix(1,nygrav,1,nxgrav); /* model gravity data */ /* save current density model */ sprintf(jac_grav,"%s_tmp.rho.%i%i",JACOBIAN,POS[1],POS[2]); FP_GRAV=fopen(jac_grav,"wb"); for (i=1; i<=NX; i=i+IDX) { for (j=1; j<=NY; j=j+IDY) { fwrite(&prhonp1[j][i],sizeof(float),1,FP_GRAV); } } fclose(FP_GRAV); MPI_Barrier(MPI_COMM_WORLD); /* merge model file */ sprintf(jac_grav,"%s_tmp.rho",JACOBIAN); if (MYID==0) mergemod(jac_grav,3); MPI_Barrier(MPI_COMM_WORLD); read_density_glob(rho_grav,2); extend_mod(rho_grav,rho_grav_ext,nxgrav,nygrav); grav_mod(rho_grav_ext,ngrav,gravpos,gz_mod,nxgrav,nygrav,NZGRAV); /* calculate gravity data residuals */ L2_grav=calc_res_grav(ngrav,gz_mod,gz_res); /* TEST: LAMBDA WEIGHTING BY GRADIENT */ /* calculate lambda_grav */ /* TEST: WITHOUT NORM */ /*LAM_GRAV = GAMMA_GRAV * (L2sum1/L2_GRAV_IT1);*/ /*LAM_GRAV = GAMMA_GRAV;*/ /* TEST: DECREASING LAMBDA PER ITERATION */ /*LAM_GRAV = GAMMA_GRAV * ((L2sum1+L2_grav)/L2_GRAV_IT1);*/ /* add gravity penalty term to the seismic objective function */ L2t[itest]+=LAM_GRAV * L2_grav; /* ONLY GRAVITY INVERSION */ /*L2t[itest] = L2_grav;*/ /* free memory */ free_matrix(rho_grav,1,NYG,1,NXG); free_matrix(rho_grav_ext,1,nygrav,1,nxgrav); free_vector(gz_res,1,ngrav); } } /* end of L2 test */ /* Did not found a step size which reduces the misfit function */ if((*step1==0)&&(L2t[1]<=L2t[2])) { eps_scale = eps_scale/scalefac; countstep++; } /* Found a step size with L2t[2] < L2t[3]*/ if((*step1==1)&&(L2t[2]<L2t[3])) { epst1[3]=eps_scale; step2=1; } /* Could not found a step size with L2t[2] < L2t[3]*/ if((*step1==1)&&(L2t[2]>=L2t[3])) { epst1[3]=eps_scale; /* increase step length to find a larger misfit function than L2t[2]*/ eps_scale = eps_scale + (eps_scale/scalefac); countstep++; } /* found a step size which reduces the misfit function */ if((*step1==0)&&(L2t[1]>L2t[2])) { epst1[2]=eps_scale; *step1=1; iteste=3; itests=3; countstep=0; /* find a second step length with a larger misfit function than L2t[2]*/ eps_scale = eps_scale + (eps_scale/scalefac); } *step3=0; if((*step1==0)&&(countstep>stepmax)) { if(MYID==0) { printf(" Steplength estimation failed!"); } if(TIME_FILT==0) { err(" "); } *step3=1; break; } if((*step1==1)&&(countstep>stepmax)) { if(MYID==0) { printf("Could not found a proper 3rd step length which brackets the minimum\n"); } *step1=1; step2=1; } if(MYID==0) { printf("iteste = %d \t itests = %d \t step1 = %d \t step2 = %d \t eps_scale = %e \t countstep = %d \t stepmax= %d \t scalefac = %e \t MYID = %d \t L2t[1] = %e \t L2t[2] = %e \t L2t[3] = %e \n",iteste,itests,*step1,step2,eps_scale,countstep,stepmax,scalefac,MYID,L2t[1],L2t[2],L2t[3]); } } /* end of while loop */ if(*step1==1) { /* only find an optimal step length if step1==1 */ /* calculate optimal step length epsilon for Vp and Vs*/ if(MYID==0) { printf("================================================= \n"); printf("calculate optimal step length epsilon for Vp and Vs \n"); printf("================================================= \n"); } opteps_vp=calc_opt_step(L2t,waveconv,gradg,epst1,1,C_vp); eps_scale = opteps_vp; } return eps_scale; }
void model_elastic(float ** rho, float ** pi, float ** u){ /*--------------------------------------------------------------------------*/ /* extern variables */ extern int NX, NY, NXG, NYG, POS[3], L, MYID; extern char MFILE[STRING_SIZE]; extern char INV_MODELFILE[STRING_SIZE]; extern float DH; /* local variables */ float vp, vs, rhov, grad1, grad2, grad3, y; int i, j, ii, jj; char modfile[STRING_SIZE]; /* parameters for layer 1 */ const float vp1=500.0, vs1=300.0, rho1=1800.0, h=15.0; /* parameters for layer 2 due to calculation of grad1, grad2 and grad3*/ const float vp2=1200.0, vs2=700.0, rho2=2000.0; /*-----------------------------------------------------------------------*/ y=h/DH; if(y==NYG) err(" \n y is equal NYG !! see src/model_grad.c \n "); grad1=(vp2-vp1)/y; grad2=(vs2-vs1)/y; grad3=(rho2-rho1)/y; /* loop over global grid */ for (i=1;i<=NXG;i++){ for (j=1;j<=NYG;j++){ if(j<=y){ vp=vp1+(j*grad1); vs=vs1+(j*grad2); rhov=rho1+(j*grad3); } else{ vp=vp2; vs=vs2; rhov=rho2; } /* only the PE which belongs to the current global gridpoint is saving model parameters in his local arrays */ if ((POS[1]==((i-1)/NX)) && (POS[2]==((j-1)/NY))){ ii=i-POS[1]*NX; jj=j-POS[2]*NY; u[jj][ii]=vs; rho[jj][ii]=rhov; pi[jj][ii]=vp; } } } sprintf(modfile,"%s_rho_it_0.bin",INV_MODELFILE); writemod(modfile,rho,3); MPI_Barrier(MPI_COMM_WORLD); if (MYID==0) mergemod(modfile,3); sprintf(modfile,"%s_vs_it_0.bin",INV_MODELFILE); writemod(modfile,u,3); MPI_Barrier(MPI_COMM_WORLD); if (MYID==0) mergemod(modfile,3); sprintf(modfile,"%s_vp_it_0.bin",INV_MODELFILE); writemod(modfile,pi,3); MPI_Barrier(MPI_COMM_WORLD); if (MYID==0) mergemod(modfile,3); }
void model(float ** rho, float ** pi, float ** u, float ** taus, float ** taup, float * eta){ /*--------------------------------------------------------------------------*/ /* extern variables */ extern float DT, *FL, TAU, DH; extern int NX, NY, NXG, NYG, POS[3], L, MYID; extern char MFILE[STRING_SIZE]; /* local variables */ float rhov, muv, piv, vp, vs, y; float *pts, ts, tp, sumu, sumpi, ws; int i, j, l, ii, jj; char modfile[STRING_SIZE]; /* parameters for layer 1 */ const float vp1=500.0, vs1=300.0, rho1=1800.0, h=2.0; /* parameters for layer 2 */ const float vp2=500.0, vs2=300.0, rho2=1800.0; /*-----------------------------------------------------------------------*/ /* vector for maxwellbodies */ pts=vector(1,L); for (l=1;l<=L;l++) { pts[l]=1.0/(2.0*PI*FL[l]); eta[l]=DT/pts[l]; } ts=TAU; tp=TAU; ws=2.0*PI*FL[1]; sumu=0.0; sumpi=0.0; for (l=1;l<=L;l++){ sumu=sumu+((ws*ws*pts[l]*pts[l]*ts)/(1.0+ws*ws*pts[l]*pts[l])); sumpi=sumpi+((ws*ws*pts[l]*pts[l]*tp)/(1.0+ws*ws*pts[l]*pts[l])); } /* loop over global grid */ for (i=1;i<=NXG;i++){ for (j=1;j<=NYG;j++){ y=(float)j*DH; if (y<=h){ vp=vp1; vs=vs1; rhov=rho1; } else{ vp=vp2; vs=vs2; rhov=rho2; } /* only the PE which belongs to the current global gridpoint is saving model parameters in his local arrays */ if ((POS[1]==((i-1)/NX)) && (POS[2]==((j-1)/NY))){ ii=i-POS[1]*NX; jj=j-POS[2]*NY; taus[jj][ii]=ts; taup[jj][ii]=tp; u[jj][ii]=vs; rho[jj][ii]=rhov; pi[jj][ii]=vp; } } } /* each PE writes his model to disk */ sprintf(modfile,"%s.u",MFILE); writemod(modfile,u,3); MPI_Barrier(MPI_COMM_WORLD); if (MYID==0) mergemod(modfile,3); /*sprintf(modfile,"%s.pi",MFILE); writemod(modfile,pi,3); MPI_Barrier(MPI_COMM_WORLD); if (MYID==0) mergemod(modfile,3); sprintf(modfile,"%s.rho",MFILE); writemod(modfile,rho,3); MPI_Barrier(MPI_COMM_WORLD); if (MYID==0) mergemod(modfile,3); sprintf(modfile,"%s.taup",MFILE); writemod(modfile,taup,3); MPI_Barrier(MPI_COMM_WORLD); if (MYID==0) mergemod(modfile,3); sprintf(modfile,"%s.taus",MFILE); writemod(modfile,taus,3); MPI_Barrier(MPI_COMM_WORLD); if (MYID==0) mergemod(modfile,3);*/ free_vector(pts,1,L); }
void FWI_PSV(){ /* global variables */ /* ---------------- */ /* forward modelling */ extern int MYID, FDORDER, NX, NY, NT, L, READMOD, QUELLART, RUN_MULTIPLE_SHOTS, TIME_FILT; extern int LOG, SEISMO, N_STREAMER, FW, NXG, NYG, IENDX, IENDY, NTDTINV, IDXI, IDYI, NXNYI, INV_STF, DTINV; extern float FC_SPIKE_1, FC_SPIKE_2, FC, FC_START, TIME, DT; extern char LOG_FILE[STRING_SIZE], MFILE[STRING_SIZE]; extern FILE *FP; /* gravity modelling/inversion */ extern int GRAVITY, NZGRAV, NGRAVB, GRAV_TYPE, BACK_DENSITY; extern char GRAV_DATA_OUT[STRING_SIZE], GRAV_DATA_IN[STRING_SIZE], GRAV_STAT_POS[STRING_SIZE], DFILE[STRING_SIZE]; extern float LAM_GRAV, GAMMA_GRAV, LAM_GRAV_GRAD, L2_GRAV_IT1; /* full waveform inversion */ extern int GRAD_METHOD, NLBFGS, ITERMAX, IDX, IDY, INVMAT1, EPRECOND; extern int GRAD_FORM, POS[3], QUELLTYPB, MIN_ITER, MODEL_FILTER; extern float FC_END, PRO, C_vp, C_vs, C_rho; extern char MISFIT_LOG_FILE[STRING_SIZE], JACOBIAN[STRING_SIZE]; extern char *FILEINP1; /* local variables */ int ns, nseismograms=0, nt, nd, fdo3, j, i, iter, h, hin, iter_true, SHOTINC, s=0; int buffsize, ntr=0, ntr_loc=0, ntr_glob=0, nsrc=0, nsrc_loc=0, nsrc_glob=0, ishot, nshots=0, itestshot; float sum, eps_scale, opteps_vp, opteps_vs, opteps_rho, Vp_avg, Vs_avg, rho_avg, Vs_sum, Vp_sum, rho_sum; char *buff_addr, ext[10], *fileinp, jac[225], source_signal_file[STRING_SIZE]; double time1, time2, time7, time8, time_av_v_update=0.0, time_av_s_update=0.0, time_av_v_exchange=0.0, time_av_s_exchange=0.0, time_av_timestep=0.0; float L2sum, *L2t; float ** taper_coeff, * epst1, *hc=NULL; int * DTINV_help; MPI_Request *req_send, *req_rec; MPI_Status *send_statuses, *rec_statuses; /* Variables for step length calculation */ int step1, step3=0; float eps_true, tmp; /* Variables for the L-BFGS method */ float * rho_LBFGS, * alpha_LBFGS, * beta_LBFGS; float * y_LBFGS, * s_LBFGS, * q_LBFGS, * r_LBFGS; int NLBFGS_class, LBFGS_pointer, NLBFGS_vec; /* Variables for energy weighted gradient */ float ** Ws, **Wr, **We; /* parameters for FWI-workflow */ int stagemax=0, nstage; /*vector for abort criterion*/ float * L2_hist=NULL; /* help variable for MIN_ITER */ int min_iter_help=0; /* parameters for gravity inversion */ float * gz_mod, * gz_res; float ** gravpos=NULL, ** rho_grav=NULL, ** rho_grav_ext=NULL; float ** grad_grav=NULL; int ngrav=0, nxgrav, nygrav; float L2_grav, FWImax, GRAVmax, FWImax_all, GRAVmax_all ; char jac_grav[STRING_SIZE]; FILE *FPL2, *FP_stage, *FP_GRAV, *LAMBDA; if (MYID == 0){ time1=MPI_Wtime(); clock(); } /* open log-file (each PE is using different file) */ /* fp=stdout; */ sprintf(ext,".%i",MYID); strcat(LOG_FILE,ext); if ((MYID==0) && (LOG==1)) FP=stdout; else FP=fopen(LOG_FILE,"w"); fprintf(FP," This is the log-file generated by PE %d \n\n",MYID); /* ----------------------- */ /* define FD grid geometry */ /* ----------------------- */ /* domain decomposition */ initproc(); NT=iround(TIME/DT); /* number of timesteps */ /* output of parameters to log-file or stdout */ if (MYID==0) write_par(FP); /* NXG, NYG denote size of the entire (global) grid */ NXG=NX; NYG=NY; /* In the following, NX and NY denote size of the local grid ! */ NX = IENDX; NY = IENDY; NTDTINV=ceil((float)NT/(float)DTINV); /* round towards next higher integer value */ /* save every IDXI and IDYI spatial point during the forward modelling */ IDXI=1; IDYI=1; NXNYI=(NX/IDXI)*(NY/IDYI); SHOTINC=1; /* use only every DTINV time sample for the inversion */ DTINV_help=ivector(1,NT); /* read parameters from workflow-file (stdin) */ FP_stage=fopen(FILEINP1,"r"); if(FP_stage==NULL) { if (MYID == 0){ printf("\n==================================================================\n"); printf(" Cannot open Denise workflow input file %s \n",FILEINP1); printf("\n==================================================================\n\n"); err(" --- "); } } /* estimate number of lines in FWI-workflow */ i=0; stagemax=0; while ((i=fgetc(FP_stage)) != EOF) if (i=='\n') ++stagemax; rewind(FP_stage); stagemax--; fclose(FP_stage); /* define data structures for PSV problem */ struct wavePSV; struct wavePSV_PML; struct matPSV; struct fwiPSV; struct mpiPSV; struct seisPSV; struct seisPSVfwi; struct acq; nd = FDORDER/2 + 1; fdo3 = 2*nd; buffsize=2.0*2.0*fdo3*(NX +NY)*sizeof(MPI_FLOAT); /* allocate buffer for buffering messages */ buff_addr=malloc(buffsize); if (!buff_addr) err("allocation failure for buffer for MPI_Bsend !"); MPI_Buffer_attach(buff_addr,buffsize); /* allocation for request and status arrays */ req_send=(MPI_Request *)malloc(REQUEST_COUNT*sizeof(MPI_Request)); req_rec=(MPI_Request *)malloc(REQUEST_COUNT*sizeof(MPI_Request)); send_statuses=(MPI_Status *)malloc(REQUEST_COUNT*sizeof(MPI_Status)); rec_statuses=(MPI_Status *)malloc(REQUEST_COUNT*sizeof(MPI_Status)); /* --------- add different modules here ------------------------ */ ns=NT; /* in a FWI one has to keep all samples of the forward modeled data at the receiver positions to calculate the adjoint sources and to do the backpropagation; look at function saveseis_glob.c to see that every NDT sample for the forward modeled wavefield is written to su files*/ if (SEISMO){ acq.recpos=receiver(FP, &ntr, ishot); acq.recswitch = ivector(1,ntr); acq.recpos_loc = splitrec(acq.recpos,&ntr_loc, ntr, acq.recswitch); ntr_glob=ntr; ntr=ntr_loc; if(N_STREAMER>0){ free_imatrix(acq.recpos,1,3,1,ntr_glob); if(ntr>0) free_imatrix(acq.recpos_loc,1,3,1,ntr); free_ivector(acq.recswitch,1,ntr_glob); } } if(N_STREAMER==0){ /* Memory for seismic data */ alloc_seisPSV(ntr,ns,&seisPSV); /* Memory for FWI seismic data */ alloc_seisPSVfwi(ntr,ntr_glob,ns,&seisPSVfwi); } /* Memory for full data seismograms */ alloc_seisPSVfull(&seisPSV,ntr_glob); /* memory allocation for abort criterion*/ L2_hist = vector(1,1000); /* estimate memory requirement of the variables in megabytes*/ switch (SEISMO){ case 1 : /* particle velocities only */ nseismograms=2; break; case 2 : /* pressure only */ nseismograms=1; break; case 3 : /* curl and div only */ nseismograms=2; break; case 4 : /* everything */ nseismograms=5; break; } /* calculate memory requirements for PSV forward problem */ mem_fwiPSV(nseismograms,ntr,ns,fdo3,nd,buffsize,ntr_glob); /* Define gradient formulation */ /* GRAD_FORM = 1 - stress-displacement gradients */ /* GRAD_FORM = 2 - stress-velocity gradients for decomposed impedance matrix */ GRAD_FORM = 1; if(GRAVITY==1 || GRAVITY==2){ if(GRAV_TYPE == 1){ sprintf(GRAV_DATA_OUT, "./gravity/grav_mod.dat"); /* output file of gravity data */ sprintf(GRAV_DATA_IN, "./gravity/grav_field.dat"); /* input file of gravity data */ } if(GRAV_TYPE == 2){ sprintf(GRAV_DATA_OUT, "./gravity/grav_grad_mod.dat"); /* output file of gravity gradient data */ sprintf(GRAV_DATA_IN, "./gravity/grav_grad_field.dat"); /* input file of gravity gradientdata */ } sprintf(GRAV_STAT_POS, "./gravity/grav_stat.dat"); /* file with station positions for gravity modelling */ /* size of the extended gravity model */ nxgrav = NXG + 2*NGRAVB; nygrav = NYG + NGRAVB; } /* allocate memory for PSV forward problem */ alloc_PSV(&wavePSV,&wavePSV_PML); /* calculate damping coefficients for CPMLs (PSV problem)*/ if(FW>0){PML_pro(wavePSV_PML.d_x, wavePSV_PML.K_x, wavePSV_PML.alpha_prime_x, wavePSV_PML.a_x, wavePSV_PML.b_x, wavePSV_PML.d_x_half, wavePSV_PML.K_x_half, wavePSV_PML.alpha_prime_x_half, wavePSV_PML.a_x_half, wavePSV_PML.b_x_half, wavePSV_PML.d_y, wavePSV_PML.K_y, wavePSV_PML.alpha_prime_y, wavePSV_PML.a_y, wavePSV_PML.b_y, wavePSV_PML.d_y_half, wavePSV_PML.K_y_half, wavePSV_PML.alpha_prime_y_half, wavePSV_PML.a_y_half, wavePSV_PML.b_y_half); } /* allocate memory for PSV material parameters */ alloc_matPSV(&matPSV); /* allocate memory for PSV FWI parameters */ alloc_fwiPSV(&fwiPSV); /* allocate memory for PSV MPI variables */ alloc_mpiPSV(&mpiPSV); /* Variables for the l-BFGS method */ if(GRAD_METHOD==2){ NLBFGS_class = 3; /* number of parameter classes */ NLBFGS_vec = NLBFGS_class*NX*NY; /* length of one LBFGS-parameter class */ LBFGS_pointer = 1; /* initiate pointer in the cyclic LBFGS-vectors */ y_LBFGS = vector(1,NLBFGS_vec*NLBFGS); s_LBFGS = vector(1,NLBFGS_vec*NLBFGS); q_LBFGS = vector(1,NLBFGS_vec); r_LBFGS = vector(1,NLBFGS_vec); rho_LBFGS = vector(1,NLBFGS); alpha_LBFGS = vector(1,NLBFGS); beta_LBFGS = vector(1,NLBFGS); } taper_coeff= matrix(1,NY,1,NX); /* memory for source position definition */ acq.srcpos1=fmatrix(1,8,1,1); /* memory of L2 norm */ L2t = vector(1,4); epst1 = vector(1,3); fprintf(FP," ... memory allocation for PE %d was successfull.\n\n", MYID); /* Holberg coefficients for FD operators*/ hc = holbergcoeff(); MPI_Barrier(MPI_COMM_WORLD); /* Reading source positions from SOURCE_FILE */ acq.srcpos=sources(&nsrc); nsrc_glob=nsrc; /* create model grids */ if(L){ if (READMOD) readmod_visc_PSV(matPSV.prho,matPSV.ppi,matPSV.pu,matPSV.ptaus,matPSV.ptaup,matPSV.peta); else model(matPSV.prho,matPSV.ppi,matPSV.pu,matPSV.ptaus,matPSV.ptaup,matPSV.peta); } else{ if (READMOD) readmod_elastic_PSV(matPSV.prho,matPSV.ppi,matPSV.pu); else model_elastic(matPSV.prho,matPSV.ppi,matPSV.pu); } /* check if the FD run will be stable and free of numerical dispersion */ if(L){ checkfd_ssg_visc(FP,matPSV.prho,matPSV.ppi,matPSV.pu,matPSV.ptaus,matPSV.ptaup,matPSV.peta,hc); } else{ checkfd_ssg_elastic(FP,matPSV.prho,matPSV.ppi,matPSV.pu,hc); } if(GRAVITY==1 || GRAVITY==2){ /* read station positions */ MPI_Barrier(MPI_COMM_WORLD); gravpos=read_grav_pos(&ngrav); /* define model and residual data vector for gz (z-component of the gravity field) */ gz_mod = vector(1,ngrav); gz_res = vector(1,ngrav); /* only forward modelling of gravity data */ if(GRAVITY==1){ /* global density model */ rho_grav = matrix(1,NYG,1,NXG); rho_grav_ext = matrix(1,nygrav,1,nxgrav); read_density_glob(rho_grav,1); extend_mod(rho_grav,rho_grav_ext,nxgrav,nygrav); grav_mod(rho_grav_ext,ngrav,gravpos,gz_mod,nxgrav,nygrav,NZGRAV); free_matrix(rho_grav,1,NYG,1,NXG); free_matrix(rho_grav_ext,1,nygrav,1,nxgrav); } if(GRAVITY==2){ grad_grav = matrix(1,NY,1,NX); } } SHOTINC=1; iter_true=1; /* Begin of FWI-workflow */ for(nstage=1;nstage<=stagemax;nstage++){ /* read workflow input file *.inp */ FP_stage=fopen(FILEINP1,"r"); read_par_inv(FP_stage,nstage,stagemax); /*fclose(FP_stage);*/ if((EPRECOND==1)||(EPRECOND==3)){ Ws = matrix(1,NY,1,NX); /* total energy of the source wavefield */ Wr = matrix(1,NY,1,NX); /* total energy of the receiver wavefield */ We = matrix(1,NY,1,NX); /* total energy of source and receiver wavefield */ } FC=FC_END; iter=1; /* -------------------------------------- * Begin of Full Waveform iteration loop * -------------------------------------- */ while(iter<=ITERMAX){ if(GRAD_METHOD==2){ /* increase pointer to LBFGS-vector*/ if(iter>2){ LBFGS_pointer++; } /* if LBFGS-pointer > NLBFGS -> set LBFGS_pointer=1 */ if(LBFGS_pointer>NLBFGS){LBFGS_pointer=1;} } if (MYID==0) { time2=MPI_Wtime(); fprintf(FP,"\n\n\n ------------------------------------------------------------------\n"); fprintf(FP,"\n\n\n TDFWI ITERATION %d \t of %d \n",iter,ITERMAX); fprintf(FP,"\n\n\n ------------------------------------------------------------------\n"); } /* For the calculation of the material parameters between gridpoints they have to be averaged. For this, values lying at 0 and NX+1, for example, are required on the local grid. These are now copied from the neighbouring grids */ if (L){ matcopy_PSV(matPSV.prho,matPSV.ppi,matPSV.pu,matPSV.ptaus,matPSV.ptaup); } else{ matcopy_elastic_PSV(matPSV.prho,matPSV.ppi,matPSV.pu); } MPI_Barrier(MPI_COMM_WORLD); av_mue(matPSV.pu,matPSV.puipjp,matPSV.prho); av_rho(matPSV.prho,matPSV.prip,matPSV.prjp); if (L) av_tau(matPSV.ptaus,matPSV.ptausipjp); /* Preparing memory variables for update_s (viscoelastic) */ if (L) prepare_update_s_visc_PSV(matPSV.etajm,matPSV.etaip,matPSV.peta,matPSV.fipjp,matPSV.pu,matPSV.puipjp,matPSV.ppi,matPSV.prho,matPSV.ptaus,matPSV.ptaup,matPSV.ptausipjp,matPSV.f,matPSV.g, matPSV.bip,matPSV.bjm,matPSV.cip,matPSV.cjm,matPSV.dip,matPSV.d,matPSV.e); if(iter_true==1){ for (i=1;i<=NX;i=i+IDX){ for (j=1;j<=NY;j=j+IDY){ if(INVMAT1==1){ fwiPSV.Vp0[j][i] = matPSV.ppi[j][i]; fwiPSV.Vs0[j][i] = matPSV.pu[j][i]; fwiPSV.Rho0[j][i] = matPSV.prho[j][i]; } if(INVMAT1==2){ fwiPSV.Vp0[j][i] = sqrt((matPSV.ppi[j][i]+2.0*matPSV.pu[j][i])*matPSV.prho[j][i]); fwiPSV.Vs0[j][i] = sqrt(matPSV.pu[j][i]*matPSV.prho[j][i]); fwiPSV.Rho0[j][i] = matPSV.prho[j][i]; } if(INVMAT1==3){ fwiPSV.Vp0[j][i] = matPSV.ppi[j][i]; fwiPSV.Vs0[j][i] = matPSV.pu[j][i]; fwiPSV.Rho0[j][i] = matPSV.prho[j][i]; } } } /* ----------------------------- */ /* calculate Covariance matrices */ /* ----------------------------- */ Vp_avg = 0.0; Vs_avg = 0.0; rho_avg = 0.0; for (i=1;i<=NX;i=i+IDX){ for (j=1;j<=NY;j=j+IDY){ /* calculate average Vp, Vs */ Vp_avg+=matPSV.ppi[j][i]; Vs_avg+=matPSV.pu[j][i]; /* calculate average rho */ rho_avg+=matPSV.prho[j][i]; } } /* calculate average Vp, Vs and rho of all CPUs*/ Vp_sum = 0.0; MPI_Allreduce(&Vp_avg,&Vp_sum,1,MPI_FLOAT,MPI_SUM,MPI_COMM_WORLD); Vp_avg=Vp_sum; Vs_sum = 0.0; MPI_Allreduce(&Vs_avg,&Vs_sum,1,MPI_FLOAT,MPI_SUM,MPI_COMM_WORLD); Vs_avg=Vs_sum; rho_sum = 0.0; MPI_Allreduce(&rho_avg,&rho_sum,1,MPI_FLOAT,MPI_SUM,MPI_COMM_WORLD); rho_avg=rho_sum; Vp_avg /=NXG*NYG; Vs_avg /=NXG*NYG; rho_avg /=NXG*NYG; if(MYID==0){ printf("Vp_avg = %.0f \t Vs_avg = %.0f \t rho_avg = %.0f \n ",Vp_avg,Vs_avg,rho_avg); } C_vp = Vp_avg; C_vs = Vs_avg; C_rho = rho_avg; } /* Open Log File for L2 norm */ if(MYID==0){ if(iter_true==1){ FPL2=fopen(MISFIT_LOG_FILE,"w"); } if(iter_true>1){ FPL2=fopen(MISFIT_LOG_FILE,"a"); } } /* ---------------------------------------------------------------------------------------------------- */ /* --------- Calculate gradient and objective function using the adjoint state method ----------------- */ /* ---------------------------------------------------------------------------------------------------- */ L2sum = grad_obj_psv(&wavePSV, &wavePSV_PML, &matPSV, &fwiPSV, &mpiPSV, &seisPSV, &seisPSVfwi, &acq, hc, iter, nsrc, ns, ntr, ntr_glob, nsrc_glob, nsrc_loc, ntr_loc, nstage, We, Ws, Wr, taper_coeff, hin, DTINV_help, req_send, req_rec); L2t[1]=L2sum; L2t[4]=L2sum; if(GRAVITY==2){ /* save seismic L2-norm of seismic data residuals */ L2sum = L2t[1]; /* global density model */ rho_grav = matrix(1,NYG,1,NXG); rho_grav_ext = matrix(1,nygrav,1,nxgrav); /* model gravity data */ /* save current density model */ sprintf(jac_grav,"%s_tmp.rho.%i%i",JACOBIAN,POS[1],POS[2]); FP_GRAV=fopen(jac_grav,"wb"); for (i=1;i<=NX;i=i+IDX){ for (j=1;j<=NY;j=j+IDY){ fwrite(&matPSV.prho[j][i],sizeof(float),1,FP_GRAV); } } fclose(FP_GRAV); MPI_Barrier(MPI_COMM_WORLD); /* merge model file */ sprintf(jac_grav,"%s_tmp.rho",JACOBIAN); if (MYID==0) mergemod(jac_grav,3); MPI_Barrier(MPI_COMM_WORLD); /* gravity forward modelling */ read_density_glob(rho_grav,2); extend_mod(rho_grav,rho_grav_ext,nxgrav,nygrav); grav_mod(rho_grav_ext,ngrav,gravpos,gz_mod,nxgrav,nygrav,NZGRAV); /* calculate gravity data residuals */ L2_grav=calc_res_grav(ngrav,gz_mod,gz_res); /* calculate lambda 1 */ if(iter==1){ LAM_GRAV = GAMMA_GRAV * (L2sum/L2_grav); } /* add gravity penalty term to the seismic objective function */ L2t[1]+=LAM_GRAV * L2_grav; L2t[4]+=LAM_GRAV * L2_grav; /* calculate gravity gradient */ for (i=1;i<=NX;i=i+IDX){ for (j=1;j<=NY;j=j+IDY){ grad_grav[j][i]=0.0; } } grav_grad(ngrav,gravpos,grad_grav,gz_res); MPI_Barrier(MPI_COMM_WORLD); /* merge model file */ sprintf(jac,"%s_grav",JACOBIAN); if (MYID==0) mergemod(jac,3); /* free memory */ free_matrix(rho_grav,1,NYG,1,NXG); free_matrix(rho_grav_ext,1,nygrav,1,nxgrav); } /* Interpolate missing spatial gradient values in case IDXI > 1 || IDXY > 1 */ /* ------------------------------------------------------------------------ */ if((IDXI>1)||(IDYI>1)){ interpol(IDXI,IDYI,fwiPSV.waveconv,1); interpol(IDXI,IDYI,fwiPSV.waveconv_u,1); interpol(IDXI,IDYI,fwiPSV.waveconv_rho,1); } /* Preconditioning of gradients after shot summation */ precond_PSV(&fwiPSV,&acq,nsrc,ntr_glob,taper_coeff,FP_GRAV); /* Add gravity gradient to FWI density gradient */ /* -------------------------------------------- */ if(GRAVITY==2){ /* calculate maximum values of waveconv_rho and grad_grav */ FWImax = 0.0; GRAVmax = 0.0; for (i=1;i<=NX;i++){ for (j=1;j<=NY;j++){ if(fabs(fwiPSV.waveconv_rho[j][i])>FWImax){FWImax=fabs(fwiPSV.waveconv_rho[j][i]);} if(fabs(grad_grav[j][i])>GRAVmax){GRAVmax=fabs(grad_grav[j][i]);} } } MPI_Allreduce(&FWImax,&FWImax_all, 1,MPI_FLOAT,MPI_MAX,MPI_COMM_WORLD); MPI_Allreduce(&GRAVmax,&GRAVmax_all,1,MPI_FLOAT,MPI_MAX,MPI_COMM_WORLD); /* calculate lambda 2, normalized with respect to the maximum gradients */ if(iter==1){ LAM_GRAV_GRAD = GAMMA_GRAV * (FWImax_all/GRAVmax_all); } /* add gravity gradient to seismic gradient with respect to the density */ for (i=1;i<=NX;i++){ for (j=1;j<=NY;j++){ fwiPSV.waveconv_rho[j][i] += LAM_GRAV_GRAD * grad_grav[j][i]; } } } /* Use preconditioned conjugate gradient optimization method */ if(GRAD_METHOD==1){ PCG(fwiPSV.waveconv, taper_coeff, nsrc, acq.srcpos, acq.recpos, ntr_glob, iter, fwiPSV.gradp, fwiPSV.waveconv_u, fwiPSV.gradp_u, fwiPSV.waveconv_rho, fwiPSV.gradp_rho); } /* Use l-BFGS optimization */ if(GRAD_METHOD==2){ /* store models and gradients in l-BFGS vectors */ store_LBFGS_PSV(taper_coeff, nsrc, acq.srcpos, acq.recpos, ntr_glob, iter, fwiPSV.waveconv, fwiPSV.gradp, fwiPSV.waveconv_u, fwiPSV.gradp_u, fwiPSV.waveconv_rho, fwiPSV.gradp_rho, y_LBFGS, s_LBFGS, q_LBFGS, matPSV.ppi, matPSV.pu, matPSV.prho, NXNYI, LBFGS_pointer, NLBFGS, NLBFGS_vec); /* apply l-BFGS optimization */ LBFGS(iter, y_LBFGS, s_LBFGS, rho_LBFGS, alpha_LBFGS, q_LBFGS, r_LBFGS, beta_LBFGS, LBFGS_pointer, NLBFGS, NLBFGS_vec); /* extract gradients and save old models/gradients for next l-BFGS iteration */ extract_LBFGS_PSV(iter, fwiPSV.waveconv, fwiPSV.gradp, fwiPSV.waveconv_u, fwiPSV.gradp_u, fwiPSV.waveconv_rho, fwiPSV.gradp_rho, matPSV.ppi, matPSV.pu, matPSV.prho, r_LBFGS); } opteps_vp=0.0; opteps_vs=0.0; opteps_rho=0.0; /* ============================================================================================================================*/ /* =============================================== test loop L2 ===============================================================*/ /* ============================================================================================================================*/ /* set min_iter_help to initial global value of MIN_ITER */ if(iter==1){min_iter_help=MIN_ITER;} /* Estimate optimum step length ... */ /* ... by line search (parabolic fitting) */ eps_scale = step_length_est_psv(&wavePSV,&wavePSV_PML,&matPSV,&fwiPSV,&mpiPSV,&seisPSV,&seisPSVfwi,&acq,hc,iter,nsrc,ns,ntr,ntr_glob,epst1,L2t,nsrc_glob,nsrc_loc,&step1,&step3,nxgrav,nygrav,ngrav,gravpos,gz_mod,NZGRAV, ntr_loc,Ws,Wr,hin,DTINV_help,req_send,req_rec); /* no model update due to steplength estimation failed or update with the smallest steplength if the number of iteration is smaller than the minimum number of iteration per frequency MIN_ITER */ if((iter>min_iter_help)&&(step1==0)){ eps_scale=0.0; opteps_vp=0.0; } else{ opteps_vp=eps_scale; } /* write log-parameter files */ if(MYID==0){ printf("MYID = %d \t opteps_vp = %e \t opteps_vs = %e \t opteps_rho = %e \n",MYID,opteps_vp,opteps_vs,opteps_rho); printf("MYID = %d \t L2t[1] = %e \t L2t[2] = %e \t L2t[3] = %e \t L2t[4] = %e \n",MYID,L2t[1],L2t[2],L2t[3],L2t[4]); printf("MYID = %d \t epst1[1] = %e \t epst1[2] = %e \t epst1[3] = %e \n",MYID,epst1[1],epst1[2],epst1[3]); /*output of log file for combined inversion*/ if(iter_true==1){ LAMBDA = fopen("gravity/lambda.dat","w"); } if(iter_true>1){ LAMBDA = fopen("gravity/lambda.dat","a"); } fprintf(LAMBDA,"%d \t %d \t %e \t %e \t %e \t %e \t %e \t %e \t %e \n",nstage,iter,LAM_GRAV,L2sum,L2_grav,L2t[4],LAM_GRAV_GRAD,FWImax_all,GRAVmax_all); fclose(LAMBDA); } if(MYID==0){ if (TIME_FILT==0){ fprintf(FPL2,"%e \t %e \t %e \t %e \t %e \t %e \t %e \t %e \t %d \n",opteps_vp,epst1[1],epst1[2],epst1[3],L2t[1],L2t[2],L2t[3],L2t[4],nstage);} else{ fprintf(FPL2,"%e \t %e \t %e \t %e \t %e \t %e \t %e \t %e \t %f \t %f \t %d \n",opteps_vp,epst1[1],epst1[2],epst1[3],L2t[1],L2t[2],L2t[3],L2t[4],FC_START,FC,nstage);}} /* saving history of final L2*/ L2_hist[iter]=L2t[4]; s=0; /* calculate optimal change in the material parameters */ eps_true=calc_mat_change_test_PSV(fwiPSV.waveconv,fwiPSV.waveconv_rho,fwiPSV.waveconv_u,fwiPSV.prho_old,matPSV.prho,fwiPSV.ppi_old,matPSV.ppi,fwiPSV.pu_old,matPSV.pu,iter,1,eps_scale,0); if (MODEL_FILTER){ /* smoothing the velocity models vp and vs */ smooth_model(matPSV.ppi,matPSV.pu,matPSV.prho,iter); } if(MYID==0){ /* fprintf(FPL2,"=============================================================\n"); fprintf(FPL2,"=============================================================\n"); fprintf(FPL2,"STATISTICS FOR ITERATION STEP %d \n",iter); fprintf(FPL2,"=============================================================\n"); fprintf(FPL2,"=============================================================\n");*/ /* fprintf(FPL2,"Low-pass filter at %e Hz\n",freq); fprintf(FPL2,"----------------------------------------------\n"); */ /*fprintf(FPL2,"L2 at iteration step n = %e \n",L2);*/ /* fprintf(FPL2,"%e \t %e \t %e \t %e \t %e \t %e \t %e \t %e \n",EPSILON,EPSILON_u,EPSILON_rho,L2t[4],betaVp,betaVs,betarho,sqrt(C_vp));*/ /*fprintf(FPL2,"----------------------------------------------\n");*/ /* fprintf(FPL2,"=============================================================\n"); fprintf(FPL2,"=============================================================\n\n\n");*/ } if(MYID==0){ fclose(FPL2); } if (iter>min_iter_help){ float diff=0.0, pro=PRO; /* calculating differnce of the actual L2 and before two iterations, dividing with L2_hist[iter-2] provide changing in procent*/ diff=fabs((L2_hist[iter-2]-L2_hist[iter])/L2_hist[iter-2]); if((diff<=pro)||(step3==1)){ /* output of the model at the end of given corner frequency */ model_freq_out_PSV(matPSV.ppi,matPSV.prho,matPSV.pu,nstage,FC); s=1; min_iter_help=0; min_iter_help=iter+MIN_ITER; iter=0; if(GRAD_METHOD==2){ zero_LBFGS(NLBFGS, NLBFGS_vec, y_LBFGS, s_LBFGS, q_LBFGS, r_LBFGS, alpha_LBFGS, beta_LBFGS, rho_LBFGS); LBFGS_pointer = 1; } if(MYID==0){ if(step3==1){ printf("\n Steplength estimation failed step3=%d \n Changing to next FWI stage \n",step3); } else{ printf("\n Reached the abort criterion of pro=%e and diff=%e \n Changing to next FWI stage \n",pro,diff); } } break; } } iter++; iter_true++; /* ====================================== */ } /* end of fullwaveform iteration loop*/ /* ====================================== */ } /* End of FWI-workflow loop */ /* deallocate memory for PSV forward problem */ dealloc_PSV(&wavePSV,&wavePSV_PML); /* deallocation of memory */ free_matrix(fwiPSV.Vp0,-nd+1,NY+nd,-nd+1,NX+nd); free_matrix(fwiPSV.Vs0,-nd+1,NY+nd,-nd+1,NX+nd); free_matrix(fwiPSV.Rho0,-nd+1,NY+nd,-nd+1,NX+nd); free_matrix(matPSV.prho,-nd+1,NY+nd,-nd+1,NX+nd); free_matrix(fwiPSV.prho_old,-nd+1,NY+nd,-nd+1,NX+nd); free_matrix(matPSV.prip,-nd+1,NY+nd,-nd+1,NX+nd); free_matrix(matPSV.prjp,-nd+1,NY+nd,-nd+1,NX+nd); free_matrix(matPSV.ppi,-nd+1,NY+nd,-nd+1,NX+nd); free_matrix(fwiPSV.ppi_old,-nd+1,NY+nd,-nd+1,NX+nd); free_matrix(matPSV.pu,-nd+1,NY+nd,-nd+1,NX+nd); free_matrix(fwiPSV.pu_old,-nd+1,NY+nd,-nd+1,NX+nd); free_matrix(matPSV.puipjp,-nd+1,NY+nd,-nd+1,NX+nd); free_matrix(fwiPSV.waveconv,-nd+1,NY+nd,-nd+1,NX+nd); free_matrix(fwiPSV.waveconv_lam,-nd+1,NY+nd,-nd+1,NX+nd); free_matrix(fwiPSV.waveconv_shot,-nd+1,NY+nd,-nd+1,NX+nd); free_matrix(mpiPSV.bufferlef_to_rig,1,NY,1,fdo3); free_matrix(mpiPSV.bufferrig_to_lef,1,NY,1,fdo3); free_matrix(mpiPSV.buffertop_to_bot,1,NX,1,fdo3); free_matrix(mpiPSV.bufferbot_to_top,1,NX,1,fdo3); free_vector(hc,0,6); free_matrix(fwiPSV.gradg,-nd+1,NY+nd,-nd+1,NX+nd); free_matrix(fwiPSV.gradp,-nd+1,NY+nd,-nd+1,NX+nd); free_matrix(fwiPSV.gradg_rho,-nd+1,NY+nd,-nd+1,NX+nd); free_matrix(fwiPSV.gradp_rho,-nd+1,NY+nd,-nd+1,NX+nd); free_matrix(fwiPSV.waveconv_rho,-nd+1,NY+nd,-nd+1,NX+nd); free_matrix(fwiPSV.waveconv_rho_s,-nd+1,NY+nd,-nd+1,NX+nd); free_matrix(fwiPSV.waveconv_rho_shot,-nd+1,NY+nd,-nd+1,NX+nd); free_matrix(fwiPSV.gradg_u,-nd+1,NY+nd,-nd+1,NX+nd); free_matrix(fwiPSV.gradp_u,-nd+1,NY+nd,-nd+1,NX+nd); free_matrix(fwiPSV.waveconv_u,-nd+1,NY+nd,-nd+1,NX+nd); free_matrix(fwiPSV.waveconv_mu,-nd+1,NY+nd,-nd+1,NX+nd); free_matrix(fwiPSV.waveconv_u_shot,-nd+1,NY+nd,-nd+1,NX+nd); free_vector(fwiPSV.forward_prop_x,1,NY*NX*NT); free_vector(fwiPSV.forward_prop_y,1,NY*NX*NT); free_vector(fwiPSV.forward_prop_rho_x,1,NY*NX*NT); free_vector(fwiPSV.forward_prop_rho_y,1,NY*NX*NT); free_vector(fwiPSV.forward_prop_u,1,NY*NX*NT); if (nsrc_loc>0){ free_matrix(acq.signals,1,nsrc_loc,1,NT); free_matrix(acq.srcpos_loc,1,8,1,nsrc_loc); free_matrix(acq.srcpos_loc_back,1,6,1,nsrc_loc); } /* free memory for global source positions */ free_matrix(acq.srcpos,1,8,1,nsrc); /* free memory for source position definition */ free_matrix(acq.srcpos1,1,8,1,1); /* free memory for abort criterion */ free_vector(L2_hist,1,1000); free_vector(L2t,1,4); free_vector(epst1,1,3); if(N_STREAMER==0){ if (SEISMO) free_imatrix(acq.recpos,1,3,1,ntr_glob); if ((ntr>0) && (SEISMO)){ free_imatrix(acq.recpos_loc,1,3,1,ntr); acq.recpos_loc = NULL; switch (SEISMO){ case 1 : /* particle velocities only */ free_matrix(seisPSV.sectionvx,1,ntr,1,ns); free_matrix(seisPSV.sectionvy,1,ntr,1,ns); seisPSV.sectionvx=NULL; seisPSV.sectionvy=NULL; break; case 2 : /* pressure only */ free_matrix(seisPSV.sectionp,1,ntr,1,ns); break; case 3 : /* curl and div only */ free_matrix(seisPSV.sectioncurl,1,ntr,1,ns); free_matrix(seisPSV.sectiondiv,1,ntr,1,ns); break; case 4 : /* everything */ free_matrix(seisPSV.sectionvx,1,ntr,1,ns); free_matrix(seisPSV.sectionvy,1,ntr,1,ns); free_matrix(seisPSV.sectionp,1,ntr,1,ns); free_matrix(seisPSV.sectioncurl,1,ntr,1,ns); free_matrix(seisPSV.sectiondiv,1,ntr,1,ns); break; } } free_matrix(seisPSVfwi.sectionread,1,ntr_glob,1,ns); free_ivector(acq.recswitch,1,ntr); if((QUELLTYPB==1)||(QUELLTYPB==3)||(QUELLTYPB==5)||(QUELLTYPB==7)){ free_matrix(seisPSVfwi.sectionvxdata,1,ntr,1,ns); free_matrix(seisPSVfwi.sectionvxdiff,1,ntr,1,ns); free_matrix(seisPSVfwi.sectionvxdiffold,1,ntr,1,ns); } if((QUELLTYPB==1)||(QUELLTYPB==2)||(QUELLTYPB==6)||(QUELLTYPB==7)){ free_matrix(seisPSVfwi.sectionvydata,1,ntr,1,ns); free_matrix(seisPSVfwi.sectionvydiff,1,ntr,1,ns); free_matrix(seisPSVfwi.sectionvydiffold,1,ntr,1,ns); } if(QUELLTYPB>=4){ free_matrix(seisPSVfwi.sectionpdata,1,ntr,1,ns); free_matrix(seisPSVfwi.sectionpdiff,1,ntr,1,ns); free_matrix(seisPSVfwi.sectionpdiffold,1,ntr,1,ns); } } if(SEISMO){ free_matrix(seisPSV.fulldata,1,ntr_glob,1,NT); } if(SEISMO==1){ free_matrix(seisPSV.fulldata_vx,1,ntr_glob,1,NT); free_matrix(seisPSV.fulldata_vy,1,ntr_glob,1,NT); } if(SEISMO==2){ free_matrix(seisPSV.fulldata_p,1,ntr_glob,1,NT); } if(SEISMO==3){ free_matrix(seisPSV.fulldata_curl,1,ntr_glob,1,NT); free_matrix(seisPSV.fulldata_div,1,ntr_glob,1,NT); } if(SEISMO==4){ free_matrix(seisPSV.fulldata_vx,1,ntr_glob,1,NT); free_matrix(seisPSV.fulldata_vy,1,ntr_glob,1,NT); free_matrix(seisPSV.fulldata_p,1,ntr_glob,1,NT); free_matrix(seisPSV.fulldata_curl,1,ntr_glob,1,NT); free_matrix(seisPSV.fulldata_div,1,ntr_glob,1,NT); } free_ivector(DTINV_help,1,NT); /* free memory for viscoelastic modeling variables */ if (L) { free_matrix(matPSV.ptaus,-nd+1,NY+nd,-nd+1,NX+nd); free_matrix(matPSV.ptausipjp,-nd+1,NY+nd,-nd+1,NX+nd); free_matrix(matPSV.ptaup,-nd+1,NY+nd,-nd+1,NX+nd); free_vector(matPSV.peta,1,L); free_vector(matPSV.etaip,1,L); free_vector(matPSV.etajm,1,L); free_vector(matPSV.bip,1,L); free_vector(matPSV.bjm,1,L); free_vector(matPSV.cip,1,L); free_vector(matPSV.cjm,1,L); free_matrix(matPSV.f,-nd+1,NY+nd,-nd+1,NX+nd); free_matrix(matPSV.g,-nd+1,NY+nd,-nd+1,NX+nd); free_matrix(matPSV.fipjp,-nd+1,NY+nd,-nd+1,NX+nd); free_f3tensor(matPSV.dip,-nd+1,NY+nd,-nd+1,NX+nd,1,L); free_f3tensor(matPSV.d,-nd+1,NY+nd,-nd+1,NX+nd,1,L); free_f3tensor(matPSV.e,-nd+1,NY+nd,-nd+1,NX+nd,1,L); } if(GRAVITY){ free_matrix(gravpos,1,2,1,ngrav); free_vector(gz_mod,1,ngrav); free_vector(gz_res,1,ngrav); if(GRAVITY==2){ free_matrix(grad_grav,1,NY,1,NX); } } /* de-allocate buffer for messages */ MPI_Buffer_detach(buff_addr,&buffsize); MPI_Barrier(MPI_COMM_WORLD); if (MYID==0){ fprintf(FP,"\n **Info from main (written by PE %d): \n",MYID); fprintf(FP," CPU time of program per PE: %li seconds.\n",clock()/CLOCKS_PER_SEC); time8=MPI_Wtime(); fprintf(FP," Total real time of program: %4.2f seconds.\n",time8-time1); time_av_v_update=time_av_v_update/(double)NT; time_av_s_update=time_av_s_update/(double)NT; time_av_v_exchange=time_av_v_exchange/(double)NT; time_av_s_exchange=time_av_s_exchange/(double)NT; time_av_timestep=time_av_timestep/(double)NT; /* fprintf(FP," Average times for \n"); fprintf(FP," velocity update: \t %5.3f seconds \n",time_av_v_update); fprintf(FP," stress update: \t %5.3f seconds \n",time_av_s_update); fprintf(FP," velocity exchange: \t %5.3f seconds \n",time_av_v_exchange); fprintf(FP," stress exchange: \t %5.3f seconds \n",time_av_s_exchange); fprintf(FP," timestep: \t %5.3f seconds \n",time_av_timestep);*/ } fclose(FP); }
void model_elastic(float ** rho, float ** pi, float ** u){ /*--------------------------------------------------------------------------*/ FILE *FP1, *FP2, *FP3; /* extern variables */ extern float DH; extern int NX, NY, NXG, NYG, POS[3], MYID; /* local variables */ float Rho, Vp, Vs, Vpnm1, x, y, undf, r; float aund, ampund, FW, shiftx; int i, j, ii, jj; char modfile[STRING_SIZE]; /* parameters for background */ const float vp2=2000.0, vs2=vp2/sqrt(3.0), rho2=1000.0*0.31*pow(vp2,(1.0/4.0)); /* parameters for sphere 1 and 2 */ const float vp3=1500.0, vs3=vp3/sqrt(3.0), rho3=1000.0*0.31*pow(vp3,(1.0/4.0)); /* location of the spheres */ const float X01 = 80.0; const float Y01 = 130.0; /* radii of spheres */ float A0, A1, A3, A4, lambda0, lambda1, lambda3, lambda4; float y0, y1, y2, y3, y4, y5, undy0, undy1, undy3, undy4; lambda0=1600.0; A0=50.0; y0=1200.0; lambda1=lambda0/2.0; A1=100.0; y1=1000.0; y2=800.0; lambda3=lambda0/2.0; A3=150.0; y3=600.0; lambda4=lambda0/2.0; A4=50.0; y4=410.0; y5=100.0; FP1=fopen("/fastfs/koehn/DENISE_backup/par/start/crase_smooth_model_vp.dat","r"); FP2=fopen("/fastfs/koehn/DENISE_backup/par/start/crase_smooth_model_vs.dat","r"); FP3=fopen("/fastfs/koehn/DENISE_backup/par/start/crase_smooth_model_rho.dat","r"); /* loop over global grid */ for (i=1;i<=NXG;i++){ for (j=1;j<=NYG;j++){ fscanf(FP1,"%e\n",&Vp); fscanf(FP2,"%e\n",&Vs); fscanf(FP3,"%e\n",&Rho); if ((POS[1]==((i-1)/NX)) && (POS[2]==((j-1)/NY))){ ii=i-POS[1]*NX; jj=j-POS[2]*NY; u[jj][ii]=Vs*Vs*Rho; rho[jj][ii]=Rho; pi[jj][ii] = Vp*Vp*Rho - 2.0 * u[jj][ii]; /*if(j==NYG){pi[jj][ii] = pi[jj-1][ii];}*/ } } } /* each PE writes his model to disk */ sprintf(modfile,"model/waveform_test_model_u.bin"); writemod(modfile,u,3); MPI_Barrier(MPI_COMM_WORLD); if (MYID==0) mergemod(modfile,3); sprintf(modfile,"model/waveform_test_model_pi.bin"); writemod(modfile,pi,3); MPI_Barrier(MPI_COMM_WORLD); if (MYID==0) mergemod(modfile,3); sprintf(modfile,"model/waveform_test_model_rho.bin"); writemod(modfile,rho,3); MPI_Barrier(MPI_COMM_WORLD); if (MYID==0) mergemod(modfile,3); fclose(FP1); fclose(FP2); fclose(FP3); }
void model(float ** rho, float ** pi, float ** u, float ** taus, float ** taup, float * eta){ /*--------------------------------------------------------------------------*/ /* extern variables */ extern int NX, NY, NXG, NYG, POS[3], L, MYID; extern char MFILE[STRING_SIZE]; extern char INV_MODELFILE[STRING_SIZE]; extern float DH, *FL, TAU, DT; /* local variables */ float vp, vs, rhov, ts, tp, muv, piv, *pts; int i, j, ii, jj, l; char modfile[STRING_SIZE]; FILE *flfile; int nodes; char cline[256]; float *fldepth, *flrho, *flvp, *flvs; /*-----------------------------------------------------------------------*/ nodes=7; fldepth=vector(1,nodes); flrho=vector(1,nodes); flvp=vector(1,nodes); flvs=vector(1,nodes); pts=vector(1,L); for (l=1;l<=L;l++) { pts[l]=1.0/(2.0*PI*FL[l]); eta[l]=DT/pts[l]; } /*read FL nodes from File*/ flfile=fopen("model_true/model4.fl.dat","r"); if (flfile==NULL) err(" FL-file could not be opened !"); for (l=1;l<=nodes;l++){ fgets(cline,255,flfile); if (cline[0]!='#'){ sscanf(cline,"%f%f%f%f",&fldepth[l], &flrho[l], &flvp[l], &flvs[l]); } else l=l-1; } if(MYID==0){ printf(" ------------------------------------------------------------------ \n\n"); printf(" Information of FL nodes: \n\n"); printf(" \t depth \t rho \t vp \t vs \n\n"); for (l=1;l<=nodes;l++){ printf(" \t %f \t %f \t %f \t %f \n\n",fldepth[l],flrho[l],flvp[l],flvs[l]); } printf(" ------------------------------------------------------------------ \n\n"); } /*-----------------------------------------------------------------------*/ /* loop over global grid */ for (i=1;i<=NXG;i++){ for (l=1;l<nodes;l++){ for(j=(int)(fldepth[l]/DH)+1;j<=(int)(fldepth[l+1]/DH);j++){ vp=0.0; vs=0.0; rhov=0.0; vp=(DH*(j-1)-fldepth[l])*(flvp[l+1]-flvp[l])/(fldepth[l+1]-fldepth[l])+flvp[l]; vp=vp*1000.0; vs=(DH*(j-1)-fldepth[l])*(flvs[l+1]-flvs[l])/(fldepth[l+1]-fldepth[l])+flvs[l]; vs=vs*1000.0; rhov=(DH*(j-1)-fldepth[l])*(flrho[l+1]-flrho[l])/(fldepth[l+1]-fldepth[l])+flrho[l]; rhov=rhov*1000.0; muv=vs; piv=vp; ts=TAU; tp=TAU; /* only the PE which belongs to the current global gridpoint is saving model parameters in his local arrays */ if ((POS[1]==((i-1)/NX)) && (POS[2]==((j-1)/NY))){ ii=i-POS[1]*NX; jj=j-POS[2]*NY; u[jj][ii]=muv; rho[jj][ii]=rhov; pi[jj][ii]=piv; taus[jj][ii]=ts; taup[jj][ii]=tp; } } for (j=(int)(fldepth[nodes]/DH)+1;j<=NYG;j++){ vp=0.0; vs=0.0; rhov=0.0; vp=flvp[nodes]*1000.0; vs=flvs[nodes]*1000.0; rhov=flrho[nodes]*1000.0; muv=vs; piv=vp; ts=TAU; tp=TAU; /* only the PE which belongs to the current global gridpoint is saving model parameters in his local arrays */ if ((POS[1]==((i-1)/NX)) && (POS[2]==((j-1)/NY))){ ii=i-POS[1]*NX; jj=j-POS[2]*NY; u[jj][ii]=muv; rho[jj][ii]=rhov; pi[jj][ii]=piv; taus[jj][ii]=ts; taup[jj][ii]=tp; } } } } sprintf(modfile,"%s_rho_it_0.bin",INV_MODELFILE); writemod(modfile,rho,3); MPI_Barrier(MPI_COMM_WORLD); if (MYID==0) mergemod(modfile,3); sprintf(modfile,"%s_vs_it_0.bin",INV_MODELFILE); writemod(modfile,u,3); MPI_Barrier(MPI_COMM_WORLD); if (MYID==0) mergemod(modfile,3); sprintf(modfile,"%s_vp_it_0.bin",INV_MODELFILE); writemod(modfile,pi,3); MPI_Barrier(MPI_COMM_WORLD); if (MYID==0) mergemod(modfile,3); free_vector(fldepth,1,nodes); free_vector(flrho,1,nodes); free_vector(flvp,1,nodes); free_vector(flvs,1,nodes); free_vector(pts,1,L); }
void PCG(float ** waveconv, float ** taper_coeff, int nsrc, float ** srcpos, int ** recpos, int ntr_glob, int iter, float C_vp, float ** gradp, int nfstart_jac, float ** waveconv_u, float C_vs, float ** gradp_u, float ** waveconv_rho, float C_rho, float ** gradp_rho){ extern int NX, NY, IDX, IDY, SPATFILTER, GRAD_FILTER; extern int SWS_TAPER_GRAD_VERT, SWS_TAPER_GRAD_HOR, SWS_TAPER_GRAD_SOURCES, SWS_TAPER_FILE; extern int POS[3], MYID, GRAD_METHOD; extern char JACOBIAN[STRING_SIZE]; char jac[225], jac2[225]; int i, j; float betaz, betan, gradplastiter, gradclastiter, betar, beta; extern FILE *FP; FILE *FP3, *FP4, *FP6, *FP5; /* =================================================================================================================================================== */ /* ===================================================================================================================================================== */ /* ===================================================== GRADIENT ZP ================================================================================== */ /* ===================================================================================================================================================== */ /* Preconditioning of the gradient */ /* ------------------------------- */ /* apply taper on the gradient */ /* --------------------------- */ if (SWS_TAPER_GRAD_VERT){ /*vertical gradient taper is applied*/ taper_grad(waveconv,taper_coeff,srcpos,nsrc,recpos,ntr_glob,1);} if (SWS_TAPER_GRAD_HOR){ /*horizontal gradient taper is applied*/ taper_grad(waveconv,taper_coeff,srcpos,nsrc,recpos,ntr_glob,2);} if (SWS_TAPER_GRAD_SOURCES){ /*cylindrical taper around sources is applied*/ taper_grad(waveconv,taper_coeff,srcpos,nsrc,recpos,ntr_glob,3);} if (SWS_TAPER_FILE){ /* read taper from BIN-File*/ taper_grad(waveconv,taper_coeff,srcpos,nsrc,recpos,ntr_glob,4);} /* apply median filter at source positions */ /*median_src(waveconv,taper_coeff,srcpos,nsrc,recpos,ntr_glob,iter,0);*/ /* apply wavenumber damping */ if(SPATFILTER==1){ wavenumber(waveconv); } if(SPATFILTER==2){ smooth2(waveconv); } /* save gradient */ /*sprintf(jac,"%s_g.old.%i%i",JACOBIAN,POS[1],POS[2]); FP3=fopen(jac,"wb"); for (i=1;i<=NX;i=i+IDX){ for (j=1;j<=NY;j=j+IDY){ fwrite(&waveconv[j][i],sizeof(float),1,FP3); } } fclose(FP3); MPI_Barrier(MPI_COMM_WORLD);*/ /* merge gradient file */ /*sprintf(jac,"%s_g.old",JACOBIAN); if (MYID==0) mergemod(jac,3);*/ /* Normalize gradient to maximum value */ /*norm(waveconv,iter,1);*/ /* apply spatial wavelength filter */ /*if(SPATFILTER==1){ if (MYID==0){ fprintf(FP,"\n Spatial filter is applied to gradient (written by PE %d)\n",MYID);} spat_filt(waveconv,iter,1);}*/ /* apply 2D-Gaussian filter*/ if(GRAD_FILTER==1){smooth_grad(waveconv,1);} /* output of the preconditioned gradient */ for (i=1;i<=NX;i=i+IDX){ for (j=1;j<=NY;j=j+IDY){ waveconv[j][i] = C_vp * waveconv[j][i]; gradp[j][i] = waveconv[j][i]; } } /* save gradient for output as inversion result */ if(iter==nfstart_jac){ sprintf(jac,"%s_p_it%d.old.%i%i",JACOBIAN,iter,POS[1],POS[2]); FP3=fopen(jac,"wb"); for (i=1;i<=NX;i=i+IDX){ for (j=1;j<=NY;j=j+IDY){ fwrite(&waveconv[j][i],sizeof(float),1,FP3); } } fclose(FP3); MPI_Barrier(MPI_COMM_WORLD); /* merge gradient file */ sprintf(jac,"%s_p_it%d.old",JACOBIAN,iter); if (MYID==0) mergemod(jac,3); MPI_Barrier(MPI_COMM_WORLD); sprintf(jac,"%s_p_it%d.old.%i%i",JACOBIAN,iter,POS[1],POS[2]); remove(jac); } /* calculate conjugate gradient direction, if iter > 1 (after Mora 1987) */ /* --------------------------------------------------------------------- */ if(GRAD_METHOD!=3){ if(iter>1){ sprintf(jac,"%s_p.old.%i%i",JACOBIAN,POS[1],POS[2]); FP6=fopen(jac,"rb"); if(iter>2){ sprintf(jac2,"%s_c.old.%i%i",JACOBIAN,POS[1],POS[2]); FP5=fopen(jac2,"rb"); } /* apply scalar product to obtain the coefficient beta */ betaz = 0.0; betan = 0.0; for (i=1;i<=NX;i=i+IDX){ for (j=1;j<=NY;j=j+IDY){ fread(&gradplastiter,sizeof(float),1,FP6); /*if(gradglastiter==gradg[j][i]) err("TEST1");*/ /*if (MYID==10) printf("TEST beta (MYID=%d) bei (j,i)=(%i,%i): gradg(k-1) = %e, gradg(k) = %e\n",MYID,j,i,gradglastiter,gradg[j][i]);*/ /* betaz += (1e5*gradp[j][i]) * ( (1e5*gradg[j][i]) - (1e5*gradglastiter) ); betan += (1e5*gradplastiter) * (1e5*gradglastiter); */ /* Polak and Ribiere */ /*betaz += (gradp[j][i]) * ( (gradg[j][i]) - (gradglastiter) ); betan += (gradplastiter) * (gradglastiter);*/ /* Polak and Ribiere */ betaz += (gradp[j][i]) * ( (gradp[j][i]) - (gradplastiter) ); betan += (gradplastiter) * (gradplastiter); /* Fletcher and Reeves */ /*betaz += (gradp[j][i]) * (gradg[j][i]); betan += (gradplastiter) * (gradglastiter);*/ } } /*printf("TEST: vor exchange (MYID=%d): beta = betaz/betan = %e/%e = %e\n",MYID,betaz,betan,betaz/betan);*/ /*betaz = exchange_L2(betaz,1,1); betan = exchange_L2(betan,1,1);*/ betar = 0.0; MPI_Allreduce(&betaz,&betar,1,MPI_FLOAT,MPI_SUM,MPI_COMM_WORLD); betaz = betar; betar = 0.0; MPI_Allreduce(&betan,&betar,1,MPI_FLOAT,MPI_SUM,MPI_COMM_WORLD); betan = betar; beta = 0.0f; if(betan !=0.0f) beta = betaz/betan; /* direction reset */ if(beta<0.0){beta = 0.0;} /*betaVp = beta;*/ printf("\n\nTEST: nach exchange (MYID=%d): beta = %e / %e = %e\n",MYID,betaz,betan,beta); fseek(FP6,0,SEEK_SET); for (i=1;i<=NX;i=i+IDX){ for (j=1;j<=NY;j=j+IDY){ if(iter==2){ fread(&gradplastiter,sizeof(float),1,FP6); waveconv[j][i] = gradp[j][i] + gradplastiter * beta; } if(iter>2){ fread(&gradclastiter,sizeof(float),1,FP5); waveconv[j][i] = gradp[j][i] + gradclastiter * beta; } } } fclose(FP6); if(iter>2){fclose(FP5);} } /* output of the conjugate gradient */ if(iter>1){ sprintf(jac2,"%s_c.old.%i%i",JACOBIAN,POS[1],POS[2]); FP5=fopen(jac2,"wb"); for (i=1;i<=NX;i=i+IDX){ for (j=1;j<=NY;j=j+IDY){ fwrite(&waveconv[j][i],sizeof(float),1,FP5); } } fclose(FP5); MPI_Barrier(MPI_COMM_WORLD); /* merge gradient file */ sprintf(jac2,"%s_c.old",JACOBIAN); if (MYID==0) mergemod(jac2,3); } } /* end of if GRAD_METHOD!=3*/ /* output of preconditioned gradient */ sprintf(jac,"%s_p.old.%i%i",JACOBIAN,POS[1],POS[2]); FP4=fopen(jac,"wb"); /* output of the preconditioned gradient */ for (i=1;i<=NX;i=i+IDX){ for (j=1;j<=NY;j=j+IDY){ /*fwrite(&waveconv[j][i],sizeof(float),1,FP4);*/ fwrite(&gradp[j][i],sizeof(float),1,FP4); } } fclose(FP4); MPI_Barrier(MPI_COMM_WORLD); /* merge gradient file */ sprintf(jac,"%s_p.old",JACOBIAN); if (MYID==0) mergemod(jac,3); /* =================================================================================================================================================== */ /* ===================================================================================================================================================== */ /* ===================================================== GRADIENT Zs ================================================================================== */ /* ===================================================================================================================================================== */ /* Preconditioning of the gradient */ /* ------------------------------- */ /* apply taper on the gradient */ /* --------------------------- */ if (SWS_TAPER_GRAD_VERT){ /*vertical gradient taper is applied*/ taper_grad(waveconv_u,taper_coeff,srcpos,nsrc,recpos,ntr_glob,1);} if (SWS_TAPER_GRAD_HOR){ /*horizontal gradient taper is applied*/ taper_grad(waveconv_u,taper_coeff,srcpos,nsrc,recpos,ntr_glob,2);} if (SWS_TAPER_GRAD_SOURCES){ /*cylindrical taper around sources is applied*/ taper_grad(waveconv_u,taper_coeff,srcpos,nsrc,recpos,ntr_glob,3);} if (SWS_TAPER_FILE){ /* read taper from BIN-File*/ taper_grad(waveconv_u,taper_coeff,srcpos,nsrc,recpos,ntr_glob,5);} /* apply median filter at source positions */ /*median_src(waveconv_u,taper_coeff,srcpos,nsrc,recpos,ntr_glob,iter,0);*/ /* apply wavenumber damping */ if(SPATFILTER==1){ wavenumber(waveconv_u); } if(SPATFILTER==2){ smooth2(waveconv_u); } /* save gradient */ /*sprintf(jac,"%s_g_u.old.%i%i",JACOBIAN,POS[1],POS[2]); FP3=fopen(jac,"wb"); for (i=1;i<=NX;i=i+IDX){ for (j=1;j<=NY;j=j+IDY){ fwrite(&waveconv_u[j][i],sizeof(float),1,FP3); } } fclose(FP3); MPI_Barrier(MPI_COMM_WORLD);*/ /* merge gradient file */ /*sprintf(jac,"%s_g_u.old",JACOBIAN); if (MYID==0) mergemod(jac,3);*/ /* Normalize gradient to maximum value */ /*norm(waveconv_u,iter,2);*/ /* apply spatial wavelength filter */ /*if(SPATFILTER==1){ if (MYID==0){ fprintf(FP,"\n Spatial filter is applied to gradient (written by PE %d)\n",MYID);} spat_filt(waveconv_u,iter,2);}*/ /* apply 2D-Gaussian filter*/ if(GRAD_FILTER==1){smooth_grad(waveconv_u,2);} /* output of the preconditioned gradient */ for (i=1;i<=NX;i=i+IDX){ for (j=1;j<=NY;j=j+IDY){ waveconv_u[j][i] = C_vs * waveconv_u[j][i]; gradp_u[j][i]=waveconv_u[j][i]; } } /* save gradient for output as inversion result */ if(iter==nfstart_jac){ sprintf(jac,"%s_p_u_it%d.old.%i%i",JACOBIAN,iter,POS[1],POS[2]); FP3=fopen(jac,"wb"); for (i=1;i<=NX;i=i+IDX){ for (j=1;j<=NY;j=j+IDY){ fwrite(&waveconv_u[j][i],sizeof(float),1,FP3); } } fclose(FP3); MPI_Barrier(MPI_COMM_WORLD); /* merge gradient file */ sprintf(jac,"%s_p_u_it%d.old",JACOBIAN,iter); if (MYID==0) mergemod(jac,3); MPI_Barrier(MPI_COMM_WORLD); sprintf(jac,"%s_p_u_it%d.old.%i%i",JACOBIAN,iter,POS[1],POS[2]); remove(jac); } /* calculate conjugate gradient direction, if iter > 1 (after Mora 1987) */ /* --------------------------------------------------------------------- */ if(GRAD_METHOD!=3){ if(iter>1){ sprintf(jac,"%s_p_u.old.%i%i",JACOBIAN,POS[1],POS[2]); FP6=fopen(jac,"rb"); if(iter>2){ sprintf(jac2,"%s_c_u.old.%i%i",JACOBIAN,POS[1],POS[2]); FP5=fopen(jac2,"rb"); } /* apply scalar product to obtain the coefficient beta */ betaz = 0.0; betan = 0.0; for (i=1;i<=NX;i=i+IDX){ for (j=1;j<=NY;j=j+IDY){ fread(&gradplastiter,sizeof(float),1,FP6); /*if(gradglastiter==gradg[j][i]) err("TEST1");*/ /*if (MYID==10) printf("TEST beta (MYID=%d) bei (j,i)=(%i,%i): gradg(k-1) = %e, gradg(k) = %e\n",MYID,j,i,gradglastiter,gradg[j][i]);*/ /* betaz += (1e5*gradp[j][i]) * ( (1e5*gradg[j][i]) - (1e5*gradglastiter) ); betan += (1e5*gradplastiter) * (1e5*gradglastiter); */ /* Polak and Ribiere */ /*betaz += (gradp_u[j][i]) * ( (gradg_u[j][i]) - (gradglastiter) ); betan += (gradplastiter) * (gradglastiter);*/ /* Polak and Ribiere */ betaz += (gradp_u[j][i]) * ( (gradp_u[j][i]) - (gradplastiter) ); betan += (gradplastiter) * (gradplastiter); /* Fletcher and Reeves */ /*betaz += (gradp[j][i]) * (gradg[j][i]); betan += (gradplastiter) * (gradglastiter);*/ } } /*printf("TEST: vor exchange (MYID=%d): beta = betaz/betan = %e/%e = %e\n",MYID,betaz,betan,betaz/betan);*/ /*betaz = exchange_L2(betaz,1,1); betan = exchange_L2(betan,1,1);*/ betar = 0.0; MPI_Allreduce(&betaz,&betar,1,MPI_FLOAT,MPI_SUM,MPI_COMM_WORLD); betaz = betar; betar = 0.0; MPI_Allreduce(&betan,&betar,1,MPI_FLOAT,MPI_SUM,MPI_COMM_WORLD); betan = betar; beta = 0.0f; if(betan !=0.0f) beta = betaz/betan; /* direction reset */ if(beta<0.0){beta = 0.0;} /*betaVs = beta;*/ printf("\n\nTEST: nach exchange (MYID=%d): beta = %e / %e = %e\n",MYID,betaz,betan,beta); fseek(FP6,0,SEEK_SET); for (i=1;i<=NX;i=i+IDX){ for (j=1;j<=NY;j=j+IDY){ if(iter==2){ fread(&gradplastiter,sizeof(float),1,FP6); waveconv_u[j][i] = gradp_u[j][i] + gradplastiter * beta; } if(iter>2){ fread(&gradclastiter,sizeof(float),1,FP5); waveconv_u[j][i] = gradp_u[j][i] + gradclastiter * beta; } } } fclose(FP6); if(iter>2){fclose(FP5);} } /* output of the conjugate gradient */ if(iter>1){ sprintf(jac2,"%s_c_u.old.%i%i",JACOBIAN,POS[1],POS[2]); FP5=fopen(jac2,"wb"); for (i=1;i<=NX;i=i+IDX){ for (j=1;j<=NY;j=j+IDY){ fwrite(&waveconv_u[j][i],sizeof(float),1,FP5); } } fclose(FP5); MPI_Barrier(MPI_COMM_WORLD); /* merge gradient file */ sprintf(jac2,"%s_c_u.old",JACOBIAN); if (MYID==0) mergemod(jac2,3); } } /* end of GRAD_METHOD!=3*/ sprintf(jac,"%s_p_u.old.%i%i",JACOBIAN,POS[1],POS[2]); FP4=fopen(jac,"wb"); /* output of the preconditioned gradient */ for (i=1;i<=NX;i=i+IDX){ for (j=1;j<=NY;j=j+IDY){ /*fwrite(&waveconv_u[j][i],sizeof(float),1,FP4);*/ fwrite(&gradp_u[j][i],sizeof(float),1,FP4); } } fclose(FP4); MPI_Barrier(MPI_COMM_WORLD); /* merge gradient file */ sprintf(jac,"%s_p_u.old",JACOBIAN); if (MYID==0) mergemod(jac,3); /* =================================================================================================================================================== */ /* ===================================================================================================================================================== */ /* ===================================================== GRADIENT rho ================================================================================== */ /* ===================================================================================================================================================== */ /* Preconditioning of the gradient */ /* ------------------------------- */ if (SWS_TAPER_GRAD_VERT){ /*vertical gradient taper is applied*/ taper_grad(waveconv_rho,taper_coeff,srcpos,nsrc,recpos,ntr_glob,1);} if (SWS_TAPER_GRAD_HOR){ /*horizontal gradient taper is applied*/ taper_grad(waveconv_rho,taper_coeff,srcpos,nsrc,recpos,ntr_glob,2);} if (SWS_TAPER_GRAD_SOURCES){ /*cylindrical taper around sources is applied*/ taper_grad(waveconv_rho,taper_coeff,srcpos,nsrc,recpos,ntr_glob,3);} if (SWS_TAPER_FILE){ /* read taper from BIN-File*/ taper_grad(waveconv_rho,taper_coeff,srcpos,nsrc,recpos,ntr_glob,6);} /* apply median filter at source positions */ /*median_src(waveconv_rho,taper_coeff,srcpos,nsrc,recpos,ntr_glob,iter,0);*/ /* apply wavenumber damping */ if(SPATFILTER==1){ wavenumber(waveconv_rho); } if(SPATFILTER==2){ smooth2(waveconv_rho); } /* save gradient */ /*sprintf(jac,"%s_g_rho.old.%i%i",JACOBIAN,POS[1],POS[2]); FP3=fopen(jac,"wb"); for (i=1;i<=NX;i=i+IDX){ for (j=1;j<=NY;j=j+IDY){ fwrite(&waveconv_rho[j][i],sizeof(float),1,FP3); } } fclose(FP3); MPI_Barrier(MPI_COMM_WORLD);*/ /* merge gradient file */ /*sprintf(jac,"%s_g_rho.old",JACOBIAN); if (MYID==0) mergemod(jac,3);*/ /* Normalize gradient to maximum value */ /*norm(waveconv_rho,iter,3);*/ /* apply spatial wavelength filter */ /*if(SPATFILTER==1){ if (MYID==0){ fprintf(FP,"\n Spatial filter is applied to gradient (written by PE %d)\n",MYID);} spat_filt(waveconv_rho,iter,3);}*/ /* apply 2D-Gaussian filter*/ if(GRAD_FILTER==1){smooth_grad(waveconv_rho,3);} /* output of the preconditioned gradient */ for (i=1;i<=NX;i=i+IDX){ for (j=1;j<=NY;j=j+IDY){ waveconv_rho[j][i] = C_rho * waveconv_rho[j][i]; gradp_rho[j][i]=waveconv_rho[j][i]; } } /* save gradient for output as inversion result */ if(iter==nfstart_jac){ sprintf(jac,"%s_p_rho_it%d.old.%i%i",JACOBIAN,iter,POS[1],POS[2]); FP3=fopen(jac,"wb"); for (i=1;i<=NX;i=i+IDX){ for (j=1;j<=NY;j=j+IDY){ fwrite(&waveconv_rho[j][i],sizeof(float),1,FP3); } } fclose(FP3); MPI_Barrier(MPI_COMM_WORLD); /* merge gradient file */ sprintf(jac,"%s_p_rho_it%d.old",JACOBIAN,iter); if (MYID==0) mergemod(jac,3); MPI_Barrier(MPI_COMM_WORLD); sprintf(jac,"%s_p_rho_it%d.old.%i%i",JACOBIAN,iter,POS[1],POS[2]); remove(jac); } /* calculate conjugate gradient direction, if iter > 1 (after Mora 1987) */ /* --------------------------------------------------------------------- */ if(GRAD_METHOD!=3){ if(iter>1){ sprintf(jac,"%s_p_rho.old.%i%i",JACOBIAN,POS[1],POS[2]); FP6=fopen(jac,"rb"); if(iter>2){ sprintf(jac2,"%s_c_rho.old.%i%i",JACOBIAN,POS[1],POS[2]); FP5=fopen(jac2,"rb"); } /* apply scalar product to obtain the coefficient beta */ betaz = 0.0; betan = 0.0; for (i=1;i<=NX;i=i+IDX){ for (j=1;j<=NY;j=j+IDY){ fread(&gradplastiter,sizeof(float),1,FP6); /*if(gradglastiter==gradg[j][i]) err("TEST1");*/ /*if (MYID==10) printf("TEST beta (MYID=%d) bei (j,i)=(%i,%i): gradg(k-1) = %e, gradg(k) = %e\n",MYID,j,i,gradglastiter,gradg[j][i]);*/ /* betaz += (1e5*gradp[j][i]) * ( (1e5*gradg[j][i]) - (1e5*gradglastiter) ); betan += (1e5*gradplastiter) * (1e5*gradglastiter); */ /* Polak and Ribiere */ /*betaz += (gradp_rho[j][i]) * ( (gradg_rho[j][i]) - (gradglastiter) ); betan += (gradplastiter) * (gradglastiter);*/ /* Polak and Ribiere */ betaz += (gradp_rho[j][i]) * ( (gradp_rho[j][i]) - (gradplastiter) ); betan += (gradplastiter) * (gradplastiter); /* Fletcher and Reeves */ /*betaz += (gradp[j][i]) * (gradg[j][i]); betan += (gradplastiter) * (gradglastiter);*/ } } /*printf("TEST: vor exchange (MYID=%d): beta = betaz/betan = %e/%e = %e\n",MYID,betaz,betan,betaz/betan);*/ /*betaz = exchange_L2(betaz,1,1); betan = exchange_L2(betan,1,1);*/ betar = 0.0; MPI_Allreduce(&betaz,&betar,1,MPI_FLOAT,MPI_SUM,MPI_COMM_WORLD); betaz = betar; betar = 0.0; MPI_Allreduce(&betan,&betar,1,MPI_FLOAT,MPI_SUM,MPI_COMM_WORLD); betan = betar; beta = 0.0f; if(betan !=0.0f) beta = betaz/betan; /* direction reset */ if(beta<0.0){beta = 0.0;} /*betarho = beta;*/ printf("\n\nTEST: nach exchange (MYID=%d): beta = %e / %e = %e\n",MYID,betaz,betan,beta); fseek(FP6,0,SEEK_SET); for (i=1;i<=NX;i=i+IDX){ for (j=1;j<=NY;j=j+IDY){ if(iter==2){ fread(&gradplastiter,sizeof(float),1,FP6); waveconv_rho[j][i] = gradp_rho[j][i] + gradplastiter * beta; } if(iter>2){ fread(&gradclastiter,sizeof(float),1,FP5); waveconv_rho[j][i] = gradp_rho[j][i] + gradclastiter * beta; } /*if (iter >= 2) { if (isnan(waveconv_u[j][i]) || isinf(waveconv_u[j][i])) { sum = 0.0; h = 0; for (ii=-1;ii<=1;ii++){ for (jj=-1;jj<=1;jj++){ if (isnan(waveconv_rho[j+jj][i+ii]) || isinf(waveconv_rho[j+jj][i+ii])) continue; sum += waveconv_rho[j+jj][i+ii]; h++; } } if (h>0) waveconv_rho[j][i] = sum / h; else waveconv_rho[j][i] = 0.0; } }*/ } } fclose(FP6); if(iter>2){fclose(FP5);} } /* output of the conjugate gradient */ if(iter>1){ sprintf(jac2,"%s_c_rho.old.%i%i",JACOBIAN,POS[1],POS[2]); FP5=fopen(jac2,"wb"); for (i=1;i<=NX;i=i+IDX){ for (j=1;j<=NY;j=j+IDY){ fwrite(&waveconv_rho[j][i],sizeof(float),1,FP5); } } fclose(FP5); MPI_Barrier(MPI_COMM_WORLD); /* merge gradient file */ sprintf(jac2,"%s_c_rho.old",JACOBIAN); if (MYID==0) mergemod(jac2,3); } } /* end of GRAD_METHOD!=3 */ sprintf(jac,"%s_p_rho.old.%i%i",JACOBIAN,POS[1],POS[2]); FP4=fopen(jac,"wb"); /* output of the preconditioned gradient */ for (i=1;i<=NX;i=i+IDX){ for (j=1;j<=NY;j=j+IDY){ /*fwrite(&waveconv_rho[j][i],sizeof(float),1,FP4);*/ fwrite(&gradp_rho[j][i],sizeof(float),1,FP4); } } fclose(FP4); MPI_Barrier(MPI_COMM_WORLD); /* merge gradient file */ sprintf(jac,"%s_p_rho.old",JACOBIAN); if (MYID==0) mergemod(jac,3); }
void model(float ** rho, float ** pi, float ** u, float ** taus, float ** taup, float * eta){ /*--------------------------------------------------------------------------*/ /* extern variables */ extern int NX, NY, NXG, NYG, POS[3], L, MYID; extern char MFILE[STRING_SIZE]; extern char INV_MODELFILE[STRING_SIZE]; extern float DH, *FL, TAU, DT; /* local variables */ float vp, vs, rhov, grad1, grad2, grad3, x, ts, tp, muv, piv, *pts, lkappa, lmu; float Qp, Qs, Qpinv, llambda; int i, j, ii, jj, l; char modfile[STRING_SIZE]; /* parameters for homogenous half-space */ /* perfect model parameters */ float vp1=2700.0, vs1=1776.0, rho1=2120.0, Qmu=20.0, Qkappa=10000.0; /*float vs2=1551.0;*/ float vs2=1400; /* calculate lateral linear gradient */ float x1 = 0.208; float b = vs1; float a = (vs2-vs1)/(x1-DH); /*-----------------------------------------------------------------------*/ pts=vector(1,L); for (l=1;l<=L;l++) { pts[l]=1.0/(2.0*PI*FL[l]); eta[l]=DT/pts[l]; } /* loop over global grid */ for (i=1;i<=NXG;i++){ for (j=1;j<=NYG;j++){ vp=vp1; rhov=rho1; /* x-coordinate on FD-grid */ x = i*DH; /* calculate Vs */ vs = a*x + b; if(x>=x1){vs = vs2;} if(x<x1){vs = vs1;} /* calculate kappa and mu*/ /*lmu=vs*vs*rhov; llambda = rhov*(vp*vp*rhov - 2.0*lmu); lkappa = llambda + ((2.0/3.0)*lmu); Qpinv = (1.0/Qmu) + (lkappa/(lkappa+(4.0*lmu/3.0)))*((1.0/Qkappa)-(1.0/Qmu)); Qp = 1.0/Qpinv;*/ Qp = Qkappa; Qs = Qmu; ts=2.0/Qs; tp=2.0/Qp; /* only the PE which belongs to the current global gridpoint is saving model parameters in his local arrays */ if ((POS[1]==((i-1)/NX)) && (POS[2]==((j-1)/NY))){ ii=i-POS[1]*NX; jj=j-POS[2]*NY; u[jj][ii]=vs; rho[jj][ii]=rhov; pi[jj][ii]=vp; taus[jj][ii]=ts; taup[jj][ii]=tp; } } } sprintf(modfile,"%s_rho_it_0.bin",INV_MODELFILE); writemod(modfile,rho,3); MPI_Barrier(MPI_COMM_WORLD); if (MYID==0) mergemod(modfile,3); sprintf(modfile,"%s_vs_it_0.bin",INV_MODELFILE); writemod(modfile,u,3); MPI_Barrier(MPI_COMM_WORLD); if (MYID==0) mergemod(modfile,3); sprintf(modfile,"%s_vp_it_0.bin",INV_MODELFILE); writemod(modfile,pi,3); MPI_Barrier(MPI_COMM_WORLD); if (MYID==0) mergemod(modfile,3); free_vector(pts,1,L); }
void model_elastic(float ** rho, float ** pi, float ** u){ /*--------------------------------------------------------------------------*/ /* extern variables */ extern float DT, DH; extern int NX, NY, NXG, NYG, POS[3], MYID; extern char MFILE[STRING_SIZE]; /* local variables */ float rhov, muv, piv, vp, vs, y, t, de, zplat1, zplat2, rplat; float *pts, ts, tp, sumu, sumpi, ws, *ri, *d, *ti, *dl, *vsl, z, r; float **checkp, **checks, **checkrho; int i, j, l, ii, jj, nk, k, nl; char filename_mu[STRING_SIZE]; char filename_rho[STRING_SIZE]; char filename_pi[STRING_SIZE]; sprintf(filename_mu,"%s.mu",MFILE); sprintf(filename_rho,"%s.rho",MFILE); sprintf(filename_pi,"%s.pi",MFILE); /*-----------------------------------------------------------------------*/ /* loop over global grid */ for (i=1;i<=NXG;i++){ for (j=1;j<=NYG;j++){ y = j*DH; vs = 1150.0; vp = 2000.0; rhov = 1800.0; if(y<0.01){ vs = 2310.0; vp = 4000.0; rhov = 1800.0; } /* only the PE which belongs to the current global gridpoint is saving model parameters in his local arrays */ if ((POS[1]==((i-1)/NX)) && (POS[2]==((j-1)/NY))){ ii = i-POS[1]*NX; jj = j-POS[2]*NY; u[jj][ii] = vs; rho[jj][ii] = rhov; pi[jj][ii] = vp; } } } /* each PE writes his model to disk */ writemod(filename_rho,rho,3); MPI_Barrier(MPI_COMM_WORLD); if (MYID==0) mergemod(filename_rho,3); /* each PE writes his model to disk */ writemod(filename_pi,pi,3); MPI_Barrier(MPI_COMM_WORLD); if (MYID==0) mergemod(filename_pi,3); /* each PE writes his model to disk */ writemod(filename_mu,u,3); MPI_Barrier(MPI_COMM_WORLD); if (MYID==0) mergemod(filename_mu,3); }
void hessian(int nshots, int SHOTINC, float *** green_vx, float *** greeni_vx, float *** green_vy, float *** greeni_vy, float *** green_sxx, float *** greeni_sxx, float *** green_syy, float *** greeni_syy, float *** green_sxy, float *** greeni_sxy, float ** prho, float ** pu, float ** ppi){ extern float DT,TIME; extern float FC_HESSIAN; extern int NX, NY, IDX, IDY, DTINV, INVMAT1, MYID, POS[4], FDORDER; extern char JACOBIAN[STRING_SIZE]; /* local variables */ int i, j, k, l, ns_hess, ishot, irec, nd, NSRC_HESSIAN, RECINC; double trig1,trig2; double t=0.0; const double pi=4.0*atan(1.0); char jac[STRING_SIZE]; float complex green_x, green_y, tmp_mu1_shot, tmp_mu2_shot, tmp_mu3_shot, tmp_mu5_shot, tmp_mu6_shot; float tmp_mu1, tmp_mu2, tmp_mu3; float complex tmp_jac_lam, tmp_jac_mu, tmp_jac_rho, tmp_jac_vp, tmp_jac_vs, tmp_fft_fsignal; float ** abs_green, omega, mulamratio, lamss, muss, HESS_SCALE; float ** hessian, ** hessian_u, ** hessian_rho, ** hessian_lam, ** hessian_mu; float ** hvxx_shot, ** hvxxi_shot, ** hvyy_shot, ** hvyyi_shot, ** hvxy_shot, ** hvxyi_shot, ** hvyx_shot, ** hvyxi_shot; float *psource_hess=NULL, *Hess_for_real=NULL, *Hess_for_complex=NULL; FILE *FP4; HESS_SCALE = 1e5; RECINC = 1; NSRC_HESSIAN=nshots; nd = FDORDER/2 + 1; abs_green = matrix(-nd+1,NY+nd,-nd+1,NX+nd); /* Diagonal elements of the Hessian*/ hessian = matrix(-nd+1,NY+nd,-nd+1,NX+nd); hessian_u = matrix(-nd+1,NY+nd,-nd+1,NX+nd); hessian_lam = matrix(-nd+1,NY+nd,-nd+1,NX+nd); hessian_mu = matrix(-nd+1,NY+nd,-nd+1,NX+nd); hessian_rho = matrix(-nd+1,NY+nd,-nd+1,NX+nd); hvxx_shot = matrix(-nd+1,NY+nd,-nd+1,NX+nd); hvxxi_shot = matrix(-nd+1,NY+nd,-nd+1,NX+nd); hvyy_shot = matrix(-nd+1,NY+nd,-nd+1,NX+nd); hvyyi_shot = matrix(-nd+1,NY+nd,-nd+1,NX+nd); hvyx_shot = matrix(-nd+1,NY+nd,-nd+1,NX+nd); hvyxi_shot = matrix(-nd+1,NY+nd,-nd+1,NX+nd); hvxy_shot = matrix(-nd+1,NY+nd,-nd+1,NX+nd); hvxyi_shot = matrix(-nd+1,NY+nd,-nd+1,NX+nd); Hess_for_real = vector(1,1); Hess_for_complex = vector(1,1); for (i=1;i<=NX;i=i+IDX){ for (j=1;j<=NY;j=j+IDY){ hessian[j][i]=0.0; hessian_lam[j][i]=0.0; hessian_u[j][i]=0.0; hessian_mu[j][i]=0.0; hessian_rho[j][i]=0.0; } } /* assemble Hessian */ /* ----------------------------------------------------------------- */ /* calculate absolute values of impulse responses */ for (ishot=1;ishot<=nshots;ishot=ishot+SHOTINC){ for (i=1;i<=NX;i=i+IDX){ for (j=1;j<=NY;j=j+IDY){ green_x = green_vx[j][i][ishot] + greeni_vx[j][i][ishot] * I; green_y = green_vy[j][i][ishot] + greeni_vy[j][i][ishot] * I; /*abs_green[j][i] += creal((green_x*conj(green_x))+(green_y*conj(green_y)));*/ abs_green[j][i] = 1.0; /*printf("green_x = %e \n",green_sxx[j][i][ishot]);*/ } } } omega = 2.0*M_PI*FC_HESSIAN; /*printf("omega = %e \n",omega); printf("NSRC = %d \n",NSRC_HESSIAN);*/ /*psource_hess=rd_sour(&ns_hess,fopen(SIGNAL_FILE,"r")); FFT_data(psource_hess,Hess_for_real,Hess_for_complex,NT); MPI_Barrier(MPI_COMM_WORLD); tmp_fft_fsignal = Hess_for_real[1] + Hess_for_complex[1] * I;*/ tmp_fft_fsignal = 1.0; for (ishot=1;ishot<=nshots;ishot=ishot+SHOTINC){ /*for (i=1;i<=NX;i=i+IDX){ for (j=1;j<=NY;j=j+IDY){*/ /* calculate spatial derivatives of the forward wavefields */ /*hvxx_shot[j][i] = (green_vx[j][i][ishot]-green_vx[j][i-1][ishot])/DH; hvxxi_shot[j][i] = (greeni_vx[j][i][ishot]-greeni_vx[j][i-1][ishot])/DH; hvyy_shot[j][i] = (green_vy[j][i][ishot]-green_vy[j-1][i][ishot])/DH; hvyyi_shot[j][i] = (greeni_vy[j][i][ishot]-greeni_vy[j-1][i][ishot])/DH; hvyx_shot[j][i] = (green_vy[j][i+1][ishot]-green_vy[j][i][ishot])/DH; hvyxi_shot[j][i] = (greeni_vy[j][i+1][ishot]-greeni_vy[j][i][ishot])/DH; hvxy_shot[j][i] = (green_vx[j+1][i][ishot]-green_vx[j][i][ishot])/DH; hvxyi_shot[j][i] = (greeni_vx[j+1][i][ishot]-greeni_vx[j][i][ishot])/DH;*/ /* } }*/ for (irec=nshots;irec<=nshots;irec=irec+RECINC){ /* construct Hessian for different material parameters */ for (i=1;i<=NX;i=i+IDX){ for (j=1;j<=NY;j=j+IDY){ /* Hessian for Lame parameter lambda, mu and rho */ tmp_mu1_shot = (green_sxx[j][i][ishot] + greeni_sxx[j][i][ishot] * I); tmp_mu2_shot = (green_syy[j][i][ishot] + greeni_syy[j][i][ishot] * I); tmp_mu3_shot = (green_sxy[j][i][ishot] + greeni_sxy[j][i][ishot] * I); tmp_mu5_shot = omega*((green_vx[j+1][i][ishot] * I) - greeni_vx[j+1][i][ishot]); tmp_mu6_shot = omega*((green_vy[j+1][i][ishot] * I) - greeni_vy[j+1][i][ishot]); tmp_mu1 = green_sxx[j][i][irec] + greeni_sxx[j][i][irec] * I; tmp_mu2 = green_syy[j][i][irec] + greeni_syy[j][i][irec] * I; tmp_mu3 = green_sxy[j][i][irec] + greeni_sxy[j][i][irec] * I; if(INVMAT1==1){ muss = prho[j][i] * pu[j][i] * pu[j][i]; lamss = prho[j][i] * ppi[j][i] * ppi[j][i] - 2.0 * muss;} if(INVMAT1=3){ muss = pu[j][i]; lamss = ppi[j][i];} /*mulamratio = (muss * muss)/((lamss+muss)*(lamss+muss));*/ /*tmp_jac_lam = (1.0/(4.0 * (lamss+muss) * (lamss+muss))) * ((tmp_mu1_shot + tmp_mu2_shot) * (tmp_mu1_shot + tmp_mu2_shot));*/ tmp_jac_lam = (tmp_mu1_shot + tmp_mu2_shot) * (tmp_mu1 + tmp_mu2); tmp_jac_mu = ((1.0/(muss*muss))*(tmp_mu3_shot * tmp_mu3_shot)) + ((1.0/4.0) * ((tmp_mu1_shot + tmp_mu2_shot) * (tmp_mu1_shot + tmp_mu2_shot)) / ((lamss+muss)*(lamss+muss))) + ((1.0/4.0) * ((tmp_mu1_shot - tmp_mu2_shot) * (tmp_mu1_shot - tmp_mu2_shot)) / (muss*muss)); /*tmp_jac_mu = (tmp_mu3_shot * tmp_mu3) + (((mulamratio*((tmp_mu1_shot + tmp_mu2_shot) * (tmp_mu1 + tmp_mu2))) + ((tmp_mu1_shot - tmp_mu2_shot) * (tmp_mu1 - tmp_mu2)))/4.0);*/ tmp_jac_rho = (tmp_mu5_shot*tmp_mu5_shot) + (tmp_mu6_shot*tmp_mu6_shot); /* Assemble Hessian for lambda, mu and rho */ if(INVMAT1==3){ hessian[j][i] += HESS_SCALE * creal(tmp_jac_lam*abs_green[j][i]*conj(tmp_jac_lam)); hessian_u[j][i] += HESS_SCALE * creal(tmp_jac_mu*abs_green[j][i]*conj(tmp_jac_mu)); hessian_rho[j][i] += HESS_SCALE * creal(tmp_jac_rho*abs_green[j][i]*conj(tmp_jac_rho)); } /* Assemble Hessian for Vp, Vs and rho*/ if(INVMAT1==1){ tmp_jac_vp = 2.0 * ppi[j][i] * prho[j][i] * tmp_jac_lam; tmp_jac_vs = (- 4.0 * prho[j][i] * pu[j][i] * tmp_jac_lam) + (2.0 * prho[j][i] * pu[j][i] * tmp_jac_mu); tmp_jac_rho += (((ppi[j][i] * ppi[j][i])-(2.0 * pu[j][i] * pu[j][i])) * tmp_jac_lam) + (pu[j][i] * pu[j][i] * tmp_jac_mu); hessian[j][i] += HESS_SCALE * creal(tmp_jac_vp*abs_green[j][i]*conj(tmp_jac_vp)); hessian_u[j][i] += HESS_SCALE * creal(tmp_jac_vs*abs_green[j][i]*conj(tmp_jac_vs)); hessian_rho[j][i] += HESS_SCALE * creal(tmp_jac_rho*abs_green[j][i]*conj(tmp_jac_rho)); } } } } } /* save Hessian for Vp */ /* ----------------------- */ sprintf(jac,"%s_hessian.%i%i",JACOBIAN,POS[1],POS[2]); FP4=fopen(jac,"wb"); /* output of the gradient */ for (i=1;i<=NX;i=i+IDX){ for (j=1;j<=NY;j=j+IDY){ fwrite(&hessian[j][i],sizeof(float),1,FP4); } } fclose(FP4); MPI_Barrier(MPI_COMM_WORLD); /* merge gradient file */ sprintf(jac,"%s_hessian",JACOBIAN); if (MYID==0) mergemod(jac,3); /* save HESSIAN for mu */ /* ----------------------- */ sprintf(jac,"%s_hessian_u.%i%i",JACOBIAN,POS[1],POS[2]); FP4=fopen(jac,"wb"); /* output of the gradient */ for (i=1;i<=NX;i=i+IDX){ for (j=1;j<=NY;j=j+IDY){ fwrite(&hessian_u[j][i],sizeof(float),1,FP4); } } fclose(FP4); MPI_Barrier(MPI_COMM_WORLD); /* merge gradient file */ sprintf(jac,"%s_hessian_u",JACOBIAN); if (MYID==0) mergemod(jac,3); /* save HESSIAN for rho */ /* ----------------------- */ sprintf(jac,"%s_hessian_rho.%i%i",JACOBIAN,POS[1],POS[2]); FP4=fopen(jac,"wb"); /* output of the gradient */ for (i=1;i<=NX;i=i+IDX){ for (j=1;j<=NY;j=j+IDY){ fwrite(&hessian_rho[j][i],sizeof(float),1,FP4); } } fclose(FP4); MPI_Barrier(MPI_COMM_WORLD); /* merge gradient file */ sprintf(jac,"%s_hessian_rho",JACOBIAN); if (MYID==0) mergemod(jac,3); free_matrix(hessian,-nd+1,NY+nd,-nd+1,NX+nd); free_matrix(hessian_u,-nd+1,NY+nd,-nd+1,NX+nd); free_matrix(hessian_lam,-nd+1,NY+nd,-nd+1,NX+nd); free_matrix(hessian_mu,-nd+1,NY+nd,-nd+1,NX+nd); free_matrix(hessian_rho,-nd+1,NY+nd,-nd+1,NX+nd); }
void hessian(int nshots, int SHOTINC, float *** green_vy, float *** greeni_vy, float *** green_syy, float *** greeni_syy, float *** green_sxy, float *** greeni_sxy, float ** prho, float ** pu, int iter){ extern float DT,DH,TIME; extern float FC_HESSIAN; extern int NX, NY, IDX, IDY, DTINV, INVMAT1, MYID, POS[4], FDORDER; extern char JACOBIAN[STRING_SIZE]; /* local variables */ int i, j, k, l, ns_hess, ishot, irec, nd, NSRC_HESSIAN, NREC_HESSIAN, RECINC; double trig1,trig2; double t=0.0; const double pi=4.0*atan(1.0); char jac[STRING_SIZE]; float complex uttx, utty, exx, eyy, eyx, Gxx, Gyx, Gxy, Gyy, Gxxx, Gyxx, Gxyy, Gyyy, Gxyx, Gyyx; float complex tmp_jac_lam, tmp_jac_mu, tmp_jac_rho, tmp_jac_vp, tmp_jac_vs, tmp_fft_fsignal; float ** abs_green, omega, mulamratio, lamss, muss, HESS_SCALE; float ** hessian, ** hessian_u, ** hessian_rho, ** hessian_lam, ** hessian_mu; float hvxx, hvxxi, hvyy, hvyyi, hvxy, hvxyi, hvyx, hvyxi; float **exx_shot, **exxi_shot, **eyy_shot, **eyyi_shot, **eyx_shot, **eyxi_shot, **uttx_shot, **uttxi_shot, **utty_shot, **uttyi_shot; float *psource_hess=NULL, *Hess_for_real=NULL, *Hess_for_complex=NULL; FILE *FP4; HESS_SCALE = 1.0; RECINC = 1; NSRC_HESSIAN=1; NREC_HESSIAN=24; nd = FDORDER/2 + 1; abs_green = matrix(-nd+1,NY+nd,-nd+1,NX+nd); /* Diagonal elements of the Hessian*/ hessian_u = matrix(-nd+1,NY+nd,-nd+1,NX+nd); hessian_mu = matrix(-nd+1,NY+nd,-nd+1,NX+nd); hessian_rho = matrix(-nd+1,NY+nd,-nd+1,NX+nd); eyy_shot = matrix(-nd+1,NY+nd,-nd+1,NX+nd); eyyi_shot = matrix(-nd+1,NY+nd,-nd+1,NX+nd); eyx_shot = matrix(-nd+1,NY+nd,-nd+1,NX+nd); eyxi_shot = matrix(-nd+1,NY+nd,-nd+1,NX+nd); utty_shot = matrix(-nd+1,NY+nd,-nd+1,NX+nd); uttyi_shot = matrix(-nd+1,NY+nd,-nd+1,NX+nd); Hess_for_real = vector(1,1); Hess_for_complex = vector(1,1); for (i=1;i<=NX;i=i+IDX){ for (j=1;j<=NY;j=j+IDY){ hessian_u[j][i]=0.0; hessian_mu[j][i]=0.0; hessian_rho[j][i]=0.0; } } /* assemble Hessian */ /* ----------------------------------------------------------------- */ /* Circular frequency of the Hessian */ omega = 2.0*M_PI*FC_HESSIAN; /* calculate absolute values of impulse responses */ for (ishot=1;ishot<=nshots;ishot=ishot+SHOTINC){ for (i=1;i<=NX;i=i+IDX){ for (j=1;j<=NY;j=j+IDY){ /*green_x = green_vx[j][i][ishot] + greeni_vx[j][i][ishot] * I; green_y = green_vy[j][i][ishot] + greeni_vy[j][i][ishot] * I;*/ abs_green[j][i] = 1.0; } } } /*printf("omega = %e \n",omega); printf("NSRC = %d \n",NSRC_HESSIAN);*/ /*psource_hess=rd_sour(&ns_hess,fopen(SIGNAL_FILE,"r")); FFT_data(psource_hess,Hess_for_real,Hess_for_complex,NT); MPI_Barrier(MPI_COMM_WORLD); tmp_fft_fsignal = Hess_for_real[1] + Hess_for_complex[1] * I;*/ tmp_fft_fsignal = 1.0; for (ishot=1;ishot<=nshots;ishot=ishot+SHOTINC){ /* calculate spatial and temporal derivatives of the forward wavefield */ for (i=1;i<=NX;i=i+IDX){ for (j=1;j<=NY;j=j+IDY){ hvyy = (green_vy[j+1][i][ishot]-green_vy[j][i][ishot])/DH; hvyyi = (greeni_vy[j+1][i][ishot]-greeni_vy[j][i][ishot])/DH; hvyx = (green_vy[j][i+1][ishot]-green_vy[j][i][ishot])/DH; hvyxi = (greeni_vy[j][i+1][ishot]-greeni_vy[j][i][ishot])/DH; /* calculate strain tensors and integrate FD-wavefield */ eyy_shot[j][i] = hvyy; eyyi_shot[j][i] = hvyyi; eyxi_shot[j][i] = hvyxi; eyx_shot[j][i] = hvyx; utty_shot[j][i] = -hvyyi*omega; uttyi_shot[j][i] = hvyy*omega; } } for (irec=1;irec<=1;irec=irec+RECINC){ /* construct Hessian for different material parameters */ for (i=1;i<=NX;i=i+IDX){ for (j=1;j<=NY;j=j+IDY){ /* assemble complex wavefields */ utty = (utty_shot[j][i] + uttyi_shot[j][i] * I); eyy = (eyy_shot[j][i] + eyyi_shot[j][i] * I); eyx = (eyx_shot[j][i] + eyxi_shot[j][i] * I); if(INVMAT1==1){ muss = prho[j][i] * pu[j][i] * pu[j][i]; } if(INVMAT1=3){ muss = pu[j][i]; } /* Hessian */ tmp_jac_rho = (conj(utty)*utty); tmp_jac_mu = (conj(eyx)*abs_green[j][i]*eyx) + (conj(eyy)*abs_green[j][i]*eyy); /* calculate Hessian for lambda, mu and rho by autocorrelation of Frechet derivatives */ /*if(INVMAT1==3){*/ hessian_u[j][i] += HESS_SCALE * creal(tmp_jac_mu); hessian_rho[j][i] += HESS_SCALE * creal(tmp_jac_rho); /*}*/ /* Assemble Hessian for Vp, Vs and rho by autocorrelation of Frechet derivatives*/ /*if(INVMAT1==1){ tmp_jac_vp = 2.0 * ppi[j][i] * prho[j][i] * tmp_jac_lam; tmp_jac_vs = (- 4.0 * prho[j][i] * pu[j][i] * tmp_jac_lam) + (2.0 * prho[j][i] * pu[j][i] * tmp_jac_mu); tmp_jac_rho += (((ppi[j][i] * ppi[j][i])-(2.0 * pu[j][i] * pu[j][i])) * tmp_jac_lam) + (pu[j][i] * pu[j][i] * tmp_jac_mu); hessian[j][i] += HESS_SCALE * creal(tmp_jac_vp*conj(tmp_jac_vp)); hessian_u[j][i] += HESS_SCALE * creal(tmp_jac_vs*conj(tmp_jac_vs)); hessian_rho[j][i] += HESS_SCALE * creal(tmp_jac_rho*conj(tmp_jac_rho)); }*/ } } } } /* apply wavenumber damping for Vp-, Vs- and density Hessian */ /*if(SPATFILTER==1){ wavenumber(hessian_u); wavenumber(hessian_rho); }*/ /* save HESSIAN for mu */ /* ----------------------- */ sprintf(jac,"%s_hessian_u_%d.%i%i",JACOBIAN,iter,POS[1],POS[2]); FP4=fopen(jac,"wb"); /* output of the gradient */ for (i=1;i<=NX;i=i+IDX){ for (j=1;j<=NY;j=j+IDY){ fwrite(&hessian_u[j][i],sizeof(float),1,FP4); } } fclose(FP4); MPI_Barrier(MPI_COMM_WORLD); /* merge gradient file */ sprintf(jac,"%s_hessian_u_%d",JACOBIAN,iter); if (MYID==0) mergemod(jac,3); /* save HESSIAN for rho */ /* ----------------------- */ sprintf(jac,"%s_hessian_rho_%d.%i%i",JACOBIAN,iter,POS[1],POS[2]); FP4=fopen(jac,"wb"); /* output of the gradient */ for (i=1;i<=NX;i=i+IDX){ for (j=1;j<=NY;j=j+IDY){ fwrite(&hessian_rho[j][i],sizeof(float),1,FP4); } } fclose(FP4); MPI_Barrier(MPI_COMM_WORLD); /* merge gradient file */ sprintf(jac,"%s_hessian_rho_%d",JACOBIAN,iter); if (MYID==0) mergemod(jac,3); free_matrix(hessian_u,-nd+1,NY+nd,-nd+1,NX+nd); free_matrix(hessian_mu,-nd+1,NY+nd,-nd+1,NX+nd); free_matrix(hessian_rho,-nd+1,NY+nd,-nd+1,NX+nd); free_matrix(eyy_shot,-nd+1,NY+nd,-nd+1,NX+nd); free_matrix(eyx_shot,-nd+1,NY+nd,-nd+1,NX+nd); free_matrix(utty_shot,-nd+1,NY+nd,-nd+1,NX+nd); free_matrix(eyyi_shot,-nd+1,NY+nd,-nd+1,NX+nd); free_matrix(eyxi_shot,-nd+1,NY+nd,-nd+1,NX+nd); free_matrix(uttyi_shot,-nd+1,NY+nd,-nd+1,NX+nd); }
void gauss_filt(float ** waveconv) { /* extern variables */ extern float DH, WD_DAMP, FC_END, C_vs; extern int FREE_SURF, NX, NY, NXG, NYG, IDX, IDY; extern int NPROCX, NPROCY, MYID, POS[3]; extern char JACOBIAN[STRING_SIZE]; extern FILE *FP; extern int FILT_SIZE_GRAD; /* local variables */ int i, j, ii, jj; int i1, j1, filtsize, hfs; float **model_tmp, **kernel, ** model_gauss, grad, normgauss, smooth_meter; float lam, sigma, s, sum, conv; char jac_tmp[STRING_SIZE]; FILE *model, *FP1; char modfile[STRING_SIZE]; /* temporarily save gradient for Gaussian filtering */ sprintf(jac_tmp,"%s_gauss.old.%i%i",JACOBIAN,POS[1],POS[2]); FP1=fopen(jac_tmp,"wb"); for (i=1;i<=NX;i=i+IDX){ for (j=1;j<=NY;j=j+IDY){ fwrite(&waveconv[j][i],sizeof(float),1,FP1); } } fclose(FP1); MPI_Barrier(MPI_COMM_WORLD); /* merge gradient file */ sprintf(jac_tmp,"%s_gauss.old",JACOBIAN); if (MYID==0) mergemod(jac_tmp,3); if(MYID==0){ lam = C_vs / FC_END; /* define filter size as fraction of reference velocity wavelength */ FILT_SIZE_GRAD = round((WD_DAMP * lam)/DH); if (FILT_SIZE_GRAD==0) return; if (!(FILT_SIZE_GRAD % 2)) { if (FILT_SIZE_GRAD > 0) FILT_SIZE_GRAD += 1; else FILT_SIZE_GRAD -= 1; } hfs = abs(FILT_SIZE_GRAD)/2; sigma = hfs/2; s = 2.0 * sigma * sigma; printf("\n hfs: %d \n",hfs); model_tmp = matrix(-hfs+1,NYG+hfs,-hfs+1,NXG+hfs); model_gauss = matrix(-hfs+1,NYG+hfs,-hfs+1,NXG+hfs); kernel = matrix(1,abs(FILT_SIZE_GRAD),1,abs(FILT_SIZE_GRAD)); sprintf(jac_tmp,"%s_gauss.old",JACOBIAN); model=fopen(jac_tmp,"rb"); if (model==NULL) err(" Could not open gradient file !"); /* load merged model */ for (i=1;i<=NXG;i++){ for (j=1;j<=NYG;j++){ fread(&grad, sizeof(float), 1, model); model_tmp[j][i]=grad; } } fclose(model); /* apply 2D-Gaussian filter on vp and vs model */ /* extrapolate array */ /* left/right boundary */ for (j=1;j<=NYG;j++){ for (i=-hfs+1;i<=0;i++){ model_tmp[j][i] = model_tmp[j][1]; } for (i=NXG+1;i<=NXG+hfs;i++){ model_tmp[j][i] = model_tmp[j][NXG]; } } /* top/bottom boundary incl. corners */ for (j=-hfs+1;j<=0;j++){ for (i=-hfs+1;i<=NXG+hfs;i++){ model_tmp[j][i] = model_tmp[1][i]; } } for (j=NYG+1;j<=NYG+hfs;j++){ for (i=-hfs+1;i<=NXG+hfs;i++){ model_tmp[j][i] = model_tmp[NYG][i]; } } /* create filter kernel */ for (ii=-hfs;ii<=hfs;ii++){ for (jj=-hfs;jj<=hfs;jj++){ kernel[jj+hfs+1][ii+hfs+1] = exp(-((ii*ii)/s) - ((jj*jj)/s)); sum += kernel[jj+hfs+1][ii+hfs+1]; } } /* normalize kernel */ for (i=1;i<=FILT_SIZE_GRAD;i++){ for (j=1;j<=FILT_SIZE_GRAD;j++){ kernel[j][i] /= sum; } } /* apply Gaussian filter to gradient */ for (j=1;j<=NYG;j++){ for (i=1;i<=NXG;i++){ conv = 0.0; /* loop over kernel*/ for (ii=-hfs;ii<=hfs;ii++){ for (jj=-hfs;jj<=hfs;jj++){ conv += model_tmp[j+jj][i+ii] * kernel[jj+hfs+1][ii+hfs+1]; } } /* output of filtered gradient */ model_gauss[j][i] = conv; } } /* output of smoothed gradients */ sprintf(jac_tmp,"%s_gauss.old",JACOBIAN); model=fopen(jac_tmp,"wb"); for (i=1;i<=NXG;i++){ for (j=1;j<=NYG;j++){ fwrite(&model_gauss[j][i],sizeof(float),1,model); } } fclose(model); free_matrix(model_tmp,-hfs+1,NYG+hfs,-hfs+1,NXG+hfs); free_matrix(model_gauss,-hfs+1,NYG+hfs,-hfs+1,NXG+hfs); free_matrix(kernel,1,abs(FILT_SIZE_GRAD),1,abs(FILT_SIZE_GRAD)); } /* end of if(MYID==0)*/ MPI_Barrier(MPI_COMM_WORLD); smooth_meter=FILT_SIZE_GRAD*DH; if(MYID==0){printf("\n \t ---- Gradient is smoothed with Gaussian (filter length of %d gridpoints which is equivalent to %4.2f meter) \n",FILT_SIZE_GRAD,smooth_meter);} /* distribute smoothed jacobian on computational nodes */ sprintf(jac_tmp,"%s_gauss.old",JACOBIAN); model=fopen(jac_tmp,"rb"); if (model==NULL) err(" Could not open gradient file ! (distribute smoothed gradient)"); for (i=1;i<=NXG;i++){ for (j=1;j<=NYG;j++){ fread(&grad, sizeof(float), 1, model); if ((POS[1]==((i-1)/NX)) && (POS[2]==((j-1)/NY))){ ii=i-POS[1]*NX; jj=j-POS[2]*NY; waveconv[jj][ii]=grad; } } } fclose(model); if(MYID==0){printf("\n \t ---- Smoothed gradient is distributed on computational nodes ... ---- \n");} /* clean up temporary files*/ MPI_Barrier(MPI_COMM_WORLD); sprintf(jac_tmp,"%s_gauss.old.%i%i",JACOBIAN,POS[1],POS[2]); remove(jac_tmp); }
void model_elastic(float ** rho, float ** pi, float ** u){ /*--------------------------------------------------------------------------*/ /* extern variables */ extern float DH; extern int NX, NY, NXG, NYG, POS[3], L, MYID; extern char MFILE[STRING_SIZE]; extern char INV_MODELFILE[STRING_SIZE]; /* local variables */ float vp, vs, rhov, y; int i, j, ii, jj; /* parameters for layer 1 */ const float vp1=680.0, vs1=320.0, rho1=1700.0, h=3.0; /* parameters for layer 2 */ const float vp2=1000.0, vs2=590.0, rho2=2000.0; char modfile[STRING_SIZE]; /*-----------------------------------------------------------------------*/ /* loop over global grid */ for (i=1;i<=NXG;i++){ for (j=1;j<=NYG;j++){ /* calculate coordinate in m */ y=(float)j*DH; /* two layer case */ if (y<=h){ vp=vp1; vs=vs1; rhov=rho1; } else{ vp=vp2; vs=vs2; rhov=rho2; } /*muv=vs1*vs1*rho1; piv=vp1*vp1*rho1; */ /* only the PE which belongs to the current global gridpoint is saving model parameters in his local arrays */ if ((POS[1]==((i-1)/NX)) && (POS[2]==((j-1)/NY))){ ii=i-POS[1]*NX; jj=j-POS[2]*NY; u[jj][ii]=vs; rho[jj][ii]=rhov; pi[jj][ii]=vp; } } } sprintf(modfile,"%s_rho_it_0.bin",INV_MODELFILE); writemod(modfile,rho,3); MPI_Barrier(MPI_COMM_WORLD); if (MYID==0) mergemod(modfile,3); sprintf(modfile,"%s_vs_it_0.bin",INV_MODELFILE); writemod(modfile,u,3); MPI_Barrier(MPI_COMM_WORLD); if (MYID==0) mergemod(modfile,3); sprintf(modfile,"%s_vp_it_0.bin",INV_MODELFILE); writemod(modfile,pi,3); MPI_Barrier(MPI_COMM_WORLD); if (MYID==0) mergemod(modfile,3); }
void hessian_out(float ** hessian_lam, float ** hessian_mu, float ** hessian_rho, float ** ppi, float ** pu, float ** prho) { extern int NX, NY, IDX, IDY, DTINV, INVMAT1, MYID, POS[4], FDORDER, SPATFILTER; extern char JACOBIAN[STRING_SIZE]; /* local variables */ int i, j, k, l, ns_hess, ishot, irec, nd, NSRC_HESSIAN, NREC_HESSIAN, RECINC; char jac[STRING_SIZE]; float lamss, muss; float ** hessian_vp, ** hessian_vs, ** hessian_rhos; FILE *FP4; nd = FDORDER/2 + 1; /* Diagonal elements of the Hessian*/ hessian_vp = matrix(-nd+1,NY+nd,-nd+1,NX+nd); hessian_vs = matrix(-nd+1,NY+nd,-nd+1,NX+nd); hessian_rhos = matrix(-nd+1,NY+nd,-nd+1,NX+nd); for (i=1; i<=NX; i=i+IDX) { for (j=1; j<=NY; j=j+IDY) { hessian_vp[j][i]=0.0; hessian_vs[j][i]=0.0; hessian_rhos[j][i]=0.0; } } /* construct Hessian for different material parameters */ for (i=1; i<=NX; i=i+IDX) { for (j=1; j<=NY; j=j+IDY) { if(INVMAT1==1) { muss = prho[j][i] * pu[j][i] * pu[j][i]; lamss = prho[j][i] * ppi[j][i] * ppi[j][i] - 2.0 * muss; } if(INVMAT1==3) { muss = pu[j][i]; lamss = ppi[j][i]; } /* new Pseudo-Hessian with improved correction of the geometrical spreading */ hessian_lam[j][i] = (1.0/(4.0 * (lamss+muss) * (lamss+muss))) * hessian_lam[j][i]; hessian_vp[j][i] = 2.0 * ppi[j][i] * prho[j][i] * hessian_lam[j][i]; hessian_vs[j][i] = (- 4.0 * prho[j][i] * pu[j][i] * hessian_lam[j][i]) + 2.0 * prho[j][i] * pu[j][i] * hessian_mu[j][i]; hessian_rhos[j][i]= ((((ppi[j][i] * ppi[j][i])-(2.0 * pu[j][i] * pu[j][i])) * hessian_lam[j][i]) + (pu[j][i] * pu[j][i] *hessian_mu[j][i]) + hessian_rho[j][i]); } } /* apply wavenumber damping for Vp-, Vs- and density Hessian */ /*if(SPATFILTER==1){ wavenumber(hessian); wavenumber(hessian_u); wavenumber(hessian_rho); }*/ /* save Hessian for Vp */ /* ----------------------- */ sprintf(jac,"%s_hessian.%i%i",JACOBIAN,POS[1],POS[2]); FP4=fopen(jac,"wb"); /* output of the gradient */ for (i=1; i<=NX; i=i+IDX) { for (j=1; j<=NY; j=j+IDY) { fwrite(&hessian_vp[j][i],sizeof(float),1,FP4); } } fclose(FP4); MPI_Barrier(MPI_COMM_WORLD); /* merge gradient file */ sprintf(jac,"%s_hessian",JACOBIAN); if (MYID==0) mergemod(jac,3); /* save HESSIAN for mu */ /* ----------------------- */ sprintf(jac,"%s_hessian_u.%i%i",JACOBIAN,POS[1],POS[2]); FP4=fopen(jac,"wb"); /* output of the gradient */ for (i=1; i<=NX; i=i+IDX) { for (j=1; j<=NY; j=j+IDY) { fwrite(&hessian_vs[j][i],sizeof(float),1,FP4); } } fclose(FP4); MPI_Barrier(MPI_COMM_WORLD); /* merge gradient file */ sprintf(jac,"%s_hessian_u",JACOBIAN); if (MYID==0) mergemod(jac,3); /* save HESSIAN for rho */ /* ----------------------- */ sprintf(jac,"%s_hessian_rho.%i%i",JACOBIAN,POS[1],POS[2]); FP4=fopen(jac,"wb"); /* output of the gradient */ for (i=1; i<=NX; i=i+IDX) { for (j=1; j<=NY; j=j+IDY) { fwrite(&hessian_rhos[j][i],sizeof(float),1,FP4); } } fclose(FP4); MPI_Barrier(MPI_COMM_WORLD); /* merge gradient file */ sprintf(jac,"%s_hessian_rho",JACOBIAN); if (MYID==0) mergemod(jac,3); free_matrix(hessian_vp,-nd+1,NY+nd,-nd+1,NX+nd); free_matrix(hessian_vs,-nd+1,NY+nd,-nd+1,NX+nd); free_matrix(hessian_rhos,-nd+1,NY+nd,-nd+1,NX+nd); }
void smooth2(float ** grad){ /* declaration of extern variables */ extern int NX, NY, NXG, NYG, IDX, IDY, GRADT2; extern int NPROCX, NPROCY, MYID, POS[3]; extern int SPAT_FILT_SIZE; extern float WD_DAMP, WD_DAMP1; extern char JACOBIAN[STRING_SIZE]; /* declaration of local variables */ int i,j, h, fa, fb, itr, ix, iz, n1,n2; int tracl1, jj, ii, nmax, * win; float gradtmp, ** v, r1, r2, **w, *d, *e, *f, rw; char jac[STRING_SIZE]; FILE *fp_grad, *FP3; /* define parameters */ r1=WD_DAMP; r2=WD_DAMP1; n1=NYG; n2=NXG; /* scale the smoothing parameter */ r1 = r1*r1*0.25; r2 = r2*r2*0.25; /* allocate space */ nmax = (n1<n2)?n2:n1; win = ivector(0,4); w = matrix(0,n2,0,n1); d = vector(0,nmax); e = vector(0,nmax); f = vector(0,nmax); /* define windows function */ win[0] = GRADT2; win[1] = n1; win[2] = 0; win[3] = n2; rw=0.; rw=rw*rw*0.25; /* temporarily save gradient for wavenumber filtering */ sprintf(jac,"%s_wavenumber.old.%i%i",JACOBIAN,POS[1],POS[2]); FP3=fopen(jac,"wb"); for (i=1;i<=NX;i=i+IDX){ for (j=1;j<=NY;j=j+IDY){ fwrite(&grad[j][i],sizeof(float),1,FP3); } } fclose(FP3); MPI_Barrier(MPI_COMM_WORLD); /* merge gradient file */ sprintf(jac,"%s_wavenumber.old",JACOBIAN); if (MYID==0) mergemod(jac,3); if(MYID==0){ /* read the global model on node 0 and apply wavenumber damping */ /* define temporary gradient matrix */ v = matrix(0,n2,0,n1); printf("\n Smooth2 is applied to gradient (written by PE %d)\n",MYID); fp_grad=fopen(jac,"rb"); if (fp_grad==NULL) err(" Could not open gradient file ! "); /* load merged gradient */ for (i=1;i<=n2;i++){ for (j=1;j<=n1;j++){ fread(&gradtmp, sizeof(float), 1, fp_grad); v[i][j] = gradtmp; } } fclose(fp_grad); /* define the window function */ for(ix=0; ix<n2; ++ix) for(iz=0; iz<n1; ++iz) w[ix][iz] = 0; for(ix=win[2]; ix<win[3]; ++ix) for(iz=win[0]; iz<win[1]; ++iz) w[ix][iz] = 1; if(win[0]>0 || win[1]<n1 || win[2]>0 || win[3]<n2){ /* smooth the window function */ for(iz=0; iz<n1; ++iz){ for(ix=0; ix<n2; ++ix){ d[ix] = 1.0+2.0*rw; e[ix] = -rw; f[ix] = w[ix][iz]; } d[0] -= rw; d[n2-1] -= rw; tripd(d,e,f,n2); for(ix=0; ix<n2; ++ix) w[ix][iz] = f[ix]; } for(ix=0; ix<n2; ++ix){ for(iz=0; iz<n1; ++iz){ d[iz] = 1.0+2.0*rw; e[iz] = -rw; f[iz] = w[ix][iz]; } d[0] -= rw; d[n1-1] -= rw; tripd(d,e,f,n1); for(iz=0; iz<n1; ++iz) w[ix][iz] = f[iz]; } } /* solving for the smoothing velocity */ for(iz=0; iz<n1; ++iz){ for(ix=0; ix<n2-1; ++ix){ d[ix] = 1.0+r2*(w[ix][iz]+w[ix+1][iz]); e[ix] = -r2*w[ix+1][iz]; f[ix] = v[ix][iz]; } d[0] -= r2*w[0][iz]; d[n2-1] = 1.0+r2*w[n2-1][iz]; f[n2-1] = v[n2-1][iz]; tripd(d,e,f,n2); for(ix=0; ix<n2; ++ix) v[ix][iz] = f[ix]; } for(ix=0; ix<n2; ++ix){ for(iz=0; iz<n1-2; ++iz){ d[iz] = 1.0+r1*(w[ix][iz+1]+w[ix][iz+2]); e[iz] = -r1*w[ix][iz+2]; f[iz] = v[ix][iz+1]; } f[0] += r1*w[ix][1]*v[ix][0]; d[n1-2] = 1.0+r1*w[ix][n1-1]; f[n1-2] = v[ix][n1-1]; tripd(d,e,f,n1-1); for(iz=0; iz<n1-1; ++iz) v[ix][iz+1] = f[iz]; } /* write damped gradient to temporary file */ sprintf(jac,"%s_smooth2.old",JACOBIAN); FP3=fopen(jac,"wb"); for (i=1;i<=n2;i++){ for (j=1;j<=n1;j++){ gradtmp = v[i][j]; fwrite(&gradtmp,sizeof(float),1,FP3); } } fclose(FP3); /* free memory */ free_matrix(v,0,n2,0,n1); } /* end of if MYID==0*/ MPI_Barrier(MPI_COMM_WORLD); sprintf(jac,"%s_smooth2.old",JACOBIAN); FP3=fopen(jac,"rb"); /* distribute spatial filtered gradient on computational nodes */ for (i=1;i<=NXG;i++){ for (j=1;j<=NYG;j++){ fread(&gradtmp, sizeof(float),1,FP3); if ((POS[1]==((i-1)/NX)) && (POS[2]==((j-1)/NY))){ ii=i-POS[1]*NX; jj=j-POS[2]*NY; grad[jj][ii]=gradtmp; } } } fclose(FP3); /* clean up temporary files*/ MPI_Barrier(MPI_COMM_WORLD); sprintf(jac,"%s_wavenumber.old.%i%i",JACOBIAN,POS[1],POS[2]); remove(jac); }
void taper_grad(float ** waveconv,float ** taper_coeff, float **srcpos, int nshots, int **recpos, int ntr, int sws) { /* extern variables */ extern float DH; extern int FREE_SURF, NX, NY, NXG, NYG; extern int NPROCX, NPROCY, MYID, POS[3]; extern FILE *FP; /* local variables */ int i, j, h, ifw, ii, jj, n, xb, yb, xe, ye, taperlength,taperlength2, VTON, SRTON; int ijc, iy, ix, iii, jjj, xx, yy, srctaper_gridpt, i1, j1; extern int GRADT1, GRADT2, GRADT3, GRADT4; float amp, a, *window, grad_tap, **waveconvtmp; char modfile[STRING_SIZE]; extern float SRTRADIUS; extern int SRTSHAPE, FILTSIZE; float **m, **edgemat, **mm, **msum, minm, maxm, x, y, rad, **taper_coeff_glob; float maxrad; float EXP_TAPER_GRAD_HOR; FILE *fp_taper; /*SRTSHAPE=2; SRTRADIUS=25.0; filtsize=2;*/ EXP_TAPER_GRAD_HOR = 2.0; /* TAPER TEST */ /* =============== */ /* Vertical taper */ /* =============== */ if(sws==1){ /* define taper geometry */ taperlength=GRADT2-GRADT1; taperlength2=GRADT4-GRADT3; ifw = GRADT4-GRADT1; /*printf("%d \t %d \t %d \t %d \n",GRADT1, GRADT2, GRADT3, GRADT4); printf("%d \t %d \t %d \n",taperlength, taperlength2,ifw);*/ if (MYID==0) { fprintf(FP,"\n **Message from taper_grad (printed by PE %d):\n",MYID); fprintf(FP," Coefficients for gradient taper are now calculated.\n"); } waveconvtmp = matrix(0,NY+1,0,NX+1); window=vector(1,ifw); /* Gaussian window */ a=3; /* damping coefficient */ for (i=1;i<=ifw;i++){ window[i] = 1.0; if(i<=taperlength){ window[i] = exp(-(1.0/2.0)*(a*(i-taperlength)/(taperlength/2.0))*(a*(i-taperlength)/(taperlength/2.0))); } if(i>=(ifw-taperlength2)){ window[i] = exp(-(1.0/2.0)*(a*(i-(ifw-taperlength2))/(taperlength2/2.0))*(a*(i-(ifw-taperlength2))/(taperlength2/2.0))); } } /* loop over global grid */ for (j=1;j<=NYG;j++){ h=1; for (i=1;i<=NXG;i++){ grad_tap=0.0; if((i>GRADT1)&&(i<GRADT4)){ grad_tap=window[h]; h++; } if ((POS[1]==((i-1)/NX)) && (POS[2]==((j-1)/NY))){ ii=i-POS[1]*NX; jj=j-POS[2]*NY; taper_coeff[jj][ii]=grad_tap; } } } /* apply taper on local gradient */ for (j=1;j<=NY;j++){ for (i=1;i<=NX;i++){ waveconv[j][i]*=taper_coeff[j][i]; waveconvtmp[j][i] = waveconv[j][i]; } } /* apply filter at shot and receiver points */ for (n=1;n<=nshots;n++) { i = iround(srcpos[1][n]/DH); j = iround(srcpos[2][n]/DH); if ((POS[1]==((i-1)/NX)) && (POS[2]==((j-1)/NY))){ ii = i-POS[1]*NX; jj = j-POS[2]*NY; /*waveconvtmp[jj][ii] = 1*waveconv[jj][ii] + 8*(waveconv[jj-1][ii] + waveconv[jj+1][ii] + waveconv[jj][ii-1] + waveconv[jj][ii+1]) + 4*(waveconv[jj-1][ii-1] + waveconv[jj-1][ii+1] + waveconv[jj+1][ii+1] + waveconv[jj+1][ii-1]); waveconvtmp[jj][ii] = waveconvtmp[jj][ii]/49;*/ waveconvtmp[jj][ii] = 0.0; } } for (j=1;j<=NY;j++){ for (i=1;i<=NX;i++){ waveconv[j][i] = waveconvtmp[j][i]; } } for (n=1;n<=ntr;n++) { i = recpos[1][n]; j = recpos[2][n]; if ((POS[1]==((i-1)/NX)) && (POS[2]==((j-1)/NY))){ ii = i-POS[1]*NX; jj = j-POS[2]*NY; /*waveconvtmp[jj][ii] = 1*waveconv[jj][ii] + 8*(waveconv[jj-1][ii] + waveconv[jj+1][ii] + waveconv[jj][ii-1] + waveconv[jj][ii+1]) + 4*(waveconv[jj-1][ii-1] + waveconv[jj-1][ii+1] + waveconv[jj+1][ii+1] + waveconv[jj+1][ii-1]); waveconvtmp[jj][ii] = waveconvtmp[jj][ii]/49;*/ waveconvtmp[jj][ii] = 0.0; } } for (j=1;j<=NY;j++){ for (i=1;i<=NX;i++){ waveconv[j][i] = waveconvtmp[j][i]; } } sprintf(modfile,"taper_coeff_vert.bin"); writemod(modfile,taper_coeff,3); MPI_Barrier(MPI_COMM_WORLD); if (MYID==0) mergemod(modfile,3); free_vector(window,1,ifw); free_matrix(waveconvtmp,0,NX+1,0,NY+1); } /* ======================== */ /* Horizontal Taper */ /* ======================== */ if(sws==2){ /* define taper geometry */ taperlength=GRADT2-GRADT1; taperlength2=GRADT4-GRADT3; ifw = GRADT2-GRADT1+1; printf("%d \t %d \t %d \t %d \n",GRADT1, GRADT2, GRADT3, GRADT4); printf("%d \t %d \t %d \n",taperlength, taperlength2,ifw); if (MYID==0) { fprintf(FP,"\n **Message from taper_grid (printed by PE %d):\n",MYID); fprintf(FP," Coefficients for gradient taper are now calculated.\n"); } waveconvtmp = matrix(0,NY+1,0,NX+1); window=vector(1,ifw); /* Gaussian window */ a=3; /* damping coefficient */ for (i=1;i<=ifw;i++){ window[i] = 1.0; if(i<=taperlength){ window[i] = exp(-(1.0/2.0)*(a*(i-taperlength)/(taperlength/2.0))*(a*(i-taperlength)/(taperlength/2.0))); } } /* loop over global grid */ h=1; for (j=1;j<=NYG;j++){ for (i=1;i<=NXG;i++){ grad_tap=0.0; if((j>=GRADT1)&&(j<=GRADT2)){ grad_tap=window[h]; } if(j>GRADT2){ /*grad_tap=((float)(j*DH))*((float)(j*DH))*((float)(j*DH));*/ /*grad_tap=((float)(j*DH))*((float)(j*DH));*/ /*grad_tap=(float)(j*DH);*/ /*grad_tap=((float)((j*DH)/(GRADT2*DH)));*/ /*grad_tap=1.0;*/ grad_tap=pow((float)(j*DH),EXP_TAPER_GRAD_HOR); } /*grad_tap=((float)(j*DH));*/ if ((POS[1]==((i-1)/NX)) && (POS[2]==((j-1)/NY))){ ii=i-POS[1]*NX; jj=j-POS[2]*NY; taper_coeff[jj][ii]=grad_tap; } } if(j>=GRADT1){h++;} } /* apply taper on local gradient */ for (j=1;j<=NY;j++){ for (i=1;i<=NX;i++){ waveconv[j][i]*=taper_coeff[j][i]; waveconvtmp[j][i] = waveconv[j][i]; } } /* apply filter at shot and receiver points */ /*for (n=1;n<=nshots;n++) { i = iround(srcpos[1][n]/DH); j = iround(srcpos[2][n]/DH); if ((POS[1]==((i-1)/NX)) && (POS[2]==((j-1)/NY))){ ii = i-POS[1]*NX; jj = j-POS[2]*NY; waveconvtmp[jj][ii] = 1*waveconv[jj][ii] + 8*(waveconv[jj-1][ii] + waveconv[jj+1][ii] + waveconv[jj][ii-1] + waveconv[jj][ii+1]) + 4*(waveconv[jj-1][ii-1] + waveconv[jj-1][ii+1] + waveconv[jj+1][ii+1] + waveconv[jj+1][ii-1]); waveconvtmp[jj][ii] = waveconvtmp[jj][ii]/49; } } for (j=1;j<=NY;j++){ for (i=1;i<=NX;i++){ waveconv[j][i] = waveconvtmp[j][i]; } } for (n=1;n<=ntr;n++) { i = recpos[1][n]; j = recpos[2][n]; if ((POS[1]==((i-1)/NX)) && (POS[2]==((j-1)/NY))){ ii = i-POS[1]*NX; jj = j-POS[2]*NY; waveconvtmp[jj][ii] = 1*waveconv[jj][ii] + 8*(waveconv[jj-1][ii] + waveconv[jj+1][ii] + waveconv[jj][ii-1] + waveconv[jj][ii+1]) + 4*(waveconv[jj-1][ii-1] + waveconv[jj-1][ii+1] + waveconv[jj+1][ii+1] + waveconv[jj+1][ii-1]); waveconvtmp[jj][ii] = waveconvtmp[jj][ii]/49; } } for (j=1;j<=NY;j++){ for (i=1;i<=NX;i++){ waveconv[j][i] = waveconvtmp[j][i]; } }*/ sprintf(modfile,"taper_coeff_hor.bin"); writemod(modfile,taper_coeff,3); MPI_Barrier(MPI_COMM_WORLD); if (MYID==0) mergemod(modfile,3); free_vector(window,1,ifw); free_matrix(waveconvtmp,0,NX+1,0,NY+1); } /* end of sws==2 */ /* =================================== */ /* taper source and receiver positions */ /* =================================== */ if(sws==3) { /* Convert from meters to gridpoints -> minimum 5x5 gridpoints */ srctaper_gridpt = (int)(ceil(2.0*SRTRADIUS/DH)); if (srctaper_gridpt<5) srctaper_gridpt = 5; m = matrix(1,srctaper_gridpt,1,srctaper_gridpt); edgemat = matrix(1,4,1,1); mm = matrix(1,NYG,1,NXG); msum = matrix(1,NYG,1,NXG); taper_coeff_glob= matrix(1,NYG,1,NXG); waveconvtmp = matrix(0,NY+1,0,NX+1); for (iy=1;iy<=NYG;iy++) for (ix=1;ix<=NXG;ix++) msum[iy][ix] = 1.0; MPI_Barrier(MPI_COMM_WORLD); /*****************************/ /* Taper at source positions */ /*****************************/ a = 1.0; maxrad = sqrt(2.0*SRTRADIUS*SRTRADIUS); for (j=1;j<=srctaper_gridpt;j++) { for (i=1;i<=srctaper_gridpt;i++) { x = ((float)i-((float)srctaper_gridpt)/2.0-0.5)*DH; y = ((float)j-((float)srctaper_gridpt)/2.0-0.5)*DH; rad = sqrt(x*x+y*y); switch (SRTSHAPE) { case 1: m[j][i] = erf(a*rad/maxrad); break; case 2: if (rad>0) m[j][i] = log(rad); else m[j][i] = 0.0; break; } } } /* generate local taper matrix */ minm = minimum_m(m,srctaper_gridpt,srctaper_gridpt); for (j=1;j<=srctaper_gridpt;j++) for (i=1;i<=srctaper_gridpt;i++) m[j][i] -= minm; /* normalize taper matrix to max of values at the centre of all 4 taper area edges, */ /* not the global maximum, which is located at the corners */ edgemat[1][1] = m[1][srctaper_gridpt/2]; edgemat[2][1] = m[srctaper_gridpt/2][1]; edgemat[3][1] = m[srctaper_gridpt/2][srctaper_gridpt]; edgemat[4][1] = m[srctaper_gridpt][srctaper_gridpt/2]; maxm = maximum_m(edgemat,1,4); for (j=1;j<=srctaper_gridpt;j++) for (i=1;i<=srctaper_gridpt;i++) { m[j][i] /= maxm; if (m[j][i]>1.0) m[j][i] = 1.0; } /* get central position within the taper */ ijc = (int)(ceil((float)srctaper_gridpt/2)); /*********************/ /* loop over sources */ for (n=1;n<=nshots;n++) { for (iy=1;iy<=NYG;iy++) for (ix=1;ix<=NXG;ix++) mm[iy][ix] = 1.0; i = iround(srcpos[1][n]/DH); j = iround(srcpos[2][n]/DH); for (iy=1;iy<=srctaper_gridpt;iy++) { for (ix=1;ix<=srctaper_gridpt;ix++) { xx = i + ix - ijc; yy = j + iy - ijc; if ((xx<1) || (xx>NXG) || (yy<1) || (yy>NYG)) continue; mm[yy][xx] = m[iy][ix]; } } /* for (iy=1;iy<=NYG;iy++) for (ix=1;ix<=NXG;ix++) msum[iy][ix] += mm[iy][ix]; */ for (iy=1;iy<=NYG;iy++) for (ix=1;ix<=NXG;ix++) if (msum[iy][ix] > mm[iy][ix]) msum[iy][ix] = mm[iy][ix]; } /***********************/ /* loop over receivers */ /*for (n=1;n<=ntr;n++) { for (iy=1;iy<=NYG;iy++) for (ix=1;ix<=NXG;ix++) mm[iy][ix] = 1.0; i = recpos[1][n]; j = recpos[2][n]; for (iy=1;iy<=srctaper_gridpt;iy++) { for (ix=1;ix<=srctaper_gridpt;ix++) { xx = i + ix - ijc; yy = j + iy - ijc; if ((xx<1) || (xx>NXG) || (yy<1) || (yy>NYG)) continue; mm[yy][xx] = m[iy][ix]; } }*/ /* for (iy=1;iy<=NYG;iy++) Die kommenden zwei Zeilen wurden von Daniel auskommentiert. for (ix=1;ix<=NXG;ix++) msum[iy][ix] += mm[iy][ix]; */ /* for (iy=1;iy<=NYG;iy++) for (ix=1;ix<=NXG;ix++) if (msum[iy][ix] > mm[iy][ix]) msum[iy][ix] = mm[iy][ix]; }*/ minm = minimum_m(msum,NXG,NYG); for (iy=1;iy<=NYG;iy++) for (ix=1;ix<=NXG;ix++) msum[iy][ix] -= minm; maxm = maximum_m(msum,NXG,NYG); for (iy=1;iy<=NYG;iy++) for (ix=1;ix<=NXG;ix++) { taper_coeff_glob[iy][ix] = msum[iy][ix]/maxm; if ((POS[1]==((ix-1)/NX)) && (POS[2]==((iy-1)/NY))){ ii = ix-POS[1]*NX; jj = iy-POS[2]*NY; /*Diese Zeile wurde von Daniel auskommentiert: taper_coeff[jj][ii] = taper_coeff_glob[iy][ix] * ((float)(iy*DH));*/ /*taper_coeff[jj][ii] = ((float)(iy*DH)) * ((float)(iy*DH)) * ((float)(iy*DH));*/ taper_coeff[jj][ii]=msum[iy][ix]/maxm; } } /* apply taper on local gradient */ for (j=1;j<=NY;j++){ for (i=1;i<=NX;i++){ waveconv[j][i]*=taper_coeff[j][i]; waveconvtmp[j][i] = waveconv[j][i]; } } /* apply filter at shot and receiver points */ for (n=1;n<=nshots;n++) { i1 = iround(srcpos[1][n]/DH); j1 = iround(srcpos[2][n]/DH); for (i=i1-FILTSIZE;i<=i1+FILTSIZE;i++){ for (j=j1-FILTSIZE;j<=j1+FILTSIZE;j++){ if ((POS[1]==((i-1)/NX)) && (POS[2]==((j-1)/NY))){ ii = i-POS[1]*NX; jj = j-POS[2]*NY; /*waveconvtmp[jj][ii] = 1*waveconv[jj][ii] + 8*(waveconv[jj-1][ii] + waveconv[jj+1][ii] + waveconv[jj][ii-1] + waveconv[jj][ii+1]) + 4*(waveconv[jj-1][ii-1] + waveconv[jj-1][ii+1] + waveconv[jj+1][ii+1] + waveconv[jj+1][ii-1]); waveconvtmp[jj][ii] = waveconvtmp[jj][ii]/49;*/ if (jj>0){ waveconvtmp[jj][ii] = 0.0; taper_coeff[jj][ii] = 0.0; } } } } } /*for (n=1;n<=ntr;n++) { i1 = recpos[1][n]; j1 = recpos[2][n]; for (i=i1-FILTSIZE;i<=i1+FILTSIZE;i++){ for (j=j1-FILTSIZE;j<=j1+FILTSIZE;j++){ if ((POS[1]==((i-1)/NX)) && (POS[2]==((j-1)/NY))){ ii = i-POS[1]*NX; jj = j-POS[2]*NY; */ /* Die kommenden 4 Zeilen wurden von Daniel auskommentiert. waveconvtmp[jj][ii] = 1*waveconv[jj][ii] + 8*(waveconv[jj-1][ii] + waveconv[jj+1][ii] + waveconv[jj][ii-1] + waveconv[jj][ii+1]) + 4*(waveconv[jj-1][ii-1] + waveconv[jj-1][ii+1] + waveconv[jj+1][ii+1] + waveconv[jj+1][ii-1]); waveconvtmp[jj][ii] = waveconvtmp[jj][ii]/49;*/ /* waveconvtmp[jj][ii] = 0.0; } } } }*/ /* apply taper on local gradient */ for (j=1;j<=NY;j++){ for (i=1;i<=NX;i++){ waveconv[j][i] = waveconvtmp[j][i]; } } free_matrix(m,1,srctaper_gridpt,1,srctaper_gridpt); free_matrix(edgemat,1,4,1,1); free_matrix(mm,1,NYG,1,NXG); free_matrix(msum,1,NYG,1,NXG); free_matrix(taper_coeff_glob,1,NYG,1,NXG); free_matrix(waveconvtmp,0,NX+1,0,NY+1); MPI_Barrier(MPI_COMM_WORLD); sprintf(modfile,"taper_coeff_sources.bin"); writemod(modfile,taper_coeff,3); MPI_Barrier(MPI_COMM_WORLD); if (MYID==0) mergemod(modfile,3); } /* ======================== */ /* Read Taper from file */ /* ======================== */ if((sws>=4)&&(sws<=6)){ if (MYID==0) { fprintf(FP,"\n **Message from taper_grid (printed by PE %d):\n",MYID); fprintf(FP," Coefficients for gradient taper are now calculated.\n"); } if(sws==4){fp_taper=fopen("taper.bin","r");} if(sws==5){fp_taper=fopen("taper_u.bin","r");} if(sws==6){fp_taper=fopen("taper_rho.bin","r");} /* loop over global grid */ for (i=1;i<=NXG;i++){ for (j=1;j<=NYG;j++){ fread(&grad_tap, sizeof(float), 1, fp_taper); if ((POS[1]==((i-1)/NX)) && (POS[2]==((j-1)/NY))){ ii=i-POS[1]*NX; jj=j-POS[2]*NY; taper_coeff[jj][ii]=grad_tap; } } } for (j=1;j<=NY;j++){ for (i=1;i<=NX;i++){ waveconv[j][i]*=taper_coeff[j][i]; } } fclose(fp_taper); sprintf(modfile,"taper_coeff_file.bin"); writemod(modfile,taper_coeff,3); MPI_Barrier(MPI_COMM_WORLD); if (MYID==0) mergemod(modfile,3); } }
void LBFGS1(float ** taper_coeff, int nsrc, float ** srcpos, int ** recpos, int ntr_glob, int iter, int nfstart_jac, float ** waveconv, float C_vp, float ** gradp, float ** waveconv_u, float C_vs, float ** gradp_u, float ** waveconv_rho, float C_rho, float ** gradp_rho, float * y_LBFGS, float * s_LBFGS, float * rho_LBFGS, float * alpha_LBFGS, float **ppi, float ** pu, float ** prho, int nxnyi, float * q_LBFGS, float * r_LBFGS, float * beta_LBFGS, int LBFGS_pointer, int NLBFGS, int NLBFGS_vec){ extern int NX, NY, IDX, IDY, SPATFILTER; extern int HESSIAN, INVMAT, SWS_TAPER_GRAD_VERT, SWS_TAPER_GRAD_HOR, SWS_TAPER_GRAD_SOURCES, SWS_TAPER_FILE; extern int POS[3], MYID; extern char JACOBIAN[STRING_SIZE]; char jac[225], jac1[225]; int i, j, k, h, h1, h2; float betaz, betan, gradplastiter, gradclastiter, betar, beta; float gamma_LBFGS, sum_nom, sum_denom; float LBFGSTMP, LBFGSTMP1, LBFGSTMP2, LBFGSTMP3, modellastiter, norm_fac, norm_fac_u, norm_fac_rho; float beta_LBFGS_1; int ki, itershift, iter1; extern FILE *FP; FILE *FP3, *FP4, *FP6, *FP5, *FP7; itershift = 1; /* =================================================================================================================================================== */ /* ===================================================================================================================================================== */ /* ===================================================== GRADIENT Vp/Zp/lambda ================================================================================== */ /* ===================================================================================================================================================== */ if((INVMAT==1)||(INVMAT==0)){ /* Normalization of the gradient */ /* ------------------------------- */ for (i=1;i<=NX;i=i+IDX){ for (j=1;j<=NY;j=j+IDY){ waveconv[j][i] = C_vp * waveconv[j][i]; } } /* TEST: IMPLEMENTATION OF TAPER IN denise.c */ /*if (SWS_TAPER_GRAD_VERT){*/ /*vertical gradient taper is applied*/ /*taper_grad(waveconv,taper_coeff,srcpos,nsrc,recpos,ntr_glob,1);}*/ /*if (SWS_TAPER_GRAD_HOR){*/ /*horizontal gradient taper is applied*/ /*taper_grad(waveconv,taper_coeff,srcpos,nsrc,recpos,ntr_glob,2);}*/ /*if (SWS_TAPER_GRAD_SOURCES){*/ /*cylindrical taper around sources is applied*/ /*taper_grad(waveconv,taper_coeff,srcpos,nsrc,recpos,ntr_glob,3);}*/ /* apply Hessian^-1 and save in gradp*/ /*if (SWS_TAPER_FILE){ taper_grad(waveconv,taper_coeff,srcpos,nsrc,recpos,ntr_glob,5); }*/ /* apply median filter at source positions */ /*median_src(waveconv,taper_coeff,srcpos,nsrc,recpos,ntr_glob,iter,0);*/ /* apply wavenumber damping */ if(SPATFILTER==1){ wavenumber(waveconv); } if(SPATFILTER==2){ smooth2(waveconv); } /* Normalize gradient to maximum value */ /*norm_fac_u=norm(waveconv_u,iter,2); if(MYID==0){printf("norm_fac_u=%e \n",norm_fac_u);}*/ for (i=1;i<=NX;i=i+IDX){ for (j=1;j<=NY;j=j+IDY){ gradp[j][i] = waveconv[j][i]; } } /* save gradient for output as inversion result */ if(iter==nfstart_jac){ sprintf(jac,"%s_p_it%d.old.%i%i",JACOBIAN,iter,POS[1],POS[2]); FP3=fopen(jac,"wb"); for (i=1;i<=NX;i=i+IDX){ for (j=1;j<=NY;j=j+IDY){ fwrite(&waveconv[j][i],sizeof(float),1,FP3); } } fclose(FP3); MPI_Barrier(MPI_COMM_WORLD); /* merge gradient file */ sprintf(jac,"%s_p_it%d.old",JACOBIAN,iter); if (MYID==0) mergemod(jac,3); } } /* =================================================================================================================================================== */ /* ===================================================================================================================================================== */ /* ===================================================== GRADIENT Vs/Zs/mu ================================================================================== */ /* ===================================================================================================================================================== */ if((INVMAT==3)||(INVMAT==0)){ /* Normalization of the gradient */ /* ------------------------------- */ for (i=1;i<=NX;i=i+IDX){ for (j=1;j<=NY;j=j+IDY){ waveconv_u[j][i] = C_vs * waveconv_u[j][i]; } } /* TEST: IMPLEMENTATION OF TAPER IN denise.c */ /*if (SWS_TAPER_GRAD_VERT){*/ /*vertical gradient taper is applied*/ /*taper_grad(waveconv_u,taper_coeff,srcpos,nsrc,recpos,ntr_glob,1);}*/ /*if (SWS_TAPER_GRAD_HOR){*/ /*horizontal gradient taper is applied*/ /*taper_grad(waveconv_u,taper_coeff,srcpos,nsrc,recpos,ntr_glob,2);}*/ /*if (SWS_TAPER_GRAD_SOURCES){*/ /*cylindrical taper around sources is applied*/ /*taper_grad(waveconv_u,taper_coeff,srcpos,nsrc,recpos,ntr_glob,3);}*/ /* apply Hessian^-1 and save in gradp*/ /*if (SWS_TAPER_FILE){ taper_grad(waveconv_u,taper_coeff,srcpos,nsrc,recpos,ntr_glob,5); }*/ /* apply median filter at source positions */ /*median_src(waveconv_u,taper_coeff,srcpos,nsrc,recpos,ntr_glob,iter,0);*/ /* apply wavenumber damping */ if(SPATFILTER==1){ wavenumber(waveconv_u); } if(SPATFILTER==2){ smooth2(waveconv_u); } /* Normalize gradient to maximum value */ /*norm_fac_u=norm(waveconv_u,iter,2); if(MYID==0){printf("norm_fac_u=%e \n",norm_fac_u);}*/ for (i=1;i<=NX;i=i+IDX){ for (j=1;j<=NY;j=j+IDY){ gradp_u[j][i] = waveconv_u[j][i]; } } /* save gradient for output as inversion result */ if(iter==nfstart_jac){ sprintf(jac,"%s_p_u_it%d.old.%i%i",JACOBIAN,iter,POS[1],POS[2]); FP3=fopen(jac,"wb"); for (i=1;i<=NX;i=i+IDX){ for (j=1;j<=NY;j=j+IDY){ fwrite(&waveconv_u[j][i],sizeof(float),1,FP3); } } fclose(FP3); MPI_Barrier(MPI_COMM_WORLD); /* merge gradient file */ sprintf(jac,"%s_p_u_it%d.old",JACOBIAN,iter); if (MYID==0) mergemod(jac,3); } } /* ===================================================================================================================================================== */ /* ===================================================== GRADIENT rho ================================================================================== */ /* ===================================================================================================================================================== */ if((INVMAT==2)||(INVMAT==0)){ /* Normalization of the gradient */ /* ------------------------------- */ for (i=1;i<=NX;i=i+IDX){ for (j=1;j<=NY;j=j+IDY){ waveconv_rho[j][i] = C_rho * waveconv_rho[j][i]; } } /* TEST: IMPLEMENTAION OF TAPER IN denise.c */ /*if (SWS_TAPER_GRAD_VERT){*/ /*vertical gradient taper is applied*/ /*taper_grad(waveconv_rho,taper_coeff,srcpos,nsrc,recpos,ntr_glob,1);}*/ /*if (SWS_TAPER_GRAD_HOR){*/ /*horizontal gradient taper is applied*/ /*taper_grad(waveconv_rho,taper_coeff,srcpos,nsrc,recpos,ntr_glob,2);}*/ /*if (SWS_TAPER_GRAD_SOURCES){*/ /*cylindrical taper around sources is applied*/ /*taper_grad(waveconv_rho,taper_coeff,srcpos,nsrc,recpos,ntr_glob,3);}*/ /* apply Hessian^-1 and save in gradp*/ /*if (SWS_TAPER_FILE){ taper_grad(waveconv_rho,taper_coeff,srcpos,nsrc,recpos,ntr_glob,6); }*/ /* apply median filter at source positions */ /*median_src(waveconv_rho,taper_coeff,srcpos,nsrc,recpos,ntr_glob,iter,0);*/ /* apply wavenumber damping */ if(SPATFILTER==1){ wavenumber(waveconv_rho); } if(SPATFILTER==2){ smooth2(waveconv_rho); } /* Normalize gradient to maximum value */ /*norm_fac_rho=norm(waveconv_rho,iter,3); if(MYID==0){printf("norm_fac_rho=%e \n",norm_fac_rho);}*/ for (i=1;i<=NX;i=i+IDX){ for (j=1;j<=NY;j=j+IDY){ gradp_rho[j][i] = waveconv_rho[j][i]; } } /* apply spatial wavelength filter */ /*if(SPATFILTER==1){ if (MYID==0){ fprintf(FP,"\n Spatial filter is applied to gradient (written by PE %d)\n",MYID);} spat_filt(waveconv_rho,iter,3);}*/ /* save gradient for output as inversion result */ if(iter==nfstart_jac){ sprintf(jac,"%s_p_rho_it%d.old.%i%i",JACOBIAN,iter,POS[1],POS[2]); FP3=fopen(jac,"wb"); for (i=1;i<=NX;i=i+IDX){ for (j=1;j<=NY;j=j+IDY){ fwrite(&waveconv_rho[j][i],sizeof(float),1,FP3); } } fclose(FP3); MPI_Barrier(MPI_COMM_WORLD); /* merge gradient file */ sprintf(jac,"%s_p_rho_it%d.old",JACOBIAN,iter); if (MYID==0) mergemod(jac,3); } } /* calculate H^-1 * waveconv, using the L-BFGS method, if iter > 1 */ /* --------------------------------------------------------------------- */ if(iter>1){ /* load old models and gradients - rho and store them in the LBFGS vectors */ /* ------------------------------------------------------------------------ */ sprintf(jac,"%s_p_rho.old.%i%i",JACOBIAN,POS[1],POS[2]); FP6=fopen(jac,"rb"); sprintf(jac1,"%s_p_mrho.old.%i%i",JACOBIAN,POS[1],POS[2]); FP7=fopen(jac1,"rb"); /*iter1 = iter-itershift;*/ /* shift iter counter by 1 because L-BFGS method starts at iter > 1 */ h = NLBFGS_vec*(LBFGS_pointer-1) + 1; /* locate current initial position in LBFGS-vector */ for (i=1;i<=NX;i=i+IDX){ for (j=1;j<=NY;j=j+IDY){ /* calculate and save y, s at iteration step iter */ fread(&gradplastiter,sizeof(float),1,FP6); y_LBFGS[h] = waveconv_rho[j][i]-gradplastiter; fread(&modellastiter,sizeof(float),1,FP7); s_LBFGS[h] = prho[j][i]-modellastiter; h++; } } fclose(FP6); fclose(FP7); /* load old models and gradients - Vs and store them in the LBFGS vectors */ /* ----------------------------------------------------------------------- */ sprintf(jac,"%s_p_u.old.%i%i",JACOBIAN,POS[1],POS[2]); FP6=fopen(jac,"rb"); sprintf(jac1,"%s_p_vs.old.%i%i",JACOBIAN,POS[1],POS[2]); FP7=fopen(jac1,"rb"); for (i=1;i<=NX;i=i+IDX){ for (j=1;j<=NY;j=j+IDY){ /* calculate and save y, s at iteration step iter */ fread(&gradplastiter,sizeof(float),1,FP6); y_LBFGS[h] = waveconv_u[j][i]-gradplastiter; fread(&modellastiter,sizeof(float),1,FP7); s_LBFGS[h] = pu[j][i]-modellastiter; h++; } } fclose(FP6); fclose(FP7); /* load old models and gradients - Vp and store them in the LBFGS vectors */ /* ----------------------------------------------------------------------- */ sprintf(jac,"%s_p.old.%i%i",JACOBIAN,POS[1],POS[2]); FP6=fopen(jac,"rb"); sprintf(jac1,"%s_p_vp.old.%i%i",JACOBIAN,POS[1],POS[2]); FP7=fopen(jac1,"rb"); for (i=1;i<=NX;i=i+IDX){ for (j=1;j<=NY;j=j+IDY){ /* calculate and save y, s at iteration step iter */ fread(&gradplastiter,sizeof(float),1,FP6); y_LBFGS[h] = waveconv[j][i]-gradplastiter; fread(&modellastiter,sizeof(float),1,FP7); s_LBFGS[h] = ppi[j][i]-modellastiter; h++; } } fclose(FP6); fclose(FP7); /* calculate improved first guess Hessian gamma_LBFGS */ h1 = NLBFGS_vec*(LBFGS_pointer-1) + 1; h2 = NLBFGS_vec*LBFGS_pointer; sum_nom = dotp(y_LBFGS,s_LBFGS,h1,h2,0); sum_denom = dotp(y_LBFGS,y_LBFGS,h1,h2,0); gamma_LBFGS = sum_nom/sum_denom; /*printf("gamma_LBFGS = %e \n",gamma_LBFGS);*/ /* update variable rho for all LBFGS-iterations and all parameter classes*/ for(k=1;k<=NLBFGS;k++){ h1 = NLBFGS_vec*(k-1) + 1; h2 = NLBFGS_vec*k; sum_nom = dotp(y_LBFGS,s_LBFGS,h1,h2,0); if(fabs(sum_nom)>0.0){ rho_LBFGS[k] = 1.0/sum_nom; } else{ rho_LBFGS[k] = 0.0; } if(MYID==0){ printf("rho_LBFGS = %e of k = %d \n",rho_LBFGS[k],k);} } /* save q_LBFGS for all material parameters */ h=1; for (i=1;i<=NX;i=i+IDX){ for (j=1;j<=NY;j=j+IDY){ q_LBFGS[h] = waveconv_rho[j][i]; h++; } } for (i=1;i<=NX;i=i+IDX){ for (j=1;j<=NY;j=j+IDY){ q_LBFGS[h] = waveconv_u[j][i]; h++; } } for (i=1;i<=NX;i=i+IDX){ for (j=1;j<=NY;j=j+IDY){ q_LBFGS[h] = waveconv[j][i]; h++; } } /* update alpha_LBFGS and q_LBFGS */ for(k=NLBFGS;k>=1;k--){ h1 = NLBFGS_vec*(k-1) + 1; h2 = NLBFGS_vec*k; sum_nom = dotp(s_LBFGS,q_LBFGS,h1,h2,1); alpha_LBFGS[k] = rho_LBFGS[k] * sum_nom; /* update q for all material parameters */ h = NLBFGS_vec*(k-1) + 1; for (i=1;i<=NLBFGS_vec;i++){ q_LBFGS[i] = q_LBFGS[i] - alpha_LBFGS[k] * y_LBFGS[h]; h++; } } /* Multiply gradient with approximated Hessian */ for (i=1;i<=NLBFGS_vec;i++){ r_LBFGS[i] = gamma_LBFGS * q_LBFGS[i]; } /* calculate H^-1 * waveconv[j][i] */ for(k=1;k<=NLBFGS;k++){ h1 = NLBFGS_vec*(k-1) + 1; h2 = NLBFGS_vec*k; /* calculate beta_LBFGS*/ sum_nom = dotp(y_LBFGS,r_LBFGS,h1,h2,1); beta_LBFGS_1 = rho_LBFGS[k] * sum_nom; h = NLBFGS_vec*(k-1) + 1; for (i=1;i<=NLBFGS_vec;i++){ r_LBFGS[i] = r_LBFGS[i] + s_LBFGS[h]*(alpha_LBFGS[k]-beta_LBFGS_1); h++; } } /* update gradients */ h=1; /* density */ for (i=1;i<=NX;i=i+IDX){ for (j=1;j<=NY;j=j+IDY){ waveconv_rho[j][i] = r_LBFGS[h]; h++; } } /* Vs */ for (i=1;i<=NX;i=i+IDX){ for (j=1;j<=NY;j=j+IDY){ waveconv_u[j][i] = r_LBFGS[h]; h++; } } /* Vp */ for (i=1;i<=NX;i=i+IDX){ for (j=1;j<=NY;j=j+IDY){ waveconv[j][i] = r_LBFGS[h]; h++; } } /* Denormalize Gradients */ for (i=1;i<=NX;i=i+IDX){ for (j=1;j<=NY;j=j+IDY){ waveconv[j][i] = waveconv[j][i] * C_vp; waveconv_u[j][i] = waveconv_u[j][i] * C_vs; waveconv_rho[j][i] = waveconv_rho[j][i] * C_rho; } } } /* save old models Vs */ /* ------------------ */ /* save old model */ sprintf(jac,"%s_p_vp.old.%i%i",JACOBIAN,POS[1],POS[2]); FP3=fopen(jac,"wb"); for (i=1;i<=NX;i=i+IDX){ for (j=1;j<=NY;j=j+IDY){ fwrite(&ppi[j][i],sizeof(float),1,FP3); } } fclose(FP3); MPI_Barrier(MPI_COMM_WORLD); /* merge model file */ sprintf(jac,"%s_p_vp.old",JACOBIAN); if (MYID==0) mergemod(jac,3); /* save old gradient */ sprintf(jac,"%s_p.old.%i%i",JACOBIAN,POS[1],POS[2]); FP3=fopen(jac,"wb"); for (i=1;i<=NX;i=i+IDX){ for (j=1;j<=NY;j=j+IDY){ fwrite(&gradp[j][i],sizeof(float),1,FP3); } } fclose(FP3); MPI_Barrier(MPI_COMM_WORLD); /* merge gradient file */ sprintf(jac,"%s_p.old",JACOBIAN); if (MYID==0) mergemod(jac,3); /* save H^-1 * g */ sprintf(jac,"%s_c.old.%i%i",JACOBIAN,POS[1],POS[2]); FP3=fopen(jac,"wb"); for (i=1;i<=NX;i=i+IDX){ for (j=1;j<=NY;j=j+IDY){ fwrite(&waveconv[j][i],sizeof(float),1,FP3); } } fclose(FP3); MPI_Barrier(MPI_COMM_WORLD); /* merge gradient file */ sprintf(jac,"%s_c.old",JACOBIAN); if (MYID==0) mergemod(jac,3); /* save old models Vs */ /* ------------------ */ /* save old model */ sprintf(jac,"%s_p_vs.old.%i%i",JACOBIAN,POS[1],POS[2]); FP3=fopen(jac,"wb"); for (i=1;i<=NX;i=i+IDX){ for (j=1;j<=NY;j=j+IDY){ fwrite(&pu[j][i],sizeof(float),1,FP3); } } fclose(FP3); MPI_Barrier(MPI_COMM_WORLD); /* merge model file */ sprintf(jac,"%s_p_vs.old",JACOBIAN); if (MYID==0) mergemod(jac,3); /* save old gradient */ sprintf(jac,"%s_p_u.old.%i%i",JACOBIAN,POS[1],POS[2]); FP3=fopen(jac,"wb"); for (i=1;i<=NX;i=i+IDX){ for (j=1;j<=NY;j=j+IDY){ fwrite(&gradp_u[j][i],sizeof(float),1,FP3); } } fclose(FP3); MPI_Barrier(MPI_COMM_WORLD); /* merge gradient file */ sprintf(jac,"%s_p_u.old",JACOBIAN); if (MYID==0) mergemod(jac,3); /* save H^-1 * g */ sprintf(jac,"%s_c_u.old.%i%i",JACOBIAN,POS[1],POS[2]); FP3=fopen(jac,"wb"); for (i=1;i<=NX;i=i+IDX){ for (j=1;j<=NY;j=j+IDY){ fwrite(&waveconv_u[j][i],sizeof(float),1,FP3); } } fclose(FP3); MPI_Barrier(MPI_COMM_WORLD); /* merge gradient file */ sprintf(jac,"%s_c_u.old",JACOBIAN); if (MYID==0) mergemod(jac,3); /* save old models Rho */ /* ------------------ */ sprintf(jac,"%s_p_mrho.old.%i%i",JACOBIAN,POS[1],POS[2]); FP3=fopen(jac,"wb"); for (i=1;i<=NX;i=i+IDX){ for (j=1;j<=NY;j=j+IDY){ fwrite(&prho[j][i],sizeof(float),1,FP3); } } fclose(FP3); MPI_Barrier(MPI_COMM_WORLD); /* merge model file */ sprintf(jac,"%s_p_mrho.old",JACOBIAN); if (MYID==0) mergemod(jac,3); /* save old gradient */ sprintf(jac,"%s_p_rho.old.%i%i",JACOBIAN,POS[1],POS[2]); FP3=fopen(jac,"wb"); for (i=1;i<=NX;i=i+IDX){ for (j=1;j<=NY;j=j+IDY){ fwrite(&gradp_rho[j][i],sizeof(float),1,FP3); } } fclose(FP3); MPI_Barrier(MPI_COMM_WORLD); /* merge gradient file */ sprintf(jac,"%s_p_rho.old",JACOBIAN); if (MYID==0) mergemod(jac,3); /* save H^-1 * g_rho */ sprintf(jac,"%s_c_rho.old.%i%i",JACOBIAN,POS[1],POS[2]); FP3=fopen(jac,"wb"); for (i=1;i<=NX;i=i+IDX){ for (j=1;j<=NY;j=j+IDY){ fwrite(&waveconv_rho[j][i],sizeof(float),1,FP3); } } fclose(FP3); MPI_Barrier(MPI_COMM_WORLD); /* merge gradient file */ sprintf(jac,"%s_c_rho.old",JACOBIAN); if (MYID==0) mergemod(jac,3); }