1 #include "BSprivate.h"
2 
3 /*@ BSeasy_A - Given A in a standard numerical format, construct the
4              sparse A that we need for BlockSolve.  This routine is
5              particularly useful for matrices created in Fortran.
6              The rows on a processor must be contiguous in the
7              global numbering.  If they are not, then other BlockSolve
8              routines must be called to construct the matrix for BlockSolve.
9              Arrays are indexed starting with 0.
10              The values in a row must be sorted according to column number.
11 
12      Input Parameters:
13      start_num - the global number of the first row on this proc.
14      n - the number of rows on *this* processor.
15      rp - an array of indices of length n+1 -- rp(i) gives the beginning
16           entry of row i in cval and aval.
17      cval - an array of column numbers.  cval[i] gives the column number
18             of entry i in aval.
19      aval - an array of the nonzero values in the sparse matrix.
20      procinfo - the usual processor information
21 
22 
23      Returns:
24      a pointer to a sparse matrix in BlockSolve format.
25 
26  @*/
27 
BSeasy_A(int start_num,int n,int * rp,int * cval,FLOAT * aval,BSprocinfo * procinfo)28 BSspmat *BSeasy_A(int start_num, int n, int *rp, int *cval,
29 			FLOAT *aval, BSprocinfo *procinfo)
30 {
31 	BSspmat *A;
32 	int	i, j;
33 	int	*i_ptr;
34 	int	gnum;
35 
36 	/* set up the structure and mapping for the sparse matrix */
37 	/* allocate the pointer to A */
38 	A = (BSspmat *) MALLOC(sizeof(BSspmat));
39 
40 	/* set the number of local rows */
41 	A->num_rows = n;
42 
43 	/* set the number of global rows */
44 	A->global_num_rows = n;
45 	GISUM(&(A->global_num_rows),1,&i,procinfo->procset);
46 
47 	/* allocate the array of rows, and the space in each row */
48 	/* allow for a max length in each row, but set the current length to 0 */
49 	A->rows = (BSsprow **) MALLOC(sizeof(BSsprow *)*A->num_rows);
50 	for (i=0;i<A->num_rows;i++) {
51 		A->rows[i] = (BSsprow *) MALLOC(sizeof(BSsprow));
52 		A->rows[i]->length = rp[i+1] - rp[i];
53 		A->rows[i]->col = &(cval[rp[i]]);
54 		A->rows[i]->nz = &(aval[rp[i]]);
55 		gnum = start_num + i;
56 		A->rows[i]->diag_ind = -1;
57 		for (j=0;j<A->rows[i]->length;j++) {
58 			if (A->rows[i]->col[j] == gnum) {
59 				A->rows[i]->diag_ind = j;
60 				break;
61 			}
62 		}
63 	}
64 
65 	/* allocate a pointer to a mapping structure */
66 	A->map = (BSmapping *) MALLOC(sizeof(BSmapping));
67 
68 	/* set up the local to global mapping */
69 	/* all we need for this is the beginning number (offset) of */
70 	/* the local rows in the global numbering (see BSloc2glob) */
71 	A->map->vlocal2global = (void *) MALLOC(sizeof(int));
72 	i_ptr = (int *) A->map->vlocal2global; /* pointer to mapping data */
73 	*(i_ptr) = start_num;
74 	A->map->flocal2global = BSloc2glob; /* the mapping function */
75 	A->map->free_l2g = BSfreel2g; /* the routine to free the mapping */
76 
77 	/* set up the global to local mapping */
78 	/* all we need for this is the beginning number (offset) of */
79 	/* the local rows in the global numbering (see BSglob2loc) */
80 	A->map->vglobal2local = (void *) MALLOC(sizeof(int));
81 	i_ptr = (int *) A->map->vglobal2local;	/* pointer to mapping data */
82 	*(i_ptr) = start_num;
83 	A->map->fglobal2local = BSglob2loc; /* the mapping function */
84 	A->map->free_g2l = BSfreeg2l;	/* the routine to free the mapping */
85 
86 	/* set up the global to processor number mapping */
87 	/* we call the routine BSmake_off_map to create the mapping data */
88 	/* the local rows in the global numbering (see BSglob2proc) */
89 	A->map->vglobal2proc = (void *)
90 		BSmake_off_map(start_num,procinfo,A->global_num_rows); CHKERRN(0);
91 	A->map->fglobal2proc = BSglob2proc;	/* the mapping function */
92 	A->map->free_g2p = BSfree_off_map;	/* the routine to free the mapping */
93 
94 	/* check for errors in A */
95 	if (procinfo->error_check) {
96 		BSrow_err_check(A,procinfo); CHKERRN(0);
97 	}
98 	return(A);
99 }
100