예제 #1
0
int main(void)
{
	long idum=(-3);
	unsigned long err,i,j,k,nn1=NX,nn2=NY,nn3=NZ;
	float fnorm,***data1,***data2,**speq1;

	fnorm=(float)nn1*(float)nn2*(float)nn3/2.0;
	data1=f3tensor(1,nn1,1,nn2,1,nn3);
	data2=f3tensor(1,nn1,1,nn2,1,nn3);
	speq1=matrix(1,nn1,1,nn2<<1);
	for (i=1;i<=nn1;i++)
		for (j=1;j<=nn2;j++)
			for (k=1;k<=nn3;k++)
				data2[i][j][k]=fnorm*(data1[i][j][k]=2*ran1(&idum)-1);
	rlft3(data1,speq1,nn1,nn2,nn3,1);
	/* here would be any processing in Fourier space */
	rlft3(data1,speq1,nn1,nn2,nn3,-1);
	err=compare("data",data1,data2,nn1,nn2,nn3,EPS);
	if (err) {
		printf("Comparison error at tolerance %12.6f\n",EPS);
		printf("Total number of errors is %d\n",err);
	}
	else {
		printf("Data compares OK to tolerance %12.6f\n",EPS);
	}
	free_matrix(speq1,1,nn1,1,nn2<<1);
	free_f3tensor(data2,1,nn1,1,nn2,1,nn3);
	free_f3tensor(data1,1,nn1,1,nn2,1,nn3);
	return (err > 0);
}
예제 #2
0
int main(int argc, char **argv){
	int i,j,k;
	int n = 257; //set problem size here (33, 65, 129, 257)
	
	int ncycle = 2;  
	double dx = 1/(n-1);
	double C = alpha * dt/pow(dx,2);
	double time_diff;
	

	mode = 1; //set as 1 for Jacobi, 2 for GS, 3 for GS with Black-Red ordering
	
	if (mode == 1)
		printf("Starting Jacobi:\n");
	else if (mode == 2)
		printf("Starting Gauss-Siedel:\n");
	else if (mode == 3)
		printf("Starting Gauss-Siedel w/ Red-Black:\n");
	
	time_t start, end;
	FILE *outfile;
	
	double *vec;
	float ***f;

	vec = dvector(1, n);
	f = f3tensor(1, n, 1, n, 1, n);
	
	for (i=1; i<=n; i++)
		vec[i] = i/n;

	//establish initial conditions for matrix and random noise
	for (i=1; i<=n; i++) 
	   for (j=1; j<=n; j++) 
	      for (k=1; k<=n; k++) 
		  {
			f[i][j][k] = exp(
				exp(-pow(5*vec[i]-2.5,2))*
				exp(-pow(5*vec[i]-2.5,2))*
				exp(-pow(5*vec[i]-2.5,2))) 
				* (noise+(rand()%10)/1000);
	      }
		  
	start = clock();
	mglin(f,n,ncycle);
	end = clock();
	
	time_diff = (double)(end-start)/CLOCKS_PER_SEC;
	printf("%lf seconds\n", time_diff);

	outfile = fopen("soln.dat", "w");
	fwrite(&f[1][1][1],sizeof(double),n*n*n,outfile);
	fclose(outfile);
	free_f3tensor(f,1,n,1,n,1,n);
}
예제 #3
0
int main(void)		/* example3 */
{
	void rlft3(float ***data, float **speq, unsigned long nn1,
		unsigned long nn2, unsigned long nn3, int isign);
	int j;
	float fac,r,i,***data1,***data2,**speq1,**speq2,*sp1,*sp2;

	data1=f3tensor(1,N,1,N,1,N);
	data2=f3tensor(1,N,1,N,1,N);
	speq1=matrix(1,N,1,2*N);
	speq2=matrix(1,N,1,2*N);

	rlft3(data1,speq1,N,N,N,1);
	rlft3(data2,speq2,N,N,N,1);
	fac=2.0/(N*N*N);
	sp1 = &data1[1][1][1];
	sp2 = &data2[1][1][1];
	for (j=1;j<=N*N*N/2;j++) {
		r = sp1[0]*sp2[0] - sp1[1]*sp2[1];
		i = sp1[0]*sp2[1] + sp1[1]*sp2[0];
		sp1[0] = fac*r;
		sp1[1] = fac*i;
		sp1 += 2;
		sp2 += 2;
	}
	sp1 = &speq1[1][1];
	sp2 = &speq2[1][1];
	for (j=1;j<=N*N;j++) {
		r = sp1[0]*sp2[0] - sp1[1]*sp2[1];
		i = sp1[0]*sp2[1] + sp1[1]*sp2[0];
		sp1[0] = fac*r;
		sp1[1] = fac*i;
		sp1 += 2;
		sp2 += 2;
	}
	rlft3(data1,speq1,N,N,N,-1);
	free_matrix(speq2,1,N,1,2*N);
	free_matrix(speq1,1,N,1,2*N);
	free_f3tensor(data2,1,N,1,N,1,N);
	free_f3tensor(data1,1,N,1,N,1,N);
	return 0;
}
예제 #4
0
int main(void)		/* example1 */
{
	void rlft3(float ***data, float **speq, unsigned long nn1,
		unsigned long nn2, unsigned long nn3, int isign);
	float ***data, **speq;

	data=f3tensor(1,1,1,N2,1,N3);
	speq=matrix(1,1,1,2*N2);
	rlft3(data,speq,1,N2,N3,1);
	rlft3(data,speq,1,N2,N3,-1);
	free_matrix(speq,1,1,1,2*N2);
	free_f3tensor(data,1,1,1,N2,1,N3);
	return 0;
}
예제 #5
0
파일: mglin.c 프로젝트: jjenq/Homework-4
void mglin(float ***u, int n, int ncycle){
/*
  Full Multigrid Algorithm for solution of the steady state heat
  equation with forcing.  On input u[1..n][1..n] contains the
  right-hand side ρ, while on output it returns the solution.  The
  dimension n must be of the form 2j + 1 for some integer j. (j is
  actually the number of grid levels used in the solution, called ng
  below.) ncycle is the number of V-cycles to be used at each level.
*/
  unsigned int j,jcycle,jj,jpost,jpre,nf,ng=0,ngrid,nn;
  /*** setup multigrid jagged arrays ***/
  float ***iu[NGMAX+1];   /* stores solution at each grid level */
  float ***irhs[NGMAX+1]; /* stores rhs at each grid level */
  float ***ires[NGMAX+1]; /* stores residual at each grid level */
  float ***irho[NGMAX+1]; /* stores rhs during intial solution of FMG */
  
  /*** use bitshift to find the number of grid levels, stored in ng ***/
  nn=n;                   
  while (nn >>= 1) ng++;     
  
  /*** some simple input checks ***/
  if (n != 1+(1L << ng)) nrerror("n-1 must be a power of 2 in mglin.");
  if (ng > NGMAX) nrerror("increase NGMAX in mglin.");
  
  /***restrict solution to next coarsest grid (irho[ng-1])***/
  nn=n/2+1;
  ngrid=ng-1;
  irho[ngrid]=f3tensor(1,nn,1,nn,1,nn); 
  rstrct(irho[ngrid],u,nn);/* coarsens rhs (u at this point) to irho on mesh size nn */
  
  /***continue setting up coarser grids down to coarsest level***/
  while (nn > 3) { 
    nn=nn/2+1; 
    irho[--ngrid]=f3tensor(1,nn,1,nn,1,nn);
    rstrct(irho[ngrid],irho[ngrid+1],nn); 
  }
  
  /***now setup and solve coarsest level iu[1],irhs[1] ***/
  nn=3;
  iu[1]=f3tensor(1,nn,1,nn,1,nn);
  irhs[1]=f3tensor(1,nn,1,nn,1,nn);
  slvsml(iu[1],irho[1]);          /* solve the small system directly */
  free_f3tensor(irho[1],1,nn,1,nn,1,nn);
  ngrid=ng;                       /* reset ngrid to original size */

  for (j=2;j<=ngrid;j++) {        /* loop over coarse to fine, starting at level 2 */
    printf("at grid level %d\n",j);
    nn=2*nn-1;                     
    iu[j]=f3tensor(1,nn,1,nn,1,nn);     /* setup grids for lhs,rhs, and residual */
    irhs[j]=f3tensor(1,nn,1,nn,1,nn);
    ires[j]=f3tensor(1,nn,1,nn,1,nn);
    interp(iu[j],iu[j-1],nn);
    /* irho contains rhs except on fine grid where it is in u */
    copy(irhs[j],(j != ngrid ? irho[j] : u),nn); 
    /* v-cycle at current grid level */
    for (jcycle=1;jcycle<=ncycle;jcycle++) {  
      /* nf is # points on finest grid for current v-sweep */
      nf=nn;                                  
      for (jj=j;jj>=2;jj--) {                 
	for (jpre=1;jpre<=NPRE;jpre++)  /* NPRE g-s sweeps on the finest (relatively) scale */
	  relax(iu[jj],iu[jj-1],irhs[jj],nf); //need iu[jj-1] for jacobi
	resid(ires[jj],iu[jj],irhs[jj],nf); /* compute res on finest scale, store in ires */
	nf=nf/2+1;                        /* next coarsest scale */
	rstrct(irhs[jj-1],ires[jj],nf);  /* restrict residuals as rhs of next coarsest scale */
	fill0(iu[jj-1],nf);              /* set the initial solution guess to zero */
      } 
      slvsml(iu[1],irhs[1]);                  /* solve the small problem exactly */
      nf=3;                                   /* fine scale now n=3 */
      for (jj=2;jj<=j;jj++) {                 /* work way back up to current finest grid */
	nf=2*nf-1;                            /* next finest scale */
	addint(iu[jj],iu[jj-1],ires[jj],nf);  /* inter error and add to previous solution guess */
	for (jpost=1;jpost<=NPOST;jpost++)    /* do NPOST g-s sweeps */
	  relax(iu[jj],iu[jj-1],irhs[jj],nf);
      }
    }
  }

  copy(u,iu[ngrid],n);              /* copy solution into input array (implicitly returned) */

  /*** clean up memory ***/
  for (nn=n,j=ng;j>=2;j--,nn=nn/2+1) {       
    free_f3tensor(ires[j],1,nn,1,nn,1,nn);      
    free_f3tensor(irhs[j],1,nn,1,nn,1,nn);
    free_f3tensor(iu[j],1,nn,1,nn,1,nn);
    if (j != ng) free_f3tensor(irho[j],1,nn,1,nn,1,nn);
  }
  free_f3tensor(irhs[1],1,3,1,3,1,3);
  free_f3tensor(iu[1],1,3,1,3,1,3);
}
예제 #6
0
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);


}
예제 #7
0
void RTM_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;

