xref: /petsc/src/mat/impls/aij/seq/ij.c (revision a4af0ceea8a251db97ee0dc5c0d52d4adf50264a)
1 
2 #include <../src/mat/impls/aij/seq/aij.h>
3 
4 /*
5   MatToSymmetricIJ_SeqAIJ - Convert a (generally nonsymmetric) sparse AIJ matrix
6            to IJ format (ignore the "A" part) Allocates the space needed. Uses only
7            the lower triangular part of the matrix.
8 
9     Description:
10     Take the data in the row-oriented sparse storage and build the
11     IJ data for the Matrix.  Return 0 on success,row + 1 on failure
12     at that row. Produces the ij for a symmetric matrix by using
13     the lower triangular part of the matrix if lower_triangular is PETSC_TRUE;
14     it uses the upper triangular otherwise.
15 
16     Input Parameters:
17 .   Matrix - matrix to convert
18 .   lower_triangular - symmetrize the lower triangular part
19 .   shiftin - the shift for the original matrix (0 or 1)
20 .   shiftout - the shift required for the ordering routine (0 or 1)
21 
22     Output Parameters:
23 .   ia     - ia part of IJ representation (row information)
24 .   ja     - ja part (column indices)
25 
26     Notes:
27     Both ia and ja may be freed with PetscFree();
28     This routine is provided for ordering routines that require a
29     symmetric structure.  It is required since those routines call
30     SparsePak routines that expect a symmetric  matrix.
31 */
32 PetscErrorCode MatToSymmetricIJ_SeqAIJ(PetscInt m,PetscInt *ai,PetscInt *aj,PetscBool lower_triangular,PetscInt shiftin,PetscInt shiftout,PetscInt **iia,PetscInt **jja)
33 {
34   PetscErrorCode ierr;
35   PetscInt       *work,*ia,*ja,*j,i,nz,row,col;
36 
37   PetscFunctionBegin;
38   /* allocate space for row pointers */
39   ierr = PetscCalloc1(m+1,&ia);CHKERRQ(ierr);
40   *iia = ia;
41   ierr = PetscMalloc1(m+1,&work);CHKERRQ(ierr);
42 
43   /* determine the number of columns in each row */
44   ia[0] = shiftout;
45   for (row = 0; row < m; row++) {
46     nz = ai[row+1] - ai[row];
47     j  = aj + ai[row] + shiftin;
48     while (nz--) {
49       col = *j++ + shiftin;
50       if (lower_triangular) {
51         if (col > row) break;
52       } else {
53         if (col < row) break;
54       }
55       if (col != row) ia[row+1]++;
56       ia[col+1]++;
57     }
58   }
59 
60   /* shiftin ia[i] to point to next row */
61   for (i=1; i<m+1; i++) {
62     row       = ia[i-1];
63     ia[i]    += row;
64     work[i-1] = row - shiftout;
65   }
66 
67   /* allocate space for column pointers */
68   nz   = ia[m] + (!shiftin);
69   ierr = PetscMalloc1(nz,&ja);CHKERRQ(ierr);
70   *jja = ja;
71 
72   /* loop over lower triangular part putting into ja */
73   for (row = 0; row < m; row++) {
74     nz = ai[row+1] - ai[row];
75     j  = aj + ai[row] + shiftin;
76     while (nz--) {
77       col = *j++ + shiftin;
78       if (lower_triangular) {
79         if (col > row) break;
80       } else {
81         if (col < row) break;
82       }
83       if (col != row) ja[work[col]++] = row + shiftout;
84       ja[work[row]++] = col + shiftout;
85     }
86   }
87   ierr = PetscFree(work);CHKERRQ(ierr);
88   PetscFunctionReturn(0);
89 }
90 
91