1a5eb4965SSatish Balay #ifdef PETSC_RCS_HEADER 2*3a40ed3dSBarry Smith static char vcid[] = "$Id: baij2.c,v 1.18 1997/10/01 21:30:01 balay Exp bsmith $"; 3cac129eeSSatish Balay #endif 4cac129eeSSatish Balay 570f55243SBarry Smith #include "src/mat/impls/baij/seq/baij.h" 6cac129eeSSatish Balay #include "petsc.h" 7736121d4SSatish Balay #include "src/inline/bitarray.h" 8cac129eeSSatish Balay 95615d1e5SSatish Balay #undef __FUNC__ 10d4bb536fSBarry Smith #define __FUNC__ "MatIncreaseOverlap_SeqBAIJ" 11736121d4SSatish Balay int MatIncreaseOverlap_SeqBAIJ(Mat A,int is_max,IS *is,int ov) 12a3192f15SSatish Balay { 13a3192f15SSatish Balay Mat_SeqBAIJ *a = (Mat_SeqBAIJ *) A->data; 14218c64b6SSatish Balay int row, i,j,k,l,m,n, *idx,ierr, *nidx, isz, val, ival; 15218c64b6SSatish Balay int start, end, *ai, *aj,bs,*nidx2; 1642523b56SSatish Balay BT table; 17a3192f15SSatish Balay 18*3a40ed3dSBarry Smith PetscFunctionBegin; 19a3192f15SSatish Balay m = a->mbs; 20a3192f15SSatish Balay ai = a->i; 21a3192f15SSatish Balay aj = a->j; 22218c64b6SSatish Balay bs = a->bs; 23a3192f15SSatish Balay 2483e2fdc7SBarry Smith if (ov < 0) SETERRQ(1,0,"Negative overlap specified"); 25a3192f15SSatish Balay 2642523b56SSatish Balay ierr = BTCreate(m,table); CHKERRQ(ierr); 27a3192f15SSatish Balay nidx = (int *) PetscMalloc((m+1)*sizeof(int)); CHKPTRQ(nidx); 28218c64b6SSatish Balay nidx2 = (int *)PetscMalloc((a->m+1)*sizeof(int)); CHKPTRQ(nidx2); 29a3192f15SSatish Balay 30a3192f15SSatish Balay for ( i=0; i<is_max; i++ ) { 31a3192f15SSatish Balay /* Initialise the two local arrays */ 32a3192f15SSatish Balay isz = 0; 3342523b56SSatish Balay BTMemzero(m,table); 34a3192f15SSatish Balay 35a3192f15SSatish Balay /* Extract the indices, assume there can be duplicate entries */ 36a3192f15SSatish Balay ierr = ISGetIndices(is[i],&idx); CHKERRQ(ierr); 37a3192f15SSatish Balay ierr = ISGetSize(is[i],&n); CHKERRQ(ierr); 38a3192f15SSatish Balay 39a3192f15SSatish Balay /* Enter these into the temp arrays i.e mark table[row], enter row into new index */ 40a3192f15SSatish Balay for ( j=0; j<n ; ++j){ 41218c64b6SSatish Balay ival = idx[j]/bs; /* convert the indices into block indices */ 42e3372554SBarry Smith if (ival>m) SETERRQ(1,0,"index greater than mat-dim"); 4342523b56SSatish Balay if(!BTLookupSet(table, ival)) { nidx[isz++] = ival;} 44a3192f15SSatish Balay } 45a3192f15SSatish Balay ierr = ISRestoreIndices(is[i],&idx); CHKERRQ(ierr); 46a3192f15SSatish Balay ierr = ISDestroy(is[i]); CHKERRQ(ierr); 47a3192f15SSatish Balay 48a3192f15SSatish Balay k = 0; 49a3192f15SSatish Balay for ( j=0; j<ov; j++){ /* for each overlap*/ 50a3192f15SSatish Balay n = isz; 51a3192f15SSatish Balay for ( ; k<n ; k++){ /* do only those rows in nidx[k], which are not done yet */ 52a3192f15SSatish Balay row = nidx[k]; 53a3192f15SSatish Balay start = ai[row]; 54a3192f15SSatish Balay end = ai[row+1]; 55a3192f15SSatish Balay for ( l = start; l<end ; l++){ 56a3192f15SSatish Balay val = aj[l]; 5742523b56SSatish Balay if (!BTLookupSet(table,val)) {nidx[isz++] = val;} 58a3192f15SSatish Balay } 59a3192f15SSatish Balay } 60a3192f15SSatish Balay } 61218c64b6SSatish Balay /* expand the Index Set */ 62218c64b6SSatish Balay for (j=0; j<isz; j++ ) { 63218c64b6SSatish Balay for (k=0; k<bs; k++ ) 64218c64b6SSatish Balay nidx2[j*bs+k] = nidx[j]*bs+k; 65218c64b6SSatish Balay } 66029af93fSBarry Smith ierr = ISCreateGeneral(PETSC_COMM_SELF, isz*bs, nidx2, (is+i)); CHKERRQ(ierr); 67a3192f15SSatish Balay } 6842523b56SSatish Balay BTDestroy(table); 69a3192f15SSatish Balay PetscFree(nidx); 70218c64b6SSatish Balay PetscFree(nidx2); 71*3a40ed3dSBarry Smith PetscFunctionReturn(0); 72a3192f15SSatish Balay } 731c351548SSatish Balay 745615d1e5SSatish Balay #undef __FUNC__ 755615d1e5SSatish Balay #define __FUNC__ "MatGetSubMatrix_SeqBAIJ_Private" 76218c64b6SSatish Balay int MatGetSubMatrix_SeqBAIJ_Private(Mat A,IS isrow,IS iscol,MatGetSubMatrixCall scall,Mat *B) 77736121d4SSatish Balay { 78736121d4SSatish Balay Mat_SeqBAIJ *a = (Mat_SeqBAIJ *) A->data,*c; 79736121d4SSatish Balay int nznew, *smap, i, k, kstart, kend, ierr, oldcols = a->nbs,*lens; 80218c64b6SSatish Balay int row,mat_i,*mat_j,tcol,*mat_ilen; 81736121d4SSatish Balay int *irow, *icol, nrows, ncols,*ssmap,bs=a->bs, bs2=a->bs2; 82218c64b6SSatish Balay int *aj = a->j, *ai = a->i; 83218c64b6SSatish Balay Scalar *mat_a; 84736121d4SSatish Balay Mat C; 85736121d4SSatish Balay 86*3a40ed3dSBarry Smith PetscFunctionBegin; 87736121d4SSatish Balay ierr = ISSorted(iscol,(PetscTruth*)&i); 88e3372554SBarry Smith if (!i) SETERRQ(1,0,"IS is not sorted"); 89736121d4SSatish Balay 90736121d4SSatish Balay ierr = ISGetIndices(isrow,&irow); CHKERRQ(ierr); 91218c64b6SSatish Balay ierr = ISGetIndices(iscol,&icol); CHKERRQ(ierr); 92736121d4SSatish Balay ierr = ISGetSize(isrow,&nrows); CHKERRQ(ierr); 93736121d4SSatish Balay ierr = ISGetSize(iscol,&ncols); CHKERRQ(ierr); 94736121d4SSatish Balay 95736121d4SSatish Balay smap = (int *) PetscMalloc((1+oldcols)*sizeof(int)); CHKPTRQ(smap); 96736121d4SSatish Balay ssmap = smap; 97736121d4SSatish Balay lens = (int *) PetscMalloc((1+nrows)*sizeof(int)); CHKPTRQ(lens); 98736121d4SSatish Balay PetscMemzero(smap,oldcols*sizeof(int)); 99736121d4SSatish Balay for ( i=0; i<ncols; i++ ) smap[icol[i]] = i+1; 100736121d4SSatish Balay /* determine lens of each row */ 101736121d4SSatish Balay for (i=0; i<nrows; i++) { 102736121d4SSatish Balay kstart = ai[irow[i]]; 103736121d4SSatish Balay kend = kstart + a->ilen[irow[i]]; 104736121d4SSatish Balay lens[i] = 0; 105736121d4SSatish Balay for ( k=kstart; k<kend; k++ ) { 106736121d4SSatish Balay if (ssmap[aj[k]]) { 107736121d4SSatish Balay lens[i]++; 108736121d4SSatish Balay } 109736121d4SSatish Balay } 110736121d4SSatish Balay } 111736121d4SSatish Balay /* Create and fill new matrix */ 112736121d4SSatish Balay if (scall == MAT_REUSE_MATRIX) { 113736121d4SSatish Balay c = (Mat_SeqBAIJ *)((*B)->data); 114736121d4SSatish Balay 115*3a40ed3dSBarry Smith if (c->mbs!=nrows || c->nbs!=ncols || c->bs!=bs) SETERRQ(1,0,""); 116736121d4SSatish Balay if (PetscMemcmp(c->ilen,lens, c->mbs *sizeof(int))) { 117e3372554SBarry Smith SETERRQ(1,0,"Cannot reuse matrix. wrong no of nonzeros"); 118736121d4SSatish Balay } 119736121d4SSatish Balay PetscMemzero(c->ilen,c->mbs*sizeof(int)); 120736121d4SSatish Balay C = *B; 121*3a40ed3dSBarry Smith } else { 122736121d4SSatish Balay ierr = MatCreateSeqBAIJ(A->comm,bs,nrows*bs,ncols*bs,0,lens,&C);CHKERRQ(ierr); 123736121d4SSatish Balay } 124736121d4SSatish Balay c = (Mat_SeqBAIJ *)(C->data); 125736121d4SSatish Balay for (i=0; i<nrows; i++) { 126736121d4SSatish Balay row = irow[i]; 127736121d4SSatish Balay nznew = 0; 128736121d4SSatish Balay kstart = ai[row]; 129736121d4SSatish Balay kend = kstart + a->ilen[row]; 130736121d4SSatish Balay mat_i = c->i[i]; 131736121d4SSatish Balay mat_j = c->j + mat_i; 132218c64b6SSatish Balay mat_a = c->a + mat_i*bs2; 133736121d4SSatish Balay mat_ilen = c->ilen + i; 134736121d4SSatish Balay for ( k=kstart; k<kend; k++ ) { 135736121d4SSatish Balay if ((tcol=ssmap[a->j[k]])) { 136736121d4SSatish Balay *mat_j++ = tcol - 1; 137736121d4SSatish Balay PetscMemcpy(mat_a,a->a+k*bs2,bs2*sizeof(Scalar)); mat_a+=bs2; 138736121d4SSatish Balay (*mat_ilen)++; 139736121d4SSatish Balay 140736121d4SSatish Balay } 141736121d4SSatish Balay } 142736121d4SSatish Balay } 143218c64b6SSatish Balay 144736121d4SSatish Balay /* Free work space */ 145736121d4SSatish Balay ierr = ISRestoreIndices(iscol,&icol); CHKERRQ(ierr); 146736121d4SSatish Balay PetscFree(smap); PetscFree(lens); 1476d4a8577SBarry Smith ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY); CHKERRQ(ierr); 1486d4a8577SBarry Smith ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY); CHKERRQ(ierr); 149736121d4SSatish Balay 150736121d4SSatish Balay ierr = ISRestoreIndices(isrow,&irow); CHKERRQ(ierr); 151736121d4SSatish Balay *B = C; 152*3a40ed3dSBarry Smith PetscFunctionReturn(0); 153736121d4SSatish Balay } 154736121d4SSatish Balay 1555615d1e5SSatish Balay #undef __FUNC__ 1565615d1e5SSatish Balay #define __FUNC__ "MatGetSubMatrix_SeqBAIJ" 157218c64b6SSatish Balay int MatGetSubMatrix_SeqBAIJ(Mat A,IS isrow,IS iscol,MatGetSubMatrixCall scall,Mat *B) 158218c64b6SSatish Balay { 159218c64b6SSatish Balay Mat_SeqBAIJ *a = (Mat_SeqBAIJ *) A->data; 160218c64b6SSatish Balay IS is1,is2; 161218c64b6SSatish Balay int *vary,*iary,*irow,*icol,nrows,ncols,i,ierr,bs=a->bs,count; 162218c64b6SSatish Balay 163*3a40ed3dSBarry Smith PetscFunctionBegin; 164218c64b6SSatish Balay ierr = ISGetIndices(isrow,&irow); CHKERRQ(ierr); 165218c64b6SSatish Balay ierr = ISGetIndices(iscol,&icol); CHKERRQ(ierr); 166218c64b6SSatish Balay ierr = ISGetSize(isrow,&nrows); CHKERRQ(ierr); 167218c64b6SSatish Balay ierr = ISGetSize(iscol,&ncols); CHKERRQ(ierr); 168218c64b6SSatish Balay 169218c64b6SSatish Balay /* Verify if the indices corespond to each elementin a block 170218c64b6SSatish Balay and form the IS with compressed IS */ 171218c64b6SSatish Balay vary = (int *) PetscMalloc(2*(a->mbs+1)*sizeof(int)); CHKPTRQ(vary); 172218c64b6SSatish Balay iary = vary + a->mbs; 173218c64b6SSatish Balay PetscMemzero(vary,(a->mbs)*sizeof(int)); 174218c64b6SSatish Balay for ( i=0; i<nrows; i++) vary[irow[i]/bs]++; 175218c64b6SSatish Balay count = 0; 176218c64b6SSatish Balay for (i=0; i<a->mbs; i++) { 177e3372554SBarry Smith if (vary[i]!=0 && vary[i]!=bs) SETERRA(1,0,"MatGetSubmatrices_SeqBAIJ:"); 178218c64b6SSatish Balay if (vary[i]==bs) iary[count++] = i; 179218c64b6SSatish Balay } 180029af93fSBarry Smith ierr = ISCreateGeneral(PETSC_COMM_SELF, count, iary,&is1); CHKERRQ(ierr); 181218c64b6SSatish Balay 182218c64b6SSatish Balay PetscMemzero(vary,(a->mbs)*sizeof(int)); 183218c64b6SSatish Balay for ( i=0; i<ncols; i++) vary[icol[i]/bs]++; 184218c64b6SSatish Balay count = 0; 185218c64b6SSatish Balay for (i=0; i<a->mbs; i++) { 186e3372554SBarry Smith if (vary[i]!=0 && vary[i]!=bs) SETERRA(1,0,"MatGetSubmatrices_SeqBAIJ:"); 187218c64b6SSatish Balay if (vary[i]==bs) iary[count++] = i; 188218c64b6SSatish Balay } 189029af93fSBarry Smith ierr = ISCreateGeneral(PETSC_COMM_SELF, count, iary,&is2); CHKERRQ(ierr); 190218c64b6SSatish Balay ierr = ISRestoreIndices(isrow,&irow); CHKERRQ(ierr); 191218c64b6SSatish Balay ierr = ISRestoreIndices(iscol,&icol); CHKERRQ(ierr); 192218c64b6SSatish Balay PetscFree(vary); 193218c64b6SSatish Balay 194218c64b6SSatish Balay ierr = MatGetSubMatrix_SeqBAIJ_Private(A,is1,is2,scall,B); CHKERRQ(ierr); 195218c64b6SSatish Balay ISDestroy(is1); 196218c64b6SSatish Balay ISDestroy(is2); 197*3a40ed3dSBarry Smith PetscFunctionReturn(0); 198218c64b6SSatish Balay } 199218c64b6SSatish Balay 200905e6a2fSBarry Smith extern int MatGetSubMatrix_SeqBAIJ(Mat,IS,IS,MatGetSubMatrixCall,Mat*); 201905e6a2fSBarry Smith 2025615d1e5SSatish Balay #undef __FUNC__ 2035615d1e5SSatish Balay #define __FUNC__ "MatGetSubMatrices_SeqBAIJ" 204736121d4SSatish Balay int MatGetSubMatrices_SeqBAIJ(Mat A,int n, IS *irow,IS *icol,MatGetSubMatrixCall scall, 205736121d4SSatish Balay Mat **B) 206736121d4SSatish Balay { 207736121d4SSatish Balay int ierr,i; 208736121d4SSatish Balay 209*3a40ed3dSBarry Smith PetscFunctionBegin; 210736121d4SSatish Balay if (scall == MAT_INITIAL_MATRIX) { 211736121d4SSatish Balay *B = (Mat *) PetscMalloc( (n+1)*sizeof(Mat) ); CHKPTRQ(*B); 212736121d4SSatish Balay } 213736121d4SSatish Balay 214736121d4SSatish Balay for ( i=0; i<n; i++ ) { 215905e6a2fSBarry Smith ierr = MatGetSubMatrix_SeqBAIJ(A,irow[i],icol[i],scall,&(*B)[i]);CHKERRQ(ierr); 216736121d4SSatish Balay } 217*3a40ed3dSBarry Smith PetscFunctionReturn(0); 218736121d4SSatish Balay } 219218c64b6SSatish Balay 220218c64b6SSatish Balay 221218c64b6SSatish Balay 222218c64b6SSatish Balay 223218c64b6SSatish Balay 224218c64b6SSatish Balay 225218c64b6SSatish Balay 226