Beispiel #1
0
void destroy_parameters(parameters *p) {
    if (strcmp(p->datafilename,"dummy"))
        free_imatrix(p->genetic_data,1,1);
    if (p->npopulations>1)
        free_ivector(p->location,1);
    p->samplesize=0;
}
Beispiel #2
0
/*
 * ASSEMBLE_K  -  assemble global stiffness matrix from individual elements 23feb94
 */
void assemble_K(
	double **K,
	int DoF, int nE,
	vec3 *xyz, float *r, double *L, double *Le,
	int *N1, int *N2,
	float *Ax, float *Asy, float *Asz,
	float *Jx, float *Iy, float *Iz,
	float *E, float *G, float *p,
	int shear, int geom, double **Q, int debug
){
	double	**k;		/* element stiffness matrix in global coord */
	int	**ind,		/* member-structure DoF index table	*/
		res=0,
		i, j, ii, jj, l, ll;
	char	stiffness_fn[FILENMAX];

	for (i=1; i<=DoF; i++)	for (j=1; j<=DoF; j++)	K[i][j] = 0.0;

	k   =  dmatrix(1,12,1,12);
	ind = imatrix(1,12,1,nE);


	for ( i=1; i<= nE; i++ ) {
		ind[1][i] = 6*N1[i] - 5;	ind[7][i]  = 6*N2[i] - 5;
		ind[2][i] = ind[1][i] + 1;	ind[8][i]  = ind[7][i] + 1;
		ind[3][i] = ind[1][i] + 2;	ind[9][i]  = ind[7][i] + 2;
		ind[4][i] = ind[1][i] + 3;	ind[10][i] = ind[7][i] + 3;
		ind[5][i] = ind[1][i] + 4;	ind[11][i] = ind[7][i] + 4;
		ind[6][i] = ind[1][i] + 5;	ind[12][i] = ind[7][i] + 5;
	}

	for ( i = 1; i <= nE; i++ ) {

		elastic_K ( k, xyz, r, L[i], Le[i], N1[i], N2[i],
		Ax[i],Asy[i],Asz[i], Jx[i],Iy[i],Iz[i], E[i],G[i], p[i], shear);

		if (geom)
		 geometric_K( k, xyz, r, L[i], Le[i], N1[i], N2[i],
		           Ax[i], Asy[i],Asz[i], 
                           Jx[i], Iy[i], Iz[i], 
                           E[i],G[i], p[i], -Q[i][1], shear);

		if (debug) {
			res = sprintf(stiffness_fn,"k_%03d",i);
			save_dmatrix(stiffness_fn,k,1,12,1,12,0, "w");
		}

		for ( l=1; l <= 12; l++ ) {
			ii = ind[l][i];
			for ( ll=1; ll <= 12; ll++ ) {
				jj = ind[ll][i];
				K[ii][jj] += k[l][ll];
			}
		}
	}
	free_dmatrix ( k,1,12,1,12);
	free_imatrix(ind,1,12,1,nE);
	return;
}
Beispiel #3
0
int free_triples_array(Triples_array * triples_array) {
    free_imatrix(triples_array->hhh_array); 
    free_imatrix(triples_array->hhs_array);
    free_imatrix(triples_array->hsh_array);
    free_imatrix(triples_array->hss_array);
    free_imatrix(triples_array->shh_array);
    free_imatrix(triples_array->ssh_array); 
    free_imatrix(triples_array->shs_array); 
    free_imatrix(triples_array->sss_array);
    return 0;
}
Beispiel #4
0
void free_results( RESULTS *strct )
/* free a RESULTS struct allocated with alloc_results() */
{
 free_ivector(strct->res_serr);
 free_ivector(strct->res_nskypix);
 free_dvector(strct->res_skyperpix);
 free_dvector(strct->res_skystddev);
 free_imatrix(strct->res_npix);
 free_dmatrix(strct->res_totalflux);
 free_dmatrix(strct->res_error);
 free_dvector(strct->res_radii);
 free_dmatrix(strct->res_apstddev);
 free_dmatrix(strct->res_fluxsec);
 free_dmatrix(strct->res_mag);
 free_dmatrix(strct->res_merr);
 return;
}
int in_group_entropy ( Alignment * alignment, int * similar_to, double **score){

    int group, col, seq, ctr, aa;
    int **freq, *norm; /* ASCII == 128,  ASCII size  */
    double p, entropy;

    if ( ! (freq=intmatrix(alignment->no_groups, ASCII)) ) return 1;
    if ( ! (norm=emalloc(alignment->no_groups*sizeof(int))) ) return 1;
    
    for (col = 0; col < alignment->length; col++){

	/* find frequencies */
	for (group=0;  group< alignment->no_groups; group++) {
	    memset (freq[group], 0, ASCII*sizeof(int));
	    norm[group] = 0;
	}
	
	for (seq=0; seq< alignment->number_of_seqs; seq++){
	    aa = (int) alignment->sequence[seq][col];
	    if ( aa == 'X' || aa == 'x' ) continue;
	    if (similar_to) aa=similar_to[aa];
	    group = alignment->belongs_to_group[seq];
 	    freq [group][aa]++;
	    norm [group] ++;
	}
	/* find entropy */
	for (group=0;  group< alignment->no_groups; group++) {
	    entropy = 0.0;
	    for ( ctr=0; ctr < ASCII; ctr++) {
		if ( freq[group][ctr] ) {
		    p = (double)freq[group][ctr]/norm[group];
		    entropy -= p*log(p);
		}
	    }
	    score[group][col] = entropy;
	}
    }

    free_imatrix (freq);
    free (norm);
    
    return 0;
}
int main(void)
{
	int i,j,**nmbr;
	float ccc,chisq,cramrv,df,prob;
	char dummy[MAXSTR],fate[NDAT+1][16],mon[NMON+1][6],txt[16];
	FILE *fp;

	nmbr=imatrix(1,NDAT,1,NMON);
	if ((fp = fopen("table1.dat","r")) == NULL)
		nrerror("Data file table1.dat not found\n");
	fgets(dummy,MAXSTR,fp);
	fgets(dummy,MAXSTR,fp);
	fscanf(fp,"%16c",txt);
	txt[15]='\0';
	for (i=1;i<=12;i++) fscanf(fp," %s",mon[i]);
	fgets(dummy,MAXSTR,fp);
	fgets(dummy,MAXSTR,fp);
	for (i=1;i<=NDAT;i++) {
		fscanf(fp,"%16[^0123456789]",fate[i]);
		fate[i][15]='\0';
		for (j=1;j<=12;j++)
			fscanf(fp,"%d ",&nmbr[i][j]);
	}
	fclose(fp);
	printf("\n%s",txt);
	for (i=1;i<=12;i++) printf("%5s",mon[i]);
	printf("\n\n");
	for (i=1;i<=NDAT;i++) {
		printf("%s",fate[i]);
		for (j=1;j<=12;j++) printf("%5d",nmbr[i][j]);
		printf("\n");
	}
	cntab1(nmbr,NDAT,NMON,&chisq,&df,&prob,&cramrv,&ccc);
	printf("\n%15s chi-squared       %20.2f\n"," ",chisq);
	printf("%15s degrees of freedom%20.2f\n"," ",df);
	printf("%15s probability       %20.4f\n"," ",prob);
	printf("%15s cramer-v          %20.4f\n"," ",cramrv);
	printf("%15s contingency coeff.%20.4f\n"," ",ccc);
	free_imatrix(nmbr,1,NDAT,1,NMON);
	return 0;
}
Beispiel #7
0
Datei: trexR.c Projekt: cran/trex
void trexR(int *threshold,  // input, threshold count of rare variants
	   int *tablevec,   // input, vector to fill 3x2 obsTable
	   double *chistatObs,
	   double *chi2sided,
	   double *chi1sided,
	   int *chistatSign,
	   double *fisher2sided,
	   double *fisher1sided,
	   int *fisherSign,
	   double *probExcluded)
{

  // DECLARE OBJECTS FOR INPUT AND OUTPUT FROM PROGRAM
  static int verbose=0;

  // PREPARE DATA FOR TREX DRIVER
  int nrow=3;
  int ncol=2;
  int **obsTable = imatrix(1,nrow, 1,ncol);
  if(!obsTable)
    errmsg("Memory allocation failure for obsTable\n");

  fillTable(tablevec, obsTable, nrow, ncol);


  // CALL TREX DRIVER 
  trexDriver(*threshold, obsTable, 
	     chistatObs, chi2sided, chi1sided, chistatSign, 
             fisher2sided, fisher1sided, fisherSign,
	     probExcluded, verbose);

  // CLEAN MEMORY AND RETURN
  free_imatrix(obsTable, 1, nrow, 1, ncol);
  
  return;

}
void delete_block_model(block_model_t *model)
{
    //printf("Clean Up After Model 0!\n");
	free_dvector(model->a);
	//printf("Clean Up After Model 1!\n");
	free_dvector(model->inva);
	free_dmatrix(model->b);
	free_dmatrix(model->c);

	free_dvector(model->gx);
	free_dvector(model->gy);
	free_dvector(model->gx_int);
	free_dvector(model->gy_int);
	free_dvector(model->gx_sp);
	//printf("Clean Up After Model 2!\n");
	free_dvector(model->gy_sp);
	free_dvector(model->gx_hs);
	//printf("Clean Up After Model 3!\n");
	free_dvector(model->gy_hs);
	free_dvector(model->g_amb);
	free_dvector(model->t_vector);
    //printf("Clean Up After Model 4!\n");
	//free_ivector(model->p);
	//printf("Clean Up After Model 5!\n");
	free_dmatrix(model->len);
	free_dmatrix(model->g);

	free_dmatrix(model->lu);
	free_imatrix(model->border);
    // added by me
    //free_flp(model->flp, FALSE);
    //model->
    //printf("Clean Up After Model 5!\n");
	free(model);

}
int find_best_triples_exhaustive_parallel(Representation* X_rep, Representation* Y_rep, int no_top_rmsd,
        double * best_rmsd, int ** best_triple_x, int ** best_triple_y,
        double **best_quat) {
    // initialization of global array of values
    no_top_rmsd = TOP_RMSD;
    // printf("%d\n", no_top_rmsd);

    // printf("proba %d %lf\n", X_rep->N_full, X_rep->cm[0][0]);

    double ** best_quat_array = dmatrix(no_top_rmsd * NUM_THREADS, 4);
    int ** best_triple_x_array = intmatrix(no_top_rmsd * NUM_THREADS, 3);
    int ** best_triple_y_array = intmatrix(no_top_rmsd * NUM_THREADS, 3);
    double * best_rmsd_array = (double *) malloc(no_top_rmsd * NUM_THREADS * sizeof (double));

    int cnt;

    for (cnt = 0; cnt < NUM_THREADS * no_top_rmsd; ++cnt) {
        best_rmsd_array[cnt] = BAD_RMSD + 1;
        best_triple_x_array[cnt][0] = -1;
    }

    omp_set_num_threads(NUM_THREADS);

#pragma omp parallel 

    {

        int top_ctr, i, j, k, l, n, m;
        int myid = omp_get_thread_num();

        double ** best_quat_local = dmatrix(no_top_rmsd, 4);
        int ** best_triple_x_local = intmatrix(no_top_rmsd, 3);
        int ** best_triple_y_local = intmatrix(no_top_rmsd, 3);
        double * best_rmsd_local = (double *) malloc(no_top_rmsd * sizeof (double));
        
        double **x = X_rep->full; // no change
        int * x_type = X_rep->full_type; // no change
        int NX = X_rep->N_full; // no change
        double **y = Y_rep->full;
        int * y_type = Y_rep->full_type;
        int NY = Y_rep->N_full;
        int x_triple[3], y_triple[3];
        int chunk;
        double cutoff_rmsd = 3.0; /* <<<<<<<<<<<<<<<<< hardcoded */
        double rmsd; // 
        double q_init[4] = {0.0}; // no change
        double ** cmx = X_rep->cm; // no change
        double ** cmy = Y_rep->cm; // no change
        double threshold_dist = THRESHOLD;

        /***************************************/
        /* find reasonable triples of SSEs      */
        /* that correspond in type             */
        /*  and can be mapped onto each other  */
        /***************************************/
        for (top_ctr = 0; top_ctr < no_top_rmsd; top_ctr++) {
            best_rmsd_local[top_ctr] = BAD_RMSD + 1;
            best_triple_x_local[top_ctr][0] = -1;
        }

        /*
         * Exhaustive search through a 6D space - ugly code
         * Parallelization 
         */


#pragma omp for       
        for (i = 0; i < NX; ++i) {
            for (j = 0; j < NY - 2; ++j) {
                if (x_type[i] != y_type[j]) continue;
                
                for (k = 0; k < NX; ++k) {
                    if (k == i) continue;
                    if (two_point_distance(cmx[i], cmx[k]) > THRESHOLD) continue;
                    
                    for (l = j + 1; l < NY - 1; ++l) {
                        if (x_type[k] != y_type[l]) continue; 
                        if (two_point_distance(cmy[j], cmy[l]) > THRESHOLD) continue;
                            
                        for (m = 0; m < NX; ++m) {
                            if (m == k || m == i) continue;
                                
                            if (two_point_distance(cmx[i], cmx[m]) > THRESHOLD) continue;
                            if (two_point_distance(cmx[k], cmx[m]) > THRESHOLD) continue;
                            
                            for (n = l + 1; n < NY; ++n) {
                                if (x_type[m] != y_type[n]) continue;
                                if (two_point_distance(cmy[j], cmy[n]) > THRESHOLD) continue;
                                if (two_point_distance(cmy[l], cmy[n]) > THRESHOLD) continue;
                                    
                                x_triple[0] = i;
                                y_triple[0] = j;
                                x_triple[1] = k;
                                y_triple[1] = l;
                                x_triple[2] = m;
                                y_triple[2] = n;

                                
                                
                                if (!same_hand_triple(X_rep, x_triple, Y_rep, y_triple, 3)) continue;
                                if (distance_of_nearest_approach(X_rep, x_triple,
                                        Y_rep, y_triple, 3, &rmsd))     continue;
                                if (rmsd > cutoff_rmsd)     continue;

                                //if (opt_quat(x, NX, x_triple, y, NY, y_triple, 3, q_init, &rmsd)) continue;

                                
                                
                                for (top_ctr = 0; top_ctr < no_top_rmsd; top_ctr++) {
                                    // insertion of a new values in arrays keeping arrays sorted

                                    if (rmsd <= best_rmsd_local[top_ctr]) {
                                        chunk = no_top_rmsd - top_ctr - 1;

                                        if (chunk) {
                                            memmove(best_rmsd_local + top_ctr + 1,
                                                    best_rmsd_local + top_ctr, chunk * sizeof(double));

                                            memmove(best_quat_local[top_ctr + 1],
                                                    best_quat_local[top_ctr], chunk * 4 * sizeof(double));

                                            memmove(best_triple_x_local[top_ctr + 1],
                                                    best_triple_x_local[top_ctr], chunk * 3 * sizeof (int));
                                            memmove(best_triple_y_local[top_ctr + 1],
                                                    best_triple_y_local[top_ctr], chunk * 3 * sizeof (int));
                                        }
                                        best_rmsd_local[top_ctr] = rmsd;

                                        memcpy(best_quat_local[top_ctr], q_init, 4 * sizeof (double));

                                        memcpy(best_triple_x_local[top_ctr], x_triple, 3 * sizeof (int));
                                        memcpy(best_triple_y_local[top_ctr], y_triple, 3 * sizeof (int));

                                        break;

                                    }
                                }
                                
                            }
                        }
                    }
                }
            }

            //           printf("%d\n", i);

            // each thread copies values to global arrays in accordance with its thread id
            //           printf("myid: %d\n", myid);

            memcpy(*(best_quat_array + myid * no_top_rmsd), *(best_quat_local), no_top_rmsd * 4 * sizeof (double));

            memcpy(*(best_triple_y_array + myid * no_top_rmsd), *(best_triple_y_local), no_top_rmsd * 3 * sizeof (int));
            memcpy(*(best_triple_x_array + myid * no_top_rmsd), *(best_triple_x_local), no_top_rmsd * 3 * sizeof (int));
            memcpy(best_rmsd_array + myid*no_top_rmsd, best_rmsd_local, no_top_rmsd * sizeof (double));

        }

        free_dmatrix(best_quat_local);
        free_imatrix(best_triple_x_local);
        free_imatrix(best_triple_y_local);
        free(best_rmsd_local);

        // parallel sort of elements of arrays 
        sortTriplets(best_triple_x_array, best_triple_y_array, best_rmsd_array, best_quat_array, no_top_rmsd);

    }


    // 
    /*
        memcpy(*best_quat, *best_quat_array, no_top_rmsd * 4 * sizeof(double));
     */
    memcpy(*best_triple_y, *best_triple_y_array, no_top_rmsd * 3 * sizeof (int));
    memcpy(*best_triple_x, *best_triple_x_array, no_top_rmsd * 3 * sizeof (int));
    memcpy(best_rmsd, best_rmsd_array, no_top_rmsd * sizeof (double));


    free_dmatrix(best_quat_array);
    free_imatrix(best_triple_x_array);
    free_imatrix(best_triple_y_array);
    free(best_rmsd_array);

    return 0;

}
Beispiel #10
0
void create_RC_matrices(flp_t *flp, int omit_lateral)
{
    int i, j, k = 0, n = flp->n_units;
    int **border;
    double **len, *gx, *gy, **g, *c_ver, **t, *gx_sp, *gy_sp;
    double r_sp1, r_sp2, r_hs;	/* lateral resistances to spreader and heatsink	*/

    /* NOTE: *_mid - the vertical R/C from CENTER nodes of spreader
     * and heatsink. *_per - the vertical R/C from PERIPHERAL (n,s,e,w) nodes
     */
    double r_sp_per, r_hs_mid, r_hs_per, c_sp_per, c_hs_mid, c_hs_per;
    double gn_sp=0, gs_sp=0, ge_sp=0, gw_sp=0;

    double w_chip = get_total_width (flp);	/* x-axis	*/
    double l_chip = get_total_height (flp);	/* y-axis	*/

    border = imatrix(n, 4);
    len = matrix(n, n);		/* len[i][j] = length of shared edge bet. i & j	*/
    gx = vector(n);			/* lumped conductances in x direction	*/
    gy = vector(n);			/* lumped conductances in y direction	*/
    gx_sp = vector(n);		/* lateral conductances in the spreader	layer */
    gy_sp = vector(n);
    g = matrix(NL*n+EXTRA, NL*n+EXTRA);	/* g[i][j] = conductance bet. nodes i & j */
    c_ver = vector(NL*n+EXTRA);	/* vertical capacitance	*/

    b = matrix(NL*n+EXTRA, NL*n+EXTRA);	/* B, C, INVA  and INVB are (NL*n+EXTRA)x(NL*n+EXTRA) matrices	*/
    c = matrix(NL*n+EXTRA, NL*n+EXTRA);
    inva = matrix(NL*n+EXTRA, NL*n+EXTRA);
    invb = matrix(NL*n+EXTRA, NL*n+EXTRA);
    t = matrix (NL*n+EXTRA, NL*n+EXTRA);	/* copy of B	*/

    /* compute the silicon fitting factor - see pg 10 of the UVA CS tech report - CS-TR-2003-08	*/
    factor_chip = C_FACTOR * ((SPEC_HEAT_INT / SPEC_HEAT_SI) * (w_chip + 0.88 * t_interface) \
                              * (l_chip + 0.88 * t_interface) * t_interface / ( w_chip * l_chip * t_chip) + 1);

    /* fitting factor for interface	 - same rationale as above */
    factor_int = C_FACTOR * ((SPEC_HEAT_CU / SPEC_HEAT_INT) * (w_chip + 0.88 * t_spreader) \
                             * (l_chip + 0.88 * t_spreader) * t_spreader / ( w_chip * l_chip * t_interface) + 1);

    /*printf("fitting factors : %lf, %lf\n", factor_chip, factor_int);	*/

    /* gx's and gy's of blocks	*/
    for (i = 0; i < n; i++) {
        /* at the silicon layer	*/
        if (omit_lateral) {
            gx[i] = gy[i] = 0;
        }
        else {
            gx[i] = 1.0/getr(K_SI, flp->units[i].height, flp->units[i].width, l_chip, t_chip);
            gy[i] = 1.0/getr(K_SI, flp->units[i].width, flp->units[i].height, w_chip, t_chip);
        }

        /* at the spreader layer	*/
        gx_sp[i] = 1.0/getr(K_CU, flp->units[i].height, flp->units[i].width, l_chip, t_spreader);
        gy_sp[i] = 1.0/getr(K_CU, flp->units[i].width, flp->units[i].height, w_chip, t_spreader);
    }

    /* shared lengths between blocks	*/
    for (i = 0; i < n; i++)
        for (j = i; j < n; j++)
            len[i][j] = len[j][i] = get_shared_len(flp, i, j);

    /* lateral R's of spreader and sink */
    r_sp1 = getr(K_CU, (s_spreader+3*w_chip)/4.0, (s_spreader-w_chip)/4.0, w_chip, t_spreader);
    r_sp2 = getr(K_CU, (3*s_spreader+w_chip)/4.0, (s_spreader-w_chip)/4.0, (s_spreader+3*w_chip)/4.0, t_spreader);
    r_hs = getr(K_CU, (s_sink+3*s_spreader)/4.0, (s_sink-s_spreader)/4.0, s_spreader, t_sink);

    /* vertical R's and C's of spreader and sink */
    r_sp_per = RHO_CU * t_spreader * 4.0 / (s_spreader * s_spreader - w_chip*l_chip);
    c_sp_per = factor_pack * SPEC_HEAT_CU * t_spreader * (s_spreader * s_spreader - w_chip*l_chip) / 4.0;
    r_hs_mid = RHO_CU * t_sink / (s_spreader*s_spreader);
    c_hs_mid = factor_pack * SPEC_HEAT_CU * t_sink * (s_spreader * s_spreader);
    r_hs_per = RHO_CU * t_sink * 4.0 / (s_sink * s_sink - s_spreader*s_spreader);
    c_hs_per = factor_pack * SPEC_HEAT_CU * t_sink * (s_sink * s_sink - s_spreader*s_spreader) / 4.0;

    /* short the R's from block centers to a particular chip edge	*/
    for (i = 0; i < n; i++) {
        if (eq(flp->units[i].bottomy + flp->units[i].height, l_chip)) {
            gn_sp += gy_sp[i];
            border[i][2] = 1;	/* block is on northern border 	*/
        }
        if (eq(flp->units[i].bottomy, 0)) {
            gs_sp += gy_sp[i];
            border[i][3] = 1;	/* block is on southern border	*/
        }
        if (eq(flp->units[i].leftx + flp->units[i].width, w_chip)) {
            ge_sp += gx_sp[i];
            border[i][1] = 1;	/* block is on eastern border	*/
        }
        if (eq(flp->units[i].leftx, 0)) {
            gw_sp += gx_sp[i];
            border[i][0] = 1;	/* block is on western border	*/
        }
    }

    /* overall R and C between nodes */
    for (i = 0; i < n; i++) {
        double area = (flp->units[i].height * flp->units[i].width);
        /*
         * amongst functional units	in the various layers
         * resistances in the interface layer are assumed
         * to be infinite
         */
        for (j = 0; j < n; j++) {
            double part = 0, part_sp = 0;
            if (is_horiz_adj(flp, i, j)) {
                part = gx[i] / flp->units[i].height;
                part_sp = gx_sp[i] / flp->units[i].height;
            }
            else if (is_vert_adj(flp, i,j))  {
                part = gy[i] / flp->units[i].width;
                part_sp = gy_sp[i] / flp->units[i].width;
            }
            g[i][j] = part * len[i][j];
            g[HSP*n+i][HSP*n+j] = part_sp * len[i][j];
        }

        /* vertical g's in the silicon layer	*/
        g[i][IFACE*n+i]=g[IFACE*n+i][i]=2.0/(RHO_SI * t_chip / area);
        /* vertical g's in the interface layer	*/
        g[IFACE*n+i][HSP*n+i]=g[HSP*n+i][IFACE*n+i]=2.0/(RHO_INT * t_interface / area);
        /* vertical g's in the spreader layer	*/
        g[HSP*n+i][NL*n+SP_B]=g[NL*n+SP_B][HSP*n+i]=2.0/(RHO_CU * t_spreader / area);

        /* C's from functional units to ground	*/
        c_ver[i] = factor_chip * SPEC_HEAT_SI * t_chip * area;
        /* C's from interface portion of the functional units to ground	*/
        c_ver[IFACE*n+i] = factor_int * SPEC_HEAT_INT * t_interface * area;
        /* C's from spreader portion of the functional units to ground	*/
        c_ver[HSP*n+i] = factor_pack * SPEC_HEAT_CU * t_spreader * area;

        /* lateral g's from block center (spreader layer) to peripheral (n,s,e,w) spreader nodes	*/
        g[HSP*n+i][NL*n+SP_N]=g[NL*n+SP_N][HSP*n+i]=2.0*border[i][2]/((1.0/gy_sp[i])+r_sp1*gn_sp/gy_sp[i]);
        g[HSP*n+i][NL*n+SP_S]=g[NL*n+SP_S][HSP*n+i]=2.0*border[i][3]/((1.0/gy_sp[i])+r_sp1*gs_sp/gy_sp[i]);
        g[HSP*n+i][NL*n+SP_E]=g[NL*n+SP_E][HSP*n+i]=2.0*border[i][1]/((1.0/gx_sp[i])+r_sp1*ge_sp/gx_sp[i]);
        g[HSP*n+i][NL*n+SP_W]=g[NL*n+SP_W][HSP*n+i]=2.0*border[i][0]/((1.0/gx_sp[i])+r_sp1*gw_sp/gx_sp[i]);
    }

    /* max slope (max_power * max_vertical_R / vertical RC time constant) for silicon	*/
    max_slope = MAX_PD / (factor_chip * t_chip * SPEC_HEAT_SI);

    /* vertical g's and C's between central nodes	*/
    /* between spreader bottom and sink bottom	*/
    g[NL*n+SINK_B][NL*n+SP_B]=g[NL*n+SP_B][NL*n+SINK_B]=2.0/r_hs_mid;
    /* from spreader bottom to ground	*/
    c_ver[NL*n+SP_B]=c_hs_mid;
    /* from sink bottom to ground	*/
    c_ver[NL*n+SINK_B] = factor_pack * c_convec;

    /* g's and C's from peripheral(n,s,e,w) nodes	*/
    for (i = 1; i <= 4; i++) {
        /* vertical g's between peripheral spreader nodes and spreader bottom */
        g[NL*n+SP_B-i][NL*n+SP_B]=g[NL*n+SP_B][NL*n+SP_B-i]=2.0/r_sp_per;
        /* lateral g's between peripheral spreader nodes and peripheral sink nodes	*/
        g[NL*n+SP_B-i][NL*n+SINK_B-i]=g[NL*n+SINK_B-i][NL*n+SP_B-i]=2.0/(r_hs + r_sp2);
        /* vertical g's between peripheral sink nodes and sink bottom	*/
        g[NL*n+SINK_B-i][NL*n+SINK_B]=g[NL*n+SINK_B][NL*n+SINK_B-i]=2.0/r_hs_per;
        /* from peripheral spreader nodes to ground	*/
        c_ver[NL*n+SP_B-i]=c_sp_per;
        /* from peripheral sink nodes to ground	*/
        c_ver[NL*n+SINK_B-i]=c_hs_per;
    }

    /* calculate matrices A, B such that A(dT) + BT = POWER */

    for (i = 0; i < NL*n+EXTRA; i++) {
        for (j = 0; j < NL*n+EXTRA; j++) {
            if (i==j) {
                inva[i][j] = 1.0/c_ver[i];
                if (i == NL*n+SINK_B)	/* sink bottom */
                    b[i][j] += 1.0 / r_convec;
                for (k = 0; k < NL*n+EXTRA; k++) {
                    if ((g[i][k]==0.0)||(g[k][i])==0.0)
                        continue;
                    else
                        /* here is why the 2.0 factor comes when calculating g[][]	*/
                        b[i][j] += 1.0/((1.0/g[i][k])+(1.0/g[k][i]));
                }
            } else {
                inva[i][j]=0.0;
                if ((g[i][j]==0.0)||(g[j][i])==0.0)
                    b[i][j]=0.0;
                else
                    b[i][j]=-1.0/((1.0/g[i][j])+(1.0/g[j][i]));
            }
        }
    }

    /* we are always going to use the eqn dT + A^-1 * B T = A^-1 * POWER. so, store  C = A^-1 * B	*/
    matmult(c, inva, b, NL*n+EXTRA);
    /* we will also be needing INVB so store it too	*/
    copy_matrix(t, b, NL*n+EXTRA, NL*n+EXTRA);
    matinv(invb, t, NL*n+EXTRA);
    /*	dump_vector(c_ver, NL*n+EXTRA);	*/
    /*	dump_matrix(g, NL*n+EXTRA, NL*n+EXTRA);	*/
    /*	dump_matrix(c, NL*n+EXTRA, NL*n+EXTRA);	*/

    /* cleanup */
    free_matrix(t, NL*n+EXTRA);
    free_matrix(g, NL*n+EXTRA);
    free_matrix(len, n);
    free_imatrix(border, n);
    free_vector(c_ver);
    free_vector(gx);
    free_vector(gy);
    free_vector(gx_sp);
    free_vector(gy_sp);
}
Beispiel #11
0
/*
 * Function to be called from Python
 */