/* help variable for MIN_ITER */
int min_iter_help=0;

/* parameters for gravity inversion */
char jac_grav[STRING_SIZE];

FILE *FP_stage, *FP_GRAV;

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);

/* Check if RTM workflow-file is defined (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(" --- ");
	}
}

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);

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

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

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);
}
      
SHOTINC=1;

/* For RTM read only first line from FWI workflow file and set iter = 1 */
stagemax = 1;   
iter_true = 1;
iter = 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;

if (MYID==0)
   {
   time2=MPI_Wtime();
   fprintf(FP,"\n\n\n ------------------------------------------------------------------\n");
   fprintf(FP,"\n\n\n                   Elastic Reverse Time Migration RTM \n");
   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);

/* ------------------------------------- */
/* calculate average material parameters */
/* ------------------------------------- */
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;

/* ---------------------------------------------------------------------------------------------------- */
/* --------- Calculate RTM P- and S- wave image 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);

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

/* Output of RTM results */
RTM_PSV_out(&fwiPSV);

} /* End of RTM-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(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);
}
 
/* 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);


}
예제 #8
0
파일: spacodi.c 프로젝트: eastman/spacodiR
void spacodi(int *np, int *ns, double *sp_plot, double *distmat, int *abundtype,
             int *Ndclass, double *dclass, double *Ist_out, double *Pst_out, double *Bst_out, double *PIst_out,
             double *pairwiseIst_out, double *pairwisePst_out, double *pairwiseBst_out, double *pairwisePIst_out) // Modified by jme 01-12-10
{
    int NP,NS,abundt,Ndivc;
    int s1,s2,p1,p2,c, **sps,counter; //Modified by jme 01-12-10
    double **fps, **dist, divc[102];
    double phylod,maxdist,F1,F2;
    float ***DivIijc,***DivPijc,***DivPIijc,***DivSijc;
    double **Ist,**Pst,**Bst,**PIst;
    double divIb[102],divIw[102],divPb[102],divPw[102],divBb[102],divBw[102],divPIb[102],divPIw[102],sumIb,sumIw1,sumIw2,sumPb,sumPw1,sumPw2,sumSb,sumSw1,sumSw2,sumPIb,sumPIw1,sumPIw2;
    double Istc[102],Pstc[102],Bstc[102],PIstc[102];

    NP=(*np);				//# plots
    NS=(*ns);				//# species
    abundt=(*abundtype);	//type of abundance (0, 1 or 2)
    Ndivc=(*Ndclass);		//# of classes of divergence intervals

    fps=dmatrix(0,NP,0,NS);	//frequency per plot and species
    dist=dmatrix(0,NS,0,NS);//divergence matrix between species

    for(s1=1; s1<=NS; s1++)for(s2=1; s2<=NS; s2++) dist[s1][s2]=distmat[(s1-1)+NS*(s2-1)];
    for(p1=1; p1<=NP; p1++)for(s1=1; s1<=NS; s1++) fps[p1][s1]=sp_plot[(s1-1)+NS*(p1-1)];
    for(c=1; c<=Ndivc; c++) divc[c]=dclass[c-1];

    //if dist classes are given, check if last class is larger or equal to max dist,
    // otherwise add a class
    maxdist=0.;
    for(s1=1; s1<NS; s1++)for(s2=s1+1; s2<=NS; s2++) if(maxdist<dist[s1][s2]) maxdist=dist[s1][s2];
    if(Ndivc) {
        if(divc[Ndivc]<maxdist) {
            Ndivc++;
            divc[Ndivc]=maxdist;
            //(*Ndclass)++;
            //dclass[Ndivc-1]=maxdist;
        }
    }
    else {
        Ndivc=1;
        divc[1]=maxdist;
    }

    //identify species present in each plot and attribute a new numerotation (to speed loops)
    // sps[plot][0]=number of species in plot
    // sps[plot][new sp number]=absolute sp number
    // where 'new sp number' ranges from 1 to number of species in plot,
    // and 'absolute sp number' ranges from 1 to NS
    sps=imatrix(0,NP,0,NS);
    for(p1=0; p1<=NP; p1++) {
        sps[p1][0]=0;
        for(s1=1; s1<=NS; s1++) if(fps[p1][s1]) {
                sps[p1][0]++;
                sps[p1][sps[p1][0]]=s1;
            }
    }

    //transform abundances in relative frequencies per plot
    //sum of abundances per plot stored in fps[plot][0]
    for(p1=1; p1<=NP; p1++) {
        fps[p1][0]=0.;
        for(s1=1; s1<=sps[p1][0]; s1++) fps[p1][0]+=fps[p1][sps[p1][s1]];
        for(s1=1; s1<=sps[p1][0]; s1++) fps[p1][sps[p1][s1]]/=fps[p1][0];
    }


    //create 3-dim arrays to store values per pair of plots and per divergence classes
    // c=0 for pairs intra-sp, c=-1 for sums over all classes
    DivIijc=f3tensor(0,NP,0,NP,-1,Ndivc);	//freq of pairs of ind
    DivPijc=f3tensor(0,NP,0,NP,-1,Ndivc);	//mean dist between ind
    DivSijc=f3tensor(0,NP,0,NP,-1,Ndivc);	//freq of pairs of species
    DivPIijc=f3tensor(0,NP,0,NP,-1,Ndivc);	//mean dist between species


    //compute diversity within and between plots
    for(p1=1; p1<=NP; p1++)for(p2=p1; p2<=NP; p2++) {
            for(c=-1; c<=Ndivc; c++) DivIijc[p1][p2][c]=DivPijc[p1][p2][c]=DivSijc[p1][p2][c]=DivPIijc[p1][p2][c]=0.f;

            for(s1=1; s1<=sps[p1][0]; s1++) {
                F1=fps[p1][sps[p1][s1]];
                for(s2=1; s2<=sps[p2][0]; s2++) {
                    F2=fps[p2][sps[p2][s2]];
                    if(p1==p2 && s1==s2 && abundt==2) F2=((F2*fps[p1][0])-1.)/(fps[p1][0]-1.); //sample size correction when abundnaces are individuals counts

                    if(sps[p1][s1]==sps[p2][s2]) {
                        c=0;
                        phylod=0.;
                    }
                    else {
                        phylod=dist[sps[p1][s1]][sps[p2][s2]];	//phyletic distance between species (0 for a species with itself)
                        c=1;
                        while(divc[c]<phylod) c++;
                    }

                    DivIijc[p1][p2][c]+=(float)(F1*F2);				//prob identity
                    DivPijc[p1][p2][c]+=(float)(F1*F2*phylod);		//mean dist btw ind
                    DivSijc[p1][p2][c]++;							//# pairs of sp
                    DivPIijc[p1][p2][c]+=(float)(phylod);			//mean dist btw sp
                }  //end of loop s2
            }  //end loop s1

            //convert into mean dist btw ind or sp per class
            for(c=0; c<=Ndivc; c++) DivPijc[p1][p2][c]/=DivIijc[p1][p2][c];
            for(c=1; c<=Ndivc; c++) DivPIijc[p1][p2][c]/=DivSijc[p1][p2][c];

            //sums
            for(c=0; c<=Ndivc; c++) DivIijc[p1][p2][-1]+=DivIijc[p1][p2][c];
            for(c=1; c<=Ndivc; c++) DivSijc[p1][p2][-1]+=DivSijc[p1][p2][c];

            //proportions
            for(c=0; c<=Ndivc; c++) DivIijc[p1][p2][c]/=DivIijc[p1][p2][-1];
            for(c=1; c<=Ndivc; c++) DivSijc[p1][p2][c]/=DivSijc[p1][p2][-1];

            //mean dist btw ind or sp cumulated over classes
            for(c=1; c<=Ndivc; c++) {
                DivPijc[p1][p2][-1]+=DivPijc[p1][p2][c]*DivIijc[p1][p2][c];
                DivPIijc[p1][p2][-1]+=DivPIijc[p1][p2][c]*DivSijc[p1][p2][c];
            }

        }

    Ist=dmatrix(0,NP,0,NP);
    Pst=dmatrix(0,NP,0,NP);
    Bst=dmatrix(0,NP,0,NP);
    PIst=dmatrix(0,NP,0,NP);

    for(c=0; c<=Ndivc; c++) divIb[c]=divIw[c]=divPb[c]=divPw[c]=divBb[c]=divBw[c]=divPIb[c]=divPIw[c]=0.;
    //pairwise Ist & cie
    counter=0; //Modified by jme 01-12-10
    for(p1=1; p1<=NP; p1++)for(p2=p1+1; p2<=NP; p2++) {
            pairwiseIst_out[counter]=Ist[p1][p2]=Ist[p2][p1]=1.- (((1.-DivIijc[p1][p1][0])+(1.-DivIijc[p2][p2][0]))/2.) / (1.-DivIijc[p1][p2][0]); //Modified by jme 01-12-10
            pairwisePst_out[counter]=Pst[p1][p2]=Pst[p2][p1]=1.- ((DivPijc[p1][p1][-1]+DivPijc[p2][p2][-1])/2.) / DivPijc[p1][p2][-1]; //Modified by jme 01-12-10
            pairwiseBst_out[counter]=Bst[p1][p2]=Bst[p2][p1]=1.- ((DivPijc[p1][p1][-1]/(1.-DivIijc[p1][p1][0])+DivPijc[p2][p2][-1]/(1.-DivIijc[p2][p2][0]))/2.) / (DivPijc[p1][p2][-1]/(1.-DivIijc[p1][p2][0])); //Modified by jme 01-12-10
            pairwisePIst_out[counter]=PIst[p1][p2]=PIst[p2][p1]=1.- ((DivPIijc[p1][p1][-1]+DivPIijc[p2][p2][-1])/2.) / DivPIijc[p1][p2][-1]; //Modified by jme 01-12-10
            counter=counter+1; //Modified by jme 01-12-10

            //sums for global stat
            divIb[0]+=(1.-DivIijc[p1][p2][0]);
            divIw[0]+=( (1.-DivIijc[p1][p1][0]) + (1.-DivIijc[p2][p2][0]) )/2.;
            divPb[0]+=DivPijc[p1][p2][-1];
            divPw[0]+=(DivPijc[p1][p1][-1]+DivPijc[p2][p2][-1])/2.;
            divBb[0]+=DivPijc[p1][p2][-1]/(1.-DivIijc[p1][p2][0]);
            divBw[0]+=( DivPijc[p1][p1][-1]/(1.-DivIijc[p1][p1][0]) + DivPijc[p2][p2][-1]/(1.-DivIijc[p2][p2][0]) )/2.;
            divPIb[0]+=DivPIijc[p1][p2][-1];
            divPIw[0]+=(DivPIijc[p1][p1][-1]+DivPIijc[p2][p2][-1])/2.;
        }
    Istc[0]=1.-divIw[0]/divIb[0];
    Pstc[0]=1.-divPw[0]/divPb[0];
    Bstc[0]=1.-divBw[0]/divBb[0];
    PIstc[0]=1.-divPIw[0]/divPIb[0];

    //global Ist by dist classes
    for(p1=1; p1<=NP; p1++)for(p2=p1+1; p2<=NP; p2++) {
            sumIb=sumIw1=sumIw2=sumPb=sumPw1=sumPw2=sumSb=sumSw1=sumSw2=sumPIb=sumPIw1=sumPIw2=0.;
            for(c=1; c<=Ndivc; c++) {
                sumIb+=DivIijc[p1][p2][c];
                sumIw1+=DivIijc[p1][p1][c];
                sumIw2+=DivIijc[p2][p2][c];
                sumPb+=DivPijc[p1][p2][c]*DivIijc[p1][p2][c];
                sumPw1+=DivPijc[p1][p1][c]*DivIijc[p1][p1][c];
                sumPw2+=DivPijc[p2][p2][c]*DivIijc[p2][p2][c];
                divBb[c]+=sumPb/sumIb;
                divBw[c]+=((sumPw1/sumIw1)+(sumPw2/sumIw2))/2.;
                divPb[c]+=sumPb/(sumIb+DivIijc[p1][p2][0]);
                divPw[c]+=((sumPw1/(sumIw1+DivIijc[p1][p1][0]))+(sumPw2/(sumIw2+DivIijc[p2][p2][0])))/2.;

                sumSb+=DivSijc[p1][p2][c];
                sumSw1+=DivSijc[p1][p1][c];
                sumSw2+=DivSijc[p2][p2][c];
                sumPIb+=DivPIijc[p1][p2][c]*DivSijc[p1][p2][c];
                sumPIw1+=DivPIijc[p1][p1][c]*DivSijc[p1][p1][c];
                sumPIw2+=DivPIijc[p2][p2][c]*DivSijc[p2][p2][c];
                divPIb[c]+=sumPIb/sumSb;
                divPIw[c]+=((sumPIw1/sumSw1)+(sumPIw2/sumSw2))/2.;
            }
        }
    for(c=1; c<=Ndivc; c++) {
        Pstc[c]=1.-divPw[c]/divPb[c];
        Bstc[c]=1.-divBw[c]/divBb[c];
        PIstc[c]=1.-divPIw[c]/divPIb[c];
    }



    (*Ist_out)=Istc[0]; // Modified by cetp 17-08-09
    (*Pst_out)=Pstc[0]; // Modified by cetp 17-08-09
    (*Bst_out)=Bstc[0]; // Modified by cetp 17-08-09
    (*PIst_out)=PIstc[0];// Modified by cetp 17-08-09

    //free memory
    free_dmatrix(fps,0,NP,0,NS);
    free_dmatrix(dist,0,NS,0,NS);
    free_imatrix(sps,0,NP,0,NS);
    free_f3tensor(DivIijc,0,NP,0,NP,-1,Ndivc);
    free_f3tensor(DivPijc,0,NP,0,NP,-1,Ndivc);
    free_f3tensor(DivSijc,0,NP,0,NP,-1,Ndivc);
    free_f3tensor(DivPIijc,0,NP,0,NP,-1,Ndivc);
    free_dmatrix(Ist,0,NP,0,NP);
    free_dmatrix(Pst,0,NP,0,NP);
    free_dmatrix(Bst,0,NP,0,NP);
    free_dmatrix(PIst,0,NP,0,NP);


}
예제 #9
0
int main(void)  /* Program sfroid */
{
	float plgndr(int l, int m, float x);
	void solvde(int itmax, float conv, float slowc, float scalv[],
		int indexv[], int ne, int nb, int m, float **y, float ***c, float **s);
	int i,itmax,k,indexv[NE+1];
	float conv,deriv,fac1,fac2,q1,slowc,scalv[NE+1];
	float **y,**s,***c;

	y=matrix(1,NYJ,1,NYK);
	s=matrix(1,NSI,1,NSJ);
	c=f3tensor(1,NCI,1,NCJ,1,NCK);
	itmax=100;
	conv=5.0e-6;
	slowc=1.0;
	h=1.0/(M-1);
	printf("\nenter m n\n");
	scanf("%d %d",&mm,&n);
	if (n+mm & 1) {
		indexv[1]=1;
		indexv[2]=2;
		indexv[3]=3;
	} else {
		indexv[1]=2;
		indexv[2]=1;
		indexv[3]=3;
	}
	anorm=1.0;
	if (mm) {
		q1=n;
		for (i=1;i<=mm;i++) anorm = -0.5*anorm*(n+i)*(q1--/i);
	}
	for (k=1;k<=(M-1);k++) {
		x[k]=(k-1)*h;
		fac1=1.0-x[k]*x[k];
		fac2=exp((-mm/2.0)*log(fac1));
		y[1][k]=plgndr(n,mm,x[k])*fac2;
		deriv = -((n-mm+1)*plgndr(n+1,mm,x[k])-
			(n+1)*x[k]*plgndr(n,mm,x[k]))/fac1;
		y[2][k]=mm*x[k]*y[1][k]/fac1+deriv*fac2;
		y[3][k]=n*(n+1)-mm*(mm+1);
	}
	x[M]=1.0;
	y[1][M]=anorm;
	y[3][M]=n*(n+1)-mm*(mm+1);
	y[2][M]=(y[3][M]-c2)*y[1][M]/(2.0*(mm+1.0));
	scalv[1]=fabs(anorm);
	scalv[2]=(y[2][M] > scalv[1] ? y[2][M] : scalv[1]);
	scalv[3]=(y[3][M] > 1.0 ? y[3][M] : 1.0);
	for (;;) {
		printf("\nEnter c**2 or 999 to end.\n");
		scanf("%f",&c2);
		if (c2 == 999) {
			free_f3tensor(c,1,NCI,1,NCJ,1,NCK);
			free_matrix(s,1,NSI,1,NSJ);
			free_matrix(y,1,NYJ,1,NYK);
			return 0;
		}
		solvde(itmax,conv,slowc,scalv,indexv,NE,NB,M,y,c,s);
		printf("\n %s %2d %s %2d %s %7.3f %s %10.6f\n",
			"m =",mm,"  n =",n,"  c**2 =",c2,
			" lamda =",y[3][1]+mm*(mm+1));
	}
}
예제 #10
0
파일: read_cdc.c 프로젝트: kassick/olam
void cdc_stw(int *iyear, int *imonth, int *idate, int *itime, char *locfn, float *soilt1, float *soilt2, float *soilw1, float *soilw2, float *snow){
  FILE*outfile;
  struct ncvar *soilw010cm_var = NULL;
  struct ncvar *soilw10200cm_var = NULL;
  struct ncvar *tmp010cm_var = NULL;
  struct ncvar *tmp10200cm_var = NULL;
  struct ncvar *weasd_var = NULL;
  struct ncvar *tmpvar = NULL;
  float ***soilw010cm = NULL;
  float ***soilw10200cm = NULL;
  float ***tmp010cm = NULL;
  float ***tmp10200cm = NULL;
  float ***weasd = NULL;
  char infilename[256];
  int lati,loni;
  size_t latmini,lonmini,latmaxi,lonmaxi,rlati,rloni;
  float lat,lon;
  double time;
  unsigned int timei;
  float u;
  int beg_time[13];
  int nlat,nlon;
  float lat_min,lon_min,lat_max,lon_max,rv;
  float stime;
  int offset_from_utc,id,ib,ih;
  int ntime;
  char tmpvar_name[256];
  char mname[3];
  hid_t fileid,dsetid,mspcid,propid;
  hid_t fileid2,dsetid2,mspcid2,propid2;
  char syscmd[256];
  float var_out[1464];
  int ndims;
  int idims[1];
  hsize_t dimsc[7] = {1,1,1,1,1,1,1};
  hsize_t maxdims[7] = {1,1,1,1,1,1,1};
  hsize_t chunk_size[7] = {0,0,0,0,0,0,0};
  int i;
  char var_name[20];
  int hdferr;
  int timeo;

  /* Read in each variable */
  printf("trying tmp.0-10cm\n");
  sprintf(infilename,"%stmp.0-10cm.gauss.%d.nc",locfn,*iyear);
  check_cdc_files(infilename, *iyear);
  tmp010cm_var = new_ncvar(infilename,"tmp");
  tmp010cm = ncgetvar(tmp010cm_var);
  
  printf("trying tmp.10-200cm\n");
  sprintf(infilename,"%stmp.10-200cm.gauss.%d.nc",locfn,*iyear);
  check_cdc_files(infilename, *iyear);
  tmp10200cm_var = new_ncvar(infilename,"tmp");
  tmp10200cm = ncgetvar(tmp10200cm_var);
  
  printf("trying soilw.0-10cm\n");
  sprintf(infilename,"%ssoilw.0-10cm.gauss.%d.nc",locfn,*iyear);
  check_cdc_files(infilename, *iyear);
  soilw010cm_var = new_ncvar(infilename,"soilw");
  soilw010cm = ncgetvar(soilw010cm_var);
  
  printf("trying soilw.10-200cm\n");
  sprintf(infilename,"%ssoilw.10-200cm.gauss.%d.nc",locfn,*iyear);
  check_cdc_files(infilename, *iyear);
  soilw10200cm_var = new_ncvar(infilename,"soilw");
  soilw10200cm = ncgetvar(soilw10200cm_var);
  
  printf("trying weasd\n");
  sprintf(infilename,"%sweasd.sfc.gauss.%d.nc",locfn,*iyear);
  check_cdc_files(infilename, *iyear);
  weasd_var = new_ncvar(infilename,"weasd");
  weasd = ncgetvar(weasd_var);

  /*   The variable beg_time is used to determine what month you are in.
   */
  beg_time[0] = 0;
  beg_time[1] = 31*4;
  if(*iyear%4 == 0){
      beg_time[2] = beg_time[1] + 29 * 4;
  }else{
      beg_time[2] = beg_time[1] + 28 * 4;
  }
  beg_time[3] = beg_time[2] + 31 * 4;
  beg_time[4] = beg_time[3] + 30 * 4;
  beg_time[5] = beg_time[4] + 31 * 4;
  beg_time[6] = beg_time[5] + 30 * 4;
  beg_time[7] = beg_time[6] + 31 * 4;
  beg_time[8] = beg_time[7] + 31 * 4;
  beg_time[9] = beg_time[8] + 30 * 4;
  beg_time[10] = beg_time[9] + 31 * 4;
  beg_time[11] = beg_time[10] + 30 * 4;
  beg_time[12] = beg_time[11] + 31 * 4;
  beg_time[*imonth-1] += 4 * (*idate - 1) + *itime/6; 

  /* loop over sites */
  for(lati = 1; lati <= 73; lati++) {
      lat = 90.0 - (lati - 1) * 2.5;
      // Goes from east to west
      for(loni = 1; loni <= 144; loni++) {
	  lon = 1.25 + (loni - 1) * 2.5;
	  ncnearest(tmp010cm_var, lat, lon, &rlati, &rloni);
	  
	  timei=beg_time[*imonth-1];
	  soilt1[144*(lati-1)+loni-1] = tmp010cm[timei][rlati][rloni];
	  soilt2[144*(lati-1)+loni-1] = tmp10200cm[timei][rlati][rloni];
	  soilw1[144*(lati-1)+loni-1] = soilw010cm[timei][rlati][rloni]/0.434;
	  soilw2[144*(lati-1)+loni-1] = soilw10200cm[timei][rlati][rloni]/0.434;
	  snow[144*(lati-1)+loni-1] = weasd[timei/4][rlati][rloni];
	  
      }
  }

  /* Free memory */

  free_f3tensor(tmp010cm, tmp010cm_var);
  free_f3tensor(tmp10200cm, tmp10200cm_var);
  free_f3tensor(soilw010cm, soilw010cm_var);
  free_f3tensor(soilw10200cm, soilw10200cm_var);
  free_f3tensor(weasd, weasd_var);

  free_ncvar(tmp010cm_var);
  free_ncvar(tmp10200cm_var);
  free_ncvar(soilw010cm_var);
  free_ncvar(soilw10200cm_var);
  free_ncvar(weasd_var);
  
  return;
}
예제 #11
0
int main(int argc,char *argv[])
{
	char *listfile,*inputfile;
	char choose= ' ';
	string operate=" ";
	double temperature=300;
	string output=" ";
	string segment="all";
	int segment_b=0;
	int segment_e=0;
//  读取当前的时间
	time_t t = time( 0 ); 
    char TIME[64]; 
    strftime( TIME, sizeof(TIME), "%Y/%m/%d %X ",localtime(&t) ); 
    
//

	switch(argc)
	{
	case 1:
		cout<<"Usage:CurAnalysis -f listfile.txt -i inputfile.txt"<<endl;
		
		exit(0);
	case 2:
		if(string(argv[1])=="-a")
		{
			Printversion();
			exit(0);
		}
		if(string(argv[1])=="-h")
		{
			Printhelp();
			exit(0);
		}
	case 5:
		if(string(argv[1])=="-f"&&string(argv[3])=="-i")
		{
			listfile=argv[2];
			inputfile=argv[4];
		}
		break;

	default:
		cout<<"Usage:CurAnalysis -f listfile.txt -i inputfile.txt"<<endl;
		exit(0);

	}

	ReadInput(inputfile,operate,choose,output,temperature,segment,segment_b,segment_e);
/*
average部分已经完成,经测试可以使用,主要的问题是读文件的异常
比如说文件残缺,文件丢失等的情况的处理的过程没有完成。
*/
	if(operate=="average")
	{
		if(choose=='E'||choose=='F'||choose=='G'||choose=='H')
		{
			double ***totaldata;
			struct	Filelist *fl;
			struct Paramater *spt;
			int N=0;
			ofstream outfile(output.c_str(),ios::app);
			fl=Readlist(listfile);
			switch(choose)
			{
			case 'E':
				spt=E_part(fl->file);
				break;
			case 'F':
				spt=F_part(fl->file);
				break;
			case 'G':
				spt=G_part(fl->file);
				break;
			case 'H':
				spt=H_part(fl->file);
				break;
			}
			int filesize=Getfilelen(fl);	
			int size=GetParamaterlen(spt);
			if(segment!="all")
			{
				size=segment_e - segment_b+1;
			}
			if(segment=="all")
			{
				segment_b=1;
				segment_e=size;
			}
			totaldata=f3tensor(0,5,0,size-1,0,filesize-1);
outfile<<"******************************************************************"<<endl;
//output the input file!
	ifstream infile(inputfile);
	string s;
    getline(infile,s);
   while(!infile.fail())
	{
		outfile<<"#"<<s<<endl;
		getline(infile,s);
	}
    outfile<<TIME<<endl;  //输出当前时间
	infile.close();

//
			while(fl!=NULL)
			{
				struct Paramater *sp; 
				switch(choose)
				{
					case 'E':
						sp=E_part(fl->file);
					break;
					case 'F':
						sp=F_part(fl->file);
					break;
					case 'G':
						sp=G_part(fl->file);
					break;
					case 'H':
						sp=H_part(fl->file);
					break;
				}
		//		int size=GetParamaterlen(sp);
				double **data;
				data=dmatrix(0,5,0,size-1);
				struct Namelist *name;
				name=(struct Namelist *)malloc(sizeof(struct Namelist));
				Paramater2double(sp,data,name,segment_b,segment_e);

				for(int i=0;i<6;i++)
				{
					for(int j=0;j<size;j++)
					{
						totaldata[i][j][N]=data[i][j];
					}
				}
				free_dmatrix(data,0,5,0,size-1);
				cout<<"Read file "<<fl->file<<" finished!"<<endl;//输出提示
				fl=fl->next;
				N++;
			}

			double **aveg;
			aveg=dmatrix(0,5,0,size-1);
			for(int i=0;i<6;i++)
			{
				for(int j=0;j<size;j++)
				{
					aveg[i][j]=0;
				}
			}

			outfile<<endl;
			outfile<<"******************************************************************"<<endl;
			outfile<<"\t"<<"rise"<<"\t"<<"roll"<<"\t"<<"shift"<<"\t"<<"slide"<<"\t"<<"tilt"<<"\t"<<"twist"<<endl;
			outfile<<endl;

			for(int i=0;i<size;i++)
			{
				outfile<<i+segment_b<<"\t";
				for(int j=0;j<6;j++)
				{
					for(int k=0;k<filesize;k++)
					{
						aveg[j][i]+=totaldata[j][i][k];
					}
					aveg[j][i]=aveg[j][i]/filesize;
					outfile<<fixed<<showpoint;
					
	 				outfile<<setprecision(2)<<aveg[j][i]<<"\t";
				}
				outfile<<endl;
			}
			outfile<<endl;
			outfile<<"******************************************************************"<<endl;
		   cout<<"finished the calculation of average !"<<endl;
		   cout<<"the output write in the file "<<output<<" !"<<endl;
			outfile.close();
			free_f3tensor(totaldata,0,5,0,size-1,0,filesize-1);
		}

		//average for J

		if(choose=='J')
		{
			double ***totaldata;
			struct	Filelist *fl;
			struct Backbone *spt;
			int N=0;
			fl=Readlist(listfile);
			spt=J_part(fl->file);
			int filesize=Getfilelen(fl);	
			int size=GetBackbonelen(spt);
			if(segment!="all")
			{
				size=segment_e - segment_b+1;
			}
			if(segment=="all")
			{
				segment_b=1;
				segment_e=size;
			}
			totaldata=f3tensor(0,13,0,size-1,0,filesize-1);
			ofstream outfile(output.c_str(),ios::app);

			outfile<<"******************************************************************"<<endl;
		//output the input file!
			ifstream infile(inputfile);
			string s;
			getline(infile,s);
			 while(!infile.fail())
			{
				outfile<<"#"<<s<<endl;
				getline(infile,s);
			}
			 outfile<<TIME<<endl; //输出当前时间
			infile.close();
//

			while(fl!=NULL)
			{
				struct Backbone *sp;
				sp=J_part(fl->file);
		//		int size=GetBackbonelen(sp);
				double **data;
				data=dmatrix(0,13,0,size-1);
				struct Namelist *name;
				name=(struct Namelist *)malloc(sizeof(struct Namelist));
				Backbone2double(sp,data,name,segment_b,segment_e);

				for(int i=0;i<14;i++)
				{
					for(int j=0;j<size;j++)
					{
						totaldata[i][j][N]=data[i][j];
					}
				}
				free_dmatrix(data,0,13,0,size-1);
				cout<<"Read file "<<fl->file<<" finished!"<<endl;//输出提示
				fl=fl->next;
				N++;
			}

			double **aveg;
			aveg=dmatrix(0,13,0,size-1);
			for(int i=0;i<14;i++)
			{
				for(int j=0;j<size;j++)
				{
					aveg[i][j]=0;
				}
			}

			outfile<<endl;
			outfile<<"******************************************************************"<<endl;
			outfile<<"\t"<<"alpha"<<"\t"<<"ampli"<<"\t"<<"beta"<<"\t"<<"c1"<<"\t"<<"c1c2"<<"\t"<<"c2"<<"\t"<<"c2c3"<<"\t"<<"c3"<<"\t"<<"chi"<<"\t"<<"delta"<<"\t"<<"epsil"<<"\t"<<"gamma"<<"\t"<<"phase"<<"\t"<<"zeta"<<endl;
			outfile<<endl;

			for(int i=0;i<size;i++)
			{
				outfile<<i+segment_b<<"\t";
				for(int j=0;j<14;j++)
				{
					for(int k=0;k<filesize;k++)
					{
						aveg[j][i]+=totaldata[j][i][k];
					}
					aveg[j][i]=aveg[j][i]/filesize;
					outfile<<fixed<<showpoint;
					outfile<<setprecision(2)<<aveg[j][i]<<"\t";
				}
				outfile<<endl;
			}
			outfile<<endl;
			outfile<<"******************************************************************"<<endl;
		   cout<<"finished the calculation of average !"<<endl;
		   cout<<"the output write in the file "<<output<<" !"<<endl;
			outfile.close();
			free_f3tensor(totaldata,0,13,0,size-1,0,filesize-1);
		}

	}

	
//计算某一数据的分布


	if(operate=="distribution")
	{
		//part 1: get the data
		if(choose=='E'||choose=='F'||choose=='G'||choose=='H')
		{
			double ***totaldata;
			struct	Filelist *fl;
			struct Paramater *spt;
			int N=0;
			ofstream outfile(output.c_str(),ios::app);
			fl=Readlist(listfile);
			switch(choose)
			{
			case 'E':
				spt=E_part(fl->file);
				break;
			case 'F':
				spt=F_part(fl->file);
				break;
			case 'G':
				spt=G_part(fl->file);
				break;
			case 'H':
				spt=H_part(fl->file);
				break;
			}
			int filesize=Getfilelen(fl);	
			int size=GetParamaterlen(spt);
			if(segment!="all")
			{
				size=segment_e - segment_b+1;
			}
			if(segment=="all")
			{
				segment_b=1;
				segment_e=size;
			}
			totaldata=f3tensor(0,5,0,size-1,0,filesize-1);
			outfile<<"******************************************************************"<<endl;

			//output the input file!
			ifstream infile(inputfile);
			string s;
			 getline(infile,s);
			while(!infile.fail())
			{
				outfile<<"#"<<s<<endl;
				getline(infile,s);
			}
		    outfile<<TIME<<endl;  //输出当前时间
			infile.close();

//
			while(fl!=NULL)
			{
				struct Paramater *sp; 
				switch(choose)
				{
					case 'E':
						sp=E_part(fl->file);
					break;
					case 'F':
						sp=F_part(fl->file);
					break;
					case 'G':
						sp=G_part(fl->file);
					break;
					case 'H':
						sp=H_part(fl->file);
					break;
				}
		//		int size=GetParamaterlen(sp);
				double **data;
				data=dmatrix(0,5,0,size-1);
				struct Namelist *name;
				name=(struct Namelist *)malloc(sizeof(struct Namelist));
				Paramater2double(sp,data,name,segment_b,segment_e);

				for(int i=0;i<6;i++)
				{
					for(int j=0;j<size;j++)
					{
						totaldata[i][j][N]=data[i][j];
					}
				}
				free_dmatrix(data,0,5,0,size-1);
				cout<<"Read file "<<fl->file<<" finished!"<<endl;//输出提示
				fl=fl->next;
				N++;
			}
// finished the input data
			//calculate the distribution!
			double *vect;
			vect=dvector(0, size*filesize-1) ;  
			for(int i=0;i<6;i++)
			{
				outfile<<"******************************************************************"<<endl;
				switch(i)
				{
					case 0:
						outfile<<"the distribution of RISE"<<endl;
						break;
					case 1:
						outfile<<"the distribution of ROLL"<<endl;
						break;
					case 2:
						outfile<<"the distribution of SHIFT"<<endl;
						break;
					case 3:
						outfile<<"the distribution of SLIDE"<<endl;
						break;
					case 4:
						outfile<<"the distribution of TILT"<<endl;
						break;
					case 5:
						outfile<<"the distribution of TWIST"<<endl;
						break;
				}
				outfile<<"******************************************************************"<<endl;
				//
				for(int m=0;m<size;m++)
				{
					for(int n=0;n<filesize;n++)
					{
						vect[m*filesize+n]=totaldata[i][m][n];
					}
				}
				//把二维的数据转化为一维的数据!
				
				Distribution(vect,size*filesize,output);
				outfile<<"******************************************************************"<<endl;
			}
		   cout<<"finished the calculation of distribution !"<<endl;
		   cout<<"the output write in the file "<<output<<" !"<<endl;
			outfile.close();
			free_f3tensor(totaldata,0,5,0,size-1,0,filesize-1);
			// finished the calculation !



		}

		if(choose=='J')
		{
			double ***totaldata;
			struct	Filelist *fl;
			struct Backbone *spt;
			int N=0;
			fl=Readlist(listfile);
			spt=J_part(fl->file);
			int filesize=Getfilelen(fl);	
			int size=GetBackbonelen(spt);
			if(segment!="all")
			{
				size=segment_e - segment_b+1;
			}
			if(segment=="all")
			{
				segment_b=1;
				segment_e=size;
			}
			totaldata=f3tensor(0,13,0,size-1,0,filesize-1);
			ofstream outfile(output.c_str(),ios::app);

			outfile<<"******************************************************************"<<endl;
		//output the input file!
			ifstream infile(inputfile);
			string s;
			getline(infile,s);
			 while(!infile.fail())
			{
				outfile<<"#"<<s<<endl;
				getline(infile,s);
			}
			 outfile<<TIME<<endl; //输出当前时间
			infile.close();
//

			while(fl!=NULL)
			{
				struct Backbone *sp;
				sp=J_part(fl->file);
		//		int size=GetBackbonelen(sp);
				double **data;
				data=dmatrix(0,13,0,size-1);
				struct Namelist *name;
				name=(struct Namelist *)malloc(sizeof(struct Namelist));
				Backbone2double(sp,data,name,segment_b,segment_e);

				for(int i=0;i<14;i++)
				{
					for(int j=0;j<size;j++)
					{
						totaldata[i][j][N]=data[i][j];
					}
				}
				free_dmatrix(data,0,13,0,size-1);
				cout<<"Read file "<<fl->file<<" finished!"<<endl;//输出提示
				fl=fl->next;
				N++;
			}

			double *vect;
			vect=dvector(0, size*filesize-1) ;  
			for(int i=0;i<14;i++)
			{
				outfile<<"******************************************************************"<<endl;
				switch(i)
				{
					case 0:
						outfile<<"the distribution of ALPHA"<<endl;
						break;
					case 1:
						outfile<<"the distribution of AMPLI"<<endl;
						break;
					case 2:
						outfile<<"the distribution of BETA"<<endl;
						break;
					case 3:
						outfile<<"the distribution of C1'"<<endl;
						break;
					case 4:
						outfile<<"the distribution of C1'-C2'"<<endl;
						break;
					case 5:
						outfile<<"the distribution of C2'"<<endl;
						break;
					case 6:
						outfile<<"the distribution of C2'-C3'"<<endl;
						break;
				    case 7:
						outfile<<"the distribution of C3'"<<endl;
						break;
					case 8:
						outfile<<"the distribution of CHI"<<endl;
						break;
					case 9:
						outfile<<"the distribution of DELTA"<<endl;
						break;
					case 10:
						outfile<<"the distribution of ESPIL"<<endl;
						break;
					case 11:
						outfile<<"the distribution of GAMMA"<<endl;
						break;
					case 12:
						outfile<<"the distribution of PHASE"<<endl;
						break;
					case 13:
						outfile<<"the distribution of ZETA"<<endl;
						break;
					}
				outfile<<"******************************************************************"<<endl;
				//
				for(int m=0;m<size;m++)
				{
					for(int n=0;n<filesize;n++)
					{
						vect[m*filesize+n]=totaldata[i][m][n];
					}
				}
				//把二维的数据转化为一维的数据!
				
				Distribution(vect,size*filesize,output);
				outfile<<"******************************************************************"<<endl;
			}
		   cout<<"finished the calculation of distribution !"<<endl;
		   cout<<"the output write in the file "<<output<<" !"<<endl;
			outfile.close();
			free_f3tensor(totaldata,0,13,0,size-1,0,filesize-1);
			// finished the calculation !
		}

	}
/*计算刚性*/
	
	if(operate=="stiffness")
	{
		/*get the data*/
		if(choose=='E'||choose=='F'||choose=='G'||choose=='H')
		{
			double ***totaldata;
			struct	Filelist *fl;
			struct Paramater *spt;
			int N=0;
			ofstream outfile(output.c_str(),ios::app);
			fl=Readlist(listfile);
			switch(choose)
			{
			case 'E':
				spt=E_part(fl->file);
				break;
			case 'F':
				spt=F_part(fl->file);
				break;
			case 'G':
				spt=G_part(fl->file);
				break;
			case 'H':
				spt=H_part(fl->file);
				break;
			}
			int filesize=Getfilelen(fl);	
			int size=GetParamaterlen(spt);
			if(segment!="all")
			{
				size=segment_e - segment_b+1;
			}
			if(segment=="all")
			{
				segment_b=1;
				segment_e=size;
			}
			totaldata=f3tensor(0,5,0,size-1,0,filesize-1);
			outfile<<"******************************************************************"<<endl;

			//output the input file!
			ifstream infile(inputfile);
			string s;
			 getline(infile,s);
			while(!infile.fail())
			{
				outfile<<"#"<<s<<endl;
				getline(infile,s);
			}
		    outfile<<TIME<<endl;  //输出当前时间
			infile.close();

//
			while(fl!=NULL)
			{
				struct Paramater *sp; 
				switch(choose)
				{
					case 'E':
						sp=E_part(fl->file);
					break;
					case 'F':
						sp=F_part(fl->file);
					break;
					case 'G':
						sp=G_part(fl->file);
					break;
					case 'H':
						sp=H_part(fl->file);
					break;
				}
		//		int size=GetParamaterlen(sp);
				double **data;
				data=dmatrix(0,5,0,size-1);
				struct Namelist *name;
				name=(struct Namelist *)malloc(sizeof(struct Namelist));
				Paramater2double(sp,data,name,segment_b,segment_e);

				for(int i=0;i<6;i++)
				{
					for(int j=0;j<size;j++)
					{
						totaldata[i][j][N]=data[i][j];
					}
				}
				free_dmatrix(data,0,5,0,size-1);
				cout<<"Read file "<<fl->file<<" finished!"<<endl;//输出提示
				fl=fl->next;
				N++;
			}
// finished the input data
			/*calculate the stiffness! */
			double **stiff;
			double **matrix;
			double **inve_matrix;

			/*output the title */
				outfile<<"******************************************************************"<<endl;
				outfile<<"calculate the stiffness of part "<<choose<<endl;
				outfile<<"******************************************************************"<<endl;
				
		for(int x=segment_b-1;x<segment_e;x++)   /* the loop for segment  */
		{
			stiff=dmatrix(0,5,0, filesize-1) ;  /* hold the space!*/
			matrix=dmatrix(0,5,0,5);
			inve_matrix=dmatrix(0,5,0,5);

			for(int i=0;i<6;i++)
			{
					for(int n=0;n<filesize;n++)
					{
						stiff[i][n]=totaldata[i][x][n];
					}			
			}

			Getmatrix(stiff,matrix,filesize);  /*cteate the helical matrix!*/
			free_dmatrix(stiff,0,5,0,filesize-1);
			inverse_matrix(matrix, inve_matrix,6);
			free_dmatrix(matrix,0,5,0,5);

			outfile<<"the stiffness of segment "<<x+1<<endl;
			outfile<<"******************************************************************"<<endl;
			outfile<<"\t"<<"rise"<<"\t"<<"roll"<<"\t"<<"shift"<<"\t"<<"slide"<<"\t"<<"tilt"<<"\t"<<"twist"<<endl;
			outfile<<fixed<<showpoint;
			for(int i=0;i<6;i++)
			{
				switch(i)
				{
				case 0:
					outfile<<"rise"<<"\t";
					break;
				case 1:
					outfile<<"roll"<<"\t";
					break;
				case 2:
					outfile<<"shift"<<"\t";
					break;
				case 3:
					outfile<<"slide"<<"\t";
					break;
				case 4:
					outfile<<"tilt"<<"\t";
					break;
				case 5:
					outfile<<"twist"<<"\t";
					break;
				}
				for(int j=0;j<6;j++)
				{
					outfile<<setprecision(2)<<R*temperature*inve_matrix[i][j]<<"\t";
				}
				outfile<<endl;
			}
			outfile<<"******************************************************************"<<endl;
		}
		cout<<"finished the calculation of stiffness !"<<endl;
		cout<<"the output write in the file "<<"\""<<output<<"\"  !"<<endl;
		outfile.close();
		free_f3tensor(totaldata,0,5,0,size-1,0,filesize-1);
			// finished the calculation !

		}
		else
		{
			cout<<"wrong input, please check!"<<endl;
			exit(0);
		}

	}


	if(operate!="stiffness"&&operate!="average"&&operate!="distribution")
	{
		cout<<"Input a wrong operate. the correct oprtate is 'average/distribution/stiffness'"<<endl;
		exit(0);
	}
	return 0;
}