#include "BSprivate.h" /*@ BSeasy_A - Given A in a standard numerical format, construct the sparse A that we need for BlockSolve. This routine is particularly useful for matrices created in Fortran. The rows on a processor must be contiguous in the global numbering. If they are not, then other BlockSolve routines must be called to construct the matrix for BlockSolve. Arrays are indexed starting with 0. The values in a row must be sorted according to column number. Input Parameters: start_num - the global number of the first row on this proc. n - the number of rows on *this* processor. rp - an array of indices of length n+1 -- rp(i) gives the beginning entry of row i in cval and aval. cval - an array of column numbers. cval[i] gives the column number of entry i in aval. aval - an array of the nonzero values in the sparse matrix. procinfo - the usual processor information Returns: a pointer to a sparse matrix in BlockSolve format. @*/ BSspmat *BSeasy_A(int start_num, int n, int *rp, int *cval, FLOAT *aval, BSprocinfo *procinfo) { BSspmat *A; int i, j; int *i_ptr; int gnum; /* set up the structure and mapping for the sparse matrix */ /* allocate the pointer to A */ A = (BSspmat *) MALLOC(sizeof(BSspmat)); /* set the number of local rows */ A->num_rows = n; /* set the number of global rows */ A->global_num_rows = n; GISUM(&(A->global_num_rows),1,&i,procinfo->procset); /* allocate the array of rows, and the space in each row */ /* allow for a max length in each row, but set the current length to 0 */ A->rows = (BSsprow **) MALLOC(sizeof(BSsprow *)*A->num_rows); for (i=0;inum_rows;i++) { A->rows[i] = (BSsprow *) MALLOC(sizeof(BSsprow)); A->rows[i]->length = rp[i+1] - rp[i]; A->rows[i]->col = &(cval[rp[i]]); A->rows[i]->nz = &(aval[rp[i]]); gnum = start_num + i; A->rows[i]->diag_ind = -1; for (j=0;jrows[i]->length;j++) { if (A->rows[i]->col[j] == gnum) { A->rows[i]->diag_ind = j; break; } } } /* allocate a pointer to a mapping structure */ A->map = (BSmapping *) MALLOC(sizeof(BSmapping)); /* set up the local to global mapping */ /* all we need for this is the beginning number (offset) of */ /* the local rows in the global numbering (see BSloc2glob) */ A->map->vlocal2global = (void *) MALLOC(sizeof(int)); i_ptr = (int *) A->map->vlocal2global; /* pointer to mapping data */ *(i_ptr) = start_num; A->map->flocal2global = BSloc2glob; /* the mapping function */ A->map->free_l2g = BSfreel2g; /* the routine to free the mapping */ /* set up the global to local mapping */ /* all we need for this is the beginning number (offset) of */ /* the local rows in the global numbering (see BSglob2loc) */ A->map->vglobal2local = (void *) MALLOC(sizeof(int)); i_ptr = (int *) A->map->vglobal2local; /* pointer to mapping data */ *(i_ptr) = start_num; A->map->fglobal2local = BSglob2loc; /* the mapping function */ A->map->free_g2l = BSfreeg2l; /* the routine to free the mapping */ /* set up the global to processor number mapping */ /* we call the routine BSmake_off_map to create the mapping data */ /* the local rows in the global numbering (see BSglob2proc) */ A->map->vglobal2proc = (void *) BSmake_off_map(start_num,procinfo,A->global_num_rows); CHKERRN(0); A->map->fglobal2proc = BSglob2proc; /* the mapping function */ A->map->free_g2p = BSfree_off_map; /* the routine to free the mapping */ /* check for errors in A */ if (procinfo->error_check) { BSrow_err_check(A,procinfo); CHKERRN(0); } return(A); }