static PyObject* py_smith_waterman_context(PyObject* self, PyObject* args)
{
    char *seq1 = NULL;
    char *seq2 = NULL;
    char retstr[100]   = {'\0'};
    int  len1, len2;
    int i, j;
    int gap_opening, gap_extension;
    static int ** similarity = NULL;
      
    
    PyArg_ParseTuple(args, "s#s#ii", &seq1, &len1, &seq2, &len2, &gap_opening, &gap_extension);


    if (!seq1 || !seq2) {
	sprintf (retstr, "no seq in py_smith_waterman_context");
	return Py_BuildValue("s", retstr);
    }

    /* passing a matrix this way is all to painful, so we'll elegantyly hardcode it: */
    if ( !similarity) {
	similarity = imatrix(ASCII_SIZE, ASCII_SIZE);
	if (!similarity) {
	    sprintf (retstr, "error alloc matrix space");
	    return Py_BuildValue("s", retstr);
	}
	load_sim_matrix (similarity);
	
    } 

    
    /**********************************************************************************/
    //int gap_opening   =  -5; // used in 15_make_maps
    //int gap_extension =  -3;
    //char gap_character = '-'
    //int gap_opening    =  -3;  // used in 25_db_migration/06_make_alignments
    //int gap_extension  =   0;
    char gap_character = '#';
    int endgap         =   0;
    int use_endgap     =   0;

    int far_away = -1;

    int max_i    = len1;
    int max_j    = len2;

    // allocation, initialization
    int  **F         = NULL;
    char **direction = NULL;
    int *map_i2j     = NULL;
    int *map_j2i     = NULL;

    if ( ! (F= imatrix (max_i+1, max_j+1)) ) {
	sprintf (retstr, "error alloc matrix space");
	return Py_BuildValue("s", retstr);
    }
    if ( ! (direction = cmatrix (max_i+1, max_j+1)) ) {
	sprintf (retstr, "error alloc matrix space");
	return Py_BuildValue("s", retstr);
    }
    if (! (map_i2j = emalloc( (max_i+1)*sizeof(int))) ) {
	sprintf (retstr, "error alloc matrix space");
	return Py_BuildValue("s", retstr);
    }
    if (! (map_j2i = emalloc( (max_j+1)*sizeof(int))) ) {
	sprintf (retstr, "error alloc matrix space");
	return Py_BuildValue("s", retstr);
    }
    for (i=0; i<=max_i; i++) map_i2j[i]=far_away;
    for (j=0; j<=max_j; j++) map_j2i[j]=far_away;

    
    int F_max   = far_away;
    int F_max_i = 0;
    int F_max_j = 0;
    int penalty = 0;
    int i_sim, j_sim, diag_sim, max_sim;
    
    int i_between_exons = 1;
    int j_between_exons = 1;
    //
    for (i=0; i<=max_i; i++) {

        if (i > 0) {
            if (seq1[i-1] == 'B') {
		i_between_exons = 0;
            } else if ( seq1[i-1] == 'Z'){
		i_between_exons = 1;
	    }
	}
	for (j=0; j<=max_j; j++) {

            if (j > 0) {
                if (seq2[j-1] == 'B') {
                    j_between_exons = 0;
		} else if (seq2[j-1] == 'Z') {
                    j_between_exons = 1;
		}
	    }
               
	    if ( !i && !j ){
		F[0][0] = 0;
		direction[i][j] = 'd';
		continue;
	    }
	    
	    if ( i && j ){

		/**********************************/
		penalty =  0;
		if ( direction[i-1][j] == 'i' ) {
		    //  gap extension
		    if  (j_between_exons) {
			penalty =  0;
                    } else {
			if (use_endgap && j==max_j){
                            penalty = endgap;
			} else {
                            penalty = gap_extension;
			}
		    }
                } else {
		    //  gap opening  */
		    if  (j_between_exons) {
			penalty =  0;
		    } else {
			if (use_endgap && j==max_j){
			    penalty = endgap;
			} else{
			    penalty = gap_opening;
			}
		    }
		}
                i_sim =  F[i-1][j] + penalty;
		
		/**********************************/
		penalty =  0;
		if ( direction[i][j-1] == 'j' ) {
		    //  gap extension
		    if (i_between_exons) {
			    penalty = 0;
		    } else {
                        if (use_endgap && i==max_i){
                            penalty = endgap;
                        } else{
                            penalty = gap_extension;
			}
		    }
		} else {
		    //  gap opening  */
		    if  (i_between_exons) {
			penalty =  0;
		    } else {
			if (use_endgap && i==max_i){
			    penalty = endgap;
			} else {
			    penalty = gap_opening;
			}
		    }

		}
		j_sim = F[i][j-1] + penalty;

		/**********************************/
		diag_sim =  F[i-1][j-1] + similarity [seq1[i-1]][seq2[j-1]];
		
		/**********************************/
		max_sim         = diag_sim;
		direction[i][j] = 'd';
		if ( i_sim > max_sim ){
		    max_sim = i_sim;
		    direction[i][j] = 'i';
		}
		if ( j_sim > max_sim ) {
		    max_sim = j_sim;
		    direction[i][j] = 'j';
		}
		

		
		
            } else if (j) {
		
		penalty =  0;
		if (j_between_exons) {
		    penalty = 0;
                } else {
		    if (use_endgap) {
			penalty = endgap;
                    } else {
			if ( direction[i][j-1] =='j' ) {
			    penalty = gap_extension;
                        } else {
			    penalty = gap_opening;
			}
		    }
		}
		j_sim   = F[i][j-1] + penalty;
		max_sim = j_sim;
		direction[i][j] = 'j';


            } else if (i) {
		
		penalty =  0;
		if (i_between_exons) {
		    penalty = 0;
                } else {
		    if ( use_endgap) {
			penalty = endgap;
                    } else {
			if ( direction[i-1][j] == 'i' ) {
			    penalty =  gap_extension;
                        } else {
			    penalty =  gap_opening;
			
			}
		    }
		}
		i_sim   = F[i-1][j] + penalty;
		max_sim = i_sim;
		direction[i][j] = 'i';
	    }
	    
	    if (max_sim < 0.0 ) max_sim = 0.0;
	    
	    F[i][j] = max_sim;
	    if ( F_max < max_sim ) {
		// TODO{ tie break here */
		F_max = max_sim;
		F_max_i = i;
		F_max_j = j;
	    }


	}
   }
		
		
	 
    i = F_max_i;
    j = F_max_j;
    // aln_score = F[i][j] ;


    while ( i>0 || j >0 ){

	if ( i<0 || j<0 ){
	    sprintf (retstr, "Retracing error");
	    return Py_BuildValue("s", retstr);
	}
	
        if (direction[i][j] == 'd'){
	    map_i2j [i-1] = j-1;
	    map_j2i [j-1] = i-1;
	    i-= 1;
	    j-= 1;
	} else if (direction[i][j] == 'i') {
	    map_i2j [i-1] = far_away;
	    i-= 1 ;
	   
	} else if (direction[i][j] == 'j') {
	    map_j2i [j-1] = far_away;
	    j-= 1 ;
	   
	} else{ 
  	    sprintf (retstr, "Retracing error");
	    return Py_BuildValue("s", retstr);
	}
    }
	
    char * aligned_seq_1 = NULL;
    char * aligned_seq_2 = NULL;

    /* (lets hope it gets properly freed in the main program */
    if (! (aligned_seq_1 = emalloc( (len1+len2)*sizeof(char))) ) {
	sprintf (retstr, "error alloc array space");
	return Py_BuildValue("s", retstr);
    }
    if (! (aligned_seq_2 = emalloc( (len1+len2)*sizeof(char))) ) {
	sprintf (retstr, "error alloc array space");
	return Py_BuildValue("s", retstr);
    }
    
    i = 0;
    j = 0;
    int done = 0;
    int pos  = 0;
    while (!done) {

        if (j>=max_j && i>=max_i){
            done = 1;
	} else if (j<max_j && i<max_i){

            if (map_i2j[i] == j){
                aligned_seq_1[pos] = seq1[i];
                aligned_seq_2[pos] = seq2[j];
                i += 1;
                j += 1;
	    } else if (map_i2j[i] < 0){
                aligned_seq_1[pos] = seq1[i];
                aligned_seq_2[pos] = gap_character;
                i += 1;
	    } else if (map_j2i[j] < 0){
                aligned_seq_1[pos] = gap_character;
                aligned_seq_2[pos] = seq2[j];
                j += 1;
	    }

	} else if (j<max_j){
	    aligned_seq_1[pos] = gap_character;
	    aligned_seq_2[pos] = seq2[j];
	    j += 1;
	} else {
            aligned_seq_1[pos] = seq1[i];
            aligned_seq_2[pos] = gap_character;
            i += 1;
	}
	pos ++;
    }
               
    free_imatrix(F);
    free_cmatrix(direction);
    free(map_i2j);
    free(map_j2i);
    
    return Py_BuildValue("ss", aligned_seq_1, aligned_seq_2 );
    
}
Beispiel #12
0
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);


}
Beispiel #13
0
void forward_shot_SH(struct waveAC *waveAC, struct PML_AC *PML_AC, struct matSH *matSH, float ** srcpos, int nshots, int ** recpos, int ntr, int nstage, int nfreq){

	/* declaration of global variables */
        extern int NSHOT1, NSHOT2, NONZERO, NX, NY, NXNY, NF;
        extern int SNAP, SEISMO, MYID, INFO, N_STREAMER, READ_REC;
        extern float DH;
        extern char SNAP_FILE[STRING_SIZE];
	extern FILE * FP;
    
        /* declaration of local variables */
        int ishot, status, nxsrc, nysrc, i;
    	double *null = (double *) NULL ;

	int     *Ap, *Ai;
	double  *Ax, *Az, *xr, *xi; 
	double  time1, time2;
        char filename[STRING_SIZE];
        void *Symbolic, *Numeric;

	/* Allocate memory for compressed sparse column form and solution vector */
	Ap = malloc(sizeof(int)*(NXNY+1));
	Ai = malloc(sizeof(int)*NONZERO);
	Ax = malloc(sizeof(double)*NONZERO);
	Az = malloc(sizeof(double)*NONZERO);
	xr = malloc(sizeof(double)*NONZERO);
	xi = malloc(sizeof(double)*NONZERO);

        /* assemble acoustic impedance matrix */
        init_A_SH_9p_pml(PML_AC,matSH,waveAC);

        /* convert triplet to compressed sparse column format */
        status = umfpack_zi_triplet_to_col(NXNY,NXNY,NONZERO,(*waveAC).irow,(*waveAC).icol,(*waveAC).Ar,(*waveAC).Ai,Ap,Ai,Ax,Az,NULL);

	/* Here is something buggy (*waveAC).Ar != Ax and (*waveAC).Ai != Az.
           Therefore, set  Ax = (*waveAC).Ar and Az = (*waveAC).Ai */
	for (i=0;i<NONZERO;i++){
	     Ax[i] = (*waveAC).Ar[i];
	     Az[i] = (*waveAC).Ai[i];
        }

	if((MYID==0)&&(INFO==1)){
	  printf("\n==================================== \n");
	  printf("\n *****  LU factorization **********  \n");
	  printf("\n==================================== \n\n");
	  time1=MPI_Wtime(); 
	}

        /* symbolic factorization */
	status = umfpack_zi_symbolic(NXNY, NXNY, Ap, Ai, Ax, Az, &Symbolic, null, null);

        /* sparse LU decomposition */
	status = umfpack_zi_numeric(Ap, Ai, Ax, Az, Symbolic, &Numeric, null, null);
        umfpack_zi_free_symbolic (&Symbolic);

	if((MYID==0)&&(INFO==1)){
	  time2=MPI_Wtime();
	  printf("\n Finished after %4.2f s \n",time2-time1);
	}

	if((MYID==0)&&(INFO==1)){
	  printf("\n============================================================================================================= \n");
	  printf("\n *****  Solve elastic SH forward problem by FDFD for shot %d - %d (f = %3.2f Hz) on MPI process no. %d **********  \n",NSHOT1,NSHOT2-1,(*waveAC).freq, MYID);
	  printf("\n============================================================================================================= \n\n");				
	  time1=MPI_Wtime(); 
	}

        /* loop over all shots */
	for (ishot=NSHOT1;ishot<NSHOT2;ishot++){

		/* read receiver positions from receiver files for each shot */
		if(READ_REC==1){
		    acq.recpos=receiver(FP, &ntr, 1);			                         
      		}

                /* define source vector RHS */
                RHS_source_AC(waveAC,srcpos,ishot);

                /* solve forward problem by forward and back substitution */
    		status = umfpack_zi_solve(UMFPACK_A, Ap, Ai, Ax, Az, xr, xi, (*waveAC).RHSr, (*waveAC).RHSi, Numeric, null, null);

		/* convert vector xr/xi to pr/pi */
		vec2mat((*waveAC).pr,(*waveAC).pi,xr,xi);

		/* write real part of pressure wavefield to file */
		if(SNAP==1){
		   sprintf(filename,"%s_shot_%d.p",SNAP_FILE,ishot);
		   /* writemod(filename,(*waveAC).pr,3); */
		   writemod_true(filename,(*waveAC).pr,3);
		}

		/* write FD seismogram files */
		if(SEISMO==1){		   
		   calc_seis_AC(waveAC,acq.recpos,ntr,ishot,nshots,nfreq);
		}

		if(READ_REC==1){
		   free_imatrix(acq.recpos,1,3,1,ntr);
		   ntr=0;
 		}

	}

	if((MYID==0)&&(INFO==1)){
	  time2=MPI_Wtime();
	  printf("\n Finished after %4.2f s \n",time2-time1);
	}
         	    
	/* free memory */
    	free(Ap); free(Ai); free(Ax); free(Az); free(xr); free(xi); 

	umfpack_zi_free_numeric (&Numeric);	

}
Beispiel #14
0
/* "calc_blessian_mem" calculates the block Hessian. */
int calc_blessian_mem(PDB_File *PDB,dSparse_Matrix *PP1,int nres,int nblx,
		      int elm,double **HB,double cut,double gam,double scl,
		      double mlo,double mhi)
{
  dSparse_Matrix *PP2;
  double **HR,***HT;
  int **CT,*BST1,*BST2;
  int ii,i,j,k,p,q,q1,q2,ti,tj,bi,bj,sb,nc,out;


  /* ------------------- INITIALIZE LOCAL VARIABLES ------------------- */

  /* HR holde three rows (corresponding to 1 residue) of the full Hessian */
  HR=zero_dmatrix(1,3*nres,1,3);

  /* CT is an array of contacts between blocks */
  CT=unit_imatrix(0,nblx);

  /* Copy PP1 to PP2 and sort by second element */
  PP2=(dSparse_Matrix *)malloc((size_t)sizeof(dSparse_Matrix));
  PP2->IDX=imatrix(1,elm,1,2);
  PP2->X=dvector(1,elm);
  copy_dsparse(PP1,PP2,1,elm);
  dsort_PP2(PP2,elm,2);

  /* BST1: for all j: BST1[i]<=j<BST[i+1], PP1->IDX[j][1]=i */
  /* BST2: for all j: BST2[i]<=j<BST2[i+1], PP2->IDX[j][2]=i */
  BST1=ivector(1,3*nres+1);
  BST2=ivector(1,6*nblx+1);
  init_bst(BST1,PP1,elm,3*nres+1,1);
  init_bst(BST2,PP2,elm,6*nblx+1,2);
  /* ------------------- LOCAL VARIABLES INITIALIZED ------------------ */



  /* ------------- FIND WHICH BLOCKS ARE IN CONTACT --------------- */
  nc=find_contacts1(CT,PDB,nres,nblx,cut);


  /* Allocate a tensor for the block Hessian */
  HT=zero_d3tensor(1,nc,1,6,1,6);


  /* Calculate each super-row of the full Hessian */
  for(ii=1;ii<=nres;ii++){

    if(PDB->atom[ii].model!=0){

      /* ----------------- FIND SUPER-ROW OF FULL HESSIAN --------------- */
      hess_superrow_mem(HR,CT,PDB,nres,ii,cut,gam,scl,mlo,mhi);


      /* Update elements of block hessian */
      q1=BST1[3*(ii-1)+2];
      q2=BST1[3*(ii-1)+3];
      /* Sum over elements of projection matrix corresponding to residue ii:
	 for each k in the following loop, PP1->IDX[k][1]==3*ii + 0,1,2 */
      for(k=BST1[3*ii-2];k<BST1[3*ii+1];k++){
	if(k<q1) q=1;
	else if(k<q2) q=2;
	else q=3;
	i=PP1->IDX[k][2];
	bi=(i-1)/6+1;
	ti=i-6*(bi-1);
	/* Sum over all elements of projection matrix with column j>=i */
	for(p=BST2[i];p<=elm;p++){
	  j=PP2->IDX[p][2];
	  bj=(j-1)/6+1;
	  sb=CT[bi][bj];
	  if(i<=j && sb!=0){  /* the first condition should ALWAYS hold */
	    tj=j-6*(bj-1);
	    HT[sb][ti][tj]+=(PP1->X[k]*PP2->X[p]*HR[PP2->IDX[p][1]][q]);
	  }
	}
      }
    }
  }


  /* Print the block Hessian in sparse format */
  out=bless_from_tensor(HB,HT,CT,nblx);

  /* Free up memory */
  free_dmatrix(HR,1,3*nres,1,3);
  free_d3tensor(HT,1,nc,1,6,1,6);
  free_imatrix(CT,0,nblx,0,nblx);
  free_ivector(BST1,1,3*nres+1);
  free_ivector(BST2,1,6*nblx+1);
  free_imatrix(PP2->IDX,1,elm,1,2);
  free_dvector(PP2->X,1,elm);
  return out;
}
Beispiel #15
0
int main(int argn, char** args){
 	if (argn !=2 ) {
        	printf("When running the simulation, please give a valid scenario file name!\n");
        	return 1;
        }
	//set the scenario
	char *filename = NULL;
	filename = args[1];

	//initialize variables
	double t = 0; /*time start*/
	int it, n = 0; /*iteration and time step counter*/
	double res; /*residual for SOR*/
		/*arrays*/
	double **U, **V, **P;
	double **RS, **F, **G;
	int **Flag; //additional data structure for arbitrary geometry
		/*those to be read in from the input file*/
	double Re, UI, VI, PI, GX, GY, t_end, xlength, ylength, dt, dx, dy, alpha, omg, tau, eps, dt_value;
	int  imax, jmax, itermax;

	double presLeft, presRight, presDelta; //for pressure stuff
	int wl, wr, wt, wb;
	char problem[32];
	double vel; //in case of a given inflow or wall velocity

	//read the parameters, using problem.dat, including wl, wr, wt, wb
	read_parameters(filename, &Re, &UI, &VI, &PI, &GX, &GY, &t_end, &xlength, &ylength, &dt, &dx, &dy, &imax,
			&jmax, &alpha, &omg, &tau, &itermax, &eps, &dt_value, &wl, &wr, &wt, &wb, problem, &presLeft, &presRight, &presDelta, &vel);

	int pics = dt_value/dt; //just a helping variable for outputing vtk


	//allocate memory, including Flag
	U = matrix(0, imax+1, 0, jmax+1);
	V = matrix(0, imax+1, 0, jmax+1);
	P = matrix(0, imax+1, 0, jmax+1);
	RS = matrix(1, imax, 1, jmax);
	F = matrix(0, imax, 1, jmax);
	G = matrix(1, imax, 0, jmax);
	Flag = imatrix(0, imax+1, 0, jmax+1); // or Flag = imatrix(1, imax, 1, jmax);

	int kmax = 20; //test no slip boundary value function
	double ***U3d  = (double ***) malloc((size_t)((imax+1)*(jmax+1)*(kmax+1) * sizeof(double*)) ); //test no slip boundary value function
	double ***V3d  = (double ***) malloc((size_t)((imax+1)*(jmax+1)*(kmax+1) * sizeof(double*)) ); //test no slip boundary value function
	double ***W3d  = (double ***) malloc((size_t)((imax+1)*(jmax+1)*(kmax+1) * sizeof(double*)) ); //test no slip boundary value function
	int ***Flag3d  = (int ***) malloc((size_t)((imax+1)*(jmax+1)*(kmax+1) * sizeof(int*)) ); //test no slip boundary value function

	//initialisation, including **Flag
	init_flag(problem, imax, jmax, presDelta, Flag);
	init_uvp(UI, VI, PI, imax, jmax, U, V, P, problem);

	//going through all time steps
	while(t < t_end){
		//adaptive time stepping
		calculate_dt(Re, tau, &dt, dx, dy, imax, jmax, U, V);
		
		//setting bound.values
		boundaryvalues(imax, jmax, U, V, P, wl, wr, wt, wb, F, G, problem, Flag, vel); //including P, wl, wr, wt, wb, F, G, problem

                //test no slip boundary value function
                for(int i=1; i<=imax; i++){
                        for(int j=1; j<=jmax; j++){
                                for(int k=1; k<=kmax; k++){
                                        boundaryvalues_no_slip(i, j, k, U3d, V3d, W3d, Flag3d); //test no slip boundary value function
                                }
                        }
		}
		
		//computing F, G and right hand side of pressue eq.
		calculate_fg(Re, GX, GY, alpha, dt, dx, dy, imax, jmax, U, V, F, G, Flag);
		calculate_rs(dt, dx, dy, imax, jmax, F, G, RS);
		
		//iteration counter
		it = 0;
		
		do{
			//
			//perform SOR iteration, at same time set bound.values for P and new residual value
			sor(omg, dx, dy, imax, jmax, P, RS, &res, Flag, presLeft, presRight);

			it++;
		}while(it<itermax && res>eps);
/*		if (it == itermax) {
			printf("Warning: sor while loop exits because it reaches the itermax. res = %f, time =%f\n", res, t);
		}
*/		//calculate U and V of this time step
		calculate_uv(dt, dx, dy, imax, jmax, U, V, F, G, P, Flag);
		
		//indent time and number of time steps
		n++;
		t += dt;
		
		//output of pics for animation
		if (n%pics==0 ){
			write_vtkFile(filename, n, xlength, ylength, imax, jmax, dx, dy, U, V, P);
		}
	}
	//output of U, V, P at the end for visualization
	//write_vtkFile("DrivenCavity", n, xlength, ylength, imax, jmax, dx, dy, U, V, P);

	//free memory
	free_matrix(U, 0, imax+1, 0, jmax+1);
	free_matrix(V, 0, imax+1, 0, jmax+1);
	free_matrix(P, 0, imax+1, 0, jmax+1);
	free_matrix(RS, 1, imax, 1, jmax);
	free_matrix(F, 0, imax, 1, jmax);
	free_matrix(G, 1, imax, 0, jmax);
	free_imatrix(Flag, 0, imax+1, 0, jmax+1);

	free(U3d);
	free(V3d);
	free(W3d);
	free(Flag3d);
	return -1;
}
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);


}
void initialiseFields( double *collideField, double *streamField, int *flagField, int * xlength, int *local_xlength, char *problem, char* pgmInput, int rank, int iProc, int jProc, int kProc )
{
    int iCoord, jCoord, kCoord, x, y, z, i;
#ifdef _ARBITRARYGEOMETRIES_
    int** pgmImage;
#endif // _ARBITRARYGEOMETRY_
    computePosition(iProc, jProc, kProc, &iCoord, &jCoord, &kCoord);
#ifdef _ARBITRARYGEOMETRIES_
    #pragma omp parallel private(x, y, z, i) shared(iCoord, jCoord, kCoord, collideField, flagField, streamField, xlength, problem, pgmInput, pgmImage, local_xlength, iProc, jProc, kProc)
#else
    #pragma omp parallel private(x, y, z, i) shared(iCoord, jCoord, kCoord, collideField, flagField, streamField, xlength, local_xlength, iProc, jProc, kProc)
#endif // _ARBITRARYGEOMETRY_
    {
        #pragma omp for schedule(static)
        for(x = 0; x < (local_xlength[0] + 2) * (local_xlength[1] + 2) * (local_xlength[2] + 2); x++)
        {
            flagField[x] = FLUID;
            for(i = 0; i < PARAMQ; i++)
                collideField[PARAMQ * x + i] = streamField[PARAMQ * x + i] = LATTICEWEIGHTS[i];
        }

        // independend of the problem first initialize all ghost cells as PARALLEL_BOUNDARY
        /* top boundary */
        #pragma omp for nowait schedule(static)
        for (z = 0; z <= local_xlength[2] + 1; z++)
            for (x = 0; x <= local_xlength[0] + 1; x++)
                flagField[z * (local_xlength[0] + 2) * (local_xlength[1] + 2) + (local_xlength[1] + 1) * (local_xlength[0] + 2) + x] = PARALLEL_BOUNDARY;

        /* back boundary */
        #pragma omp for nowait schedule(static)
        for (y = 0; y <= local_xlength[1] + 1; y++)
            for (x = 0; x <= local_xlength[0] + 1; x++)
                flagField[y * (local_xlength[0] + 2) + x] = PARALLEL_BOUNDARY;

        /* bottom boundary */
        #pragma omp for nowait schedule(static)
        for (z = 0; z <= local_xlength[2] + 1; z++)
            for (x = 0; x <= local_xlength[0] + 1; x++)
                flagField[z * (local_xlength[0] + 2) * (local_xlength[1] + 2) + x] = PARALLEL_BOUNDARY;

        /* left boundary */
        #pragma omp for nowait schedule(static)
        for (z = 0; z <= local_xlength[2] + 1; z++)
            for (y = 0; y <= local_xlength[1] + 1; y++)
                flagField[z * (local_xlength[0] + 2) * (local_xlength[1] + 2) + y * (local_xlength[0] + 2)] = PARALLEL_BOUNDARY;

        /* right boundary */
        #pragma omp for nowait schedule(static)
        for (z = 0; z <= local_xlength[2] + 1; z++)
            for (y = 0; y <= local_xlength[1] + 1; y++)
                flagField[z * (local_xlength[0] + 2) * (local_xlength[1] + 2) + y * (local_xlength[0] + 2) + local_xlength[0] + 1] = PARALLEL_BOUNDARY;

        /* front boundary, i.e. z = local_xlength + 1 */
        #pragma omp for schedule(static)
        for (y = 0; y <= local_xlength[1] + 1; y++)
            for (x = 0; x <= local_xlength[0] + 1; x++)
                flagField[(local_xlength[2] + 1) * (local_xlength[0] + 2) * (local_xlength[1] + 2) + y * (local_xlength[0] + 2) + x] = PARALLEL_BOUNDARY;

        /** initialization of different scenarios */
#ifdef _ARBITRARYGEOMETRIES_
        if (!strcmp(problem, "drivenCavity"))
        {
#endif // _ARBITRARYGEOMETRY_
            /* front boundary, i.e. z = local_xlength + 1 */
            if (kCoord == kProc - 1)
            {
                #pragma omp for nowait schedule(static)
                for (y = 0; y <= local_xlength[1] + 1; y++)
                    for (x = 0; x <= local_xlength[0] + 1; x++)
                        flagField[(local_xlength[2] + 1) * (local_xlength[0] + 2) * (local_xlength[1] + 2) + y * (local_xlength[0] + 2) + x] = NO_SLIP;
            }

            /* back boundary */
            if (kCoord == 0)
            {
                #pragma omp for schedule(static)
                for (y = 0; y <= local_xlength[1] + 1; y++)
                    for (x = 0; x <= local_xlength[0] + 1; x++)
                        flagField[y * (local_xlength[0] + 2) + x] = NO_SLIP;
            }

            /* left boundary */
            if (iCoord == 0)
            {
                #pragma omp for nowait schedule(static)
                for (z = 0; z <= local_xlength[2] + 1; z++)
                    for (y = 0; y <= local_xlength[1] + 1; y++)
                        flagField[z * (local_xlength[0] + 2) * (local_xlength[1] + 2) + y * (local_xlength[0] + 2)] = NO_SLIP;
            }
            /* right boundary */
            if (iCoord == iProc - 1)
            {
                #pragma omp for schedule(static)
                for (z = 0; z <= local_xlength[2] + 1; z++)
                    for (y = 0; y <= local_xlength[1] + 1; y++)
                        flagField[z * (local_xlength[0] + 2) * (local_xlength[1] + 2) + y * (local_xlength[0] + 2) + local_xlength[0] + 1] = NO_SLIP;
            }
            /* bottom boundary */
            if (jCoord == 0)
            {
                #pragma omp for nowait schedule(static)
                for (z = 0; z <= local_xlength[2] + 1; z++)
                    for (x = 0; x <= local_xlength[0] + 1; x++)

                        flagField[z * (local_xlength[0] + 2) * (local_xlength[1] + 2) + x] = NO_SLIP;
            }

            /* top boundary */
            if (jCoord == jProc - 1)
            {
                #pragma omp for nowait schedule(static)
                for (z = 0; z <= local_xlength[2] + 1; z++)
                    for (x = 0; x <= local_xlength[0] + 1; x++)
                        flagField[z * (local_xlength[0] + 2) * (local_xlength[1] + 2) + (local_xlength[1] + 1) * (local_xlength[0] + 2) + x] = MOVING_WALL;
            }
#ifdef _ARBITRARYGEOMETRIES_
        }
        if (!strcmp(problem, "tiltedPlate"))
        {
            #pragma omp single
            {
                pgmImage = read_pgm(pgmInput);
            }
            #pragma omp for nowait schedule(static)
            for (z = 1; z <= local_xlength[2]; z++)
                for (y = 1; y <= local_xlength[1]; y++)
                    for (x = 1; x <= local_xlength[0]; x++)
                        flagField[z * (local_xlength[0] + 2) * (local_xlength[1] + 2) + y * (local_xlength[0] + 2) + x] = !!pgmImage[(xlength[0] / iProc) * iCoord + x][(xlength[1] / jProc) * jCoord + y];


            /* front boundary, i.e. z = local_xlength + 1 */
            if (kCoord == kProc - 1)
                #pragma omp for nowait schedule(static)
                for (y = 0; y <= local_xlength[1] + 1; y++)
                    for (x = 0; x <= local_xlength[0] + 1; x++)
                    {
                        // check for obstacle in the cell in the inner part of the domain adjacent to the boundary (i.e. NO_SLIP)
                        // if there is an obstacle, make the boundary NO_SLIP instead of FREE_SLIP as well
                        if (pgmImage[(xlength[0] / iProc) * iCoord + x][(xlength[1] / jProc) * jCoord + y])
                            flagField[(local_xlength[2] + 1) * (local_xlength[0] + 2) * (local_xlength[1] + 2) + y * (local_xlength[0] + 2) + x] = NO_SLIP;
                        else
                            flagField[(local_xlength[2] + 1) * (local_xlength[0] + 2) * (local_xlength[1] + 2) + y * (local_xlength[0] + 2) + x] = FREE_SLIP;
                    }

            /* back boundary */
            if (kCoord == 0)
                #pragma omp for schedule(static)
                for (y = 0; y <= local_xlength[1] + 1; y++)
                    for (x = 0; x <= local_xlength[0] + 1; x++)
                    {
                        // check for obstacle in the cell in the inner part of the domain adjacent to the boundary
                        // if there is an obstacle, make the boundary NO_SLIP instead of FREE_SLIP as well
                        if (pgmImage[(xlength[0] / iProc) * iCoord + x][(xlength[1] / jProc) * jCoord + y])
                            flagField[y * (local_xlength[0] + 2) + x] = NO_SLIP;
                        else
                            flagField[y * (local_xlength[0] + 2) + x] = FREE_SLIP;
                    }


            /* left boundary */
            if (iCoord == 0)
                #pragma omp for nowait schedule(static)
                for (z = 0; z <= local_xlength[2] + 1; z++)
                    for (y = 0; y <= local_xlength[1] + 1; y++)
                        flagField[z * (local_xlength[0] + 2) * (local_xlength[1] + 2) + y * (local_xlength[0] + 2)] = INFLOW;

            /* right boundary */
            if (iCoord == iProc - 1)
                #pragma omp for schedule(static)
                for (z = 0; z <= local_xlength[2] + 1; z++)
                    for (y = 0; y <= local_xlength[1] + 1; y++)
                        flagField[z * (local_xlength[0] + 2) * (local_xlength[1] + 2) + y * (local_xlength[0] + 2) + local_xlength[0] + 1] = OUTFLOW;


            /* top boundary */
            if (jCoord == jProc - 1)
                #pragma omp for nowait schedule(static)
                for (z = 0; z <= local_xlength[2] + 1; z++)
                    for (x = 0; x <= local_xlength[0] + 1; x++)
                        flagField[z * (local_xlength[0] + 2) * (local_xlength[1] + 2) + (local_xlength[1] + 1) * (local_xlength[0] + 2) + x] = NO_SLIP;

            /* bottom boundary */
            if (jCoord == 0)
                #pragma omp for schedule(static)
                for (z = 0; z <= local_xlength[2] + 1; z++)
                    for (x = 0; x <= local_xlength[0] + 1; x++)
                        flagField[z * (local_xlength[0] + 2) * (local_xlength[1] + 2) + x] = NO_SLIP;


            // Adjust PARALLEL_BOUNDARY if the "adjacent" cell in the domain of the neighbouring process is an obstacle cell
            /* top boundary */
            #pragma omp for nowait schedule(static)
            for (z = 0; z <= local_xlength[2] + 1; z++)
                for (x = 0; x <= local_xlength[0] + 1; x++)
                    if (flagField[z * (local_xlength[0] + 2) * (local_xlength[1] + 2) + (local_xlength[1] + 1) * (local_xlength[0] + 2) + x] == PARALLEL_BOUNDARY && pgmImage[(xlength[0] / iProc) * iCoord + x][(xlength[1] / jProc) * (jCoord + 1) +  1])
                        flagField[z * (local_xlength[0] + 2) * (local_xlength[1] + 2) + (local_xlength[1] + 1) * (local_xlength[0] + 2) + x] = NO_SLIP;

            /* bottom boundary */
            #pragma omp for schedule(static)
            for (z = 0; z <= local_xlength[2] + 1; z++)
                for (x = 0; x <= local_xlength[0] + 1; x++)
                    if (flagField[z * (local_xlength[0] + 2) * (local_xlength[1] + 2) + x] == PARALLEL_BOUNDARY && pgmImage[(xlength[0] / iProc) * iCoord + x][(xlength[1] / jProc) * jCoord])
                        flagField[z * (local_xlength[0] + 2) * (local_xlength[1] + 2) + x] = NO_SLIP;

            /* left boundary */
            #pragma omp for nowait schedule(static)
            for (z = 0; z <= local_xlength[2] + 1; z++)
                for (y = 0; y <= local_xlength[1] + 1; y++)
                    if (flagField[z * (local_xlength[0] + 2) * (local_xlength[1] + 2) + y * (local_xlength[0] + 2)] == PARALLEL_BOUNDARY && pgmImage[(xlength[0] / iProc) * iCoord][(xlength[1] / jProc) * jCoord + y])
                        flagField[z * (local_xlength[0] + 2) * (local_xlength[1] + 2) + y * (local_xlength[0] + 2)] = NO_SLIP;

            /* right boundary */
            #pragma omp for schedule(static)
            for (z = 0; z <= local_xlength[2] + 1; z++)
                for (y = 0; y <= local_xlength[1] + 1; y++)
                    if (flagField[z * (local_xlength[0] + 2) * (local_xlength[1] + 2) + y * (local_xlength[0] + 2) + local_xlength[0] + 1] == PARALLEL_BOUNDARY && pgmImage[(xlength[0] / iProc) * (iCoord + 1) + 1][(xlength[1] / jProc) * jCoord + y])
                        flagField[z * (local_xlength[0] + 2) * (local_xlength[1] + 2) + y * (local_xlength[0] + 2) + local_xlength[0] + 1] = NO_SLIP;
            #pragma omp single
            {
                free_imatrix(pgmImage, 0, xlength[0] + 2, 0, xlength[1] + 2);
            }
        }
        if (!strcmp(problem, "flowStep"))
        {
            /* front boundary, i.e. z = local_xlength + 1 */
            if (kCoord == kProc - 1)
                #pragma omp for schedule(static)
                for (y = 0; y <= local_xlength[1] + 1; y++)
                    for (x = 0; x <= local_xlength[0] + 1; x++)
                        flagField[(local_xlength[2] + 1) * (local_xlength[0] + 2) * (local_xlength[1] + 2) + y * (local_xlength[0] + 2) + x] = NO_SLIP;

            /* back boundary */
            if (kCoord == 0)
                #pragma omp for schedule(static)
                for (y = 0; y <= local_xlength[1] + 1; y++)
                    for (x = 0; x <= local_xlength[0] + 1; x++)
                        flagField[y * (local_xlength[0] + 2) + x] = NO_SLIP;

            /* left boundary */
            if (iCoord == 0)
                #pragma omp for schedule(static)
                for (z = 0; z <= local_xlength[2] + 1; z++)
                    for (y = 0; y <= local_xlength[1] + 1; y++)
                        flagField[z * (local_xlength[0] + 2) * (local_xlength[1] + 2) + y * (local_xlength[0] + 2)] = INFLOW;

            /* right boundary */
            if (iCoord == iProc - 1)
                #pragma omp for schedule(static)
                for (z = 0; z <= local_xlength[2] + 1; z++)
                    for (y = 0; y <= local_xlength[1] + 1; y++)
                        flagField[z * (local_xlength[0] + 2) * (local_xlength[1] + 2) + y * (local_xlength[0] + 2) + local_xlength[0] + 1] = OUTFLOW;

            /* top boundary */
            if (jCoord == jProc - 1)
                #pragma omp for schedule(static)
                for (z = 0; z <= local_xlength[2] + 1; z++)
                    for (x = 0; x <= local_xlength[0] + 1; x++)
                        flagField[z * (local_xlength[0] + 2) * (local_xlength[1] + 2) + (local_xlength[1] + 1) * (local_xlength[0] + 2) + x] = NO_SLIP;

            /* bottom boundary */
            if (jCoord == 0)
                #pragma omp for schedule(static)
                for (z = 0; z <= local_xlength[2] + 1; z++)
                    for (x = 0; x <= local_xlength[0] + 1; x++)
                        flagField[z * (local_xlength[0] + 2) * (local_xlength[1] + 2) + x] = NO_SLIP;


            /* step */
            // step height & width: jProc * local_xlength[1] / 2
            #pragma omp for schedule(static)
            for (z = 0; z <= local_xlength[2] + 1; z++)
                for (y = 1; y <= min(xlength[1] / 2 - jCoord * (xlength[1] / jProc), local_xlength[1] ) ; y++) /* integer division on purpose, half of the channel is blocked by step */
                    for (x = 1; x <= min(xlength[1] / 2 - iCoord * (xlength[0] / iProc), local_xlength[0] ); x++)
                        flagField[z * (local_xlength[0] + 2) * (local_xlength[1] + 2) + y * (local_xlength[0] + 2) + x] = NO_SLIP;

            // adjust the PARALLEL_BOUNDARY where "adjacent" cells in the neighbouring domain are NO_SLIP
            /* top boundary */
            #pragma omp for schedule(static)
            for (z = 0; z <= local_xlength[2] + 1; z++)
                for (x = 0; x <= local_xlength[0] + 1; x++)
                    if (x <= xlength[1] / 2 - iCoord * (xlength[0] / iProc) && xlength[1] / 2 - (jCoord + 1) * (xlength[1] / jProc) >= 1 && flagField[z * (local_xlength[0] + 2) * (local_xlength[1] + 2) + (local_xlength[1] + 1) * (local_xlength[0] + 2) + x] == PARALLEL_BOUNDARY)
                        flagField[z * (local_xlength[0] + 2) * (local_xlength[1] + 2) + (local_xlength[1] + 1) * (local_xlength[0] + 2) + x] = NO_SLIP;


            /* bottom boundary */
            #pragma omp for schedule(static)
            for (z = 0; z <= local_xlength[2] + 1; z++)
                for (x = 0; x <= local_xlength[0] + 1; x++)
                    if( x <= xlength[1] / 2 - iCoord * (xlength[0] / iProc) && 0 <= xlength[1] / 2 - jCoord * (xlength[1] / jProc) && flagField[z * (local_xlength[0] + 2) * (local_xlength[1] + 2) + x] == PARALLEL_BOUNDARY)
                        flagField[z * (local_xlength[0] + 2) * (local_xlength[1] + 2) + x] = NO_SLIP;

            /* left boundary */
            #pragma omp for schedule(static)
            for (z = 0; z <= local_xlength[2] + 1; z++)
                for (y = 0; y <= local_xlength[1] + 1; y++)
                    if( 0 <= xlength[1] / 2 - iCoord * (xlength[0] / iProc) && y <= xlength[1] / 2 - jCoord * (xlength[1] / jProc)  && flagField[z * (local_xlength[0] + 2) * (local_xlength[1] + 2) + y * (local_xlength[0] + 2)] == PARALLEL_BOUNDARY)
                        flagField[z * (local_xlength[0] + 2) * (local_xlength[1] + 2) + y * (local_xlength[0] + 2)] = NO_SLIP;

            /* right boundary */
            #pragma omp for schedule(static)
            for (z = 0; z <= local_xlength[2] + 1; z++)
                for (y = 0; y <= local_xlength[1] + 1; y++)
                    if( 1 <= xlength[1] / 2 - (iCoord + 1) * (xlength[0] / iProc) && y <= xlength[1] / 2 - jCoord * (xlength[1] / jProc)  && flagField[z * (local_xlength[0] + 2) * (local_xlength[1] + 2) + y * (local_xlength[0] + 2) + local_xlength[0] + 1] == PARALLEL_BOUNDARY)
                        flagField[z * (local_xlength[0] + 2) * (local_xlength[1] + 2) + y * (local_xlength[0] + 2) + local_xlength[0] + 1] = NO_SLIP;
        }
        if (!strcmp(problem, "planeShearFlow"))
        {

            /* front boundary, i.e. z = xlength + 1 */
            if (kCoord == kProc - 1)
                #pragma omp for schedule(static)
                for (y = 0; y <= local_xlength[1] + 1; y++)
                    for (x = 0; x <= local_xlength[0] + 1; x++)
                        flagField[(local_xlength[2] + 1) * (local_xlength[0] + 2) * (local_xlength[1] + 2) + y * (local_xlength[0] + 2) + x] = FREE_SLIP;

            /* back boundary */
            if (kCoord == 0)
                #pragma omp for schedule(static)
                for (y = 0; y <= local_xlength[1] + 1; y++)
                    for (x = 0; x <= local_xlength[0] + 1; x++)
                        flagField[y * (local_xlength[0] + 2) + x] = FREE_SLIP;

            /* left boundary */
            if (iCoord == 0)
                #pragma omp for schedule(static)
                for (z = 0; z <= local_xlength[2] + 1; z++)
                    for (y = 0; y <= local_xlength[1] + 1; y++)
                        flagField[z * (local_xlength[0] + 2) * (local_xlength[1] + 2) + y * (local_xlength[0] + 2)] = PRESSURE_IN;

            /* right boundary */
            if (iCoord == iProc - 1)
                #pragma omp for schedule(static)
                for (z = 0; z <= local_xlength[2] + 1; z++)
                    for (y = 0; y <= local_xlength[1] + 1; y++)
                        flagField[z * (local_xlength[0] + 2) * (local_xlength[1] + 2) + y * (local_xlength[0] + 2) + local_xlength[0] + 1] = OUTFLOW;

            /* top boundary */
            if (jCoord == jProc - 1)
                #pragma omp for schedule(static)
                for (z = 0; z <= local_xlength[2] + 1; z++)
                    for (x = 0; x <= local_xlength[0] + 1; x++)
                        flagField[z * (local_xlength[0] + 2) * (local_xlength[1] + 2) + (local_xlength[1] + 1) * (local_xlength[0] + 2) + x] = NO_SLIP;

            /* bottom boundary */
            if (jCoord == 0)
                #pragma omp for schedule(static)
                for (z = 0; z <= local_xlength[2] + 1; z++)
                    for (x = 0; x <= local_xlength[0] + 1; x++)
                        flagField[z * (local_xlength[0] + 2) * (local_xlength[1] + 2) + x] = NO_SLIP;
        }
#endif // _ARBITRARYGEOMETRY_
    } // end of parallel region

    /** debugging code: checking the flagField */
#ifdef DEBUG
    int * exactFlagField;
    exactFlagField = (int *) malloc( (size_t) sizeof( int ) * (xlength[0] + 2) *  (xlength[1] + 2) * (xlength[2] + 2));
    FILE *fp2 = NULL;
    unsigned int line2 = 0;
    int noOfReadEntries;
    int error2 = 0;
    char szFileName2[80];
    computePosition(iProc, jProc, kProc, &iCoord, &jCoord, &kCoord);
    sprintf( szFileName2, "Testdata/%s/flagField.dat", problem );
    fp2 = fopen(szFileName2,"r");
    if (fp2 != NULL)
    {
        for (line2 = 0; line2 < (xlength[0] + 2) *  (xlength[1] + 2) * (xlength[2] + 2); line2++)
        {
            noOfReadEntries = fscanf(fp2,"%d",&exactFlagField[line2]);
            if (noOfReadEntries != 1)
                continue;
        }

    }
    fclose(fp2);
    for (z = 1; z <= local_xlength[2]; z++)
        for (y = 1; y <= local_xlength[1]; y++)
            for(x = 1; x <= local_xlength[0]; x++)
                for (i = 0; i < PARAMQ; i++)
                    if (flagField[(z * (local_xlength[0] + 2) * (local_xlength[1] + 2) + y * (local_xlength[0] + 2) + x)] != exactFlagField[((z + kCoord * (xlength[2] / kProc)) * (xlength[0] + 2) * (xlength[1] + 2) + (y + jCoord * (xlength[1] / jProc)) * (xlength[0] + 2) + (x + iCoord * (xlength[0] / iProc)))])
                        error2 = 1;
    if (error2)
        printf("ERROR: Process %d has a different flagField at inner nodes.\n",rank);

    error2 = 0;
    // Check global boundaries as well
    if (iCoord == 0)
    {
        // Left boundary
        x = 0;
        for (z = 0; z <= local_xlength[2] + 1; z++)
            for (y = 0; y <= local_xlength[1] + 1; y++)
                if (flagField[(z * (local_xlength[0] + 2) * (local_xlength[1] + 2) + y * (local_xlength[0] + 2) + x)] != exactFlagField[((z + kCoord * (xlength[2] / kProc)) * (xlength[0] + 2) * (xlength[1] + 2) + (y + jCoord * (xlength[1] / jProc)) * (xlength[0] + 2) + (x + iCoord * (xlength[0] / iProc)))])
                    error2 = 1;

    }
    if (iCoord == iProc - 1)
    {
        // Right boundary
        x = local_xlength[0] + 1;
        for (z = 0; z <= local_xlength[2] + 1; z++)
            for (y = 0; y <= local_xlength[1] + 1; y++)
                if (flagField[(z * (local_xlength[0] + 2) * (local_xlength[1] + 2) + y * (local_xlength[0] + 2) + x)] != exactFlagField[((z + kCoord * (xlength[2] / kProc)) * (xlength[0] + 2) * (xlength[1] + 2) + (y + jCoord * (xlength[1] / jProc)) * (xlength[0] + 2) + (x + iCoord * (xlength[0] / iProc)))])
                    error2 = 1;
    }
    if (jCoord == 0)
    {
        // Bottom boundary
        y = 0;
        for (z = 0; z <= local_xlength[2] + 1; z++)
            for (x = 0; x <= local_xlength[0] + 1; x++)
                if (flagField[(z * (local_xlength[0] + 2) * (local_xlength[1] + 2) + y * (local_xlength[0] + 2) + x)] != exactFlagField[((z + kCoord * (xlength[2] / kProc)) * (xlength[0] + 2) * (xlength[1] + 2) + (y + jCoord * (xlength[1] / jProc)) * (xlength[0] + 2) + (x + iCoord * (xlength[0] / iProc)))])
                    error2 = 1;

    }
    if (jCoord == jProc - 1)
    {
        // Top boundary
        y = local_xlength[1] + 1;
        for (z = 0; z <= local_xlength[2] + 1; z++)
            for (x = 0; x <= local_xlength[0] + 1; x++)
                if (flagField[(z * (local_xlength[0] + 2) * (local_xlength[1] + 2) + y * (local_xlength[0] + 2) + x)] != exactFlagField[((z + kCoord * (xlength[2] / kProc)) * (xlength[0] + 2) * (xlength[1] + 2) + (y + jCoord * (xlength[1] / jProc)) * (xlength[0] + 2) + (x + iCoord * (xlength[0] / iProc)))])
                    error2 = 1;
    }
    if (kCoord == 0)
    {
        // back boundary
        z = 0;
        for (y = 0; y <= local_xlength[1] + 1; y++)
            for (x = 0; x <= local_xlength[0] + 1; x++)
                if (flagField[(z * (local_xlength[0] + 2) * (local_xlength[1] + 2) + y * (local_xlength[0] + 2) + x)] != exactFlagField[((z + kCoord * (xlength[2] / kProc)) * (xlength[0] + 2) * (xlength[1] + 2) + (y + jCoord * (xlength[1] / jProc)) * (xlength[0] + 2) + (x + iCoord * (xlength[0] / iProc)))])
                    error2 = 1;

    }
    if (kCoord == kProc - 1)
    {
        // front boundary
        z = local_xlength[2] + 1;
        for (y = 0; y <= local_xlength[1] + 1; y++)
            for (x = 0; x <= local_xlength[0] + 1; x++)
                if (flagField[(z * (local_xlength[0] + 2) * (local_xlength[1] + 2) + y * (local_xlength[0] + 2) + x)] != exactFlagField[((z + kCoord * (xlength[2] / kProc)) * (xlength[0] + 2) * (xlength[1] + 2) + (y + jCoord * (xlength[1] / jProc)) * (xlength[0] + 2) + (x + iCoord * (xlength[0] / iProc)))])
                    error2 = 1;
    }

    if (error2)
        printf("ERROR: Process %d has a different flagField at global boundary.\n",rank);
    free(exactFlagField);
#endif
    /** debugging code end */
}
Beispiel #18
0
int main(int argc,char *argv[])
{
  Centroid *SYS,*ENV;
  Sprngmtx *Gamma;
  char *sysfile,*envfile,*massfile,*ctfile,*spgfile;
  double **GG;
  double *CUT,**HS,**HE,**HX,**PH,*P;
  double dd,x,y;
  int **CT,**PIX,nss,nen,nn,ntp,nse,r1,c1,r2,c2,i,j,k;
  int ptmd,rprm,pprm;


  /* Formalities */
  read_command_line(argc,argv,&pprm,&rprm,&ptmd,&MSCL);


  /* Read coordinate and mass data */
  sysfile=get_param(argv[pprm],"syscoords");
  envfile=get_param(argv[pprm],"envcoords");
  massfile=get_param(argv[pprm],"massfile");
  SYS=read_centroids1(sysfile,massfile,&nss);
  ENV=read_centroids1(envfile,massfile,&nen);
  nn=nss+nen;
  fprintf(stderr,"System read from %s: %d centroids\n",sysfile,nss);
  fprintf(stderr,"Environment read from %s: %d centroids\n",envfile,nen);
  fprintf(stderr,"Masses read from %s\n",massfile);
  CT=imatrix(1,nn,1,nn);


  /* Find extent of membrane */
  membounds(ENV,nen,&MHI,&MLO);


  /* Print masses, if called for */
  if(ptmd==2){
    for(i=1;i<=nss;i++)
      for(j=-2;j<=0;j++){
	k=3*i+j;
	printf("%8d%8d% 25.15e\n",k,k,SYS[i].mass);
      }
    for(i=1;i<=nen;i++)
      for(j=-2;j<=0;j++){
	k=3*nss+3*i+j;
	printf("%8d%8d% 25.15e\n",k,k,ENV[i].mass);
      }
    return 0;
  }


  /* ---------------- Assign contacts... ----------------- */
  /* From a contact file... */
  if((ctfile=get_param(argv[pprm],"contactfile"))!=NULL){
    read_contacts(ctfile,CT,nn);
    fprintf(stderr,"Contacts read from %s\n",ctfile);
  }
  /* ...or from a cutoff file... */
  else if((ctfile=get_param(argv[pprm],"cutfile"))!=NULL){
    fprintf(stderr,"Cutoff values read from %s\n",ctfile);
    CUT=read_cutfile2(ctfile,SYS,ENV,nss,nen);
    radius_contact_sysenv(CT,SYS,ENV,nss,nen,CUT);
  }
  /* ...or from default values */
  else{
    CUT=dvector(1,nn);
    for(i=1;i<=nn;i++) CUT[i]=DEFCUT;
    fprintf(stderr,"All cutoff values set to %.3f\n",DEFCUT);
    radius_contact_sysenv(CT,SYS,ENV,nss,nen,CUT);
  }
  fprintf(stderr,"%d clusters\n",num_clusters(CT,nn));

  if(ptmd==1){
    fprintf(stderr,"Printing contacts\n");
    for(i=1;i<=nn;i++)
      for(j=i+1;j<=nn;j++)
	if(CT[i][j]!=0)
	  printf("%d\t%d\n",i,j);
    return 0;
  }

    



  /* ------- Construct the matrix of force constants -------*/
  GG=dmatrix(1,nn,1,nn);
  
  /* Read force constants from file... */
  if((spgfile=get_param(argv[pprm],"springfile"))!=NULL){
    fprintf(stderr,"Reading spring constants from %s\n",spgfile);
    Gamma=read_springfile_sysenv(spgfile,SYS,ENV,nss,nen,&ntp);
    spring_constants_sysenv(SYS,ENV,GG,CT,Gamma,nss,nen,ntp);
  }
  /* ...or else assign the default value to all springs */
  else
    for(i=1;i<=nn;i++)
      for(j=i;j<=nn;j++)
	if(CT[i][j]!=0)
	  GG[i][j]=GG[j][i]=DEFGAM;



  /* Construct the mass-weighted Hessian from 
     coordinates, masses, and potential matrix */
  fprintf(stderr,"Calculating Hessian...\n");
  HS=dmatrix(1,3*nss,1,3*nss);
  HE=dmatrix(1,3*nen,1,3*nen);
  HX=dmatrix(1,3*nss,1,3*nen);
  mwhess_sysenv(HS,HE,HX,SYS,ENV,GG,nss,nen);
      


  /* PRINT THE ENVIRONMENT-ENVIRONMENT SUB-HESSIAN IN SPARSE FORMAT */
  if(ptmd==0 && rprm==-1){
    fprintf(stderr,"\nPrinting env-env sub-hessian...\n\n");
    for(i=1;i<=3*nen;i++)
      for(j=i;j<=3*nen;j++)
	if(fabs(HE[i][j])>1.0e-10)
	  printf("%8d%8d% 25.15e\n",i,j,HE[i][j]);
    return 0;
  }


  /* PRINT THE FULL HESSIAN IN SPARSE FORMAT */
  if(ptmd==3){
    for(i=1;i<=3*nss;i++){
      for(j=i;j<=3*nss;j++)
	if(fabs(HS[i][j])>1.0e-10)
	  printf("%8d%8d% 20.10e\n",i,j,HS[i][j]);
      for(j=1;j<=3*nen;j++)
	if(fabs(HX[i][j])>1.0e-10)
	  printf("%8d%8d% 20.10e\n",i,j+3*nss,HX[i][j]);
    }
    for(i=1;i<=3*nen;i++)
      for(j=i;j<=3*nen;j++)
	if(fabs(HE[i][j])>1.0e-10)
	  printf("%8d%8d% 20.10e\n",i+3*nss,j+3*nss,HE[i][j]);
    return 0;
  }


  /* READ INVERSE OF ENVIRONMENTAL HESSIAN, OR INVERT HE */
  free_imatrix(CT,1,nn,1,nn);
  free_dmatrix(GG,1,nn,1,nn);
  if(rprm!=-1){
    fprintf(stderr,"Reading matrix from %s...\n",argv[rprm]);
    read_sparsemtx(argv[rprm],HE,3*nen,3*nen);
  }
  else{
    fprintf(stderr,"\nWell...How did I get here?\n\n");
    exit(1);}


  /* ---------------- CALCULATE AND PRINT THE PSEUDOHESSIAN ---------------- */

  /* COUNT THE NUMBER OF NON-ZERO TERMS IN THE PROJECTION MATRIX */
  nse=0;
  for(i=1;i<=3*nss;i++)
    for(j=1;j<=3*nen;j++)
      if(fabs(HX[i][j])>1.0e-9) nse++;
  fprintf(stderr,"%d non-zero projection elements\n",nse);
  P=dvector(1,nse);
  PIX=imatrix(1,nse,1,2);
  k=1;
  for(i=1;i<=3*nss;i++)
    for(j=1;j<=3*nen;j++)
      if(fabs(HX[i][j])>1.0e-9){
	PIX[k][1]=i;
	PIX[k][2]=j;
	P[k]=HX[i][j];
	k++;
      }
  free_dmatrix(HX,1,3*nss,1,3*nen);
  PH=dmatrix(1,3*nss,1,3*nss);
  for(i=1;i<=3*nss;i++)
    for(j=i;j<=3*nss;j++)
      PH[i][j]=PH[j][i]=0.0;
  for(i=1;i<=nse;i++){
    r1=PIX[i][1];
    c1=PIX[i][2];
    x=P[i];
    for(j=i;j<=nse;j++){
      r2=PIX[j][1];
      c2=PIX[j][2];
      y=HE[c1][c2]*P[j]*x;
      PH[r1][r2]+=y;
      if(r1==r2 && c1!=c2)
	PH[r1][r2]+=y;
    }
  }

  for(i=1;i<=3*nss;i++)
    for(j=i;j<=3*nss;j++){
      dd=HS[i][j]-PH[i][j];
      if(fabs(dd)>1.0e-10)
	printf("%8d%8d% 25.15e\n",i,j,dd);
    }
  return 0;
}
Beispiel #19
0
char getNodeSign (uint mode, uint treeID, Node *nodePtr, uint *bmIndex, uint repMembrSize) {
  int   *mvNSptr;
  int   *fmvNSptr;
  char result;
  uint i,p,q,m;
  result = TRUE;
  switch (mode) {
  case RF_PRED:
    if (RF_mRecordSize > 0) {
      stackMPSign(nodePtr, RF_mpIndexSize);
      mvNSptr = nodePtr -> mpSign;
    }
    else {
      mvNSptr = NULL;
    }
    if (RF_fmRecordSize > 0) {
      stackFMPSign(nodePtr, RF_fmpIndexSize);
      fmvNSptr = nodePtr -> fmpSign;
    }
    else {
      fmvNSptr = NULL;
    }
    break;
  default:
    if (RF_mRecordSize > 0) {
      stackMPSign(nodePtr, RF_mpIndexSize);
      mvNSptr = nodePtr -> mpSign;
    }
    else {
      mvNSptr = NULL;
    }
    fmvNSptr = NULL;
    break;
  }  
  if (mvNSptr != NULL) {
    int **mvBootstrapSign = imatrix(1, RF_mpIndexSize, 1, repMembrSize);
    for (p = 1; p <= RF_mpIndexSize; p++) {
      for (i = 1; i <= repMembrSize; i++) {
        mvBootstrapSign[p][i] = 0;
      }
    }
    for (p = 1; p <= RF_mpIndexSize; p++) {
      mvNSptr[p] = 0;
    }
    for (i=1; i <= repMembrSize; i++) {
      m = bmIndex[i];
      if (RF_mRecordMap[m] != 0) {
        for (p = 1; p <= RF_mpIndexSize; p++) {
          if (RF_mpIndex[p] < 0) {
            mvBootstrapSign[p][i] = RF_mpSign[(uint) abs(RF_mpIndex[p])][RF_mRecordMap[m]];
          }
          else {
            mvBootstrapSign[p][i] = RF_mpSign[RF_rSize + (uint) RF_mpIndex[p]][RF_mRecordMap[m]];
          }
        }
      }
      else {
        for (p = 1; p <= RF_mpIndexSize; p++) {
          mvBootstrapSign[p][i] = 0;
        }
      }
      for (p = 1; p <= RF_mpIndexSize; p++) {
        mvNSptr[p] = mvNSptr[p] + mvBootstrapSign[p][i];
      }
    }
    m = 0;
    for (p = 1; p <= RF_mpIndexSize; p++) {
      if (mvNSptr[p] > 0) {
        if (mvNSptr[p] == repMembrSize) {
          mvNSptr[p] = -1;
        }
        else {
          mvNSptr[p] = 1;
        }
      }
      if(RF_mpIndex[p] < 0) {
        if (mvNSptr[p] == -1) result = FALSE;
      }
      else {
        if (mvNSptr[p] == -1) m ++;
      }
    }  
    if (m == RF_mpIndexSize) {
      result = FALSE;
    }
    free_imatrix(mvBootstrapSign, 1, RF_mpIndexSize, 1, repMembrSize);
  }
  if (fmvNSptr != NULL) {
    for (p = 1; p <= RF_fmpIndexSize; p++) {
      fmvNSptr[p] = 1;
    }
    if (RF_mRecordSize > 0) {
      p = q = 1;
      while ((p <= RF_mpIndexSize) && (q <= RF_fmpIndexSize)) {
        if (RF_mpIndex[p] == RF_fmpIndex[q]) {
          if (mvNSptr[p] == -1) {
            fmvNSptr[q] = -1;
          }
          p++;
          q++;
        }
        else if (RF_fmpIndex[q] < 0) {
          if (RF_mpIndex[p] > 0) {
            q++;
          }
          else {
            if (abs(RF_fmpIndex[q]) < abs(RF_mpIndex[p])) {
              q++;
            }
            else {
              p++;
            }
          }
        }
        else {
          if (RF_fmpIndex[q] < RF_mpIndex[p]) {
            q++;
          }
          else {
            p++;
          }
        }
      }  
    }  
  }  
  return result;
}
Beispiel #20
0
static Gdinfo *ReadGridFile(FileList *f) {
    register int  i,j,k;
    char     buf[BUFSIZ];
    int      nel,npt,nbnd,vid,vid1,eid,eid1,**bndpts,trip;
    Gdinfo   *ginfo = (Gdinfo *)malloc(sizeof(Gdinfo));
    Cinfo    *con,*c,*c1;
    FILE     *fp = f->in.fp;

    /* read boundary condition file */
    if(f->mesh.name) ReadBcond(f->mesh.fp,ginfo);



    fgets(buf,BUFSIZ,fp);
    fgets(buf,BUFSIZ,fp);

    sscanf(buf,"%d%d%d%*d",&nel,&npt,&nbnd);
    ginfo->nel     = nel;
    ginfo->npt     = npt;
    ginfo->nbnd    = nbnd;
    ginfo->elmtpts = imatrix(0,nel-1,0,2);
    ginfo->x       = dvector(0,npt-1);
    ginfo->y       = dvector(0,npt-1);
    bndpts         = imatrix(0,nel-1,0,2);

    ginfo->elmtcon    = (Cinfo**)malloc(nel*sizeof(Cinfo *));
    ginfo->elmtcon[0] = (Cinfo *)calloc(3*nel,sizeof(Cinfo) );

    for(k = 1; k < nel; ++k) ginfo->elmtcon[k] = ginfo->elmtcon[k-1]+3;

    con = (Cinfo *)calloc(npt,sizeof(Cinfo));

    /* read element vertex co-ordinate indices */
    fgets(buf,BUFSIZ,fp);
    for(k = 0; k < nel; ++k) {
        fgets (buf,BUFSIZ,fp);
        sscanf(buf,"%*d%d%d%d",ginfo->elmtpts[k],
               ginfo->elmtpts[k]+1,ginfo->elmtpts[k]+2);
    }

    /* read co-ordinates */
    fgets(buf,BUFSIZ,fp);
    for(k = 0; k < npt; ++k) {
        fgets (buf,BUFSIZ,fp);
        sscanf(buf,"%*d%lf%lf",ginfo->x+k,ginfo->y+k);
    }

    /* read boundary info */
    fgets(buf,BUFSIZ,fp);
    for(k = 0; k < nbnd; ++k) {
        fgets (buf,BUFSIZ,fp);
        sscanf(buf,"%d%d%*d%d",bndpts[k],bndpts[k]+1,bndpts[k]+2);
    }

    /* sort out connectivity */
    /* get list of all elements at a vertex */
    for(k = 0; k < nel; ++k)
        for(i = 0; i < 3; ++i)
            addcon(con+ginfo->elmtpts[k][i]-1,k+1,i);

    /* search through element list and fill out element connectivity */
    for(i = 0; i < npt; ++i) {
        for(c = con[i].next; c; c = c->next) {
            vid = (c->vsid+1)%3;
            eid =  c->elmtid;
            for(c1 = con[i].next; c1; c1 = c1->next) {
                vid1 = (c1->vsid+2)%3;
                eid1 =  c1->elmtid;
                if(ginfo->elmtpts[eid-1][vid] == ginfo->elmtpts[eid1-1][vid1]) {
                    ginfo->elmtcon[eid -1][c->vsid].type   = 'E';
                    ginfo->elmtcon[eid -1][c->vsid].elmtid = eid1;
                    ginfo->elmtcon[eid -1][c->vsid].vsid   = vid1;
                    ginfo->elmtcon[eid1-1][vid1   ].type   = 'E';
                    ginfo->elmtcon[eid1-1][vid1   ].elmtid = eid;
                    ginfo->elmtcon[eid1-1][vid1   ].vsid   = c->vsid;
                }
            }
        }
    }

    /* check through list and match any missing element with boundary values */
    for(k = 0; k < nel; ++k)
        for(i = 0; i < 3; ++i)
            if(!ginfo->elmtcon[k][i].elmtid) {
                vid  = ginfo->elmtpts[k][i];
                vid1 = ginfo->elmtpts[k][(i+1)%3];
                /* check to see that this side is a boundary */
                for(j = 0,trip=1; j < nbnd; ++j)
                    if(vid == bndpts[j][0] && vid1 == bndpts[j][1]) {
                        /* set boundary condition from given values if present */
                        if(f->mesh.name) {
                            register int  i1;
                            Bndinfo *b;
                            Curinfo *c;

                            for(b=ginfo->bnd; b; b = b->next)
                                if(b->region == bndpts[j][2]) {
                                    ginfo->elmtcon[k][i].type = b->type;
                                    switch(b->type) {
                                    case 'W':
                                    case 'O':
                                    case 'S':
                                    case 'B':
                                    case 'M':
                                    case 'I':
                                    case 'Z':
                                        break;
                                    case 'V':
                                    case 'F':
                                        dcopy(b->nbcs,b->data.val,1,ginfo->elmtcon[k][i].f,1);
                                        break;
                                    case 'v':
                                    case 'f':
                                    case 'm':
                                        for(i1=0; i1 < b->nbcs; ++i1)
                                            ginfo->elmtcon[k][i].str[i1] = b->data.str[i1];
                                        break;
                                    }
                                }

                            for(c=ginfo->curve; c; c = c->next) {
                                if(c->region == bndpts[j][2]) {
                                    /* reset co-ordinates */
                                    switch(c->type) {
                                    case 'C': /* arc */
                                    {
                                        double theta;

                                        theta = atan2(ginfo->y[vid-1]-c->info.arc.yc,
                                                      ginfo->x[vid-1]-c->info.arc.xc);

                                        ginfo->x[vid-1] = fabs(c->info.arc.radius)*cos(theta)
                                                          + c->info.arc.xc;
                                        ginfo->y[vid-1] = fabs(c->info.arc.radius)*sin(theta)
                                                          + c->info.arc.yc;

                                        theta = atan2(ginfo->y[vid1-1]-c->info.arc.yc,
                                                      ginfo->x[vid1-1]-c->info.arc.xc);

                                        ginfo->x[vid1-1] = fabs(c->info.arc.radius)*cos(theta)
                                                           + c->info.arc.xc;
                                        ginfo->y[vid1-1] = fabs(c->info.arc.radius)*sin(theta)
                                                           + c->info.arc.yc;
                                        break;
                                    }
                                    }

                                    /* add curved information about element to ginfo */
                                    addcurve(ginfo,k+1,i,c->idtype);

                                }
                            }
                        }
                        else
                            ginfo->elmtcon[k][i].type = 'W';

                        trip=0;
                    }
                if(trip)
                    fprintf(stderr,"side %d of element %d using coordinate indices"
                            " (%d,%d) is not a boundary\n",i+1,k+1,vid,vid1);
            }

    /* free the con list */
    for(k = 0; k < npt; ++k) {
        c = con[k].next;
        while(c) {
            c1 = c->next;
            free(c);
            c = c1;
        }
    }
    free(con);
    free_imatrix(bndpts,0,0);

    return ginfo;
}
void laplace_fourier_res(float **sectionvy_obs, float **sectionvy, float **sectiondiff, int ntr, int ntr_glob, int ns, int ishot, int nshots, int iter, int **recpos, int **recpos_loc, float **srcpos){ 

	/* declaration of global variables */
	extern float DT, DH, OFFSETC;
	extern int SEIS_FORMAT, MYID, NT, TIMEWIN;
	extern char  SEIS_FILE_VY[STRING_SIZE], PARA[STRING_SIZE], DATA_DIR[STRING_SIZE];
	extern int TRKILL, OFFSET_MUTE, GRAD_FORM;
	extern char TRKILL_FILE[STRING_SIZE];
	
	/* declaration of variables for trace killing */
	int ** kill_tmp, *kill_vector, h, j, i, Npad;
	char trace_kill_file[STRING_SIZE];	
	FILE *ftracekill;

        /* declaration of variables for offset-muting */
        float offset, xr, yr, xs, ys;

        /* complex variables for source wavelet estimation */
        fftw_complex *D_ss, *D_ss_fd;

        /* parameters for STA/LTA first arrival picking */
        float *picked_times=NULL;
	
	/* variables for data integration */
	int invtime;
	float **integrated_section=NULL, **integrated_sectiondata=NULL;
	float EPS_NORM;
	
        integrated_section = matrix(1,ntr,1,ns);
	integrated_sectiondata = matrix(1,ntr,1,ns);
	
	Npad = 2.0 * ns;
        Npad = (int)(pow(2.0, ceil(log((double)(Npad))/log(2.0))+2.0) );
    
        EPS_NORM=1e0;
    
        /* Allocate memory */
        D_ss  = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * Npad);
        D_ss_fd  = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * Npad);
        
        
	/* reverse time direction integrate data if GRAD_FORM=1 */
        for(i=1;i<=ntr;i++){
    
           invtime = ns;
	   for(j=1;j<=ns;j++){
	   
	   
	      if(GRAD_FORM==1){
	         integrated_section[i][invtime] += DT*sectionvy[i][j];
	         integrated_sectiondata[i][invtime] += DT*sectionvy_obs[i][j];
	      }
	      
	      if(GRAD_FORM==2){
	         integrated_section[i][invtime] = sectionvy[i][j];
	         integrated_sectiondata[i][invtime] = sectionvy_obs[i][j];
	      }	      
	      
	      invtime--;
	   }	
	   
	}
		
        /* pick first arrivals in the synthetic data with STA/LTA-picker and apply time window to field data before stf inversion */ 	                                           
        /*if(TIMEWIN==3){
	  picked_times = vector(1,ntr);
	  stalta(sectionvy, ntr, ns, picked_times, ishot);
          time_window_stf(sectionvy_obs, iter, ntr, ns, ishot);
        }*/
	
	TIMEWIN=2;
	
	/* apply time damping to field and model data */
	picked_times = vector(1,ntr);
	time_window(integrated_sectiondata,picked_times,iter,ntr_glob,recpos_loc,ntr,ns,ishot);
        time_window(integrated_section,picked_times,iter,ntr_glob,recpos_loc,ntr,ns,ishot);
	                  
			       
	/* TRKILL==1 - trace killing is applied */
	if(TRKILL){
	  kill_tmp = imatrix(1,nshots,1,ntr);
	  kill_vector = ivector(1,ntr);

	  ftracekill=fopen(TRKILL_FILE,"r");

	  if (ftracekill==NULL) err(" Trace kill file could not be opened!");

		for(i=1;i<=nshots;i++){
			for(j=1;j<=ntr;j++){
				fscanf(ftracekill,"%d",&kill_tmp[i][j]);
			}
		}

		fclose(ftracekill);

		for(i=1;i<=ntr;i++){
	   	   kill_vector[i] = kill_tmp[ishot][i];
		}

	  for(i=1;i<=ntr;i++){

	     if(kill_vector[i]==1){
	       
	        for(j=1;j<=ns;j++){
		   integrated_section[i][j]=0.0;
		   integrated_sectiondata[i][j]=0.0;
	        }
	     }	
    	     
	  }
	
	}
		
	/* trace killing ends here */

        /* apply offset mute */
        if(OFFSET_MUTE){

         /*printf("OFFSETC = %f \n",OFFSETC);
         printf("OFFSET_MUTE = %d \n",OFFSET_MUTE);      */

         for (i=1;i<=ntr;i++){
             
             /* calculate source and receiver positions */
      	     xr = recpos[1][recpos_loc[3][i]]*DH;
      	     xs = srcpos[1][ishot];
      	     yr = recpos[2][recpos_loc[3][i]]*DH;
      	     ys = srcpos[2][ishot];

             /* calculate absolute offset */
             offset = sqrt(((xs-xr)*(xs-xr))+((ys-yr)*(ys-yr)));

             /* mute far-offset data*/
             if((OFFSET_MUTE==1)&&(offset>=OFFSETC)){
                
                for(j=1;j<=ns;j++){
		   integrated_section[i][j]=0.0;
		   integrated_sectiondata[i][j]=0.0;
	        }
                    
             }

             /* mute near-offset data*/
             if((OFFSET_MUTE==2)&&(offset<=OFFSETC)){

	        for(j=1;j<=ns;j++){
		   integrated_section[i][j]=0.0;
		   integrated_sectiondata[i][j]=0.0;
	        }

             }
         } 

        } /* end of OFFSET_MUTE */	                                 


        /* FFT of each data and model trace and calculation of nominator and denominator of Wiener deconvolution */
        for(i=1;i<=ntr;i++){

           /* allocate memory for complex variables */           
           fftw_complex *in_data, *out_data, *in_model, *out_model, *res_td, *res;
           fftw_plan p_data,p_model;
         
           in_data  = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * Npad);
           out_data = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * Npad);

           in_model  = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * Npad);
           out_model = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * Npad);
	   
	   res_td  = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * Npad);
	   res  = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * Npad);

           /* define real and imaginary parts of data vectors and apply zero-padding */
           for(j=0;j<Npad;j++){

              if(j<ns){
                 
	      	 in_model[j] = (integrated_section[i][j+1]) + 0.0*I;
                 in_data[j]  = (integrated_sectiondata[i][j+1]) + 0.0*I;	
              }
              else{
	      	in_model[j] = 0.0 + 0.0*I;
                 in_data[j] = 0.0 + 0.0*I;
              }
              
	   }
           
           /* apply FFTW */           
           p_data  = fftw_plan_dft_1d(Npad, in_data, out_data, 1, FFTW_ESTIMATE);
           p_model = fftw_plan_dft_1d(Npad, in_model, out_model, 1, FFTW_ESTIMATE);         

           fftw_execute(p_data);
           fftw_execute(p_model);

           /* calculate data residuals in the Laplace-Fourier domain (Jun etal., 2014)*/
           for(j=0;j<Npad;j++){

              /* real parts of the nominator and denominator */
              res[j] = (1.0/out_model[j]+EPS_NORM)*conj(log(out_model[j]+EPS_NORM)-log(out_data[j]+EPS_NORM));
	      
           }
	   
	   /* inverse FFTW of data residuals */
           fftw_plan p_stf;
           p_stf  = fftw_plan_dft_1d(Npad, res, res_td, -1, FFTW_ESTIMATE);
           fftw_execute(p_stf);

           /* extract real part and write data to sectiondiff */
	   /*h=1;
           for(j=Npad;j>Npad-ns;j--){
       	      sectiondiff[i][h]=creal(res_td[h])/Npad;
	      h=h+1;
           }*/  
	   
	 
	   for(j=1;j<=ns;j++){
	      sectiondiff[i][j] = integrated_section[i][j] - integrated_sectiondata[i][j];    	
	   }         

           fftw_destroy_plan(p_data);
           fftw_free(in_data); 
           fftw_free(out_data);          

           fftw_destroy_plan(p_model);
	   fftw_destroy_plan(p_stf);
           fftw_free(in_model); 
           fftw_free(out_model);
	   fftw_free(res);
	   fftw_free(res_td);
	   
        }
        						
	/* free memory for trace killing and FFTW */
	if(TRKILL){
	   free_imatrix(kill_tmp,1,nshots,1,ntr);
	   free_ivector(kill_vector,1,ntr);
	}

         
 	fftw_free(D_ss);
	fftw_free(D_ss_fd);
	
	
	free_vector(picked_times,1,ntr);
	free_matrix(integrated_section,1,ntr,1,ns);
        free_matrix(integrated_sectiondata,1,ntr,1,ns);
 
}
Beispiel #22
0
void viterbi(HMM *hmm_ptr, int T, char *O, double *pprob, int *vpath, char *signal_file1, char *signal_file2, char *out_file, char *phmm_dir1, char *out_dir1, char *hmmerv){

	/*
	   chr *O: sequecne
	   int *vpath: optimal path after backtracking
	   int T: the length of sequence


	   hmm.A[][]: transition prob
	   hmm.B[][]: emission prob
	   hmm.N: the number of state

	   int i: index for start state, current state
	   int j: index for end start
	   int t: index for string
	   int t1: subindex for string

	   int state_end;
	   double state_score;
	   */

	int i, j, t, t1, d, ss, si;
	double max_val, temp_val;
	int max_state;
	int **path;           /* viterbi path */
	double **alpha;       /* viterbi array */
	int *signal;          /* chromosomal position for the index in X axis of array */
	int *path_signal;     /* 0: start of fragment, 1: end */

	int temp1, temp2;
	double temp3, temp4;
	FILE *fp,*outfp;
	int state_end;
	double state_score;
	int *ape, *rt;
	int *start, *end;
	int flag;
	char state_flag[20];
	int prev_state;
	int final_t;

	int sig_id = 0;      /* index for signal of fragments */
	int num_sig = 0;     /* total numer of signals */
	int temp_id;
	double temp_prob;
	int check_prob;
	int debug = 0;

	/*

	   if ((phmm_dir = (char *)malloc(50 * sizeof(char)))==NULL){ 
	   printf("ERROR: allocation of phmm_dir\n");
	   exit;
	   }
	   if ((out_dir = (char *)malloc(50 * sizeof(char)))==NULL){ 
	   printf("ERROR: allocation of out_dir\n");
	   exit;
	   }

	   memset(phmm_dir,0,50);
	   memset(out_dir,0,50);
	   */
	phmm_dir = phmm_dir1;


	out_dir = out_dir1; 

	memset(state_flag,0,20);

	/***************************************************************/
	/* initialize viterbi array                                    */
	/***************************************************************/
	ape = (int *)ivector(T+1);
	rt = (int *)ivector(T+1);
	start = (int *)ivector(hmm_ptr->N);
	end = (int *)ivector(hmm_ptr->N);
	/*****************************************************************/
	/* mark signal                                                   */
	/*****************************************************************/  
	for (t=0; t<T; t++){
		ape[t] = 0;
		rt[t] = 0;
	}
	fp = fopen(signal_file1, "r");
	while (fscanf(fp, "%d %d %lf %lf\n", &temp1, &temp2, &temp3, &temp4) != EOF){
		ape[temp1] = 1;
		if (temp2 > T) {temp2 = T;}
		ape[temp2] = 2;
		num_sig += 2;
	}
	fclose(fp);

	fp = fopen(signal_file2, "r");
	while (fscanf(fp, "%d %d %lf %lf\n", &temp1, &temp2, &temp3, &temp4) != EOF){
		rt[temp1] = 1;
		if (temp2 > T) {temp2 = T;}
		rt[temp2] = 2;
		num_sig += 4; 
	}
	fclose(fp);

	num_sig *= 2; 

	/***************************************************************/
	/* initialize viterbi array                                    */
	/***************************************************************/
	alpha = (double **)dmatrix(hmm_ptr->N, num_sig);
	path = (int **)imatrix(hmm_ptr->N, num_sig);
	signal = (int *)ivector(num_sig);
	path_signal = (int *)ivector(num_sig);
	outfp = fopen (out_file , "w");

	if (num_sig > 0){

		/******************************************************************/
		/* initialize the first IE state                                  */
		/******************************************************************/
		start[IE]=0;
		signal[sig_id] = 0;
		sig_id ++;



		for (i=0; i<hmm_ptr->N; i++){
			alpha[i][0] = -1 * log(hmm_ptr->pi[i]);
			for (t=1; t<num_sig; t++){
				alpha[i][t] = DBL_MAX;
			}
		}

		/******************************************************************/
		/* do recursion to fill out rest of the columns                   */
		/******************************************************************/

		for (t = 1; t < T - 2; t++) {

			if (sig_id >= num_sig) { break; }

			flag=0;

			/*********************/
			/* state APE start  */
			/*********************/      
			if (ape[t]==1){

				flag=1;      
				strcpy(state_flag, "APE start");
				path_signal[sig_id] = 0;

				alpha[IE][sig_id] = DBL_MAX;
				path[IE][sig_id] = IE;
				start[IE] = sig_id;

				for(ss=0; ss<NO_APE; ss++){
					alpha[ape_state[ss]][sig_id] = alpha[IE][sig_id-1] - log(hmm_ptr->A[IE][ape_state[ss]]);
					path[ape_state[ss]][sig_id] = IE;
					start[ape_state[ss]] = sig_id;
				}	
			}
			/*********************/
			/* state APE end     */
			/*********************/      

			if (ape[t] == 2) {

				flag=1;
				strcpy(state_flag,  "APE end");
				path_signal[sig_id] = 1;

				alpha[IE][sig_id] = DBL_MAX;
				path[IE][sig_id] = IE;

				for (ss=0; ss<NO_APE; ss++){
					state_score = get_prob(ape_state[ss], signal[start[ape_state[ss]]], t, O, hmmerv);
					if (state_score == DBL_MAX){
						alpha[ape_state[ss]][sig_id] = DBL_MAX;
					}else{
						alpha[ape_state[ss]][sig_id] = alpha[ape_state[ss]][start[ape_state[ss]]] - state_score - log(dist_ape(t-signal[start[ape_state[ss]]]+1)); 
					}
					path[ape_state[ss]][sig_id] = ape_state[ss];
				}
			}
			/*********************/
			/* state ID/IE start */
			/*********************/      

			if (ape[t-1] == 2){

				flag=1;
				strcpy(state_flag,  "ID/IE start");
				path_signal[sig_id] = 0;

				alpha[IE][sig_id] = alpha[IE][sig_id-1];
				path[IE][sig_id] = IE;
				start[IE] = sig_id;

				for (si=0; si<NO_APE; si++){
					temp_val = alpha[ape_state[si]][sig_id-1] - log(hmm_ptr->A[ape_state[si]][IE]);
					if (temp_val < alpha[IE][sig_id]){
						alpha[IE][sig_id] = temp_val;
						path[IE][sig_id] = ape_state[si];
					}
				}

				for (si=0; si<NO_APE; si++){
					if (alpha[ape_state[si]][sig_id-1]==DBL_MAX){
						alpha[id_state[si]][sig_id]  = DBL_MAX;
					}else{
						alpha[id_state[si]][sig_id] = alpha[ape_state[si]][sig_id-1] - log(hmm_ptr->A[ape_state[si]][id_state[si]]);
					}
					path[id_state[si]][sig_id] = ape_state[si];
					start[id_state[si]] = sig_id;
				}
			}
			/*********************/
			/* state ID/IE end   */
			/*********************/      

			if (rt[t+1] == 1 ) {

				flag=1;
				strcpy(state_flag,  "ID/IE end");
				path_signal[sig_id] = 1;

				state_score = get_prob(IE, signal[start[IE]], t, O, hmmerv);

				alpha[IE][sig_id] = alpha[IE][start[IE]] - state_score - log(dist_ie(t-signal[start[IE]]+1));   
				path[IE][sig_id] = IE;

				if (start[id_state[0]] >-1){
					for (si=0; si<NO_APE; si++){
						state_score = get_prob(id_state[si], signal[start[id_state[si]]], t, O, hmmerv);

						if (dist_id(t-signal[start[id_state[si]]]+1)==0){
							alpha[id_state[si]][sig_id] = DBL_MAX;   
						}else{
							alpha[id_state[si]][sig_id] = alpha[id_state[si]][start[id_state[si]]] - state_score - log(dist_id(t-signal[start[id_state[si]]]+1));   
						}
						path[id_state[si]][sig_id] = id_state[si];
						start[id_state[si]]=-1;
					}
				}else{
					for (si=0; si<NO_APE; si++){
						alpha[id_state[si]][sig_id] = DBL_MAX;   
						path[id_state[si]][sig_id] = -1;
					}
				}
			}
			/*********************/
			/* state RT1 start   */
			/*********************/

			if (rt[t] == 1) {         

				flag=1;
				strcpy(state_flag,  "RT start");
				path_signal[sig_id] = 0;

				alpha[IE][sig_id] = DBL_MAX;
				path[IE][sig_id] = IE;
				start[IE] = sig_id;

				for (si=0; si<NO_RT; si++){

					alpha[rt_state[si]][sig_id] = alpha[IE][sig_id-1] - log(hmm_ptr->A[IE][rt_state[si]]);
					path[rt_state[si]][sig_id] = IE;
					start[rt_state[si]] = sig_id;	

					temp_val = alpha[id_state[si]][sig_id-1] - log(hmm_ptr->A[id_state[si]][rt_state[si]]);

					if (temp_val < alpha[rt_state[si]][sig_id]){
						alpha[rt_state[si]][sig_id] = temp_val;
						path[rt_state[si]][sig_id] = id_state[si];
					}
				}
			}
			/*********************/
			/* state RT1 end     */
			/*********************/      

			if (rt[t] == 2) {

				flag=1;
				strcpy(state_flag,  "RT end");
				path_signal[sig_id] = 1;

				alpha[IE][sig_id] = DBL_MAX;
				path[IE][sig_id] = IE;

				for (si=0; si<NO_RT; si++) {
					state_score = get_prob(rt_state[si], signal[start[rt_state[si]]], t, O, hmmerv);
					if (state_score == DBL_MAX){
						alpha[rt_state[si]][sig_id] = DBL_MAX;
					}else{
						alpha[rt_state[si]][sig_id] = alpha[rt_state[si]][start[rt_state[si]]] - state_score - log(dist_rt(t-signal[start[rt_state[si]]]+1));   
					}
					path[rt_state[si]][sig_id] = rt_state[si];
				}
			}

			/*********************/
			/* state IE start    */
			/*********************/      

			if (rt[t-1] == 2){

				flag=1;
				strcpy(state_flag,  "IE start");
				path_signal[sig_id] = 0;

				alpha[IE][sig_id] = DBL_MAX;
				path[IE][sig_id] = IE;
				start[IE] = sig_id;

				for (si=0; si<NO_RT; si++){
					temp_val = alpha[rt_state[si]][sig_id-1] - log(hmm_ptr->A[rt_state[si]][IE]);
					if (temp_val < alpha[IE][sig_id]){
						alpha[IE][sig_id] = temp_val;
						path[IE][sig_id] = rt_state[si];
					}
				}
				for (si=0; si<NO_APE; si++){
					alpha[id_state[si]][sig_id]=DBL_MAX;
					path[id_state[si]][sig_id] = -1;
				}
			}
			/*********************/
			/* state IE end     */
			/*********************/      

			if (ape[t+1] == 1  ) {

				flag=1;
				strcpy(state_flag,  "IE end");
				path_signal[sig_id] = 1;

				state_score = get_prob(IE, signal[start[IE]], t, O, hmmerv);

				if (dist_ie(t-signal[start[IE]]+1)==0){
					alpha[IE][sig_id] = DBL_MAX;
				}else{
					alpha[IE][sig_id] = alpha[IE][start[IE]] - state_score - log(dist_ie(t-signal[start[IE]]+1));
				}
				path[IE][sig_id] = IE;
			}

			/************************/
			/* print                */
			/************************/

			if (flag==1){
				final_t = sig_id;
				signal[sig_id] = t;
				if (debug==1){
					printf("%d %d %s\t\t", sig_id, t, state_flag);

					for (i=0; i<hmm_ptr->N; i++){
						if (alpha[i][sig_id] < DBL_MAX ){
							printf("%lf\t", alpha[i][sig_id]);
						}else{
							printf("-\t");
						}
					}
					printf("\n\n");

					printf("%d %d %s\t\t", sig_id, t, state_flag);

					for (i=0; i<hmm_ptr->N; i++){
						printf("%d\t", path[i][sig_id]);
					}
					printf("\n\n\n");
				}
				sig_id++;
			}

		}

		/***********************************************************/
		/* backtrack array to find the optimal path                */
		/***********************************************************/

		*pprob = DBL_MAX;
		vpath = (int *)ivector(num_sig);

		for (i = 0; i < hmm_ptr->N; i++){
			if (alpha[i][final_t] < *pprob && alpha[i][final_t] > 0.00001){
				*pprob = alpha[i][final_t];
				vpath[final_t] = i;
			}
		} 
		if (*pprob == DBL_MAX) {
			vpath[final_t]=0;
		}

		for(sig_id=final_t-1; sig_id>=0; sig_id--){

			// skip if viterbi path or array is out of range
			if ( path[vpath[sig_id+1]][sig_id+1] == -1)
				continue;
			vpath[sig_id] = path[vpath[sig_id+1]][sig_id+1];

			if (path_signal[sig_id] == 1 && alpha[vpath[sig_id]][sig_id] != DBL_MAX){
				fprintf(outfp, "%d %d %lf\n", signal[sig_id], vpath[sig_id], alpha[vpath[sig_id]][sig_id]);
			}
		}

	}

	fclose(outfp);
	free_ivector(ape);
	free_ivector(rt);
	free_ivector(start);
	free_ivector(end);
	free_imatrix(path, hmm_ptr->N);
	free_dmatrix(alpha, hmm_ptr->N);
	free_ivector(signal);
	free_ivector(path_signal);
	free_ivector(vpath);
}
Beispiel #23
0
double calc_misfit(float **sectiondata, float **section, int ntr, int ns, int LNORM, float L2, int itest, int sws, int swstestshot,int ntr_glob, int **recpos_loc, int nsrc_glob, int ishot){

/* declaration of variables */
extern float DT;
extern int MYID;
extern int TRKILL;
extern char TRKILL_FILE[STRING_SIZE];
float intseis, intseis_data, intseis_synthetics, abs_synthetics, abs_data;
int i,j;
float l2;
float L2_dummy;
int umax=0, h;
	

/* declaration of variables for trace killing */
int ** kill_tmp, *kill_vector;
char trace_kill_file[STRING_SIZE];	
FILE *ftracekill;

if(TRKILL){
	kill_tmp = imatrix(1,ntr_glob,1,nsrc_glob);
	kill_vector = ivector(1,ntr);

	ftracekill=fopen(TRKILL_FILE,"r");

	if (ftracekill==NULL) err(" Trace kill file could not be opened!");

	for(i=1;i<=ntr_glob;i++){
		for(j=1;j<=nsrc_glob;j++){
			fscanf(ftracekill,"%d",&kill_tmp[i][j]);
		}
	}

	fclose(ftracekill);

	h=1;
	for(i=1;i<=ntr;i++){
	   kill_vector[h] = kill_tmp[recpos_loc[3][i]][ishot];
	   h++;
	}
} /* end if(TRKILL)*/



/* calculate misfit */

for(i=1;i<=ntr;i++){
	if((TRKILL==1)&&(kill_vector[i]==1))
    	continue;	


    intseis = 0.0;
    intseis_data = 0.0;
    intseis_synthetics = 0.0;
    abs_data = 0.0;
    abs_synthetics = 0.0;
    L2_dummy=0.0;
      for(j=1;j<=ns;j++){
                        /*printf("%d \t %d \t %e \t %e \n",i,j,sectionpdata[i][j],sectionp[i][j]);*/
                        
			
			/* calculate L2 residuals */
			if((LNORM==2) ||(LNORM==6)){
			intseis += section[i][j]-sectiondata[i][j];}
			
			if(LNORM==5){
			intseis_data += sectiondata[i][j]*DT;
			intseis_synthetics += section[i][j]*DT;
			abs_data += intseis_data*intseis_data;
			abs_synthetics += intseis_synthetics*intseis_synthetics;
			L2_dummy+=(intseis_data*intseis_synthetics);}
			                        
			/* calculate norm */
			/*if((sws==1)&&(swstestshot==1)){*/
			if(((LNORM==2) ||(LNORM==6)) &&(swstestshot==1)){
			/*L2+=sectiondiff[i][invtime]*sectiondiff[i][invtime];*/
			L2+=intseis*intseis*DT*DT; 
			}
			
			}
			if(LNORM==5){
			L2 -= L2_dummy/(sqrt(abs_data)*sqrt(abs_synthetics));}

}
		    l2=L2;
return l2;

/* free memory for trace killing */
if(TRKILL){
free_imatrix(kill_tmp,1,ntr_glob,1,nsrc_glob);
free_ivector(kill_vector,1,ntr);
}

}
Beispiel #24
0
/* creates 3 matrices: invA, B, C: dT + A^-1*BT = A^-1*Power, 
 * C = A^-1 * B. note that A is a diagonal matrix (no lateral
 * capacitances. all capacitances are to ground). so, inva[i][i]
 * (= 1/a[i][i]) is just enough.
 *
 * NOTE: EXTRA nodes: 1 chip bottom, 5 spreader and 5 heat sink nodes
 * (north, south, east, west and bottom).
 */
