Actual source code: sro.c

  1: #include <../src/mat/impls/baij/seq/baij.h>
  2: #include <../src/mat/impls/sbaij/seq/sbaij.h>

  4: /*@
  5:   MatReorderingSeqSBAIJ - Prepare an updated index structure for a symmetric reordering of a `MATSEQSBAIJ` matrix.

  7:   Not Collective

  9:   Input Parameters:
 10: + A    - the `MATSEQSBAIJ` matrix
 11: - perm - the (assumed symmetric) permutation to be applied

 13:   Level: developer

 15:   Notes:
 16:   This routine currently raises `PETSC_ERR_SUP`; matrix reordering is not supported for `MATSEQSBAIJ` matrices,
 17:   so callers should convert to `MATSEQAIJ` first.

 19:   The intent (unimplemented) is to compute a new index set `(inew, jnew)` for `A` and a value map so that
 20:   all nonzero entries `A(perm(i), perm(k))` are stored in the upper triangle; the matrix itself is not permuted.

 22: .seealso: `Mat`, `MATSEQSBAIJ`, `MatGetOrdering()`, `MatPermute()`
 23: @*/
 24: PetscErrorCode MatReorderingSeqSBAIJ(Mat A, IS perm)
 25: {
 26:   Mat_SeqSBAIJ  *a   = (Mat_SeqSBAIJ *)A->data;
 27:   const PetscInt mbs = a->mbs;

 29:   PetscFunctionBegin;
 30:   if (!mbs) PetscFunctionReturn(PETSC_SUCCESS);
 31:   SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP, "Matrix reordering is not supported for sbaij matrix. Use aij format");
 32: #if 0
 33:   const PetscInt *rip,*riip;
 34:   PetscInt       *ai,*aj,*r;
 35:   PetscInt       *nzr,nz,jmin,jmax,j,k,ajk,i;
 36:   IS             iperm;  /* inverse of perm */
 37:   PetscCall(ISGetIndices(perm,&rip));

 39:   PetscCall(ISInvertPermutation(perm,PETSC_DECIDE,&iperm));
 40:   PetscCall(ISGetIndices(iperm,&riip));

 42:   for (i=0; i<mbs; i++) PetscCheck(rip[i] == riip[i],PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"Non-symmetric permutation, use symmetric permutation for symmetric matrices");
 43:   PetscCall(ISRestoreIndices(iperm,&riip));
 44:   PetscCall(ISDestroy(&iperm));

 46:   if (!a->inew) PetscCall(PetscMalloc2(mbs+1,&ai, 2*a->i[mbs],&aj));
 47:   else {
 48:     ai = a->inew;
 49:     aj = a->jnew;
 50:   }
 51:   PetscCall(PetscArraycpy(ai,a->i,mbs+1));
 52:   PetscCall(PetscArraycpy(aj,a->j,a->i[mbs]));

 54:   /*
 55:      Phase 1: Find row index r in which to store each nonzero.
 56:               Initialize count of nonzeros to be stored in each row (nzr).
 57:               At the end of this phase, a nonzero a(*,*)=a(r(),aj())
 58:               s.t. a(perm(r),perm(aj)) will fall into upper triangle part.
 59:   */

 61:   PetscCall(PetscMalloc1(mbs,&nzr));
 62:   PetscCall(PetscMalloc1(ai[mbs],&r));
 63:   for (i=0; i<mbs; i++) nzr[i] = 0;
 64:   for (i=0; i<ai[mbs]; i++) r[i] = 0;

 66:   /*  for each nonzero element */
 67:   for (i=0; i<mbs; i++) {
 68:     nz = ai[i+1] - ai[i];
 69:     j  = ai[i];
 70:     /* printf("nz = %d, j=%d\n",nz,j); */
 71:     while (nz--) {
 72:       /*  --- find row (=r[j]) and column (=aj[j]) in which to store a[j] ...*/
 73:       k = aj[j];                          /* col. index */
 74:       /* printf("nz = %d, k=%d\n", nz,k); */
 75:       /* for entry that will be permuted into lower triangle, swap row and col. index */
 76:       if (rip[k] < rip[i]) aj[j] = i;
 77:       else k = i;

 79:       r[j] = k; j++;
 80:       nzr[k]++;  /* increment count of nonzeros in that row */
 81:     }
 82:   }

 84:   /* Phase 2: Find new ai and permutation to apply to (aj,a).
 85:               Determine pointers (r) to delimit rows in permuted (aj,a).
 86:               Note: r is different from r used in phase 1.
 87:               At the end of this phase, (aj[j],a[j]) will be stored in
 88:               (aj[r(j)],a[r(j)]).
 89:   */
 90:   for (i=0; i<mbs; i++) {
 91:     ai[i+1] = ai[i] + nzr[i];
 92:     nzr[i]  = ai[i+1];
 93:   }

 95:   /* determine where each (aj[j], a[j]) is stored in new (aj,a)
 96:      for each nonzero element (in reverse order) */
 97:   jmin = ai[0]; jmax = ai[mbs];
 98:   nz   = jmax - jmin;
 99:   j    = jmax-1;
100:   while (nz--) {
101:     i = r[j];  /* row value */
102:     if (aj[j] == i) r[j] = ai[i]; /* put diagonal nonzero at beginning of row */
103:     else { /* put off-diagonal nonzero in last unused location in row */
104:       nzr[i]--; r[j] = nzr[i];
105:     }
106:     j--;
107:   }

109:   a->a2anew = aj + ai[mbs];
110:   PetscCall(PetscArraycpy(a->a2anew,r,ai[mbs]));

112:   /* Phase 3: permute (aj,a) to upper triangular form (wrt new ordering) */
113:   for (j=jmin; j<jmax; j++) {
114:     while (r[j] != j) {
115:       k   = r[j]; r[j] = r[k]; r[k] = k;
116:       ajk = aj[k]; aj[k] = aj[j]; aj[j] = ajk;
117:       /* ak = aa[k]; aa[k] = aa[j]; aa[j] = ak; */
118:     }
119:   }
120:   PetscCall(ISRestoreIndices(perm,&rip));

122:   a->inew = ai;
123:   a->jnew = aj;

125:   PetscCall(ISDestroy(&a->row));
126:   PetscCall(ISDestroy(&a->icol));
127:   PetscCall(PetscObjectReference((PetscObject)perm));
128:   PetscCall(ISDestroy(&a->row));
129:   a->row  = perm;
130:   PetscCall(PetscObjectReference((PetscObject)perm));
131:   PetscCall(ISDestroy(&a->icol));
132:   a->icol = perm;

134:   PetscCall(PetscFree(nzr));
135:   PetscCall(PetscFree(r));
136:   PetscFunctionReturn(PETSC_SUCCESS);
137: #endif
138: }