1be1d678aSKris Buschelman #define PETSCMAT_DLL 249b5e25fSSatish Balay 349b5e25fSSatish Balay /* 4a1373b80SHong Zhang Defines the basic matrix operations for the SBAIJ (compressed row) 549b5e25fSSatish Balay matrix storage format. 649b5e25fSSatish Balay */ 77c4f633dSBarry Smith #include "../src/mat/impls/baij/seq/baij.h" /*I "petscmat.h" I*/ 87c4f633dSBarry Smith #include "../src/inline/spops.h" 97c4f633dSBarry Smith #include "../src/mat/impls/sbaij/seq/sbaij.h" 1049b5e25fSSatish Balay 11db4efbfdSBarry Smith extern PetscErrorCode MatSeqSBAIJSetNumericFactorization(Mat,PetscTruth); 1249b5e25fSSatish Balay #define CHUNKSIZE 10 1349b5e25fSSatish Balay 1449b5e25fSSatish Balay /* 1549b5e25fSSatish Balay Checks for missing diagonals 1649b5e25fSSatish Balay */ 174a2ae208SSatish Balay #undef __FUNCT__ 184a2ae208SSatish Balay #define __FUNCT__ "MatMissingDiagonal_SeqSBAIJ" 192af78befSBarry Smith PetscErrorCode MatMissingDiagonal_SeqSBAIJ(Mat A,PetscTruth *missing,PetscInt *dd) 2049b5e25fSSatish Balay { 21045c9aa0SHong Zhang Mat_SeqSBAIJ *a = (Mat_SeqSBAIJ*)A->data; 226849ba73SBarry Smith PetscErrorCode ierr; 2313f74950SBarry Smith PetscInt *diag,*jj = a->j,i; 2449b5e25fSSatish Balay 2549b5e25fSSatish Balay PetscFunctionBegin; 26045c9aa0SHong Zhang ierr = MatMarkDiagonal_SeqSBAIJ(A);CHKERRQ(ierr); 2749b5e25fSSatish Balay diag = a->diag; 282af78befSBarry Smith *missing = PETSC_FALSE; 2949b5e25fSSatish Balay for (i=0; i<a->mbs; i++) { 302af78befSBarry Smith if (jj[diag[i]] != i) { 312af78befSBarry Smith *missing = PETSC_TRUE; 322af78befSBarry Smith if (dd) *dd = i; 332af78befSBarry Smith break; 342af78befSBarry Smith } 3549b5e25fSSatish Balay } 3649b5e25fSSatish Balay PetscFunctionReturn(0); 3749b5e25fSSatish Balay } 3849b5e25fSSatish Balay 394a2ae208SSatish Balay #undef __FUNCT__ 404a2ae208SSatish Balay #define __FUNCT__ "MatMarkDiagonal_SeqSBAIJ" 41dfbe8321SBarry Smith PetscErrorCode MatMarkDiagonal_SeqSBAIJ(Mat A) 4249b5e25fSSatish Balay { 43045c9aa0SHong Zhang Mat_SeqSBAIJ *a = (Mat_SeqSBAIJ*)A->data; 446849ba73SBarry Smith PetscErrorCode ierr; 4509f38230SBarry Smith PetscInt i; 4649b5e25fSSatish Balay 4749b5e25fSSatish Balay PetscFunctionBegin; 4809f38230SBarry Smith if (!a->diag) { 4909f38230SBarry Smith ierr = PetscMalloc(a->mbs*sizeof(PetscInt),&a->diag);CHKERRQ(ierr); 5009f38230SBarry Smith } 5109f38230SBarry Smith for (i=0; i<a->mbs; i++) a->diag[i] = a->i[i]; 5249b5e25fSSatish Balay PetscFunctionReturn(0); 5349b5e25fSSatish Balay } 5449b5e25fSSatish Balay 554a2ae208SSatish Balay #undef __FUNCT__ 564a2ae208SSatish Balay #define __FUNCT__ "MatGetRowIJ_SeqSBAIJ" 578f7157efSSatish Balay static PetscErrorCode MatGetRowIJ_SeqSBAIJ(Mat A,PetscInt oshift,PetscTruth symmetric,PetscTruth blockcompressed,PetscInt *nn,PetscInt *ia[],PetscInt *ja[],PetscTruth *done) 5849b5e25fSSatish Balay { 59a6ece127SHong Zhang Mat_SeqSBAIJ *a = (Mat_SeqSBAIJ*)A->data; 60d0f46423SBarry Smith PetscInt i,j,n = a->mbs,nz = a->i[n],bs = A->rmap->bs; 618f7157efSSatish Balay PetscErrorCode ierr; 6249b5e25fSSatish Balay 6349b5e25fSSatish Balay PetscFunctionBegin; 64d3e5a4abSHong Zhang *nn = n; 65a1373b80SHong Zhang if (!ia) PetscFunctionReturn(0); 668f7157efSSatish Balay if (!blockcompressed) { 678f7157efSSatish Balay /* malloc & create the natural set of indices */ 68f1d0d59dSSatish Balay ierr = PetscMalloc2((n+1)*bs,PetscInt,ia,nz*bs,PetscInt,ja);CHKERRQ(ierr); 698f7157efSSatish Balay for (i=0; i<n+1; i++) { 708f7157efSSatish Balay for (j=0; j<bs; j++) { 718f7157efSSatish Balay *ia[i*bs+j] = a->i[i]*bs+j+oshift; 728f7157efSSatish Balay } 738f7157efSSatish Balay } 748f7157efSSatish Balay for (i=0; i<nz; i++) { 758f7157efSSatish Balay for (j=0; j<bs; j++) { 768f7157efSSatish Balay *ja[i*bs+j] = a->j[i]*bs+j+oshift; 778f7157efSSatish Balay } 788f7157efSSatish Balay } 798f7157efSSatish Balay } else { /* blockcompressed */ 80a6ece127SHong Zhang if (oshift == 1) { 81a6ece127SHong Zhang /* temporarily add 1 to i and j indices */ 826c6c5352SBarry Smith for (i=0; i<nz; i++) a->j[i]++; 83a1373b80SHong Zhang for (i=0; i<n+1; i++) a->i[i]++; 848f7157efSSatish Balay } 85a1373b80SHong Zhang *ia = a->i; *ja = a->j; 86a6ece127SHong Zhang } 878f7157efSSatish Balay 8849b5e25fSSatish Balay PetscFunctionReturn(0); 8949b5e25fSSatish Balay } 9049b5e25fSSatish Balay 914a2ae208SSatish Balay #undef __FUNCT__ 924a2ae208SSatish Balay #define __FUNCT__ "MatRestoreRowIJ_SeqSBAIJ" 938f7157efSSatish Balay static PetscErrorCode MatRestoreRowIJ_SeqSBAIJ(Mat A,PetscInt oshift,PetscTruth symmetric,PetscTruth blockcompressed,PetscInt *nn,PetscInt *ia[],PetscInt *ja[],PetscTruth *done) 9449b5e25fSSatish Balay { 95b7aaefc3SHong Zhang Mat_SeqSBAIJ *a = (Mat_SeqSBAIJ*)A->data; 968f7157efSSatish Balay PetscInt i,n = a->mbs,nz = a->i[n]; 978f7157efSSatish Balay PetscErrorCode ierr; 98a6ece127SHong Zhang 9949b5e25fSSatish Balay PetscFunctionBegin; 10049b5e25fSSatish Balay if (!ia) PetscFunctionReturn(0); 101a6ece127SHong Zhang 1028f7157efSSatish Balay if (!blockcompressed) { 1038f7157efSSatish Balay ierr = PetscFree2(*ia,*ja);CHKERRQ(ierr); 1048f7157efSSatish Balay } else if (oshift == 1) { /* blockcompressed */ 1056c6c5352SBarry Smith for (i=0; i<nz; i++) a->j[i]--; 106a6ece127SHong Zhang for (i=0; i<n+1; i++) a->i[i]--; 107a6ece127SHong Zhang } 1088f7157efSSatish Balay 109a6ece127SHong Zhang PetscFunctionReturn(0); 11049b5e25fSSatish Balay } 11149b5e25fSSatish Balay 1124a2ae208SSatish Balay #undef __FUNCT__ 1134a2ae208SSatish Balay #define __FUNCT__ "MatDestroy_SeqSBAIJ" 114dfbe8321SBarry Smith PetscErrorCode MatDestroy_SeqSBAIJ(Mat A) 11549b5e25fSSatish Balay { 11649b5e25fSSatish Balay Mat_SeqSBAIJ *a = (Mat_SeqSBAIJ*)A->data; 117dfbe8321SBarry Smith PetscErrorCode ierr; 11849b5e25fSSatish Balay 11949b5e25fSSatish Balay PetscFunctionBegin; 120a9f03627SSatish Balay #if defined(PETSC_USE_LOG) 121d0f46423SBarry Smith PetscLogObjectState((PetscObject)A,"Rows=%D, NZ=%D",A->rmap->N,a->nz); 122a9f03627SSatish Balay #endif 123e6b907acSBarry Smith ierr = MatSeqXAIJFreeAIJ(A,&a->a,&a->j,&a->i);CHKERRQ(ierr); 1249bfd6278SHong Zhang if (a->row) {ierr = ISDestroy(a->row);CHKERRQ(ierr);} 1259bfd6278SHong Zhang if (a->col){ierr = ISDestroy(a->col);CHKERRQ(ierr);} 1269bfd6278SHong Zhang if (a->icol) {ierr = ISDestroy(a->icol);CHKERRQ(ierr);} 127061b2667SBarry Smith if (a->idiag) {ierr = PetscFree(a->idiag);CHKERRQ(ierr);} 128*0def2e27SBarry Smith if (a->inode.size) {ierr = PetscFree(a->inode.size);CHKERRQ(ierr);} 12905b42c5fSBarry Smith ierr = PetscFree(a->diag);CHKERRQ(ierr); 13005b42c5fSBarry Smith ierr = PetscFree2(a->imax,a->ilen);CHKERRQ(ierr); 13105b42c5fSBarry Smith ierr = PetscFree(a->solve_work);CHKERRQ(ierr); 132e2ee2a47SBarry Smith ierr = PetscFree(a->relax_work);CHKERRQ(ierr); 13305b42c5fSBarry Smith ierr = PetscFree(a->solves_work);CHKERRQ(ierr); 13405b42c5fSBarry Smith ierr = PetscFree(a->mult_work);CHKERRQ(ierr); 13505b42c5fSBarry Smith ierr = PetscFree(a->saved_values);CHKERRQ(ierr); 13605b42c5fSBarry Smith ierr = PetscFree(a->xtoy);CHKERRQ(ierr); 1371a3463dfSHong Zhang 1381a3463dfSHong Zhang ierr = PetscFree(a->inew);CHKERRQ(ierr); 13949b5e25fSSatish Balay ierr = PetscFree(a);CHKERRQ(ierr); 140901853e0SKris Buschelman 141dbd8c25aSHong Zhang ierr = PetscObjectChangeTypeName((PetscObject)A,0);CHKERRQ(ierr); 142901853e0SKris Buschelman ierr = PetscObjectComposeFunction((PetscObject)A,"MatStoreValues_C","",PETSC_NULL);CHKERRQ(ierr); 143901853e0SKris Buschelman ierr = PetscObjectComposeFunction((PetscObject)A,"MatRetrieveValues_C","",PETSC_NULL);CHKERRQ(ierr); 144901853e0SKris Buschelman ierr = PetscObjectComposeFunction((PetscObject)A,"MatSeqSBAIJSetColumnIndices_C","",PETSC_NULL);CHKERRQ(ierr); 145901853e0SKris Buschelman ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqsbaij_seqaij_C","",PETSC_NULL);CHKERRQ(ierr); 146901853e0SKris Buschelman ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqsbaij_seqbaij_C","",PETSC_NULL);CHKERRQ(ierr); 147901853e0SKris Buschelman ierr = PetscObjectComposeFunction((PetscObject)A,"MatSeqSBAIJSetPreallocation_C","",PETSC_NULL);CHKERRQ(ierr); 14849b5e25fSSatish Balay PetscFunctionReturn(0); 14949b5e25fSSatish Balay } 15049b5e25fSSatish Balay 1514a2ae208SSatish Balay #undef __FUNCT__ 1524a2ae208SSatish Balay #define __FUNCT__ "MatSetOption_SeqSBAIJ" 1534e0d8c25SBarry Smith PetscErrorCode MatSetOption_SeqSBAIJ(Mat A,MatOption op,PetscTruth flg) 15449b5e25fSSatish Balay { 155045c9aa0SHong Zhang Mat_SeqSBAIJ *a = (Mat_SeqSBAIJ*)A->data; 15663ba0a88SBarry Smith PetscErrorCode ierr; 15749b5e25fSSatish Balay 15849b5e25fSSatish Balay PetscFunctionBegin; 1594d9d31abSKris Buschelman switch (op) { 1604d9d31abSKris Buschelman case MAT_ROW_ORIENTED: 1614e0d8c25SBarry Smith a->roworiented = flg; 1624d9d31abSKris Buschelman break; 163a9817697SBarry Smith case MAT_KEEP_NONZERO_PATTERN: 164a9817697SBarry Smith a->keepnonzeropattern = flg; 1654d9d31abSKris Buschelman break; 166512a5fc5SBarry Smith case MAT_NEW_NONZERO_LOCATIONS: 167512a5fc5SBarry Smith a->nonew = (flg ? 0 : 1); 1684d9d31abSKris Buschelman break; 1694d9d31abSKris Buschelman case MAT_NEW_NONZERO_LOCATION_ERR: 1704e0d8c25SBarry Smith a->nonew = (flg ? -1 : 0); 1714d9d31abSKris Buschelman break; 1724d9d31abSKris Buschelman case MAT_NEW_NONZERO_ALLOCATION_ERR: 1734e0d8c25SBarry Smith a->nonew = (flg ? -2 : 0); 1744d9d31abSKris Buschelman break; 17528b2fa4aSMatthew Knepley case MAT_UNUSED_NONZERO_LOCATION_ERR: 17628b2fa4aSMatthew Knepley a->nounused = (flg ? -1 : 0); 17728b2fa4aSMatthew Knepley break; 1784e0d8c25SBarry Smith case MAT_NEW_DIAGONALS: 1794d9d31abSKris Buschelman case MAT_IGNORE_OFF_PROC_ENTRIES: 1804d9d31abSKris Buschelman case MAT_USE_HASH_TABLE: 181290bbb0aSBarry Smith ierr = PetscInfo1(A,"Option %s ignored\n",MatOptions[op]);CHKERRQ(ierr); 1824d9d31abSKris Buschelman break; 1839a4540c5SBarry Smith case MAT_HERMITIAN: 1844e0d8c25SBarry Smith if (flg) SETERRQ(PETSC_ERR_SUP,"Matrix must be symmetric"); 18577e54ba9SKris Buschelman case MAT_SYMMETRIC: 18677e54ba9SKris Buschelman case MAT_STRUCTURALLY_SYMMETRIC: 1879a4540c5SBarry Smith case MAT_SYMMETRY_ETERNAL: 1884e0d8c25SBarry Smith if (!flg) SETERRQ(PETSC_ERR_SUP,"Matrix must be symmetric"); 189290bbb0aSBarry Smith ierr = PetscInfo1(A,"Option %s not relevent\n",MatOptions[op]);CHKERRQ(ierr); 190290bbb0aSBarry Smith break; 191941593c8SHong Zhang case MAT_IGNORE_LOWER_TRIANGULAR: 1924e0d8c25SBarry Smith a->ignore_ltriangular = flg; 193941593c8SHong Zhang break; 194941593c8SHong Zhang case MAT_ERROR_LOWER_TRIANGULAR: 1954e0d8c25SBarry Smith a->ignore_ltriangular = flg; 19677e54ba9SKris Buschelman break; 197f5edf698SHong Zhang case MAT_GETROW_UPPERTRIANGULAR: 1984e0d8c25SBarry Smith a->getrow_utriangular = flg; 199f5edf698SHong Zhang break; 2004d9d31abSKris Buschelman default: 201ad86a440SBarry Smith SETERRQ1(PETSC_ERR_SUP,"unknown option %d",op); 20249b5e25fSSatish Balay } 20349b5e25fSSatish Balay PetscFunctionReturn(0); 20449b5e25fSSatish Balay } 20549b5e25fSSatish Balay 2064a2ae208SSatish Balay #undef __FUNCT__ 2074a2ae208SSatish Balay #define __FUNCT__ "MatGetRow_SeqSBAIJ" 20813f74950SBarry Smith PetscErrorCode MatGetRow_SeqSBAIJ(Mat A,PetscInt row,PetscInt *ncols,PetscInt **cols,PetscScalar **v) 20949b5e25fSSatish Balay { 21049b5e25fSSatish Balay Mat_SeqSBAIJ *a = (Mat_SeqSBAIJ*)A->data; 2116849ba73SBarry Smith PetscErrorCode ierr; 21213f74950SBarry Smith PetscInt itmp,i,j,k,M,*ai,*aj,bs,bn,bp,*cols_i,bs2; 21349b5e25fSSatish Balay MatScalar *aa,*aa_i; 21487828ca2SBarry Smith PetscScalar *v_i; 21549b5e25fSSatish Balay 21649b5e25fSSatish Balay PetscFunctionBegin; 2174e0d8c25SBarry Smith if (A && !a->getrow_utriangular) SETERRQ(PETSC_ERR_SUP,"MatGetRow is not supported for SBAIJ matrix format. Getting the upper triangular part of row, run with -mat_getrow_uppertriangular, call MatSetOption(mat,MAT_GETROW_UPPERTRIANGULAR,PETSC_TRUE) or MatGetRowUpperTriangular()"); 218f5edf698SHong Zhang /* Get the upper triangular part of the row */ 219d0f46423SBarry Smith bs = A->rmap->bs; 22049b5e25fSSatish Balay ai = a->i; 22149b5e25fSSatish Balay aj = a->j; 22249b5e25fSSatish Balay aa = a->a; 22349b5e25fSSatish Balay bs2 = a->bs2; 22449b5e25fSSatish Balay 225d0f46423SBarry Smith if (row < 0 || row >= A->rmap->N) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE, "Row %D out of range", row); 22649b5e25fSSatish Balay 22749b5e25fSSatish Balay bn = row/bs; /* Block number */ 22849b5e25fSSatish Balay bp = row % bs; /* Block position */ 22949b5e25fSSatish Balay M = ai[bn+1] - ai[bn]; 23049b5e25fSSatish Balay *ncols = bs*M; 23149b5e25fSSatish Balay 23249b5e25fSSatish Balay if (v) { 23349b5e25fSSatish Balay *v = 0; 23449b5e25fSSatish Balay if (*ncols) { 23587828ca2SBarry Smith ierr = PetscMalloc((*ncols+row)*sizeof(PetscScalar),v);CHKERRQ(ierr); 23649b5e25fSSatish Balay for (i=0; i<M; i++) { /* for each block in the block row */ 23749b5e25fSSatish Balay v_i = *v + i*bs; 23849b5e25fSSatish Balay aa_i = aa + bs2*(ai[bn] + i); 23949b5e25fSSatish Balay for (j=bp,k=0; j<bs2; j+=bs,k++) {v_i[k] = aa_i[j];} 24049b5e25fSSatish Balay } 24149b5e25fSSatish Balay } 24249b5e25fSSatish Balay } 24349b5e25fSSatish Balay 24449b5e25fSSatish Balay if (cols) { 24549b5e25fSSatish Balay *cols = 0; 24649b5e25fSSatish Balay if (*ncols) { 24713f74950SBarry Smith ierr = PetscMalloc((*ncols+row)*sizeof(PetscInt),cols);CHKERRQ(ierr); 24849b5e25fSSatish Balay for (i=0; i<M; i++) { /* for each block in the block row */ 24949b5e25fSSatish Balay cols_i = *cols + i*bs; 25049b5e25fSSatish Balay itmp = bs*aj[ai[bn] + i]; 25149b5e25fSSatish Balay for (j=0; j<bs; j++) {cols_i[j] = itmp++;} 25249b5e25fSSatish Balay } 25349b5e25fSSatish Balay } 25449b5e25fSSatish Balay } 25549b5e25fSSatish Balay 25649b5e25fSSatish Balay /*search column A(0:row-1,row) (=A(row,0:row-1)). Could be expensive! */ 2575ddb2528SHong Zhang /* this segment is currently removed, so only entries in the upper triangle are obtained */ 2585ddb2528SHong Zhang #ifdef column_search 25949b5e25fSSatish Balay v_i = *v + M*bs; 26049b5e25fSSatish Balay cols_i = *cols + M*bs; 26149b5e25fSSatish Balay for (i=0; i<bn; i++){ /* for each block row */ 26249b5e25fSSatish Balay M = ai[i+1] - ai[i]; 26349b5e25fSSatish Balay for (j=0; j<M; j++){ 26449b5e25fSSatish Balay itmp = aj[ai[i] + j]; /* block column value */ 26549b5e25fSSatish Balay if (itmp == bn){ 26649b5e25fSSatish Balay aa_i = aa + bs2*(ai[i] + j) + bs*bp; 26749b5e25fSSatish Balay for (k=0; k<bs; k++) { 26849b5e25fSSatish Balay *cols_i++ = i*bs+k; 26949b5e25fSSatish Balay *v_i++ = aa_i[k]; 27049b5e25fSSatish Balay } 27149b5e25fSSatish Balay *ncols += bs; 27249b5e25fSSatish Balay break; 27349b5e25fSSatish Balay } 27449b5e25fSSatish Balay } 27549b5e25fSSatish Balay } 2765ddb2528SHong Zhang #endif 27749b5e25fSSatish Balay PetscFunctionReturn(0); 27849b5e25fSSatish Balay } 27949b5e25fSSatish Balay 2804a2ae208SSatish Balay #undef __FUNCT__ 2814a2ae208SSatish Balay #define __FUNCT__ "MatRestoreRow_SeqSBAIJ" 28213f74950SBarry Smith PetscErrorCode MatRestoreRow_SeqSBAIJ(Mat A,PetscInt row,PetscInt *nz,PetscInt **idx,PetscScalar **v) 28349b5e25fSSatish Balay { 284dfbe8321SBarry Smith PetscErrorCode ierr; 28549b5e25fSSatish Balay 28649b5e25fSSatish Balay PetscFunctionBegin; 28705b42c5fSBarry Smith if (idx) {ierr = PetscFree(*idx);CHKERRQ(ierr);} 28805b42c5fSBarry Smith if (v) {ierr = PetscFree(*v);CHKERRQ(ierr);} 28949b5e25fSSatish Balay PetscFunctionReturn(0); 29049b5e25fSSatish Balay } 29149b5e25fSSatish Balay 2924a2ae208SSatish Balay #undef __FUNCT__ 293f5edf698SHong Zhang #define __FUNCT__ "MatGetRowUpperTriangular_SeqSBAIJ" 294f5edf698SHong Zhang PetscErrorCode MatGetRowUpperTriangular_SeqSBAIJ(Mat A) 295f5edf698SHong Zhang { 296f5edf698SHong Zhang Mat_SeqSBAIJ *a = (Mat_SeqSBAIJ*)A->data; 297f5edf698SHong Zhang 298f5edf698SHong Zhang PetscFunctionBegin; 299f5edf698SHong Zhang a->getrow_utriangular = PETSC_TRUE; 300f5edf698SHong Zhang PetscFunctionReturn(0); 301f5edf698SHong Zhang } 302f5edf698SHong Zhang #undef __FUNCT__ 303f5edf698SHong Zhang #define __FUNCT__ "MatRestoreRowUpperTriangular_SeqSBAIJ" 304f5edf698SHong Zhang PetscErrorCode MatRestoreRowUpperTriangular_SeqSBAIJ(Mat A) 305f5edf698SHong Zhang { 306f5edf698SHong Zhang Mat_SeqSBAIJ *a = (Mat_SeqSBAIJ*)A->data; 307f5edf698SHong Zhang 308f5edf698SHong Zhang PetscFunctionBegin; 309f5edf698SHong Zhang a->getrow_utriangular = PETSC_FALSE; 310f5edf698SHong Zhang PetscFunctionReturn(0); 311f5edf698SHong Zhang } 312f5edf698SHong Zhang 313f5edf698SHong Zhang #undef __FUNCT__ 3144a2ae208SSatish Balay #define __FUNCT__ "MatTranspose_SeqSBAIJ" 315fc4dec0aSBarry Smith PetscErrorCode MatTranspose_SeqSBAIJ(Mat A,MatReuse reuse,Mat *B) 31649b5e25fSSatish Balay { 317dfbe8321SBarry Smith PetscErrorCode ierr; 31849b5e25fSSatish Balay PetscFunctionBegin; 319815cbec1SBarry Smith if (reuse == MAT_INITIAL_MATRIX || *B != A) { 320999d9058SBarry Smith ierr = MatDuplicate(A,MAT_COPY_VALUES,B);CHKERRQ(ierr); 321fc4dec0aSBarry Smith } 3228115998fSBarry Smith PetscFunctionReturn(0); 32349b5e25fSSatish Balay } 32449b5e25fSSatish Balay 3254a2ae208SSatish Balay #undef __FUNCT__ 3264a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqSBAIJ_ASCII" 3276849ba73SBarry Smith static PetscErrorCode MatView_SeqSBAIJ_ASCII(Mat A,PetscViewer viewer) 32849b5e25fSSatish Balay { 32949b5e25fSSatish Balay Mat_SeqSBAIJ *a = (Mat_SeqSBAIJ*)A->data; 330dfbe8321SBarry Smith PetscErrorCode ierr; 331d0f46423SBarry Smith PetscInt i,j,bs = A->rmap->bs,k,l,bs2=a->bs2; 3322dcb1b2aSMatthew Knepley const char *name; 333f3ef73ceSBarry Smith PetscViewerFormat format; 33449b5e25fSSatish Balay 33549b5e25fSSatish Balay PetscFunctionBegin; 33680fe4e49SBarry Smith ierr = PetscObjectGetName((PetscObject)A,&name);CHKERRQ(ierr); 337b0a32e0cSBarry Smith ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr); 338456192e2SBarry Smith if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) { 33977431f27SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," block size is %D\n",bs);CHKERRQ(ierr); 340fb9695e5SSatish Balay } else if (format == PETSC_VIEWER_ASCII_MATLAB) { 341d2507d54SMatthew Knepley Mat aij; 342d2507d54SMatthew Knepley 34370d5e725SHong Zhang if (A->factor && bs>1){ 34470d5e725SHong Zhang ierr = PetscPrintf(PETSC_COMM_SELF,"Warning: matrix is factored with bs>1. MatView() with PETSC_VIEWER_ASCII_MATLAB is not supported and ignored!\n");CHKERRQ(ierr); 34570d5e725SHong Zhang PetscFunctionReturn(0); 34670d5e725SHong Zhang } 347c9f458caSMatthew Knepley ierr = MatConvert(A,MATSEQAIJ,MAT_INITIAL_MATRIX,&aij);CHKERRQ(ierr); 348c9f458caSMatthew Knepley ierr = MatView(aij,viewer);CHKERRQ(ierr); 349c9f458caSMatthew Knepley ierr = MatDestroy(aij);CHKERRQ(ierr); 350fb9695e5SSatish Balay } else if (format == PETSC_VIEWER_ASCII_COMMON) { 351b0a32e0cSBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_NO);CHKERRQ(ierr); 35249b5e25fSSatish Balay for (i=0; i<a->mbs; i++) { 35349b5e25fSSatish Balay for (j=0; j<bs; j++) { 35477431f27SBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"row %D:",i*bs+j);CHKERRQ(ierr); 35549b5e25fSSatish Balay for (k=a->i[i]; k<a->i[i+1]; k++) { 35649b5e25fSSatish Balay for (l=0; l<bs; l++) { 35749b5e25fSSatish Balay #if defined(PETSC_USE_COMPLEX) 35849b5e25fSSatish Balay if (PetscImaginaryPart(a->a[bs2*k + l*bs + j]) > 0.0 && PetscRealPart(a->a[bs2*k + l*bs + j]) != 0.0) { 359a83599f4SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %G + %G i) ",bs*a->j[k]+l, 36049b5e25fSSatish Balay PetscRealPart(a->a[bs2*k + l*bs + j]),PetscImaginaryPart(a->a[bs2*k + l*bs + j]));CHKERRQ(ierr); 36149b5e25fSSatish Balay } else if (PetscImaginaryPart(a->a[bs2*k + l*bs + j]) < 0.0 && PetscRealPart(a->a[bs2*k + l*bs + j]) != 0.0) { 362a83599f4SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %G - %G i) ",bs*a->j[k]+l, 36349b5e25fSSatish Balay PetscRealPart(a->a[bs2*k + l*bs + j]),-PetscImaginaryPart(a->a[bs2*k + l*bs + j]));CHKERRQ(ierr); 36449b5e25fSSatish Balay } else if (PetscRealPart(a->a[bs2*k + l*bs + j]) != 0.0) { 365a83599f4SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %G) ",bs*a->j[k]+l,PetscRealPart(a->a[bs2*k + l*bs + j]));CHKERRQ(ierr); 36649b5e25fSSatish Balay } 36749b5e25fSSatish Balay #else 36849b5e25fSSatish Balay if (a->a[bs2*k + l*bs + j] != 0.0) { 369a83599f4SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %G) ",bs*a->j[k]+l,a->a[bs2*k + l*bs + j]);CHKERRQ(ierr); 37049b5e25fSSatish Balay } 37149b5e25fSSatish Balay #endif 37249b5e25fSSatish Balay } 37349b5e25fSSatish Balay } 374b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 37549b5e25fSSatish Balay } 37649b5e25fSSatish Balay } 377b0a32e0cSBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_YES);CHKERRQ(ierr); 378c1490034SHong Zhang } else if (format == PETSC_VIEWER_ASCII_FACTOR_INFO) { 379c1490034SHong Zhang PetscFunctionReturn(0); 38049b5e25fSSatish Balay } else { 3818608aa04SHong Zhang if (A->factor && bs>1){ 3828608aa04SHong Zhang ierr = PetscPrintf(PETSC_COMM_SELF,"Warning: matrix is factored. MatView_SeqSBAIJ_ASCII() may not display complete or logically correct entries!\n");CHKERRQ(ierr); 3838608aa04SHong Zhang } 384b0a32e0cSBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_NO);CHKERRQ(ierr); 38549b5e25fSSatish Balay for (i=0; i<a->mbs; i++) { 38649b5e25fSSatish Balay for (j=0; j<bs; j++) { 38777431f27SBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"row %D:",i*bs+j);CHKERRQ(ierr); 38849b5e25fSSatish Balay for (k=a->i[i]; k<a->i[i+1]; k++) { 38949b5e25fSSatish Balay for (l=0; l<bs; l++) { 39049b5e25fSSatish Balay #if defined(PETSC_USE_COMPLEX) 39149b5e25fSSatish Balay if (PetscImaginaryPart(a->a[bs2*k + l*bs + j]) > 0.0) { 392a83599f4SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %G + %G i) ",bs*a->j[k]+l, 39349b5e25fSSatish Balay PetscRealPart(a->a[bs2*k + l*bs + j]),PetscImaginaryPart(a->a[bs2*k + l*bs + j]));CHKERRQ(ierr); 39449b5e25fSSatish Balay } else if (PetscImaginaryPart(a->a[bs2*k + l*bs + j]) < 0.0) { 395a83599f4SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %G - %G i) ",bs*a->j[k]+l, 39649b5e25fSSatish Balay PetscRealPart(a->a[bs2*k + l*bs + j]),-PetscImaginaryPart(a->a[bs2*k + l*bs + j]));CHKERRQ(ierr); 39749b5e25fSSatish Balay } else { 398a83599f4SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %G) ",bs*a->j[k]+l,PetscRealPart(a->a[bs2*k + l*bs + j]));CHKERRQ(ierr); 39949b5e25fSSatish Balay } 40049b5e25fSSatish Balay #else 401e9f7bc9eSHong Zhang ierr = PetscViewerASCIIPrintf(viewer," (%D, %G) ",bs*a->j[k]+l,a->a[bs2*k + l*bs + j]);CHKERRQ(ierr); 40249b5e25fSSatish Balay #endif 40349b5e25fSSatish Balay } 40449b5e25fSSatish Balay } 405b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 40649b5e25fSSatish Balay } 40749b5e25fSSatish Balay } 408b0a32e0cSBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_YES);CHKERRQ(ierr); 40949b5e25fSSatish Balay } 410b0a32e0cSBarry Smith ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 41149b5e25fSSatish Balay PetscFunctionReturn(0); 41249b5e25fSSatish Balay } 41349b5e25fSSatish Balay 4144a2ae208SSatish Balay #undef __FUNCT__ 4154a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqSBAIJ_Draw_Zoom" 4166849ba73SBarry Smith static PetscErrorCode MatView_SeqSBAIJ_Draw_Zoom(PetscDraw draw,void *Aa) 41749b5e25fSSatish Balay { 41849b5e25fSSatish Balay Mat A = (Mat) Aa; 41949b5e25fSSatish Balay Mat_SeqSBAIJ *a=(Mat_SeqSBAIJ*)A->data; 4206849ba73SBarry Smith PetscErrorCode ierr; 421d0f46423SBarry Smith PetscInt row,i,j,k,l,mbs=a->mbs,color,bs=A->rmap->bs,bs2=a->bs2; 42213f74950SBarry Smith PetscMPIInt rank; 42349b5e25fSSatish Balay PetscReal xl,yl,xr,yr,x_l,x_r,y_l,y_r; 42449b5e25fSSatish Balay MatScalar *aa; 42549b5e25fSSatish Balay MPI_Comm comm; 426b0a32e0cSBarry Smith PetscViewer viewer; 42749b5e25fSSatish Balay 42849b5e25fSSatish Balay PetscFunctionBegin; 42949b5e25fSSatish Balay /* 43049b5e25fSSatish Balay This is nasty. If this is called from an originally parallel matrix 43149b5e25fSSatish Balay then all processes call this,but only the first has the matrix so the 43249b5e25fSSatish Balay rest should return immediately. 43349b5e25fSSatish Balay */ 43449b5e25fSSatish Balay ierr = PetscObjectGetComm((PetscObject)draw,&comm);CHKERRQ(ierr); 43549b5e25fSSatish Balay ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 43649b5e25fSSatish Balay if (rank) PetscFunctionReturn(0); 43749b5e25fSSatish Balay 43849b5e25fSSatish Balay ierr = PetscObjectQuery((PetscObject)A,"Zoomviewer",(PetscObject*)&viewer);CHKERRQ(ierr); 43949b5e25fSSatish Balay 440b0a32e0cSBarry Smith ierr = PetscDrawGetCoordinates(draw,&xl,&yl,&xr,&yr);CHKERRQ(ierr); 441b0a32e0cSBarry Smith PetscDrawString(draw, .3*(xl+xr), .3*(yl+yr), PETSC_DRAW_BLACK, "symmetric"); 44249b5e25fSSatish Balay 44349b5e25fSSatish Balay /* loop over matrix elements drawing boxes */ 444b0a32e0cSBarry Smith color = PETSC_DRAW_BLUE; 44549b5e25fSSatish Balay for (i=0,row=0; i<mbs; i++,row+=bs) { 44649b5e25fSSatish Balay for (j=a->i[i]; j<a->i[i+1]; j++) { 447d0f46423SBarry Smith y_l = A->rmap->N - row - 1.0; y_r = y_l + 1.0; 44849b5e25fSSatish Balay x_l = a->j[j]*bs; x_r = x_l + 1.0; 44949b5e25fSSatish Balay aa = a->a + j*bs2; 45049b5e25fSSatish Balay for (k=0; k<bs; k++) { 45149b5e25fSSatish Balay for (l=0; l<bs; l++) { 45249b5e25fSSatish Balay if (PetscRealPart(*aa++) >= 0.) continue; 453b0a32e0cSBarry Smith ierr = PetscDrawRectangle(draw,x_l+k,y_l-l,x_r+k,y_r-l,color,color,color,color);CHKERRQ(ierr); 45449b5e25fSSatish Balay } 45549b5e25fSSatish Balay } 45649b5e25fSSatish Balay } 45749b5e25fSSatish Balay } 458b0a32e0cSBarry Smith color = PETSC_DRAW_CYAN; 45949b5e25fSSatish Balay for (i=0,row=0; i<mbs; i++,row+=bs) { 46049b5e25fSSatish Balay for (j=a->i[i]; j<a->i[i+1]; j++) { 461d0f46423SBarry Smith y_l = A->rmap->N - row - 1.0; y_r = y_l + 1.0; 46249b5e25fSSatish Balay x_l = a->j[j]*bs; x_r = x_l + 1.0; 46349b5e25fSSatish Balay aa = a->a + j*bs2; 46449b5e25fSSatish Balay for (k=0; k<bs; k++) { 46549b5e25fSSatish Balay for (l=0; l<bs; l++) { 46649b5e25fSSatish Balay if (PetscRealPart(*aa++) != 0.) continue; 467b0a32e0cSBarry Smith ierr = PetscDrawRectangle(draw,x_l+k,y_l-l,x_r+k,y_r-l,color,color,color,color);CHKERRQ(ierr); 46849b5e25fSSatish Balay } 46949b5e25fSSatish Balay } 47049b5e25fSSatish Balay } 47149b5e25fSSatish Balay } 47249b5e25fSSatish Balay 473b0a32e0cSBarry Smith color = PETSC_DRAW_RED; 47449b5e25fSSatish Balay for (i=0,row=0; i<mbs; i++,row+=bs) { 47549b5e25fSSatish Balay for (j=a->i[i]; j<a->i[i+1]; j++) { 476d0f46423SBarry Smith y_l = A->rmap->N - row - 1.0; y_r = y_l + 1.0; 47749b5e25fSSatish Balay x_l = a->j[j]*bs; x_r = x_l + 1.0; 47849b5e25fSSatish Balay aa = a->a + j*bs2; 47949b5e25fSSatish Balay for (k=0; k<bs; k++) { 48049b5e25fSSatish Balay for (l=0; l<bs; l++) { 48149b5e25fSSatish Balay if (PetscRealPart(*aa++) <= 0.) continue; 482b0a32e0cSBarry Smith ierr = PetscDrawRectangle(draw,x_l+k,y_l-l,x_r+k,y_r-l,color,color,color,color);CHKERRQ(ierr); 48349b5e25fSSatish Balay } 48449b5e25fSSatish Balay } 48549b5e25fSSatish Balay } 48649b5e25fSSatish Balay } 48749b5e25fSSatish Balay PetscFunctionReturn(0); 48849b5e25fSSatish Balay } 48949b5e25fSSatish Balay 4904a2ae208SSatish Balay #undef __FUNCT__ 4914a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqSBAIJ_Draw" 4926849ba73SBarry Smith static PetscErrorCode MatView_SeqSBAIJ_Draw(Mat A,PetscViewer viewer) 49349b5e25fSSatish Balay { 494dfbe8321SBarry Smith PetscErrorCode ierr; 49549b5e25fSSatish Balay PetscReal xl,yl,xr,yr,w,h; 496b0a32e0cSBarry Smith PetscDraw draw; 49749b5e25fSSatish Balay PetscTruth isnull; 49849b5e25fSSatish Balay 49949b5e25fSSatish Balay PetscFunctionBegin; 500b0a32e0cSBarry Smith ierr = PetscViewerDrawGetDraw(viewer,0,&draw);CHKERRQ(ierr); 501b0a32e0cSBarry Smith ierr = PetscDrawIsNull(draw,&isnull);CHKERRQ(ierr); if (isnull) PetscFunctionReturn(0); 50249b5e25fSSatish Balay 50349b5e25fSSatish Balay ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",(PetscObject)viewer);CHKERRQ(ierr); 504d0f46423SBarry Smith xr = A->rmap->N; yr = A->rmap->N; h = yr/10.0; w = xr/10.0; 50549b5e25fSSatish Balay xr += w; yr += h; xl = -w; yl = -h; 506b0a32e0cSBarry Smith ierr = PetscDrawSetCoordinates(draw,xl,yl,xr,yr);CHKERRQ(ierr); 507b0a32e0cSBarry Smith ierr = PetscDrawZoom(draw,MatView_SeqSBAIJ_Draw_Zoom,A);CHKERRQ(ierr); 50849b5e25fSSatish Balay ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",PETSC_NULL);CHKERRQ(ierr); 50949b5e25fSSatish Balay PetscFunctionReturn(0); 51049b5e25fSSatish Balay } 51149b5e25fSSatish Balay 5124a2ae208SSatish Balay #undef __FUNCT__ 5134a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqSBAIJ" 514dfbe8321SBarry Smith PetscErrorCode MatView_SeqSBAIJ(Mat A,PetscViewer viewer) 51549b5e25fSSatish Balay { 516dfbe8321SBarry Smith PetscErrorCode ierr; 51732077d6dSBarry Smith PetscTruth iascii,isdraw; 51849b5e25fSSatish Balay 51949b5e25fSSatish Balay PetscFunctionBegin; 52032077d6dSBarry Smith ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&iascii);CHKERRQ(ierr); 521fb9695e5SSatish Balay ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_DRAW,&isdraw);CHKERRQ(ierr); 52232077d6dSBarry Smith if (iascii){ 52349b5e25fSSatish Balay ierr = MatView_SeqSBAIJ_ASCII(A,viewer);CHKERRQ(ierr); 52449b5e25fSSatish Balay } else if (isdraw) { 52549b5e25fSSatish Balay ierr = MatView_SeqSBAIJ_Draw(A,viewer);CHKERRQ(ierr); 52649b5e25fSSatish Balay } else { 527a5e6ed63SBarry Smith Mat B; 528ceb03754SKris Buschelman ierr = MatConvert(A,MATSEQAIJ,MAT_INITIAL_MATRIX,&B);CHKERRQ(ierr); 529a5e6ed63SBarry Smith ierr = MatView(B,viewer);CHKERRQ(ierr); 530a5e6ed63SBarry Smith ierr = MatDestroy(B);CHKERRQ(ierr); 53149b5e25fSSatish Balay } 53249b5e25fSSatish Balay PetscFunctionReturn(0); 53349b5e25fSSatish Balay } 53449b5e25fSSatish Balay 53549b5e25fSSatish Balay 5364a2ae208SSatish Balay #undef __FUNCT__ 5374a2ae208SSatish Balay #define __FUNCT__ "MatGetValues_SeqSBAIJ" 53813f74950SBarry Smith PetscErrorCode MatGetValues_SeqSBAIJ(Mat A,PetscInt m,const PetscInt im[],PetscInt n,const PetscInt in[],PetscScalar v[]) 53949b5e25fSSatish Balay { 540045c9aa0SHong Zhang Mat_SeqSBAIJ *a = (Mat_SeqSBAIJ*)A->data; 54113f74950SBarry Smith PetscInt *rp,k,low,high,t,row,nrow,i,col,l,*aj = a->j; 54213f74950SBarry Smith PetscInt *ai = a->i,*ailen = a->ilen; 543d0f46423SBarry Smith PetscInt brow,bcol,ridx,cidx,bs=A->rmap->bs,bs2=a->bs2; 54497e567efSBarry Smith MatScalar *ap,*aa = a->a; 54549b5e25fSSatish Balay 54649b5e25fSSatish Balay PetscFunctionBegin; 54749b5e25fSSatish Balay for (k=0; k<m; k++) { /* loop over rows */ 54849b5e25fSSatish Balay row = im[k]; brow = row/bs; 54997e567efSBarry Smith if (row < 0) {v += n; continue;} /* SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Negative row: %D",row); */ 550d0f46423SBarry Smith if (row >= A->rmap->N) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"Row too large: row %D max %D",row,A->rmap->N-1); 55149b5e25fSSatish Balay rp = aj + ai[brow] ; ap = aa + bs2*ai[brow] ; 55249b5e25fSSatish Balay nrow = ailen[brow]; 55349b5e25fSSatish Balay for (l=0; l<n; l++) { /* loop over columns */ 55497e567efSBarry Smith if (in[l] < 0) {v++; continue;} /* SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Negative column: %D",in[l]); */ 555d0f46423SBarry Smith if (in[l] >= A->cmap->n) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"Column too large: col %D max %D",in[l],A->cmap->n-1); 55649b5e25fSSatish Balay col = in[l] ; 55749b5e25fSSatish Balay bcol = col/bs; 55849b5e25fSSatish Balay cidx = col%bs; 55949b5e25fSSatish Balay ridx = row%bs; 56049b5e25fSSatish Balay high = nrow; 56149b5e25fSSatish Balay low = 0; /* assume unsorted */ 56249b5e25fSSatish Balay while (high-low > 5) { 56349b5e25fSSatish Balay t = (low+high)/2; 56449b5e25fSSatish Balay if (rp[t] > bcol) high = t; 56549b5e25fSSatish Balay else low = t; 56649b5e25fSSatish Balay } 56749b5e25fSSatish Balay for (i=low; i<high; i++) { 56849b5e25fSSatish Balay if (rp[i] > bcol) break; 56949b5e25fSSatish Balay if (rp[i] == bcol) { 57049b5e25fSSatish Balay *v++ = ap[bs2*i+bs*cidx+ridx]; 57149b5e25fSSatish Balay goto finished; 57249b5e25fSSatish Balay } 57349b5e25fSSatish Balay } 57497e567efSBarry Smith *v++ = 0.0; 57549b5e25fSSatish Balay finished:; 57649b5e25fSSatish Balay } 57749b5e25fSSatish Balay } 57849b5e25fSSatish Balay PetscFunctionReturn(0); 57949b5e25fSSatish Balay } 58049b5e25fSSatish Balay 58149b5e25fSSatish Balay 5824a2ae208SSatish Balay #undef __FUNCT__ 5834a2ae208SSatish Balay #define __FUNCT__ "MatSetValuesBlocked_SeqSBAIJ" 58413f74950SBarry Smith PetscErrorCode MatSetValuesBlocked_SeqSBAIJ(Mat A,PetscInt m,const PetscInt im[],PetscInt n,const PetscInt in[],const PetscScalar v[],InsertMode is) 58549b5e25fSSatish Balay { 5860880e062SHong Zhang Mat_SeqSBAIJ *a = (Mat_SeqSBAIJ*)A->data; 5876849ba73SBarry Smith PetscErrorCode ierr; 588e2ee6c50SBarry Smith PetscInt *rp,k,low,high,t,ii,jj,row,nrow,i,col,l,rmax,N,lastcol = -1; 58913f74950SBarry Smith PetscInt *imax=a->imax,*ai=a->i,*ailen=a->ilen; 590d0f46423SBarry Smith PetscInt *aj=a->j,nonew=a->nonew,bs2=a->bs2,bs=A->rmap->bs,stepval; 5910880e062SHong Zhang PetscTruth roworiented=a->roworiented; 592dd6ea824SBarry Smith const PetscScalar *value = v; 593f15d580aSBarry Smith MatScalar *ap,*aa = a->a,*bap; 5940880e062SHong Zhang 59549b5e25fSSatish Balay PetscFunctionBegin; 5960880e062SHong Zhang if (roworiented) { 5970880e062SHong Zhang stepval = (n-1)*bs; 5980880e062SHong Zhang } else { 5990880e062SHong Zhang stepval = (m-1)*bs; 6000880e062SHong Zhang } 6010880e062SHong Zhang for (k=0; k<m; k++) { /* loop over added rows */ 6020880e062SHong Zhang row = im[k]; 6030880e062SHong Zhang if (row < 0) continue; 6042515c552SBarry Smith #if defined(PETSC_USE_DEBUG) 60577431f27SBarry Smith if (row >= a->mbs) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"Row too large: row %D max %D",row,a->mbs-1); 6060880e062SHong Zhang #endif 6070880e062SHong Zhang rp = aj + ai[row]; 6080880e062SHong Zhang ap = aa + bs2*ai[row]; 6090880e062SHong Zhang rmax = imax[row]; 6100880e062SHong Zhang nrow = ailen[row]; 6110880e062SHong Zhang low = 0; 612818f2c47SBarry Smith high = nrow; 6130880e062SHong Zhang for (l=0; l<n; l++) { /* loop over added columns */ 6140880e062SHong Zhang if (in[l] < 0) continue; 6150880e062SHong Zhang col = in[l]; 6162515c552SBarry Smith #if defined(PETSC_USE_DEBUG) 61777431f27SBarry Smith if (col >= a->nbs) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"Column too large: col %D max %D",col,a->nbs-1); 618b1823623SSatish Balay #endif 6190880e062SHong Zhang if (col < row) continue; /* ignore lower triangular block */ 6200880e062SHong Zhang if (roworiented) { 6210880e062SHong Zhang value = v + k*(stepval+bs)*bs + l*bs; 6220880e062SHong Zhang } else { 6230880e062SHong Zhang value = v + l*(stepval+bs)*bs + k*bs; 6240880e062SHong Zhang } 6257cd84e04SBarry Smith if (col <= lastcol) low = 0; else high = nrow; 626e2ee6c50SBarry Smith lastcol = col; 6270880e062SHong Zhang while (high-low > 7) { 6280880e062SHong Zhang t = (low+high)/2; 6290880e062SHong Zhang if (rp[t] > col) high = t; 6300880e062SHong Zhang else low = t; 6310880e062SHong Zhang } 6320880e062SHong Zhang for (i=low; i<high; i++) { 6330880e062SHong Zhang if (rp[i] > col) break; 6340880e062SHong Zhang if (rp[i] == col) { 6350880e062SHong Zhang bap = ap + bs2*i; 6360880e062SHong Zhang if (roworiented) { 6370880e062SHong Zhang if (is == ADD_VALUES) { 6380880e062SHong Zhang for (ii=0; ii<bs; ii++,value+=stepval) { 6390880e062SHong Zhang for (jj=ii; jj<bs2; jj+=bs) { 6400880e062SHong Zhang bap[jj] += *value++; 6410880e062SHong Zhang } 6420880e062SHong Zhang } 6430880e062SHong Zhang } else { 6440880e062SHong Zhang for (ii=0; ii<bs; ii++,value+=stepval) { 6450880e062SHong Zhang for (jj=ii; jj<bs2; jj+=bs) { 6460880e062SHong Zhang bap[jj] = *value++; 6470880e062SHong Zhang } 6480880e062SHong Zhang } 6490880e062SHong Zhang } 6500880e062SHong Zhang } else { 6510880e062SHong Zhang if (is == ADD_VALUES) { 6520880e062SHong Zhang for (ii=0; ii<bs; ii++,value+=stepval) { 6530880e062SHong Zhang for (jj=0; jj<bs; jj++) { 6540880e062SHong Zhang *bap++ += *value++; 6550880e062SHong Zhang } 6560880e062SHong Zhang } 6570880e062SHong Zhang } else { 6580880e062SHong Zhang for (ii=0; ii<bs; ii++,value+=stepval) { 6590880e062SHong Zhang for (jj=0; jj<bs; jj++) { 6600880e062SHong Zhang *bap++ = *value++; 6610880e062SHong Zhang } 6620880e062SHong Zhang } 6630880e062SHong Zhang } 6640880e062SHong Zhang } 6650880e062SHong Zhang goto noinsert2; 6660880e062SHong Zhang } 6670880e062SHong Zhang } 6680880e062SHong Zhang if (nonew == 1) goto noinsert2; 669085a36d4SBarry Smith if (nonew == -1) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"Inserting a new nonzero (%D, %D) in the matrix", row, col); 670421e10b8SBarry Smith MatSeqXAIJReallocateAIJ(A,a->mbs,bs2,nrow,row,col,rmax,aa,ai,aj,rp,ap,imax,nonew,MatScalar); 671c03d1d03SSatish Balay N = nrow++ - 1; high++; 6720880e062SHong Zhang /* shift up all the later entries in this row */ 6730880e062SHong Zhang for (ii=N; ii>=i; ii--) { 6740880e062SHong Zhang rp[ii+1] = rp[ii]; 6750880e062SHong Zhang ierr = PetscMemcpy(ap+bs2*(ii+1),ap+bs2*(ii),bs2*sizeof(MatScalar));CHKERRQ(ierr); 6760880e062SHong Zhang } 6770880e062SHong Zhang if (N >= i) { 6780880e062SHong Zhang ierr = PetscMemzero(ap+bs2*i,bs2*sizeof(MatScalar));CHKERRQ(ierr); 6790880e062SHong Zhang } 6800880e062SHong Zhang rp[i] = col; 6810880e062SHong Zhang bap = ap + bs2*i; 6820880e062SHong Zhang if (roworiented) { 6830880e062SHong Zhang for (ii=0; ii<bs; ii++,value+=stepval) { 6840880e062SHong Zhang for (jj=ii; jj<bs2; jj+=bs) { 6850880e062SHong Zhang bap[jj] = *value++; 6860880e062SHong Zhang } 6870880e062SHong Zhang } 6880880e062SHong Zhang } else { 6890880e062SHong Zhang for (ii=0; ii<bs; ii++,value+=stepval) { 6900880e062SHong Zhang for (jj=0; jj<bs; jj++) { 6910880e062SHong Zhang *bap++ = *value++; 6920880e062SHong Zhang } 6930880e062SHong Zhang } 6940880e062SHong Zhang } 6950880e062SHong Zhang noinsert2:; 6960880e062SHong Zhang low = i; 6970880e062SHong Zhang } 6980880e062SHong Zhang ailen[row] = nrow; 6990880e062SHong Zhang } 7000880e062SHong Zhang PetscFunctionReturn(0); 70149b5e25fSSatish Balay } 70249b5e25fSSatish Balay 7034a2ae208SSatish Balay #undef __FUNCT__ 704*0def2e27SBarry Smith #define __FUNCT__ "MatAssemblyEnd_SeqSBAIJ_Inode" 705*0def2e27SBarry Smith PetscErrorCode MatAssemblyEnd_SeqSBAIJ_Inode(Mat A) 706*0def2e27SBarry Smith { 707*0def2e27SBarry Smith Mat_SeqSBAIJ *a = (Mat_SeqSBAIJ*)A->data; 708*0def2e27SBarry Smith PetscErrorCode ierr; 709*0def2e27SBarry Smith const PetscInt *ai = a->i, *aj = a->j,*cols; 710*0def2e27SBarry Smith PetscInt i = 0,j,blk_size,m = A->rmap->n,node_count = 0,nzx,nzy,*ns,row,nz,cnt,cnt2,*counts; 711*0def2e27SBarry Smith PetscTruth flag; 712*0def2e27SBarry Smith 713*0def2e27SBarry Smith PetscFunctionBegin; 714*0def2e27SBarry Smith ierr = PetscMalloc(m*sizeof(PetscInt),&ns);CHKERRQ(ierr); 715*0def2e27SBarry Smith while (i < m){ 716*0def2e27SBarry Smith nzx = ai[i+1] - ai[i]; /* Number of nonzeros */ 717*0def2e27SBarry Smith /* Limits the number of elements in a node to 'a->inode.limit' */ 718*0def2e27SBarry Smith for (j=i+1,blk_size=1; j<m && blk_size <a->inode.limit; ++j,++blk_size) { 719*0def2e27SBarry Smith nzy = ai[j+1] - ai[j]; 720*0def2e27SBarry Smith if (nzy != (nzx - j + i)) break; 721*0def2e27SBarry Smith ierr = PetscMemcmp(aj + ai[i] + j - i,aj + ai[j],nzy*sizeof(PetscInt),&flag);CHKERRQ(ierr); 722*0def2e27SBarry Smith if (!flag) break; 723*0def2e27SBarry Smith } 724*0def2e27SBarry Smith ns[node_count++] = blk_size; 725*0def2e27SBarry Smith i = j; 726*0def2e27SBarry Smith } 727*0def2e27SBarry Smith if (!a->inode.size && m && node_count > .9*m) { 728*0def2e27SBarry Smith ierr = PetscFree(ns);CHKERRQ(ierr); 729*0def2e27SBarry Smith ierr = PetscInfo2(A,"Found %D nodes out of %D rows. Not using Inode routines\n",node_count,m);CHKERRQ(ierr); 730*0def2e27SBarry Smith } else { 731*0def2e27SBarry Smith a->inode.node_count = node_count; 732*0def2e27SBarry Smith ierr = PetscMalloc(node_count*sizeof(PetscInt),&a->inode.size);CHKERRQ(ierr); 733*0def2e27SBarry Smith ierr = PetscMemcpy(a->inode.size,ns,node_count*sizeof(PetscInt)); 734*0def2e27SBarry Smith ierr = PetscFree(ns);CHKERRQ(ierr); 735*0def2e27SBarry Smith ierr = PetscInfo3(A,"Found %D nodes of %D. Limit used: %D. Using Inode routines\n",node_count,m,a->inode.limit);CHKERRQ(ierr); 736*0def2e27SBarry Smith 737*0def2e27SBarry Smith /* count collections of adjacent columns in each inode */ 738*0def2e27SBarry Smith row = 0; 739*0def2e27SBarry Smith cnt = 0; 740*0def2e27SBarry Smith for (i=0; i<node_count; i++) { 741*0def2e27SBarry Smith cols = aj + ai[row] + a->inode.size[i]; 742*0def2e27SBarry Smith nz = ai[row+1] - ai[row] - a->inode.size[i]; 743*0def2e27SBarry Smith for (j=1; j<nz; j++) { 744*0def2e27SBarry Smith if (cols[j] != cols[j-1]+1) { 745*0def2e27SBarry Smith cnt++; 746*0def2e27SBarry Smith } 747*0def2e27SBarry Smith } 748*0def2e27SBarry Smith cnt++; 749*0def2e27SBarry Smith row += a->inode.size[i]; 750*0def2e27SBarry Smith } 751*0def2e27SBarry Smith ierr = PetscMalloc(2*cnt*sizeof(PetscInt),&counts);CHKERRQ(ierr); 752*0def2e27SBarry Smith cnt = 0; 753*0def2e27SBarry Smith row = 0; 754*0def2e27SBarry Smith for (i=0; i<node_count; i++) { 755*0def2e27SBarry Smith cols = aj + ai[row] + a->inode.size[i]; 756*0def2e27SBarry Smith CHKMEMQ; 757*0def2e27SBarry Smith counts[2*cnt] = cols[0]; 758*0def2e27SBarry Smith CHKMEMQ; 759*0def2e27SBarry Smith nz = ai[row+1] - ai[row] - a->inode.size[i]; 760*0def2e27SBarry Smith cnt2 = 1; 761*0def2e27SBarry Smith for (j=1; j<nz; j++) { 762*0def2e27SBarry Smith if (cols[j] != cols[j-1]+1) { 763*0def2e27SBarry Smith CHKMEMQ; 764*0def2e27SBarry Smith counts[2*(cnt++)+1] = cnt2; 765*0def2e27SBarry Smith counts[2*cnt] = cols[j]; 766*0def2e27SBarry Smith CHKMEMQ; 767*0def2e27SBarry Smith cnt2 = 1; 768*0def2e27SBarry Smith } else cnt2++; 769*0def2e27SBarry Smith } 770*0def2e27SBarry Smith CHKMEMQ; 771*0def2e27SBarry Smith counts[2*(cnt++)+1] = cnt2; 772*0def2e27SBarry Smith CHKMEMQ; 773*0def2e27SBarry Smith row += a->inode.size[i]; 774*0def2e27SBarry Smith } 775*0def2e27SBarry Smith ierr = PetscIntView(2*cnt,counts,0); 776*0def2e27SBarry Smith } 777*0def2e27SBarry Smith 778*0def2e27SBarry Smith 779*0def2e27SBarry Smith PetscFunctionReturn(0); 780*0def2e27SBarry Smith } 781*0def2e27SBarry Smith 782*0def2e27SBarry Smith #undef __FUNCT__ 7834a2ae208SSatish Balay #define __FUNCT__ "MatAssemblyEnd_SeqSBAIJ" 784dfbe8321SBarry Smith PetscErrorCode MatAssemblyEnd_SeqSBAIJ(Mat A,MatAssemblyType mode) 78549b5e25fSSatish Balay { 78649b5e25fSSatish Balay Mat_SeqSBAIJ *a = (Mat_SeqSBAIJ*)A->data; 7876849ba73SBarry Smith PetscErrorCode ierr; 78813f74950SBarry Smith PetscInt fshift = 0,i,j,*ai = a->i,*aj = a->j,*imax = a->imax; 789d0f46423SBarry Smith PetscInt m = A->rmap->N,*ip,N,*ailen = a->ilen; 79013f74950SBarry Smith PetscInt mbs = a->mbs,bs2 = a->bs2,rmax = 0; 79149b5e25fSSatish Balay MatScalar *aa = a->a,*ap; 79249b5e25fSSatish Balay 79349b5e25fSSatish Balay PetscFunctionBegin; 79449b5e25fSSatish Balay if (mode == MAT_FLUSH_ASSEMBLY) PetscFunctionReturn(0); 79549b5e25fSSatish Balay 79649b5e25fSSatish Balay if (m) rmax = ailen[0]; 79749b5e25fSSatish Balay for (i=1; i<mbs; i++) { 79849b5e25fSSatish Balay /* move each row back by the amount of empty slots (fshift) before it*/ 79949b5e25fSSatish Balay fshift += imax[i-1] - ailen[i-1]; 80049b5e25fSSatish Balay rmax = PetscMax(rmax,ailen[i]); 80149b5e25fSSatish Balay if (fshift) { 80249b5e25fSSatish Balay ip = aj + ai[i]; ap = aa + bs2*ai[i]; 80349b5e25fSSatish Balay N = ailen[i]; 80449b5e25fSSatish Balay for (j=0; j<N; j++) { 80549b5e25fSSatish Balay ip[j-fshift] = ip[j]; 80649b5e25fSSatish Balay ierr = PetscMemcpy(ap+(j-fshift)*bs2,ap+j*bs2,bs2*sizeof(MatScalar));CHKERRQ(ierr); 80749b5e25fSSatish Balay } 80849b5e25fSSatish Balay } 80949b5e25fSSatish Balay ai[i] = ai[i-1] + ailen[i-1]; 81049b5e25fSSatish Balay } 81149b5e25fSSatish Balay if (mbs) { 81249b5e25fSSatish Balay fshift += imax[mbs-1] - ailen[mbs-1]; 81349b5e25fSSatish Balay ai[mbs] = ai[mbs-1] + ailen[mbs-1]; 81449b5e25fSSatish Balay } 81549b5e25fSSatish Balay /* reset ilen and imax for each row */ 81649b5e25fSSatish Balay for (i=0; i<mbs; i++) { 81749b5e25fSSatish Balay ailen[i] = imax[i] = ai[i+1] - ai[i]; 81849b5e25fSSatish Balay } 8196c6c5352SBarry Smith a->nz = ai[mbs]; 82049b5e25fSSatish Balay 821b424e231SHong Zhang /* diagonals may have moved, reset it */ 822b424e231SHong Zhang if (a->diag) { 82313f74950SBarry Smith ierr = PetscMemcpy(a->diag,ai,(mbs+1)*sizeof(PetscInt));CHKERRQ(ierr); 82449b5e25fSSatish Balay } 82528b2fa4aSMatthew Knepley if (fshift && a->nounused == -1) { 82628b2fa4aSMatthew Knepley SETERRQ4(PETSC_ERR_PLIB, "Unused space detected in matrix: %D X %D block size %D, %D unneeded", m, A->cmap->n, A->rmap->bs, fshift*bs2); 82728b2fa4aSMatthew Knepley } 828d0f46423SBarry Smith ierr = PetscInfo5(A,"Matrix size: %D X %D, block size %D; storage space: %D unneeded, %D used\n",m,A->rmap->N,A->rmap->bs,fshift*bs2,a->nz*bs2);CHKERRQ(ierr); 829ae15b995SBarry Smith ierr = PetscInfo1(A,"Number of mallocs during MatSetValues is %D\n",a->reallocs);CHKERRQ(ierr); 830ae15b995SBarry Smith ierr = PetscInfo1(A,"Most nonzeros blocks in any row is %D\n",rmax);CHKERRQ(ierr); 83149b5e25fSSatish Balay a->reallocs = 0; 83249b5e25fSSatish Balay A->info.nz_unneeded = (PetscReal)fshift*bs2; 833061b2667SBarry Smith a->idiagvalid = PETSC_FALSE; 834*0def2e27SBarry Smith if (bs2 == 1) { 835*0def2e27SBarry Smith ierr = MatAssemblyEnd_SeqSBAIJ_Inode(A);CHKERRQ(ierr); 836*0def2e27SBarry Smith } 83749b5e25fSSatish Balay PetscFunctionReturn(0); 83849b5e25fSSatish Balay } 83949b5e25fSSatish Balay 84049b5e25fSSatish Balay /* 84149b5e25fSSatish Balay This function returns an array of flags which indicate the locations of contiguous 84249b5e25fSSatish Balay blocks that should be zeroed. for eg: if bs = 3 and is = [0,1,2,3,5,6,7,8,9] 84349b5e25fSSatish Balay then the resulting sizes = [3,1,1,3,1] correspondig to sets [(0,1,2),(3),(5),(6,7,8),(9)] 84449b5e25fSSatish Balay Assume: sizes should be long enough to hold all the values. 84549b5e25fSSatish Balay */ 8464a2ae208SSatish Balay #undef __FUNCT__ 8474a2ae208SSatish Balay #define __FUNCT__ "MatZeroRows_SeqSBAIJ_Check_Blocks" 84813f74950SBarry Smith PetscErrorCode MatZeroRows_SeqSBAIJ_Check_Blocks(PetscInt idx[],PetscInt n,PetscInt bs,PetscInt sizes[], PetscInt *bs_max) 84949b5e25fSSatish Balay { 85013f74950SBarry Smith PetscInt i,j,k,row; 85149b5e25fSSatish Balay PetscTruth flg; 85249b5e25fSSatish Balay 85349b5e25fSSatish Balay PetscFunctionBegin; 85449b5e25fSSatish Balay for (i=0,j=0; i<n; j++) { 85549b5e25fSSatish Balay row = idx[i]; 85649b5e25fSSatish Balay if (row%bs!=0) { /* Not the begining of a block */ 85749b5e25fSSatish Balay sizes[j] = 1; 85849b5e25fSSatish Balay i++; 85949b5e25fSSatish Balay } else if (i+bs > n) { /* Beginning of a block, but complete block doesn't exist (at idx end) */ 86049b5e25fSSatish Balay sizes[j] = 1; /* Also makes sure atleast 'bs' values exist for next else */ 86149b5e25fSSatish Balay i++; 86249b5e25fSSatish Balay } else { /* Begining of the block, so check if the complete block exists */ 86349b5e25fSSatish Balay flg = PETSC_TRUE; 86449b5e25fSSatish Balay for (k=1; k<bs; k++) { 86549b5e25fSSatish Balay if (row+k != idx[i+k]) { /* break in the block */ 86649b5e25fSSatish Balay flg = PETSC_FALSE; 86749b5e25fSSatish Balay break; 86849b5e25fSSatish Balay } 86949b5e25fSSatish Balay } 870abc0a331SBarry Smith if (flg) { /* No break in the bs */ 87149b5e25fSSatish Balay sizes[j] = bs; 87249b5e25fSSatish Balay i+= bs; 87349b5e25fSSatish Balay } else { 87449b5e25fSSatish Balay sizes[j] = 1; 87549b5e25fSSatish Balay i++; 87649b5e25fSSatish Balay } 87749b5e25fSSatish Balay } 87849b5e25fSSatish Balay } 87949b5e25fSSatish Balay *bs_max = j; 88049b5e25fSSatish Balay PetscFunctionReturn(0); 88149b5e25fSSatish Balay } 88249b5e25fSSatish Balay 88349b5e25fSSatish Balay 88449b5e25fSSatish Balay /* Only add/insert a(i,j) with i<=j (blocks). 88549b5e25fSSatish Balay Any a(i,j) with i>j input by user is ingored. 88649b5e25fSSatish Balay */ 88749b5e25fSSatish Balay 8884a2ae208SSatish Balay #undef __FUNCT__ 8894a2ae208SSatish Balay #define __FUNCT__ "MatSetValues_SeqSBAIJ" 89013f74950SBarry Smith PetscErrorCode MatSetValues_SeqSBAIJ(Mat A,PetscInt m,const PetscInt im[],PetscInt n,const PetscInt in[],const PetscScalar v[],InsertMode is) 89149b5e25fSSatish Balay { 89249b5e25fSSatish Balay Mat_SeqSBAIJ *a = (Mat_SeqSBAIJ*)A->data; 8936849ba73SBarry Smith PetscErrorCode ierr; 894e2ee6c50SBarry Smith PetscInt *rp,k,low,high,t,ii,row,nrow,i,col,l,rmax,N,lastcol = -1; 89513f74950SBarry Smith PetscInt *imax=a->imax,*ai=a->i,*ailen=a->ilen,roworiented=a->roworiented; 896d0f46423SBarry Smith PetscInt *aj=a->j,nonew=a->nonew,bs=A->rmap->bs,brow,bcol; 89713f74950SBarry Smith PetscInt ridx,cidx,bs2=a->bs2; 89849b5e25fSSatish Balay MatScalar *ap,value,*aa=a->a,*bap; 89949b5e25fSSatish Balay 90049b5e25fSSatish Balay PetscFunctionBegin; 90149b5e25fSSatish Balay for (k=0; k<m; k++) { /* loop over added rows */ 90249b5e25fSSatish Balay row = im[k]; /* row number */ 90349b5e25fSSatish Balay brow = row/bs; /* block row number */ 90449b5e25fSSatish Balay if (row < 0) continue; 9052515c552SBarry Smith #if defined(PETSC_USE_DEBUG) 906d0f46423SBarry Smith if (row >= A->rmap->N) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"Row too large: row %D max %D",row,A->rmap->N-1); 90749b5e25fSSatish Balay #endif 90849b5e25fSSatish Balay rp = aj + ai[brow]; /*ptr to beginning of column value of the row block*/ 90949b5e25fSSatish Balay ap = aa + bs2*ai[brow]; /*ptr to beginning of element value of the row block*/ 91049b5e25fSSatish Balay rmax = imax[brow]; /* maximum space allocated for this row */ 91149b5e25fSSatish Balay nrow = ailen[brow]; /* actual length of this row */ 91249b5e25fSSatish Balay low = 0; 91349b5e25fSSatish Balay 91449b5e25fSSatish Balay for (l=0; l<n; l++) { /* loop over added columns */ 91549b5e25fSSatish Balay if (in[l] < 0) continue; 9162515c552SBarry Smith #if defined(PETSC_USE_DEBUG) 917d0f46423SBarry Smith if (in[l] >= A->rmap->N) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"Column too large: col %D max %D",in[l],A->rmap->N-1); 91849b5e25fSSatish Balay #endif 91949b5e25fSSatish Balay col = in[l]; 92049b5e25fSSatish Balay bcol = col/bs; /* block col number */ 92149b5e25fSSatish Balay 922941593c8SHong Zhang if (brow > bcol) { 923941593c8SHong Zhang if (a->ignore_ltriangular){ 924941593c8SHong Zhang continue; /* ignore lower triangular values */ 925941593c8SHong Zhang } else { 9264e0d8c25SBarry Smith SETERRQ(PETSC_ERR_USER,"Lower triangular value cannot be set for sbaij format. Ignoring these values, run with -mat_ignore_lower_triangular or call MatSetOption(mat,MAT_IGNORE_LOWER_TRIANGULAR,PETSC_TRUE)"); 927941593c8SHong Zhang } 928941593c8SHong Zhang } 929f4989cb3SHong Zhang 93049b5e25fSSatish Balay ridx = row % bs; cidx = col % bs; /*row and col index inside the block */ 9318549e402SHong Zhang if ((brow==bcol && ridx<=cidx) || (brow<bcol)){ 93249b5e25fSSatish Balay /* element value a(k,l) */ 93349b5e25fSSatish Balay if (roworiented) { 93449b5e25fSSatish Balay value = v[l + k*n]; 93549b5e25fSSatish Balay } else { 93649b5e25fSSatish Balay value = v[k + l*m]; 93749b5e25fSSatish Balay } 93849b5e25fSSatish Balay 93949b5e25fSSatish Balay /* move pointer bap to a(k,l) quickly and add/insert value */ 9407cd84e04SBarry Smith if (col <= lastcol) low = 0; high = nrow; 941e2ee6c50SBarry Smith lastcol = col; 94249b5e25fSSatish Balay while (high-low > 7) { 94349b5e25fSSatish Balay t = (low+high)/2; 94449b5e25fSSatish Balay if (rp[t] > bcol) high = t; 94549b5e25fSSatish Balay else low = t; 94649b5e25fSSatish Balay } 94749b5e25fSSatish Balay for (i=low; i<high; i++) { 94849b5e25fSSatish Balay if (rp[i] > bcol) break; 94949b5e25fSSatish Balay if (rp[i] == bcol) { 95049b5e25fSSatish Balay bap = ap + bs2*i + bs*cidx + ridx; 95149b5e25fSSatish Balay if (is == ADD_VALUES) *bap += value; 95249b5e25fSSatish Balay else *bap = value; 9538549e402SHong Zhang /* for diag block, add/insert its symmetric element a(cidx,ridx) */ 9548549e402SHong Zhang if (brow == bcol && ridx < cidx){ 9558549e402SHong Zhang bap = ap + bs2*i + bs*ridx + cidx; 9568549e402SHong Zhang if (is == ADD_VALUES) *bap += value; 9578549e402SHong Zhang else *bap = value; 9588549e402SHong Zhang } 95949b5e25fSSatish Balay goto noinsert1; 96049b5e25fSSatish Balay } 96149b5e25fSSatish Balay } 96249b5e25fSSatish Balay 96349b5e25fSSatish Balay if (nonew == 1) goto noinsert1; 964085a36d4SBarry Smith if (nonew == -1) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"Inserting a new nonzero (%D, %D) in the matrix", row, col); 965421e10b8SBarry Smith MatSeqXAIJReallocateAIJ(A,a->mbs,bs2,nrow,brow,bcol,rmax,aa,ai,aj,rp,ap,imax,nonew,MatScalar); 96649b5e25fSSatish Balay 967c03d1d03SSatish Balay N = nrow++ - 1; high++; 96849b5e25fSSatish Balay /* shift up all the later entries in this row */ 96949b5e25fSSatish Balay for (ii=N; ii>=i; ii--) { 97049b5e25fSSatish Balay rp[ii+1] = rp[ii]; 97149b5e25fSSatish Balay ierr = PetscMemcpy(ap+bs2*(ii+1),ap+bs2*(ii),bs2*sizeof(MatScalar));CHKERRQ(ierr); 97249b5e25fSSatish Balay } 97349b5e25fSSatish Balay if (N>=i) { 97449b5e25fSSatish Balay ierr = PetscMemzero(ap+bs2*i,bs2*sizeof(MatScalar));CHKERRQ(ierr); 97549b5e25fSSatish Balay } 97649b5e25fSSatish Balay rp[i] = bcol; 97749b5e25fSSatish Balay ap[bs2*i + bs*cidx + ridx] = value; 97849b5e25fSSatish Balay noinsert1:; 97949b5e25fSSatish Balay low = i; 9808549e402SHong Zhang } 98149b5e25fSSatish Balay } /* end of loop over added columns */ 98249b5e25fSSatish Balay ailen[brow] = nrow; 98349b5e25fSSatish Balay } /* end of loop over added rows */ 98449b5e25fSSatish Balay PetscFunctionReturn(0); 98549b5e25fSSatish Balay } 98649b5e25fSSatish Balay 9874a2ae208SSatish Balay #undef __FUNCT__ 9884d101231SSatish Balay #define __FUNCT__ "MatICCFactor_SeqSBAIJ" 9890481f469SBarry Smith PetscErrorCode MatICCFactor_SeqSBAIJ(Mat inA,IS row,const MatFactorInfo *info) 99049b5e25fSSatish Balay { 9914ccecd49SHong Zhang Mat_SeqSBAIJ *a = (Mat_SeqSBAIJ*)inA->data; 99249b5e25fSSatish Balay Mat outA; 993dfbe8321SBarry Smith PetscErrorCode ierr; 994c84f5b01SHong Zhang PetscTruth row_identity; 99549b5e25fSSatish Balay 99649b5e25fSSatish Balay PetscFunctionBegin; 997c84f5b01SHong Zhang if (info->levels != 0) SETERRQ(PETSC_ERR_SUP,"Only levels=0 is supported for in-place icc"); 998c84f5b01SHong Zhang ierr = ISIdentity(row,&row_identity);CHKERRQ(ierr); 999c84f5b01SHong Zhang if (!row_identity) SETERRQ(PETSC_ERR_SUP,"Matrix reordering is not supported"); 1000d0f46423SBarry Smith if (inA->rmap->bs != 1) SETERRQ1(PETSC_ERR_SUP,"Matrix block size %D is not supported",inA->rmap->bs); /* Need to replace MatCholeskyFactorSymbolic_SeqSBAIJ_MSR()! */ 1001c84f5b01SHong Zhang 100249b5e25fSSatish Balay outA = inA; 1003c078aec8SLisandro Dalcin inA->factor = MAT_FACTOR_ICC; 100449b5e25fSSatish Balay 10051a3463dfSHong Zhang ierr = MatMarkDiagonal_SeqSBAIJ(inA);CHKERRQ(ierr); 1006db4efbfdSBarry Smith ierr = MatSeqSBAIJSetNumericFactorization(inA,row_identity);CHKERRQ(ierr); 100749b5e25fSSatish Balay 1008c3122656SLisandro Dalcin ierr = PetscObjectReference((PetscObject)row);CHKERRQ(ierr); 1009c3122656SLisandro Dalcin if (a->row) { ierr = ISDestroy(a->row);CHKERRQ(ierr); } 1010c84f5b01SHong Zhang a->row = row; 1011c3122656SLisandro Dalcin ierr = PetscObjectReference((PetscObject)row);CHKERRQ(ierr); 1012c3122656SLisandro Dalcin if (a->col) { ierr = ISDestroy(a->col);CHKERRQ(ierr); } 1013c84f5b01SHong Zhang a->col = row; 1014c84f5b01SHong Zhang 1015c84f5b01SHong Zhang /* Create the invert permutation so that it can be used in MatCholeskyFactorNumeric() */ 1016c84f5b01SHong Zhang if (a->icol) {ierr = ISInvertPermutation(row,PETSC_DECIDE, &a->icol);CHKERRQ(ierr);} 101752e6d16bSBarry Smith ierr = PetscLogObjectParent(inA,a->icol);CHKERRQ(ierr); 101849b5e25fSSatish Balay 101949b5e25fSSatish Balay if (!a->solve_work) { 1020d0f46423SBarry Smith ierr = PetscMalloc((inA->rmap->N+inA->rmap->bs)*sizeof(PetscScalar),&a->solve_work);CHKERRQ(ierr); 1021d0f46423SBarry Smith ierr = PetscLogObjectMemory(inA,(inA->rmap->N+inA->rmap->bs)*sizeof(PetscScalar));CHKERRQ(ierr); 102249b5e25fSSatish Balay } 102349b5e25fSSatish Balay 1024719d5645SBarry Smith ierr = MatCholeskyFactorNumeric(outA,inA,info);CHKERRQ(ierr); 102549b5e25fSSatish Balay PetscFunctionReturn(0); 102649b5e25fSSatish Balay } 1027950f1e5bSHong Zhang 102849b5e25fSSatish Balay EXTERN_C_BEGIN 10294a2ae208SSatish Balay #undef __FUNCT__ 10304a2ae208SSatish Balay #define __FUNCT__ "MatSeqSBAIJSetColumnIndices_SeqSBAIJ" 1031be1d678aSKris Buschelman PetscErrorCode PETSCMAT_DLLEXPORT MatSeqSBAIJSetColumnIndices_SeqSBAIJ(Mat mat,PetscInt *indices) 103249b5e25fSSatish Balay { 1033045c9aa0SHong Zhang Mat_SeqSBAIJ *baij = (Mat_SeqSBAIJ *)mat->data; 103413f74950SBarry Smith PetscInt i,nz,n; 103549b5e25fSSatish Balay 103649b5e25fSSatish Balay PetscFunctionBegin; 10376c6c5352SBarry Smith nz = baij->maxnz; 1038d0f46423SBarry Smith n = mat->cmap->n; 103949b5e25fSSatish Balay for (i=0; i<nz; i++) { 104049b5e25fSSatish Balay baij->j[i] = indices[i]; 104149b5e25fSSatish Balay } 10426c6c5352SBarry Smith baij->nz = nz; 104349b5e25fSSatish Balay for (i=0; i<n; i++) { 104449b5e25fSSatish Balay baij->ilen[i] = baij->imax[i]; 104549b5e25fSSatish Balay } 104649b5e25fSSatish Balay PetscFunctionReturn(0); 104749b5e25fSSatish Balay } 104849b5e25fSSatish Balay EXTERN_C_END 104949b5e25fSSatish Balay 10504a2ae208SSatish Balay #undef __FUNCT__ 10514a2ae208SSatish Balay #define __FUNCT__ "MatSeqSBAIJSetColumnIndices" 105249b5e25fSSatish Balay /*@ 105319585528SSatish Balay MatSeqSBAIJSetColumnIndices - Set the column indices for all the rows 105449b5e25fSSatish Balay in the matrix. 105549b5e25fSSatish Balay 105649b5e25fSSatish Balay Input Parameters: 105719585528SSatish Balay + mat - the SeqSBAIJ matrix 105849b5e25fSSatish Balay - indices - the column indices 105949b5e25fSSatish Balay 106049b5e25fSSatish Balay Level: advanced 106149b5e25fSSatish Balay 106249b5e25fSSatish Balay Notes: 106349b5e25fSSatish Balay This can be called if you have precomputed the nonzero structure of the 106449b5e25fSSatish Balay matrix and want to provide it to the matrix object to improve the performance 106549b5e25fSSatish Balay of the MatSetValues() operation. 106649b5e25fSSatish Balay 106749b5e25fSSatish Balay You MUST have set the correct numbers of nonzeros per row in the call to 1068d1be2dadSMatthew Knepley MatCreateSeqSBAIJ(), and the columns indices MUST be sorted. 106949b5e25fSSatish Balay 1070ab9f2c04SSatish Balay MUST be called before any calls to MatSetValues() 107149b5e25fSSatish Balay 1072ab9f2c04SSatish Balay .seealso: MatCreateSeqSBAIJ 107349b5e25fSSatish Balay @*/ 1074be1d678aSKris Buschelman PetscErrorCode PETSCMAT_DLLEXPORT MatSeqSBAIJSetColumnIndices(Mat mat,PetscInt *indices) 107549b5e25fSSatish Balay { 107613f74950SBarry Smith PetscErrorCode ierr,(*f)(Mat,PetscInt *); 107749b5e25fSSatish Balay 107849b5e25fSSatish Balay PetscFunctionBegin; 10794482741eSBarry Smith PetscValidHeaderSpecific(mat,MAT_COOKIE,1); 10804482741eSBarry Smith PetscValidPointer(indices,2); 1081c134de8dSSatish Balay ierr = PetscObjectQueryFunction((PetscObject)mat,"MatSeqSBAIJSetColumnIndices_C",(void (**)(void))&f);CHKERRQ(ierr); 108249b5e25fSSatish Balay if (f) { 108349b5e25fSSatish Balay ierr = (*f)(mat,indices);CHKERRQ(ierr); 108449b5e25fSSatish Balay } else { 1085e005ede5SBarry Smith SETERRQ(PETSC_ERR_SUP,"Wrong type of matrix to set column indices"); 108649b5e25fSSatish Balay } 108749b5e25fSSatish Balay PetscFunctionReturn(0); 108849b5e25fSSatish Balay } 108949b5e25fSSatish Balay 10904a2ae208SSatish Balay #undef __FUNCT__ 10913c896bc6SHong Zhang #define __FUNCT__ "MatCopy_SeqSBAIJ" 10923c896bc6SHong Zhang PetscErrorCode MatCopy_SeqSBAIJ(Mat A,Mat B,MatStructure str) 10933c896bc6SHong Zhang { 10943c896bc6SHong Zhang PetscErrorCode ierr; 10953c896bc6SHong Zhang 10963c896bc6SHong Zhang PetscFunctionBegin; 10973c896bc6SHong Zhang /* If the two matrices have the same copy implementation, use fast copy. */ 10983c896bc6SHong Zhang if (str == SAME_NONZERO_PATTERN && (A->ops->copy == B->ops->copy)) { 10993c896bc6SHong Zhang Mat_SeqSBAIJ *a = (Mat_SeqSBAIJ*)A->data; 11003c896bc6SHong Zhang Mat_SeqSBAIJ *b = (Mat_SeqSBAIJ*)B->data; 11013c896bc6SHong Zhang 1102d0f46423SBarry Smith if (a->i[A->rmap->N] != b->i[B->rmap->N]) { 11033c896bc6SHong Zhang SETERRQ(PETSC_ERR_ARG_INCOMP,"Number of nonzeros in two matrices are different"); 11043c896bc6SHong Zhang } 1105d0f46423SBarry Smith ierr = PetscMemcpy(b->a,a->a,(a->i[A->rmap->N])*sizeof(PetscScalar));CHKERRQ(ierr); 11063c896bc6SHong Zhang } else { 1107f5edf698SHong Zhang ierr = MatGetRowUpperTriangular(A);CHKERRQ(ierr); 11083c896bc6SHong Zhang ierr = MatCopy_Basic(A,B,str);CHKERRQ(ierr); 1109f5edf698SHong Zhang ierr = MatRestoreRowUpperTriangular(A);CHKERRQ(ierr); 11103c896bc6SHong Zhang } 11113c896bc6SHong Zhang PetscFunctionReturn(0); 11123c896bc6SHong Zhang } 11133c896bc6SHong Zhang 11143c896bc6SHong Zhang #undef __FUNCT__ 11154a2ae208SSatish Balay #define __FUNCT__ "MatSetUpPreallocation_SeqSBAIJ" 1116dfbe8321SBarry Smith PetscErrorCode MatSetUpPreallocation_SeqSBAIJ(Mat A) 1117273d9f13SBarry Smith { 1118dfbe8321SBarry Smith PetscErrorCode ierr; 1119273d9f13SBarry Smith 1120273d9f13SBarry Smith PetscFunctionBegin; 1121db4efbfdSBarry Smith ierr = MatSeqSBAIJSetPreallocation_SeqSBAIJ(A,-PetscMax(A->rmap->bs,1),PETSC_DEFAULT,0);CHKERRQ(ierr); 1122273d9f13SBarry Smith PetscFunctionReturn(0); 1123273d9f13SBarry Smith } 1124273d9f13SBarry Smith 1125a6ece127SHong Zhang #undef __FUNCT__ 1126a6ece127SHong Zhang #define __FUNCT__ "MatGetArray_SeqSBAIJ" 1127dfbe8321SBarry Smith PetscErrorCode MatGetArray_SeqSBAIJ(Mat A,PetscScalar *array[]) 1128a6ece127SHong Zhang { 1129a6ece127SHong Zhang Mat_SeqSBAIJ *a = (Mat_SeqSBAIJ*)A->data; 1130a6ece127SHong Zhang PetscFunctionBegin; 1131a6ece127SHong Zhang *array = a->a; 1132a6ece127SHong Zhang PetscFunctionReturn(0); 1133a6ece127SHong Zhang } 1134a6ece127SHong Zhang 1135a6ece127SHong Zhang #undef __FUNCT__ 1136a6ece127SHong Zhang #define __FUNCT__ "MatRestoreArray_SeqSBAIJ" 1137dfbe8321SBarry Smith PetscErrorCode MatRestoreArray_SeqSBAIJ(Mat A,PetscScalar *array[]) 1138a6ece127SHong Zhang { 1139a6ece127SHong Zhang PetscFunctionBegin; 1140a6ece127SHong Zhang PetscFunctionReturn(0); 1141a6ece127SHong Zhang } 1142a6ece127SHong Zhang 114342ee4b1aSHong Zhang #include "petscblaslapack.h" 114442ee4b1aSHong Zhang #undef __FUNCT__ 114542ee4b1aSHong Zhang #define __FUNCT__ "MatAXPY_SeqSBAIJ" 1146f4df32b1SMatthew Knepley PetscErrorCode MatAXPY_SeqSBAIJ(Mat Y,PetscScalar a,Mat X,MatStructure str) 114742ee4b1aSHong Zhang { 114842ee4b1aSHong Zhang Mat_SeqSBAIJ *x=(Mat_SeqSBAIJ *)X->data, *y=(Mat_SeqSBAIJ *)Y->data; 1149dfbe8321SBarry Smith PetscErrorCode ierr; 1150d0f46423SBarry Smith PetscInt i,bs=Y->rmap->bs,bs2,j; 11510805154bSBarry Smith PetscBLASInt one = 1,bnz = PetscBLASIntCast(x->nz); 115242ee4b1aSHong Zhang 115342ee4b1aSHong Zhang PetscFunctionBegin; 115442ee4b1aSHong Zhang if (str == SAME_NONZERO_PATTERN) { 1155f4df32b1SMatthew Knepley PetscScalar alpha = a; 1156f4df32b1SMatthew Knepley BLASaxpy_(&bnz,&alpha,x->a,&one,y->a,&one); 1157c537a176SHong Zhang } else if (str == SUBSET_NONZERO_PATTERN) { /* nonzeros of X is a subset of Y's */ 1158c4319e64SHong Zhang if (y->xtoy && y->XtoY != X) { 1159c4319e64SHong Zhang ierr = PetscFree(y->xtoy);CHKERRQ(ierr); 1160c4319e64SHong Zhang ierr = MatDestroy(y->XtoY);CHKERRQ(ierr); 1161c537a176SHong Zhang } 1162c4319e64SHong Zhang if (!y->xtoy) { /* get xtoy */ 1163c4319e64SHong Zhang ierr = MatAXPYGetxtoy_Private(x->mbs,x->i,x->j,PETSC_NULL, y->i,y->j,PETSC_NULL, &y->xtoy);CHKERRQ(ierr); 1164c4319e64SHong Zhang y->XtoY = X; 1165c537a176SHong Zhang } 1166c4319e64SHong Zhang bs2 = bs*bs; 11676c6c5352SBarry Smith for (i=0; i<x->nz; i++) { 1168c4319e64SHong Zhang j = 0; 1169c4319e64SHong Zhang while (j < bs2){ 1170f4df32b1SMatthew Knepley y->a[bs2*y->xtoy[i]+j] += a*(x->a[bs2*i+j]); 1171c4319e64SHong Zhang j++; 1172c537a176SHong Zhang } 1173c4319e64SHong Zhang } 11741e2582c4SBarry Smith ierr = PetscInfo3(Y,"ratio of nnz_s(X)/nnz_s(Y): %D/%D = %G\n",bs2*x->nz,bs2*y->nz,(PetscReal)(bs2*x->nz)/(bs2*y->nz));CHKERRQ(ierr); 117542ee4b1aSHong Zhang } else { 1176f5edf698SHong Zhang ierr = MatGetRowUpperTriangular(X);CHKERRQ(ierr); 1177f4df32b1SMatthew Knepley ierr = MatAXPY_Basic(Y,a,X,str);CHKERRQ(ierr); 1178f5edf698SHong Zhang ierr = MatRestoreRowUpperTriangular(X);CHKERRQ(ierr); 117942ee4b1aSHong Zhang } 118042ee4b1aSHong Zhang PetscFunctionReturn(0); 118142ee4b1aSHong Zhang } 118242ee4b1aSHong Zhang 1183efcf0fc3SBarry Smith #undef __FUNCT__ 1184efcf0fc3SBarry Smith #define __FUNCT__ "MatIsSymmetric_SeqSBAIJ" 1185dfbe8321SBarry Smith PetscErrorCode MatIsSymmetric_SeqSBAIJ(Mat A,PetscReal tol,PetscTruth *flg) 1186efcf0fc3SBarry Smith { 1187efcf0fc3SBarry Smith PetscFunctionBegin; 1188efcf0fc3SBarry Smith *flg = PETSC_TRUE; 1189efcf0fc3SBarry Smith PetscFunctionReturn(0); 1190efcf0fc3SBarry Smith } 1191efcf0fc3SBarry Smith 1192efcf0fc3SBarry Smith #undef __FUNCT__ 1193efcf0fc3SBarry Smith #define __FUNCT__ "MatIsStructurallySymmetric_SeqSBAIJ" 1194dfbe8321SBarry Smith PetscErrorCode MatIsStructurallySymmetric_SeqSBAIJ(Mat A,PetscTruth *flg) 1195efcf0fc3SBarry Smith { 1196efcf0fc3SBarry Smith PetscFunctionBegin; 1197efcf0fc3SBarry Smith *flg = PETSC_TRUE; 1198efcf0fc3SBarry Smith PetscFunctionReturn(0); 1199efcf0fc3SBarry Smith } 1200efcf0fc3SBarry Smith 1201efcf0fc3SBarry Smith #undef __FUNCT__ 1202efcf0fc3SBarry Smith #define __FUNCT__ "MatIsHermitian_SeqSBAIJ" 1203ab5e4463SMatthew Knepley PetscErrorCode MatIsHermitian_SeqSBAIJ(Mat A,PetscReal tol,PetscTruth *flg) 1204efcf0fc3SBarry Smith { 1205efcf0fc3SBarry Smith PetscFunctionBegin; 1206efcf0fc3SBarry Smith *flg = PETSC_FALSE; 1207efcf0fc3SBarry Smith PetscFunctionReturn(0); 1208efcf0fc3SBarry Smith } 1209efcf0fc3SBarry Smith 121099cafbc1SBarry Smith #undef __FUNCT__ 121199cafbc1SBarry Smith #define __FUNCT__ "MatRealPart_SeqSBAIJ" 121299cafbc1SBarry Smith PetscErrorCode MatRealPart_SeqSBAIJ(Mat A) 121399cafbc1SBarry Smith { 121499cafbc1SBarry Smith Mat_SeqSBAIJ *a = (Mat_SeqSBAIJ*)A->data; 121599cafbc1SBarry Smith PetscInt i,nz = a->bs2*a->i[a->mbs]; 1216dd6ea824SBarry Smith MatScalar *aa = a->a; 121799cafbc1SBarry Smith 121899cafbc1SBarry Smith PetscFunctionBegin; 121999cafbc1SBarry Smith for (i=0; i<nz; i++) aa[i] = PetscRealPart(aa[i]); 122099cafbc1SBarry Smith PetscFunctionReturn(0); 122199cafbc1SBarry Smith } 122299cafbc1SBarry Smith 122399cafbc1SBarry Smith #undef __FUNCT__ 122499cafbc1SBarry Smith #define __FUNCT__ "MatImaginaryPart_SeqSBAIJ" 122599cafbc1SBarry Smith PetscErrorCode MatImaginaryPart_SeqSBAIJ(Mat A) 122699cafbc1SBarry Smith { 122799cafbc1SBarry Smith Mat_SeqSBAIJ *a = (Mat_SeqSBAIJ*)A->data; 122899cafbc1SBarry Smith PetscInt i,nz = a->bs2*a->i[a->mbs]; 1229dd6ea824SBarry Smith MatScalar *aa = a->a; 123099cafbc1SBarry Smith 123199cafbc1SBarry Smith PetscFunctionBegin; 123299cafbc1SBarry Smith for (i=0; i<nz; i++) aa[i] = PetscImaginaryPart(aa[i]); 123399cafbc1SBarry Smith PetscFunctionReturn(0); 123499cafbc1SBarry Smith } 123599cafbc1SBarry Smith 123649b5e25fSSatish Balay /* -------------------------------------------------------------------*/ 123749b5e25fSSatish Balay static struct _MatOps MatOps_Values = {MatSetValues_SeqSBAIJ, 123849b5e25fSSatish Balay MatGetRow_SeqSBAIJ, 123949b5e25fSSatish Balay MatRestoreRow_SeqSBAIJ, 124049b5e25fSSatish Balay MatMult_SeqSBAIJ_N, 124197304618SKris Buschelman /* 4*/ MatMultAdd_SeqSBAIJ_N, 1242431c96f7SBarry Smith MatMult_SeqSBAIJ_N, /* transpose versions are same as non-transpose versions */ 1243e005ede5SBarry Smith MatMultAdd_SeqSBAIJ_N, 1244db4efbfdSBarry Smith 0, 124549b5e25fSSatish Balay 0, 124649b5e25fSSatish Balay 0, 124797304618SKris Buschelman /*10*/ 0, 124849b5e25fSSatish Balay 0, 1249c078aec8SLisandro Dalcin MatCholeskyFactor_SeqSBAIJ, 1250d06b337dSHong Zhang MatRelax_SeqSBAIJ, 125149b5e25fSSatish Balay MatTranspose_SeqSBAIJ, 125297304618SKris Buschelman /*15*/ MatGetInfo_SeqSBAIJ, 125349b5e25fSSatish Balay MatEqual_SeqSBAIJ, 125449b5e25fSSatish Balay MatGetDiagonal_SeqSBAIJ, 125549b5e25fSSatish Balay MatDiagonalScale_SeqSBAIJ, 125649b5e25fSSatish Balay MatNorm_SeqSBAIJ, 125797304618SKris Buschelman /*20*/ 0, 125849b5e25fSSatish Balay MatAssemblyEnd_SeqSBAIJ, 125949b5e25fSSatish Balay MatSetOption_SeqSBAIJ, 126049b5e25fSSatish Balay MatZeroEntries_SeqSBAIJ, 1261d519adbfSMatthew Knepley /*24*/ 0, 126249b5e25fSSatish Balay 0, 126349b5e25fSSatish Balay 0, 1264db4efbfdSBarry Smith 0, 1265db4efbfdSBarry Smith 0, 1266d519adbfSMatthew Knepley /*29*/ MatSetUpPreallocation_SeqSBAIJ, 1267c464158bSHong Zhang 0, 1268db4efbfdSBarry Smith 0, 1269a6ece127SHong Zhang MatGetArray_SeqSBAIJ, 1270a6ece127SHong Zhang MatRestoreArray_SeqSBAIJ, 1271d519adbfSMatthew Knepley /*34*/ MatDuplicate_SeqSBAIJ, 1272719d5645SBarry Smith 0, 1273719d5645SBarry Smith 0, 127449b5e25fSSatish Balay 0, 1275c84f5b01SHong Zhang MatICCFactor_SeqSBAIJ, 1276d519adbfSMatthew Knepley /*39*/ MatAXPY_SeqSBAIJ, 127749b5e25fSSatish Balay MatGetSubMatrices_SeqSBAIJ, 127849b5e25fSSatish Balay MatIncreaseOverlap_SeqSBAIJ, 127949b5e25fSSatish Balay MatGetValues_SeqSBAIJ, 12803c896bc6SHong Zhang MatCopy_SeqSBAIJ, 1281d519adbfSMatthew Knepley /*44*/ 0, 128249b5e25fSSatish Balay MatScale_SeqSBAIJ, 128349b5e25fSSatish Balay 0, 128449b5e25fSSatish Balay 0, 128549b5e25fSSatish Balay 0, 1286d519adbfSMatthew Knepley /*49*/ 0, 128749b5e25fSSatish Balay MatGetRowIJ_SeqSBAIJ, 128849b5e25fSSatish Balay MatRestoreRowIJ_SeqSBAIJ, 128949b5e25fSSatish Balay 0, 129049b5e25fSSatish Balay 0, 1291d519adbfSMatthew Knepley /*54*/ 0, 129249b5e25fSSatish Balay 0, 129349b5e25fSSatish Balay 0, 129449b5e25fSSatish Balay 0, 129549b5e25fSSatish Balay MatSetValuesBlocked_SeqSBAIJ, 1296d519adbfSMatthew Knepley /*59*/ MatGetSubMatrix_SeqSBAIJ, 129749b5e25fSSatish Balay 0, 129849b5e25fSSatish Balay 0, 1299357abbc8SBarry Smith 0, 1300d959ec07SHong Zhang 0, 1301d519adbfSMatthew Knepley /*64*/ 0, 1302d959ec07SHong Zhang 0, 1303d959ec07SHong Zhang 0, 1304d959ec07SHong Zhang 0, 1305d959ec07SHong Zhang 0, 1306d519adbfSMatthew Knepley /*69*/ MatGetRowMaxAbs_SeqSBAIJ, 13073e0d88b5SBarry Smith 0, 13083e0d88b5SBarry Smith 0, 13093e0d88b5SBarry Smith 0, 13103e0d88b5SBarry Smith 0, 1311d519adbfSMatthew Knepley /*74*/ 0, 13123e0d88b5SBarry Smith 0, 13133e0d88b5SBarry Smith 0, 13143e0d88b5SBarry Smith 0, 13153e0d88b5SBarry Smith 0, 1316d519adbfSMatthew Knepley /*79*/ 0, 13173e0d88b5SBarry Smith 0, 13183e0d88b5SBarry Smith 0, 13193e0d88b5SBarry Smith #if !defined(PETSC_USE_COMPLEX) 132097304618SKris Buschelman MatGetInertia_SeqSBAIJ, 13213e0d88b5SBarry Smith #else 132297304618SKris Buschelman 0, 13233e0d88b5SBarry Smith #endif 1324865e5f61SKris Buschelman MatLoad_SeqSBAIJ, 1325d519adbfSMatthew Knepley /*84*/ MatIsSymmetric_SeqSBAIJ, 1326865e5f61SKris Buschelman MatIsHermitian_SeqSBAIJ, 1327efcf0fc3SBarry Smith MatIsStructurallySymmetric_SeqSBAIJ, 1328865e5f61SKris Buschelman 0, 1329865e5f61SKris Buschelman 0, 1330d519adbfSMatthew Knepley /*89*/ 0, 1331865e5f61SKris Buschelman 0, 1332865e5f61SKris Buschelman 0, 1333865e5f61SKris Buschelman 0, 1334865e5f61SKris Buschelman 0, 1335d519adbfSMatthew Knepley /*94*/ 0, 1336865e5f61SKris Buschelman 0, 1337865e5f61SKris Buschelman 0, 133899cafbc1SBarry Smith 0, 133999cafbc1SBarry Smith 0, 1340d519adbfSMatthew Knepley /*99*/ 0, 134199cafbc1SBarry Smith 0, 134299cafbc1SBarry Smith 0, 134399cafbc1SBarry Smith 0, 134499cafbc1SBarry Smith 0, 1345d519adbfSMatthew Knepley /*104*/0, 134699cafbc1SBarry Smith MatRealPart_SeqSBAIJ, 1347f5edf698SHong Zhang MatImaginaryPart_SeqSBAIJ, 1348f5edf698SHong Zhang MatGetRowUpperTriangular_SeqSBAIJ, 13492af78befSBarry Smith MatRestoreRowUpperTriangular_SeqSBAIJ, 1350d519adbfSMatthew Knepley /*109*/0, 13512af78befSBarry Smith 0, 13522af78befSBarry Smith 0, 13532af78befSBarry Smith 0, 13542af78befSBarry Smith MatMissingDiagonal_SeqSBAIJ 135599cafbc1SBarry Smith }; 1356be1d678aSKris Buschelman 135749b5e25fSSatish Balay EXTERN_C_BEGIN 13584a2ae208SSatish Balay #undef __FUNCT__ 13594a2ae208SSatish Balay #define __FUNCT__ "MatStoreValues_SeqSBAIJ" 1360be1d678aSKris Buschelman PetscErrorCode PETSCMAT_DLLEXPORT MatStoreValues_SeqSBAIJ(Mat mat) 136149b5e25fSSatish Balay { 13624afc71dfSHong Zhang Mat_SeqSBAIJ *aij = (Mat_SeqSBAIJ *)mat->data; 1363d0f46423SBarry Smith PetscInt nz = aij->i[mat->rmap->N]*mat->rmap->bs*aij->bs2; 1364dfbe8321SBarry Smith PetscErrorCode ierr; 136549b5e25fSSatish Balay 136649b5e25fSSatish Balay PetscFunctionBegin; 136749b5e25fSSatish Balay if (aij->nonew != 1) { 1368512a5fc5SBarry Smith SETERRQ(PETSC_ERR_ORDER,"Must call MatSetOption(A,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE);first"); 136949b5e25fSSatish Balay } 137049b5e25fSSatish Balay 137149b5e25fSSatish Balay /* allocate space for values if not already there */ 137249b5e25fSSatish Balay if (!aij->saved_values) { 137387828ca2SBarry Smith ierr = PetscMalloc((nz+1)*sizeof(PetscScalar),&aij->saved_values);CHKERRQ(ierr); 137449b5e25fSSatish Balay } 137549b5e25fSSatish Balay 137649b5e25fSSatish Balay /* copy values over */ 137787828ca2SBarry Smith ierr = PetscMemcpy(aij->saved_values,aij->a,nz*sizeof(PetscScalar));CHKERRQ(ierr); 137849b5e25fSSatish Balay PetscFunctionReturn(0); 137949b5e25fSSatish Balay } 138049b5e25fSSatish Balay EXTERN_C_END 138149b5e25fSSatish Balay 138249b5e25fSSatish Balay EXTERN_C_BEGIN 13834a2ae208SSatish Balay #undef __FUNCT__ 13844a2ae208SSatish Balay #define __FUNCT__ "MatRetrieveValues_SeqSBAIJ" 1385be1d678aSKris Buschelman PetscErrorCode PETSCMAT_DLLEXPORT MatRetrieveValues_SeqSBAIJ(Mat mat) 138649b5e25fSSatish Balay { 13874afc71dfSHong Zhang Mat_SeqSBAIJ *aij = (Mat_SeqSBAIJ *)mat->data; 13886849ba73SBarry Smith PetscErrorCode ierr; 1389d0f46423SBarry Smith PetscInt nz = aij->i[mat->rmap->N]*mat->rmap->bs*aij->bs2; 139049b5e25fSSatish Balay 139149b5e25fSSatish Balay PetscFunctionBegin; 139249b5e25fSSatish Balay if (aij->nonew != 1) { 1393512a5fc5SBarry Smith SETERRQ(PETSC_ERR_ORDER,"Must call MatSetOption(A,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE);first"); 139449b5e25fSSatish Balay } 139549b5e25fSSatish Balay if (!aij->saved_values) { 1396e005ede5SBarry Smith SETERRQ(PETSC_ERR_ORDER,"Must call MatStoreValues(A);first"); 139749b5e25fSSatish Balay } 139849b5e25fSSatish Balay 139949b5e25fSSatish Balay /* copy values over */ 140087828ca2SBarry Smith ierr = PetscMemcpy(aij->a,aij->saved_values,nz*sizeof(PetscScalar));CHKERRQ(ierr); 140149b5e25fSSatish Balay PetscFunctionReturn(0); 140249b5e25fSSatish Balay } 140349b5e25fSSatish Balay EXTERN_C_END 140449b5e25fSSatish Balay 14058549e402SHong Zhang EXTERN_C_BEGIN 14064a2ae208SSatish Balay #undef __FUNCT__ 1407a23d5eceSKris Buschelman #define __FUNCT__ "MatSeqSBAIJSetPreallocation_SeqSBAIJ" 1408be1d678aSKris Buschelman PetscErrorCode PETSCMAT_DLLEXPORT MatSeqSBAIJSetPreallocation_SeqSBAIJ(Mat B,PetscInt bs,PetscInt nz,PetscInt *nnz) 140949b5e25fSSatish Balay { 1410c464158bSHong Zhang Mat_SeqSBAIJ *b = (Mat_SeqSBAIJ*)B->data; 14116849ba73SBarry Smith PetscErrorCode ierr; 1412db4efbfdSBarry Smith PetscInt i,mbs,bs2, newbs = PetscAbs(bs); 141390d69ab7SBarry Smith PetscTruth skipallocation = PETSC_FALSE,flg = PETSC_FALSE; 141449b5e25fSSatish Balay 141549b5e25fSSatish Balay PetscFunctionBegin; 1416273d9f13SBarry Smith B->preallocated = PETSC_TRUE; 1417db4efbfdSBarry Smith if (bs < 0) { 1418db4efbfdSBarry Smith ierr = PetscOptionsBegin(((PetscObject)B)->comm,((PetscObject)B)->prefix,"Options for MPISBAIJ matrix","Mat");CHKERRQ(ierr); 1419db4efbfdSBarry Smith ierr = PetscOptionsInt("-mat_block_size","Set the blocksize used to store the matrix","MatSeqSBAIJSetPreallocation",newbs,&newbs,PETSC_NULL);CHKERRQ(ierr); 1420db4efbfdSBarry Smith ierr = PetscOptionsEnd();CHKERRQ(ierr); 1421db4efbfdSBarry Smith bs = PetscAbs(bs); 1422db4efbfdSBarry Smith } 1423db4efbfdSBarry Smith if (nnz && newbs != bs) { 1424db4efbfdSBarry Smith SETERRQ(PETSC_ERR_ARG_WRONG,"Cannot change blocksize from command line if setting nnz"); 1425db4efbfdSBarry Smith } 1426db4efbfdSBarry Smith bs = newbs; 1427db4efbfdSBarry Smith 14287408324eSLisandro Dalcin ierr = PetscMapSetBlockSize(B->rmap,bs);CHKERRQ(ierr); 14297408324eSLisandro Dalcin ierr = PetscMapSetBlockSize(B->cmap,bs);CHKERRQ(ierr); 1430d0f46423SBarry Smith ierr = PetscMapSetUp(B->rmap);CHKERRQ(ierr); 1431d0f46423SBarry Smith ierr = PetscMapSetUp(B->cmap);CHKERRQ(ierr); 1432899cda47SBarry Smith 1433d0f46423SBarry Smith mbs = B->rmap->N/bs; 143449b5e25fSSatish Balay bs2 = bs*bs; 143549b5e25fSSatish Balay 1436d0f46423SBarry Smith if (mbs*bs != B->rmap->N) { 143729bbc08cSBarry Smith SETERRQ(PETSC_ERR_ARG_SIZ,"Number rows, cols must be divisible by blocksize"); 143849b5e25fSSatish Balay } 143949b5e25fSSatish Balay 1440ab93d7beSBarry Smith if (nz == MAT_SKIP_ALLOCATION) { 1441ab93d7beSBarry Smith skipallocation = PETSC_TRUE; 1442ab93d7beSBarry Smith nz = 0; 1443ab93d7beSBarry Smith } 1444ab93d7beSBarry Smith 1445435da068SBarry Smith if (nz == PETSC_DEFAULT || nz == PETSC_DECIDE) nz = 3; 144677431f27SBarry Smith if (nz < 0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"nz cannot be less than 0: value %D",nz); 144749b5e25fSSatish Balay if (nnz) { 144849b5e25fSSatish Balay for (i=0; i<mbs; i++) { 144977431f27SBarry Smith if (nnz[i] < 0) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"nnz cannot be less than 0: local row %D value %D",i,nnz[i]); 145077431f27SBarry Smith if (nnz[i] > mbs) SETERRQ3(PETSC_ERR_ARG_OUTOFRANGE,"nnz cannot be greater than block row length: local row %D value %D rowlength %D",i,nnz[i],mbs); 145149b5e25fSSatish Balay } 145249b5e25fSSatish Balay } 145349b5e25fSSatish Balay 1454db4efbfdSBarry Smith B->ops->mult = MatMult_SeqSBAIJ_N; 1455db4efbfdSBarry Smith B->ops->multadd = MatMultAdd_SeqSBAIJ_N; 1456db4efbfdSBarry Smith B->ops->multtranspose = MatMult_SeqSBAIJ_N; 1457db4efbfdSBarry Smith B->ops->multtransposeadd = MatMultAdd_SeqSBAIJ_N; 145890d69ab7SBarry Smith ierr = PetscOptionsGetTruth(((PetscObject)B)->prefix,"-mat_no_unroll",&flg,PETSC_NULL);CHKERRQ(ierr); 145949b5e25fSSatish Balay if (!flg) { 146049b5e25fSSatish Balay switch (bs) { 146149b5e25fSSatish Balay case 1: 146249b5e25fSSatish Balay B->ops->mult = MatMult_SeqSBAIJ_1; 146349b5e25fSSatish Balay B->ops->multadd = MatMultAdd_SeqSBAIJ_1; 1464431c96f7SBarry Smith B->ops->multtranspose = MatMult_SeqSBAIJ_1; 1465431c96f7SBarry Smith B->ops->multtransposeadd = MatMultAdd_SeqSBAIJ_1; 146649b5e25fSSatish Balay break; 146749b5e25fSSatish Balay case 2: 146849b5e25fSSatish Balay B->ops->mult = MatMult_SeqSBAIJ_2; 146949b5e25fSSatish Balay B->ops->multadd = MatMultAdd_SeqSBAIJ_2; 1470431c96f7SBarry Smith B->ops->multtranspose = MatMult_SeqSBAIJ_2; 1471431c96f7SBarry Smith B->ops->multtransposeadd = MatMultAdd_SeqSBAIJ_2; 147249b5e25fSSatish Balay break; 147349b5e25fSSatish Balay case 3: 147449b5e25fSSatish Balay B->ops->mult = MatMult_SeqSBAIJ_3; 147549b5e25fSSatish Balay B->ops->multadd = MatMultAdd_SeqSBAIJ_3; 1476431c96f7SBarry Smith B->ops->multtranspose = MatMult_SeqSBAIJ_3; 1477431c96f7SBarry Smith B->ops->multtransposeadd = MatMultAdd_SeqSBAIJ_3; 147849b5e25fSSatish Balay break; 147949b5e25fSSatish Balay case 4: 148049b5e25fSSatish Balay B->ops->mult = MatMult_SeqSBAIJ_4; 148149b5e25fSSatish Balay B->ops->multadd = MatMultAdd_SeqSBAIJ_4; 1482431c96f7SBarry Smith B->ops->multtranspose = MatMult_SeqSBAIJ_4; 1483431c96f7SBarry Smith B->ops->multtransposeadd = MatMultAdd_SeqSBAIJ_4; 148449b5e25fSSatish Balay break; 148549b5e25fSSatish Balay case 5: 148649b5e25fSSatish Balay B->ops->mult = MatMult_SeqSBAIJ_5; 148749b5e25fSSatish Balay B->ops->multadd = MatMultAdd_SeqSBAIJ_5; 1488431c96f7SBarry Smith B->ops->multtranspose = MatMult_SeqSBAIJ_5; 1489431c96f7SBarry Smith B->ops->multtransposeadd = MatMultAdd_SeqSBAIJ_5; 149049b5e25fSSatish Balay break; 149149b5e25fSSatish Balay case 6: 149249b5e25fSSatish Balay B->ops->mult = MatMult_SeqSBAIJ_6; 149349b5e25fSSatish Balay B->ops->multadd = MatMultAdd_SeqSBAIJ_6; 1494431c96f7SBarry Smith B->ops->multtranspose = MatMult_SeqSBAIJ_6; 1495431c96f7SBarry Smith B->ops->multtransposeadd = MatMultAdd_SeqSBAIJ_6; 149649b5e25fSSatish Balay break; 149749b5e25fSSatish Balay case 7: 1498de53e5efSHong Zhang B->ops->mult = MatMult_SeqSBAIJ_7; 149949b5e25fSSatish Balay B->ops->multadd = MatMultAdd_SeqSBAIJ_7; 1500431c96f7SBarry Smith B->ops->multtranspose = MatMult_SeqSBAIJ_7; 1501431c96f7SBarry Smith B->ops->multtransposeadd = MatMultAdd_SeqSBAIJ_7; 150249b5e25fSSatish Balay break; 150349b5e25fSSatish Balay } 150449b5e25fSSatish Balay } 150549b5e25fSSatish Balay 150649b5e25fSSatish Balay b->mbs = mbs; 15074afc71dfSHong Zhang b->nbs = mbs; 1508ab93d7beSBarry Smith if (!skipallocation) { 15092ee49352SLisandro Dalcin if (!b->imax) { 1510ab93d7beSBarry Smith ierr = PetscMalloc2(mbs,PetscInt,&b->imax,mbs,PetscInt,&b->ilen);CHKERRQ(ierr); 15112ee49352SLisandro Dalcin ierr = PetscLogObjectMemory(B,2*mbs*sizeof(PetscInt));CHKERRQ(ierr); 15122ee49352SLisandro Dalcin } 151349b5e25fSSatish Balay if (!nnz) { 1514435da068SBarry Smith if (nz == PETSC_DEFAULT || nz == PETSC_DECIDE) nz = 5; 151549b5e25fSSatish Balay else if (nz <= 0) nz = 1; 151649b5e25fSSatish Balay for (i=0; i<mbs; i++) { 15178cef66ccSHong Zhang b->imax[i] = nz; 151849b5e25fSSatish Balay } 1519153ea458SHong Zhang nz = nz*mbs; /* total nz */ 152049b5e25fSSatish Balay } else { 152149b5e25fSSatish Balay nz = 0; 15228cef66ccSHong Zhang for (i=0; i<mbs; i++) {b->imax[i] = nnz[i]; nz += nnz[i];} 152349b5e25fSSatish Balay } 15242ee49352SLisandro Dalcin /* b->ilen will count nonzeros in each block row so far. */ 15252ee49352SLisandro Dalcin for (i=0; i<mbs; i++) { b->ilen[i] = 0;} 15266c6c5352SBarry Smith /* nz=(nz+mbs)/2; */ /* total diagonal and superdiagonal nonzero blocks */ 152749b5e25fSSatish Balay 152849b5e25fSSatish Balay /* allocate the matrix space */ 15292ee49352SLisandro Dalcin ierr = MatSeqXAIJFreeAIJ(B,&b->a,&b->j,&b->i);CHKERRQ(ierr); 1530d0f46423SBarry Smith ierr = PetscMalloc3(bs2*nz,PetscScalar,&b->a,nz,PetscInt,&b->j,B->rmap->N+1,PetscInt,&b->i);CHKERRQ(ierr); 1531d0f46423SBarry Smith ierr = PetscLogObjectMemory(B,(B->rmap->N+1)*sizeof(PetscInt)+nz*(bs2*sizeof(PetscScalar)+sizeof(PetscInt)));CHKERRQ(ierr); 15326c6c5352SBarry Smith ierr = PetscMemzero(b->a,nz*bs2*sizeof(MatScalar));CHKERRQ(ierr); 153313f74950SBarry Smith ierr = PetscMemzero(b->j,nz*sizeof(PetscInt));CHKERRQ(ierr); 153449b5e25fSSatish Balay b->singlemalloc = PETSC_TRUE; 153549b5e25fSSatish Balay 153649b5e25fSSatish Balay /* pointer to beginning of each row */ 153749b5e25fSSatish Balay b->i[0] = 0; 153849b5e25fSSatish Balay for (i=1; i<mbs+1; i++) { 153949b5e25fSSatish Balay b->i[i] = b->i[i-1] + b->imax[i-1]; 154049b5e25fSSatish Balay } 1541e6b907acSBarry Smith b->free_a = PETSC_TRUE; 1542e6b907acSBarry Smith b->free_ij = PETSC_TRUE; 1543e811da20SHong Zhang } else { 1544e6b907acSBarry Smith b->free_a = PETSC_FALSE; 1545e6b907acSBarry Smith b->free_ij = PETSC_FALSE; 1546ab93d7beSBarry Smith } 154749b5e25fSSatish Balay 1548d0f46423SBarry Smith B->rmap->bs = bs; 154949b5e25fSSatish Balay b->bs2 = bs2; 15506c6c5352SBarry Smith b->nz = 0; 15516c6c5352SBarry Smith b->maxnz = nz*bs2; 1552153ea458SHong Zhang 155316cdd363SHong Zhang b->inew = 0; 155416cdd363SHong Zhang b->jnew = 0; 155516cdd363SHong Zhang b->anew = 0; 155616cdd363SHong Zhang b->a2anew = 0; 15571a3463dfSHong Zhang b->permute = PETSC_FALSE; 1558c464158bSHong Zhang PetscFunctionReturn(0); 1559c464158bSHong Zhang } 1560a23d5eceSKris Buschelman EXTERN_C_END 1561153ea458SHong Zhang 1562db4efbfdSBarry Smith #undef __FUNCT__ 1563db4efbfdSBarry Smith #define __FUNCT__ "MatSeqBAIJSetNumericFactorization" 1564db4efbfdSBarry Smith /* 1565db4efbfdSBarry Smith This is used to set the numeric factorization for both Cholesky and ICC symbolic factorization 1566db4efbfdSBarry Smith */ 1567db4efbfdSBarry Smith PetscErrorCode MatSeqSBAIJSetNumericFactorization(Mat B,PetscTruth natural) 1568db4efbfdSBarry Smith { 1569db4efbfdSBarry Smith PetscErrorCode ierr; 157090d69ab7SBarry Smith PetscTruth flg = PETSC_FALSE; 1571db4efbfdSBarry Smith PetscInt bs = B->rmap->bs; 1572db4efbfdSBarry Smith 1573db4efbfdSBarry Smith PetscFunctionBegin; 157490d69ab7SBarry Smith ierr = PetscOptionsGetTruth(((PetscObject)B)->prefix,"-mat_no_unroll",&flg,PETSC_NULL);CHKERRQ(ierr); 1575db4efbfdSBarry Smith if (flg) bs = 8; 1576db4efbfdSBarry Smith 1577db4efbfdSBarry Smith if (!natural) { 1578db4efbfdSBarry Smith switch (bs) { 1579db4efbfdSBarry Smith case 1: 1580db4efbfdSBarry Smith B->ops->choleskyfactornumeric = MatCholeskyFactorNumeric_SeqSBAIJ_1; 1581db4efbfdSBarry Smith break; 1582db4efbfdSBarry Smith case 2: 1583db4efbfdSBarry Smith B->ops->choleskyfactornumeric = MatCholeskyFactorNumeric_SeqSBAIJ_2; 1584db4efbfdSBarry Smith break; 1585db4efbfdSBarry Smith case 3: 1586db4efbfdSBarry Smith B->ops->choleskyfactornumeric = MatCholeskyFactorNumeric_SeqSBAIJ_3; 1587db4efbfdSBarry Smith break; 1588db4efbfdSBarry Smith case 4: 1589db4efbfdSBarry Smith B->ops->choleskyfactornumeric = MatCholeskyFactorNumeric_SeqSBAIJ_4; 1590db4efbfdSBarry Smith break; 1591db4efbfdSBarry Smith case 5: 1592db4efbfdSBarry Smith B->ops->choleskyfactornumeric = MatCholeskyFactorNumeric_SeqSBAIJ_5; 1593db4efbfdSBarry Smith break; 1594db4efbfdSBarry Smith case 6: 1595db4efbfdSBarry Smith B->ops->choleskyfactornumeric = MatCholeskyFactorNumeric_SeqSBAIJ_6; 1596db4efbfdSBarry Smith break; 1597db4efbfdSBarry Smith case 7: 1598db4efbfdSBarry Smith B->ops->choleskyfactornumeric = MatCholeskyFactorNumeric_SeqSBAIJ_7; 1599db4efbfdSBarry Smith break; 1600db4efbfdSBarry Smith default: 1601db4efbfdSBarry Smith B->ops->choleskyfactornumeric = MatCholeskyFactorNumeric_SeqSBAIJ_N; 1602db4efbfdSBarry Smith break; 1603db4efbfdSBarry Smith } 1604db4efbfdSBarry Smith } else { 1605db4efbfdSBarry Smith switch (bs) { 1606db4efbfdSBarry Smith case 1: 1607db4efbfdSBarry Smith B->ops->choleskyfactornumeric = MatCholeskyFactorNumeric_SeqSBAIJ_1_NaturalOrdering; 1608db4efbfdSBarry Smith break; 1609db4efbfdSBarry Smith case 2: 1610db4efbfdSBarry Smith B->ops->choleskyfactornumeric = MatCholeskyFactorNumeric_SeqSBAIJ_2_NaturalOrdering; 1611db4efbfdSBarry Smith break; 1612db4efbfdSBarry Smith case 3: 1613db4efbfdSBarry Smith B->ops->choleskyfactornumeric = MatCholeskyFactorNumeric_SeqSBAIJ_3_NaturalOrdering; 1614db4efbfdSBarry Smith break; 1615db4efbfdSBarry Smith case 4: 1616db4efbfdSBarry Smith B->ops->choleskyfactornumeric = MatCholeskyFactorNumeric_SeqSBAIJ_4_NaturalOrdering; 1617db4efbfdSBarry Smith break; 1618db4efbfdSBarry Smith case 5: 1619db4efbfdSBarry Smith B->ops->choleskyfactornumeric = MatCholeskyFactorNumeric_SeqSBAIJ_5_NaturalOrdering; 1620db4efbfdSBarry Smith break; 1621db4efbfdSBarry Smith case 6: 1622db4efbfdSBarry Smith B->ops->choleskyfactornumeric = MatCholeskyFactorNumeric_SeqSBAIJ_6_NaturalOrdering; 1623db4efbfdSBarry Smith break; 1624db4efbfdSBarry Smith case 7: 1625db4efbfdSBarry Smith B->ops->choleskyfactornumeric = MatCholeskyFactorNumeric_SeqSBAIJ_7_NaturalOrdering; 1626db4efbfdSBarry Smith break; 1627db4efbfdSBarry Smith default: 1628db4efbfdSBarry Smith B->ops->choleskyfactornumeric = MatCholeskyFactorNumeric_SeqSBAIJ_N_NaturalOrdering; 1629db4efbfdSBarry Smith break; 1630db4efbfdSBarry Smith } 1631db4efbfdSBarry Smith } 1632db4efbfdSBarry Smith PetscFunctionReturn(0); 1633db4efbfdSBarry Smith } 1634db4efbfdSBarry Smith 1635d769727bSBarry Smith EXTERN_C_BEGIN 1636f69a0ea3SMatthew Knepley EXTERN PetscErrorCode PETSCMAT_DLLEXPORT MatConvert_SeqSBAIJ_SeqAIJ(Mat, MatType,MatReuse,Mat*); 1637f69a0ea3SMatthew Knepley EXTERN PetscErrorCode PETSCMAT_DLLEXPORT MatConvert_SeqSBAIJ_SeqBAIJ(Mat, MatType,MatReuse,Mat*); 1638d769727bSBarry Smith EXTERN_C_END 1639d769727bSBarry Smith 1640e631078cSBarry Smith 1641e631078cSBarry Smith EXTERN_C_BEGIN 16425c9eb25fSBarry Smith #undef __FUNCT__ 16435c9eb25fSBarry Smith #define __FUNCT__ "MatGetFactor_seqsbaij_petsc" 16445c9eb25fSBarry Smith PetscErrorCode MatGetFactor_seqsbaij_petsc(Mat A,MatFactorType ftype,Mat *B) 16455c9eb25fSBarry Smith { 1646d0f46423SBarry Smith PetscInt n = A->rmap->n; 16475c9eb25fSBarry Smith PetscErrorCode ierr; 16485c9eb25fSBarry Smith 16495c9eb25fSBarry Smith PetscFunctionBegin; 16505c9eb25fSBarry Smith ierr = MatCreate(((PetscObject)A)->comm,B);CHKERRQ(ierr); 16515c9eb25fSBarry Smith ierr = MatSetSizes(*B,n,n,n,n);CHKERRQ(ierr); 16525c9eb25fSBarry Smith if (ftype == MAT_FACTOR_CHOLESKY || ftype == MAT_FACTOR_ICC) { 16535c9eb25fSBarry Smith ierr = MatSetType(*B,MATSEQSBAIJ);CHKERRQ(ierr); 16545c9eb25fSBarry Smith ierr = MatSeqSBAIJSetPreallocation(*B,1,MAT_SKIP_ALLOCATION,PETSC_NULL);CHKERRQ(ierr); 1655db4efbfdSBarry Smith (*B)->ops->choleskyfactorsymbolic = MatCholeskyFactorSymbolic_SeqSBAIJ; 1656db4efbfdSBarry Smith (*B)->ops->iccfactorsymbolic = MatICCFactorSymbolic_SeqSBAIJ; 16575c9eb25fSBarry Smith } else SETERRQ(PETSC_ERR_SUP,"Factor type not supported"); 1658719d5645SBarry Smith (*B)->factor = ftype; 16595c9eb25fSBarry Smith PetscFunctionReturn(0); 16605c9eb25fSBarry Smith } 1661e631078cSBarry Smith EXTERN_C_END 16625c9eb25fSBarry Smith 16635c9eb25fSBarry Smith EXTERN_C_BEGIN 1664db4efbfdSBarry Smith #undef __FUNCT__ 1665db4efbfdSBarry Smith #define __FUNCT__ "MatGetFactorAvailable_seqsbaij_petsc" 1666db4efbfdSBarry Smith PetscErrorCode MatGetFactorAvailable_seqsbaij_petsc(Mat A,MatFactorType ftype,PetscTruth *flg) 1667db4efbfdSBarry Smith { 1668db4efbfdSBarry Smith PetscFunctionBegin; 1669db4efbfdSBarry Smith if (ftype == MAT_FACTOR_CHOLESKY || ftype == MAT_FACTOR_ICC) { 1670db4efbfdSBarry Smith *flg = PETSC_TRUE; 1671db4efbfdSBarry Smith } else { 1672db4efbfdSBarry Smith *flg = PETSC_FALSE; 1673db4efbfdSBarry Smith } 1674db4efbfdSBarry Smith PetscFunctionReturn(0); 1675db4efbfdSBarry Smith } 1676db4efbfdSBarry Smith EXTERN_C_END 1677db4efbfdSBarry Smith 1678db4efbfdSBarry Smith EXTERN_C_BEGIN 1679611f576cSBarry Smith #if defined(PETSC_HAVE_MUMPS) 16805c9eb25fSBarry Smith extern PetscErrorCode MatGetFactor_seqsbaij_mumps(Mat,MatFactorType,Mat*); 1681611f576cSBarry Smith #endif 1682611f576cSBarry Smith #if defined(PETSC_HAVE_SPOOLES) 16835c9eb25fSBarry Smith extern PetscErrorCode MatGetFactor_seqsbaij_spooles(Mat,MatFactorType,Mat*); 1684611f576cSBarry Smith #endif 1685b5e56a35SBarry Smith #if defined(PETSC_HAVE_PASTIX) 1686b5e56a35SBarry Smith extern PetscErrorCode MatGetFactor_seqsbaij_pastix(Mat,MatFactorType,Mat*); 1687b5e56a35SBarry Smith #endif 16885c9eb25fSBarry Smith EXTERN_C_END 16895c9eb25fSBarry Smith 16900bad9183SKris Buschelman /*MC 1691fafad747SKris Buschelman MATSEQSBAIJ - MATSEQSBAIJ = "seqsbaij" - A matrix type to be used for sequential symmetric block sparse matrices, 16920bad9183SKris Buschelman based on block compressed sparse row format. Only the upper triangular portion of the matrix is stored. 16930bad9183SKris Buschelman 16940bad9183SKris Buschelman Options Database Keys: 16950bad9183SKris Buschelman . -mat_type seqsbaij - sets the matrix type to "seqsbaij" during a call to MatSetFromOptions() 16960bad9183SKris Buschelman 16970bad9183SKris Buschelman Level: beginner 16980bad9183SKris Buschelman 16990bad9183SKris Buschelman .seealso: MatCreateSeqSBAIJ 17000bad9183SKris Buschelman M*/ 17010bad9183SKris Buschelman 1702a23d5eceSKris Buschelman EXTERN_C_BEGIN 1703a23d5eceSKris Buschelman #undef __FUNCT__ 1704a23d5eceSKris Buschelman #define __FUNCT__ "MatCreate_SeqSBAIJ" 1705be1d678aSKris Buschelman PetscErrorCode PETSCMAT_DLLEXPORT MatCreate_SeqSBAIJ(Mat B) 1706a23d5eceSKris Buschelman { 1707a23d5eceSKris Buschelman Mat_SeqSBAIJ *b; 1708dfbe8321SBarry Smith PetscErrorCode ierr; 170913f74950SBarry Smith PetscMPIInt size; 1710*0def2e27SBarry Smith PetscTruth no_unroll = PETSC_FALSE,no_inode = PETSC_FALSE; 1711a23d5eceSKris Buschelman 1712a23d5eceSKris Buschelman PetscFunctionBegin; 17137adad957SLisandro Dalcin ierr = MPI_Comm_size(((PetscObject)B)->comm,&size);CHKERRQ(ierr); 1714a23d5eceSKris Buschelman if (size > 1) SETERRQ(PETSC_ERR_ARG_WRONG,"Comm must be of size 1"); 1715a23d5eceSKris Buschelman 171638f2d2fdSLisandro Dalcin ierr = PetscNewLog(B,Mat_SeqSBAIJ,&b);CHKERRQ(ierr); 1717a23d5eceSKris Buschelman B->data = (void*)b; 1718a23d5eceSKris Buschelman ierr = PetscMemcpy(B->ops,&MatOps_Values,sizeof(struct _MatOps));CHKERRQ(ierr); 1719a23d5eceSKris Buschelman B->ops->destroy = MatDestroy_SeqSBAIJ; 1720a23d5eceSKris Buschelman B->ops->view = MatView_SeqSBAIJ; 1721a23d5eceSKris Buschelman B->mapping = 0; 1722a23d5eceSKris Buschelman b->row = 0; 1723a23d5eceSKris Buschelman b->icol = 0; 1724a23d5eceSKris Buschelman b->reallocs = 0; 1725a23d5eceSKris Buschelman b->saved_values = 0; 1726*0def2e27SBarry Smith b->inode.limit = 5; 1727*0def2e27SBarry Smith b->inode.max_limit = 5; 1728a23d5eceSKris Buschelman 1729a23d5eceSKris Buschelman b->roworiented = PETSC_TRUE; 1730a23d5eceSKris Buschelman b->nonew = 0; 1731a23d5eceSKris Buschelman b->diag = 0; 1732a23d5eceSKris Buschelman b->solve_work = 0; 1733a23d5eceSKris Buschelman b->mult_work = 0; 1734a23d5eceSKris Buschelman B->spptr = 0; 1735a9817697SBarry Smith b->keepnonzeropattern = PETSC_FALSE; 1736a23d5eceSKris Buschelman b->xtoy = 0; 1737a23d5eceSKris Buschelman b->XtoY = 0; 1738a23d5eceSKris Buschelman 1739a23d5eceSKris Buschelman b->inew = 0; 1740a23d5eceSKris Buschelman b->jnew = 0; 1741a23d5eceSKris Buschelman b->anew = 0; 1742a23d5eceSKris Buschelman b->a2anew = 0; 1743a23d5eceSKris Buschelman b->permute = PETSC_FALSE; 1744a23d5eceSKris Buschelman 1745941593c8SHong Zhang b->ignore_ltriangular = PETSC_FALSE; 174690d69ab7SBarry Smith ierr = PetscOptionsGetTruth(((PetscObject)B)->prefix,"-mat_ignore_lower_triangular",&b->ignore_ltriangular,PETSC_NULL);CHKERRQ(ierr); 1747941593c8SHong Zhang 1748f5edf698SHong Zhang b->getrow_utriangular = PETSC_FALSE; 174990d69ab7SBarry Smith ierr = PetscOptionsGetTruth(((PetscObject)B)->prefix,"-mat_getrow_uppertriangular",&b->getrow_utriangular,PETSC_NULL);CHKERRQ(ierr); 1750f5edf698SHong Zhang 1751b5e56a35SBarry Smith #if defined(PETSC_HAVE_PASTIX) 1752b5e56a35SBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatGetFactor_seqsbaij_pastix_C", 1753b5e56a35SBarry Smith "MatGetFactor_seqsbaij_pastix", 1754b5e56a35SBarry Smith MatGetFactor_seqsbaij_pastix);CHKERRQ(ierr); 1755b5e56a35SBarry Smith #endif 1756611f576cSBarry Smith #if defined(PETSC_HAVE_SPOOLES) 17575c9eb25fSBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatGetFactor_seqsbaij_spooles_C", 17585c9eb25fSBarry Smith "MatGetFactor_seqsbaij_spooles", 17595c9eb25fSBarry Smith MatGetFactor_seqsbaij_spooles);CHKERRQ(ierr); 1760611f576cSBarry Smith #endif 1761611f576cSBarry Smith #if defined(PETSC_HAVE_MUMPS) 17625c9eb25fSBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatGetFactor_seqsbaij_mumps_C", 17635c9eb25fSBarry Smith "MatGetFactor_seqsbaij_mumps", 17645c9eb25fSBarry Smith MatGetFactor_seqsbaij_mumps);CHKERRQ(ierr); 1765611f576cSBarry Smith #endif 1766db4efbfdSBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatGetFactorAvailable_seqsbaij_petsc_C", 1767db4efbfdSBarry Smith "MatGetFactorAvailable_seqsbaij_petsc", 1768db4efbfdSBarry Smith MatGetFactorAvailable_seqsbaij_petsc);CHKERRQ(ierr); 17695c9eb25fSBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatGetFactor_seqsbaij_petsc_C", 17705c9eb25fSBarry Smith "MatGetFactor_seqsbaij_petsc", 17715c9eb25fSBarry Smith MatGetFactor_seqsbaij_petsc);CHKERRQ(ierr); 1772a23d5eceSKris Buschelman ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatStoreValues_C", 1773a23d5eceSKris Buschelman "MatStoreValues_SeqSBAIJ", 1774a23d5eceSKris Buschelman MatStoreValues_SeqSBAIJ);CHKERRQ(ierr); 1775a23d5eceSKris Buschelman ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatRetrieveValues_C", 1776a23d5eceSKris Buschelman "MatRetrieveValues_SeqSBAIJ", 1777a23d5eceSKris Buschelman (void*)MatRetrieveValues_SeqSBAIJ);CHKERRQ(ierr); 1778a23d5eceSKris Buschelman ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatSeqSBAIJSetColumnIndices_C", 1779a23d5eceSKris Buschelman "MatSeqSBAIJSetColumnIndices_SeqSBAIJ", 1780a23d5eceSKris Buschelman MatSeqSBAIJSetColumnIndices_SeqSBAIJ);CHKERRQ(ierr); 17814e5e7fe4SHong Zhang ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatConvert_seqsbaij_seqaij_C", 17824e5e7fe4SHong Zhang "MatConvert_SeqSBAIJ_SeqAIJ", 17834e5e7fe4SHong Zhang MatConvert_SeqSBAIJ_SeqAIJ);CHKERRQ(ierr); 1784a0e1a404SHong Zhang ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatConvert_seqsbaij_seqbaij_C", 1785a0e1a404SHong Zhang "MatConvert_SeqSBAIJ_SeqBAIJ", 1786a0e1a404SHong Zhang MatConvert_SeqSBAIJ_SeqBAIJ);CHKERRQ(ierr); 1787a23d5eceSKris Buschelman ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatSeqSBAIJSetPreallocation_C", 1788a23d5eceSKris Buschelman "MatSeqSBAIJSetPreallocation_SeqSBAIJ", 1789a23d5eceSKris Buschelman MatSeqSBAIJSetPreallocation_SeqSBAIJ);CHKERRQ(ierr); 179023ce1328SBarry Smith 179123ce1328SBarry Smith B->symmetric = PETSC_TRUE; 179223ce1328SBarry Smith B->structurally_symmetric = PETSC_TRUE; 179323ce1328SBarry Smith B->symmetric_set = PETSC_TRUE; 179423ce1328SBarry Smith B->structurally_symmetric_set = PETSC_TRUE; 179517667f90SBarry Smith ierr = PetscObjectChangeTypeName((PetscObject)B,MATSEQSBAIJ);CHKERRQ(ierr); 1796*0def2e27SBarry Smith 1797*0def2e27SBarry Smith ierr = PetscOptionsBegin(((PetscObject)B)->comm,((PetscObject)B)->prefix,"Options for SEQSBAIJ matrix","Mat");CHKERRQ(ierr); 1798*0def2e27SBarry Smith ierr = PetscOptionsTruth("-mat_no_unroll","Do not optimize for inodes (slower)",PETSC_NULL,no_unroll,&no_unroll,PETSC_NULL);CHKERRQ(ierr); 1799*0def2e27SBarry Smith if (no_unroll) {ierr = PetscInfo(B,"Not using Inode routines due to -mat_no_unroll\n");CHKERRQ(ierr);} 1800*0def2e27SBarry Smith ierr = PetscOptionsTruth("-mat_no_inode","Do not optimize for inodes (slower)",PETSC_NULL,no_inode,&no_inode,PETSC_NULL);CHKERRQ(ierr); 1801*0def2e27SBarry Smith if (no_inode) {ierr = PetscInfo(B,"Not using Inode routines due to -mat_no_inode\n");CHKERRQ(ierr);} 1802*0def2e27SBarry Smith ierr = PetscOptionsInt("-mat_inode_limit","Do not use inodes larger then this value",PETSC_NULL,b->inode.limit,&b->inode.limit,PETSC_NULL);CHKERRQ(ierr); 1803*0def2e27SBarry Smith ierr = PetscOptionsEnd();CHKERRQ(ierr); 1804*0def2e27SBarry Smith b->inode.use = (PetscTruth)(!(no_unroll || no_inode)); 1805*0def2e27SBarry Smith if (b->inode.limit > b->inode.max_limit) b->inode.limit = b->inode.max_limit; 1806*0def2e27SBarry Smith 1807a23d5eceSKris Buschelman PetscFunctionReturn(0); 1808a23d5eceSKris Buschelman } 1809a23d5eceSKris Buschelman EXTERN_C_END 1810a23d5eceSKris Buschelman 1811a23d5eceSKris Buschelman #undef __FUNCT__ 1812a23d5eceSKris Buschelman #define __FUNCT__ "MatSeqSBAIJSetPreallocation" 1813a23d5eceSKris Buschelman /*@C 1814a23d5eceSKris Buschelman MatSeqSBAIJSetPreallocation - Creates a sparse symmetric matrix in block AIJ (block 1815a23d5eceSKris Buschelman compressed row) format. For good matrix assembly performance the 1816a23d5eceSKris Buschelman user should preallocate the matrix storage by setting the parameter nz 1817a23d5eceSKris Buschelman (or the array nnz). By setting these parameters accurately, performance 1818a23d5eceSKris Buschelman during matrix assembly can be increased by more than a factor of 50. 1819a23d5eceSKris Buschelman 1820a23d5eceSKris Buschelman Collective on Mat 1821a23d5eceSKris Buschelman 1822a23d5eceSKris Buschelman Input Parameters: 1823a23d5eceSKris Buschelman + A - the symmetric matrix 1824a23d5eceSKris Buschelman . bs - size of block 1825a23d5eceSKris Buschelman . nz - number of block nonzeros per block row (same for all rows) 1826a23d5eceSKris Buschelman - nnz - array containing the number of block nonzeros in the upper triangular plus 1827a23d5eceSKris Buschelman diagonal portion of each block (possibly different for each block row) or PETSC_NULL 1828a23d5eceSKris Buschelman 1829a23d5eceSKris Buschelman Options Database Keys: 1830a23d5eceSKris Buschelman . -mat_no_unroll - uses code that does not unroll the loops in the 1831a23d5eceSKris Buschelman block calculations (much slower) 1832db4efbfdSBarry Smith . -mat_block_size - size of the blocks to use (only works if a negative bs is passed in 1833a23d5eceSKris Buschelman 1834a23d5eceSKris Buschelman Level: intermediate 1835a23d5eceSKris Buschelman 1836a23d5eceSKris Buschelman Notes: 1837a23d5eceSKris Buschelman Specify the preallocated storage with either nz or nnz (not both). 1838a23d5eceSKris Buschelman Set nz=PETSC_DEFAULT and nnz=PETSC_NULL for PETSc to control dynamic memory 1839a23d5eceSKris Buschelman allocation. For additional details, see the users manual chapter on 1840a23d5eceSKris Buschelman matrices. 1841a23d5eceSKris Buschelman 1842aa95bbe8SBarry Smith You can call MatGetInfo() to get information on how effective the preallocation was; 1843aa95bbe8SBarry Smith for example the fields mallocs,nz_allocated,nz_used,nz_unneeded; 1844aa95bbe8SBarry Smith You can also run with the option -info and look for messages with the string 1845aa95bbe8SBarry Smith malloc in them to see if additional memory allocation was needed. 1846aa95bbe8SBarry Smith 184749a6f317SBarry Smith If the nnz parameter is given then the nz parameter is ignored 184849a6f317SBarry Smith 184949a6f317SBarry Smith 1850a23d5eceSKris Buschelman .seealso: MatCreate(), MatCreateSeqAIJ(), MatSetValues(), MatCreateMPISBAIJ() 1851a23d5eceSKris Buschelman @*/ 1852be1d678aSKris Buschelman PetscErrorCode PETSCMAT_DLLEXPORT MatSeqSBAIJSetPreallocation(Mat B,PetscInt bs,PetscInt nz,const PetscInt nnz[]) 185313f74950SBarry Smith { 185413f74950SBarry Smith PetscErrorCode ierr,(*f)(Mat,PetscInt,PetscInt,const PetscInt[]); 1855a23d5eceSKris Buschelman 1856a23d5eceSKris Buschelman PetscFunctionBegin; 1857a23d5eceSKris Buschelman ierr = PetscObjectQueryFunction((PetscObject)B,"MatSeqSBAIJSetPreallocation_C",(void (**)(void))&f);CHKERRQ(ierr); 1858a23d5eceSKris Buschelman if (f) { 1859a23d5eceSKris Buschelman ierr = (*f)(B,bs,nz,nnz);CHKERRQ(ierr); 1860a23d5eceSKris Buschelman } 1861a23d5eceSKris Buschelman PetscFunctionReturn(0); 1862a23d5eceSKris Buschelman } 186349b5e25fSSatish Balay 18644a2ae208SSatish Balay #undef __FUNCT__ 18654a2ae208SSatish Balay #define __FUNCT__ "MatCreateSeqSBAIJ" 1866c464158bSHong Zhang /*@C 1867c464158bSHong Zhang MatCreateSeqSBAIJ - Creates a sparse symmetric matrix in block AIJ (block 1868c464158bSHong Zhang compressed row) format. For good matrix assembly performance the 1869c464158bSHong Zhang user should preallocate the matrix storage by setting the parameter nz 1870c464158bSHong Zhang (or the array nnz). By setting these parameters accurately, performance 1871c464158bSHong Zhang during matrix assembly can be increased by more than a factor of 50. 187249b5e25fSSatish Balay 1873c464158bSHong Zhang Collective on MPI_Comm 1874c464158bSHong Zhang 1875c464158bSHong Zhang Input Parameters: 1876c464158bSHong Zhang + comm - MPI communicator, set to PETSC_COMM_SELF 1877c464158bSHong Zhang . bs - size of block 1878c464158bSHong Zhang . m - number of rows, or number of columns 1879c464158bSHong Zhang . nz - number of block nonzeros per block row (same for all rows) 1880744e8345SSatish Balay - nnz - array containing the number of block nonzeros in the upper triangular plus 1881744e8345SSatish Balay diagonal portion of each block (possibly different for each block row) or PETSC_NULL 1882c464158bSHong Zhang 1883c464158bSHong Zhang Output Parameter: 1884c464158bSHong Zhang . A - the symmetric matrix 1885c464158bSHong Zhang 1886c464158bSHong Zhang Options Database Keys: 1887c464158bSHong Zhang . -mat_no_unroll - uses code that does not unroll the loops in the 1888c464158bSHong Zhang block calculations (much slower) 1889c464158bSHong Zhang . -mat_block_size - size of the blocks to use 1890c464158bSHong Zhang 1891c464158bSHong Zhang Level: intermediate 1892c464158bSHong Zhang 1893175b88e8SBarry Smith It is recommended that one use the MatCreate(), MatSetType() and/or MatSetFromOptions(), 1894ae1d86c5SBarry Smith MatXXXXSetPreallocation() paradgm instead of this routine directly. 1895175b88e8SBarry Smith [MatXXXXSetPreallocation() is, for example, MatSeqAIJSetPreallocation] 1896175b88e8SBarry Smith 1897c464158bSHong Zhang Notes: 18986d6d819aSHong Zhang The number of rows and columns must be divisible by blocksize. 18996d6d819aSHong Zhang This matrix type does not support complex Hermitian operation. 1900c464158bSHong Zhang 1901c464158bSHong Zhang Specify the preallocated storage with either nz or nnz (not both). 1902c464158bSHong Zhang Set nz=PETSC_DEFAULT and nnz=PETSC_NULL for PETSc to control dynamic memory 1903c464158bSHong Zhang allocation. For additional details, see the users manual chapter on 1904c464158bSHong Zhang matrices. 1905c464158bSHong Zhang 190649a6f317SBarry Smith If the nnz parameter is given then the nz parameter is ignored 190749a6f317SBarry Smith 1908c464158bSHong Zhang .seealso: MatCreate(), MatCreateSeqAIJ(), MatSetValues(), MatCreateMPISBAIJ() 1909c464158bSHong Zhang @*/ 1910be1d678aSKris Buschelman PetscErrorCode PETSCMAT_DLLEXPORT MatCreateSeqSBAIJ(MPI_Comm comm,PetscInt bs,PetscInt m,PetscInt n,PetscInt nz,const PetscInt nnz[],Mat *A) 1911c464158bSHong Zhang { 1912dfbe8321SBarry Smith PetscErrorCode ierr; 1913c464158bSHong Zhang 1914c464158bSHong Zhang PetscFunctionBegin; 1915f69a0ea3SMatthew Knepley ierr = MatCreate(comm,A);CHKERRQ(ierr); 1916f69a0ea3SMatthew Knepley ierr = MatSetSizes(*A,m,n,m,n);CHKERRQ(ierr); 1917c464158bSHong Zhang ierr = MatSetType(*A,MATSEQSBAIJ);CHKERRQ(ierr); 1918ab93d7beSBarry Smith ierr = MatSeqSBAIJSetPreallocation_SeqSBAIJ(*A,bs,nz,(PetscInt*)nnz);CHKERRQ(ierr); 191949b5e25fSSatish Balay PetscFunctionReturn(0); 192049b5e25fSSatish Balay } 192149b5e25fSSatish Balay 19224a2ae208SSatish Balay #undef __FUNCT__ 19234a2ae208SSatish Balay #define __FUNCT__ "MatDuplicate_SeqSBAIJ" 1924dfbe8321SBarry Smith PetscErrorCode MatDuplicate_SeqSBAIJ(Mat A,MatDuplicateOption cpvalues,Mat *B) 192549b5e25fSSatish Balay { 192649b5e25fSSatish Balay Mat C; 192749b5e25fSSatish Balay Mat_SeqSBAIJ *c,*a = (Mat_SeqSBAIJ*)A->data; 19286849ba73SBarry Smith PetscErrorCode ierr; 1929b40805acSSatish Balay PetscInt i,mbs = a->mbs,nz = a->nz,bs2 =a->bs2; 193049b5e25fSSatish Balay 193149b5e25fSSatish Balay PetscFunctionBegin; 193229bbc08cSBarry Smith if (a->i[mbs] != nz) SETERRQ(PETSC_ERR_PLIB,"Corrupt matrix"); 193349b5e25fSSatish Balay 193449b5e25fSSatish Balay *B = 0; 19357adad957SLisandro Dalcin ierr = MatCreate(((PetscObject)A)->comm,&C);CHKERRQ(ierr); 1936d0f46423SBarry Smith ierr = MatSetSizes(C,A->rmap->N,A->cmap->n,A->rmap->N,A->cmap->n);CHKERRQ(ierr); 19377adad957SLisandro Dalcin ierr = MatSetType(C,((PetscObject)A)->type_name);CHKERRQ(ierr); 19381d5dac46SHong Zhang ierr = PetscMemcpy(C->ops,A->ops,sizeof(struct _MatOps));CHKERRQ(ierr); 1939692f9cbeSHong Zhang c = (Mat_SeqSBAIJ*)C->data; 1940692f9cbeSHong Zhang 1941273d9f13SBarry Smith C->preallocated = PETSC_TRUE; 194249b5e25fSSatish Balay C->factor = A->factor; 194349b5e25fSSatish Balay c->row = 0; 194449b5e25fSSatish Balay c->icol = 0; 194549b5e25fSSatish Balay c->saved_values = 0; 1946a9817697SBarry Smith c->keepnonzeropattern = a->keepnonzeropattern; 194749b5e25fSSatish Balay C->assembled = PETSC_TRUE; 194849b5e25fSSatish Balay 1949d0f46423SBarry Smith ierr = PetscMapCopy(((PetscObject)A)->comm,A->rmap,C->rmap);CHKERRQ(ierr); 1950d0f46423SBarry Smith ierr = PetscMapCopy(((PetscObject)A)->comm,A->cmap,C->cmap);CHKERRQ(ierr); 195149b5e25fSSatish Balay c->bs2 = a->bs2; 195249b5e25fSSatish Balay c->mbs = a->mbs; 195349b5e25fSSatish Balay c->nbs = a->nbs; 195449b5e25fSSatish Balay 19558777fc3fSSatish Balay ierr = PetscMalloc2((mbs+1),PetscInt,&c->imax,(mbs+1),PetscInt,&c->ilen);CHKERRQ(ierr); 195649b5e25fSSatish Balay for (i=0; i<mbs; i++) { 195749b5e25fSSatish Balay c->imax[i] = a->imax[i]; 195849b5e25fSSatish Balay c->ilen[i] = a->ilen[i]; 195949b5e25fSSatish Balay } 196049b5e25fSSatish Balay 196149b5e25fSSatish Balay /* allocate the matrix space */ 1962b40805acSSatish Balay ierr = PetscMalloc3(bs2*nz,MatScalar,&c->a,nz,PetscInt,&c->j,mbs+1,PetscInt,&c->i);CHKERRQ(ierr); 196349b5e25fSSatish Balay c->singlemalloc = PETSC_TRUE; 196413f74950SBarry Smith ierr = PetscMemcpy(c->i,a->i,(mbs+1)*sizeof(PetscInt));CHKERRQ(ierr); 1965b40805acSSatish Balay ierr = PetscLogObjectMemory(C,(mbs+1)*sizeof(PetscInt) + nz*(bs2*sizeof(MatScalar) + sizeof(PetscInt)));CHKERRQ(ierr); 196649b5e25fSSatish Balay if (mbs > 0) { 196713f74950SBarry Smith ierr = PetscMemcpy(c->j,a->j,nz*sizeof(PetscInt));CHKERRQ(ierr); 196849b5e25fSSatish Balay if (cpvalues == MAT_COPY_VALUES) { 196949b5e25fSSatish Balay ierr = PetscMemcpy(c->a,a->a,bs2*nz*sizeof(MatScalar));CHKERRQ(ierr); 197049b5e25fSSatish Balay } else { 197149b5e25fSSatish Balay ierr = PetscMemzero(c->a,bs2*nz*sizeof(MatScalar));CHKERRQ(ierr); 197249b5e25fSSatish Balay } 197349b5e25fSSatish Balay } 197449b5e25fSSatish Balay 197549b5e25fSSatish Balay c->roworiented = a->roworiented; 197649b5e25fSSatish Balay c->nonew = a->nonew; 197749b5e25fSSatish Balay 197849b5e25fSSatish Balay if (a->diag) { 197913f74950SBarry Smith ierr = PetscMalloc((mbs+1)*sizeof(PetscInt),&c->diag);CHKERRQ(ierr); 198052e6d16bSBarry Smith ierr = PetscLogObjectMemory(C,(mbs+1)*sizeof(PetscInt));CHKERRQ(ierr); 198149b5e25fSSatish Balay for (i=0; i<mbs; i++) { 198249b5e25fSSatish Balay c->diag[i] = a->diag[i]; 198349b5e25fSSatish Balay } 198449b5e25fSSatish Balay } else c->diag = 0; 19856c6c5352SBarry Smith c->nz = a->nz; 19866c6c5352SBarry Smith c->maxnz = a->maxnz; 198749b5e25fSSatish Balay c->solve_work = 0; 198849b5e25fSSatish Balay c->mult_work = 0; 1989e6b907acSBarry Smith c->free_a = PETSC_TRUE; 1990e6b907acSBarry Smith c->free_ij = PETSC_TRUE; 199149b5e25fSSatish Balay *B = C; 19927adad957SLisandro Dalcin ierr = PetscFListDuplicate(((PetscObject)A)->qlist,&((PetscObject)C)->qlist);CHKERRQ(ierr); 199349b5e25fSSatish Balay PetscFunctionReturn(0); 199449b5e25fSSatish Balay } 199549b5e25fSSatish Balay 19964a2ae208SSatish Balay #undef __FUNCT__ 19974a2ae208SSatish Balay #define __FUNCT__ "MatLoad_SeqSBAIJ" 1998a313700dSBarry Smith PetscErrorCode MatLoad_SeqSBAIJ(PetscViewer viewer, const MatType type,Mat *A) 199949b5e25fSSatish Balay { 200049b5e25fSSatish Balay Mat_SeqSBAIJ *a; 200149b5e25fSSatish Balay Mat B; 20026849ba73SBarry Smith PetscErrorCode ierr; 200313f74950SBarry Smith int fd; 200413f74950SBarry Smith PetscMPIInt size; 200513f74950SBarry Smith PetscInt i,nz,header[4],*rowlengths=0,M,N,bs=1; 200613f74950SBarry Smith PetscInt *mask,mbs,*jj,j,rowcount,nzcount,k,*s_browlengths,maskcount; 200713f74950SBarry Smith PetscInt kmax,jcount,block,idx,point,nzcountb,extra_rows; 200813f74950SBarry Smith PetscInt *masked,nmask,tmp,bs2,ishift; 200987828ca2SBarry Smith PetscScalar *aa; 201049b5e25fSSatish Balay MPI_Comm comm = ((PetscObject)viewer)->comm; 201149b5e25fSSatish Balay 201249b5e25fSSatish Balay PetscFunctionBegin; 2013b0a32e0cSBarry Smith ierr = PetscOptionsGetInt(PETSC_NULL,"-matload_block_size",&bs,PETSC_NULL);CHKERRQ(ierr); 201449b5e25fSSatish Balay bs2 = bs*bs; 201549b5e25fSSatish Balay 201649b5e25fSSatish Balay ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); 201729bbc08cSBarry Smith if (size > 1) SETERRQ(PETSC_ERR_ARG_WRONG,"view must have one processor"); 2018b0a32e0cSBarry Smith ierr = PetscViewerBinaryGetDescriptor(viewer,&fd);CHKERRQ(ierr); 201949b5e25fSSatish Balay ierr = PetscBinaryRead(fd,header,4,PETSC_INT);CHKERRQ(ierr); 2020552e946dSBarry Smith if (header[0] != MAT_FILE_COOKIE) SETERRQ(PETSC_ERR_FILE_UNEXPECTED,"not Mat object"); 202149b5e25fSSatish Balay M = header[1]; N = header[2]; nz = header[3]; 202249b5e25fSSatish Balay 202349b5e25fSSatish Balay if (header[3] < 0) { 202429bbc08cSBarry Smith SETERRQ(PETSC_ERR_FILE_UNEXPECTED,"Matrix stored in special format, cannot load as SeqSBAIJ"); 202549b5e25fSSatish Balay } 202649b5e25fSSatish Balay 202729bbc08cSBarry Smith if (M != N) SETERRQ(PETSC_ERR_SUP,"Can only do square matrices"); 202849b5e25fSSatish Balay 202949b5e25fSSatish Balay /* 203049b5e25fSSatish Balay This code adds extra rows to make sure the number of rows is 203149b5e25fSSatish Balay divisible by the blocksize 203249b5e25fSSatish Balay */ 203349b5e25fSSatish Balay mbs = M/bs; 203449b5e25fSSatish Balay extra_rows = bs - M + bs*(mbs); 203549b5e25fSSatish Balay if (extra_rows == bs) extra_rows = 0; 203649b5e25fSSatish Balay else mbs++; 203749b5e25fSSatish Balay if (extra_rows) { 20381e2582c4SBarry Smith ierr = PetscInfo(viewer,"Padding loaded matrix to match blocksize\n");CHKERRQ(ierr); 203949b5e25fSSatish Balay } 204049b5e25fSSatish Balay 204149b5e25fSSatish Balay /* read in row lengths */ 204213f74950SBarry Smith ierr = PetscMalloc((M+extra_rows)*sizeof(PetscInt),&rowlengths);CHKERRQ(ierr); 204349b5e25fSSatish Balay ierr = PetscBinaryRead(fd,rowlengths,M,PETSC_INT);CHKERRQ(ierr); 204449b5e25fSSatish Balay for (i=0; i<extra_rows; i++) rowlengths[M+i] = 1; 204549b5e25fSSatish Balay 204649b5e25fSSatish Balay /* read in column indices */ 204713f74950SBarry Smith ierr = PetscMalloc((nz+extra_rows)*sizeof(PetscInt),&jj);CHKERRQ(ierr); 204849b5e25fSSatish Balay ierr = PetscBinaryRead(fd,jj,nz,PETSC_INT);CHKERRQ(ierr); 204949b5e25fSSatish Balay for (i=0; i<extra_rows; i++) jj[nz+i] = M+i; 205049b5e25fSSatish Balay 205149b5e25fSSatish Balay /* loop over row lengths determining block row lengths */ 205213f74950SBarry Smith ierr = PetscMalloc(mbs*sizeof(PetscInt),&s_browlengths);CHKERRQ(ierr); 205313f74950SBarry Smith ierr = PetscMemzero(s_browlengths,mbs*sizeof(PetscInt));CHKERRQ(ierr); 205413f74950SBarry Smith ierr = PetscMalloc(2*mbs*sizeof(PetscInt),&mask);CHKERRQ(ierr); 205513f74950SBarry Smith ierr = PetscMemzero(mask,mbs*sizeof(PetscInt));CHKERRQ(ierr); 205649b5e25fSSatish Balay masked = mask + mbs; 205749b5e25fSSatish Balay rowcount = 0; nzcount = 0; 205849b5e25fSSatish Balay for (i=0; i<mbs; i++) { 205949b5e25fSSatish Balay nmask = 0; 206049b5e25fSSatish Balay for (j=0; j<bs; j++) { 206149b5e25fSSatish Balay kmax = rowlengths[rowcount]; 206249b5e25fSSatish Balay for (k=0; k<kmax; k++) { 20632d703238SHong Zhang tmp = jj[nzcount++]/bs; /* block col. index */ 206403630b6eSHong Zhang if (!mask[tmp] && tmp >= i) {masked[nmask++] = tmp; mask[tmp] = 1;} 206549b5e25fSSatish Balay } 206649b5e25fSSatish Balay rowcount++; 206749b5e25fSSatish Balay } 2068574b2666SHong Zhang s_browlengths[i] += nmask; 2069574b2666SHong Zhang 207049b5e25fSSatish Balay /* zero out the mask elements we set */ 207149b5e25fSSatish Balay for (j=0; j<nmask; j++) mask[masked[j]] = 0; 207249b5e25fSSatish Balay } 207349b5e25fSSatish Balay 207449b5e25fSSatish Balay /* create our matrix */ 2075f69a0ea3SMatthew Knepley ierr = MatCreate(comm,&B);CHKERRQ(ierr); 2076f69a0ea3SMatthew Knepley ierr = MatSetSizes(B,M+extra_rows,N+extra_rows,M+extra_rows,N+extra_rows);CHKERRQ(ierr); 20779abb65ffSKris Buschelman ierr = MatSetType(B,type);CHKERRQ(ierr); 2078ab93d7beSBarry Smith ierr = MatSeqSBAIJSetPreallocation_SeqSBAIJ(B,bs,0,s_browlengths);CHKERRQ(ierr); 207949b5e25fSSatish Balay a = (Mat_SeqSBAIJ*)B->data; 208049b5e25fSSatish Balay 208149b5e25fSSatish Balay /* set matrix "i" values */ 208249b5e25fSSatish Balay a->i[0] = 0; 208349b5e25fSSatish Balay for (i=1; i<= mbs; i++) { 2084574b2666SHong Zhang a->i[i] = a->i[i-1] + s_browlengths[i-1]; 2085574b2666SHong Zhang a->ilen[i-1] = s_browlengths[i-1]; 208649b5e25fSSatish Balay } 20876c6c5352SBarry Smith a->nz = a->i[mbs]; 208849b5e25fSSatish Balay 208949b5e25fSSatish Balay /* read in nonzero values */ 209087828ca2SBarry Smith ierr = PetscMalloc((nz+extra_rows)*sizeof(PetscScalar),&aa);CHKERRQ(ierr); 209149b5e25fSSatish Balay ierr = PetscBinaryRead(fd,aa,nz,PETSC_SCALAR);CHKERRQ(ierr); 209249b5e25fSSatish Balay for (i=0; i<extra_rows; i++) aa[nz+i] = 1.0; 209349b5e25fSSatish Balay 209449b5e25fSSatish Balay /* set "a" and "j" values into matrix */ 209549b5e25fSSatish Balay nzcount = 0; jcount = 0; 209649b5e25fSSatish Balay for (i=0; i<mbs; i++) { 209749b5e25fSSatish Balay nzcountb = nzcount; 209849b5e25fSSatish Balay nmask = 0; 209949b5e25fSSatish Balay for (j=0; j<bs; j++) { 210049b5e25fSSatish Balay kmax = rowlengths[i*bs+j]; 210149b5e25fSSatish Balay for (k=0; k<kmax; k++) { 21022d703238SHong Zhang tmp = jj[nzcount++]/bs; /* block col. index */ 210303630b6eSHong Zhang if (!mask[tmp] && tmp >= i) { masked[nmask++] = tmp; mask[tmp] = 1;} 21042d703238SHong Zhang } 21052d703238SHong Zhang } 21062d703238SHong Zhang /* sort the masked values */ 21072d703238SHong Zhang ierr = PetscSortInt(nmask,masked);CHKERRQ(ierr); 21082d703238SHong Zhang 21092d703238SHong Zhang /* set "j" values into matrix */ 21102d703238SHong Zhang maskcount = 1; 21112d703238SHong Zhang for (j=0; j<nmask; j++) { 211249b5e25fSSatish Balay a->j[jcount++] = masked[j]; 211349b5e25fSSatish Balay mask[masked[j]] = maskcount++; 211449b5e25fSSatish Balay } 2115574b2666SHong Zhang 211649b5e25fSSatish Balay /* set "a" values into matrix */ 211749b5e25fSSatish Balay ishift = bs2*a->i[i]; 211849b5e25fSSatish Balay for (j=0; j<bs; j++) { 211949b5e25fSSatish Balay kmax = rowlengths[i*bs+j]; 212049b5e25fSSatish Balay for (k=0; k<kmax; k++) { 2121574b2666SHong Zhang tmp = jj[nzcountb]/bs ; /* block col. index */ 2122574b2666SHong Zhang if (tmp >= i){ 212349b5e25fSSatish Balay block = mask[tmp] - 1; 212449b5e25fSSatish Balay point = jj[nzcountb] - bs*tmp; 212549b5e25fSSatish Balay idx = ishift + bs2*block + j + bs*point; 2126574b2666SHong Zhang a->a[idx] = aa[nzcountb]; 2127574b2666SHong Zhang } 2128574b2666SHong Zhang nzcountb++; 212949b5e25fSSatish Balay } 213049b5e25fSSatish Balay } 213149b5e25fSSatish Balay /* zero out the mask elements we set */ 213249b5e25fSSatish Balay for (j=0; j<nmask; j++) mask[masked[j]] = 0; 213349b5e25fSSatish Balay } 21346c6c5352SBarry Smith if (jcount != a->nz) SETERRQ(PETSC_ERR_FILE_UNEXPECTED,"Bad binary matrix"); 213549b5e25fSSatish Balay 213649b5e25fSSatish Balay ierr = PetscFree(rowlengths);CHKERRQ(ierr); 2137574b2666SHong Zhang ierr = PetscFree(s_browlengths);CHKERRQ(ierr); 213849b5e25fSSatish Balay ierr = PetscFree(aa);CHKERRQ(ierr); 213949b5e25fSSatish Balay ierr = PetscFree(jj);CHKERRQ(ierr); 214049b5e25fSSatish Balay ierr = PetscFree(mask);CHKERRQ(ierr); 214149b5e25fSSatish Balay 21429abb65ffSKris Buschelman ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 21439abb65ffSKris Buschelman ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 214449b5e25fSSatish Balay ierr = MatView_Private(B);CHKERRQ(ierr); 21459abb65ffSKris Buschelman *A = B; 214649b5e25fSSatish Balay PetscFunctionReturn(0); 214749b5e25fSSatish Balay } 2148574b2666SHong Zhang 2149*0def2e27SBarry Smith 2150*0def2e27SBarry Smith 2151d06b337dSHong Zhang #undef __FUNCT__ 2152d06b337dSHong Zhang #define __FUNCT__ "MatRelax_SeqSBAIJ" 215313f74950SBarry Smith PetscErrorCode MatRelax_SeqSBAIJ(Mat A,Vec bb,PetscReal omega,MatSORType flag,PetscReal fshift,PetscInt its,PetscInt lits,Vec xx) 2154d06b337dSHong Zhang { 2155d06b337dSHong Zhang Mat_SeqSBAIJ *a = (Mat_SeqSBAIJ*)A->data; 2156061b2667SBarry Smith const MatScalar *aa=a->a,*v,*v1; 2157d06b337dSHong Zhang PetscScalar *x,*b,*t,sum,d; 2158061b2667SBarry Smith MatScalar tmp; 21596849ba73SBarry Smith PetscErrorCode ierr; 2160061b2667SBarry Smith PetscInt m=a->mbs,bs=A->rmap->bs,j; 2161061b2667SBarry Smith const PetscInt *ai=a->i,*aj=a->j,*vj,*vj1; 2162061b2667SBarry Smith PetscInt nz,nz1,i; 2163d06b337dSHong Zhang 2164d06b337dSHong Zhang PetscFunctionBegin; 216551f519a2SBarry Smith if (flag & SOR_EISENSTAT) SETERRQ(PETSC_ERR_SUP,"No support yet for Eisenstat"); 216651f519a2SBarry Smith 2167b965ef7fSBarry Smith its = its*lits; 216877431f27SBarry Smith if (its <= 0) SETERRQ2(PETSC_ERR_ARG_WRONG,"Relaxation requires global its %D and local its %D both positive",its,lits); 2169d06b337dSHong Zhang 2170061b2667SBarry Smith if (bs > 1) SETERRQ(PETSC_ERR_SUP,"SSOR for block size > 1 is not yet implemented"); 2171d06b337dSHong Zhang 21721ebc52fbSHong Zhang ierr = VecGetArray(xx,&x);CHKERRQ(ierr); 2173d06b337dSHong Zhang if (xx != bb) { 21741ebc52fbSHong Zhang ierr = VecGetArray(bb,&b);CHKERRQ(ierr); 2175d06b337dSHong Zhang } else { 2176d06b337dSHong Zhang b = x; 2177d06b337dSHong Zhang } 2178d06b337dSHong Zhang 2179061b2667SBarry Smith if (!a->idiagvalid) { 2180061b2667SBarry Smith if (!a->idiag) { 2181061b2667SBarry Smith ierr = PetscMalloc(m*sizeof(PetscScalar),&a->idiag);CHKERRQ(ierr); 2182061b2667SBarry Smith } 2183061b2667SBarry Smith for (i=0; i<a->mbs; i++) a->idiag[i] = 1.0/a->a[a->i[i]]; 2184061b2667SBarry Smith a->idiagvalid = PETSC_TRUE; 2185061b2667SBarry Smith } 2186061b2667SBarry Smith 2187e2ee2a47SBarry Smith if (!a->relax_work) { 2188e2ee2a47SBarry Smith ierr = PetscMalloc(m*sizeof(PetscScalar),&a->relax_work);CHKERRQ(ierr); 2189e2ee2a47SBarry Smith } 2190e2ee2a47SBarry Smith t = a->relax_work; 2191d06b337dSHong Zhang 2192061b2667SBarry Smith 2193d06b337dSHong Zhang if (flag & SOR_ZERO_INITIAL_GUESS) { 21942798e883SHong Zhang if (flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP){ 2195290bbb0aSBarry Smith ierr = PetscMemcpy(t,b,m*sizeof(PetscScalar));CHKERRQ(ierr); 2196d06b337dSHong Zhang 2197d06b337dSHong Zhang for (i=0; i<m; i++){ 2198d06b337dSHong Zhang v = aa + ai[i] + 1; 2199d06b337dSHong Zhang vj = aj + ai[i] + 1; 2200d06b337dSHong Zhang nz = ai[i+1] - ai[i] - 1; 2201061b2667SBarry Smith x[i] = tmp = omega*t[i]*a->idiag[i]; 2202061b2667SBarry Smith for (j=0; j<nz; j++) { 2203061b2667SBarry Smith t[vj[j]] -= tmp*v[j]; 2204d06b337dSHong Zhang } 2205d06b337dSHong Zhang } 2206061b2667SBarry Smith ierr = PetscLogFlops(2*a->nz);CHKERRQ(ierr); 2207061b2667SBarry Smith } 2208d06b337dSHong Zhang 22092798e883SHong Zhang if (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP){ 221095d750ceSBarry Smith if (!(flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP)){ 221195d750ceSBarry Smith t = b; 2212d06b337dSHong Zhang } 221395d750ceSBarry Smith 2214d06b337dSHong Zhang for (i=m-1; i>=0; i--){ 2215d06b337dSHong Zhang v = aa + ai[i] + 1; 2216d06b337dSHong Zhang vj = aj + ai[i] + 1; 2217d06b337dSHong Zhang nz = ai[i+1] - ai[i] - 1; 2218d06b337dSHong Zhang sum = t[i]; 2219061b2667SBarry Smith PetscSparseDenseMinusDot(sum,x,v,vj,nz); 2220061b2667SBarry Smith x[i] = (1-omega)*x[i] + omega*sum*a->idiag[i]; 2221d06b337dSHong Zhang } 222295d750ceSBarry Smith t = a->relax_work; 2223061b2667SBarry Smith ierr = PetscLogFlops(2*a->nz);CHKERRQ(ierr); 2224d06b337dSHong Zhang } 2225d06b337dSHong Zhang its--; 2226d06b337dSHong Zhang } 2227d06b337dSHong Zhang 2228d06b337dSHong Zhang while (its--) { 222944706875SHong Zhang /* 223044706875SHong Zhang forward sweep: 223144706875SHong Zhang for i=0,...,m-1: 223244706875SHong Zhang sum[i] = (b[i] - U(i,:)x )/d[i]; 223344706875SHong Zhang x[i] = (1-omega)x[i] + omega*sum[i]; 223444706875SHong Zhang b = b - x[i]*U^T(i,:); 2235d06b337dSHong Zhang 223644706875SHong Zhang */ 22372798e883SHong Zhang if (flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP){ 2238290bbb0aSBarry Smith ierr = PetscMemcpy(t,b,m*sizeof(PetscScalar));CHKERRQ(ierr); 2239d06b337dSHong Zhang 2240d06b337dSHong Zhang for (i=0; i<m; i++){ 224144706875SHong Zhang d = *(aa + ai[i]); /* diag[i] */ 2242d06b337dSHong Zhang v = aa + ai[i] + 1; v1=v; 2243d06b337dSHong Zhang vj = aj + ai[i] + 1; vj1=vj; 2244d06b337dSHong Zhang nz = ai[i+1] - ai[i] - 1; nz1=nz; 2245d06b337dSHong Zhang sum = t[i]; 2246dc0b31edSSatish Balay ierr = PetscLogFlops(4.0*nz-2);CHKERRQ(ierr); 2247d06b337dSHong Zhang while (nz1--) sum -= (*v1++)*x[*vj1++]; 2248d06b337dSHong Zhang x[i] = (1-omega)*x[i] + omega*sum/d; 2249d06b337dSHong Zhang while (nz--) t[*vj++] -= x[i]*(*v++); 2250d06b337dSHong Zhang } 2251d06b337dSHong Zhang } 2252d06b337dSHong Zhang 22532798e883SHong Zhang if (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP){ 225444706875SHong Zhang /* 225544706875SHong Zhang backward sweep: 225644706875SHong Zhang b = b - x[i]*U^T(i,:), i=0,...,n-2 225744706875SHong Zhang for i=m-1,...,0: 225844706875SHong Zhang sum[i] = (b[i] - U(i,:)x )/d[i]; 225944706875SHong Zhang x[i] = (1-omega)x[i] + omega*sum[i]; 226044706875SHong Zhang */ 226195d750ceSBarry Smith /* if there was a forward sweep done above then I thing the next two for loops are not needed */ 2262290bbb0aSBarry Smith ierr = PetscMemcpy(t,b,m*sizeof(PetscScalar));CHKERRQ(ierr); 2263d06b337dSHong Zhang 2264d06b337dSHong Zhang for (i=0; i<m-1; i++){ /* update rhs */ 2265d06b337dSHong Zhang v = aa + ai[i] + 1; 2266d06b337dSHong Zhang vj = aj + ai[i] + 1; 2267d06b337dSHong Zhang nz = ai[i+1] - ai[i] - 1; 2268dc0b31edSSatish Balay ierr = PetscLogFlops(2.0*nz-1);CHKERRQ(ierr); 2269e6b907acSBarry Smith while (nz--) t[*vj++] -= x[i]*(*v++); 2270d06b337dSHong Zhang } 2271d06b337dSHong Zhang for (i=m-1; i>=0; i--){ 2272d06b337dSHong Zhang d = *(aa + ai[i]); 2273d06b337dSHong Zhang v = aa + ai[i] + 1; 2274d06b337dSHong Zhang vj = aj + ai[i] + 1; 2275d06b337dSHong Zhang nz = ai[i+1] - ai[i] - 1; 2276dc0b31edSSatish Balay ierr = PetscLogFlops(2.0*nz-1);CHKERRQ(ierr); 2277d06b337dSHong Zhang sum = t[i]; 2278d06b337dSHong Zhang while (nz--) sum -= x[*vj++]*(*v++); 2279d06b337dSHong Zhang x[i] = (1-omega)*x[i] + omega*sum/d; 2280d06b337dSHong Zhang } 2281d06b337dSHong Zhang } 2282d06b337dSHong Zhang } 2283d06b337dSHong Zhang 22841ebc52fbSHong Zhang ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr); 2285d06b337dSHong Zhang if (bb != xx) { 22861ebc52fbSHong Zhang ierr = VecRestoreArray(bb,&b);CHKERRQ(ierr); 2287d06b337dSHong Zhang } 2288d06b337dSHong Zhang PetscFunctionReturn(0); 2289d06b337dSHong Zhang } 2290d06b337dSHong Zhang 2291c75a6043SHong Zhang #undef __FUNCT__ 2292c75a6043SHong Zhang #define __FUNCT__ "MatCreateSeqSBAIJWithArrays" 2293c75a6043SHong Zhang /*@ 2294c75a6043SHong Zhang MatCreateSeqSBAIJWithArrays - Creates an sequential SBAIJ matrix using matrix elements 2295c75a6043SHong Zhang (upper triangular entries in CSR format) provided by the user. 2296c75a6043SHong Zhang 2297c75a6043SHong Zhang Collective on MPI_Comm 2298c75a6043SHong Zhang 2299c75a6043SHong Zhang Input Parameters: 2300c75a6043SHong Zhang + comm - must be an MPI communicator of size 1 2301c75a6043SHong Zhang . bs - size of block 2302c75a6043SHong Zhang . m - number of rows 2303c75a6043SHong Zhang . n - number of columns 2304c75a6043SHong Zhang . i - row indices 2305c75a6043SHong Zhang . j - column indices 2306c75a6043SHong Zhang - a - matrix values 2307c75a6043SHong Zhang 2308c75a6043SHong Zhang Output Parameter: 2309c75a6043SHong Zhang . mat - the matrix 2310c75a6043SHong Zhang 2311c75a6043SHong Zhang Level: intermediate 2312c75a6043SHong Zhang 2313c75a6043SHong Zhang Notes: 2314c75a6043SHong Zhang The i, j, and a arrays are not copied by this routine, the user must free these arrays 2315c75a6043SHong Zhang once the matrix is destroyed 2316c75a6043SHong Zhang 2317c75a6043SHong Zhang You cannot set new nonzero locations into this matrix, that will generate an error. 2318c75a6043SHong Zhang 2319c75a6043SHong Zhang The i and j indices are 0 based 2320c75a6043SHong Zhang 2321c75a6043SHong Zhang .seealso: MatCreate(), MatCreateMPISBAIJ(), MatCreateSeqSBAIJ() 2322c75a6043SHong Zhang 2323c75a6043SHong Zhang @*/ 2324c75a6043SHong Zhang PetscErrorCode PETSCMAT_DLLEXPORT MatCreateSeqSBAIJWithArrays(MPI_Comm comm,PetscInt bs,PetscInt m,PetscInt n,PetscInt* i,PetscInt*j,PetscScalar *a,Mat *mat) 2325c75a6043SHong Zhang { 2326c75a6043SHong Zhang PetscErrorCode ierr; 2327c75a6043SHong Zhang PetscInt ii; 2328c75a6043SHong Zhang Mat_SeqSBAIJ *sbaij; 2329c75a6043SHong Zhang 2330c75a6043SHong Zhang PetscFunctionBegin; 2331c75a6043SHong Zhang if (bs != 1) SETERRQ1(PETSC_ERR_SUP,"block size %D > 1 is not supported yet",bs); 2332c75a6043SHong Zhang if (i[0]) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"i (row indices) must start with 0"); 2333c75a6043SHong Zhang 2334c75a6043SHong Zhang ierr = MatCreate(comm,mat);CHKERRQ(ierr); 2335c75a6043SHong Zhang ierr = MatSetSizes(*mat,m,n,m,n);CHKERRQ(ierr); 2336c75a6043SHong Zhang ierr = MatSetType(*mat,MATSEQSBAIJ);CHKERRQ(ierr); 2337c75a6043SHong Zhang ierr = MatSeqSBAIJSetPreallocation_SeqSBAIJ(*mat,bs,MAT_SKIP_ALLOCATION,0);CHKERRQ(ierr); 2338c75a6043SHong Zhang sbaij = (Mat_SeqSBAIJ*)(*mat)->data; 2339c75a6043SHong Zhang ierr = PetscMalloc2(m,PetscInt,&sbaij->imax,m,PetscInt,&sbaij->ilen);CHKERRQ(ierr); 2340c75a6043SHong Zhang 2341c75a6043SHong Zhang sbaij->i = i; 2342c75a6043SHong Zhang sbaij->j = j; 2343c75a6043SHong Zhang sbaij->a = a; 2344c75a6043SHong Zhang sbaij->singlemalloc = PETSC_FALSE; 2345c75a6043SHong Zhang sbaij->nonew = -1; /*this indicates that inserting a new value in the matrix that generates a new nonzero is an error*/ 2346e6b907acSBarry Smith sbaij->free_a = PETSC_FALSE; 2347e6b907acSBarry Smith sbaij->free_ij = PETSC_FALSE; 2348c75a6043SHong Zhang 2349c75a6043SHong Zhang for (ii=0; ii<m; ii++) { 2350c75a6043SHong Zhang sbaij->ilen[ii] = sbaij->imax[ii] = i[ii+1] - i[ii]; 2351c75a6043SHong Zhang #if defined(PETSC_USE_DEBUG) 2352c75a6043SHong Zhang if (i[ii+1] - i[ii] < 0) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"Negative row length in i (row indices) row = %d length = %d",ii,i[ii+1] - i[ii]); 2353c75a6043SHong Zhang #endif 2354c75a6043SHong Zhang } 2355c75a6043SHong Zhang #if defined(PETSC_USE_DEBUG) 2356c75a6043SHong Zhang for (ii=0; ii<sbaij->i[m]; ii++) { 2357c75a6043SHong Zhang if (j[ii] < 0) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"Negative column index at location = %d index = %d",ii,j[ii]); 2358c75a6043SHong Zhang if (j[ii] > n - 1) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"Column index to large at location = %d index = %d",ii,j[ii]); 2359c75a6043SHong Zhang } 2360c75a6043SHong Zhang #endif 2361c75a6043SHong Zhang 2362c75a6043SHong Zhang ierr = MatAssemblyBegin(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2363c75a6043SHong Zhang ierr = MatAssemblyEnd(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2364c75a6043SHong Zhang PetscFunctionReturn(0); 2365c75a6043SHong Zhang } 2366d06b337dSHong Zhang 2367d06b337dSHong Zhang 2368d06b337dSHong Zhang 236949b5e25fSSatish Balay 237049b5e25fSSatish Balay 2371