void create_RC_matrices(flp_t *flp, int omit_lateral)
{
	int i, j, k = 0, n = flp->n_units;
	int **border;
	double **len, *gx, *gy, **g, *c_ver, **t;
	double r_sp1, r_sp2, r_hs;	/* lateral resistances to spreader and heatsink	*/

	/* NOTE: *_mid - the vertical R/C from center nodes of spreader 
	 * and heatsink. *_ver - the vertical R/C from peripheral (n,s,e,w) nodes
	 */
	double r_sp_mid, r_sp_ver, r_hs_mid, r_hs_ver, c_sp_mid, c_sp_ver, c_hs_mid, c_hs_ver;
	double gn=0, gs=0, ge=0, gw=0;
	double w_chip = get_total_width (flp);	/* x-axis	*/
	double l_chip = get_total_height (flp);	/* y-axis	*/
	FILE *fp_b,*fp_c,*fp_inva,*fp_invb;
	fp_b=fopen("B","w");
	fp_c=fopen("C","w");
	fp_invb=fopen("invB","w");
	fp_inva=fopen("invA","w");

	border = imatrix(n, 4);
	len = matrix(n, n);		/* len[i][j] = length of shared edge bet. i & j	*/
	gx = vector(n);			/* lumped conductances in x direction	*/
	gy = vector(n);			/* lumped conductances in y direction	*/
	g = matrix(n+EXTRA, n+EXTRA);	/* g[i][j] = conductance bet. nodes i & j */
	c_ver = vector(n+EXTRA);	/* vertical capacitance	*/

	b = matrix(n+EXTRA, n+EXTRA);	/* B, C, INVA  and INVB are (n+EXTRA)x(n+EXTRA) matrices	*/
	c = matrix(n+EXTRA, n+EXTRA);
	inva = matrix(n+EXTRA, n+EXTRA);
	invb = matrix(n+EXTRA, n+EXTRA);
	t = matrix (n+EXTRA, n+EXTRA);	/* copy of B	*/

	/* compute the silicon fitting factor - see pg 10 of the UVA CS tech report - CS-TR-2003-08	*/
	factor_chip = C_FACTOR * ((SPEC_HEAT_CU / SPEC_HEAT_SI) * (w_chip + 0.88 * t_spreader) \
				* (l_chip + 0.88 * t_spreader) * t_spreader / ( w_chip * l_chip * t_chip) + 1);

	/* gx's and gy's of blocks	*/
	for (i = 0; i < n; i++) {
		gx[i] = 1.0/getr(K_SI, flp->units[i].height, flp->units[i].width, l_chip);
		gy[i] = 1.0/getr(K_SI, flp->units[i].width, flp->units[i].height, w_chip);
	}

	/* shared lengths between blocks	*/
	for (i = 0; i < n; i++) 
		for (j = i; j < n; j++) 
			len[i][j] = len[j][i] = get_shared_len(flp, i, j);

	/* lateral R's of spreader and sink */
	r_sp1 = getr(K_CU, (s_spreader+3*w_chip)/4.0, (s_spreader-w_chip)/4.0, w_chip);
	r_sp2 = getr(K_CU, (3*s_spreader+w_chip)/4.0, (s_spreader-w_chip)/4.0, (s_spreader+3*w_chip)/4.0);
	r_hs = getr(K_CU, (s_sink+3*s_spreader)/4.0, (s_sink-s_spreader)/4.0, s_spreader);

	/* vertical R's and C's of spreader and sink */
	r_sp_mid = RHO_CU * t_spreader / (w_chip * l_chip);
	c_sp_mid = factor_pack * SPEC_HEAT_CU * t_spreader * (w_chip * l_chip);
	r_sp_ver = RHO_CU * t_spreader * 4.0 / (s_spreader * s_spreader - w_chip*l_chip);
	c_sp_ver = factor_pack * SPEC_HEAT_CU * t_spreader * (s_spreader * s_spreader - w_chip*l_chip) / 4.0;
	r_hs_mid = RHO_CU * t_sink / (s_spreader*s_spreader);
	c_hs_mid = factor_pack * SPEC_HEAT_CU * t_sink * (s_spreader * s_spreader);
	r_hs_ver = RHO_CU * t_sink * 4.0 / (s_sink * s_sink - s_spreader*s_spreader);
	c_hs_ver = factor_pack * SPEC_HEAT_CU * t_sink * (s_sink * s_sink - s_spreader*s_spreader) / 4.0;

	/* short the R's from block centers to a particular chip edge	*/
	for (i = 0; i < n; i++) {
		if (eq(flp->units[i].bottomy + flp->units[i].height, l_chip)) {
			gn += gy[i];
			border[i][2] = 1;	/* block is on northern border 	*/
		}	
		if (eq(flp->units[i].bottomy, 0)) {
			gs += gy[i];
			border[i][3] = 1;	/* block is on southern border	*/
		}	
		if (eq(flp->units[i].leftx + flp->units[i].width, w_chip)) {
			ge += gx[i];
			border[i][1] = 1;	/* block is on eastern border	*/
		}	
		if (eq(flp->units[i].leftx, 0)) {
			gw += gx[i];
			border[i][0] = 1;	/* block is on western border	*/
		}	
	}

	/* overall R and C between nodes */
	for (i = 0; i < n; i++) {

		/* amongst functional units	*/
		for (j = 0; j < n; j++) {
			double part = 0;
			if (!omit_lateral) {
				if (is_horiz_adj(flp, i, j)){ 
					part = gx[i] / flp->units[i].height;
					printf("%d %d horiz adj\n",i,j);
				}
				else if (is_vert_adj(flp, i,j)) {
					part = gy[i] / flp->units[i].width;
					printf("%d %d vert adj\n",i,j);
				}
			}
			g[i][j] = part * len[i][j];
		}

		/* C's from functional units to ground	*/
		c_ver[i] = factor_chip * SPEC_HEAT_SI * t_chip * flp->units[i].height * flp->units[i].width;

		/* lateral g's from block center to peripheral (n,s,e,w) spreader nodes	*/
		g[i][n+SP_N]=g[n+SP_N][i]=2.0*border[i][2]/((1.0/gy[i])+r_sp1*gn/gy[i]);
		g[i][n+SP_S]=g[n+SP_S][i]=2.0*border[i][3]/((1.0/gy[i])+r_sp1*gs/gy[i]);
		g[i][n+SP_E]=g[n+SP_E][i]=2.0*border[i][1]/((1.0/gx[i])+r_sp1*ge/gx[i]);
		g[i][n+SP_W]=g[n+SP_W][i]=2.0*border[i][0]/((1.0/gx[i])+r_sp1*gw/gx[i]);

 		/* vertical g's from block center to chip bottom */
		g[i][n+CHIP_B]=g[n+CHIP_B][i]=2.0/(RHO_SI * t_chip / (flp->units[i].height * flp->units[i].width));

	}

	/* max slope (1/vertical RC time constant) for silicon	*/
	max_slope = 1.0 / (factor_chip * t_chip * t_chip * RHO_SI * SPEC_HEAT_SI);

	/* vertical g's and C's between central nodes	*/
 	/* between chip bottom and spreader bottom */
	g[n+CHIP_B][n+SP_B]=g[n+SP_B][n+CHIP_B]=2.0/r_sp_mid;
 	/* from chip bottom to ground	*/
	c_ver[n+CHIP_B]=c_sp_mid;
 	/* between spreader bottom and sink bottom	*/
	g[n+SINK_B][n+SP_B]=g[n+SP_B][n+SINK_B]=2.0/r_hs_mid;
 	/* from spreader bottom to ground	*/
	c_ver[n+SP_B]=c_hs_mid;
 	/* from sink bottom to ground	*/
	c_ver[n+SINK_B]=c_convec;

	/* g's and C's from peripheral(n,s,e,w) nodes	*/
	for (i = 1; i <= 4; i++) {
 		/* vertical g's between peripheral spreader nodes and spreader bottom */
		g[n+SP_B-i][n+SP_B]=g[n+SP_B][n+SP_B-i]=2.0/r_sp_ver;
 		/* lateral g's between peripheral spreader nodes and peripheral sink nodes	*/
		g[n+SP_B-i][n+SINK_B-i]=g[n+SINK_B-i][n+SP_B-i]=2.0/(r_hs + r_sp2);
 		/* vertical g's between peripheral sink nodes and sink bottom	*/
		g[n+SINK_B-i][n+SINK_B]=g[n+SINK_B][n+SINK_B-i]=2.0/r_hs_ver;
 		/* from peripheral spreader nodes to ground	*/
		c_ver[n+SP_B-i]=c_sp_ver;
 		/* from peripheral sink nodes to ground	*/
		c_ver[n+SINK_B-i]=c_hs_ver;
	}

	/* calculate matrices A, B such that A(dT) + BT = POWER */

	for (i = 0; i < n+EXTRA; i++) {
		for (j = 0; j < n+EXTRA; j++) {
			if (i==j) {
				inva[i][j] = 1.0/c_ver[i];
				if (i == n+SINK_B)	/* sink bottom */
					b[i][j] += 1.0 / r_convec;
				for (k = 0; k < n+EXTRA; k++) {
					if ((g[i][k]==0.0)||(g[k][i])==0.0) 
						continue;
					else 
					/* here is why the 2.0 factor comes when calculating g[][]	*/
						b[i][j] += 1.0/((1.0/g[i][k])+(1.0/g[k][i]));
				}
			} else {
				inva[i][j]=0.0;
				if ((g[i][j]==0.0)||(g[j][i])==0.0)
					b[i][j]=0.0;
				else
				b[i][j]=-1.0/((1.0/g[i][j])+(1.0/g[j][i]));
			}
		}
	}

	/* we are always going to use the eqn dT + A^-1 * B T = A^-1 * POWER. so, store  C = A^-1 * B	*/
	matmult(c, inva, b, n+EXTRA);
	/* we will also be needing INVB so store it too	*/
	copy_matrix(t, b, n+EXTRA, n+EXTRA);
	matinv(invb, t, n+EXTRA);
	for (i = 0; i < n+EXTRA; i++) {
		for (j = 0; j < n+EXTRA; j++) {
			fprintf(fp_inva,"%f  ",inva[i][j]);
			fprintf(fp_invb,"%f  ",invb[i][j]);
			fprintf(fp_c,"%f  ",c[i][j]);
			fprintf(fp_b,"%f  ",b[i][j]);
		}
		fprintf(fp_inva, "\n");
		fprintf(fp_invb, "\n");
		fprintf(fp_c , "\n");
		fprintf(fp_b, "\n");
	}
	fclose(fp_inva);
	fclose(fp_b);
	fclose(fp_c);
	fclose(fp_invb);

/*	dump_vector(c_ver, n+EXTRA);	*/
/*	dump_matrix(invb, n+EXTRA, n+EXTRA);	*/
/*	dump_matrix(c, n+EXTRA, n+EXTRA);	*/

	/* cleanup */
	free_matrix(t, n+EXTRA);
	free_matrix(g, n+EXTRA);
	free_matrix(len, n);
	free_imatrix(border, n);
	free_vector(c_ver);
	free_vector(gx);
	free_vector(gy);
}
Beispiel #25
0
int main(int argc, char** args){
	
	double Re, UI, VI, PI, GX, GY, t_end, xlength, ylength, dt, dx, dy, alpha, omg, tau, eps, dt_value, t, res, dp, nu;
	double **U, **V, **P, **F, **G, **RS;
	double **K, **E;					/* turbulent kinetic energy k, dissipation rate epsilon*/
	double Fu, Fv;						/* force integration variables */
	double KI, EI, cn, ce, c1, c2; 			/* K and E: Initial values for k and epsilon */

	int n, it, imax, jmax, itermax, pb, boundaries[4];
	int fluid_cells;		/* Number of fluid cells in our geometry */
	int **Flag;			/* Flagflield matrix */
	
	char vtkname[200];
	char pgm[200];
	char problem[10];		/* Problem name */
	char fname[200];

	if(argc<2){
		printf("No parameter file specified. Terminating...\n");
		exit(1);
	}

	sprintf(fname, "%s%s", CONFIGS_FOLDER, args[1]);
	printf("%s\n",fname);
	read_parameters(fname, &Re, &UI, &VI, &PI, &GX, &GY, &t_end, &xlength, &ylength, &dt, &dx, &dy, &imax, &jmax, &alpha, &omg, &itermax, &eps, boundaries, &dp, &pb, &KI, &EI, &cn, &ce, &c1, &c2, pgm, &nu, problem);

	/* Allocate Flag matrix */
	Flag = imatrix( 0, imax+1, 0, jmax+1 );

	U = matrix ( 0 , imax+1 , 0 , jmax+1 );
	V = matrix ( 0 , imax+1 , 0 , jmax+1 );
	P = matrix ( 0 , imax+1 , 0 , jmax+1 );

	F = matrix ( 0 , imax , 0 , jmax );
	G = matrix ( 0 , imax , 0 , jmax );
	RS = matrix ( 0 , imax , 0 , jmax );

	K = matrix ( 0 , imax+1 , 0 , jmax+1 );
	E = matrix ( 0 , imax+1 , 0 , jmax+1 );
	
	/* Initialize values to the Flag, u, v and p */
	init_flag(CONFIGS_FOLDER,pgm, imax, jmax, &fluid_cells, Flag );
	init_uvp(UI, VI, PI, KI, EI, imax, jmax, U, V, P, K, E, Flag, problem );

	printf("Problem: %s\n", problem );
	printf( "xlength = %f, ylength = %f\n", xlength, ylength );
	printf( "imax = %d, jmax = %d\n", imax, jmax );
	printf( "dt = %f, dx = %f, dy = %f\n", dt, dx, dy);
	printf( "Number of fluid cells = %d\n", fluid_cells );
	printf( "Reynolds number: %f\n\n", Re);

	t=.0;
	n=0;

	while( t <= t_end ){
		boundaryvalues( imax, jmax, U, V, K, E, boundaries, Flag );

		/* special inflow boundaries, including k and eps */
		spec_boundary_val( problem, imax, jmax, U, V, K, E, Re, dp, cn, ylength);

		/* calculate new values for k and eps */
		comp_KAEP(Re, nu, cn, ce, c1, c2, alpha, dt, dx, dy, imax, jmax, U, V, K, E, GX, GY, Flag);


		/* calculate new values for F and G */
		calculate_fg( Re, GX, GY, alpha, dt, dx, dy, imax, jmax, U, V, F, G, K, E, nu, cn, Flag );

		/* calculate right hand side */
		calculate_rs( dt, dx, dy, imax, jmax, F, G, RS, Flag );

		it = 0;
		res = 10000.0;
		while( it < itermax && fabs(res) > eps ){
			sor( omg, dx, dy, imax, jmax, fluid_cells, P, RS, Flag, &res, problem, dp );
			it++;
		}

		printf("[%5d: %f] dt: %f, sor iterations: %4d \n", n, t, dt, it);

		/* calculate new values for u and v */
		calculate_uv( dt, dx, dy, imax, jmax, U, V, F, G, P, Flag );

		t += dt;
		n++;
	}

	sprintf(vtkname, "%s%s", VISUA_FOLDER,  args[1]);
	write_vtkFile( vtkname, 1, xlength, ylength, imax, jmax, dx, dy, U, V, P, K, E, Flag);
	
	comp_surface_force( Re, dx, dy, imax, jmax, U, V, P, Flag, &Fu, &Fv);

	printf( "\nProblem: %s\n", problem );
	printf( "xlength = %f, ylength = %f\n", xlength, ylength );
	printf( "imax = %d, jmax = %d\n", imax, jmax );
	printf( "dt = %f, dx = %f, dy = %f\n", dt, dx, dy);
	printf( "Number of fluid cells = %d\n", fluid_cells );
	printf( "Reynolds number: %f\n", Re);
	printf( "Drag force = %f Lift force = %f\n", Fu, Fv);

	/* free memory */
	free_matrix(U,0,imax+1,0,jmax+1);
	free_matrix(V,0,imax+1,0,jmax+1);
	free_matrix(P,0,imax+1,0,jmax+1);
	free_matrix(K,0,imax+1,0,jmax+1);
	free_matrix(E,0,imax+1,0,jmax+1);
	
	free_matrix(F,0,imax,0,jmax);
	free_matrix(G,0,imax,0,jmax);
	free_matrix(RS,0,imax,0,jmax);

	free_imatrix(Flag,0,imax+1,0,jmax+1);

	return 0;
}
Beispiel #26
0
static int compute_tree_adaboost(ETree *etree,int n,int d,double *x[],int y[],
				 int nmodels,int stumps, int minsize)
{
  int i,b;
  int *samples;
  double **trx;
  int *try;
  double *prob;
  double *prob_copy;
  double sumalpha;
  double eps;
  int *pred;
  double *margin;
  double sumprob;
  

  if(nmodels<1){
    fprintf(stderr,"compute_tree_adaboost: nmodels must be greater than 0\n");
    return 1;
  }

 if(stumps != 0 && stumps != 1){
    fprintf(stderr,"compute_tree_bagging: parameter stumps must be 0 or 1\n");
    return 1;
  }

  if(minsize < 0){
    fprintf(stderr,"compute_tree_bagging: parameter minsize must be >= 0\n");
    return 1;
  }

  etree->nclasses=iunique(y,n, &(etree->classes));

  if(etree->nclasses<=0){
    fprintf(stderr,"compute_tree_adaboost: iunique error\n");
    return 1;
  }
  if(etree->nclasses==1){
    fprintf(stderr,"compute_tree_adaboost: only 1 class recognized\n");
    return 1;
  }

  if(etree->nclasses==2)
    if(etree->classes[0] != -1 || etree->classes[1] != 1){
      fprintf(stderr,"compute_tree_adaboost: for binary classification classes must be -1,1\n");
      return 1;
    }
  
  if(etree->nclasses>2){
    fprintf(stderr,"compute_tree_adaboost: multiclass classification not allowed\n");
    return 1;
  }

  if(!(etree->tree=(Tree *)calloc(nmodels,sizeof(Tree)))){
    fprintf(stderr,"compute_tree_adaboost: out of memory\n");
    return 1;
  }

  if(!(etree->weights=dvector(nmodels))){
    fprintf(stderr,"compute_tree_adaboost: out of memory\n");
    return 1;
  }

  if(!(trx=(double **)calloc(n,sizeof(double*)))){
    fprintf(stderr,"compute_tree_adaboost: out of memory\n");
    return 1;
  }
  if(!(try=ivector(n))){
    fprintf(stderr,"compute_tree_adaboost: out of memory\n");
    return 1;
  }
  
  if(!(prob_copy=dvector(n))){
    fprintf(stderr,"compute_tree_adaboost: out of memory\n");
    return 1;
  }
  if(!(prob=dvector(n))){
    fprintf(stderr,"compute_tree_adaboost: out of memory\n");
    return 1;
  }

  if(!(pred=ivector(n))){
    fprintf(stderr,"compute_tree_adaboost: out of memory\n");
    return 1;
  }

  for(i =0;i<n;i++)
    prob[i]=1.0/(double)n;

  etree->nmodels=nmodels;
  sumalpha=0.0;
  for(b=0;b<nmodels;b++){

    for(i =0;i<n;i++)
      prob_copy[i]=prob[i];
    if(sample(n, prob_copy, n, &samples, TRUE,b)!=0){
      fprintf(stderr,"compute_tree_adaboost: sample error\n");
      return 1;
    }

    for(i=0;i<n;i++){
      trx[i] = x[samples[i]];
      try[i] = y[samples[i]];
    }
    
    if(compute_tree(&(etree->tree[b]),n,d,trx,try,stumps,minsize)!=0){
      fprintf(stderr,"compute_tree_adaboost: compute_tree error\n");
      return 1;
    }
    free_ivector(samples);

    eps=0.0;
    for(i=0;i<n;i++){
      pred[i]=predict_tree(&(etree->tree[b]),x[i],&margin);
      if(pred[i] < -1 ){
	fprintf(stderr,"compute_tree_adaboost: predict_tree error\n");
	return 1;
      }
      if(pred[i]==0 || pred[i] != y[i])
	eps += prob[i];
      free_dvector(margin);
    }
    
    if(eps > 0.0 && eps < 0.5){
      etree->weights[b]=0.5 *log((1.0-eps)/eps);
      sumalpha+=etree->weights[b];
    }else{
      etree->nmodels=b;
      break;
    }
      
    sumprob=0.0;
    for(i=0;i<n;i++){
      prob[i]=prob[i]*exp(-etree->weights[b]*y[i]*pred[i]);
      sumprob+=prob[i];
    }

    if(sumprob <=0.0){
      fprintf(stderr,"compute_tree_adaboost: sumprob = 0\n");
      return 1;
    }
    for(i=0;i<n;i++)
      prob[i] /= sumprob;
    
  }
  
  if(etree->nmodels<=0){
    fprintf(stderr,"compute_tree_adaboost: no models produced\n");
    return 1;
  }

  if(sumalpha <=0){
      fprintf(stderr,"compute_tree_adaboost: sumalpha = 0\n");
      return 1;
  }
  for(b=0;b<etree->nmodels;b++)
    etree->weights[b] /= sumalpha;
  
  free(trx);
  free_ivector(try);
  free_ivector(pred);
  free_dvector(prob);
  free_dvector(prob_copy);
  return 0;

}



