xref: /petsc/src/mat/impls/aij/seq/ij.c (revision 3ba1676111f5c958fe6c2729b46ca4d523958bb3)
1d6dfbf8fSBarry Smith 
2c6db04a5SJed Brown #include <../src/mat/impls/aij/seq/aij.h>
32d9e4a2aSBarry Smith 
42d9e4a2aSBarry Smith /*
53b2fbd54SBarry Smith   MatToSymmetricIJ_SeqAIJ - Convert a (generally nonsymmetric) sparse AIJ matrix
63b2fbd54SBarry Smith            to IJ format (ignore the "A" part) Allocates the space needed. Uses only
7d5d45c9bSBarry Smith            the lower triangular part of the matrix.
82d9e4a2aSBarry Smith 
92d9e4a2aSBarry Smith     Description:
102d9e4a2aSBarry Smith     Take the data in the row-oriented sparse storage and build the
112d9e4a2aSBarry Smith     IJ data for the Matrix.  Return 0 on success,row + 1 on failure
122462f5fdSStefano Zampini     at that row. Produces the ij for a symmetric matrix by using
132462f5fdSStefano Zampini     the lower triangular part of the matrix if lower_triangular is PETSC_TRUE;
1413d4cfd3SStefano Zampini     it uses the upper triangular otherwise.
152d9e4a2aSBarry Smith 
162d9e4a2aSBarry Smith     Input Parameters:
172d9e4a2aSBarry Smith .   Matrix - matrix to convert
182462f5fdSStefano Zampini .   lower_triangular - symmetrize the lower triangular part
19bcd2baecSBarry Smith .   shiftin - the shift for the original matrix (0 or 1)
2091e9ee9fSBarry Smith .   shiftout - the shift required for the ordering routine (0 or 1)
212d9e4a2aSBarry Smith 
222d9e4a2aSBarry Smith     Output Parameters:
232d9e4a2aSBarry Smith .   ia     - ia part of IJ representation (row information)
242d9e4a2aSBarry Smith .   ja     - ja part (column indices)
252d9e4a2aSBarry Smith 
2611a5261eSBarry Smith     Note:
27b833fc0dSLois Curfman McInnes     Both ia and ja may be freed with PetscFree();
28b833fc0dSLois Curfman McInnes     This routine is provided for ordering routines that require a
29b833fc0dSLois Curfman McInnes     symmetric structure.  It is required since those routines call
30b833fc0dSLois Curfman McInnes     SparsePak routines that expect a symmetric  matrix.
312d9e4a2aSBarry Smith */
32d71ae5a4SJacob Faibussowitsch PetscErrorCode MatToSymmetricIJ_SeqAIJ(PetscInt m, PetscInt *ai, PetscInt *aj, PetscBool lower_triangular, PetscInt shiftin, PetscInt shiftout, PetscInt **iia, PetscInt **jja)
33d71ae5a4SJacob Faibussowitsch {
3438baddfdSBarry Smith   PetscInt *work, *ia, *ja, *j, i, nz, row, col;
352d9e4a2aSBarry Smith 
363a40ed3dSBarry Smith   PetscFunctionBegin;
372d9e4a2aSBarry Smith   /* allocate space for row pointers */
389566063dSJacob Faibussowitsch   PetscCall(PetscCalloc1(m + 1, &ia));
39b0a32e0cSBarry Smith   *iia = ia;
409566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(m + 1, &work));
412d9e4a2aSBarry Smith 
422d9e4a2aSBarry Smith   /* determine the number of columns in each row */
433b2fbd54SBarry Smith   ia[0] = shiftout;
4431625ec5SSatish Balay   for (row = 0; row < m; row++) {
453439631bSBarry Smith     nz = ai[row + 1] - ai[row];
460b6503f3SSatish Balay     j  = aj + ai[row] + shiftin;
472d9e4a2aSBarry Smith     while (nz--) {
4817603e33SSatish Balay       col = *j++ + shiftin;
492462f5fdSStefano Zampini       if (lower_triangular) {
502205254eSKarl Rupp         if (col > row) break;
512462f5fdSStefano Zampini       } else {
522462f5fdSStefano Zampini         if (col < row) break;
532462f5fdSStefano Zampini       }
542d9e4a2aSBarry Smith       if (col != row) ia[row + 1]++;
552d9e4a2aSBarry Smith       ia[col + 1]++;
562d9e4a2aSBarry Smith     }
572d9e4a2aSBarry Smith   }
582d9e4a2aSBarry Smith 
59bcd2baecSBarry Smith   /* shiftin ia[i] to point to next row */
6031625ec5SSatish Balay   for (i = 1; i < m + 1; i++) {
610b6503f3SSatish Balay     row = ia[i - 1];
622d9e4a2aSBarry Smith     ia[i] += row;
630b6503f3SSatish Balay     work[i - 1] = row - shiftout;
642d9e4a2aSBarry Smith   }
652d9e4a2aSBarry Smith 
662d9e4a2aSBarry Smith   /* allocate space for column pointers */
6731625ec5SSatish Balay   nz = ia[m] + (!shiftin);
689566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(nz, &ja));
69b0a32e0cSBarry Smith   *jja = ja;
702d9e4a2aSBarry Smith 
712d9e4a2aSBarry Smith   /* loop over lower triangular part putting into ja */
7231625ec5SSatish Balay   for (row = 0; row < m; row++) {
733439631bSBarry Smith     nz = ai[row + 1] - ai[row];
740b6503f3SSatish Balay     j  = aj + ai[row] + shiftin;
752d9e4a2aSBarry Smith     while (nz--) {
7617603e33SSatish Balay       col = *j++ + shiftin;
772462f5fdSStefano Zampini       if (lower_triangular) {
782205254eSKarl Rupp         if (col > row) break;
792462f5fdSStefano Zampini       } else {
802462f5fdSStefano Zampini         if (col < row) break;
812462f5fdSStefano Zampini       }
822205254eSKarl Rupp       if (col != row) ja[work[col]++] = row + shiftout;
833b2fbd54SBarry Smith       ja[work[row]++] = col + shiftout;
842d9e4a2aSBarry Smith     }
852d9e4a2aSBarry Smith   }
869566063dSJacob Faibussowitsch   PetscCall(PetscFree(work));
87*3ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
882d9e4a2aSBarry Smith }
89