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 */ 79e070d67SMatthew Knepley #include "src/mat/impls/baij/seq/baij.h" /*I "petscmat.h" I*/ 849b5e25fSSatish Balay #include "src/inline/spops.h" 9aec82049SSatish Balay #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);} 12705b42c5fSBarry Smith ierr = PetscFree(a->diag);CHKERRQ(ierr); 12805b42c5fSBarry Smith ierr = PetscFree2(a->imax,a->ilen);CHKERRQ(ierr); 12905b42c5fSBarry Smith ierr = PetscFree(a->solve_work);CHKERRQ(ierr); 130e2ee2a47SBarry Smith ierr = PetscFree(a->relax_work);CHKERRQ(ierr); 13105b42c5fSBarry Smith ierr = PetscFree(a->solves_work);CHKERRQ(ierr); 13205b42c5fSBarry Smith ierr = PetscFree(a->mult_work);CHKERRQ(ierr); 13305b42c5fSBarry Smith ierr = PetscFree(a->saved_values);CHKERRQ(ierr); 13405b42c5fSBarry Smith ierr = PetscFree(a->xtoy);CHKERRQ(ierr); 1351a3463dfSHong Zhang 1361a3463dfSHong Zhang ierr = PetscFree(a->inew);CHKERRQ(ierr); 13749b5e25fSSatish Balay ierr = PetscFree(a);CHKERRQ(ierr); 138901853e0SKris Buschelman 139dbd8c25aSHong Zhang ierr = PetscObjectChangeTypeName((PetscObject)A,0);CHKERRQ(ierr); 140901853e0SKris Buschelman ierr = PetscObjectComposeFunction((PetscObject)A,"MatStoreValues_C","",PETSC_NULL);CHKERRQ(ierr); 141901853e0SKris Buschelman ierr = PetscObjectComposeFunction((PetscObject)A,"MatRetrieveValues_C","",PETSC_NULL);CHKERRQ(ierr); 142901853e0SKris Buschelman ierr = PetscObjectComposeFunction((PetscObject)A,"MatSeqSBAIJSetColumnIndices_C","",PETSC_NULL);CHKERRQ(ierr); 143901853e0SKris Buschelman ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqsbaij_seqaij_C","",PETSC_NULL);CHKERRQ(ierr); 144901853e0SKris Buschelman ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqsbaij_seqbaij_C","",PETSC_NULL);CHKERRQ(ierr); 145901853e0SKris Buschelman ierr = PetscObjectComposeFunction((PetscObject)A,"MatSeqSBAIJSetPreallocation_C","",PETSC_NULL);CHKERRQ(ierr); 14649b5e25fSSatish Balay PetscFunctionReturn(0); 14749b5e25fSSatish Balay } 14849b5e25fSSatish Balay 1494a2ae208SSatish Balay #undef __FUNCT__ 1504a2ae208SSatish Balay #define __FUNCT__ "MatSetOption_SeqSBAIJ" 1514e0d8c25SBarry Smith PetscErrorCode MatSetOption_SeqSBAIJ(Mat A,MatOption op,PetscTruth flg) 15249b5e25fSSatish Balay { 153045c9aa0SHong Zhang Mat_SeqSBAIJ *a = (Mat_SeqSBAIJ*)A->data; 15463ba0a88SBarry Smith PetscErrorCode ierr; 15549b5e25fSSatish Balay 15649b5e25fSSatish Balay PetscFunctionBegin; 1574d9d31abSKris Buschelman switch (op) { 1584d9d31abSKris Buschelman case MAT_ROW_ORIENTED: 1594e0d8c25SBarry Smith a->roworiented = flg; 1604d9d31abSKris Buschelman break; 1614d9d31abSKris Buschelman case MAT_KEEP_ZEROED_ROWS: 1624e0d8c25SBarry Smith a->keepzeroedrows = flg; 1634d9d31abSKris Buschelman break; 164512a5fc5SBarry Smith case MAT_NEW_NONZERO_LOCATIONS: 165512a5fc5SBarry Smith a->nonew = (flg ? 0 : 1); 1664d9d31abSKris Buschelman break; 1674d9d31abSKris Buschelman case MAT_NEW_NONZERO_LOCATION_ERR: 1684e0d8c25SBarry Smith a->nonew = (flg ? -1 : 0); 1694d9d31abSKris Buschelman break; 1704d9d31abSKris Buschelman case MAT_NEW_NONZERO_ALLOCATION_ERR: 1714e0d8c25SBarry Smith a->nonew = (flg ? -2 : 0); 1724d9d31abSKris Buschelman break; 1734e0d8c25SBarry Smith case MAT_NEW_DIAGONALS: 1744d9d31abSKris Buschelman case MAT_IGNORE_OFF_PROC_ENTRIES: 1754d9d31abSKris Buschelman case MAT_USE_HASH_TABLE: 176290bbb0aSBarry Smith ierr = PetscInfo1(A,"Option %s ignored\n",MatOptions[op]);CHKERRQ(ierr); 1774d9d31abSKris Buschelman break; 1789a4540c5SBarry Smith case MAT_HERMITIAN: 1794e0d8c25SBarry Smith if (flg) SETERRQ(PETSC_ERR_SUP,"Matrix must be symmetric"); 18077e54ba9SKris Buschelman case MAT_SYMMETRIC: 18177e54ba9SKris Buschelman case MAT_STRUCTURALLY_SYMMETRIC: 1829a4540c5SBarry Smith case MAT_SYMMETRY_ETERNAL: 1834e0d8c25SBarry Smith if (!flg) SETERRQ(PETSC_ERR_SUP,"Matrix must be symmetric"); 184290bbb0aSBarry Smith ierr = PetscInfo1(A,"Option %s not relevent\n",MatOptions[op]);CHKERRQ(ierr); 185290bbb0aSBarry Smith break; 186941593c8SHong Zhang case MAT_IGNORE_LOWER_TRIANGULAR: 1874e0d8c25SBarry Smith a->ignore_ltriangular = flg; 188941593c8SHong Zhang break; 189941593c8SHong Zhang case MAT_ERROR_LOWER_TRIANGULAR: 1904e0d8c25SBarry Smith a->ignore_ltriangular = flg; 19177e54ba9SKris Buschelman break; 192f5edf698SHong Zhang case MAT_GETROW_UPPERTRIANGULAR: 1934e0d8c25SBarry Smith a->getrow_utriangular = flg; 194f5edf698SHong Zhang break; 1954d9d31abSKris Buschelman default: 196ad86a440SBarry Smith SETERRQ1(PETSC_ERR_SUP,"unknown option %d",op); 19749b5e25fSSatish Balay } 19849b5e25fSSatish Balay PetscFunctionReturn(0); 19949b5e25fSSatish Balay } 20049b5e25fSSatish Balay 2014a2ae208SSatish Balay #undef __FUNCT__ 2024a2ae208SSatish Balay #define __FUNCT__ "MatGetRow_SeqSBAIJ" 20313f74950SBarry Smith PetscErrorCode MatGetRow_SeqSBAIJ(Mat A,PetscInt row,PetscInt *ncols,PetscInt **cols,PetscScalar **v) 20449b5e25fSSatish Balay { 20549b5e25fSSatish Balay Mat_SeqSBAIJ *a = (Mat_SeqSBAIJ*)A->data; 2066849ba73SBarry Smith PetscErrorCode ierr; 20713f74950SBarry Smith PetscInt itmp,i,j,k,M,*ai,*aj,bs,bn,bp,*cols_i,bs2; 20849b5e25fSSatish Balay MatScalar *aa,*aa_i; 20987828ca2SBarry Smith PetscScalar *v_i; 21049b5e25fSSatish Balay 21149b5e25fSSatish Balay PetscFunctionBegin; 2124e0d8c25SBarry 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()"); 213f5edf698SHong Zhang /* Get the upper triangular part of the row */ 214d0f46423SBarry Smith bs = A->rmap->bs; 21549b5e25fSSatish Balay ai = a->i; 21649b5e25fSSatish Balay aj = a->j; 21749b5e25fSSatish Balay aa = a->a; 21849b5e25fSSatish Balay bs2 = a->bs2; 21949b5e25fSSatish Balay 220d0f46423SBarry Smith if (row < 0 || row >= A->rmap->N) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE, "Row %D out of range", row); 22149b5e25fSSatish Balay 22249b5e25fSSatish Balay bn = row/bs; /* Block number */ 22349b5e25fSSatish Balay bp = row % bs; /* Block position */ 22449b5e25fSSatish Balay M = ai[bn+1] - ai[bn]; 22549b5e25fSSatish Balay *ncols = bs*M; 22649b5e25fSSatish Balay 22749b5e25fSSatish Balay if (v) { 22849b5e25fSSatish Balay *v = 0; 22949b5e25fSSatish Balay if (*ncols) { 23087828ca2SBarry Smith ierr = PetscMalloc((*ncols+row)*sizeof(PetscScalar),v);CHKERRQ(ierr); 23149b5e25fSSatish Balay for (i=0; i<M; i++) { /* for each block in the block row */ 23249b5e25fSSatish Balay v_i = *v + i*bs; 23349b5e25fSSatish Balay aa_i = aa + bs2*(ai[bn] + i); 23449b5e25fSSatish Balay for (j=bp,k=0; j<bs2; j+=bs,k++) {v_i[k] = aa_i[j];} 23549b5e25fSSatish Balay } 23649b5e25fSSatish Balay } 23749b5e25fSSatish Balay } 23849b5e25fSSatish Balay 23949b5e25fSSatish Balay if (cols) { 24049b5e25fSSatish Balay *cols = 0; 24149b5e25fSSatish Balay if (*ncols) { 24213f74950SBarry Smith ierr = PetscMalloc((*ncols+row)*sizeof(PetscInt),cols);CHKERRQ(ierr); 24349b5e25fSSatish Balay for (i=0; i<M; i++) { /* for each block in the block row */ 24449b5e25fSSatish Balay cols_i = *cols + i*bs; 24549b5e25fSSatish Balay itmp = bs*aj[ai[bn] + i]; 24649b5e25fSSatish Balay for (j=0; j<bs; j++) {cols_i[j] = itmp++;} 24749b5e25fSSatish Balay } 24849b5e25fSSatish Balay } 24949b5e25fSSatish Balay } 25049b5e25fSSatish Balay 25149b5e25fSSatish Balay /*search column A(0:row-1,row) (=A(row,0:row-1)). Could be expensive! */ 2525ddb2528SHong Zhang /* this segment is currently removed, so only entries in the upper triangle are obtained */ 2535ddb2528SHong Zhang #ifdef column_search 25449b5e25fSSatish Balay v_i = *v + M*bs; 25549b5e25fSSatish Balay cols_i = *cols + M*bs; 25649b5e25fSSatish Balay for (i=0; i<bn; i++){ /* for each block row */ 25749b5e25fSSatish Balay M = ai[i+1] - ai[i]; 25849b5e25fSSatish Balay for (j=0; j<M; j++){ 25949b5e25fSSatish Balay itmp = aj[ai[i] + j]; /* block column value */ 26049b5e25fSSatish Balay if (itmp == bn){ 26149b5e25fSSatish Balay aa_i = aa + bs2*(ai[i] + j) + bs*bp; 26249b5e25fSSatish Balay for (k=0; k<bs; k++) { 26349b5e25fSSatish Balay *cols_i++ = i*bs+k; 26449b5e25fSSatish Balay *v_i++ = aa_i[k]; 26549b5e25fSSatish Balay } 26649b5e25fSSatish Balay *ncols += bs; 26749b5e25fSSatish Balay break; 26849b5e25fSSatish Balay } 26949b5e25fSSatish Balay } 27049b5e25fSSatish Balay } 2715ddb2528SHong Zhang #endif 27249b5e25fSSatish Balay PetscFunctionReturn(0); 27349b5e25fSSatish Balay } 27449b5e25fSSatish Balay 2754a2ae208SSatish Balay #undef __FUNCT__ 2764a2ae208SSatish Balay #define __FUNCT__ "MatRestoreRow_SeqSBAIJ" 27713f74950SBarry Smith PetscErrorCode MatRestoreRow_SeqSBAIJ(Mat A,PetscInt row,PetscInt *nz,PetscInt **idx,PetscScalar **v) 27849b5e25fSSatish Balay { 279dfbe8321SBarry Smith PetscErrorCode ierr; 28049b5e25fSSatish Balay 28149b5e25fSSatish Balay PetscFunctionBegin; 28205b42c5fSBarry Smith if (idx) {ierr = PetscFree(*idx);CHKERRQ(ierr);} 28305b42c5fSBarry Smith if (v) {ierr = PetscFree(*v);CHKERRQ(ierr);} 28449b5e25fSSatish Balay PetscFunctionReturn(0); 28549b5e25fSSatish Balay } 28649b5e25fSSatish Balay 2874a2ae208SSatish Balay #undef __FUNCT__ 288f5edf698SHong Zhang #define __FUNCT__ "MatGetRowUpperTriangular_SeqSBAIJ" 289f5edf698SHong Zhang PetscErrorCode MatGetRowUpperTriangular_SeqSBAIJ(Mat A) 290f5edf698SHong Zhang { 291f5edf698SHong Zhang Mat_SeqSBAIJ *a = (Mat_SeqSBAIJ*)A->data; 292f5edf698SHong Zhang 293f5edf698SHong Zhang PetscFunctionBegin; 294f5edf698SHong Zhang a->getrow_utriangular = PETSC_TRUE; 295f5edf698SHong Zhang PetscFunctionReturn(0); 296f5edf698SHong Zhang } 297f5edf698SHong Zhang #undef __FUNCT__ 298f5edf698SHong Zhang #define __FUNCT__ "MatRestoreRowUpperTriangular_SeqSBAIJ" 299f5edf698SHong Zhang PetscErrorCode MatRestoreRowUpperTriangular_SeqSBAIJ(Mat A) 300f5edf698SHong Zhang { 301f5edf698SHong Zhang Mat_SeqSBAIJ *a = (Mat_SeqSBAIJ*)A->data; 302f5edf698SHong Zhang 303f5edf698SHong Zhang PetscFunctionBegin; 304f5edf698SHong Zhang a->getrow_utriangular = PETSC_FALSE; 305f5edf698SHong Zhang PetscFunctionReturn(0); 306f5edf698SHong Zhang } 307f5edf698SHong Zhang 308f5edf698SHong Zhang #undef __FUNCT__ 3094a2ae208SSatish Balay #define __FUNCT__ "MatTranspose_SeqSBAIJ" 310fc4dec0aSBarry Smith PetscErrorCode MatTranspose_SeqSBAIJ(Mat A,MatReuse reuse,Mat *B) 31149b5e25fSSatish Balay { 312dfbe8321SBarry Smith PetscErrorCode ierr; 31349b5e25fSSatish Balay PetscFunctionBegin; 314815cbec1SBarry Smith if (reuse == MAT_INITIAL_MATRIX || *B != A) { 315999d9058SBarry Smith ierr = MatDuplicate(A,MAT_COPY_VALUES,B);CHKERRQ(ierr); 316fc4dec0aSBarry Smith } 3178115998fSBarry Smith PetscFunctionReturn(0); 31849b5e25fSSatish Balay } 31949b5e25fSSatish Balay 3204a2ae208SSatish Balay #undef __FUNCT__ 3214a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqSBAIJ_ASCII" 3226849ba73SBarry Smith static PetscErrorCode MatView_SeqSBAIJ_ASCII(Mat A,PetscViewer viewer) 32349b5e25fSSatish Balay { 32449b5e25fSSatish Balay Mat_SeqSBAIJ *a = (Mat_SeqSBAIJ*)A->data; 325dfbe8321SBarry Smith PetscErrorCode ierr; 326d0f46423SBarry Smith PetscInt i,j,bs = A->rmap->bs,k,l,bs2=a->bs2; 3272dcb1b2aSMatthew Knepley const char *name; 328f3ef73ceSBarry Smith PetscViewerFormat format; 32949b5e25fSSatish Balay 33049b5e25fSSatish Balay PetscFunctionBegin; 33180fe4e49SBarry Smith ierr = PetscObjectGetName((PetscObject)A,&name);CHKERRQ(ierr); 332b0a32e0cSBarry Smith ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr); 333456192e2SBarry Smith if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) { 33477431f27SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," block size is %D\n",bs);CHKERRQ(ierr); 335fb9695e5SSatish Balay } else if (format == PETSC_VIEWER_ASCII_MATLAB) { 336d2507d54SMatthew Knepley Mat aij; 337d2507d54SMatthew Knepley 33870d5e725SHong Zhang if (A->factor && bs>1){ 33970d5e725SHong 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); 34070d5e725SHong Zhang PetscFunctionReturn(0); 34170d5e725SHong Zhang } 342c9f458caSMatthew Knepley ierr = MatConvert(A,MATSEQAIJ,MAT_INITIAL_MATRIX,&aij);CHKERRQ(ierr); 343c9f458caSMatthew Knepley ierr = MatView(aij,viewer);CHKERRQ(ierr); 344c9f458caSMatthew Knepley ierr = MatDestroy(aij);CHKERRQ(ierr); 345fb9695e5SSatish Balay } else if (format == PETSC_VIEWER_ASCII_COMMON) { 346b0a32e0cSBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_NO);CHKERRQ(ierr); 34749b5e25fSSatish Balay for (i=0; i<a->mbs; i++) { 34849b5e25fSSatish Balay for (j=0; j<bs; j++) { 34977431f27SBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"row %D:",i*bs+j);CHKERRQ(ierr); 35049b5e25fSSatish Balay for (k=a->i[i]; k<a->i[i+1]; k++) { 35149b5e25fSSatish Balay for (l=0; l<bs; l++) { 35249b5e25fSSatish Balay #if defined(PETSC_USE_COMPLEX) 35349b5e25fSSatish Balay if (PetscImaginaryPart(a->a[bs2*k + l*bs + j]) > 0.0 && PetscRealPart(a->a[bs2*k + l*bs + j]) != 0.0) { 354a83599f4SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %G + %G i) ",bs*a->j[k]+l, 35549b5e25fSSatish Balay PetscRealPart(a->a[bs2*k + l*bs + j]),PetscImaginaryPart(a->a[bs2*k + l*bs + j]));CHKERRQ(ierr); 35649b5e25fSSatish Balay } else if (PetscImaginaryPart(a->a[bs2*k + l*bs + j]) < 0.0 && PetscRealPart(a->a[bs2*k + l*bs + j]) != 0.0) { 357a83599f4SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %G - %G i) ",bs*a->j[k]+l, 35849b5e25fSSatish Balay PetscRealPart(a->a[bs2*k + l*bs + j]),-PetscImaginaryPart(a->a[bs2*k + l*bs + j]));CHKERRQ(ierr); 35949b5e25fSSatish Balay } else if (PetscRealPart(a->a[bs2*k + l*bs + j]) != 0.0) { 360a83599f4SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %G) ",bs*a->j[k]+l,PetscRealPart(a->a[bs2*k + l*bs + j]));CHKERRQ(ierr); 36149b5e25fSSatish Balay } 36249b5e25fSSatish Balay #else 36349b5e25fSSatish Balay if (a->a[bs2*k + l*bs + j] != 0.0) { 364a83599f4SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %G) ",bs*a->j[k]+l,a->a[bs2*k + l*bs + j]);CHKERRQ(ierr); 36549b5e25fSSatish Balay } 36649b5e25fSSatish Balay #endif 36749b5e25fSSatish Balay } 36849b5e25fSSatish Balay } 369b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 37049b5e25fSSatish Balay } 37149b5e25fSSatish Balay } 372b0a32e0cSBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_YES);CHKERRQ(ierr); 373c1490034SHong Zhang } else if (format == PETSC_VIEWER_ASCII_FACTOR_INFO) { 374c1490034SHong Zhang PetscFunctionReturn(0); 37549b5e25fSSatish Balay } else { 3768608aa04SHong Zhang if (A->factor && bs>1){ 3778608aa04SHong Zhang ierr = PetscPrintf(PETSC_COMM_SELF,"Warning: matrix is factored. MatView_SeqSBAIJ_ASCII() may not display complete or logically correct entries!\n");CHKERRQ(ierr); 3788608aa04SHong Zhang } 379b0a32e0cSBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_NO);CHKERRQ(ierr); 38049b5e25fSSatish Balay for (i=0; i<a->mbs; i++) { 38149b5e25fSSatish Balay for (j=0; j<bs; j++) { 38277431f27SBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"row %D:",i*bs+j);CHKERRQ(ierr); 38349b5e25fSSatish Balay for (k=a->i[i]; k<a->i[i+1]; k++) { 38449b5e25fSSatish Balay for (l=0; l<bs; l++) { 38549b5e25fSSatish Balay #if defined(PETSC_USE_COMPLEX) 38649b5e25fSSatish Balay if (PetscImaginaryPart(a->a[bs2*k + l*bs + j]) > 0.0) { 387a83599f4SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %G + %G i) ",bs*a->j[k]+l, 38849b5e25fSSatish Balay PetscRealPart(a->a[bs2*k + l*bs + j]),PetscImaginaryPart(a->a[bs2*k + l*bs + j]));CHKERRQ(ierr); 38949b5e25fSSatish Balay } else if (PetscImaginaryPart(a->a[bs2*k + l*bs + j]) < 0.0) { 390a83599f4SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %G - %G i) ",bs*a->j[k]+l, 39149b5e25fSSatish Balay PetscRealPart(a->a[bs2*k + l*bs + j]),-PetscImaginaryPart(a->a[bs2*k + l*bs + j]));CHKERRQ(ierr); 39249b5e25fSSatish Balay } else { 393a83599f4SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %G) ",bs*a->j[k]+l,PetscRealPart(a->a[bs2*k + l*bs + j]));CHKERRQ(ierr); 39449b5e25fSSatish Balay } 39549b5e25fSSatish Balay #else 396e9f7bc9eSHong Zhang ierr = PetscViewerASCIIPrintf(viewer," (%D, %G) ",bs*a->j[k]+l,a->a[bs2*k + l*bs + j]);CHKERRQ(ierr); 39749b5e25fSSatish Balay #endif 39849b5e25fSSatish Balay } 39949b5e25fSSatish Balay } 400b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 40149b5e25fSSatish Balay } 40249b5e25fSSatish Balay } 403b0a32e0cSBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_YES);CHKERRQ(ierr); 40449b5e25fSSatish Balay } 405b0a32e0cSBarry Smith ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 40649b5e25fSSatish Balay PetscFunctionReturn(0); 40749b5e25fSSatish Balay } 40849b5e25fSSatish Balay 4094a2ae208SSatish Balay #undef __FUNCT__ 4104a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqSBAIJ_Draw_Zoom" 4116849ba73SBarry Smith static PetscErrorCode MatView_SeqSBAIJ_Draw_Zoom(PetscDraw draw,void *Aa) 41249b5e25fSSatish Balay { 41349b5e25fSSatish Balay Mat A = (Mat) Aa; 41449b5e25fSSatish Balay Mat_SeqSBAIJ *a=(Mat_SeqSBAIJ*)A->data; 4156849ba73SBarry Smith PetscErrorCode ierr; 416d0f46423SBarry Smith PetscInt row,i,j,k,l,mbs=a->mbs,color,bs=A->rmap->bs,bs2=a->bs2; 41713f74950SBarry Smith PetscMPIInt rank; 41849b5e25fSSatish Balay PetscReal xl,yl,xr,yr,x_l,x_r,y_l,y_r; 41949b5e25fSSatish Balay MatScalar *aa; 42049b5e25fSSatish Balay MPI_Comm comm; 421b0a32e0cSBarry Smith PetscViewer viewer; 42249b5e25fSSatish Balay 42349b5e25fSSatish Balay PetscFunctionBegin; 42449b5e25fSSatish Balay /* 42549b5e25fSSatish Balay This is nasty. If this is called from an originally parallel matrix 42649b5e25fSSatish Balay then all processes call this,but only the first has the matrix so the 42749b5e25fSSatish Balay rest should return immediately. 42849b5e25fSSatish Balay */ 42949b5e25fSSatish Balay ierr = PetscObjectGetComm((PetscObject)draw,&comm);CHKERRQ(ierr); 43049b5e25fSSatish Balay ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 43149b5e25fSSatish Balay if (rank) PetscFunctionReturn(0); 43249b5e25fSSatish Balay 43349b5e25fSSatish Balay ierr = PetscObjectQuery((PetscObject)A,"Zoomviewer",(PetscObject*)&viewer);CHKERRQ(ierr); 43449b5e25fSSatish Balay 435b0a32e0cSBarry Smith ierr = PetscDrawGetCoordinates(draw,&xl,&yl,&xr,&yr);CHKERRQ(ierr); 436b0a32e0cSBarry Smith PetscDrawString(draw, .3*(xl+xr), .3*(yl+yr), PETSC_DRAW_BLACK, "symmetric"); 43749b5e25fSSatish Balay 43849b5e25fSSatish Balay /* loop over matrix elements drawing boxes */ 439b0a32e0cSBarry Smith color = PETSC_DRAW_BLUE; 44049b5e25fSSatish Balay for (i=0,row=0; i<mbs; i++,row+=bs) { 44149b5e25fSSatish Balay for (j=a->i[i]; j<a->i[i+1]; j++) { 442d0f46423SBarry Smith y_l = A->rmap->N - row - 1.0; y_r = y_l + 1.0; 44349b5e25fSSatish Balay x_l = a->j[j]*bs; x_r = x_l + 1.0; 44449b5e25fSSatish Balay aa = a->a + j*bs2; 44549b5e25fSSatish Balay for (k=0; k<bs; k++) { 44649b5e25fSSatish Balay for (l=0; l<bs; l++) { 44749b5e25fSSatish Balay if (PetscRealPart(*aa++) >= 0.) continue; 448b0a32e0cSBarry Smith ierr = PetscDrawRectangle(draw,x_l+k,y_l-l,x_r+k,y_r-l,color,color,color,color);CHKERRQ(ierr); 44949b5e25fSSatish Balay } 45049b5e25fSSatish Balay } 45149b5e25fSSatish Balay } 45249b5e25fSSatish Balay } 453b0a32e0cSBarry Smith color = PETSC_DRAW_CYAN; 45449b5e25fSSatish Balay for (i=0,row=0; i<mbs; i++,row+=bs) { 45549b5e25fSSatish Balay for (j=a->i[i]; j<a->i[i+1]; j++) { 456d0f46423SBarry Smith y_l = A->rmap->N - row - 1.0; y_r = y_l + 1.0; 45749b5e25fSSatish Balay x_l = a->j[j]*bs; x_r = x_l + 1.0; 45849b5e25fSSatish Balay aa = a->a + j*bs2; 45949b5e25fSSatish Balay for (k=0; k<bs; k++) { 46049b5e25fSSatish Balay for (l=0; l<bs; l++) { 46149b5e25fSSatish Balay if (PetscRealPart(*aa++) != 0.) continue; 462b0a32e0cSBarry Smith ierr = PetscDrawRectangle(draw,x_l+k,y_l-l,x_r+k,y_r-l,color,color,color,color);CHKERRQ(ierr); 46349b5e25fSSatish Balay } 46449b5e25fSSatish Balay } 46549b5e25fSSatish Balay } 46649b5e25fSSatish Balay } 46749b5e25fSSatish Balay 468b0a32e0cSBarry Smith color = PETSC_DRAW_RED; 46949b5e25fSSatish Balay for (i=0,row=0; i<mbs; i++,row+=bs) { 47049b5e25fSSatish Balay for (j=a->i[i]; j<a->i[i+1]; j++) { 471d0f46423SBarry Smith y_l = A->rmap->N - row - 1.0; y_r = y_l + 1.0; 47249b5e25fSSatish Balay x_l = a->j[j]*bs; x_r = x_l + 1.0; 47349b5e25fSSatish Balay aa = a->a + j*bs2; 47449b5e25fSSatish Balay for (k=0; k<bs; k++) { 47549b5e25fSSatish Balay for (l=0; l<bs; l++) { 47649b5e25fSSatish Balay if (PetscRealPart(*aa++) <= 0.) continue; 477b0a32e0cSBarry Smith ierr = PetscDrawRectangle(draw,x_l+k,y_l-l,x_r+k,y_r-l,color,color,color,color);CHKERRQ(ierr); 47849b5e25fSSatish Balay } 47949b5e25fSSatish Balay } 48049b5e25fSSatish Balay } 48149b5e25fSSatish Balay } 48249b5e25fSSatish Balay PetscFunctionReturn(0); 48349b5e25fSSatish Balay } 48449b5e25fSSatish Balay 4854a2ae208SSatish Balay #undef __FUNCT__ 4864a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqSBAIJ_Draw" 4876849ba73SBarry Smith static PetscErrorCode MatView_SeqSBAIJ_Draw(Mat A,PetscViewer viewer) 48849b5e25fSSatish Balay { 489dfbe8321SBarry Smith PetscErrorCode ierr; 49049b5e25fSSatish Balay PetscReal xl,yl,xr,yr,w,h; 491b0a32e0cSBarry Smith PetscDraw draw; 49249b5e25fSSatish Balay PetscTruth isnull; 49349b5e25fSSatish Balay 49449b5e25fSSatish Balay PetscFunctionBegin; 495b0a32e0cSBarry Smith ierr = PetscViewerDrawGetDraw(viewer,0,&draw);CHKERRQ(ierr); 496b0a32e0cSBarry Smith ierr = PetscDrawIsNull(draw,&isnull);CHKERRQ(ierr); if (isnull) PetscFunctionReturn(0); 49749b5e25fSSatish Balay 49849b5e25fSSatish Balay ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",(PetscObject)viewer);CHKERRQ(ierr); 499d0f46423SBarry Smith xr = A->rmap->N; yr = A->rmap->N; h = yr/10.0; w = xr/10.0; 50049b5e25fSSatish Balay xr += w; yr += h; xl = -w; yl = -h; 501b0a32e0cSBarry Smith ierr = PetscDrawSetCoordinates(draw,xl,yl,xr,yr);CHKERRQ(ierr); 502b0a32e0cSBarry Smith ierr = PetscDrawZoom(draw,MatView_SeqSBAIJ_Draw_Zoom,A);CHKERRQ(ierr); 50349b5e25fSSatish Balay ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",PETSC_NULL);CHKERRQ(ierr); 50449b5e25fSSatish Balay PetscFunctionReturn(0); 50549b5e25fSSatish Balay } 50649b5e25fSSatish Balay 5074a2ae208SSatish Balay #undef __FUNCT__ 5084a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqSBAIJ" 509dfbe8321SBarry Smith PetscErrorCode MatView_SeqSBAIJ(Mat A,PetscViewer viewer) 51049b5e25fSSatish Balay { 511dfbe8321SBarry Smith PetscErrorCode ierr; 51232077d6dSBarry Smith PetscTruth iascii,isdraw; 51349b5e25fSSatish Balay 51449b5e25fSSatish Balay PetscFunctionBegin; 51532077d6dSBarry Smith ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&iascii);CHKERRQ(ierr); 516fb9695e5SSatish Balay ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_DRAW,&isdraw);CHKERRQ(ierr); 51732077d6dSBarry Smith if (iascii){ 51849b5e25fSSatish Balay ierr = MatView_SeqSBAIJ_ASCII(A,viewer);CHKERRQ(ierr); 51949b5e25fSSatish Balay } else if (isdraw) { 52049b5e25fSSatish Balay ierr = MatView_SeqSBAIJ_Draw(A,viewer);CHKERRQ(ierr); 52149b5e25fSSatish Balay } else { 522a5e6ed63SBarry Smith Mat B; 523ceb03754SKris Buschelman ierr = MatConvert(A,MATSEQAIJ,MAT_INITIAL_MATRIX,&B);CHKERRQ(ierr); 524a5e6ed63SBarry Smith ierr = MatView(B,viewer);CHKERRQ(ierr); 525a5e6ed63SBarry Smith ierr = MatDestroy(B);CHKERRQ(ierr); 52649b5e25fSSatish Balay } 52749b5e25fSSatish Balay PetscFunctionReturn(0); 52849b5e25fSSatish Balay } 52949b5e25fSSatish Balay 53049b5e25fSSatish Balay 5314a2ae208SSatish Balay #undef __FUNCT__ 5324a2ae208SSatish Balay #define __FUNCT__ "MatGetValues_SeqSBAIJ" 53313f74950SBarry Smith PetscErrorCode MatGetValues_SeqSBAIJ(Mat A,PetscInt m,const PetscInt im[],PetscInt n,const PetscInt in[],PetscScalar v[]) 53449b5e25fSSatish Balay { 535045c9aa0SHong Zhang Mat_SeqSBAIJ *a = (Mat_SeqSBAIJ*)A->data; 53613f74950SBarry Smith PetscInt *rp,k,low,high,t,row,nrow,i,col,l,*aj = a->j; 53713f74950SBarry Smith PetscInt *ai = a->i,*ailen = a->ilen; 538d0f46423SBarry Smith PetscInt brow,bcol,ridx,cidx,bs=A->rmap->bs,bs2=a->bs2; 53997e567efSBarry Smith MatScalar *ap,*aa = a->a; 54049b5e25fSSatish Balay 54149b5e25fSSatish Balay PetscFunctionBegin; 54249b5e25fSSatish Balay for (k=0; k<m; k++) { /* loop over rows */ 54349b5e25fSSatish Balay row = im[k]; brow = row/bs; 54497e567efSBarry Smith if (row < 0) {v += n; continue;} /* SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Negative row: %D",row); */ 545d0f46423SBarry Smith if (row >= A->rmap->N) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"Row too large: row %D max %D",row,A->rmap->N-1); 54649b5e25fSSatish Balay rp = aj + ai[brow] ; ap = aa + bs2*ai[brow] ; 54749b5e25fSSatish Balay nrow = ailen[brow]; 54849b5e25fSSatish Balay for (l=0; l<n; l++) { /* loop over columns */ 54997e567efSBarry Smith if (in[l] < 0) {v++; continue;} /* SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Negative column: %D",in[l]); */ 550d0f46423SBarry 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); 55149b5e25fSSatish Balay col = in[l] ; 55249b5e25fSSatish Balay bcol = col/bs; 55349b5e25fSSatish Balay cidx = col%bs; 55449b5e25fSSatish Balay ridx = row%bs; 55549b5e25fSSatish Balay high = nrow; 55649b5e25fSSatish Balay low = 0; /* assume unsorted */ 55749b5e25fSSatish Balay while (high-low > 5) { 55849b5e25fSSatish Balay t = (low+high)/2; 55949b5e25fSSatish Balay if (rp[t] > bcol) high = t; 56049b5e25fSSatish Balay else low = t; 56149b5e25fSSatish Balay } 56249b5e25fSSatish Balay for (i=low; i<high; i++) { 56349b5e25fSSatish Balay if (rp[i] > bcol) break; 56449b5e25fSSatish Balay if (rp[i] == bcol) { 56549b5e25fSSatish Balay *v++ = ap[bs2*i+bs*cidx+ridx]; 56649b5e25fSSatish Balay goto finished; 56749b5e25fSSatish Balay } 56849b5e25fSSatish Balay } 56997e567efSBarry Smith *v++ = 0.0; 57049b5e25fSSatish Balay finished:; 57149b5e25fSSatish Balay } 57249b5e25fSSatish Balay } 57349b5e25fSSatish Balay PetscFunctionReturn(0); 57449b5e25fSSatish Balay } 57549b5e25fSSatish Balay 57649b5e25fSSatish Balay 5774a2ae208SSatish Balay #undef __FUNCT__ 5784a2ae208SSatish Balay #define __FUNCT__ "MatSetValuesBlocked_SeqSBAIJ" 57913f74950SBarry Smith PetscErrorCode MatSetValuesBlocked_SeqSBAIJ(Mat A,PetscInt m,const PetscInt im[],PetscInt n,const PetscInt in[],const PetscScalar v[],InsertMode is) 58049b5e25fSSatish Balay { 5810880e062SHong Zhang Mat_SeqSBAIJ *a = (Mat_SeqSBAIJ*)A->data; 5826849ba73SBarry Smith PetscErrorCode ierr; 583e2ee6c50SBarry Smith PetscInt *rp,k,low,high,t,ii,jj,row,nrow,i,col,l,rmax,N,lastcol = -1; 58413f74950SBarry Smith PetscInt *imax=a->imax,*ai=a->i,*ailen=a->ilen; 585d0f46423SBarry Smith PetscInt *aj=a->j,nonew=a->nonew,bs2=a->bs2,bs=A->rmap->bs,stepval; 5860880e062SHong Zhang PetscTruth roworiented=a->roworiented; 587dd6ea824SBarry Smith const PetscScalar *value = v; 588f15d580aSBarry Smith MatScalar *ap,*aa = a->a,*bap; 5890880e062SHong Zhang 59049b5e25fSSatish Balay PetscFunctionBegin; 5910880e062SHong Zhang if (roworiented) { 5920880e062SHong Zhang stepval = (n-1)*bs; 5930880e062SHong Zhang } else { 5940880e062SHong Zhang stepval = (m-1)*bs; 5950880e062SHong Zhang } 5960880e062SHong Zhang for (k=0; k<m; k++) { /* loop over added rows */ 5970880e062SHong Zhang row = im[k]; 5980880e062SHong Zhang if (row < 0) continue; 5992515c552SBarry Smith #if defined(PETSC_USE_DEBUG) 60077431f27SBarry Smith if (row >= a->mbs) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"Row too large: row %D max %D",row,a->mbs-1); 6010880e062SHong Zhang #endif 6020880e062SHong Zhang rp = aj + ai[row]; 6030880e062SHong Zhang ap = aa + bs2*ai[row]; 6040880e062SHong Zhang rmax = imax[row]; 6050880e062SHong Zhang nrow = ailen[row]; 6060880e062SHong Zhang low = 0; 607818f2c47SBarry Smith high = nrow; 6080880e062SHong Zhang for (l=0; l<n; l++) { /* loop over added columns */ 6090880e062SHong Zhang if (in[l] < 0) continue; 6100880e062SHong Zhang col = in[l]; 6112515c552SBarry Smith #if defined(PETSC_USE_DEBUG) 61277431f27SBarry Smith if (col >= a->nbs) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"Column too large: col %D max %D",col,a->nbs-1); 613b1823623SSatish Balay #endif 6140880e062SHong Zhang if (col < row) continue; /* ignore lower triangular block */ 6150880e062SHong Zhang if (roworiented) { 6160880e062SHong Zhang value = v + k*(stepval+bs)*bs + l*bs; 6170880e062SHong Zhang } else { 6180880e062SHong Zhang value = v + l*(stepval+bs)*bs + k*bs; 6190880e062SHong Zhang } 6207cd84e04SBarry Smith if (col <= lastcol) low = 0; else high = nrow; 621e2ee6c50SBarry Smith lastcol = col; 6220880e062SHong Zhang while (high-low > 7) { 6230880e062SHong Zhang t = (low+high)/2; 6240880e062SHong Zhang if (rp[t] > col) high = t; 6250880e062SHong Zhang else low = t; 6260880e062SHong Zhang } 6270880e062SHong Zhang for (i=low; i<high; i++) { 6280880e062SHong Zhang if (rp[i] > col) break; 6290880e062SHong Zhang if (rp[i] == col) { 6300880e062SHong Zhang bap = ap + bs2*i; 6310880e062SHong Zhang if (roworiented) { 6320880e062SHong Zhang if (is == ADD_VALUES) { 6330880e062SHong Zhang for (ii=0; ii<bs; ii++,value+=stepval) { 6340880e062SHong Zhang for (jj=ii; jj<bs2; jj+=bs) { 6350880e062SHong Zhang bap[jj] += *value++; 6360880e062SHong Zhang } 6370880e062SHong Zhang } 6380880e062SHong Zhang } else { 6390880e062SHong Zhang for (ii=0; ii<bs; ii++,value+=stepval) { 6400880e062SHong Zhang for (jj=ii; jj<bs2; jj+=bs) { 6410880e062SHong Zhang bap[jj] = *value++; 6420880e062SHong Zhang } 6430880e062SHong Zhang } 6440880e062SHong Zhang } 6450880e062SHong Zhang } else { 6460880e062SHong Zhang if (is == ADD_VALUES) { 6470880e062SHong Zhang for (ii=0; ii<bs; ii++,value+=stepval) { 6480880e062SHong Zhang for (jj=0; jj<bs; jj++) { 6490880e062SHong Zhang *bap++ += *value++; 6500880e062SHong Zhang } 6510880e062SHong Zhang } 6520880e062SHong Zhang } else { 6530880e062SHong Zhang for (ii=0; ii<bs; ii++,value+=stepval) { 6540880e062SHong Zhang for (jj=0; jj<bs; jj++) { 6550880e062SHong Zhang *bap++ = *value++; 6560880e062SHong Zhang } 6570880e062SHong Zhang } 6580880e062SHong Zhang } 6590880e062SHong Zhang } 6600880e062SHong Zhang goto noinsert2; 6610880e062SHong Zhang } 6620880e062SHong Zhang } 6630880e062SHong Zhang if (nonew == 1) goto noinsert2; 664085a36d4SBarry Smith if (nonew == -1) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"Inserting a new nonzero (%D, %D) in the matrix", row, col); 665421e10b8SBarry Smith MatSeqXAIJReallocateAIJ(A,a->mbs,bs2,nrow,row,col,rmax,aa,ai,aj,rp,ap,imax,nonew,MatScalar); 666c03d1d03SSatish Balay N = nrow++ - 1; high++; 6670880e062SHong Zhang /* shift up all the later entries in this row */ 6680880e062SHong Zhang for (ii=N; ii>=i; ii--) { 6690880e062SHong Zhang rp[ii+1] = rp[ii]; 6700880e062SHong Zhang ierr = PetscMemcpy(ap+bs2*(ii+1),ap+bs2*(ii),bs2*sizeof(MatScalar));CHKERRQ(ierr); 6710880e062SHong Zhang } 6720880e062SHong Zhang if (N >= i) { 6730880e062SHong Zhang ierr = PetscMemzero(ap+bs2*i,bs2*sizeof(MatScalar));CHKERRQ(ierr); 6740880e062SHong Zhang } 6750880e062SHong Zhang rp[i] = col; 6760880e062SHong Zhang bap = ap + bs2*i; 6770880e062SHong Zhang if (roworiented) { 6780880e062SHong Zhang for (ii=0; ii<bs; ii++,value+=stepval) { 6790880e062SHong Zhang for (jj=ii; jj<bs2; jj+=bs) { 6800880e062SHong Zhang bap[jj] = *value++; 6810880e062SHong Zhang } 6820880e062SHong Zhang } 6830880e062SHong Zhang } else { 6840880e062SHong Zhang for (ii=0; ii<bs; ii++,value+=stepval) { 6850880e062SHong Zhang for (jj=0; jj<bs; jj++) { 6860880e062SHong Zhang *bap++ = *value++; 6870880e062SHong Zhang } 6880880e062SHong Zhang } 6890880e062SHong Zhang } 6900880e062SHong Zhang noinsert2:; 6910880e062SHong Zhang low = i; 6920880e062SHong Zhang } 6930880e062SHong Zhang ailen[row] = nrow; 6940880e062SHong Zhang } 6950880e062SHong Zhang PetscFunctionReturn(0); 69649b5e25fSSatish Balay } 69749b5e25fSSatish Balay 6984a2ae208SSatish Balay #undef __FUNCT__ 6994a2ae208SSatish Balay #define __FUNCT__ "MatAssemblyEnd_SeqSBAIJ" 700dfbe8321SBarry Smith PetscErrorCode MatAssemblyEnd_SeqSBAIJ(Mat A,MatAssemblyType mode) 70149b5e25fSSatish Balay { 70249b5e25fSSatish Balay Mat_SeqSBAIJ *a = (Mat_SeqSBAIJ*)A->data; 7036849ba73SBarry Smith PetscErrorCode ierr; 70413f74950SBarry Smith PetscInt fshift = 0,i,j,*ai = a->i,*aj = a->j,*imax = a->imax; 705d0f46423SBarry Smith PetscInt m = A->rmap->N,*ip,N,*ailen = a->ilen; 70613f74950SBarry Smith PetscInt mbs = a->mbs,bs2 = a->bs2,rmax = 0; 70749b5e25fSSatish Balay MatScalar *aa = a->a,*ap; 70849b5e25fSSatish Balay 70949b5e25fSSatish Balay PetscFunctionBegin; 71049b5e25fSSatish Balay if (mode == MAT_FLUSH_ASSEMBLY) PetscFunctionReturn(0); 71149b5e25fSSatish Balay 71249b5e25fSSatish Balay if (m) rmax = ailen[0]; 71349b5e25fSSatish Balay for (i=1; i<mbs; i++) { 71449b5e25fSSatish Balay /* move each row back by the amount of empty slots (fshift) before it*/ 71549b5e25fSSatish Balay fshift += imax[i-1] - ailen[i-1]; 71649b5e25fSSatish Balay rmax = PetscMax(rmax,ailen[i]); 71749b5e25fSSatish Balay if (fshift) { 71849b5e25fSSatish Balay ip = aj + ai[i]; ap = aa + bs2*ai[i]; 71949b5e25fSSatish Balay N = ailen[i]; 72049b5e25fSSatish Balay for (j=0; j<N; j++) { 72149b5e25fSSatish Balay ip[j-fshift] = ip[j]; 72249b5e25fSSatish Balay ierr = PetscMemcpy(ap+(j-fshift)*bs2,ap+j*bs2,bs2*sizeof(MatScalar));CHKERRQ(ierr); 72349b5e25fSSatish Balay } 72449b5e25fSSatish Balay } 72549b5e25fSSatish Balay ai[i] = ai[i-1] + ailen[i-1]; 72649b5e25fSSatish Balay } 72749b5e25fSSatish Balay if (mbs) { 72849b5e25fSSatish Balay fshift += imax[mbs-1] - ailen[mbs-1]; 72949b5e25fSSatish Balay ai[mbs] = ai[mbs-1] + ailen[mbs-1]; 73049b5e25fSSatish Balay } 73149b5e25fSSatish Balay /* reset ilen and imax for each row */ 73249b5e25fSSatish Balay for (i=0; i<mbs; i++) { 73349b5e25fSSatish Balay ailen[i] = imax[i] = ai[i+1] - ai[i]; 73449b5e25fSSatish Balay } 7356c6c5352SBarry Smith a->nz = ai[mbs]; 73649b5e25fSSatish Balay 737b424e231SHong Zhang /* diagonals may have moved, reset it */ 738b424e231SHong Zhang if (a->diag) { 73913f74950SBarry Smith ierr = PetscMemcpy(a->diag,ai,(mbs+1)*sizeof(PetscInt));CHKERRQ(ierr); 74049b5e25fSSatish Balay } 741d0f46423SBarry 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); 742ae15b995SBarry Smith ierr = PetscInfo1(A,"Number of mallocs during MatSetValues is %D\n",a->reallocs);CHKERRQ(ierr); 743ae15b995SBarry Smith ierr = PetscInfo1(A,"Most nonzeros blocks in any row is %D\n",rmax);CHKERRQ(ierr); 74449b5e25fSSatish Balay a->reallocs = 0; 74549b5e25fSSatish Balay A->info.nz_unneeded = (PetscReal)fshift*bs2; 74649b5e25fSSatish Balay PetscFunctionReturn(0); 74749b5e25fSSatish Balay } 74849b5e25fSSatish Balay 74949b5e25fSSatish Balay /* 75049b5e25fSSatish Balay This function returns an array of flags which indicate the locations of contiguous 75149b5e25fSSatish Balay blocks that should be zeroed. for eg: if bs = 3 and is = [0,1,2,3,5,6,7,8,9] 75249b5e25fSSatish Balay then the resulting sizes = [3,1,1,3,1] correspondig to sets [(0,1,2),(3),(5),(6,7,8),(9)] 75349b5e25fSSatish Balay Assume: sizes should be long enough to hold all the values. 75449b5e25fSSatish Balay */ 7554a2ae208SSatish Balay #undef __FUNCT__ 7564a2ae208SSatish Balay #define __FUNCT__ "MatZeroRows_SeqSBAIJ_Check_Blocks" 75713f74950SBarry Smith PetscErrorCode MatZeroRows_SeqSBAIJ_Check_Blocks(PetscInt idx[],PetscInt n,PetscInt bs,PetscInt sizes[], PetscInt *bs_max) 75849b5e25fSSatish Balay { 75913f74950SBarry Smith PetscInt i,j,k,row; 76049b5e25fSSatish Balay PetscTruth flg; 76149b5e25fSSatish Balay 76249b5e25fSSatish Balay PetscFunctionBegin; 76349b5e25fSSatish Balay for (i=0,j=0; i<n; j++) { 76449b5e25fSSatish Balay row = idx[i]; 76549b5e25fSSatish Balay if (row%bs!=0) { /* Not the begining of a block */ 76649b5e25fSSatish Balay sizes[j] = 1; 76749b5e25fSSatish Balay i++; 76849b5e25fSSatish Balay } else if (i+bs > n) { /* Beginning of a block, but complete block doesn't exist (at idx end) */ 76949b5e25fSSatish Balay sizes[j] = 1; /* Also makes sure atleast 'bs' values exist for next else */ 77049b5e25fSSatish Balay i++; 77149b5e25fSSatish Balay } else { /* Begining of the block, so check if the complete block exists */ 77249b5e25fSSatish Balay flg = PETSC_TRUE; 77349b5e25fSSatish Balay for (k=1; k<bs; k++) { 77449b5e25fSSatish Balay if (row+k != idx[i+k]) { /* break in the block */ 77549b5e25fSSatish Balay flg = PETSC_FALSE; 77649b5e25fSSatish Balay break; 77749b5e25fSSatish Balay } 77849b5e25fSSatish Balay } 779abc0a331SBarry Smith if (flg) { /* No break in the bs */ 78049b5e25fSSatish Balay sizes[j] = bs; 78149b5e25fSSatish Balay i+= bs; 78249b5e25fSSatish Balay } else { 78349b5e25fSSatish Balay sizes[j] = 1; 78449b5e25fSSatish Balay i++; 78549b5e25fSSatish Balay } 78649b5e25fSSatish Balay } 78749b5e25fSSatish Balay } 78849b5e25fSSatish Balay *bs_max = j; 78949b5e25fSSatish Balay PetscFunctionReturn(0); 79049b5e25fSSatish Balay } 79149b5e25fSSatish Balay 79249b5e25fSSatish Balay 79349b5e25fSSatish Balay /* Only add/insert a(i,j) with i<=j (blocks). 79449b5e25fSSatish Balay Any a(i,j) with i>j input by user is ingored. 79549b5e25fSSatish Balay */ 79649b5e25fSSatish Balay 7974a2ae208SSatish Balay #undef __FUNCT__ 7984a2ae208SSatish Balay #define __FUNCT__ "MatSetValues_SeqSBAIJ" 79913f74950SBarry Smith PetscErrorCode MatSetValues_SeqSBAIJ(Mat A,PetscInt m,const PetscInt im[],PetscInt n,const PetscInt in[],const PetscScalar v[],InsertMode is) 80049b5e25fSSatish Balay { 80149b5e25fSSatish Balay Mat_SeqSBAIJ *a = (Mat_SeqSBAIJ*)A->data; 8026849ba73SBarry Smith PetscErrorCode ierr; 803e2ee6c50SBarry Smith PetscInt *rp,k,low,high,t,ii,row,nrow,i,col,l,rmax,N,lastcol = -1; 80413f74950SBarry Smith PetscInt *imax=a->imax,*ai=a->i,*ailen=a->ilen,roworiented=a->roworiented; 805d0f46423SBarry Smith PetscInt *aj=a->j,nonew=a->nonew,bs=A->rmap->bs,brow,bcol; 80613f74950SBarry Smith PetscInt ridx,cidx,bs2=a->bs2; 80749b5e25fSSatish Balay MatScalar *ap,value,*aa=a->a,*bap; 80849b5e25fSSatish Balay 80949b5e25fSSatish Balay PetscFunctionBegin; 81049b5e25fSSatish Balay for (k=0; k<m; k++) { /* loop over added rows */ 81149b5e25fSSatish Balay row = im[k]; /* row number */ 81249b5e25fSSatish Balay brow = row/bs; /* block row number */ 81349b5e25fSSatish Balay if (row < 0) continue; 8142515c552SBarry Smith #if defined(PETSC_USE_DEBUG) 815d0f46423SBarry Smith if (row >= A->rmap->N) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"Row too large: row %D max %D",row,A->rmap->N-1); 81649b5e25fSSatish Balay #endif 81749b5e25fSSatish Balay rp = aj + ai[brow]; /*ptr to beginning of column value of the row block*/ 81849b5e25fSSatish Balay ap = aa + bs2*ai[brow]; /*ptr to beginning of element value of the row block*/ 81949b5e25fSSatish Balay rmax = imax[brow]; /* maximum space allocated for this row */ 82049b5e25fSSatish Balay nrow = ailen[brow]; /* actual length of this row */ 82149b5e25fSSatish Balay low = 0; 82249b5e25fSSatish Balay 82349b5e25fSSatish Balay for (l=0; l<n; l++) { /* loop over added columns */ 82449b5e25fSSatish Balay if (in[l] < 0) continue; 8252515c552SBarry Smith #if defined(PETSC_USE_DEBUG) 826d0f46423SBarry 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); 82749b5e25fSSatish Balay #endif 82849b5e25fSSatish Balay col = in[l]; 82949b5e25fSSatish Balay bcol = col/bs; /* block col number */ 83049b5e25fSSatish Balay 831941593c8SHong Zhang if (brow > bcol) { 832941593c8SHong Zhang if (a->ignore_ltriangular){ 833941593c8SHong Zhang continue; /* ignore lower triangular values */ 834941593c8SHong Zhang } else { 8354e0d8c25SBarry 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)"); 836941593c8SHong Zhang } 837941593c8SHong Zhang } 838f4989cb3SHong Zhang 83949b5e25fSSatish Balay ridx = row % bs; cidx = col % bs; /*row and col index inside the block */ 8408549e402SHong Zhang if ((brow==bcol && ridx<=cidx) || (brow<bcol)){ 84149b5e25fSSatish Balay /* element value a(k,l) */ 84249b5e25fSSatish Balay if (roworiented) { 84349b5e25fSSatish Balay value = v[l + k*n]; 84449b5e25fSSatish Balay } else { 84549b5e25fSSatish Balay value = v[k + l*m]; 84649b5e25fSSatish Balay } 84749b5e25fSSatish Balay 84849b5e25fSSatish Balay /* move pointer bap to a(k,l) quickly and add/insert value */ 8497cd84e04SBarry Smith if (col <= lastcol) low = 0; high = nrow; 850e2ee6c50SBarry Smith lastcol = col; 85149b5e25fSSatish Balay while (high-low > 7) { 85249b5e25fSSatish Balay t = (low+high)/2; 85349b5e25fSSatish Balay if (rp[t] > bcol) high = t; 85449b5e25fSSatish Balay else low = t; 85549b5e25fSSatish Balay } 85649b5e25fSSatish Balay for (i=low; i<high; i++) { 85749b5e25fSSatish Balay if (rp[i] > bcol) break; 85849b5e25fSSatish Balay if (rp[i] == bcol) { 85949b5e25fSSatish Balay bap = ap + bs2*i + bs*cidx + ridx; 86049b5e25fSSatish Balay if (is == ADD_VALUES) *bap += value; 86149b5e25fSSatish Balay else *bap = value; 8628549e402SHong Zhang /* for diag block, add/insert its symmetric element a(cidx,ridx) */ 8638549e402SHong Zhang if (brow == bcol && ridx < cidx){ 8648549e402SHong Zhang bap = ap + bs2*i + bs*ridx + cidx; 8658549e402SHong Zhang if (is == ADD_VALUES) *bap += value; 8668549e402SHong Zhang else *bap = value; 8678549e402SHong Zhang } 86849b5e25fSSatish Balay goto noinsert1; 86949b5e25fSSatish Balay } 87049b5e25fSSatish Balay } 87149b5e25fSSatish Balay 87249b5e25fSSatish Balay if (nonew == 1) goto noinsert1; 873085a36d4SBarry Smith if (nonew == -1) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"Inserting a new nonzero (%D, %D) in the matrix", row, col); 874421e10b8SBarry Smith MatSeqXAIJReallocateAIJ(A,a->mbs,bs2,nrow,brow,bcol,rmax,aa,ai,aj,rp,ap,imax,nonew,MatScalar); 87549b5e25fSSatish Balay 876c03d1d03SSatish Balay N = nrow++ - 1; high++; 87749b5e25fSSatish Balay /* shift up all the later entries in this row */ 87849b5e25fSSatish Balay for (ii=N; ii>=i; ii--) { 87949b5e25fSSatish Balay rp[ii+1] = rp[ii]; 88049b5e25fSSatish Balay ierr = PetscMemcpy(ap+bs2*(ii+1),ap+bs2*(ii),bs2*sizeof(MatScalar));CHKERRQ(ierr); 88149b5e25fSSatish Balay } 88249b5e25fSSatish Balay if (N>=i) { 88349b5e25fSSatish Balay ierr = PetscMemzero(ap+bs2*i,bs2*sizeof(MatScalar));CHKERRQ(ierr); 88449b5e25fSSatish Balay } 88549b5e25fSSatish Balay rp[i] = bcol; 88649b5e25fSSatish Balay ap[bs2*i + bs*cidx + ridx] = value; 88749b5e25fSSatish Balay noinsert1:; 88849b5e25fSSatish Balay low = i; 8898549e402SHong Zhang } 89049b5e25fSSatish Balay } /* end of loop over added columns */ 89149b5e25fSSatish Balay ailen[brow] = nrow; 89249b5e25fSSatish Balay } /* end of loop over added rows */ 89349b5e25fSSatish Balay PetscFunctionReturn(0); 89449b5e25fSSatish Balay } 89549b5e25fSSatish Balay 8964a2ae208SSatish Balay #undef __FUNCT__ 8974d101231SSatish Balay #define __FUNCT__ "MatICCFactor_SeqSBAIJ" 898dfbe8321SBarry Smith PetscErrorCode MatICCFactor_SeqSBAIJ(Mat inA,IS row,MatFactorInfo *info) 89949b5e25fSSatish Balay { 9004ccecd49SHong Zhang Mat_SeqSBAIJ *a = (Mat_SeqSBAIJ*)inA->data; 90149b5e25fSSatish Balay Mat outA; 902dfbe8321SBarry Smith PetscErrorCode ierr; 903c84f5b01SHong Zhang PetscTruth row_identity; 90449b5e25fSSatish Balay 90549b5e25fSSatish Balay PetscFunctionBegin; 906c84f5b01SHong Zhang if (info->levels != 0) SETERRQ(PETSC_ERR_SUP,"Only levels=0 is supported for in-place icc"); 907c84f5b01SHong Zhang ierr = ISIdentity(row,&row_identity);CHKERRQ(ierr); 908c84f5b01SHong Zhang if (!row_identity) SETERRQ(PETSC_ERR_SUP,"Matrix reordering is not supported"); 909d0f46423SBarry 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()! */ 910c84f5b01SHong Zhang 91149b5e25fSSatish Balay outA = inA; 91249b5e25fSSatish Balay 9131a3463dfSHong Zhang ierr = MatMarkDiagonal_SeqSBAIJ(inA);CHKERRQ(ierr); 914db4efbfdSBarry Smith ierr = MatSeqSBAIJSetNumericFactorization(inA,row_identity);CHKERRQ(ierr); 91549b5e25fSSatish Balay 916c3122656SLisandro Dalcin ierr = PetscObjectReference((PetscObject)row);CHKERRQ(ierr); 917c3122656SLisandro Dalcin if (a->row) { ierr = ISDestroy(a->row);CHKERRQ(ierr); } 918c84f5b01SHong Zhang a->row = row; 919c3122656SLisandro Dalcin ierr = PetscObjectReference((PetscObject)row);CHKERRQ(ierr); 920c3122656SLisandro Dalcin if (a->col) { ierr = ISDestroy(a->col);CHKERRQ(ierr); } 921c84f5b01SHong Zhang a->col = row; 922c84f5b01SHong Zhang 923c84f5b01SHong Zhang /* Create the invert permutation so that it can be used in MatCholeskyFactorNumeric() */ 924c84f5b01SHong Zhang if (a->icol) {ierr = ISInvertPermutation(row,PETSC_DECIDE, &a->icol);CHKERRQ(ierr);} 92552e6d16bSBarry Smith ierr = PetscLogObjectParent(inA,a->icol);CHKERRQ(ierr); 92649b5e25fSSatish Balay 92749b5e25fSSatish Balay if (!a->solve_work) { 928d0f46423SBarry Smith ierr = PetscMalloc((inA->rmap->N+inA->rmap->bs)*sizeof(PetscScalar),&a->solve_work);CHKERRQ(ierr); 929d0f46423SBarry Smith ierr = PetscLogObjectMemory(inA,(inA->rmap->N+inA->rmap->bs)*sizeof(PetscScalar));CHKERRQ(ierr); 93049b5e25fSSatish Balay } 93149b5e25fSSatish Balay 932*719d5645SBarry Smith ierr = MatCholeskyFactorNumeric(outA,inA,info);CHKERRQ(ierr); 93349b5e25fSSatish Balay PetscFunctionReturn(0); 93449b5e25fSSatish Balay } 935950f1e5bSHong Zhang 93649b5e25fSSatish Balay EXTERN_C_BEGIN 9374a2ae208SSatish Balay #undef __FUNCT__ 9384a2ae208SSatish Balay #define __FUNCT__ "MatSeqSBAIJSetColumnIndices_SeqSBAIJ" 939be1d678aSKris Buschelman PetscErrorCode PETSCMAT_DLLEXPORT MatSeqSBAIJSetColumnIndices_SeqSBAIJ(Mat mat,PetscInt *indices) 94049b5e25fSSatish Balay { 941045c9aa0SHong Zhang Mat_SeqSBAIJ *baij = (Mat_SeqSBAIJ *)mat->data; 94213f74950SBarry Smith PetscInt i,nz,n; 94349b5e25fSSatish Balay 94449b5e25fSSatish Balay PetscFunctionBegin; 9456c6c5352SBarry Smith nz = baij->maxnz; 946d0f46423SBarry Smith n = mat->cmap->n; 94749b5e25fSSatish Balay for (i=0; i<nz; i++) { 94849b5e25fSSatish Balay baij->j[i] = indices[i]; 94949b5e25fSSatish Balay } 9506c6c5352SBarry Smith baij->nz = nz; 95149b5e25fSSatish Balay for (i=0; i<n; i++) { 95249b5e25fSSatish Balay baij->ilen[i] = baij->imax[i]; 95349b5e25fSSatish Balay } 95449b5e25fSSatish Balay PetscFunctionReturn(0); 95549b5e25fSSatish Balay } 95649b5e25fSSatish Balay EXTERN_C_END 95749b5e25fSSatish Balay 9584a2ae208SSatish Balay #undef __FUNCT__ 9594a2ae208SSatish Balay #define __FUNCT__ "MatSeqSBAIJSetColumnIndices" 96049b5e25fSSatish Balay /*@ 96119585528SSatish Balay MatSeqSBAIJSetColumnIndices - Set the column indices for all the rows 96249b5e25fSSatish Balay in the matrix. 96349b5e25fSSatish Balay 96449b5e25fSSatish Balay Input Parameters: 96519585528SSatish Balay + mat - the SeqSBAIJ matrix 96649b5e25fSSatish Balay - indices - the column indices 96749b5e25fSSatish Balay 96849b5e25fSSatish Balay Level: advanced 96949b5e25fSSatish Balay 97049b5e25fSSatish Balay Notes: 97149b5e25fSSatish Balay This can be called if you have precomputed the nonzero structure of the 97249b5e25fSSatish Balay matrix and want to provide it to the matrix object to improve the performance 97349b5e25fSSatish Balay of the MatSetValues() operation. 97449b5e25fSSatish Balay 97549b5e25fSSatish Balay You MUST have set the correct numbers of nonzeros per row in the call to 976d1be2dadSMatthew Knepley MatCreateSeqSBAIJ(), and the columns indices MUST be sorted. 97749b5e25fSSatish Balay 978ab9f2c04SSatish Balay MUST be called before any calls to MatSetValues() 97949b5e25fSSatish Balay 980ab9f2c04SSatish Balay .seealso: MatCreateSeqSBAIJ 98149b5e25fSSatish Balay @*/ 982be1d678aSKris Buschelman PetscErrorCode PETSCMAT_DLLEXPORT MatSeqSBAIJSetColumnIndices(Mat mat,PetscInt *indices) 98349b5e25fSSatish Balay { 98413f74950SBarry Smith PetscErrorCode ierr,(*f)(Mat,PetscInt *); 98549b5e25fSSatish Balay 98649b5e25fSSatish Balay PetscFunctionBegin; 9874482741eSBarry Smith PetscValidHeaderSpecific(mat,MAT_COOKIE,1); 9884482741eSBarry Smith PetscValidPointer(indices,2); 989c134de8dSSatish Balay ierr = PetscObjectQueryFunction((PetscObject)mat,"MatSeqSBAIJSetColumnIndices_C",(void (**)(void))&f);CHKERRQ(ierr); 99049b5e25fSSatish Balay if (f) { 99149b5e25fSSatish Balay ierr = (*f)(mat,indices);CHKERRQ(ierr); 99249b5e25fSSatish Balay } else { 993e005ede5SBarry Smith SETERRQ(PETSC_ERR_SUP,"Wrong type of matrix to set column indices"); 99449b5e25fSSatish Balay } 99549b5e25fSSatish Balay PetscFunctionReturn(0); 99649b5e25fSSatish Balay } 99749b5e25fSSatish Balay 9984a2ae208SSatish Balay #undef __FUNCT__ 9993c896bc6SHong Zhang #define __FUNCT__ "MatCopy_SeqSBAIJ" 10003c896bc6SHong Zhang PetscErrorCode MatCopy_SeqSBAIJ(Mat A,Mat B,MatStructure str) 10013c896bc6SHong Zhang { 10023c896bc6SHong Zhang PetscErrorCode ierr; 10033c896bc6SHong Zhang 10043c896bc6SHong Zhang PetscFunctionBegin; 10053c896bc6SHong Zhang /* If the two matrices have the same copy implementation, use fast copy. */ 10063c896bc6SHong Zhang if (str == SAME_NONZERO_PATTERN && (A->ops->copy == B->ops->copy)) { 10073c896bc6SHong Zhang Mat_SeqSBAIJ *a = (Mat_SeqSBAIJ*)A->data; 10083c896bc6SHong Zhang Mat_SeqSBAIJ *b = (Mat_SeqSBAIJ*)B->data; 10093c896bc6SHong Zhang 1010d0f46423SBarry Smith if (a->i[A->rmap->N] != b->i[B->rmap->N]) { 10113c896bc6SHong Zhang SETERRQ(PETSC_ERR_ARG_INCOMP,"Number of nonzeros in two matrices are different"); 10123c896bc6SHong Zhang } 1013d0f46423SBarry Smith ierr = PetscMemcpy(b->a,a->a,(a->i[A->rmap->N])*sizeof(PetscScalar));CHKERRQ(ierr); 10143c896bc6SHong Zhang } else { 1015f5edf698SHong Zhang ierr = MatGetRowUpperTriangular(A);CHKERRQ(ierr); 10163c896bc6SHong Zhang ierr = MatCopy_Basic(A,B,str);CHKERRQ(ierr); 1017f5edf698SHong Zhang ierr = MatRestoreRowUpperTriangular(A);CHKERRQ(ierr); 10183c896bc6SHong Zhang } 10193c896bc6SHong Zhang PetscFunctionReturn(0); 10203c896bc6SHong Zhang } 10213c896bc6SHong Zhang 10223c896bc6SHong Zhang #undef __FUNCT__ 10234a2ae208SSatish Balay #define __FUNCT__ "MatSetUpPreallocation_SeqSBAIJ" 1024dfbe8321SBarry Smith PetscErrorCode MatSetUpPreallocation_SeqSBAIJ(Mat A) 1025273d9f13SBarry Smith { 1026dfbe8321SBarry Smith PetscErrorCode ierr; 1027273d9f13SBarry Smith 1028273d9f13SBarry Smith PetscFunctionBegin; 1029db4efbfdSBarry Smith ierr = MatSeqSBAIJSetPreallocation_SeqSBAIJ(A,-PetscMax(A->rmap->bs,1),PETSC_DEFAULT,0);CHKERRQ(ierr); 1030273d9f13SBarry Smith PetscFunctionReturn(0); 1031273d9f13SBarry Smith } 1032273d9f13SBarry Smith 1033a6ece127SHong Zhang #undef __FUNCT__ 1034a6ece127SHong Zhang #define __FUNCT__ "MatGetArray_SeqSBAIJ" 1035dfbe8321SBarry Smith PetscErrorCode MatGetArray_SeqSBAIJ(Mat A,PetscScalar *array[]) 1036a6ece127SHong Zhang { 1037a6ece127SHong Zhang Mat_SeqSBAIJ *a = (Mat_SeqSBAIJ*)A->data; 1038a6ece127SHong Zhang PetscFunctionBegin; 1039a6ece127SHong Zhang *array = a->a; 1040a6ece127SHong Zhang PetscFunctionReturn(0); 1041a6ece127SHong Zhang } 1042a6ece127SHong Zhang 1043a6ece127SHong Zhang #undef __FUNCT__ 1044a6ece127SHong Zhang #define __FUNCT__ "MatRestoreArray_SeqSBAIJ" 1045dfbe8321SBarry Smith PetscErrorCode MatRestoreArray_SeqSBAIJ(Mat A,PetscScalar *array[]) 1046a6ece127SHong Zhang { 1047a6ece127SHong Zhang PetscFunctionBegin; 1048a6ece127SHong Zhang PetscFunctionReturn(0); 1049a6ece127SHong Zhang } 1050a6ece127SHong Zhang 105142ee4b1aSHong Zhang #include "petscblaslapack.h" 105242ee4b1aSHong Zhang #undef __FUNCT__ 105342ee4b1aSHong Zhang #define __FUNCT__ "MatAXPY_SeqSBAIJ" 1054f4df32b1SMatthew Knepley PetscErrorCode MatAXPY_SeqSBAIJ(Mat Y,PetscScalar a,Mat X,MatStructure str) 105542ee4b1aSHong Zhang { 105642ee4b1aSHong Zhang Mat_SeqSBAIJ *x=(Mat_SeqSBAIJ *)X->data, *y=(Mat_SeqSBAIJ *)Y->data; 1057dfbe8321SBarry Smith PetscErrorCode ierr; 1058d0f46423SBarry Smith PetscInt i,bs=Y->rmap->bs,bs2,j; 10590805154bSBarry Smith PetscBLASInt one = 1,bnz = PetscBLASIntCast(x->nz); 106042ee4b1aSHong Zhang 106142ee4b1aSHong Zhang PetscFunctionBegin; 106242ee4b1aSHong Zhang if (str == SAME_NONZERO_PATTERN) { 1063f4df32b1SMatthew Knepley PetscScalar alpha = a; 1064f4df32b1SMatthew Knepley BLASaxpy_(&bnz,&alpha,x->a,&one,y->a,&one); 1065c537a176SHong Zhang } else if (str == SUBSET_NONZERO_PATTERN) { /* nonzeros of X is a subset of Y's */ 1066c4319e64SHong Zhang if (y->xtoy && y->XtoY != X) { 1067c4319e64SHong Zhang ierr = PetscFree(y->xtoy);CHKERRQ(ierr); 1068c4319e64SHong Zhang ierr = MatDestroy(y->XtoY);CHKERRQ(ierr); 1069c537a176SHong Zhang } 1070c4319e64SHong Zhang if (!y->xtoy) { /* get xtoy */ 1071c4319e64SHong Zhang ierr = MatAXPYGetxtoy_Private(x->mbs,x->i,x->j,PETSC_NULL, y->i,y->j,PETSC_NULL, &y->xtoy);CHKERRQ(ierr); 1072c4319e64SHong Zhang y->XtoY = X; 1073c537a176SHong Zhang } 1074c4319e64SHong Zhang bs2 = bs*bs; 10756c6c5352SBarry Smith for (i=0; i<x->nz; i++) { 1076c4319e64SHong Zhang j = 0; 1077c4319e64SHong Zhang while (j < bs2){ 1078f4df32b1SMatthew Knepley y->a[bs2*y->xtoy[i]+j] += a*(x->a[bs2*i+j]); 1079c4319e64SHong Zhang j++; 1080c537a176SHong Zhang } 1081c4319e64SHong Zhang } 10821e2582c4SBarry 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); 108342ee4b1aSHong Zhang } else { 1084f5edf698SHong Zhang ierr = MatGetRowUpperTriangular(X);CHKERRQ(ierr); 1085f4df32b1SMatthew Knepley ierr = MatAXPY_Basic(Y,a,X,str);CHKERRQ(ierr); 1086f5edf698SHong Zhang ierr = MatRestoreRowUpperTriangular(X);CHKERRQ(ierr); 108742ee4b1aSHong Zhang } 108842ee4b1aSHong Zhang PetscFunctionReturn(0); 108942ee4b1aSHong Zhang } 109042ee4b1aSHong Zhang 1091efcf0fc3SBarry Smith #undef __FUNCT__ 1092efcf0fc3SBarry Smith #define __FUNCT__ "MatIsSymmetric_SeqSBAIJ" 1093dfbe8321SBarry Smith PetscErrorCode MatIsSymmetric_SeqSBAIJ(Mat A,PetscReal tol,PetscTruth *flg) 1094efcf0fc3SBarry Smith { 1095efcf0fc3SBarry Smith PetscFunctionBegin; 1096efcf0fc3SBarry Smith *flg = PETSC_TRUE; 1097efcf0fc3SBarry Smith PetscFunctionReturn(0); 1098efcf0fc3SBarry Smith } 1099efcf0fc3SBarry Smith 1100efcf0fc3SBarry Smith #undef __FUNCT__ 1101efcf0fc3SBarry Smith #define __FUNCT__ "MatIsStructurallySymmetric_SeqSBAIJ" 1102dfbe8321SBarry Smith PetscErrorCode MatIsStructurallySymmetric_SeqSBAIJ(Mat A,PetscTruth *flg) 1103efcf0fc3SBarry Smith { 1104efcf0fc3SBarry Smith PetscFunctionBegin; 1105efcf0fc3SBarry Smith *flg = PETSC_TRUE; 1106efcf0fc3SBarry Smith PetscFunctionReturn(0); 1107efcf0fc3SBarry Smith } 1108efcf0fc3SBarry Smith 1109efcf0fc3SBarry Smith #undef __FUNCT__ 1110efcf0fc3SBarry Smith #define __FUNCT__ "MatIsHermitian_SeqSBAIJ" 1111ab5e4463SMatthew Knepley PetscErrorCode MatIsHermitian_SeqSBAIJ(Mat A,PetscReal tol,PetscTruth *flg) 1112efcf0fc3SBarry Smith { 1113efcf0fc3SBarry Smith PetscFunctionBegin; 1114efcf0fc3SBarry Smith *flg = PETSC_FALSE; 1115efcf0fc3SBarry Smith PetscFunctionReturn(0); 1116efcf0fc3SBarry Smith } 1117efcf0fc3SBarry Smith 111899cafbc1SBarry Smith #undef __FUNCT__ 111999cafbc1SBarry Smith #define __FUNCT__ "MatRealPart_SeqSBAIJ" 112099cafbc1SBarry Smith PetscErrorCode MatRealPart_SeqSBAIJ(Mat A) 112199cafbc1SBarry Smith { 112299cafbc1SBarry Smith Mat_SeqSBAIJ *a = (Mat_SeqSBAIJ*)A->data; 112399cafbc1SBarry Smith PetscInt i,nz = a->bs2*a->i[a->mbs]; 1124dd6ea824SBarry Smith MatScalar *aa = a->a; 112599cafbc1SBarry Smith 112699cafbc1SBarry Smith PetscFunctionBegin; 112799cafbc1SBarry Smith for (i=0; i<nz; i++) aa[i] = PetscRealPart(aa[i]); 112899cafbc1SBarry Smith PetscFunctionReturn(0); 112999cafbc1SBarry Smith } 113099cafbc1SBarry Smith 113199cafbc1SBarry Smith #undef __FUNCT__ 113299cafbc1SBarry Smith #define __FUNCT__ "MatImaginaryPart_SeqSBAIJ" 113399cafbc1SBarry Smith PetscErrorCode MatImaginaryPart_SeqSBAIJ(Mat A) 113499cafbc1SBarry Smith { 113599cafbc1SBarry Smith Mat_SeqSBAIJ *a = (Mat_SeqSBAIJ*)A->data; 113699cafbc1SBarry Smith PetscInt i,nz = a->bs2*a->i[a->mbs]; 1137dd6ea824SBarry Smith MatScalar *aa = a->a; 113899cafbc1SBarry Smith 113999cafbc1SBarry Smith PetscFunctionBegin; 114099cafbc1SBarry Smith for (i=0; i<nz; i++) aa[i] = PetscImaginaryPart(aa[i]); 114199cafbc1SBarry Smith PetscFunctionReturn(0); 114299cafbc1SBarry Smith } 114399cafbc1SBarry Smith 114449b5e25fSSatish Balay /* -------------------------------------------------------------------*/ 114549b5e25fSSatish Balay static struct _MatOps MatOps_Values = {MatSetValues_SeqSBAIJ, 114649b5e25fSSatish Balay MatGetRow_SeqSBAIJ, 114749b5e25fSSatish Balay MatRestoreRow_SeqSBAIJ, 114849b5e25fSSatish Balay MatMult_SeqSBAIJ_N, 114997304618SKris Buschelman /* 4*/ MatMultAdd_SeqSBAIJ_N, 1150431c96f7SBarry Smith MatMult_SeqSBAIJ_N, /* transpose versions are same as non-transpose versions */ 1151e005ede5SBarry Smith MatMultAdd_SeqSBAIJ_N, 1152db4efbfdSBarry Smith 0, 115349b5e25fSSatish Balay 0, 115449b5e25fSSatish Balay 0, 115597304618SKris Buschelman /*10*/ 0, 115649b5e25fSSatish Balay 0, 1157*719d5645SBarry Smith 0, 1158d06b337dSHong Zhang MatRelax_SeqSBAIJ, 115949b5e25fSSatish Balay MatTranspose_SeqSBAIJ, 116097304618SKris Buschelman /*15*/ MatGetInfo_SeqSBAIJ, 116149b5e25fSSatish Balay MatEqual_SeqSBAIJ, 116249b5e25fSSatish Balay MatGetDiagonal_SeqSBAIJ, 116349b5e25fSSatish Balay MatDiagonalScale_SeqSBAIJ, 116449b5e25fSSatish Balay MatNorm_SeqSBAIJ, 116597304618SKris Buschelman /*20*/ 0, 116649b5e25fSSatish Balay MatAssemblyEnd_SeqSBAIJ, 116749b5e25fSSatish Balay 0, 116849b5e25fSSatish Balay MatSetOption_SeqSBAIJ, 116949b5e25fSSatish Balay MatZeroEntries_SeqSBAIJ, 1170dcf5cc72SBarry Smith /*25*/ 0, 117149b5e25fSSatish Balay 0, 117249b5e25fSSatish Balay 0, 1173db4efbfdSBarry Smith 0, 1174db4efbfdSBarry Smith 0, 117597304618SKris Buschelman /*30*/ MatSetUpPreallocation_SeqSBAIJ, 1176c464158bSHong Zhang 0, 1177db4efbfdSBarry Smith 0, 1178a6ece127SHong Zhang MatGetArray_SeqSBAIJ, 1179a6ece127SHong Zhang MatRestoreArray_SeqSBAIJ, 118097304618SKris Buschelman /*35*/ MatDuplicate_SeqSBAIJ, 1181*719d5645SBarry Smith 0, 1182*719d5645SBarry Smith 0, 118349b5e25fSSatish Balay 0, 1184c84f5b01SHong Zhang MatICCFactor_SeqSBAIJ, 118597304618SKris Buschelman /*40*/ MatAXPY_SeqSBAIJ, 118649b5e25fSSatish Balay MatGetSubMatrices_SeqSBAIJ, 118749b5e25fSSatish Balay MatIncreaseOverlap_SeqSBAIJ, 118849b5e25fSSatish Balay MatGetValues_SeqSBAIJ, 11893c896bc6SHong Zhang MatCopy_SeqSBAIJ, 11908c07d4e3SBarry Smith /*45*/ 0, 119149b5e25fSSatish Balay MatScale_SeqSBAIJ, 119249b5e25fSSatish Balay 0, 119349b5e25fSSatish Balay 0, 119449b5e25fSSatish Balay 0, 1195521d7252SBarry Smith /*50*/ 0, 119649b5e25fSSatish Balay MatGetRowIJ_SeqSBAIJ, 119749b5e25fSSatish Balay MatRestoreRowIJ_SeqSBAIJ, 119849b5e25fSSatish Balay 0, 119949b5e25fSSatish Balay 0, 120097304618SKris Buschelman /*55*/ 0, 120149b5e25fSSatish Balay 0, 120249b5e25fSSatish Balay 0, 120349b5e25fSSatish Balay 0, 120449b5e25fSSatish Balay MatSetValuesBlocked_SeqSBAIJ, 120597304618SKris Buschelman /*60*/ MatGetSubMatrix_SeqSBAIJ, 120649b5e25fSSatish Balay 0, 120749b5e25fSSatish Balay 0, 1208357abbc8SBarry Smith 0, 1209d959ec07SHong Zhang 0, 121097304618SKris Buschelman /*65*/ 0, 1211d959ec07SHong Zhang 0, 1212d959ec07SHong Zhang 0, 1213d959ec07SHong Zhang 0, 1214d959ec07SHong Zhang 0, 1215985db425SBarry Smith /*70*/ MatGetRowMaxAbs_SeqSBAIJ, 12163e0d88b5SBarry Smith 0, 12173e0d88b5SBarry Smith 0, 12183e0d88b5SBarry Smith 0, 12193e0d88b5SBarry Smith 0, 122097304618SKris Buschelman /*75*/ 0, 12213e0d88b5SBarry Smith 0, 12223e0d88b5SBarry Smith 0, 12233e0d88b5SBarry Smith 0, 12243e0d88b5SBarry Smith 0, 122597304618SKris Buschelman /*80*/ 0, 12263e0d88b5SBarry Smith 0, 12273e0d88b5SBarry Smith 0, 12283e0d88b5SBarry Smith #if !defined(PETSC_USE_COMPLEX) 122997304618SKris Buschelman MatGetInertia_SeqSBAIJ, 12303e0d88b5SBarry Smith #else 123197304618SKris Buschelman 0, 12323e0d88b5SBarry Smith #endif 1233865e5f61SKris Buschelman MatLoad_SeqSBAIJ, 1234865e5f61SKris Buschelman /*85*/ MatIsSymmetric_SeqSBAIJ, 1235865e5f61SKris Buschelman MatIsHermitian_SeqSBAIJ, 1236efcf0fc3SBarry Smith MatIsStructurallySymmetric_SeqSBAIJ, 1237865e5f61SKris Buschelman 0, 1238865e5f61SKris Buschelman 0, 1239865e5f61SKris Buschelman /*90*/ 0, 1240865e5f61SKris Buschelman 0, 1241865e5f61SKris Buschelman 0, 1242865e5f61SKris Buschelman 0, 1243865e5f61SKris Buschelman 0, 1244865e5f61SKris Buschelman /*95*/ 0, 1245865e5f61SKris Buschelman 0, 1246865e5f61SKris Buschelman 0, 124799cafbc1SBarry Smith 0, 124899cafbc1SBarry Smith 0, 124999cafbc1SBarry Smith /*100*/0, 125099cafbc1SBarry Smith 0, 125199cafbc1SBarry Smith 0, 125299cafbc1SBarry Smith 0, 125399cafbc1SBarry Smith 0, 125499cafbc1SBarry Smith /*105*/0, 125599cafbc1SBarry Smith MatRealPart_SeqSBAIJ, 1256f5edf698SHong Zhang MatImaginaryPart_SeqSBAIJ, 1257f5edf698SHong Zhang MatGetRowUpperTriangular_SeqSBAIJ, 12582af78befSBarry Smith MatRestoreRowUpperTriangular_SeqSBAIJ, 12592af78befSBarry Smith /*110*/0, 12602af78befSBarry Smith 0, 12612af78befSBarry Smith 0, 12622af78befSBarry Smith 0, 12632af78befSBarry Smith MatMissingDiagonal_SeqSBAIJ 126499cafbc1SBarry Smith }; 1265be1d678aSKris Buschelman 126649b5e25fSSatish Balay EXTERN_C_BEGIN 12674a2ae208SSatish Balay #undef __FUNCT__ 12684a2ae208SSatish Balay #define __FUNCT__ "MatStoreValues_SeqSBAIJ" 1269be1d678aSKris Buschelman PetscErrorCode PETSCMAT_DLLEXPORT MatStoreValues_SeqSBAIJ(Mat mat) 127049b5e25fSSatish Balay { 12714afc71dfSHong Zhang Mat_SeqSBAIJ *aij = (Mat_SeqSBAIJ *)mat->data; 1272d0f46423SBarry Smith PetscInt nz = aij->i[mat->rmap->N]*mat->rmap->bs*aij->bs2; 1273dfbe8321SBarry Smith PetscErrorCode ierr; 127449b5e25fSSatish Balay 127549b5e25fSSatish Balay PetscFunctionBegin; 127649b5e25fSSatish Balay if (aij->nonew != 1) { 1277512a5fc5SBarry Smith SETERRQ(PETSC_ERR_ORDER,"Must call MatSetOption(A,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE);first"); 127849b5e25fSSatish Balay } 127949b5e25fSSatish Balay 128049b5e25fSSatish Balay /* allocate space for values if not already there */ 128149b5e25fSSatish Balay if (!aij->saved_values) { 128287828ca2SBarry Smith ierr = PetscMalloc((nz+1)*sizeof(PetscScalar),&aij->saved_values);CHKERRQ(ierr); 128349b5e25fSSatish Balay } 128449b5e25fSSatish Balay 128549b5e25fSSatish Balay /* copy values over */ 128687828ca2SBarry Smith ierr = PetscMemcpy(aij->saved_values,aij->a,nz*sizeof(PetscScalar));CHKERRQ(ierr); 128749b5e25fSSatish Balay PetscFunctionReturn(0); 128849b5e25fSSatish Balay } 128949b5e25fSSatish Balay EXTERN_C_END 129049b5e25fSSatish Balay 129149b5e25fSSatish Balay EXTERN_C_BEGIN 12924a2ae208SSatish Balay #undef __FUNCT__ 12934a2ae208SSatish Balay #define __FUNCT__ "MatRetrieveValues_SeqSBAIJ" 1294be1d678aSKris Buschelman PetscErrorCode PETSCMAT_DLLEXPORT MatRetrieveValues_SeqSBAIJ(Mat mat) 129549b5e25fSSatish Balay { 12964afc71dfSHong Zhang Mat_SeqSBAIJ *aij = (Mat_SeqSBAIJ *)mat->data; 12976849ba73SBarry Smith PetscErrorCode ierr; 1298d0f46423SBarry Smith PetscInt nz = aij->i[mat->rmap->N]*mat->rmap->bs*aij->bs2; 129949b5e25fSSatish Balay 130049b5e25fSSatish Balay PetscFunctionBegin; 130149b5e25fSSatish Balay if (aij->nonew != 1) { 1302512a5fc5SBarry Smith SETERRQ(PETSC_ERR_ORDER,"Must call MatSetOption(A,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE);first"); 130349b5e25fSSatish Balay } 130449b5e25fSSatish Balay if (!aij->saved_values) { 1305e005ede5SBarry Smith SETERRQ(PETSC_ERR_ORDER,"Must call MatStoreValues(A);first"); 130649b5e25fSSatish Balay } 130749b5e25fSSatish Balay 130849b5e25fSSatish Balay /* copy values over */ 130987828ca2SBarry Smith ierr = PetscMemcpy(aij->a,aij->saved_values,nz*sizeof(PetscScalar));CHKERRQ(ierr); 131049b5e25fSSatish Balay PetscFunctionReturn(0); 131149b5e25fSSatish Balay } 131249b5e25fSSatish Balay EXTERN_C_END 131349b5e25fSSatish Balay 13148549e402SHong Zhang EXTERN_C_BEGIN 13154a2ae208SSatish Balay #undef __FUNCT__ 1316a23d5eceSKris Buschelman #define __FUNCT__ "MatSeqSBAIJSetPreallocation_SeqSBAIJ" 1317be1d678aSKris Buschelman PetscErrorCode PETSCMAT_DLLEXPORT MatSeqSBAIJSetPreallocation_SeqSBAIJ(Mat B,PetscInt bs,PetscInt nz,PetscInt *nnz) 131849b5e25fSSatish Balay { 1319c464158bSHong Zhang Mat_SeqSBAIJ *b = (Mat_SeqSBAIJ*)B->data; 13206849ba73SBarry Smith PetscErrorCode ierr; 1321db4efbfdSBarry Smith PetscInt i,mbs,bs2, newbs = PetscAbs(bs); 1322ab93d7beSBarry Smith PetscTruth skipallocation = PETSC_FALSE,flg; 132349b5e25fSSatish Balay 132449b5e25fSSatish Balay PetscFunctionBegin; 1325273d9f13SBarry Smith B->preallocated = PETSC_TRUE; 1326db4efbfdSBarry Smith if (bs < 0) { 1327db4efbfdSBarry Smith ierr = PetscOptionsBegin(((PetscObject)B)->comm,((PetscObject)B)->prefix,"Options for MPISBAIJ matrix","Mat");CHKERRQ(ierr); 1328db4efbfdSBarry Smith ierr = PetscOptionsInt("-mat_block_size","Set the blocksize used to store the matrix","MatSeqSBAIJSetPreallocation",newbs,&newbs,PETSC_NULL);CHKERRQ(ierr); 1329db4efbfdSBarry Smith ierr = PetscOptionsEnd();CHKERRQ(ierr); 1330db4efbfdSBarry Smith bs = PetscAbs(bs); 1331db4efbfdSBarry Smith } 1332db4efbfdSBarry Smith if (nnz && newbs != bs) { 1333db4efbfdSBarry Smith SETERRQ(PETSC_ERR_ARG_WRONG,"Cannot change blocksize from command line if setting nnz"); 1334db4efbfdSBarry Smith } 1335db4efbfdSBarry Smith bs = newbs; 1336db4efbfdSBarry Smith 1337d0f46423SBarry Smith B->rmap->bs = B->cmap->bs = bs; 1338d0f46423SBarry Smith ierr = PetscMapSetUp(B->rmap);CHKERRQ(ierr); 1339d0f46423SBarry Smith ierr = PetscMapSetUp(B->cmap);CHKERRQ(ierr); 1340899cda47SBarry Smith 1341d0f46423SBarry Smith mbs = B->rmap->N/bs; 134249b5e25fSSatish Balay bs2 = bs*bs; 134349b5e25fSSatish Balay 1344d0f46423SBarry Smith if (mbs*bs != B->rmap->N) { 134529bbc08cSBarry Smith SETERRQ(PETSC_ERR_ARG_SIZ,"Number rows, cols must be divisible by blocksize"); 134649b5e25fSSatish Balay } 134749b5e25fSSatish Balay 1348ab93d7beSBarry Smith if (nz == MAT_SKIP_ALLOCATION) { 1349ab93d7beSBarry Smith skipallocation = PETSC_TRUE; 1350ab93d7beSBarry Smith nz = 0; 1351ab93d7beSBarry Smith } 1352ab93d7beSBarry Smith 1353435da068SBarry Smith if (nz == PETSC_DEFAULT || nz == PETSC_DECIDE) nz = 3; 135477431f27SBarry Smith if (nz < 0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"nz cannot be less than 0: value %D",nz); 135549b5e25fSSatish Balay if (nnz) { 135649b5e25fSSatish Balay for (i=0; i<mbs; i++) { 135777431f27SBarry Smith if (nnz[i] < 0) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"nnz cannot be less than 0: local row %D value %D",i,nnz[i]); 135877431f27SBarry 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); 135949b5e25fSSatish Balay } 136049b5e25fSSatish Balay } 136149b5e25fSSatish Balay 1362db4efbfdSBarry Smith B->ops->mult = MatMult_SeqSBAIJ_N; 1363db4efbfdSBarry Smith B->ops->multadd = MatMultAdd_SeqSBAIJ_N; 1364db4efbfdSBarry Smith B->ops->multtranspose = MatMult_SeqSBAIJ_N; 1365db4efbfdSBarry Smith B->ops->multtransposeadd = MatMultAdd_SeqSBAIJ_N; 13667adad957SLisandro Dalcin ierr = PetscOptionsHasName(((PetscObject)B)->prefix,"-mat_no_unroll",&flg);CHKERRQ(ierr); 136749b5e25fSSatish Balay if (!flg) { 136849b5e25fSSatish Balay switch (bs) { 136949b5e25fSSatish Balay case 1: 137049b5e25fSSatish Balay B->ops->mult = MatMult_SeqSBAIJ_1; 137149b5e25fSSatish Balay B->ops->multadd = MatMultAdd_SeqSBAIJ_1; 1372431c96f7SBarry Smith B->ops->multtranspose = MatMult_SeqSBAIJ_1; 1373431c96f7SBarry Smith B->ops->multtransposeadd = MatMultAdd_SeqSBAIJ_1; 137449b5e25fSSatish Balay break; 137549b5e25fSSatish Balay case 2: 137649b5e25fSSatish Balay B->ops->mult = MatMult_SeqSBAIJ_2; 137749b5e25fSSatish Balay B->ops->multadd = MatMultAdd_SeqSBAIJ_2; 1378431c96f7SBarry Smith B->ops->multtranspose = MatMult_SeqSBAIJ_2; 1379431c96f7SBarry Smith B->ops->multtransposeadd = MatMultAdd_SeqSBAIJ_2; 138049b5e25fSSatish Balay break; 138149b5e25fSSatish Balay case 3: 138249b5e25fSSatish Balay B->ops->mult = MatMult_SeqSBAIJ_3; 138349b5e25fSSatish Balay B->ops->multadd = MatMultAdd_SeqSBAIJ_3; 1384431c96f7SBarry Smith B->ops->multtranspose = MatMult_SeqSBAIJ_3; 1385431c96f7SBarry Smith B->ops->multtransposeadd = MatMultAdd_SeqSBAIJ_3; 138649b5e25fSSatish Balay break; 138749b5e25fSSatish Balay case 4: 138849b5e25fSSatish Balay B->ops->mult = MatMult_SeqSBAIJ_4; 138949b5e25fSSatish Balay B->ops->multadd = MatMultAdd_SeqSBAIJ_4; 1390431c96f7SBarry Smith B->ops->multtranspose = MatMult_SeqSBAIJ_4; 1391431c96f7SBarry Smith B->ops->multtransposeadd = MatMultAdd_SeqSBAIJ_4; 139249b5e25fSSatish Balay break; 139349b5e25fSSatish Balay case 5: 139449b5e25fSSatish Balay B->ops->mult = MatMult_SeqSBAIJ_5; 139549b5e25fSSatish Balay B->ops->multadd = MatMultAdd_SeqSBAIJ_5; 1396431c96f7SBarry Smith B->ops->multtranspose = MatMult_SeqSBAIJ_5; 1397431c96f7SBarry Smith B->ops->multtransposeadd = MatMultAdd_SeqSBAIJ_5; 139849b5e25fSSatish Balay break; 139949b5e25fSSatish Balay case 6: 140049b5e25fSSatish Balay B->ops->mult = MatMult_SeqSBAIJ_6; 140149b5e25fSSatish Balay B->ops->multadd = MatMultAdd_SeqSBAIJ_6; 1402431c96f7SBarry Smith B->ops->multtranspose = MatMult_SeqSBAIJ_6; 1403431c96f7SBarry Smith B->ops->multtransposeadd = MatMultAdd_SeqSBAIJ_6; 140449b5e25fSSatish Balay break; 140549b5e25fSSatish Balay case 7: 1406de53e5efSHong Zhang B->ops->mult = MatMult_SeqSBAIJ_7; 140749b5e25fSSatish Balay B->ops->multadd = MatMultAdd_SeqSBAIJ_7; 1408431c96f7SBarry Smith B->ops->multtranspose = MatMult_SeqSBAIJ_7; 1409431c96f7SBarry Smith B->ops->multtransposeadd = MatMultAdd_SeqSBAIJ_7; 141049b5e25fSSatish Balay break; 141149b5e25fSSatish Balay } 141249b5e25fSSatish Balay } 141349b5e25fSSatish Balay 141449b5e25fSSatish Balay b->mbs = mbs; 14154afc71dfSHong Zhang b->nbs = mbs; 1416ab93d7beSBarry Smith if (!skipallocation) { 14172ee49352SLisandro Dalcin if (!b->imax) { 1418ab93d7beSBarry Smith ierr = PetscMalloc2(mbs,PetscInt,&b->imax,mbs,PetscInt,&b->ilen);CHKERRQ(ierr); 14192ee49352SLisandro Dalcin ierr = PetscLogObjectMemory(B,2*mbs*sizeof(PetscInt));CHKERRQ(ierr); 14202ee49352SLisandro Dalcin } 142149b5e25fSSatish Balay if (!nnz) { 1422435da068SBarry Smith if (nz == PETSC_DEFAULT || nz == PETSC_DECIDE) nz = 5; 142349b5e25fSSatish Balay else if (nz <= 0) nz = 1; 142449b5e25fSSatish Balay for (i=0; i<mbs; i++) { 14258cef66ccSHong Zhang b->imax[i] = nz; 142649b5e25fSSatish Balay } 1427153ea458SHong Zhang nz = nz*mbs; /* total nz */ 142849b5e25fSSatish Balay } else { 142949b5e25fSSatish Balay nz = 0; 14308cef66ccSHong Zhang for (i=0; i<mbs; i++) {b->imax[i] = nnz[i]; nz += nnz[i];} 143149b5e25fSSatish Balay } 14322ee49352SLisandro Dalcin /* b->ilen will count nonzeros in each block row so far. */ 14332ee49352SLisandro Dalcin for (i=0; i<mbs; i++) { b->ilen[i] = 0;} 14346c6c5352SBarry Smith /* nz=(nz+mbs)/2; */ /* total diagonal and superdiagonal nonzero blocks */ 143549b5e25fSSatish Balay 143649b5e25fSSatish Balay /* allocate the matrix space */ 14372ee49352SLisandro Dalcin ierr = MatSeqXAIJFreeAIJ(B,&b->a,&b->j,&b->i);CHKERRQ(ierr); 1438d0f46423SBarry Smith ierr = PetscMalloc3(bs2*nz,PetscScalar,&b->a,nz,PetscInt,&b->j,B->rmap->N+1,PetscInt,&b->i);CHKERRQ(ierr); 1439d0f46423SBarry Smith ierr = PetscLogObjectMemory(B,(B->rmap->N+1)*sizeof(PetscInt)+nz*(bs2*sizeof(PetscScalar)+sizeof(PetscInt)));CHKERRQ(ierr); 14406c6c5352SBarry Smith ierr = PetscMemzero(b->a,nz*bs2*sizeof(MatScalar));CHKERRQ(ierr); 144113f74950SBarry Smith ierr = PetscMemzero(b->j,nz*sizeof(PetscInt));CHKERRQ(ierr); 144249b5e25fSSatish Balay b->singlemalloc = PETSC_TRUE; 144349b5e25fSSatish Balay 144449b5e25fSSatish Balay /* pointer to beginning of each row */ 144549b5e25fSSatish Balay b->i[0] = 0; 144649b5e25fSSatish Balay for (i=1; i<mbs+1; i++) { 144749b5e25fSSatish Balay b->i[i] = b->i[i-1] + b->imax[i-1]; 144849b5e25fSSatish Balay } 1449e6b907acSBarry Smith b->free_a = PETSC_TRUE; 1450e6b907acSBarry Smith b->free_ij = PETSC_TRUE; 1451e811da20SHong Zhang } else { 1452e6b907acSBarry Smith b->free_a = PETSC_FALSE; 1453e6b907acSBarry Smith b->free_ij = PETSC_FALSE; 1454ab93d7beSBarry Smith } 145549b5e25fSSatish Balay 1456d0f46423SBarry Smith B->rmap->bs = bs; 145749b5e25fSSatish Balay b->bs2 = bs2; 14586c6c5352SBarry Smith b->nz = 0; 14596c6c5352SBarry Smith b->maxnz = nz*bs2; 1460153ea458SHong Zhang 146116cdd363SHong Zhang b->inew = 0; 146216cdd363SHong Zhang b->jnew = 0; 146316cdd363SHong Zhang b->anew = 0; 146416cdd363SHong Zhang b->a2anew = 0; 14651a3463dfSHong Zhang b->permute = PETSC_FALSE; 1466c464158bSHong Zhang PetscFunctionReturn(0); 1467c464158bSHong Zhang } 1468a23d5eceSKris Buschelman EXTERN_C_END 1469153ea458SHong Zhang 1470db4efbfdSBarry Smith #undef __FUNCT__ 1471db4efbfdSBarry Smith #define __FUNCT__ "MatSeqBAIJSetNumericFactorization" 1472db4efbfdSBarry Smith /* 1473db4efbfdSBarry Smith This is used to set the numeric factorization for both Cholesky and ICC symbolic factorization 1474db4efbfdSBarry Smith */ 1475db4efbfdSBarry Smith PetscErrorCode MatSeqSBAIJSetNumericFactorization(Mat B,PetscTruth natural) 1476db4efbfdSBarry Smith { 1477db4efbfdSBarry Smith PetscErrorCode ierr; 1478db4efbfdSBarry Smith PetscTruth flg; 1479db4efbfdSBarry Smith PetscInt bs = B->rmap->bs; 1480db4efbfdSBarry Smith 1481db4efbfdSBarry Smith PetscFunctionBegin; 1482db4efbfdSBarry Smith ierr = PetscOptionsHasName(((PetscObject)B)->prefix,"-mat_no_unroll",&flg);CHKERRQ(ierr); 1483db4efbfdSBarry Smith if (flg) bs = 8; 1484db4efbfdSBarry Smith 1485db4efbfdSBarry Smith if (!natural) { 1486db4efbfdSBarry Smith switch (bs) { 1487db4efbfdSBarry Smith case 1: 1488db4efbfdSBarry Smith B->ops->choleskyfactornumeric = MatCholeskyFactorNumeric_SeqSBAIJ_1; 1489db4efbfdSBarry Smith break; 1490db4efbfdSBarry Smith case 2: 1491db4efbfdSBarry Smith B->ops->choleskyfactornumeric = MatCholeskyFactorNumeric_SeqSBAIJ_2; 1492db4efbfdSBarry Smith break; 1493db4efbfdSBarry Smith case 3: 1494db4efbfdSBarry Smith B->ops->choleskyfactornumeric = MatCholeskyFactorNumeric_SeqSBAIJ_3; 1495db4efbfdSBarry Smith break; 1496db4efbfdSBarry Smith case 4: 1497db4efbfdSBarry Smith B->ops->choleskyfactornumeric = MatCholeskyFactorNumeric_SeqSBAIJ_4; 1498db4efbfdSBarry Smith break; 1499db4efbfdSBarry Smith case 5: 1500db4efbfdSBarry Smith B->ops->choleskyfactornumeric = MatCholeskyFactorNumeric_SeqSBAIJ_5; 1501db4efbfdSBarry Smith break; 1502db4efbfdSBarry Smith case 6: 1503db4efbfdSBarry Smith B->ops->choleskyfactornumeric = MatCholeskyFactorNumeric_SeqSBAIJ_6; 1504db4efbfdSBarry Smith break; 1505db4efbfdSBarry Smith case 7: 1506db4efbfdSBarry Smith B->ops->choleskyfactornumeric = MatCholeskyFactorNumeric_SeqSBAIJ_7; 1507db4efbfdSBarry Smith break; 1508db4efbfdSBarry Smith default: 1509db4efbfdSBarry Smith B->ops->choleskyfactornumeric = MatCholeskyFactorNumeric_SeqSBAIJ_N; 1510db4efbfdSBarry Smith break; 1511db4efbfdSBarry Smith } 1512db4efbfdSBarry Smith } else { 1513db4efbfdSBarry Smith switch (bs) { 1514db4efbfdSBarry Smith case 1: 1515db4efbfdSBarry Smith B->ops->choleskyfactornumeric = MatCholeskyFactorNumeric_SeqSBAIJ_1_NaturalOrdering; 1516db4efbfdSBarry Smith break; 1517db4efbfdSBarry Smith case 2: 1518db4efbfdSBarry Smith B->ops->choleskyfactornumeric = MatCholeskyFactorNumeric_SeqSBAIJ_2_NaturalOrdering; 1519db4efbfdSBarry Smith break; 1520db4efbfdSBarry Smith case 3: 1521db4efbfdSBarry Smith B->ops->choleskyfactornumeric = MatCholeskyFactorNumeric_SeqSBAIJ_3_NaturalOrdering; 1522db4efbfdSBarry Smith break; 1523db4efbfdSBarry Smith case 4: 1524db4efbfdSBarry Smith B->ops->choleskyfactornumeric = MatCholeskyFactorNumeric_SeqSBAIJ_4_NaturalOrdering; 1525db4efbfdSBarry Smith break; 1526db4efbfdSBarry Smith case 5: 1527db4efbfdSBarry Smith B->ops->choleskyfactornumeric = MatCholeskyFactorNumeric_SeqSBAIJ_5_NaturalOrdering; 1528db4efbfdSBarry Smith break; 1529db4efbfdSBarry Smith case 6: 1530db4efbfdSBarry Smith B->ops->choleskyfactornumeric = MatCholeskyFactorNumeric_SeqSBAIJ_6_NaturalOrdering; 1531db4efbfdSBarry Smith break; 1532db4efbfdSBarry Smith case 7: 1533db4efbfdSBarry Smith B->ops->choleskyfactornumeric = MatCholeskyFactorNumeric_SeqSBAIJ_7_NaturalOrdering; 1534db4efbfdSBarry Smith break; 1535db4efbfdSBarry Smith default: 1536db4efbfdSBarry Smith B->ops->choleskyfactornumeric = MatCholeskyFactorNumeric_SeqSBAIJ_N_NaturalOrdering; 1537db4efbfdSBarry Smith break; 1538db4efbfdSBarry Smith } 1539db4efbfdSBarry Smith } 1540db4efbfdSBarry Smith PetscFunctionReturn(0); 1541db4efbfdSBarry Smith } 1542db4efbfdSBarry Smith 1543d769727bSBarry Smith EXTERN_C_BEGIN 1544f69a0ea3SMatthew Knepley EXTERN PetscErrorCode PETSCMAT_DLLEXPORT MatConvert_SeqSBAIJ_SeqAIJ(Mat, MatType,MatReuse,Mat*); 1545f69a0ea3SMatthew Knepley EXTERN PetscErrorCode PETSCMAT_DLLEXPORT MatConvert_SeqSBAIJ_SeqBAIJ(Mat, MatType,MatReuse,Mat*); 1546*719d5645SBarry Smith EXTERN PetscErrorCode PETSCMAT_DLLEXPORT MatCholeskyFactorSymbolic_SeqSBAIJ(Mat,Mat,IS,MatFactorInfo*); 1547d769727bSBarry Smith EXTERN_C_END 1548d769727bSBarry Smith 1549e631078cSBarry Smith 1550e631078cSBarry Smith EXTERN_C_BEGIN 15515c9eb25fSBarry Smith #undef __FUNCT__ 15525c9eb25fSBarry Smith #define __FUNCT__ "MatGetFactor_seqsbaij_petsc" 15535c9eb25fSBarry Smith PetscErrorCode MatGetFactor_seqsbaij_petsc(Mat A,MatFactorType ftype,Mat *B) 15545c9eb25fSBarry Smith { 1555d0f46423SBarry Smith PetscInt n = A->rmap->n; 15565c9eb25fSBarry Smith PetscErrorCode ierr; 15575c9eb25fSBarry Smith 15585c9eb25fSBarry Smith PetscFunctionBegin; 15595c9eb25fSBarry Smith ierr = MatCreate(((PetscObject)A)->comm,B);CHKERRQ(ierr); 15605c9eb25fSBarry Smith ierr = MatSetSizes(*B,n,n,n,n);CHKERRQ(ierr); 15615c9eb25fSBarry Smith if (ftype == MAT_FACTOR_CHOLESKY || ftype == MAT_FACTOR_ICC) { 15625c9eb25fSBarry Smith ierr = MatSetType(*B,MATSEQSBAIJ);CHKERRQ(ierr); 15635c9eb25fSBarry Smith ierr = MatSeqSBAIJSetPreallocation(*B,1,MAT_SKIP_ALLOCATION,PETSC_NULL);CHKERRQ(ierr); 1564db4efbfdSBarry Smith (*B)->ops->choleskyfactorsymbolic = MatCholeskyFactorSymbolic_SeqSBAIJ; 1565db4efbfdSBarry Smith (*B)->ops->iccfactorsymbolic = MatICCFactorSymbolic_SeqSBAIJ; 15665c9eb25fSBarry Smith } else SETERRQ(PETSC_ERR_SUP,"Factor type not supported"); 1567*719d5645SBarry Smith (*B)->factor = ftype; 15685c9eb25fSBarry Smith PetscFunctionReturn(0); 15695c9eb25fSBarry Smith } 1570e631078cSBarry Smith EXTERN_C_END 15715c9eb25fSBarry Smith 15725c9eb25fSBarry Smith EXTERN_C_BEGIN 1573db4efbfdSBarry Smith #undef __FUNCT__ 1574db4efbfdSBarry Smith #define __FUNCT__ "MatGetFactorAvailable_seqsbaij_petsc" 1575db4efbfdSBarry Smith PetscErrorCode MatGetFactorAvailable_seqsbaij_petsc(Mat A,MatFactorType ftype,PetscTruth *flg) 1576db4efbfdSBarry Smith { 1577db4efbfdSBarry Smith PetscFunctionBegin; 1578db4efbfdSBarry Smith if (ftype == MAT_FACTOR_CHOLESKY || ftype == MAT_FACTOR_ICC) { 1579db4efbfdSBarry Smith *flg = PETSC_TRUE; 1580db4efbfdSBarry Smith } else { 1581db4efbfdSBarry Smith *flg = PETSC_FALSE; 1582db4efbfdSBarry Smith } 1583db4efbfdSBarry Smith PetscFunctionReturn(0); 1584db4efbfdSBarry Smith } 1585db4efbfdSBarry Smith EXTERN_C_END 1586db4efbfdSBarry Smith 1587db4efbfdSBarry Smith EXTERN_C_BEGIN 1588611f576cSBarry Smith #if defined(PETSC_HAVE_MUMPS) 15895c9eb25fSBarry Smith extern PetscErrorCode MatGetFactor_seqsbaij_mumps(Mat,MatFactorType,Mat*); 1590611f576cSBarry Smith #endif 1591611f576cSBarry Smith #if defined(PETSC_HAVE_SPOOLES) 15925c9eb25fSBarry Smith extern PetscErrorCode MatGetFactor_seqsbaij_spooles(Mat,MatFactorType,Mat*); 1593611f576cSBarry Smith #endif 15945c9eb25fSBarry Smith EXTERN_C_END 15955c9eb25fSBarry Smith 15960bad9183SKris Buschelman /*MC 1597fafad747SKris Buschelman MATSEQSBAIJ - MATSEQSBAIJ = "seqsbaij" - A matrix type to be used for sequential symmetric block sparse matrices, 15980bad9183SKris Buschelman based on block compressed sparse row format. Only the upper triangular portion of the matrix is stored. 15990bad9183SKris Buschelman 16000bad9183SKris Buschelman Options Database Keys: 16010bad9183SKris Buschelman . -mat_type seqsbaij - sets the matrix type to "seqsbaij" during a call to MatSetFromOptions() 16020bad9183SKris Buschelman 16030bad9183SKris Buschelman Level: beginner 16040bad9183SKris Buschelman 16050bad9183SKris Buschelman .seealso: MatCreateSeqSBAIJ 16060bad9183SKris Buschelman M*/ 16070bad9183SKris Buschelman 1608a23d5eceSKris Buschelman EXTERN_C_BEGIN 1609a23d5eceSKris Buschelman #undef __FUNCT__ 1610a23d5eceSKris Buschelman #define __FUNCT__ "MatCreate_SeqSBAIJ" 1611be1d678aSKris Buschelman PetscErrorCode PETSCMAT_DLLEXPORT MatCreate_SeqSBAIJ(Mat B) 1612a23d5eceSKris Buschelman { 1613a23d5eceSKris Buschelman Mat_SeqSBAIJ *b; 1614dfbe8321SBarry Smith PetscErrorCode ierr; 161513f74950SBarry Smith PetscMPIInt size; 1616941593c8SHong Zhang PetscTruth flg; 1617a23d5eceSKris Buschelman 1618a23d5eceSKris Buschelman PetscFunctionBegin; 16197adad957SLisandro Dalcin ierr = MPI_Comm_size(((PetscObject)B)->comm,&size);CHKERRQ(ierr); 1620a23d5eceSKris Buschelman if (size > 1) SETERRQ(PETSC_ERR_ARG_WRONG,"Comm must be of size 1"); 1621a23d5eceSKris Buschelman 162238f2d2fdSLisandro Dalcin ierr = PetscNewLog(B,Mat_SeqSBAIJ,&b);CHKERRQ(ierr); 1623a23d5eceSKris Buschelman B->data = (void*)b; 1624a23d5eceSKris Buschelman ierr = PetscMemcpy(B->ops,&MatOps_Values,sizeof(struct _MatOps));CHKERRQ(ierr); 1625a23d5eceSKris Buschelman B->ops->destroy = MatDestroy_SeqSBAIJ; 1626a23d5eceSKris Buschelman B->ops->view = MatView_SeqSBAIJ; 1627a23d5eceSKris Buschelman B->mapping = 0; 1628a23d5eceSKris Buschelman b->row = 0; 1629a23d5eceSKris Buschelman b->icol = 0; 1630a23d5eceSKris Buschelman b->reallocs = 0; 1631a23d5eceSKris Buschelman b->saved_values = 0; 1632a23d5eceSKris Buschelman 1633a23d5eceSKris Buschelman 1634a23d5eceSKris Buschelman b->roworiented = PETSC_TRUE; 1635a23d5eceSKris Buschelman b->nonew = 0; 1636a23d5eceSKris Buschelman b->diag = 0; 1637a23d5eceSKris Buschelman b->solve_work = 0; 1638a23d5eceSKris Buschelman b->mult_work = 0; 1639a23d5eceSKris Buschelman B->spptr = 0; 1640a23d5eceSKris Buschelman b->keepzeroedrows = PETSC_FALSE; 1641a23d5eceSKris Buschelman b->xtoy = 0; 1642a23d5eceSKris Buschelman b->XtoY = 0; 1643a23d5eceSKris Buschelman 1644a23d5eceSKris Buschelman b->inew = 0; 1645a23d5eceSKris Buschelman b->jnew = 0; 1646a23d5eceSKris Buschelman b->anew = 0; 1647a23d5eceSKris Buschelman b->a2anew = 0; 1648a23d5eceSKris Buschelman b->permute = PETSC_FALSE; 1649a23d5eceSKris Buschelman 1650941593c8SHong Zhang b->ignore_ltriangular = PETSC_FALSE; 1651941593c8SHong Zhang ierr = PetscOptionsHasName(PETSC_NULL,"-mat_ignore_lower_triangular",&flg);CHKERRQ(ierr); 1652941593c8SHong Zhang if (flg) b->ignore_ltriangular = PETSC_TRUE; 1653941593c8SHong Zhang 1654f5edf698SHong Zhang b->getrow_utriangular = PETSC_FALSE; 1655f5edf698SHong Zhang ierr = PetscOptionsHasName(PETSC_NULL,"-mat_getrow_uppertriangular",&flg);CHKERRQ(ierr); 1656f5edf698SHong Zhang if (flg) b->getrow_utriangular = PETSC_TRUE; 1657f5edf698SHong Zhang 1658611f576cSBarry Smith #if defined(PETSC_HAVE_SPOOLES) 16595c9eb25fSBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatGetFactor_seqsbaij_spooles_C", 16605c9eb25fSBarry Smith "MatGetFactor_seqsbaij_spooles", 16615c9eb25fSBarry Smith MatGetFactor_seqsbaij_spooles);CHKERRQ(ierr); 1662611f576cSBarry Smith #endif 1663611f576cSBarry Smith #if defined(PETSC_HAVE_MUMPS) 16645c9eb25fSBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatGetFactor_seqsbaij_mumps_C", 16655c9eb25fSBarry Smith "MatGetFactor_seqsbaij_mumps", 16665c9eb25fSBarry Smith MatGetFactor_seqsbaij_mumps);CHKERRQ(ierr); 1667611f576cSBarry Smith #endif 1668db4efbfdSBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatGetFactorAvailable_seqsbaij_petsc_C", 1669db4efbfdSBarry Smith "MatGetFactorAvailable_seqsbaij_petsc", 1670db4efbfdSBarry Smith MatGetFactorAvailable_seqsbaij_petsc);CHKERRQ(ierr); 16715c9eb25fSBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatGetFactor_seqsbaij_petsc_C", 16725c9eb25fSBarry Smith "MatGetFactor_seqsbaij_petsc", 16735c9eb25fSBarry Smith MatGetFactor_seqsbaij_petsc);CHKERRQ(ierr); 1674a23d5eceSKris Buschelman ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatStoreValues_C", 1675a23d5eceSKris Buschelman "MatStoreValues_SeqSBAIJ", 1676a23d5eceSKris Buschelman MatStoreValues_SeqSBAIJ);CHKERRQ(ierr); 1677a23d5eceSKris Buschelman ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatRetrieveValues_C", 1678a23d5eceSKris Buschelman "MatRetrieveValues_SeqSBAIJ", 1679a23d5eceSKris Buschelman (void*)MatRetrieveValues_SeqSBAIJ);CHKERRQ(ierr); 1680a23d5eceSKris Buschelman ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatSeqSBAIJSetColumnIndices_C", 1681a23d5eceSKris Buschelman "MatSeqSBAIJSetColumnIndices_SeqSBAIJ", 1682a23d5eceSKris Buschelman MatSeqSBAIJSetColumnIndices_SeqSBAIJ);CHKERRQ(ierr); 16834e5e7fe4SHong Zhang ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatConvert_seqsbaij_seqaij_C", 16844e5e7fe4SHong Zhang "MatConvert_SeqSBAIJ_SeqAIJ", 16854e5e7fe4SHong Zhang MatConvert_SeqSBAIJ_SeqAIJ);CHKERRQ(ierr); 1686a0e1a404SHong Zhang ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatConvert_seqsbaij_seqbaij_C", 1687a0e1a404SHong Zhang "MatConvert_SeqSBAIJ_SeqBAIJ", 1688a0e1a404SHong Zhang MatConvert_SeqSBAIJ_SeqBAIJ);CHKERRQ(ierr); 1689a23d5eceSKris Buschelman ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatSeqSBAIJSetPreallocation_C", 1690a23d5eceSKris Buschelman "MatSeqSBAIJSetPreallocation_SeqSBAIJ", 1691a23d5eceSKris Buschelman MatSeqSBAIJSetPreallocation_SeqSBAIJ);CHKERRQ(ierr); 169223ce1328SBarry Smith 169323ce1328SBarry Smith B->symmetric = PETSC_TRUE; 169423ce1328SBarry Smith B->structurally_symmetric = PETSC_TRUE; 169523ce1328SBarry Smith B->symmetric_set = PETSC_TRUE; 169623ce1328SBarry Smith B->structurally_symmetric_set = PETSC_TRUE; 169717667f90SBarry Smith ierr = PetscObjectChangeTypeName((PetscObject)B,MATSEQSBAIJ);CHKERRQ(ierr); 1698a23d5eceSKris Buschelman PetscFunctionReturn(0); 1699a23d5eceSKris Buschelman } 1700a23d5eceSKris Buschelman EXTERN_C_END 1701a23d5eceSKris Buschelman 1702a23d5eceSKris Buschelman #undef __FUNCT__ 1703a23d5eceSKris Buschelman #define __FUNCT__ "MatSeqSBAIJSetPreallocation" 1704a23d5eceSKris Buschelman /*@C 1705a23d5eceSKris Buschelman MatSeqSBAIJSetPreallocation - Creates a sparse symmetric matrix in block AIJ (block 1706a23d5eceSKris Buschelman compressed row) format. For good matrix assembly performance the 1707a23d5eceSKris Buschelman user should preallocate the matrix storage by setting the parameter nz 1708a23d5eceSKris Buschelman (or the array nnz). By setting these parameters accurately, performance 1709a23d5eceSKris Buschelman during matrix assembly can be increased by more than a factor of 50. 1710a23d5eceSKris Buschelman 1711a23d5eceSKris Buschelman Collective on Mat 1712a23d5eceSKris Buschelman 1713a23d5eceSKris Buschelman Input Parameters: 1714a23d5eceSKris Buschelman + A - the symmetric matrix 1715a23d5eceSKris Buschelman . bs - size of block 1716a23d5eceSKris Buschelman . nz - number of block nonzeros per block row (same for all rows) 1717a23d5eceSKris Buschelman - nnz - array containing the number of block nonzeros in the upper triangular plus 1718a23d5eceSKris Buschelman diagonal portion of each block (possibly different for each block row) or PETSC_NULL 1719a23d5eceSKris Buschelman 1720a23d5eceSKris Buschelman Options Database Keys: 1721a23d5eceSKris Buschelman . -mat_no_unroll - uses code that does not unroll the loops in the 1722a23d5eceSKris Buschelman block calculations (much slower) 1723db4efbfdSBarry Smith . -mat_block_size - size of the blocks to use (only works if a negative bs is passed in 1724a23d5eceSKris Buschelman 1725a23d5eceSKris Buschelman Level: intermediate 1726a23d5eceSKris Buschelman 1727a23d5eceSKris Buschelman Notes: 1728a23d5eceSKris Buschelman Specify the preallocated storage with either nz or nnz (not both). 1729a23d5eceSKris Buschelman Set nz=PETSC_DEFAULT and nnz=PETSC_NULL for PETSc to control dynamic memory 1730a23d5eceSKris Buschelman allocation. For additional details, see the users manual chapter on 1731a23d5eceSKris Buschelman matrices. 1732a23d5eceSKris Buschelman 1733aa95bbe8SBarry Smith You can call MatGetInfo() to get information on how effective the preallocation was; 1734aa95bbe8SBarry Smith for example the fields mallocs,nz_allocated,nz_used,nz_unneeded; 1735aa95bbe8SBarry Smith You can also run with the option -info and look for messages with the string 1736aa95bbe8SBarry Smith malloc in them to see if additional memory allocation was needed. 1737aa95bbe8SBarry Smith 173849a6f317SBarry Smith If the nnz parameter is given then the nz parameter is ignored 173949a6f317SBarry Smith 174049a6f317SBarry Smith 1741a23d5eceSKris Buschelman .seealso: MatCreate(), MatCreateSeqAIJ(), MatSetValues(), MatCreateMPISBAIJ() 1742a23d5eceSKris Buschelman @*/ 1743be1d678aSKris Buschelman PetscErrorCode PETSCMAT_DLLEXPORT MatSeqSBAIJSetPreallocation(Mat B,PetscInt bs,PetscInt nz,const PetscInt nnz[]) 174413f74950SBarry Smith { 174513f74950SBarry Smith PetscErrorCode ierr,(*f)(Mat,PetscInt,PetscInt,const PetscInt[]); 1746a23d5eceSKris Buschelman 1747a23d5eceSKris Buschelman PetscFunctionBegin; 1748a23d5eceSKris Buschelman ierr = PetscObjectQueryFunction((PetscObject)B,"MatSeqSBAIJSetPreallocation_C",(void (**)(void))&f);CHKERRQ(ierr); 1749a23d5eceSKris Buschelman if (f) { 1750a23d5eceSKris Buschelman ierr = (*f)(B,bs,nz,nnz);CHKERRQ(ierr); 1751a23d5eceSKris Buschelman } 1752a23d5eceSKris Buschelman PetscFunctionReturn(0); 1753a23d5eceSKris Buschelman } 175449b5e25fSSatish Balay 17554a2ae208SSatish Balay #undef __FUNCT__ 17564a2ae208SSatish Balay #define __FUNCT__ "MatCreateSeqSBAIJ" 1757c464158bSHong Zhang /*@C 1758c464158bSHong Zhang MatCreateSeqSBAIJ - Creates a sparse symmetric matrix in block AIJ (block 1759c464158bSHong Zhang compressed row) format. For good matrix assembly performance the 1760c464158bSHong Zhang user should preallocate the matrix storage by setting the parameter nz 1761c464158bSHong Zhang (or the array nnz). By setting these parameters accurately, performance 1762c464158bSHong Zhang during matrix assembly can be increased by more than a factor of 50. 176349b5e25fSSatish Balay 1764c464158bSHong Zhang Collective on MPI_Comm 1765c464158bSHong Zhang 1766c464158bSHong Zhang Input Parameters: 1767c464158bSHong Zhang + comm - MPI communicator, set to PETSC_COMM_SELF 1768c464158bSHong Zhang . bs - size of block 1769c464158bSHong Zhang . m - number of rows, or number of columns 1770c464158bSHong Zhang . nz - number of block nonzeros per block row (same for all rows) 1771744e8345SSatish Balay - nnz - array containing the number of block nonzeros in the upper triangular plus 1772744e8345SSatish Balay diagonal portion of each block (possibly different for each block row) or PETSC_NULL 1773c464158bSHong Zhang 1774c464158bSHong Zhang Output Parameter: 1775c464158bSHong Zhang . A - the symmetric matrix 1776c464158bSHong Zhang 1777c464158bSHong Zhang Options Database Keys: 1778c464158bSHong Zhang . -mat_no_unroll - uses code that does not unroll the loops in the 1779c464158bSHong Zhang block calculations (much slower) 1780c464158bSHong Zhang . -mat_block_size - size of the blocks to use 1781c464158bSHong Zhang 1782c464158bSHong Zhang Level: intermediate 1783c464158bSHong Zhang 1784175b88e8SBarry Smith It is recommended that one use the MatCreate(), MatSetType() and/or MatSetFromOptions(), 1785175b88e8SBarry Smith MatXXXXSetPreallocation() paradgm instead of this routine directly. This is definitely 1786175b88e8SBarry Smith true if you plan to use the external direct solvers such as SuperLU, MUMPS or Spooles. 1787175b88e8SBarry Smith [MatXXXXSetPreallocation() is, for example, MatSeqAIJSetPreallocation] 1788175b88e8SBarry Smith 1789c464158bSHong Zhang Notes: 17906d6d819aSHong Zhang The number of rows and columns must be divisible by blocksize. 17916d6d819aSHong Zhang This matrix type does not support complex Hermitian operation. 1792c464158bSHong Zhang 1793c464158bSHong Zhang Specify the preallocated storage with either nz or nnz (not both). 1794c464158bSHong Zhang Set nz=PETSC_DEFAULT and nnz=PETSC_NULL for PETSc to control dynamic memory 1795c464158bSHong Zhang allocation. For additional details, see the users manual chapter on 1796c464158bSHong Zhang matrices. 1797c464158bSHong Zhang 179849a6f317SBarry Smith If the nnz parameter is given then the nz parameter is ignored 179949a6f317SBarry Smith 1800c464158bSHong Zhang .seealso: MatCreate(), MatCreateSeqAIJ(), MatSetValues(), MatCreateMPISBAIJ() 1801c464158bSHong Zhang @*/ 1802be1d678aSKris Buschelman PetscErrorCode PETSCMAT_DLLEXPORT MatCreateSeqSBAIJ(MPI_Comm comm,PetscInt bs,PetscInt m,PetscInt n,PetscInt nz,const PetscInt nnz[],Mat *A) 1803c464158bSHong Zhang { 1804dfbe8321SBarry Smith PetscErrorCode ierr; 1805c464158bSHong Zhang 1806c464158bSHong Zhang PetscFunctionBegin; 1807f69a0ea3SMatthew Knepley ierr = MatCreate(comm,A);CHKERRQ(ierr); 1808f69a0ea3SMatthew Knepley ierr = MatSetSizes(*A,m,n,m,n);CHKERRQ(ierr); 1809c464158bSHong Zhang ierr = MatSetType(*A,MATSEQSBAIJ);CHKERRQ(ierr); 1810ab93d7beSBarry Smith ierr = MatSeqSBAIJSetPreallocation_SeqSBAIJ(*A,bs,nz,(PetscInt*)nnz);CHKERRQ(ierr); 181149b5e25fSSatish Balay PetscFunctionReturn(0); 181249b5e25fSSatish Balay } 181349b5e25fSSatish Balay 18144a2ae208SSatish Balay #undef __FUNCT__ 18154a2ae208SSatish Balay #define __FUNCT__ "MatDuplicate_SeqSBAIJ" 1816dfbe8321SBarry Smith PetscErrorCode MatDuplicate_SeqSBAIJ(Mat A,MatDuplicateOption cpvalues,Mat *B) 181749b5e25fSSatish Balay { 181849b5e25fSSatish Balay Mat C; 181949b5e25fSSatish Balay Mat_SeqSBAIJ *c,*a = (Mat_SeqSBAIJ*)A->data; 18206849ba73SBarry Smith PetscErrorCode ierr; 1821b40805acSSatish Balay PetscInt i,mbs = a->mbs,nz = a->nz,bs2 =a->bs2; 182249b5e25fSSatish Balay 182349b5e25fSSatish Balay PetscFunctionBegin; 182429bbc08cSBarry Smith if (a->i[mbs] != nz) SETERRQ(PETSC_ERR_PLIB,"Corrupt matrix"); 182549b5e25fSSatish Balay 182649b5e25fSSatish Balay *B = 0; 18277adad957SLisandro Dalcin ierr = MatCreate(((PetscObject)A)->comm,&C);CHKERRQ(ierr); 1828d0f46423SBarry Smith ierr = MatSetSizes(C,A->rmap->N,A->cmap->n,A->rmap->N,A->cmap->n);CHKERRQ(ierr); 18297adad957SLisandro Dalcin ierr = MatSetType(C,((PetscObject)A)->type_name);CHKERRQ(ierr); 18301d5dac46SHong Zhang ierr = PetscMemcpy(C->ops,A->ops,sizeof(struct _MatOps));CHKERRQ(ierr); 1831692f9cbeSHong Zhang c = (Mat_SeqSBAIJ*)C->data; 1832692f9cbeSHong Zhang 1833273d9f13SBarry Smith C->preallocated = PETSC_TRUE; 183449b5e25fSSatish Balay C->factor = A->factor; 183549b5e25fSSatish Balay c->row = 0; 183649b5e25fSSatish Balay c->icol = 0; 183749b5e25fSSatish Balay c->saved_values = 0; 183849b5e25fSSatish Balay c->keepzeroedrows = a->keepzeroedrows; 183949b5e25fSSatish Balay C->assembled = PETSC_TRUE; 184049b5e25fSSatish Balay 1841d0f46423SBarry Smith ierr = PetscMapCopy(((PetscObject)A)->comm,A->rmap,C->rmap);CHKERRQ(ierr); 1842d0f46423SBarry Smith ierr = PetscMapCopy(((PetscObject)A)->comm,A->cmap,C->cmap);CHKERRQ(ierr); 184349b5e25fSSatish Balay c->bs2 = a->bs2; 184449b5e25fSSatish Balay c->mbs = a->mbs; 184549b5e25fSSatish Balay c->nbs = a->nbs; 184649b5e25fSSatish Balay 18478777fc3fSSatish Balay ierr = PetscMalloc2((mbs+1),PetscInt,&c->imax,(mbs+1),PetscInt,&c->ilen);CHKERRQ(ierr); 184849b5e25fSSatish Balay for (i=0; i<mbs; i++) { 184949b5e25fSSatish Balay c->imax[i] = a->imax[i]; 185049b5e25fSSatish Balay c->ilen[i] = a->ilen[i]; 185149b5e25fSSatish Balay } 185249b5e25fSSatish Balay 185349b5e25fSSatish Balay /* allocate the matrix space */ 1854b40805acSSatish Balay ierr = PetscMalloc3(bs2*nz,MatScalar,&c->a,nz,PetscInt,&c->j,mbs+1,PetscInt,&c->i);CHKERRQ(ierr); 185549b5e25fSSatish Balay c->singlemalloc = PETSC_TRUE; 185613f74950SBarry Smith ierr = PetscMemcpy(c->i,a->i,(mbs+1)*sizeof(PetscInt));CHKERRQ(ierr); 1857b40805acSSatish Balay ierr = PetscLogObjectMemory(C,(mbs+1)*sizeof(PetscInt) + nz*(bs2*sizeof(MatScalar) + sizeof(PetscInt)));CHKERRQ(ierr); 185849b5e25fSSatish Balay if (mbs > 0) { 185913f74950SBarry Smith ierr = PetscMemcpy(c->j,a->j,nz*sizeof(PetscInt));CHKERRQ(ierr); 186049b5e25fSSatish Balay if (cpvalues == MAT_COPY_VALUES) { 186149b5e25fSSatish Balay ierr = PetscMemcpy(c->a,a->a,bs2*nz*sizeof(MatScalar));CHKERRQ(ierr); 186249b5e25fSSatish Balay } else { 186349b5e25fSSatish Balay ierr = PetscMemzero(c->a,bs2*nz*sizeof(MatScalar));CHKERRQ(ierr); 186449b5e25fSSatish Balay } 186549b5e25fSSatish Balay } 186649b5e25fSSatish Balay 186749b5e25fSSatish Balay c->roworiented = a->roworiented; 186849b5e25fSSatish Balay c->nonew = a->nonew; 186949b5e25fSSatish Balay 187049b5e25fSSatish Balay if (a->diag) { 187113f74950SBarry Smith ierr = PetscMalloc((mbs+1)*sizeof(PetscInt),&c->diag);CHKERRQ(ierr); 187252e6d16bSBarry Smith ierr = PetscLogObjectMemory(C,(mbs+1)*sizeof(PetscInt));CHKERRQ(ierr); 187349b5e25fSSatish Balay for (i=0; i<mbs; i++) { 187449b5e25fSSatish Balay c->diag[i] = a->diag[i]; 187549b5e25fSSatish Balay } 187649b5e25fSSatish Balay } else c->diag = 0; 18776c6c5352SBarry Smith c->nz = a->nz; 18786c6c5352SBarry Smith c->maxnz = a->maxnz; 187949b5e25fSSatish Balay c->solve_work = 0; 188049b5e25fSSatish Balay c->mult_work = 0; 1881e6b907acSBarry Smith c->free_a = PETSC_TRUE; 1882e6b907acSBarry Smith c->free_ij = PETSC_TRUE; 188349b5e25fSSatish Balay *B = C; 18847adad957SLisandro Dalcin ierr = PetscFListDuplicate(((PetscObject)A)->qlist,&((PetscObject)C)->qlist);CHKERRQ(ierr); 188549b5e25fSSatish Balay PetscFunctionReturn(0); 188649b5e25fSSatish Balay } 188749b5e25fSSatish Balay 18884a2ae208SSatish Balay #undef __FUNCT__ 18894a2ae208SSatish Balay #define __FUNCT__ "MatLoad_SeqSBAIJ" 1890a313700dSBarry Smith PetscErrorCode MatLoad_SeqSBAIJ(PetscViewer viewer, const MatType type,Mat *A) 189149b5e25fSSatish Balay { 189249b5e25fSSatish Balay Mat_SeqSBAIJ *a; 189349b5e25fSSatish Balay Mat B; 18946849ba73SBarry Smith PetscErrorCode ierr; 189513f74950SBarry Smith int fd; 189613f74950SBarry Smith PetscMPIInt size; 189713f74950SBarry Smith PetscInt i,nz,header[4],*rowlengths=0,M,N,bs=1; 189813f74950SBarry Smith PetscInt *mask,mbs,*jj,j,rowcount,nzcount,k,*s_browlengths,maskcount; 189913f74950SBarry Smith PetscInt kmax,jcount,block,idx,point,nzcountb,extra_rows; 190013f74950SBarry Smith PetscInt *masked,nmask,tmp,bs2,ishift; 190187828ca2SBarry Smith PetscScalar *aa; 190249b5e25fSSatish Balay MPI_Comm comm = ((PetscObject)viewer)->comm; 190349b5e25fSSatish Balay 190449b5e25fSSatish Balay PetscFunctionBegin; 1905b0a32e0cSBarry Smith ierr = PetscOptionsGetInt(PETSC_NULL,"-matload_block_size",&bs,PETSC_NULL);CHKERRQ(ierr); 190649b5e25fSSatish Balay bs2 = bs*bs; 190749b5e25fSSatish Balay 190849b5e25fSSatish Balay ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); 190929bbc08cSBarry Smith if (size > 1) SETERRQ(PETSC_ERR_ARG_WRONG,"view must have one processor"); 1910b0a32e0cSBarry Smith ierr = PetscViewerBinaryGetDescriptor(viewer,&fd);CHKERRQ(ierr); 191149b5e25fSSatish Balay ierr = PetscBinaryRead(fd,header,4,PETSC_INT);CHKERRQ(ierr); 1912552e946dSBarry Smith if (header[0] != MAT_FILE_COOKIE) SETERRQ(PETSC_ERR_FILE_UNEXPECTED,"not Mat object"); 191349b5e25fSSatish Balay M = header[1]; N = header[2]; nz = header[3]; 191449b5e25fSSatish Balay 191549b5e25fSSatish Balay if (header[3] < 0) { 191629bbc08cSBarry Smith SETERRQ(PETSC_ERR_FILE_UNEXPECTED,"Matrix stored in special format, cannot load as SeqSBAIJ"); 191749b5e25fSSatish Balay } 191849b5e25fSSatish Balay 191929bbc08cSBarry Smith if (M != N) SETERRQ(PETSC_ERR_SUP,"Can only do square matrices"); 192049b5e25fSSatish Balay 192149b5e25fSSatish Balay /* 192249b5e25fSSatish Balay This code adds extra rows to make sure the number of rows is 192349b5e25fSSatish Balay divisible by the blocksize 192449b5e25fSSatish Balay */ 192549b5e25fSSatish Balay mbs = M/bs; 192649b5e25fSSatish Balay extra_rows = bs - M + bs*(mbs); 192749b5e25fSSatish Balay if (extra_rows == bs) extra_rows = 0; 192849b5e25fSSatish Balay else mbs++; 192949b5e25fSSatish Balay if (extra_rows) { 19301e2582c4SBarry Smith ierr = PetscInfo(viewer,"Padding loaded matrix to match blocksize\n");CHKERRQ(ierr); 193149b5e25fSSatish Balay } 193249b5e25fSSatish Balay 193349b5e25fSSatish Balay /* read in row lengths */ 193413f74950SBarry Smith ierr = PetscMalloc((M+extra_rows)*sizeof(PetscInt),&rowlengths);CHKERRQ(ierr); 193549b5e25fSSatish Balay ierr = PetscBinaryRead(fd,rowlengths,M,PETSC_INT);CHKERRQ(ierr); 193649b5e25fSSatish Balay for (i=0; i<extra_rows; i++) rowlengths[M+i] = 1; 193749b5e25fSSatish Balay 193849b5e25fSSatish Balay /* read in column indices */ 193913f74950SBarry Smith ierr = PetscMalloc((nz+extra_rows)*sizeof(PetscInt),&jj);CHKERRQ(ierr); 194049b5e25fSSatish Balay ierr = PetscBinaryRead(fd,jj,nz,PETSC_INT);CHKERRQ(ierr); 194149b5e25fSSatish Balay for (i=0; i<extra_rows; i++) jj[nz+i] = M+i; 194249b5e25fSSatish Balay 194349b5e25fSSatish Balay /* loop over row lengths determining block row lengths */ 194413f74950SBarry Smith ierr = PetscMalloc(mbs*sizeof(PetscInt),&s_browlengths);CHKERRQ(ierr); 194513f74950SBarry Smith ierr = PetscMemzero(s_browlengths,mbs*sizeof(PetscInt));CHKERRQ(ierr); 194613f74950SBarry Smith ierr = PetscMalloc(2*mbs*sizeof(PetscInt),&mask);CHKERRQ(ierr); 194713f74950SBarry Smith ierr = PetscMemzero(mask,mbs*sizeof(PetscInt));CHKERRQ(ierr); 194849b5e25fSSatish Balay masked = mask + mbs; 194949b5e25fSSatish Balay rowcount = 0; nzcount = 0; 195049b5e25fSSatish Balay for (i=0; i<mbs; i++) { 195149b5e25fSSatish Balay nmask = 0; 195249b5e25fSSatish Balay for (j=0; j<bs; j++) { 195349b5e25fSSatish Balay kmax = rowlengths[rowcount]; 195449b5e25fSSatish Balay for (k=0; k<kmax; k++) { 19552d703238SHong Zhang tmp = jj[nzcount++]/bs; /* block col. index */ 195603630b6eSHong Zhang if (!mask[tmp] && tmp >= i) {masked[nmask++] = tmp; mask[tmp] = 1;} 195749b5e25fSSatish Balay } 195849b5e25fSSatish Balay rowcount++; 195949b5e25fSSatish Balay } 1960574b2666SHong Zhang s_browlengths[i] += nmask; 1961574b2666SHong Zhang 196249b5e25fSSatish Balay /* zero out the mask elements we set */ 196349b5e25fSSatish Balay for (j=0; j<nmask; j++) mask[masked[j]] = 0; 196449b5e25fSSatish Balay } 196549b5e25fSSatish Balay 196649b5e25fSSatish Balay /* create our matrix */ 1967f69a0ea3SMatthew Knepley ierr = MatCreate(comm,&B);CHKERRQ(ierr); 1968f69a0ea3SMatthew Knepley ierr = MatSetSizes(B,M+extra_rows,N+extra_rows,M+extra_rows,N+extra_rows);CHKERRQ(ierr); 19699abb65ffSKris Buschelman ierr = MatSetType(B,type);CHKERRQ(ierr); 1970ab93d7beSBarry Smith ierr = MatSeqSBAIJSetPreallocation_SeqSBAIJ(B,bs,0,s_browlengths);CHKERRQ(ierr); 197149b5e25fSSatish Balay a = (Mat_SeqSBAIJ*)B->data; 197249b5e25fSSatish Balay 197349b5e25fSSatish Balay /* set matrix "i" values */ 197449b5e25fSSatish Balay a->i[0] = 0; 197549b5e25fSSatish Balay for (i=1; i<= mbs; i++) { 1976574b2666SHong Zhang a->i[i] = a->i[i-1] + s_browlengths[i-1]; 1977574b2666SHong Zhang a->ilen[i-1] = s_browlengths[i-1]; 197849b5e25fSSatish Balay } 19796c6c5352SBarry Smith a->nz = a->i[mbs]; 198049b5e25fSSatish Balay 198149b5e25fSSatish Balay /* read in nonzero values */ 198287828ca2SBarry Smith ierr = PetscMalloc((nz+extra_rows)*sizeof(PetscScalar),&aa);CHKERRQ(ierr); 198349b5e25fSSatish Balay ierr = PetscBinaryRead(fd,aa,nz,PETSC_SCALAR);CHKERRQ(ierr); 198449b5e25fSSatish Balay for (i=0; i<extra_rows; i++) aa[nz+i] = 1.0; 198549b5e25fSSatish Balay 198649b5e25fSSatish Balay /* set "a" and "j" values into matrix */ 198749b5e25fSSatish Balay nzcount = 0; jcount = 0; 198849b5e25fSSatish Balay for (i=0; i<mbs; i++) { 198949b5e25fSSatish Balay nzcountb = nzcount; 199049b5e25fSSatish Balay nmask = 0; 199149b5e25fSSatish Balay for (j=0; j<bs; j++) { 199249b5e25fSSatish Balay kmax = rowlengths[i*bs+j]; 199349b5e25fSSatish Balay for (k=0; k<kmax; k++) { 19942d703238SHong Zhang tmp = jj[nzcount++]/bs; /* block col. index */ 199503630b6eSHong Zhang if (!mask[tmp] && tmp >= i) { masked[nmask++] = tmp; mask[tmp] = 1;} 19962d703238SHong Zhang } 19972d703238SHong Zhang } 19982d703238SHong Zhang /* sort the masked values */ 19992d703238SHong Zhang ierr = PetscSortInt(nmask,masked);CHKERRQ(ierr); 20002d703238SHong Zhang 20012d703238SHong Zhang /* set "j" values into matrix */ 20022d703238SHong Zhang maskcount = 1; 20032d703238SHong Zhang for (j=0; j<nmask; j++) { 200449b5e25fSSatish Balay a->j[jcount++] = masked[j]; 200549b5e25fSSatish Balay mask[masked[j]] = maskcount++; 200649b5e25fSSatish Balay } 2007574b2666SHong Zhang 200849b5e25fSSatish Balay /* set "a" values into matrix */ 200949b5e25fSSatish Balay ishift = bs2*a->i[i]; 201049b5e25fSSatish Balay for (j=0; j<bs; j++) { 201149b5e25fSSatish Balay kmax = rowlengths[i*bs+j]; 201249b5e25fSSatish Balay for (k=0; k<kmax; k++) { 2013574b2666SHong Zhang tmp = jj[nzcountb]/bs ; /* block col. index */ 2014574b2666SHong Zhang if (tmp >= i){ 201549b5e25fSSatish Balay block = mask[tmp] - 1; 201649b5e25fSSatish Balay point = jj[nzcountb] - bs*tmp; 201749b5e25fSSatish Balay idx = ishift + bs2*block + j + bs*point; 2018574b2666SHong Zhang a->a[idx] = aa[nzcountb]; 2019574b2666SHong Zhang } 2020574b2666SHong Zhang nzcountb++; 202149b5e25fSSatish Balay } 202249b5e25fSSatish Balay } 202349b5e25fSSatish Balay /* zero out the mask elements we set */ 202449b5e25fSSatish Balay for (j=0; j<nmask; j++) mask[masked[j]] = 0; 202549b5e25fSSatish Balay } 20266c6c5352SBarry Smith if (jcount != a->nz) SETERRQ(PETSC_ERR_FILE_UNEXPECTED,"Bad binary matrix"); 202749b5e25fSSatish Balay 202849b5e25fSSatish Balay ierr = PetscFree(rowlengths);CHKERRQ(ierr); 2029574b2666SHong Zhang ierr = PetscFree(s_browlengths);CHKERRQ(ierr); 203049b5e25fSSatish Balay ierr = PetscFree(aa);CHKERRQ(ierr); 203149b5e25fSSatish Balay ierr = PetscFree(jj);CHKERRQ(ierr); 203249b5e25fSSatish Balay ierr = PetscFree(mask);CHKERRQ(ierr); 203349b5e25fSSatish Balay 20349abb65ffSKris Buschelman ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 20359abb65ffSKris Buschelman ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 203649b5e25fSSatish Balay ierr = MatView_Private(B);CHKERRQ(ierr); 20379abb65ffSKris Buschelman *A = B; 203849b5e25fSSatish Balay PetscFunctionReturn(0); 203949b5e25fSSatish Balay } 2040574b2666SHong Zhang 2041d06b337dSHong Zhang #undef __FUNCT__ 2042d06b337dSHong Zhang #define __FUNCT__ "MatRelax_SeqSBAIJ" 204313f74950SBarry Smith PetscErrorCode MatRelax_SeqSBAIJ(Mat A,Vec bb,PetscReal omega,MatSORType flag,PetscReal fshift,PetscInt its,PetscInt lits,Vec xx) 2044d06b337dSHong Zhang { 2045d06b337dSHong Zhang Mat_SeqSBAIJ *a = (Mat_SeqSBAIJ*)A->data; 2046d06b337dSHong Zhang MatScalar *aa=a->a,*v,*v1; 2047d06b337dSHong Zhang PetscScalar *x,*b,*t,sum,d; 20486849ba73SBarry Smith PetscErrorCode ierr; 2049d0f46423SBarry Smith PetscInt m=a->mbs,bs=A->rmap->bs,*ai=a->i,*aj=a->j; 2050521d7252SBarry Smith PetscInt nz,nz1,*vj,*vj1,i; 2051d06b337dSHong Zhang 2052d06b337dSHong Zhang PetscFunctionBegin; 205351f519a2SBarry Smith if (flag & SOR_EISENSTAT) SETERRQ(PETSC_ERR_SUP,"No support yet for Eisenstat"); 205451f519a2SBarry Smith 2055b965ef7fSBarry Smith its = its*lits; 205677431f27SBarry Smith if (its <= 0) SETERRQ2(PETSC_ERR_ARG_WRONG,"Relaxation requires global its %D and local its %D both positive",its,lits); 2057d06b337dSHong Zhang 2058d06b337dSHong Zhang if (bs > 1) 2059d06b337dSHong Zhang SETERRQ(PETSC_ERR_SUP,"SSOR for block size > 1 is not yet implemented"); 2060d06b337dSHong Zhang 20611ebc52fbSHong Zhang ierr = VecGetArray(xx,&x);CHKERRQ(ierr); 2062d06b337dSHong Zhang if (xx != bb) { 20631ebc52fbSHong Zhang ierr = VecGetArray(bb,&b);CHKERRQ(ierr); 2064d06b337dSHong Zhang } else { 2065d06b337dSHong Zhang b = x; 2066d06b337dSHong Zhang } 2067d06b337dSHong Zhang 2068e2ee2a47SBarry Smith if (!a->relax_work) { 2069e2ee2a47SBarry Smith ierr = PetscMalloc(m*sizeof(PetscScalar),&a->relax_work);CHKERRQ(ierr); 2070e2ee2a47SBarry Smith } 2071e2ee2a47SBarry Smith t = a->relax_work; 2072d06b337dSHong Zhang 2073d06b337dSHong Zhang if (flag & SOR_ZERO_INITIAL_GUESS) { 20742798e883SHong Zhang if (flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP){ 2075290bbb0aSBarry Smith ierr = PetscMemcpy(t,b,m*sizeof(PetscScalar));CHKERRQ(ierr); 2076d06b337dSHong Zhang 2077d06b337dSHong Zhang for (i=0; i<m; i++){ 207844706875SHong Zhang d = *(aa + ai[i]); /* diag[i] */ 2079d06b337dSHong Zhang v = aa + ai[i] + 1; 2080d06b337dSHong Zhang vj = aj + ai[i] + 1; 2081d06b337dSHong Zhang nz = ai[i+1] - ai[i] - 1; 2082e6b907acSBarry Smith ierr = PetscLogFlops(2*nz-1);CHKERRQ(ierr); 2083d06b337dSHong Zhang x[i] = omega*t[i]/d; 2084d06b337dSHong Zhang while (nz--) t[*vj++] -= x[i]*(*v++); /* update rhs */ 2085d06b337dSHong Zhang } 2086d06b337dSHong Zhang } 2087d06b337dSHong Zhang 20882798e883SHong Zhang if (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP){ 208995d750ceSBarry Smith if (!(flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP)){ 209095d750ceSBarry Smith t = b; 2091d06b337dSHong Zhang } 209295d750ceSBarry Smith 2093d06b337dSHong Zhang for (i=m-1; i>=0; i--){ 2094d06b337dSHong Zhang d = *(aa + ai[i]); 2095d06b337dSHong Zhang v = aa + ai[i] + 1; 2096d06b337dSHong Zhang vj = aj + ai[i] + 1; 2097d06b337dSHong Zhang nz = ai[i+1] - ai[i] - 1; 2098e6b907acSBarry Smith ierr = PetscLogFlops(2*nz-1);CHKERRQ(ierr); 2099d06b337dSHong Zhang sum = t[i]; 2100d06b337dSHong Zhang while (nz--) sum -= x[*vj++]*(*v++); 2101d06b337dSHong Zhang x[i] = (1-omega)*x[i] + omega*sum/d; 2102d06b337dSHong Zhang } 210395d750ceSBarry Smith t = a->relax_work; 2104d06b337dSHong Zhang } 2105d06b337dSHong Zhang its--; 2106d06b337dSHong Zhang } 2107d06b337dSHong Zhang 2108d06b337dSHong Zhang while (its--) { 210944706875SHong Zhang /* 211044706875SHong Zhang forward sweep: 211144706875SHong Zhang for i=0,...,m-1: 211244706875SHong Zhang sum[i] = (b[i] - U(i,:)x )/d[i]; 211344706875SHong Zhang x[i] = (1-omega)x[i] + omega*sum[i]; 211444706875SHong Zhang b = b - x[i]*U^T(i,:); 2115d06b337dSHong Zhang 211644706875SHong Zhang */ 21172798e883SHong Zhang if (flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP){ 2118290bbb0aSBarry Smith ierr = PetscMemcpy(t,b,m*sizeof(PetscScalar));CHKERRQ(ierr); 2119d06b337dSHong Zhang 2120d06b337dSHong Zhang for (i=0; i<m; i++){ 212144706875SHong Zhang d = *(aa + ai[i]); /* diag[i] */ 2122d06b337dSHong Zhang v = aa + ai[i] + 1; v1=v; 2123d06b337dSHong Zhang vj = aj + ai[i] + 1; vj1=vj; 2124d06b337dSHong Zhang nz = ai[i+1] - ai[i] - 1; nz1=nz; 2125d06b337dSHong Zhang sum = t[i]; 2126e6b907acSBarry Smith ierr = PetscLogFlops(4*nz-2);CHKERRQ(ierr); 2127d06b337dSHong Zhang while (nz1--) sum -= (*v1++)*x[*vj1++]; 2128d06b337dSHong Zhang x[i] = (1-omega)*x[i] + omega*sum/d; 2129d06b337dSHong Zhang while (nz--) t[*vj++] -= x[i]*(*v++); 2130d06b337dSHong Zhang } 2131d06b337dSHong Zhang } 2132d06b337dSHong Zhang 21332798e883SHong Zhang if (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP){ 213444706875SHong Zhang /* 213544706875SHong Zhang backward sweep: 213644706875SHong Zhang b = b - x[i]*U^T(i,:), i=0,...,n-2 213744706875SHong Zhang for i=m-1,...,0: 213844706875SHong Zhang sum[i] = (b[i] - U(i,:)x )/d[i]; 213944706875SHong Zhang x[i] = (1-omega)x[i] + omega*sum[i]; 214044706875SHong Zhang */ 214195d750ceSBarry Smith /* if there was a forward sweep done above then I thing the next two for loops are not needed */ 2142290bbb0aSBarry Smith ierr = PetscMemcpy(t,b,m*sizeof(PetscScalar));CHKERRQ(ierr); 2143d06b337dSHong Zhang 2144d06b337dSHong Zhang for (i=0; i<m-1; i++){ /* update rhs */ 2145d06b337dSHong Zhang v = aa + ai[i] + 1; 2146d06b337dSHong Zhang vj = aj + ai[i] + 1; 2147d06b337dSHong Zhang nz = ai[i+1] - ai[i] - 1; 2148efee365bSSatish Balay ierr = PetscLogFlops(2*nz-1);CHKERRQ(ierr); 2149e6b907acSBarry Smith while (nz--) t[*vj++] -= x[i]*(*v++); 2150d06b337dSHong Zhang } 2151d06b337dSHong Zhang for (i=m-1; i>=0; i--){ 2152d06b337dSHong Zhang d = *(aa + ai[i]); 2153d06b337dSHong Zhang v = aa + ai[i] + 1; 2154d06b337dSHong Zhang vj = aj + ai[i] + 1; 2155d06b337dSHong Zhang nz = ai[i+1] - ai[i] - 1; 2156e6b907acSBarry Smith ierr = PetscLogFlops(2*nz-1);CHKERRQ(ierr); 2157d06b337dSHong Zhang sum = t[i]; 2158d06b337dSHong Zhang while (nz--) sum -= x[*vj++]*(*v++); 2159d06b337dSHong Zhang x[i] = (1-omega)*x[i] + omega*sum/d; 2160d06b337dSHong Zhang } 2161d06b337dSHong Zhang } 2162d06b337dSHong Zhang } 2163d06b337dSHong Zhang 21641ebc52fbSHong Zhang ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr); 2165d06b337dSHong Zhang if (bb != xx) { 21661ebc52fbSHong Zhang ierr = VecRestoreArray(bb,&b);CHKERRQ(ierr); 2167d06b337dSHong Zhang } 2168d06b337dSHong Zhang PetscFunctionReturn(0); 2169d06b337dSHong Zhang } 2170d06b337dSHong Zhang 2171c75a6043SHong Zhang #undef __FUNCT__ 2172c75a6043SHong Zhang #define __FUNCT__ "MatCreateSeqSBAIJWithArrays" 2173c75a6043SHong Zhang /*@ 2174c75a6043SHong Zhang MatCreateSeqSBAIJWithArrays - Creates an sequential SBAIJ matrix using matrix elements 2175c75a6043SHong Zhang (upper triangular entries in CSR format) provided by the user. 2176c75a6043SHong Zhang 2177c75a6043SHong Zhang Collective on MPI_Comm 2178c75a6043SHong Zhang 2179c75a6043SHong Zhang Input Parameters: 2180c75a6043SHong Zhang + comm - must be an MPI communicator of size 1 2181c75a6043SHong Zhang . bs - size of block 2182c75a6043SHong Zhang . m - number of rows 2183c75a6043SHong Zhang . n - number of columns 2184c75a6043SHong Zhang . i - row indices 2185c75a6043SHong Zhang . j - column indices 2186c75a6043SHong Zhang - a - matrix values 2187c75a6043SHong Zhang 2188c75a6043SHong Zhang Output Parameter: 2189c75a6043SHong Zhang . mat - the matrix 2190c75a6043SHong Zhang 2191c75a6043SHong Zhang Level: intermediate 2192c75a6043SHong Zhang 2193c75a6043SHong Zhang Notes: 2194c75a6043SHong Zhang The i, j, and a arrays are not copied by this routine, the user must free these arrays 2195c75a6043SHong Zhang once the matrix is destroyed 2196c75a6043SHong Zhang 2197c75a6043SHong Zhang You cannot set new nonzero locations into this matrix, that will generate an error. 2198c75a6043SHong Zhang 2199c75a6043SHong Zhang The i and j indices are 0 based 2200c75a6043SHong Zhang 2201c75a6043SHong Zhang .seealso: MatCreate(), MatCreateMPISBAIJ(), MatCreateSeqSBAIJ() 2202c75a6043SHong Zhang 2203c75a6043SHong Zhang @*/ 2204c75a6043SHong Zhang PetscErrorCode PETSCMAT_DLLEXPORT MatCreateSeqSBAIJWithArrays(MPI_Comm comm,PetscInt bs,PetscInt m,PetscInt n,PetscInt* i,PetscInt*j,PetscScalar *a,Mat *mat) 2205c75a6043SHong Zhang { 2206c75a6043SHong Zhang PetscErrorCode ierr; 2207c75a6043SHong Zhang PetscInt ii; 2208c75a6043SHong Zhang Mat_SeqSBAIJ *sbaij; 2209c75a6043SHong Zhang 2210c75a6043SHong Zhang PetscFunctionBegin; 2211c75a6043SHong Zhang if (bs != 1) SETERRQ1(PETSC_ERR_SUP,"block size %D > 1 is not supported yet",bs); 2212c75a6043SHong Zhang if (i[0]) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"i (row indices) must start with 0"); 2213c75a6043SHong Zhang 2214c75a6043SHong Zhang ierr = MatCreate(comm,mat);CHKERRQ(ierr); 2215c75a6043SHong Zhang ierr = MatSetSizes(*mat,m,n,m,n);CHKERRQ(ierr); 2216c75a6043SHong Zhang ierr = MatSetType(*mat,MATSEQSBAIJ);CHKERRQ(ierr); 2217c75a6043SHong Zhang ierr = MatSeqSBAIJSetPreallocation_SeqSBAIJ(*mat,bs,MAT_SKIP_ALLOCATION,0);CHKERRQ(ierr); 2218c75a6043SHong Zhang sbaij = (Mat_SeqSBAIJ*)(*mat)->data; 2219c75a6043SHong Zhang ierr = PetscMalloc2(m,PetscInt,&sbaij->imax,m,PetscInt,&sbaij->ilen);CHKERRQ(ierr); 2220c75a6043SHong Zhang 2221c75a6043SHong Zhang sbaij->i = i; 2222c75a6043SHong Zhang sbaij->j = j; 2223c75a6043SHong Zhang sbaij->a = a; 2224c75a6043SHong Zhang sbaij->singlemalloc = PETSC_FALSE; 2225c75a6043SHong Zhang sbaij->nonew = -1; /*this indicates that inserting a new value in the matrix that generates a new nonzero is an error*/ 2226e6b907acSBarry Smith sbaij->free_a = PETSC_FALSE; 2227e6b907acSBarry Smith sbaij->free_ij = PETSC_FALSE; 2228c75a6043SHong Zhang 2229c75a6043SHong Zhang for (ii=0; ii<m; ii++) { 2230c75a6043SHong Zhang sbaij->ilen[ii] = sbaij->imax[ii] = i[ii+1] - i[ii]; 2231c75a6043SHong Zhang #if defined(PETSC_USE_DEBUG) 2232c75a6043SHong 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]); 2233c75a6043SHong Zhang #endif 2234c75a6043SHong Zhang } 2235c75a6043SHong Zhang #if defined(PETSC_USE_DEBUG) 2236c75a6043SHong Zhang for (ii=0; ii<sbaij->i[m]; ii++) { 2237c75a6043SHong Zhang if (j[ii] < 0) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"Negative column index at location = %d index = %d",ii,j[ii]); 2238c75a6043SHong Zhang if (j[ii] > n - 1) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"Column index to large at location = %d index = %d",ii,j[ii]); 2239c75a6043SHong Zhang } 2240c75a6043SHong Zhang #endif 2241c75a6043SHong Zhang 2242c75a6043SHong Zhang ierr = MatAssemblyBegin(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2243c75a6043SHong Zhang ierr = MatAssemblyEnd(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2244c75a6043SHong Zhang PetscFunctionReturn(0); 2245c75a6043SHong Zhang } 2246d06b337dSHong Zhang 2247d06b337dSHong Zhang 2248d06b337dSHong Zhang 224949b5e25fSSatish Balay 225049b5e25fSSatish Balay 2251