#include <../src/mat/impls/baij/seq/baij.h> #include <../src/mat/impls/sbaij/seq/sbaij.h> /* This function is used before applying a symmetric reordering to matrix A that is in SBAIJ format. The permutation is assumed to be symmetric, i.e., P = P^T (= inv(P)), so the permuted matrix P*A*inv(P)=P*A*P^T is ensured to be symmetric. - a wrong assumption! This code needs rework! -- Hong The function is modified from sro.f of YSMP. The description from YSMP: C THE NONZERO ENTRIES OF THE MATRIX M ARE ASSUMED TO BE STORED C SYMMETRICALLY IN (IA,JA,A) FORMAT (I.E., NOT BOTH M(I,J) AND M(J,I) C ARE STORED IF I NE J). C C SRO DOES NOT REARRANGE THE ORDER OF THE ROWS, BUT DOES MOVE C NONZEROES FROM ONE ROW TO ANOTHER TO ENSURE THAT IF M(I,J) WILL BE C IN THE UPPER TRIANGLE OF M WITH RESPECT TO THE NEW ORDERING, THEN C M(I,J) IS STORED IN ROW I (AND THUS M(J,I) IS NOT STORED); WHEREAS C IF M(I,J) WILL BE IN THE STRICT LOWER TRIANGLE OF M, THEN M(J,I) IS C STORED IN ROW J (AND THUS M(I,J) IS NOT STORED). -- output: new index set (inew, jnew) for A and a map a2anew that maps values a to anew, such that all nonzero A_(perm(i),iperm(k)) will be stored in the upper triangle. Note: matrix A is not permuted by this function! */ PetscErrorCode MatReorderingSeqSBAIJ(Mat A, IS perm) { Mat_SeqSBAIJ *a = (Mat_SeqSBAIJ *)A->data; const PetscInt mbs = a->mbs; PetscFunctionBegin; if (!mbs) PetscFunctionReturn(PETSC_SUCCESS); SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP, "Matrix reordering is not supported for sbaij matrix. Use aij format"); #if 0 const PetscInt *rip,*riip; PetscInt *ai,*aj,*r; PetscInt *nzr,nz,jmin,jmax,j,k,ajk,i; IS iperm; /* inverse of perm */ PetscCall(ISGetIndices(perm,&rip)); PetscCall(ISInvertPermutation(perm,PETSC_DECIDE,&iperm)); PetscCall(ISGetIndices(iperm,&riip)); for (i=0; iinew) { PetscCall(PetscMalloc2(mbs+1,&ai, 2*a->i[mbs],&aj)); } else { ai = a->inew; aj = a->jnew; } PetscCall(PetscArraycpy(ai,a->i,mbs+1)); PetscCall(PetscArraycpy(aj,a->j,a->i[mbs])); /* Phase 1: Find row index r in which to store each nonzero. Initialize count of nonzeros to be stored in each row (nzr). At the end of this phase, a nonzero a(*,*)=a(r(),aj()) s.t. a(perm(r),perm(aj)) will fall into upper triangle part. */ PetscCall(PetscMalloc1(mbs,&nzr)); PetscCall(PetscMalloc1(ai[mbs],&r)); for (i=0; ia2anew = aj + ai[mbs]; PetscCall(PetscArraycpy(a->a2anew,r,ai[mbs])); /* Phase 3: permute (aj,a) to upper triangular form (wrt new ordering) */ for (j=jmin; jinew = ai; a->jnew = aj; PetscCall(ISDestroy(&a->row)); PetscCall(ISDestroy(&a->icol)); PetscCall(PetscObjectReference((PetscObject)perm)); PetscCall(ISDestroy(&a->row)); a->row = perm; PetscCall(PetscObjectReference((PetscObject)perm)); PetscCall(ISDestroy(&a->icol)); a->icol = perm; PetscCall(PetscFree(nzr)); PetscCall(PetscFree(r)); PetscFunctionReturn(PETSC_SUCCESS); #endif }