static void split_node(Node *node,Node *nodeL,Node *nodeR,int classes[],
		       int nclasses)
{
  int **indx;
  double *tmpvar;
  int i,j,k;
  int **npL , **npR;
  double **prL , **prR;
  int totL,totR;
  double a,b;
  double *decrease_in_inpurity;
  double max_decrease=0;
  int splitvar;
  int splitvalue;
  int morenumerous;

  nodeL->priors=dvector(nclasses);
  nodeR->priors=dvector(nclasses);
  nodeL->npoints_for_class=ivector(nclasses);
  nodeR->npoints_for_class=ivector(nclasses);
  indx=imatrix(node->nvar,node->npoints);
  tmpvar=dvector(node->npoints);
  decrease_in_inpurity=dvector(node->npoints-1);
  npL=imatrix(node->npoints,nclasses);
  npR=imatrix(node->npoints,nclasses);
  prL=dmatrix(node->npoints,nclasses);
  prR=dmatrix(node->npoints,nclasses);

  splitvar=0;
  splitvalue=0;
  max_decrease=0;

  for(i=0;i<node->nvar;i++){
    for(j=0;j<node->npoints;j++)
      tmpvar[j]=node->data[j][i];
    
    for(j=0;j<node->npoints;j++)
      indx[i][j]=j;
    dsort(tmpvar,indx[i],node->npoints,SORT_ASCENDING);

    for(k=0;k<nclasses;k++)
      if(node->classes[indx[i][0]]==classes[k]){
	npL[0][k] = 1;
	npR[0][k] = node->npoints_for_class[k]-npL[0][k];
      } else{
	npL[0][k] = 0;
	npR[0][k] = node->npoints_for_class[k];
      }
    
    for(j=1;j<node->npoints-1;j++)
      for(k=0;k<nclasses;k++)
	if(node->classes[indx[i][j]]==classes[k]){
	  npL[j][k] = npL[j-1][k] +1;
	  npR[j][k] = node->npoints_for_class[k] - npL[j][k];
	}
	else {
	  npL[j][k] = npL[j-1][k];
	  npR[j][k] = node->npoints_for_class[k] - npL[j][k];
	}


    for(j=0;j<node->npoints-1;j++){
      if(node->data[indx[i][j]][i] != node->data[indx[i][j+1]][i]){
	totL = totR = 0;
	
	for(k=0;k<nclasses;k++)
	  totL += npL[j][k];
	for(k=0;k<nclasses;k++)
	  prL[j][k] =  (double) npL[j][k] / (double) totL;
	
	for(k=0;k<nclasses;k++)
	  totR += npR[j][k];
	for(k=0;k<nclasses;k++)
	  prR[j][k] =  (double) npR[j][k] /(double)  totR;
	
	a = (double) totL / (double) node->npoints;
	b = (double) totR / (double) node->npoints ;
	
	decrease_in_inpurity[j] = gini_index(node->priors,nclasses) - 
	  a * gini_index(prL[j],nclasses) - b * gini_index(prR[j],nclasses);
      }
    }

    for(j=0;j<node->npoints-1;j++)
      if(decrease_in_inpurity[j] > max_decrease){
	max_decrease = decrease_in_inpurity[j];
	
	splitvar=i;
	splitvalue=j;

	for(k=0;k<nclasses;k++){
	  nodeL->priors[k]=prL[splitvalue][k];
	  nodeR->priors[k]=prR[splitvalue][k];
	  nodeL->npoints_for_class[k]=npL[splitvalue][k];
	  nodeR->npoints_for_class[k]=npR[splitvalue][k];
	}
      }
  }
  
  
  node->var=splitvar;
  node->value=(node->data[indx[splitvar][splitvalue]][node->var]+      
	       node->data[indx[splitvar][splitvalue+1]][node->var])/2.;

  nodeL->nvar=node->nvar;
  nodeL->nclasses=node->nclasses;
  nodeL->npoints=splitvalue+1;

  nodeL->terminal=TRUE;
  if(gini_index(nodeL->priors,nclasses) >0)
    nodeL->terminal=FALSE;

  nodeL->data=(double **) calloc(nodeL->npoints,sizeof(double *));
  nodeL->classes=ivector(nodeL->npoints);

  for(i=0;i<nodeL->npoints;i++){
    nodeL->data[i] = node->data[indx[splitvar][i]];
    nodeL->classes[i] = node->classes[indx[splitvar][i]];
  }
  
  
  morenumerous=0;
  for(k=0;k<nclasses;k++)
    if(nodeL->npoints_for_class[k] > morenumerous){
      morenumerous = nodeL->npoints_for_class[k];
      nodeL->node_class=classes[k];
    }
  


  nodeR->nvar=node->nvar;
  nodeR->nclasses=node->nclasses;
  nodeR->npoints=node->npoints-nodeL->npoints;

  nodeR->terminal=TRUE;
  if(gini_index(nodeR->priors,nclasses) >0)
    nodeR->terminal=FALSE;

  nodeR->data=(double **) calloc(nodeR->npoints,sizeof(double *));
  nodeR->classes=ivector(nodeR->npoints);

  for(i=0;i<nodeR->npoints;i++){
    nodeR->data[i] = node->data[indx[splitvar][nodeL->npoints+i]];
    nodeR->classes[i] = node->classes[indx[splitvar][nodeL->npoints+i]];
  }
  
  morenumerous=0;
  for(k=0;k<nclasses;k++)
    if(nodeR->npoints_for_class[k] > morenumerous){
      morenumerous = nodeR->npoints_for_class[k];
      nodeR->node_class=classes[k];
    }

  free_imatrix(indx,  node->nvar,node->npoints);
  free_imatrix(npL, node->npoints,nclasses);
  free_imatrix(npR, node->npoints,nclasses);
  free_dmatrix(prL, node->npoints,nclasses);
  free_dmatrix(prR, node->npoints,nclasses);
  free_dvector(tmpvar);
  free_dvector(decrease_in_inpurity);

}
Beispiel #27
0
/* "buildhessian" constructs a block Hessian and associated projection matrix 
   by application of the ANM.  Atomic coordinates and block definitions are 
   provided in 'coords' and 'blocks'; ANM parameters are provided in 'cutoff' 
   and 'gamma'.  On successful termination, the block Hessian is stored in 
   'hessian', and the projection matrix between block and all-atom spaces is 
   in 'projection'. */
