#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(0); SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix reordering is not supported for sbaij matrix. Use aij format"); #if 0 PetscErrorCode ierr; const PetscInt *rip,*riip; PetscInt *ai,*aj,*r; PetscInt *nzr,nz,jmin,jmax,j,k,ajk,i; IS iperm; /* inverse of perm */ ierr = ISGetIndices(perm,&rip);CHKERRQ(ierr); ierr = ISInvertPermutation(perm,PETSC_DECIDE,&iperm);CHKERRQ(ierr); ierr = ISGetIndices(iperm,&riip);CHKERRQ(ierr); for (i=0; iinew) { ierr = PetscMalloc2(mbs+1,&ai, 2*a->i[mbs],&aj);CHKERRQ(ierr); } else { ai = a->inew; aj = a->jnew; } ierr = PetscArraycpy(ai,a->i,mbs+1);CHKERRQ(ierr); ierr = PetscArraycpy(aj,a->j,a->i[mbs]);CHKERRQ(ierr); /* 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. */ ierr = PetscMalloc1(mbs,&nzr);CHKERRQ(ierr); ierr = PetscMalloc1(ai[mbs],&r);CHKERRQ(ierr); for (i=0; ia2anew = aj + ai[mbs]; ierr = PetscArraycpy(a->a2anew,r,ai[mbs]);CHKERRQ(ierr); /* Phase 3: permute (aj,a) to upper triangular form (wrt new ordering) */ for (j=jmin; jinew = ai; a->jnew = aj; ierr = ISDestroy(&a->row);CHKERRQ(ierr); ierr = ISDestroy(&a->icol);CHKERRQ(ierr); ierr = PetscObjectReference((PetscObject)perm);CHKERRQ(ierr); ierr = ISDestroy(&a->row);CHKERRQ(ierr); a->row = perm; ierr = PetscObjectReference((PetscObject)perm);CHKERRQ(ierr); ierr = ISDestroy(&a->icol);CHKERRQ(ierr); a->icol = perm; ierr = PetscFree(nzr);CHKERRQ(ierr); ierr = PetscFree(r);CHKERRQ(ierr); PetscFunctionReturn(0); #endif }