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