static PyObject *buildhessian(PyObject *self, PyObject *args, PyObject *kwargs) {
  PDB_File PDB;
  dSparse_Matrix PP,HH;
  PyArrayObject *coords, *blocks, *hessian, *projection;
  double *XYZ,*hess,*proj;
  long *BLK;
  double **HB;
  double cutoff = 15., gamma = 1., scl=1., mlo=1., mhi=-1.;
  int natm, nblx, bmx;
  int hsize,elm,bdim,i,j;

  static char *kwlist[] = {"coords", "blocks", "hessian", "projection",
			   "natoms", "nblocks", "maxsize", "cutoff",
			   "gamma", "scale", "memlo", "memhi", NULL};

  if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OOOOiii|ddddd", kwlist,
				   &coords, &blocks, &hessian, &projection,
				   &natm, &nblx, &bmx, &cutoff, &gamma, &scl,
				   &mlo, &mhi))
    return NULL;

  XYZ = (double *) PyArray_DATA(coords);
  BLK = (long *) PyArray_DATA(blocks);
  hess = (double *) PyArray_DATA(hessian);
  proj = (double *) PyArray_DATA(projection);



  /* First allocate a PDB_File object to hold the coordinates and block
     indices of the atoms.  This wastes a bit of memory, but it prevents
     the need to re-write all of the RTB functions that are used in
     standalone C code. */
  PDB.atom=malloc((size_t)((natm+2)*sizeof(Atom_Line)));
  if(!PDB.atom) return PyErr_NoMemory();
  for(i=1;i<=natm;i++){
    PDB.atom[i].model=BLK[i-1];
    for(j=0;j<3;j++)
      PDB.atom[i].X[j]=XYZ[j*natm+i-1];
  }



  /* Find the projection matrix */
  hsize = 18*bmx*nblx > 12*natm ? 12*natm : 18*bmx*nblx;
  HH.IDX=imatrix(1,hsize,1,2);
  HH.X=dvector(1,hsize);
  elm=dblock_projections2(&HH,&PDB,natm,nblx,bmx);
  PP.IDX=imatrix(1,elm,1,2);
  PP.X=dvector(1,elm);
  for(i=1;i<=elm;i++){
    PP.IDX[i][1]=HH.IDX[i][1];
    PP.IDX[i][2]=HH.IDX[i][2];
    PP.X[i]=HH.X[i];
  }
  free_imatrix(HH.IDX,1,hsize,1,2);
  free_dvector(HH.X,1,hsize);
  dsort_PP2(&PP,elm,1);


  /* Calculate the block Hessian */
  HB=dmatrix(1,6*nblx,1,6*nblx);
  bdim=calc_blessian_mem(&PDB,&PP,natm,nblx,elm,HB,cutoff,gamma,scl,mlo,mhi);


  /* Cast the block Hessian and projection matrix into 1D arrays. */
  copy_prj_ofst(&PP,proj,elm,bdim);
  for(i=1;i<=bdim;i++)
    for(j=1;j<=bdim;j++)
      hess[bdim*(i-1)+j-1]=HB[i][j];


  free(PDB.atom);
  free_imatrix(PP.IDX,1,elm,1,2);
  free_dvector(PP.X,1,elm);
  free_dmatrix(HB,1,6*nblx,1,6*nblx);


  Py_RETURN_NONE;
}
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 evolvedependent(long **matrix,long **tree,int *trpd,int ttlbr,int notu,int *steps,int ind,int dep,int nstates,int ctype,int bias,int maxd,int **taxachange,int deltas,int UNKNOWN,int INAP)
Beispiel #30
0
void forward_SH(char *fileinp1){

	/* declaration of global variables */
      	extern int MYID, NF, MYID, LOG, NXG, NYG, NX, NY, NXNY, INFO, INVMAT, N_STREAMER;
	extern int READMOD, NX0, NY0, NPML, READ_REC, FSSHIFT, NFREQ1, NFREQ2, COLOR;
	extern int NPROCFREQ, NPROCSHOT, NP, MYID_SHOT, NSHOT1, NSHOT2, NF, SEISMO;
        extern float FC_low, FC_high, A0_PML;
	extern char LOG_FILE[STRING_SIZE];
	extern FILE *FP;
    
        /* declaration of local variables */
	int i, j, nstage, stagemax, nfreq;
        char ext[10];
	int ntr, nshots;

	FILE *FP_stage;

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

	/* output of parameters to log-file or stdout */
	if (MYID==0) write_par(FP);

	/* store old NX and NY values */
	NX0 = NX;
        NY0 = NY;

	/* add external PML layers */
	NX += 2 * NPML;
	NY += NPML + FSSHIFT;

	NXG = NX;
	NYG = NY;

	/* size of impedance matrix */
	NXNY = NX * NY;

	/* Calculate number of non-zero elements in impedance matrix */
	calc_nonzero();

	/* define data structures for acoustic problem */
	struct waveAC;
	struct matSH;
	struct PML_AC;
	struct acq;

	/* allocate memory for acoustic forward problem */
	alloc_waveAC(&waveAC,&PML_AC);
	alloc_matSH(&matSH);

	/* If INVMAT!=0 deactivate unnecessary output */
	INFO=0;

	/* If INVMAT==0 allow unnecessary output */
	if(INVMAT==0){
	   INFO=1;
	}

	/*if (MYID == 0) info_mem(stdout,NLBFGS_vec,ntr);*/

	/* Reading source positions from SOURCE_FILE */ 	
	acq.srcpos=sources(&nshots);

	/* read receiver positions from receiver files for each shot */
	if(READ_REC==0){
	    acq.recpos=receiver(FP, &ntr, 1);	                         
	}

	/* read/create S-wave velocity and density models */
	if (READMOD){
	    readmod_SH(&matSH); 
	}else{
	    model_SH(&matSH);
	}

	/* read parameters from workflow-file (stdin) */
	FP=fopen(fileinp1,"r");
	if(FP==NULL) {
		if (MYID == 0){
			printf("\n==================================================================\n");
			printf(" Cannot open GERMAINE 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)) != EOF)
	if (i=='\n') ++stagemax;
	rewind(FP);
	stagemax--;
	fclose(FP);  

	/* loop over GERMAINE workflow stages */
	for(nstage=1;nstage<=stagemax;nstage++){

		/* read workflow input file *.inp */
		FP_stage=fopen(fileinp1,"r");
		read_par_inv(FP_stage,nstage,stagemax);

		/* estimate frequency sample interval and set first frequency */
		if(NF>1){waveAC.dfreq = (FC_high-FC_low) / (NF-1);}
		else{waveAC.dfreq = (FC_high-FC_low) / NF;}
                
		/* estimate frequencies for current FWI stage */
		waveAC.stage_freq = vector(1,NF);
		waveAC.stage_freq[1] = FC_low;

		for(i=2;i<=NF;i++){
		    waveAC.stage_freq[i] = waveAC.stage_freq[i-1] + waveAC.dfreq; 
		}   		

		/* split MPI communicator for shot parallelization */
		COLOR = MYID / NPROCFREQ;

		MPI_Comm shot_comm;
		MPI_Comm_split(MPI_COMM_WORLD, COLOR, MYID, &shot_comm);		

		/* esimtate communicator size for shot_comm and number of colors (NPROCSHOT) */
		MPI_Comm_rank(shot_comm, &MYID_SHOT);
		NPROCSHOT = NP / NPROCFREQ;

		/* Initiate MPI shot parallelization */
		init_MPIshot(nshots);

		/* Initiate MPI frequency parallelization */		
                init_MPIfreq();

                /* allocate memory for FD data */
		if(READ_REC==0){
 	           alloc_seis_AC(&waveAC,ntr,nshots);			                         
	        }

		/* loop over frequencies at each stage */
		for(nfreq=NFREQ1;nfreq<NFREQ2;nfreq++){

			/* set frequency on local MPI process */
			waveAC.freq = waveAC.stage_freq[nfreq]; 

			/* define PML damping profiles */
			pml_pro(&PML_AC,&waveAC);			
	
			/* solve forward problem for all shots*/
			forward_shot_SH(&waveAC,&PML_AC,&matSH,acq.srcpos,nshots,acq.recpos,ntr,nstage,nfreq);

		} /* end of loop over frequencies */

		/* write FD seismogram files */
		if(SEISMO==1){
	   	   write_seis_AC(&waveAC,nshots,ntr,nstage);
		}

		/* free memory */
		if(READ_REC==0){
		   free_vector(waveAC.precr,1,ntr*NF*nshots);
		   free_vector(waveAC.preci,1,ntr*NF*nshots);
		}

		/* free shot_comm */
		MPI_Comm_free(&shot_comm);

  	} /* end of loop over workflow stages*/

	if(READ_REC==0){free_imatrix(acq.recpos,1,3,1,ntr);}
	
}