#include "src/mat/impls/baij/seq/baij.h" #include "src/inline/spops.h" #include "src/mat/impls/sbaij/seq/sbaij.h" #include "petscsys.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. 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! */ #undef __FUNCT__ #define __FUNCT__ "MatReorderingSeqSBAIJ" PetscErrorCode MatReorderingSeqSBAIJ(Mat A,IS perm) { Mat_SeqSBAIJ *a=(Mat_SeqSBAIJ *)A->data; PetscErrorCode ierr; int *r,i,mbs=a->mbs,*rip,*riip; int *ai,*aj; int *nzr,nz,jmin,jmax,j,k,ajk,len; IS iperm; /* inverse of perm */ PetscFunctionBegin; if (!mbs) PetscFunctionReturn(0); ierr = ISGetIndices(perm,&rip);CHKERRQ(ierr); ierr = ISInvertPermutation(perm,PETSC_DECIDE,&iperm);CHKERRQ(ierr); ierr = ISGetIndices(iperm,&riip);CHKERRQ(ierr); for (i=0; iinew){ len = (mbs+1 + 2*(a->i[mbs]))*sizeof(int); ierr = PetscMalloc(len,&ai);CHKERRQ(ierr); aj = ai + mbs+1; } else { ai = a->inew; aj = a->jnew; } ierr = PetscMemcpy(ai,a->i,(mbs+1)*sizeof(int));CHKERRQ(ierr); ierr = PetscMemcpy(aj,a->j,(a->i[mbs])*sizeof(int));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 = PetscMalloc(mbs*sizeof(int),&nzr);CHKERRQ(ierr); ierr = PetscMalloc(ai[mbs]*sizeof(int),&r);CHKERRQ(ierr); for (i=0; ia2anew = aj + ai[mbs]; ierr = PetscMemcpy(a->a2anew,r,ai[mbs]*sizeof(int));CHKERRQ(ierr); /* Phase 3: permute (aj,a) to upper triangular form (wrt new ordering) */ for (j=jmin; jinew = ai; a->jnew = aj; if (a->row) { ierr = ISDestroy(a->row);CHKERRQ(ierr); } if (a->icol) { ierr = ISDestroy(a->icol);CHKERRQ(ierr); } a->row = perm; a->icol = perm; ierr = PetscObjectReference((PetscObject)perm);CHKERRQ(ierr); ierr = PetscObjectReference((PetscObject)perm);CHKERRQ(ierr); ierr = PetscFree(nzr);CHKERRQ(ierr); ierr = PetscFree(r);CHKERRQ(ierr); PetscFunctionReturn(0); }