#include "BSprivate.h"

/*@ BScopy_par_mat - Create of copy of a matrix

    Input Parameters:
.   A - The sparse matrix

    Returns:
    the copy of A

    Notes:
$   In the ICC case, we reuse the block matrices
$     in the cliques (we use the unused portion).
$   We reuse the permutations.
$   We reuse the map color_2_cl.
$   We reuse the diagonal.
$   We reuse the global numbering.
$   We reuse the reperm structure.
$   As in the original matrix, we only have a pointer
$     to the map.  IMPORTANT: this reuse must be 
$     accounted for when freeing things.
 @*/
BSpar_mat *BScopy_par_mat(BSpar_mat *A)
{
	BSpar_mat *newA;
	int	i, j, size;
	BScl_2_inode *cl2i, *newcl2i;
	BSinode_list *inodes, *new_inodes;

	MY_MALLOCN(newA,(BSpar_mat *),sizeof(BSpar_mat),1);
	newA->num_rows = A->num_rows;
	newA->global_num_rows = A->global_num_rows;
	newA->local_nnz = A->local_nnz;
	newA->local_num_inodes = A->local_num_inodes;
	newA->global_num_inodes = A->global_num_inodes;
	newA->local_num_cliques = A->local_num_cliques;
	newA->global_num_cliques = A->global_num_cliques;
	newA->num_colors = A->num_colors;
	newA->max_local_row_length = A->max_local_row_length;
	newA->symmetric = A->symmetric;
	newA->icc_storage = A->icc_storage;

	newA->perm = A->perm;
	newA->inv_perm = A->inv_perm;
	newA->global_row_num = A->global_row_num;
	newA->color2clique = A->color2clique;
	newA->diag = A->diag;
	newA->save_diag = A->save_diag;
	newA->scale_diag = A->scale_diag;

	newA->map = A->map;
	newA->reperm = A->reperm;

	/* make a copy of the "clique to inode" structure */
	cl2i = A->clique2inode;
	MY_MALLOCN(newcl2i,(BScl_2_inode *),sizeof(BScl_2_inode),2);
	newA->clique2inode = newcl2i;
	newcl2i->num_cols = cl2i->num_cols;
	MY_MALLOCN(newcl2i->g_offset,(int *),sizeof(int)*(cl2i->num_cols+1),3);
	MY_MALLOCN(newcl2i->proc,(int *),sizeof(int)*(cl2i->num_cols+1),4);
	MY_MALLOCN(newcl2i->inode_index,(int *),sizeof(int)*(cl2i->num_cols+1),5);
	MY_MALLOCN(newcl2i->d_mats,(BSdense *),sizeof(BSdense)*(cl2i->num_cols+1),6);
	for (i=0;i<cl2i->num_cols+1;i++) {
		newcl2i->g_offset[i] = cl2i->g_offset[i];
		newcl2i->proc[i] = cl2i->proc[i];
		newcl2i->inode_index[i] = cl2i->inode_index[i];
		newcl2i->d_mats[i].size = cl2i->d_mats[i].size;
		newcl2i->d_mats[i].local_ind = cl2i->d_mats[i].local_ind;
		if(A->icc_storage) {
			newcl2i->d_mats[i].matrix = cl2i->d_mats[i].matrix;
		} else {
			/* We do not reuse the clique matrices (ILU) */
			size = cl2i->d_mats[i].size;
			if ((i < cl2i->num_cols) && (size > 0)) {
				MY_MALLOCN(newcl2i->d_mats[i].matrix,(FLOAT *),
					size*size*sizeof(FLOAT)+size*sizeof(int),7);
			} else {
				newcl2i->d_mats[i].matrix = NULL;
			}
		}
	}

	/* make a copy of the "inode" structure */
	inodes = A->inodes;
	MY_MALLOCN(new_inodes,(BSinode_list *),sizeof(BSinode_list),7);
	newA->inodes = new_inodes;
	new_inodes->length = inodes->length;
	MY_MALLOCN(new_inodes->list,(BSinode *),
		sizeof(BSinode)*(inodes->length+1),8);
	new_inodes->list[inodes->length].gcol_num = INT_MAX;
	MY_MALLOCN(new_inodes->list[inodes->length].o_gcol_num,(int *),
		sizeof(int),21);
	new_inodes->list[inodes->length].o_gcol_num[0] = INT_MAX;
	for (i=0;i<inodes->length;i++) {
		new_inodes->list[i].num_cols = inodes->list[i].num_cols;
		new_inodes->list[i].gcol_num = inodes->list[i].gcol_num;
		MY_MALLOCN(new_inodes->list[i].o_gcol_num,(int *),
			sizeof(int)*new_inodes->list[i].num_cols,20);
		for (j=0;j<new_inodes->list[i].num_cols;j++) {
			new_inodes->list[i].o_gcol_num[j] = inodes->list[i].o_gcol_num[j];
		}
		new_inodes->list[i].length = inodes->list[i].length;
		new_inodes->list[i].below_diag = inodes->list[i].below_diag;
		MY_MALLOCN(new_inodes->list[i].row_num,(int *),
			sizeof(int)*new_inodes->list[i].length,10);
		for (j=0;j<new_inodes->list[i].length;j++) {
			new_inodes->list[i].row_num[j] = inodes->list[i].row_num[j];
		}
		MY_MALLOCN(new_inodes->list[i].nz,(FLOAT *),sizeof(FLOAT)*
			new_inodes->list[i].length*new_inodes->list[i].num_cols,11);
	}

	/* now, fill in the nonzero values */
	BScopy_nz(A,newA); CHKERRN(0);

	return(newA);
}


syntax highlighted by Code2HTML, v. 0.9.1