#include <../src/mat/impls/aij/seq/aij.h> /* MatToSymmetricIJ_SeqAIJ - Convert a (generally nonsymmetric) sparse AIJ matrix to IJ format (ignore the "A" part) Allocates the space needed. Uses only the lower triangular part of the matrix. Description: Take the data in the row-oriented sparse storage and build the IJ data for the Matrix. Return 0 on success,row + 1 on failure at that row. Produces the ij for a symmetric matrix by using the lower triangular part of the matrix if lower_triangular is PETSC_TRUE; it uses the upper triangular otherwise. Input Parameters: . Matrix - matrix to convert . lower_triangular - symmetrize the lower triangular part . shiftin - the shift for the original matrix (0 or 1) . shiftout - the shift required for the ordering routine (0 or 1) Output Parameters: . ia - ia part of IJ representation (row information) . ja - ja part (column indices) Note: Both ia and ja may be freed with PetscFree(); This routine is provided for ordering routines that require a symmetric structure. It is required since those routines call SparsePak routines that expect a symmetric matrix. */ PetscErrorCode MatToSymmetricIJ_SeqAIJ(PetscInt m, PetscInt *ai, PetscInt *aj, PetscBool lower_triangular, PetscInt shiftin, PetscInt shiftout, PetscInt **iia, PetscInt **jja) { PetscInt *work, *ia, *ja, *j, i, nz, row, col; PetscFunctionBegin; /* allocate space for row pointers */ PetscCall(PetscCalloc1(m + 1, &ia)); *iia = ia; PetscCall(PetscMalloc1(m + 1, &work)); /* determine the number of columns in each row */ ia[0] = shiftout; for (row = 0; row < m; row++) { nz = ai[row + 1] - ai[row]; j = aj + ai[row] + shiftin; while (nz--) { col = *j++ + shiftin; if (lower_triangular) { if (col > row) break; } else { if (col < row) break; } if (col != row) ia[row + 1]++; ia[col + 1]++; } } /* shiftin ia[i] to point to next row */ for (i = 1; i < m + 1; i++) { row = ia[i - 1]; ia[i] += row; work[i - 1] = row - shiftout; } /* allocate space for column pointers */ nz = ia[m] + (!shiftin); PetscCall(PetscMalloc1(nz, &ja)); *jja = ja; /* loop over lower triangular part putting into ja */ for (row = 0; row < m; row++) { nz = ai[row + 1] - ai[row]; j = aj + ai[row] + shiftin; while (nz--) { col = *j++ + shiftin; if (lower_triangular) { if (col > row) break; } else { if (col < row) break; } if (col != row) ja[work[col]++] = row + shiftout; ja[work[row]++] = col + shiftout; } } PetscCall(PetscFree(work)); PetscFunctionReturn(PETSC_SUCCESS); }