1be1d678aSKris Buschelman #define PETSCMAT_DLL 249b5e25fSSatish Balay 349b5e25fSSatish Balay /* 4a1373b80SHong Zhang Defines the basic matrix operations for the SBAIJ (compressed row) 549b5e25fSSatish Balay matrix storage format. 649b5e25fSSatish Balay */ 77c4f633dSBarry Smith #include "../src/mat/impls/baij/seq/baij.h" /*I "petscmat.h" I*/ 87c4f633dSBarry Smith #include "../src/mat/impls/sbaij/seq/sbaij.h" 949b5e25fSSatish Balay 10db4efbfdSBarry Smith extern PetscErrorCode MatSeqSBAIJSetNumericFactorization(Mat,PetscTruth); 1149b5e25fSSatish Balay #define CHUNKSIZE 10 1249b5e25fSSatish Balay 1349b5e25fSSatish Balay /* 1449b5e25fSSatish Balay Checks for missing diagonals 1549b5e25fSSatish Balay */ 164a2ae208SSatish Balay #undef __FUNCT__ 174a2ae208SSatish Balay #define __FUNCT__ "MatMissingDiagonal_SeqSBAIJ" 182af78befSBarry Smith PetscErrorCode MatMissingDiagonal_SeqSBAIJ(Mat A,PetscTruth *missing,PetscInt *dd) 1949b5e25fSSatish Balay { 20045c9aa0SHong Zhang Mat_SeqSBAIJ *a = (Mat_SeqSBAIJ*)A->data; 216849ba73SBarry Smith PetscErrorCode ierr; 2213f74950SBarry Smith PetscInt *diag,*jj = a->j,i; 2349b5e25fSSatish Balay 2449b5e25fSSatish Balay PetscFunctionBegin; 25045c9aa0SHong Zhang ierr = MatMarkDiagonal_SeqSBAIJ(A);CHKERRQ(ierr); 2649b5e25fSSatish Balay diag = a->diag; 272af78befSBarry Smith *missing = PETSC_FALSE; 2849b5e25fSSatish Balay for (i=0; i<a->mbs; i++) { 292af78befSBarry Smith if (jj[diag[i]] != i) { 302af78befSBarry Smith *missing = PETSC_TRUE; 312af78befSBarry Smith if (dd) *dd = i; 322af78befSBarry Smith break; 332af78befSBarry Smith } 3449b5e25fSSatish Balay } 3549b5e25fSSatish Balay PetscFunctionReturn(0); 3649b5e25fSSatish Balay } 3749b5e25fSSatish Balay 384a2ae208SSatish Balay #undef __FUNCT__ 394a2ae208SSatish Balay #define __FUNCT__ "MatMarkDiagonal_SeqSBAIJ" 40dfbe8321SBarry Smith PetscErrorCode MatMarkDiagonal_SeqSBAIJ(Mat A) 4149b5e25fSSatish Balay { 42045c9aa0SHong Zhang Mat_SeqSBAIJ *a = (Mat_SeqSBAIJ*)A->data; 436849ba73SBarry Smith PetscErrorCode ierr; 4409f38230SBarry Smith PetscInt i; 4549b5e25fSSatish Balay 4649b5e25fSSatish Balay PetscFunctionBegin; 4709f38230SBarry Smith if (!a->diag) { 4809f38230SBarry Smith ierr = PetscMalloc(a->mbs*sizeof(PetscInt),&a->diag);CHKERRQ(ierr); 4909f38230SBarry Smith } 5009f38230SBarry Smith for (i=0; i<a->mbs; i++) a->diag[i] = a->i[i]; 5149b5e25fSSatish Balay PetscFunctionReturn(0); 5249b5e25fSSatish Balay } 5349b5e25fSSatish Balay 544a2ae208SSatish Balay #undef __FUNCT__ 554a2ae208SSatish Balay #define __FUNCT__ "MatGetRowIJ_SeqSBAIJ" 568f7157efSSatish Balay static PetscErrorCode MatGetRowIJ_SeqSBAIJ(Mat A,PetscInt oshift,PetscTruth symmetric,PetscTruth blockcompressed,PetscInt *nn,PetscInt *ia[],PetscInt *ja[],PetscTruth *done) 5749b5e25fSSatish Balay { 58a6ece127SHong Zhang Mat_SeqSBAIJ *a = (Mat_SeqSBAIJ*)A->data; 59d0f46423SBarry Smith PetscInt i,j,n = a->mbs,nz = a->i[n],bs = A->rmap->bs; 608f7157efSSatish Balay PetscErrorCode ierr; 6149b5e25fSSatish Balay 6249b5e25fSSatish Balay PetscFunctionBegin; 63d3e5a4abSHong Zhang *nn = n; 64a1373b80SHong Zhang if (!ia) PetscFunctionReturn(0); 658f7157efSSatish Balay if (!blockcompressed) { 668f7157efSSatish Balay /* malloc & create the natural set of indices */ 67f1d0d59dSSatish Balay ierr = PetscMalloc2((n+1)*bs,PetscInt,ia,nz*bs,PetscInt,ja);CHKERRQ(ierr); 688f7157efSSatish Balay for (i=0; i<n+1; i++) { 698f7157efSSatish Balay for (j=0; j<bs; j++) { 708f7157efSSatish Balay *ia[i*bs+j] = a->i[i]*bs+j+oshift; 718f7157efSSatish Balay } 728f7157efSSatish Balay } 738f7157efSSatish Balay for (i=0; i<nz; i++) { 748f7157efSSatish Balay for (j=0; j<bs; j++) { 758f7157efSSatish Balay *ja[i*bs+j] = a->j[i]*bs+j+oshift; 768f7157efSSatish Balay } 778f7157efSSatish Balay } 788f7157efSSatish Balay } else { /* blockcompressed */ 79a6ece127SHong Zhang if (oshift == 1) { 80a6ece127SHong Zhang /* temporarily add 1 to i and j indices */ 816c6c5352SBarry Smith for (i=0; i<nz; i++) a->j[i]++; 82a1373b80SHong Zhang for (i=0; i<n+1; i++) a->i[i]++; 838f7157efSSatish Balay } 84a1373b80SHong Zhang *ia = a->i; *ja = a->j; 85a6ece127SHong Zhang } 868f7157efSSatish Balay 8749b5e25fSSatish Balay PetscFunctionReturn(0); 8849b5e25fSSatish Balay } 8949b5e25fSSatish Balay 904a2ae208SSatish Balay #undef __FUNCT__ 914a2ae208SSatish Balay #define __FUNCT__ "MatRestoreRowIJ_SeqSBAIJ" 928f7157efSSatish Balay static PetscErrorCode MatRestoreRowIJ_SeqSBAIJ(Mat A,PetscInt oshift,PetscTruth symmetric,PetscTruth blockcompressed,PetscInt *nn,PetscInt *ia[],PetscInt *ja[],PetscTruth *done) 9349b5e25fSSatish Balay { 94b7aaefc3SHong Zhang Mat_SeqSBAIJ *a = (Mat_SeqSBAIJ*)A->data; 958f7157efSSatish Balay PetscInt i,n = a->mbs,nz = a->i[n]; 968f7157efSSatish Balay PetscErrorCode ierr; 97a6ece127SHong Zhang 9849b5e25fSSatish Balay PetscFunctionBegin; 9949b5e25fSSatish Balay if (!ia) PetscFunctionReturn(0); 100a6ece127SHong Zhang 1018f7157efSSatish Balay if (!blockcompressed) { 1028f7157efSSatish Balay ierr = PetscFree2(*ia,*ja);CHKERRQ(ierr); 1038f7157efSSatish Balay } else if (oshift == 1) { /* blockcompressed */ 1046c6c5352SBarry Smith for (i=0; i<nz; i++) a->j[i]--; 105a6ece127SHong Zhang for (i=0; i<n+1; i++) a->i[i]--; 106a6ece127SHong Zhang } 1078f7157efSSatish Balay 108a6ece127SHong Zhang PetscFunctionReturn(0); 10949b5e25fSSatish Balay } 11049b5e25fSSatish Balay 1114a2ae208SSatish Balay #undef __FUNCT__ 1124a2ae208SSatish Balay #define __FUNCT__ "MatDestroy_SeqSBAIJ" 113dfbe8321SBarry Smith PetscErrorCode MatDestroy_SeqSBAIJ(Mat A) 11449b5e25fSSatish Balay { 11549b5e25fSSatish Balay Mat_SeqSBAIJ *a = (Mat_SeqSBAIJ*)A->data; 116dfbe8321SBarry Smith PetscErrorCode ierr; 11749b5e25fSSatish Balay 11849b5e25fSSatish Balay PetscFunctionBegin; 119a9f03627SSatish Balay #if defined(PETSC_USE_LOG) 120d0f46423SBarry Smith PetscLogObjectState((PetscObject)A,"Rows=%D, NZ=%D",A->rmap->N,a->nz); 121a9f03627SSatish Balay #endif 122e6b907acSBarry Smith ierr = MatSeqXAIJFreeAIJ(A,&a->a,&a->j,&a->i);CHKERRQ(ierr); 1239bfd6278SHong Zhang if (a->row) {ierr = ISDestroy(a->row);CHKERRQ(ierr);} 1249bfd6278SHong Zhang if (a->col){ierr = ISDestroy(a->col);CHKERRQ(ierr);} 1259bfd6278SHong Zhang if (a->icol) {ierr = ISDestroy(a->icol);CHKERRQ(ierr);} 126061b2667SBarry Smith if (a->idiag) {ierr = PetscFree(a->idiag);CHKERRQ(ierr);} 1270def2e27SBarry Smith if (a->inode.size) {ierr = PetscFree(a->inode.size);CHKERRQ(ierr);} 12805b42c5fSBarry Smith ierr = PetscFree(a->diag);CHKERRQ(ierr); 12905b42c5fSBarry Smith ierr = PetscFree2(a->imax,a->ilen);CHKERRQ(ierr); 13005b42c5fSBarry Smith ierr = PetscFree(a->solve_work);CHKERRQ(ierr); 131e2ee2a47SBarry Smith ierr = PetscFree(a->relax_work);CHKERRQ(ierr); 13205b42c5fSBarry Smith ierr = PetscFree(a->solves_work);CHKERRQ(ierr); 13305b42c5fSBarry Smith ierr = PetscFree(a->mult_work);CHKERRQ(ierr); 13405b42c5fSBarry Smith ierr = PetscFree(a->saved_values);CHKERRQ(ierr); 13505b42c5fSBarry Smith ierr = PetscFree(a->xtoy);CHKERRQ(ierr); 1361a3463dfSHong Zhang 1371a3463dfSHong Zhang ierr = PetscFree(a->inew);CHKERRQ(ierr); 13849b5e25fSSatish Balay ierr = PetscFree(a);CHKERRQ(ierr); 139901853e0SKris Buschelman 140dbd8c25aSHong Zhang ierr = PetscObjectChangeTypeName((PetscObject)A,0);CHKERRQ(ierr); 141901853e0SKris Buschelman ierr = PetscObjectComposeFunction((PetscObject)A,"MatStoreValues_C","",PETSC_NULL);CHKERRQ(ierr); 142901853e0SKris Buschelman ierr = PetscObjectComposeFunction((PetscObject)A,"MatRetrieveValues_C","",PETSC_NULL);CHKERRQ(ierr); 143901853e0SKris Buschelman ierr = PetscObjectComposeFunction((PetscObject)A,"MatSeqSBAIJSetColumnIndices_C","",PETSC_NULL);CHKERRQ(ierr); 144901853e0SKris Buschelman ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqsbaij_seqaij_C","",PETSC_NULL);CHKERRQ(ierr); 145901853e0SKris Buschelman ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqsbaij_seqbaij_C","",PETSC_NULL);CHKERRQ(ierr); 146901853e0SKris Buschelman ierr = PetscObjectComposeFunction((PetscObject)A,"MatSeqSBAIJSetPreallocation_C","",PETSC_NULL);CHKERRQ(ierr); 14749b5e25fSSatish Balay PetscFunctionReturn(0); 14849b5e25fSSatish Balay } 14949b5e25fSSatish Balay 1504a2ae208SSatish Balay #undef __FUNCT__ 1514a2ae208SSatish Balay #define __FUNCT__ "MatSetOption_SeqSBAIJ" 1524e0d8c25SBarry Smith PetscErrorCode MatSetOption_SeqSBAIJ(Mat A,MatOption op,PetscTruth flg) 15349b5e25fSSatish Balay { 154045c9aa0SHong Zhang Mat_SeqSBAIJ *a = (Mat_SeqSBAIJ*)A->data; 15563ba0a88SBarry Smith PetscErrorCode ierr; 15649b5e25fSSatish Balay 15749b5e25fSSatish Balay PetscFunctionBegin; 1584d9d31abSKris Buschelman switch (op) { 1594d9d31abSKris Buschelman case MAT_ROW_ORIENTED: 1604e0d8c25SBarry Smith a->roworiented = flg; 1614d9d31abSKris Buschelman break; 162a9817697SBarry Smith case MAT_KEEP_NONZERO_PATTERN: 163a9817697SBarry Smith a->keepnonzeropattern = flg; 1644d9d31abSKris Buschelman break; 165512a5fc5SBarry Smith case MAT_NEW_NONZERO_LOCATIONS: 166512a5fc5SBarry Smith a->nonew = (flg ? 0 : 1); 1674d9d31abSKris Buschelman break; 1684d9d31abSKris Buschelman case MAT_NEW_NONZERO_LOCATION_ERR: 1694e0d8c25SBarry Smith a->nonew = (flg ? -1 : 0); 1704d9d31abSKris Buschelman break; 1714d9d31abSKris Buschelman case MAT_NEW_NONZERO_ALLOCATION_ERR: 1724e0d8c25SBarry Smith a->nonew = (flg ? -2 : 0); 1734d9d31abSKris Buschelman break; 17428b2fa4aSMatthew Knepley case MAT_UNUSED_NONZERO_LOCATION_ERR: 17528b2fa4aSMatthew Knepley a->nounused = (flg ? -1 : 0); 17628b2fa4aSMatthew Knepley break; 1774e0d8c25SBarry Smith case MAT_NEW_DIAGONALS: 1784d9d31abSKris Buschelman case MAT_IGNORE_OFF_PROC_ENTRIES: 1794d9d31abSKris Buschelman case MAT_USE_HASH_TABLE: 180290bbb0aSBarry Smith ierr = PetscInfo1(A,"Option %s ignored\n",MatOptions[op]);CHKERRQ(ierr); 1814d9d31abSKris Buschelman break; 1829a4540c5SBarry Smith case MAT_HERMITIAN: 1834e0d8c25SBarry Smith if (flg) SETERRQ(PETSC_ERR_SUP,"Matrix must be symmetric"); 18477e54ba9SKris Buschelman case MAT_SYMMETRIC: 18577e54ba9SKris Buschelman case MAT_STRUCTURALLY_SYMMETRIC: 1869a4540c5SBarry Smith case MAT_SYMMETRY_ETERNAL: 1874e0d8c25SBarry Smith if (!flg) SETERRQ(PETSC_ERR_SUP,"Matrix must be symmetric"); 188290bbb0aSBarry Smith ierr = PetscInfo1(A,"Option %s not relevent\n",MatOptions[op]);CHKERRQ(ierr); 189290bbb0aSBarry Smith break; 190941593c8SHong Zhang case MAT_IGNORE_LOWER_TRIANGULAR: 1914e0d8c25SBarry Smith a->ignore_ltriangular = flg; 192941593c8SHong Zhang break; 193941593c8SHong Zhang case MAT_ERROR_LOWER_TRIANGULAR: 1944e0d8c25SBarry Smith a->ignore_ltriangular = flg; 19577e54ba9SKris Buschelman break; 196f5edf698SHong Zhang case MAT_GETROW_UPPERTRIANGULAR: 1974e0d8c25SBarry Smith a->getrow_utriangular = flg; 198f5edf698SHong Zhang break; 1994d9d31abSKris Buschelman default: 200ad86a440SBarry Smith SETERRQ1(PETSC_ERR_SUP,"unknown option %d",op); 20149b5e25fSSatish Balay } 20249b5e25fSSatish Balay PetscFunctionReturn(0); 20349b5e25fSSatish Balay } 20449b5e25fSSatish Balay 2054a2ae208SSatish Balay #undef __FUNCT__ 2064a2ae208SSatish Balay #define __FUNCT__ "MatGetRow_SeqSBAIJ" 20713f74950SBarry Smith PetscErrorCode MatGetRow_SeqSBAIJ(Mat A,PetscInt row,PetscInt *ncols,PetscInt **cols,PetscScalar **v) 20849b5e25fSSatish Balay { 20949b5e25fSSatish Balay Mat_SeqSBAIJ *a = (Mat_SeqSBAIJ*)A->data; 2106849ba73SBarry Smith PetscErrorCode ierr; 21113f74950SBarry Smith PetscInt itmp,i,j,k,M,*ai,*aj,bs,bn,bp,*cols_i,bs2; 21249b5e25fSSatish Balay MatScalar *aa,*aa_i; 21387828ca2SBarry Smith PetscScalar *v_i; 21449b5e25fSSatish Balay 21549b5e25fSSatish Balay PetscFunctionBegin; 2164e0d8c25SBarry 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()"); 217f5edf698SHong Zhang /* Get the upper triangular part of the row */ 218d0f46423SBarry Smith bs = A->rmap->bs; 21949b5e25fSSatish Balay ai = a->i; 22049b5e25fSSatish Balay aj = a->j; 22149b5e25fSSatish Balay aa = a->a; 22249b5e25fSSatish Balay bs2 = a->bs2; 22349b5e25fSSatish Balay 224d0f46423SBarry Smith if (row < 0 || row >= A->rmap->N) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE, "Row %D out of range", row); 22549b5e25fSSatish Balay 22649b5e25fSSatish Balay bn = row/bs; /* Block number */ 22749b5e25fSSatish Balay bp = row % bs; /* Block position */ 22849b5e25fSSatish Balay M = ai[bn+1] - ai[bn]; 22949b5e25fSSatish Balay *ncols = bs*M; 23049b5e25fSSatish Balay 23149b5e25fSSatish Balay if (v) { 23249b5e25fSSatish Balay *v = 0; 23349b5e25fSSatish Balay if (*ncols) { 23487828ca2SBarry Smith ierr = PetscMalloc((*ncols+row)*sizeof(PetscScalar),v);CHKERRQ(ierr); 23549b5e25fSSatish Balay for (i=0; i<M; i++) { /* for each block in the block row */ 23649b5e25fSSatish Balay v_i = *v + i*bs; 23749b5e25fSSatish Balay aa_i = aa + bs2*(ai[bn] + i); 23849b5e25fSSatish Balay for (j=bp,k=0; j<bs2; j+=bs,k++) {v_i[k] = aa_i[j];} 23949b5e25fSSatish Balay } 24049b5e25fSSatish Balay } 24149b5e25fSSatish Balay } 24249b5e25fSSatish Balay 24349b5e25fSSatish Balay if (cols) { 24449b5e25fSSatish Balay *cols = 0; 24549b5e25fSSatish Balay if (*ncols) { 24613f74950SBarry Smith ierr = PetscMalloc((*ncols+row)*sizeof(PetscInt),cols);CHKERRQ(ierr); 24749b5e25fSSatish Balay for (i=0; i<M; i++) { /* for each block in the block row */ 24849b5e25fSSatish Balay cols_i = *cols + i*bs; 24949b5e25fSSatish Balay itmp = bs*aj[ai[bn] + i]; 25049b5e25fSSatish Balay for (j=0; j<bs; j++) {cols_i[j] = itmp++;} 25149b5e25fSSatish Balay } 25249b5e25fSSatish Balay } 25349b5e25fSSatish Balay } 25449b5e25fSSatish Balay 25549b5e25fSSatish Balay /*search column A(0:row-1,row) (=A(row,0:row-1)). Could be expensive! */ 2565ddb2528SHong Zhang /* this segment is currently removed, so only entries in the upper triangle are obtained */ 2575ddb2528SHong Zhang #ifdef column_search 25849b5e25fSSatish Balay v_i = *v + M*bs; 25949b5e25fSSatish Balay cols_i = *cols + M*bs; 26049b5e25fSSatish Balay for (i=0; i<bn; i++){ /* for each block row */ 26149b5e25fSSatish Balay M = ai[i+1] - ai[i]; 26249b5e25fSSatish Balay for (j=0; j<M; j++){ 26349b5e25fSSatish Balay itmp = aj[ai[i] + j]; /* block column value */ 26449b5e25fSSatish Balay if (itmp == bn){ 26549b5e25fSSatish Balay aa_i = aa + bs2*(ai[i] + j) + bs*bp; 26649b5e25fSSatish Balay for (k=0; k<bs; k++) { 26749b5e25fSSatish Balay *cols_i++ = i*bs+k; 26849b5e25fSSatish Balay *v_i++ = aa_i[k]; 26949b5e25fSSatish Balay } 27049b5e25fSSatish Balay *ncols += bs; 27149b5e25fSSatish Balay break; 27249b5e25fSSatish Balay } 27349b5e25fSSatish Balay } 27449b5e25fSSatish Balay } 2755ddb2528SHong Zhang #endif 27649b5e25fSSatish Balay PetscFunctionReturn(0); 27749b5e25fSSatish Balay } 27849b5e25fSSatish Balay 2794a2ae208SSatish Balay #undef __FUNCT__ 2804a2ae208SSatish Balay #define __FUNCT__ "MatRestoreRow_SeqSBAIJ" 28113f74950SBarry Smith PetscErrorCode MatRestoreRow_SeqSBAIJ(Mat A,PetscInt row,PetscInt *nz,PetscInt **idx,PetscScalar **v) 28249b5e25fSSatish Balay { 283dfbe8321SBarry Smith PetscErrorCode ierr; 28449b5e25fSSatish Balay 28549b5e25fSSatish Balay PetscFunctionBegin; 28605b42c5fSBarry Smith if (idx) {ierr = PetscFree(*idx);CHKERRQ(ierr);} 28705b42c5fSBarry Smith if (v) {ierr = PetscFree(*v);CHKERRQ(ierr);} 28849b5e25fSSatish Balay PetscFunctionReturn(0); 28949b5e25fSSatish Balay } 29049b5e25fSSatish Balay 2914a2ae208SSatish Balay #undef __FUNCT__ 292f5edf698SHong Zhang #define __FUNCT__ "MatGetRowUpperTriangular_SeqSBAIJ" 293f5edf698SHong Zhang PetscErrorCode MatGetRowUpperTriangular_SeqSBAIJ(Mat A) 294f5edf698SHong Zhang { 295f5edf698SHong Zhang Mat_SeqSBAIJ *a = (Mat_SeqSBAIJ*)A->data; 296f5edf698SHong Zhang 297f5edf698SHong Zhang PetscFunctionBegin; 298f5edf698SHong Zhang a->getrow_utriangular = PETSC_TRUE; 299f5edf698SHong Zhang PetscFunctionReturn(0); 300f5edf698SHong Zhang } 301f5edf698SHong Zhang #undef __FUNCT__ 302f5edf698SHong Zhang #define __FUNCT__ "MatRestoreRowUpperTriangular_SeqSBAIJ" 303f5edf698SHong Zhang PetscErrorCode MatRestoreRowUpperTriangular_SeqSBAIJ(Mat A) 304f5edf698SHong Zhang { 305f5edf698SHong Zhang Mat_SeqSBAIJ *a = (Mat_SeqSBAIJ*)A->data; 306f5edf698SHong Zhang 307f5edf698SHong Zhang PetscFunctionBegin; 308f5edf698SHong Zhang a->getrow_utriangular = PETSC_FALSE; 309f5edf698SHong Zhang PetscFunctionReturn(0); 310f5edf698SHong Zhang } 311f5edf698SHong Zhang 312f5edf698SHong Zhang #undef __FUNCT__ 3134a2ae208SSatish Balay #define __FUNCT__ "MatTranspose_SeqSBAIJ" 314fc4dec0aSBarry Smith PetscErrorCode MatTranspose_SeqSBAIJ(Mat A,MatReuse reuse,Mat *B) 31549b5e25fSSatish Balay { 316dfbe8321SBarry Smith PetscErrorCode ierr; 31749b5e25fSSatish Balay PetscFunctionBegin; 318815cbec1SBarry Smith if (reuse == MAT_INITIAL_MATRIX || *B != A) { 319999d9058SBarry Smith ierr = MatDuplicate(A,MAT_COPY_VALUES,B);CHKERRQ(ierr); 320fc4dec0aSBarry Smith } 3218115998fSBarry Smith PetscFunctionReturn(0); 32249b5e25fSSatish Balay } 32349b5e25fSSatish Balay 3244a2ae208SSatish Balay #undef __FUNCT__ 3254a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqSBAIJ_ASCII" 3266849ba73SBarry Smith static PetscErrorCode MatView_SeqSBAIJ_ASCII(Mat A,PetscViewer viewer) 32749b5e25fSSatish Balay { 32849b5e25fSSatish Balay Mat_SeqSBAIJ *a = (Mat_SeqSBAIJ*)A->data; 329dfbe8321SBarry Smith PetscErrorCode ierr; 330d0f46423SBarry Smith PetscInt i,j,bs = A->rmap->bs,k,l,bs2=a->bs2; 3312dcb1b2aSMatthew Knepley const char *name; 332f3ef73ceSBarry Smith PetscViewerFormat format; 33349b5e25fSSatish Balay 33449b5e25fSSatish Balay PetscFunctionBegin; 33580fe4e49SBarry Smith ierr = PetscObjectGetName((PetscObject)A,&name);CHKERRQ(ierr); 336b0a32e0cSBarry Smith ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr); 337456192e2SBarry Smith if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) { 33877431f27SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," block size is %D\n",bs);CHKERRQ(ierr); 339fb9695e5SSatish Balay } else if (format == PETSC_VIEWER_ASCII_MATLAB) { 340d2507d54SMatthew Knepley Mat aij; 341d2507d54SMatthew Knepley 34270d5e725SHong Zhang if (A->factor && bs>1){ 34370d5e725SHong 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); 34470d5e725SHong Zhang PetscFunctionReturn(0); 34570d5e725SHong Zhang } 346c9f458caSMatthew Knepley ierr = MatConvert(A,MATSEQAIJ,MAT_INITIAL_MATRIX,&aij);CHKERRQ(ierr); 347c9f458caSMatthew Knepley ierr = MatView(aij,viewer);CHKERRQ(ierr); 348c9f458caSMatthew Knepley ierr = MatDestroy(aij);CHKERRQ(ierr); 349fb9695e5SSatish Balay } else if (format == PETSC_VIEWER_ASCII_COMMON) { 350b0a32e0cSBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_NO);CHKERRQ(ierr); 35149b5e25fSSatish Balay for (i=0; i<a->mbs; i++) { 35249b5e25fSSatish Balay for (j=0; j<bs; j++) { 35377431f27SBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"row %D:",i*bs+j);CHKERRQ(ierr); 35449b5e25fSSatish Balay for (k=a->i[i]; k<a->i[i+1]; k++) { 35549b5e25fSSatish Balay for (l=0; l<bs; l++) { 35649b5e25fSSatish Balay #if defined(PETSC_USE_COMPLEX) 35749b5e25fSSatish Balay if (PetscImaginaryPart(a->a[bs2*k + l*bs + j]) > 0.0 && PetscRealPart(a->a[bs2*k + l*bs + j]) != 0.0) { 358a83599f4SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %G + %G i) ",bs*a->j[k]+l, 35949b5e25fSSatish Balay PetscRealPart(a->a[bs2*k + l*bs + j]),PetscImaginaryPart(a->a[bs2*k + l*bs + j]));CHKERRQ(ierr); 36049b5e25fSSatish Balay } else if (PetscImaginaryPart(a->a[bs2*k + l*bs + j]) < 0.0 && PetscRealPart(a->a[bs2*k + l*bs + j]) != 0.0) { 361a83599f4SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %G - %G i) ",bs*a->j[k]+l, 36249b5e25fSSatish Balay PetscRealPart(a->a[bs2*k + l*bs + j]),-PetscImaginaryPart(a->a[bs2*k + l*bs + j]));CHKERRQ(ierr); 36349b5e25fSSatish Balay } else if (PetscRealPart(a->a[bs2*k + l*bs + j]) != 0.0) { 364a83599f4SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %G) ",bs*a->j[k]+l,PetscRealPart(a->a[bs2*k + l*bs + j]));CHKERRQ(ierr); 36549b5e25fSSatish Balay } 36649b5e25fSSatish Balay #else 36749b5e25fSSatish Balay if (a->a[bs2*k + l*bs + j] != 0.0) { 368a83599f4SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %G) ",bs*a->j[k]+l,a->a[bs2*k + l*bs + j]);CHKERRQ(ierr); 36949b5e25fSSatish Balay } 37049b5e25fSSatish Balay #endif 37149b5e25fSSatish Balay } 37249b5e25fSSatish Balay } 373b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 37449b5e25fSSatish Balay } 37549b5e25fSSatish Balay } 376b0a32e0cSBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_YES);CHKERRQ(ierr); 377c1490034SHong Zhang } else if (format == PETSC_VIEWER_ASCII_FACTOR_INFO) { 378c1490034SHong Zhang PetscFunctionReturn(0); 37949b5e25fSSatish Balay } else { 3808608aa04SHong Zhang if (A->factor && bs>1){ 3818608aa04SHong Zhang ierr = PetscPrintf(PETSC_COMM_SELF,"Warning: matrix is factored. MatView_SeqSBAIJ_ASCII() may not display complete or logically correct entries!\n");CHKERRQ(ierr); 3828608aa04SHong Zhang } 383b0a32e0cSBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_NO);CHKERRQ(ierr); 38449b5e25fSSatish Balay for (i=0; i<a->mbs; i++) { 38549b5e25fSSatish Balay for (j=0; j<bs; j++) { 38677431f27SBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"row %D:",i*bs+j);CHKERRQ(ierr); 38749b5e25fSSatish Balay for (k=a->i[i]; k<a->i[i+1]; k++) { 38849b5e25fSSatish Balay for (l=0; l<bs; l++) { 38949b5e25fSSatish Balay #if defined(PETSC_USE_COMPLEX) 39049b5e25fSSatish Balay if (PetscImaginaryPart(a->a[bs2*k + l*bs + j]) > 0.0) { 391a83599f4SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %G + %G i) ",bs*a->j[k]+l, 39249b5e25fSSatish Balay PetscRealPart(a->a[bs2*k + l*bs + j]),PetscImaginaryPart(a->a[bs2*k + l*bs + j]));CHKERRQ(ierr); 39349b5e25fSSatish Balay } else if (PetscImaginaryPart(a->a[bs2*k + l*bs + j]) < 0.0) { 394a83599f4SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %G - %G i) ",bs*a->j[k]+l, 39549b5e25fSSatish Balay PetscRealPart(a->a[bs2*k + l*bs + j]),-PetscImaginaryPart(a->a[bs2*k + l*bs + j]));CHKERRQ(ierr); 39649b5e25fSSatish Balay } else { 397a83599f4SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %G) ",bs*a->j[k]+l,PetscRealPart(a->a[bs2*k + l*bs + j]));CHKERRQ(ierr); 39849b5e25fSSatish Balay } 39949b5e25fSSatish Balay #else 400e9f7bc9eSHong Zhang ierr = PetscViewerASCIIPrintf(viewer," (%D, %G) ",bs*a->j[k]+l,a->a[bs2*k + l*bs + j]);CHKERRQ(ierr); 40149b5e25fSSatish Balay #endif 40249b5e25fSSatish Balay } 40349b5e25fSSatish Balay } 404b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 40549b5e25fSSatish Balay } 40649b5e25fSSatish Balay } 407b0a32e0cSBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_YES);CHKERRQ(ierr); 40849b5e25fSSatish Balay } 409b0a32e0cSBarry Smith ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 41049b5e25fSSatish Balay PetscFunctionReturn(0); 41149b5e25fSSatish Balay } 41249b5e25fSSatish Balay 4134a2ae208SSatish Balay #undef __FUNCT__ 4144a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqSBAIJ_Draw_Zoom" 4156849ba73SBarry Smith static PetscErrorCode MatView_SeqSBAIJ_Draw_Zoom(PetscDraw draw,void *Aa) 41649b5e25fSSatish Balay { 41749b5e25fSSatish Balay Mat A = (Mat) Aa; 41849b5e25fSSatish Balay Mat_SeqSBAIJ *a=(Mat_SeqSBAIJ*)A->data; 4196849ba73SBarry Smith PetscErrorCode ierr; 420d0f46423SBarry Smith PetscInt row,i,j,k,l,mbs=a->mbs,color,bs=A->rmap->bs,bs2=a->bs2; 42113f74950SBarry Smith PetscMPIInt rank; 42249b5e25fSSatish Balay PetscReal xl,yl,xr,yr,x_l,x_r,y_l,y_r; 42349b5e25fSSatish Balay MatScalar *aa; 42449b5e25fSSatish Balay MPI_Comm comm; 425b0a32e0cSBarry Smith PetscViewer viewer; 42649b5e25fSSatish Balay 42749b5e25fSSatish Balay PetscFunctionBegin; 42849b5e25fSSatish Balay /* 42949b5e25fSSatish Balay This is nasty. If this is called from an originally parallel matrix 43049b5e25fSSatish Balay then all processes call this,but only the first has the matrix so the 43149b5e25fSSatish Balay rest should return immediately. 43249b5e25fSSatish Balay */ 43349b5e25fSSatish Balay ierr = PetscObjectGetComm((PetscObject)draw,&comm);CHKERRQ(ierr); 43449b5e25fSSatish Balay ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 43549b5e25fSSatish Balay if (rank) PetscFunctionReturn(0); 43649b5e25fSSatish Balay 43749b5e25fSSatish Balay ierr = PetscObjectQuery((PetscObject)A,"Zoomviewer",(PetscObject*)&viewer);CHKERRQ(ierr); 43849b5e25fSSatish Balay 439b0a32e0cSBarry Smith ierr = PetscDrawGetCoordinates(draw,&xl,&yl,&xr,&yr);CHKERRQ(ierr); 440b0a32e0cSBarry Smith PetscDrawString(draw, .3*(xl+xr), .3*(yl+yr), PETSC_DRAW_BLACK, "symmetric"); 44149b5e25fSSatish Balay 44249b5e25fSSatish Balay /* loop over matrix elements drawing boxes */ 443b0a32e0cSBarry Smith color = PETSC_DRAW_BLUE; 44449b5e25fSSatish Balay for (i=0,row=0; i<mbs; i++,row+=bs) { 44549b5e25fSSatish Balay for (j=a->i[i]; j<a->i[i+1]; j++) { 446d0f46423SBarry Smith y_l = A->rmap->N - row - 1.0; y_r = y_l + 1.0; 44749b5e25fSSatish Balay x_l = a->j[j]*bs; x_r = x_l + 1.0; 44849b5e25fSSatish Balay aa = a->a + j*bs2; 44949b5e25fSSatish Balay for (k=0; k<bs; k++) { 45049b5e25fSSatish Balay for (l=0; l<bs; l++) { 45149b5e25fSSatish Balay if (PetscRealPart(*aa++) >= 0.) continue; 452b0a32e0cSBarry Smith ierr = PetscDrawRectangle(draw,x_l+k,y_l-l,x_r+k,y_r-l,color,color,color,color);CHKERRQ(ierr); 45349b5e25fSSatish Balay } 45449b5e25fSSatish Balay } 45549b5e25fSSatish Balay } 45649b5e25fSSatish Balay } 457b0a32e0cSBarry Smith color = PETSC_DRAW_CYAN; 45849b5e25fSSatish Balay for (i=0,row=0; i<mbs; i++,row+=bs) { 45949b5e25fSSatish Balay for (j=a->i[i]; j<a->i[i+1]; j++) { 460d0f46423SBarry Smith y_l = A->rmap->N - row - 1.0; y_r = y_l + 1.0; 46149b5e25fSSatish Balay x_l = a->j[j]*bs; x_r = x_l + 1.0; 46249b5e25fSSatish Balay aa = a->a + j*bs2; 46349b5e25fSSatish Balay for (k=0; k<bs; k++) { 46449b5e25fSSatish Balay for (l=0; l<bs; l++) { 46549b5e25fSSatish Balay if (PetscRealPart(*aa++) != 0.) continue; 466b0a32e0cSBarry Smith ierr = PetscDrawRectangle(draw,x_l+k,y_l-l,x_r+k,y_r-l,color,color,color,color);CHKERRQ(ierr); 46749b5e25fSSatish Balay } 46849b5e25fSSatish Balay } 46949b5e25fSSatish Balay } 47049b5e25fSSatish Balay } 47149b5e25fSSatish Balay 472b0a32e0cSBarry Smith color = PETSC_DRAW_RED; 47349b5e25fSSatish Balay for (i=0,row=0; i<mbs; i++,row+=bs) { 47449b5e25fSSatish Balay for (j=a->i[i]; j<a->i[i+1]; j++) { 475d0f46423SBarry Smith y_l = A->rmap->N - row - 1.0; y_r = y_l + 1.0; 47649b5e25fSSatish Balay x_l = a->j[j]*bs; x_r = x_l + 1.0; 47749b5e25fSSatish Balay aa = a->a + j*bs2; 47849b5e25fSSatish Balay for (k=0; k<bs; k++) { 47949b5e25fSSatish Balay for (l=0; l<bs; l++) { 48049b5e25fSSatish Balay if (PetscRealPart(*aa++) <= 0.) continue; 481b0a32e0cSBarry Smith ierr = PetscDrawRectangle(draw,x_l+k,y_l-l,x_r+k,y_r-l,color,color,color,color);CHKERRQ(ierr); 48249b5e25fSSatish Balay } 48349b5e25fSSatish Balay } 48449b5e25fSSatish Balay } 48549b5e25fSSatish Balay } 48649b5e25fSSatish Balay PetscFunctionReturn(0); 48749b5e25fSSatish Balay } 48849b5e25fSSatish Balay 4894a2ae208SSatish Balay #undef __FUNCT__ 4904a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqSBAIJ_Draw" 4916849ba73SBarry Smith static PetscErrorCode MatView_SeqSBAIJ_Draw(Mat A,PetscViewer viewer) 49249b5e25fSSatish Balay { 493dfbe8321SBarry Smith PetscErrorCode ierr; 49449b5e25fSSatish Balay PetscReal xl,yl,xr,yr,w,h; 495b0a32e0cSBarry Smith PetscDraw draw; 49649b5e25fSSatish Balay PetscTruth isnull; 49749b5e25fSSatish Balay 49849b5e25fSSatish Balay PetscFunctionBegin; 499b0a32e0cSBarry Smith ierr = PetscViewerDrawGetDraw(viewer,0,&draw);CHKERRQ(ierr); 500b0a32e0cSBarry Smith ierr = PetscDrawIsNull(draw,&isnull);CHKERRQ(ierr); if (isnull) PetscFunctionReturn(0); 50149b5e25fSSatish Balay 50249b5e25fSSatish Balay ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",(PetscObject)viewer);CHKERRQ(ierr); 503d0f46423SBarry Smith xr = A->rmap->N; yr = A->rmap->N; h = yr/10.0; w = xr/10.0; 50449b5e25fSSatish Balay xr += w; yr += h; xl = -w; yl = -h; 505b0a32e0cSBarry Smith ierr = PetscDrawSetCoordinates(draw,xl,yl,xr,yr);CHKERRQ(ierr); 506b0a32e0cSBarry Smith ierr = PetscDrawZoom(draw,MatView_SeqSBAIJ_Draw_Zoom,A);CHKERRQ(ierr); 50749b5e25fSSatish Balay ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",PETSC_NULL);CHKERRQ(ierr); 50849b5e25fSSatish Balay PetscFunctionReturn(0); 50949b5e25fSSatish Balay } 51049b5e25fSSatish Balay 5114a2ae208SSatish Balay #undef __FUNCT__ 5124a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqSBAIJ" 513dfbe8321SBarry Smith PetscErrorCode MatView_SeqSBAIJ(Mat A,PetscViewer viewer) 51449b5e25fSSatish Balay { 515dfbe8321SBarry Smith PetscErrorCode ierr; 51632077d6dSBarry Smith PetscTruth iascii,isdraw; 51749b5e25fSSatish Balay 51849b5e25fSSatish Balay PetscFunctionBegin; 51932077d6dSBarry Smith ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&iascii);CHKERRQ(ierr); 520fb9695e5SSatish Balay ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_DRAW,&isdraw);CHKERRQ(ierr); 52132077d6dSBarry Smith if (iascii){ 52249b5e25fSSatish Balay ierr = MatView_SeqSBAIJ_ASCII(A,viewer);CHKERRQ(ierr); 52349b5e25fSSatish Balay } else if (isdraw) { 52449b5e25fSSatish Balay ierr = MatView_SeqSBAIJ_Draw(A,viewer);CHKERRQ(ierr); 52549b5e25fSSatish Balay } else { 526a5e6ed63SBarry Smith Mat B; 527ceb03754SKris Buschelman ierr = MatConvert(A,MATSEQAIJ,MAT_INITIAL_MATRIX,&B);CHKERRQ(ierr); 528a5e6ed63SBarry Smith ierr = MatView(B,viewer);CHKERRQ(ierr); 529a5e6ed63SBarry Smith ierr = MatDestroy(B);CHKERRQ(ierr); 53049b5e25fSSatish Balay } 53149b5e25fSSatish Balay PetscFunctionReturn(0); 53249b5e25fSSatish Balay } 53349b5e25fSSatish Balay 53449b5e25fSSatish Balay 5354a2ae208SSatish Balay #undef __FUNCT__ 5364a2ae208SSatish Balay #define __FUNCT__ "MatGetValues_SeqSBAIJ" 53713f74950SBarry Smith PetscErrorCode MatGetValues_SeqSBAIJ(Mat A,PetscInt m,const PetscInt im[],PetscInt n,const PetscInt in[],PetscScalar v[]) 53849b5e25fSSatish Balay { 539045c9aa0SHong Zhang Mat_SeqSBAIJ *a = (Mat_SeqSBAIJ*)A->data; 54013f74950SBarry Smith PetscInt *rp,k,low,high,t,row,nrow,i,col,l,*aj = a->j; 54113f74950SBarry Smith PetscInt *ai = a->i,*ailen = a->ilen; 542d0f46423SBarry Smith PetscInt brow,bcol,ridx,cidx,bs=A->rmap->bs,bs2=a->bs2; 54397e567efSBarry Smith MatScalar *ap,*aa = a->a; 54449b5e25fSSatish Balay 54549b5e25fSSatish Balay PetscFunctionBegin; 54649b5e25fSSatish Balay for (k=0; k<m; k++) { /* loop over rows */ 54749b5e25fSSatish Balay row = im[k]; brow = row/bs; 54897e567efSBarry Smith if (row < 0) {v += n; continue;} /* SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Negative row: %D",row); */ 549d0f46423SBarry Smith if (row >= A->rmap->N) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"Row too large: row %D max %D",row,A->rmap->N-1); 55049b5e25fSSatish Balay rp = aj + ai[brow] ; ap = aa + bs2*ai[brow] ; 55149b5e25fSSatish Balay nrow = ailen[brow]; 55249b5e25fSSatish Balay for (l=0; l<n; l++) { /* loop over columns */ 55397e567efSBarry Smith if (in[l] < 0) {v++; continue;} /* SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Negative column: %D",in[l]); */ 554d0f46423SBarry 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); 55549b5e25fSSatish Balay col = in[l] ; 55649b5e25fSSatish Balay bcol = col/bs; 55749b5e25fSSatish Balay cidx = col%bs; 55849b5e25fSSatish Balay ridx = row%bs; 55949b5e25fSSatish Balay high = nrow; 56049b5e25fSSatish Balay low = 0; /* assume unsorted */ 56149b5e25fSSatish Balay while (high-low > 5) { 56249b5e25fSSatish Balay t = (low+high)/2; 56349b5e25fSSatish Balay if (rp[t] > bcol) high = t; 56449b5e25fSSatish Balay else low = t; 56549b5e25fSSatish Balay } 56649b5e25fSSatish Balay for (i=low; i<high; i++) { 56749b5e25fSSatish Balay if (rp[i] > bcol) break; 56849b5e25fSSatish Balay if (rp[i] == bcol) { 56949b5e25fSSatish Balay *v++ = ap[bs2*i+bs*cidx+ridx]; 57049b5e25fSSatish Balay goto finished; 57149b5e25fSSatish Balay } 57249b5e25fSSatish Balay } 57397e567efSBarry Smith *v++ = 0.0; 57449b5e25fSSatish Balay finished:; 57549b5e25fSSatish Balay } 57649b5e25fSSatish Balay } 57749b5e25fSSatish Balay PetscFunctionReturn(0); 57849b5e25fSSatish Balay } 57949b5e25fSSatish Balay 58049b5e25fSSatish Balay 5814a2ae208SSatish Balay #undef __FUNCT__ 5824a2ae208SSatish Balay #define __FUNCT__ "MatSetValuesBlocked_SeqSBAIJ" 58313f74950SBarry Smith PetscErrorCode MatSetValuesBlocked_SeqSBAIJ(Mat A,PetscInt m,const PetscInt im[],PetscInt n,const PetscInt in[],const PetscScalar v[],InsertMode is) 58449b5e25fSSatish Balay { 5850880e062SHong Zhang Mat_SeqSBAIJ *a = (Mat_SeqSBAIJ*)A->data; 5866849ba73SBarry Smith PetscErrorCode ierr; 587e2ee6c50SBarry Smith PetscInt *rp,k,low,high,t,ii,jj,row,nrow,i,col,l,rmax,N,lastcol = -1; 58813f74950SBarry Smith PetscInt *imax=a->imax,*ai=a->i,*ailen=a->ilen; 589d0f46423SBarry Smith PetscInt *aj=a->j,nonew=a->nonew,bs2=a->bs2,bs=A->rmap->bs,stepval; 5900880e062SHong Zhang PetscTruth roworiented=a->roworiented; 591dd6ea824SBarry Smith const PetscScalar *value = v; 592f15d580aSBarry Smith MatScalar *ap,*aa = a->a,*bap; 5930880e062SHong Zhang 59449b5e25fSSatish Balay PetscFunctionBegin; 5950880e062SHong Zhang if (roworiented) { 5960880e062SHong Zhang stepval = (n-1)*bs; 5970880e062SHong Zhang } else { 5980880e062SHong Zhang stepval = (m-1)*bs; 5990880e062SHong Zhang } 6000880e062SHong Zhang for (k=0; k<m; k++) { /* loop over added rows */ 6010880e062SHong Zhang row = im[k]; 6020880e062SHong Zhang if (row < 0) continue; 6032515c552SBarry Smith #if defined(PETSC_USE_DEBUG) 60477431f27SBarry Smith if (row >= a->mbs) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"Row too large: row %D max %D",row,a->mbs-1); 6050880e062SHong Zhang #endif 6060880e062SHong Zhang rp = aj + ai[row]; 6070880e062SHong Zhang ap = aa + bs2*ai[row]; 6080880e062SHong Zhang rmax = imax[row]; 6090880e062SHong Zhang nrow = ailen[row]; 6100880e062SHong Zhang low = 0; 611818f2c47SBarry Smith high = nrow; 6120880e062SHong Zhang for (l=0; l<n; l++) { /* loop over added columns */ 6130880e062SHong Zhang if (in[l] < 0) continue; 6140880e062SHong Zhang col = in[l]; 6152515c552SBarry Smith #if defined(PETSC_USE_DEBUG) 61677431f27SBarry Smith if (col >= a->nbs) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"Column too large: col %D max %D",col,a->nbs-1); 617b1823623SSatish Balay #endif 6180880e062SHong Zhang if (col < row) continue; /* ignore lower triangular block */ 6190880e062SHong Zhang if (roworiented) { 6200880e062SHong Zhang value = v + k*(stepval+bs)*bs + l*bs; 6210880e062SHong Zhang } else { 6220880e062SHong Zhang value = v + l*(stepval+bs)*bs + k*bs; 6230880e062SHong Zhang } 6247cd84e04SBarry Smith if (col <= lastcol) low = 0; else high = nrow; 625e2ee6c50SBarry Smith lastcol = col; 6260880e062SHong Zhang while (high-low > 7) { 6270880e062SHong Zhang t = (low+high)/2; 6280880e062SHong Zhang if (rp[t] > col) high = t; 6290880e062SHong Zhang else low = t; 6300880e062SHong Zhang } 6310880e062SHong Zhang for (i=low; i<high; i++) { 6320880e062SHong Zhang if (rp[i] > col) break; 6330880e062SHong Zhang if (rp[i] == col) { 6340880e062SHong Zhang bap = ap + bs2*i; 6350880e062SHong Zhang if (roworiented) { 6360880e062SHong Zhang if (is == ADD_VALUES) { 6370880e062SHong Zhang for (ii=0; ii<bs; ii++,value+=stepval) { 6380880e062SHong Zhang for (jj=ii; jj<bs2; jj+=bs) { 6390880e062SHong Zhang bap[jj] += *value++; 6400880e062SHong Zhang } 6410880e062SHong Zhang } 6420880e062SHong Zhang } else { 6430880e062SHong Zhang for (ii=0; ii<bs; ii++,value+=stepval) { 6440880e062SHong Zhang for (jj=ii; jj<bs2; jj+=bs) { 6450880e062SHong Zhang bap[jj] = *value++; 6460880e062SHong Zhang } 6470880e062SHong Zhang } 6480880e062SHong Zhang } 6490880e062SHong Zhang } else { 6500880e062SHong Zhang if (is == ADD_VALUES) { 6510880e062SHong Zhang for (ii=0; ii<bs; ii++,value+=stepval) { 6520880e062SHong Zhang for (jj=0; jj<bs; jj++) { 6530880e062SHong Zhang *bap++ += *value++; 6540880e062SHong Zhang } 6550880e062SHong Zhang } 6560880e062SHong Zhang } else { 6570880e062SHong Zhang for (ii=0; ii<bs; ii++,value+=stepval) { 6580880e062SHong Zhang for (jj=0; jj<bs; jj++) { 6590880e062SHong Zhang *bap++ = *value++; 6600880e062SHong Zhang } 6610880e062SHong Zhang } 6620880e062SHong Zhang } 6630880e062SHong Zhang } 6640880e062SHong Zhang goto noinsert2; 6650880e062SHong Zhang } 6660880e062SHong Zhang } 6670880e062SHong Zhang if (nonew == 1) goto noinsert2; 668085a36d4SBarry Smith if (nonew == -1) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"Inserting a new nonzero (%D, %D) in the matrix", row, col); 669421e10b8SBarry Smith MatSeqXAIJReallocateAIJ(A,a->mbs,bs2,nrow,row,col,rmax,aa,ai,aj,rp,ap,imax,nonew,MatScalar); 670c03d1d03SSatish Balay N = nrow++ - 1; high++; 6710880e062SHong Zhang /* shift up all the later entries in this row */ 6720880e062SHong Zhang for (ii=N; ii>=i; ii--) { 6730880e062SHong Zhang rp[ii+1] = rp[ii]; 6740880e062SHong Zhang ierr = PetscMemcpy(ap+bs2*(ii+1),ap+bs2*(ii),bs2*sizeof(MatScalar));CHKERRQ(ierr); 6750880e062SHong Zhang } 6760880e062SHong Zhang if (N >= i) { 6770880e062SHong Zhang ierr = PetscMemzero(ap+bs2*i,bs2*sizeof(MatScalar));CHKERRQ(ierr); 6780880e062SHong Zhang } 6790880e062SHong Zhang rp[i] = col; 6800880e062SHong Zhang bap = ap + bs2*i; 6810880e062SHong Zhang if (roworiented) { 6820880e062SHong Zhang for (ii=0; ii<bs; ii++,value+=stepval) { 6830880e062SHong Zhang for (jj=ii; jj<bs2; jj+=bs) { 6840880e062SHong Zhang bap[jj] = *value++; 6850880e062SHong Zhang } 6860880e062SHong Zhang } 6870880e062SHong Zhang } else { 6880880e062SHong Zhang for (ii=0; ii<bs; ii++,value+=stepval) { 6890880e062SHong Zhang for (jj=0; jj<bs; jj++) { 6900880e062SHong Zhang *bap++ = *value++; 6910880e062SHong Zhang } 6920880e062SHong Zhang } 6930880e062SHong Zhang } 6940880e062SHong Zhang noinsert2:; 6950880e062SHong Zhang low = i; 6960880e062SHong Zhang } 6970880e062SHong Zhang ailen[row] = nrow; 6980880e062SHong Zhang } 6990880e062SHong Zhang PetscFunctionReturn(0); 70049b5e25fSSatish Balay } 70149b5e25fSSatish Balay 70264831d72SBarry Smith /* 70364831d72SBarry Smith This is not yet used 70464831d72SBarry Smith */ 7054a2ae208SSatish Balay #undef __FUNCT__ 7060def2e27SBarry Smith #define __FUNCT__ "MatAssemblyEnd_SeqSBAIJ_Inode" 7070def2e27SBarry Smith PetscErrorCode MatAssemblyEnd_SeqSBAIJ_Inode(Mat A) 7080def2e27SBarry Smith { 7090def2e27SBarry Smith Mat_SeqSBAIJ *a = (Mat_SeqSBAIJ*)A->data; 7100def2e27SBarry Smith PetscErrorCode ierr; 7110def2e27SBarry Smith const PetscInt *ai = a->i, *aj = a->j,*cols; 7120def2e27SBarry Smith PetscInt i = 0,j,blk_size,m = A->rmap->n,node_count = 0,nzx,nzy,*ns,row,nz,cnt,cnt2,*counts; 7130def2e27SBarry Smith PetscTruth flag; 7140def2e27SBarry Smith 7150def2e27SBarry Smith PetscFunctionBegin; 7160def2e27SBarry Smith ierr = PetscMalloc(m*sizeof(PetscInt),&ns);CHKERRQ(ierr); 7170def2e27SBarry Smith while (i < m){ 7180def2e27SBarry Smith nzx = ai[i+1] - ai[i]; /* Number of nonzeros */ 7190def2e27SBarry Smith /* Limits the number of elements in a node to 'a->inode.limit' */ 7200def2e27SBarry Smith for (j=i+1,blk_size=1; j<m && blk_size <a->inode.limit; ++j,++blk_size) { 7210def2e27SBarry Smith nzy = ai[j+1] - ai[j]; 7220def2e27SBarry Smith if (nzy != (nzx - j + i)) break; 7230def2e27SBarry Smith ierr = PetscMemcmp(aj + ai[i] + j - i,aj + ai[j],nzy*sizeof(PetscInt),&flag);CHKERRQ(ierr); 7240def2e27SBarry Smith if (!flag) break; 7250def2e27SBarry Smith } 7260def2e27SBarry Smith ns[node_count++] = blk_size; 7270def2e27SBarry Smith i = j; 7280def2e27SBarry Smith } 7290def2e27SBarry Smith if (!a->inode.size && m && node_count > .9*m) { 7300def2e27SBarry Smith ierr = PetscFree(ns);CHKERRQ(ierr); 7310def2e27SBarry Smith ierr = PetscInfo2(A,"Found %D nodes out of %D rows. Not using Inode routines\n",node_count,m);CHKERRQ(ierr); 7320def2e27SBarry Smith } else { 7330def2e27SBarry Smith a->inode.node_count = node_count; 7340def2e27SBarry Smith ierr = PetscMalloc(node_count*sizeof(PetscInt),&a->inode.size);CHKERRQ(ierr); 7350def2e27SBarry Smith ierr = PetscMemcpy(a->inode.size,ns,node_count*sizeof(PetscInt)); 7360def2e27SBarry Smith ierr = PetscFree(ns);CHKERRQ(ierr); 7370def2e27SBarry Smith ierr = PetscInfo3(A,"Found %D nodes of %D. Limit used: %D. Using Inode routines\n",node_count,m,a->inode.limit);CHKERRQ(ierr); 7380def2e27SBarry Smith 7390def2e27SBarry Smith /* count collections of adjacent columns in each inode */ 7400def2e27SBarry Smith row = 0; 7410def2e27SBarry Smith cnt = 0; 7420def2e27SBarry Smith for (i=0; i<node_count; i++) { 7430def2e27SBarry Smith cols = aj + ai[row] + a->inode.size[i]; 7440def2e27SBarry Smith nz = ai[row+1] - ai[row] - a->inode.size[i]; 7450def2e27SBarry Smith for (j=1; j<nz; j++) { 7460def2e27SBarry Smith if (cols[j] != cols[j-1]+1) { 7470def2e27SBarry Smith cnt++; 7480def2e27SBarry Smith } 7490def2e27SBarry Smith } 7500def2e27SBarry Smith cnt++; 7510def2e27SBarry Smith row += a->inode.size[i]; 7520def2e27SBarry Smith } 7530def2e27SBarry Smith ierr = PetscMalloc(2*cnt*sizeof(PetscInt),&counts);CHKERRQ(ierr); 7540def2e27SBarry Smith cnt = 0; 7550def2e27SBarry Smith row = 0; 7560def2e27SBarry Smith for (i=0; i<node_count; i++) { 7570def2e27SBarry Smith cols = aj + ai[row] + a->inode.size[i]; 7580def2e27SBarry Smith CHKMEMQ; 7590def2e27SBarry Smith counts[2*cnt] = cols[0]; 7600def2e27SBarry Smith CHKMEMQ; 7610def2e27SBarry Smith nz = ai[row+1] - ai[row] - a->inode.size[i]; 7620def2e27SBarry Smith cnt2 = 1; 7630def2e27SBarry Smith for (j=1; j<nz; j++) { 7640def2e27SBarry Smith if (cols[j] != cols[j-1]+1) { 7650def2e27SBarry Smith CHKMEMQ; 7660def2e27SBarry Smith counts[2*(cnt++)+1] = cnt2; 7670def2e27SBarry Smith counts[2*cnt] = cols[j]; 7680def2e27SBarry Smith CHKMEMQ; 7690def2e27SBarry Smith cnt2 = 1; 7700def2e27SBarry Smith } else cnt2++; 7710def2e27SBarry Smith } 7720def2e27SBarry Smith CHKMEMQ; 7730def2e27SBarry Smith counts[2*(cnt++)+1] = cnt2; 7740def2e27SBarry Smith CHKMEMQ; 7750def2e27SBarry Smith row += a->inode.size[i]; 7760def2e27SBarry Smith } 7770def2e27SBarry Smith ierr = PetscIntView(2*cnt,counts,0); 7780def2e27SBarry Smith } 7790def2e27SBarry Smith 7800def2e27SBarry Smith 7810def2e27SBarry Smith PetscFunctionReturn(0); 7820def2e27SBarry Smith } 7830def2e27SBarry Smith 7840def2e27SBarry Smith #undef __FUNCT__ 7854a2ae208SSatish Balay #define __FUNCT__ "MatAssemblyEnd_SeqSBAIJ" 786dfbe8321SBarry Smith PetscErrorCode MatAssemblyEnd_SeqSBAIJ(Mat A,MatAssemblyType mode) 78749b5e25fSSatish Balay { 78849b5e25fSSatish Balay Mat_SeqSBAIJ *a = (Mat_SeqSBAIJ*)A->data; 7896849ba73SBarry Smith PetscErrorCode ierr; 79013f74950SBarry Smith PetscInt fshift = 0,i,j,*ai = a->i,*aj = a->j,*imax = a->imax; 791d0f46423SBarry Smith PetscInt m = A->rmap->N,*ip,N,*ailen = a->ilen; 79213f74950SBarry Smith PetscInt mbs = a->mbs,bs2 = a->bs2,rmax = 0; 79349b5e25fSSatish Balay MatScalar *aa = a->a,*ap; 79449b5e25fSSatish Balay 79549b5e25fSSatish Balay PetscFunctionBegin; 79649b5e25fSSatish Balay if (mode == MAT_FLUSH_ASSEMBLY) PetscFunctionReturn(0); 79749b5e25fSSatish Balay 79849b5e25fSSatish Balay if (m) rmax = ailen[0]; 79949b5e25fSSatish Balay for (i=1; i<mbs; i++) { 80049b5e25fSSatish Balay /* move each row back by the amount of empty slots (fshift) before it*/ 80149b5e25fSSatish Balay fshift += imax[i-1] - ailen[i-1]; 80249b5e25fSSatish Balay rmax = PetscMax(rmax,ailen[i]); 80349b5e25fSSatish Balay if (fshift) { 80449b5e25fSSatish Balay ip = aj + ai[i]; ap = aa + bs2*ai[i]; 80549b5e25fSSatish Balay N = ailen[i]; 80649b5e25fSSatish Balay for (j=0; j<N; j++) { 80749b5e25fSSatish Balay ip[j-fshift] = ip[j]; 80849b5e25fSSatish Balay ierr = PetscMemcpy(ap+(j-fshift)*bs2,ap+j*bs2,bs2*sizeof(MatScalar));CHKERRQ(ierr); 80949b5e25fSSatish Balay } 81049b5e25fSSatish Balay } 81149b5e25fSSatish Balay ai[i] = ai[i-1] + ailen[i-1]; 81249b5e25fSSatish Balay } 81349b5e25fSSatish Balay if (mbs) { 81449b5e25fSSatish Balay fshift += imax[mbs-1] - ailen[mbs-1]; 81549b5e25fSSatish Balay ai[mbs] = ai[mbs-1] + ailen[mbs-1]; 81649b5e25fSSatish Balay } 81749b5e25fSSatish Balay /* reset ilen and imax for each row */ 81849b5e25fSSatish Balay for (i=0; i<mbs; i++) { 81949b5e25fSSatish Balay ailen[i] = imax[i] = ai[i+1] - ai[i]; 82049b5e25fSSatish Balay } 8216c6c5352SBarry Smith a->nz = ai[mbs]; 82249b5e25fSSatish Balay 823b424e231SHong Zhang /* diagonals may have moved, reset it */ 824b424e231SHong Zhang if (a->diag) { 82513f74950SBarry Smith ierr = PetscMemcpy(a->diag,ai,(mbs+1)*sizeof(PetscInt));CHKERRQ(ierr); 82649b5e25fSSatish Balay } 82728b2fa4aSMatthew Knepley if (fshift && a->nounused == -1) { 82828b2fa4aSMatthew Knepley SETERRQ4(PETSC_ERR_PLIB, "Unused space detected in matrix: %D X %D block size %D, %D unneeded", m, A->cmap->n, A->rmap->bs, fshift*bs2); 82928b2fa4aSMatthew Knepley } 830d0f46423SBarry 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); 831ae15b995SBarry Smith ierr = PetscInfo1(A,"Number of mallocs during MatSetValues is %D\n",a->reallocs);CHKERRQ(ierr); 832ae15b995SBarry Smith ierr = PetscInfo1(A,"Most nonzeros blocks in any row is %D\n",rmax);CHKERRQ(ierr); 83349b5e25fSSatish Balay a->reallocs = 0; 83449b5e25fSSatish Balay A->info.nz_unneeded = (PetscReal)fshift*bs2; 835061b2667SBarry Smith a->idiagvalid = PETSC_FALSE; 83664831d72SBarry Smith /* if (bs2 == 1) { 8370def2e27SBarry Smith ierr = MatAssemblyEnd_SeqSBAIJ_Inode(A);CHKERRQ(ierr); 83864831d72SBarry Smith } */ 83949b5e25fSSatish Balay PetscFunctionReturn(0); 84049b5e25fSSatish Balay } 84149b5e25fSSatish Balay 84249b5e25fSSatish Balay /* 84349b5e25fSSatish Balay This function returns an array of flags which indicate the locations of contiguous 84449b5e25fSSatish Balay blocks that should be zeroed. for eg: if bs = 3 and is = [0,1,2,3,5,6,7,8,9] 84549b5e25fSSatish Balay then the resulting sizes = [3,1,1,3,1] correspondig to sets [(0,1,2),(3),(5),(6,7,8),(9)] 84649b5e25fSSatish Balay Assume: sizes should be long enough to hold all the values. 84749b5e25fSSatish Balay */ 8484a2ae208SSatish Balay #undef __FUNCT__ 8494a2ae208SSatish Balay #define __FUNCT__ "MatZeroRows_SeqSBAIJ_Check_Blocks" 85013f74950SBarry Smith PetscErrorCode MatZeroRows_SeqSBAIJ_Check_Blocks(PetscInt idx[],PetscInt n,PetscInt bs,PetscInt sizes[], PetscInt *bs_max) 85149b5e25fSSatish Balay { 85213f74950SBarry Smith PetscInt i,j,k,row; 85349b5e25fSSatish Balay PetscTruth flg; 85449b5e25fSSatish Balay 85549b5e25fSSatish Balay PetscFunctionBegin; 85649b5e25fSSatish Balay for (i=0,j=0; i<n; j++) { 85749b5e25fSSatish Balay row = idx[i]; 85849b5e25fSSatish Balay if (row%bs!=0) { /* Not the begining of a block */ 85949b5e25fSSatish Balay sizes[j] = 1; 86049b5e25fSSatish Balay i++; 86149b5e25fSSatish Balay } else if (i+bs > n) { /* Beginning of a block, but complete block doesn't exist (at idx end) */ 86249b5e25fSSatish Balay sizes[j] = 1; /* Also makes sure atleast 'bs' values exist for next else */ 86349b5e25fSSatish Balay i++; 86449b5e25fSSatish Balay } else { /* Begining of the block, so check if the complete block exists */ 86549b5e25fSSatish Balay flg = PETSC_TRUE; 86649b5e25fSSatish Balay for (k=1; k<bs; k++) { 86749b5e25fSSatish Balay if (row+k != idx[i+k]) { /* break in the block */ 86849b5e25fSSatish Balay flg = PETSC_FALSE; 86949b5e25fSSatish Balay break; 87049b5e25fSSatish Balay } 87149b5e25fSSatish Balay } 872abc0a331SBarry Smith if (flg) { /* No break in the bs */ 87349b5e25fSSatish Balay sizes[j] = bs; 87449b5e25fSSatish Balay i+= bs; 87549b5e25fSSatish Balay } else { 87649b5e25fSSatish Balay sizes[j] = 1; 87749b5e25fSSatish Balay i++; 87849b5e25fSSatish Balay } 87949b5e25fSSatish Balay } 88049b5e25fSSatish Balay } 88149b5e25fSSatish Balay *bs_max = j; 88249b5e25fSSatish Balay PetscFunctionReturn(0); 88349b5e25fSSatish Balay } 88449b5e25fSSatish Balay 88549b5e25fSSatish Balay 88649b5e25fSSatish Balay /* Only add/insert a(i,j) with i<=j (blocks). 88749b5e25fSSatish Balay Any a(i,j) with i>j input by user is ingored. 88849b5e25fSSatish Balay */ 88949b5e25fSSatish Balay 8904a2ae208SSatish Balay #undef __FUNCT__ 8914a2ae208SSatish Balay #define __FUNCT__ "MatSetValues_SeqSBAIJ" 89213f74950SBarry Smith PetscErrorCode MatSetValues_SeqSBAIJ(Mat A,PetscInt m,const PetscInt im[],PetscInt n,const PetscInt in[],const PetscScalar v[],InsertMode is) 89349b5e25fSSatish Balay { 89449b5e25fSSatish Balay Mat_SeqSBAIJ *a = (Mat_SeqSBAIJ*)A->data; 8956849ba73SBarry Smith PetscErrorCode ierr; 896e2ee6c50SBarry Smith PetscInt *rp,k,low,high,t,ii,row,nrow,i,col,l,rmax,N,lastcol = -1; 89713f74950SBarry Smith PetscInt *imax=a->imax,*ai=a->i,*ailen=a->ilen,roworiented=a->roworiented; 898d0f46423SBarry Smith PetscInt *aj=a->j,nonew=a->nonew,bs=A->rmap->bs,brow,bcol; 89913f74950SBarry Smith PetscInt ridx,cidx,bs2=a->bs2; 90049b5e25fSSatish Balay MatScalar *ap,value,*aa=a->a,*bap; 90149b5e25fSSatish Balay 90249b5e25fSSatish Balay PetscFunctionBegin; 90349b5e25fSSatish Balay for (k=0; k<m; k++) { /* loop over added rows */ 90449b5e25fSSatish Balay row = im[k]; /* row number */ 90549b5e25fSSatish Balay brow = row/bs; /* block row number */ 90649b5e25fSSatish Balay if (row < 0) continue; 9072515c552SBarry Smith #if defined(PETSC_USE_DEBUG) 908d0f46423SBarry Smith if (row >= A->rmap->N) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"Row too large: row %D max %D",row,A->rmap->N-1); 90949b5e25fSSatish Balay #endif 91049b5e25fSSatish Balay rp = aj + ai[brow]; /*ptr to beginning of column value of the row block*/ 91149b5e25fSSatish Balay ap = aa + bs2*ai[brow]; /*ptr to beginning of element value of the row block*/ 91249b5e25fSSatish Balay rmax = imax[brow]; /* maximum space allocated for this row */ 91349b5e25fSSatish Balay nrow = ailen[brow]; /* actual length of this row */ 91449b5e25fSSatish Balay low = 0; 91549b5e25fSSatish Balay 91649b5e25fSSatish Balay for (l=0; l<n; l++) { /* loop over added columns */ 91749b5e25fSSatish Balay if (in[l] < 0) continue; 9182515c552SBarry Smith #if defined(PETSC_USE_DEBUG) 919d0f46423SBarry 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); 92049b5e25fSSatish Balay #endif 92149b5e25fSSatish Balay col = in[l]; 92249b5e25fSSatish Balay bcol = col/bs; /* block col number */ 92349b5e25fSSatish Balay 924941593c8SHong Zhang if (brow > bcol) { 925941593c8SHong Zhang if (a->ignore_ltriangular){ 926941593c8SHong Zhang continue; /* ignore lower triangular values */ 927941593c8SHong Zhang } else { 9284e0d8c25SBarry 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)"); 929941593c8SHong Zhang } 930941593c8SHong Zhang } 931f4989cb3SHong Zhang 93249b5e25fSSatish Balay ridx = row % bs; cidx = col % bs; /*row and col index inside the block */ 9338549e402SHong Zhang if ((brow==bcol && ridx<=cidx) || (brow<bcol)){ 93449b5e25fSSatish Balay /* element value a(k,l) */ 93549b5e25fSSatish Balay if (roworiented) { 93649b5e25fSSatish Balay value = v[l + k*n]; 93749b5e25fSSatish Balay } else { 93849b5e25fSSatish Balay value = v[k + l*m]; 93949b5e25fSSatish Balay } 94049b5e25fSSatish Balay 94149b5e25fSSatish Balay /* move pointer bap to a(k,l) quickly and add/insert value */ 9427cd84e04SBarry Smith if (col <= lastcol) low = 0; high = nrow; 943e2ee6c50SBarry Smith lastcol = col; 94449b5e25fSSatish Balay while (high-low > 7) { 94549b5e25fSSatish Balay t = (low+high)/2; 94649b5e25fSSatish Balay if (rp[t] > bcol) high = t; 94749b5e25fSSatish Balay else low = t; 94849b5e25fSSatish Balay } 94949b5e25fSSatish Balay for (i=low; i<high; i++) { 95049b5e25fSSatish Balay if (rp[i] > bcol) break; 95149b5e25fSSatish Balay if (rp[i] == bcol) { 95249b5e25fSSatish Balay bap = ap + bs2*i + bs*cidx + ridx; 95349b5e25fSSatish Balay if (is == ADD_VALUES) *bap += value; 95449b5e25fSSatish Balay else *bap = value; 9558549e402SHong Zhang /* for diag block, add/insert its symmetric element a(cidx,ridx) */ 9568549e402SHong Zhang if (brow == bcol && ridx < cidx){ 9578549e402SHong Zhang bap = ap + bs2*i + bs*ridx + cidx; 9588549e402SHong Zhang if (is == ADD_VALUES) *bap += value; 9598549e402SHong Zhang else *bap = value; 9608549e402SHong Zhang } 96149b5e25fSSatish Balay goto noinsert1; 96249b5e25fSSatish Balay } 96349b5e25fSSatish Balay } 96449b5e25fSSatish Balay 96549b5e25fSSatish Balay if (nonew == 1) goto noinsert1; 966085a36d4SBarry Smith if (nonew == -1) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"Inserting a new nonzero (%D, %D) in the matrix", row, col); 967421e10b8SBarry Smith MatSeqXAIJReallocateAIJ(A,a->mbs,bs2,nrow,brow,bcol,rmax,aa,ai,aj,rp,ap,imax,nonew,MatScalar); 96849b5e25fSSatish Balay 969c03d1d03SSatish Balay N = nrow++ - 1; high++; 97049b5e25fSSatish Balay /* shift up all the later entries in this row */ 97149b5e25fSSatish Balay for (ii=N; ii>=i; ii--) { 97249b5e25fSSatish Balay rp[ii+1] = rp[ii]; 97349b5e25fSSatish Balay ierr = PetscMemcpy(ap+bs2*(ii+1),ap+bs2*(ii),bs2*sizeof(MatScalar));CHKERRQ(ierr); 97449b5e25fSSatish Balay } 97549b5e25fSSatish Balay if (N>=i) { 97649b5e25fSSatish Balay ierr = PetscMemzero(ap+bs2*i,bs2*sizeof(MatScalar));CHKERRQ(ierr); 97749b5e25fSSatish Balay } 97849b5e25fSSatish Balay rp[i] = bcol; 97949b5e25fSSatish Balay ap[bs2*i + bs*cidx + ridx] = value; 98049b5e25fSSatish Balay noinsert1:; 98149b5e25fSSatish Balay low = i; 9828549e402SHong Zhang } 98349b5e25fSSatish Balay } /* end of loop over added columns */ 98449b5e25fSSatish Balay ailen[brow] = nrow; 98549b5e25fSSatish Balay } /* end of loop over added rows */ 98649b5e25fSSatish Balay PetscFunctionReturn(0); 98749b5e25fSSatish Balay } 98849b5e25fSSatish Balay 9894a2ae208SSatish Balay #undef __FUNCT__ 9904d101231SSatish Balay #define __FUNCT__ "MatICCFactor_SeqSBAIJ" 9910481f469SBarry Smith PetscErrorCode MatICCFactor_SeqSBAIJ(Mat inA,IS row,const MatFactorInfo *info) 99249b5e25fSSatish Balay { 9934ccecd49SHong Zhang Mat_SeqSBAIJ *a = (Mat_SeqSBAIJ*)inA->data; 99449b5e25fSSatish Balay Mat outA; 995dfbe8321SBarry Smith PetscErrorCode ierr; 996c84f5b01SHong Zhang PetscTruth row_identity; 99749b5e25fSSatish Balay 99849b5e25fSSatish Balay PetscFunctionBegin; 999c84f5b01SHong Zhang if (info->levels != 0) SETERRQ(PETSC_ERR_SUP,"Only levels=0 is supported for in-place icc"); 1000c84f5b01SHong Zhang ierr = ISIdentity(row,&row_identity);CHKERRQ(ierr); 1001c84f5b01SHong Zhang if (!row_identity) SETERRQ(PETSC_ERR_SUP,"Matrix reordering is not supported"); 1002d0f46423SBarry 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()! */ 1003c84f5b01SHong Zhang 100449b5e25fSSatish Balay outA = inA; 1005c078aec8SLisandro Dalcin inA->factor = MAT_FACTOR_ICC; 100649b5e25fSSatish Balay 10071a3463dfSHong Zhang ierr = MatMarkDiagonal_SeqSBAIJ(inA);CHKERRQ(ierr); 1008db4efbfdSBarry Smith ierr = MatSeqSBAIJSetNumericFactorization(inA,row_identity);CHKERRQ(ierr); 100949b5e25fSSatish Balay 1010c3122656SLisandro Dalcin ierr = PetscObjectReference((PetscObject)row);CHKERRQ(ierr); 1011c3122656SLisandro Dalcin if (a->row) { ierr = ISDestroy(a->row);CHKERRQ(ierr); } 1012c84f5b01SHong Zhang a->row = row; 1013c3122656SLisandro Dalcin ierr = PetscObjectReference((PetscObject)row);CHKERRQ(ierr); 1014c3122656SLisandro Dalcin if (a->col) { ierr = ISDestroy(a->col);CHKERRQ(ierr); } 1015c84f5b01SHong Zhang a->col = row; 1016c84f5b01SHong Zhang 1017c84f5b01SHong Zhang /* Create the invert permutation so that it can be used in MatCholeskyFactorNumeric() */ 1018c84f5b01SHong Zhang if (a->icol) {ierr = ISInvertPermutation(row,PETSC_DECIDE, &a->icol);CHKERRQ(ierr);} 101952e6d16bSBarry Smith ierr = PetscLogObjectParent(inA,a->icol);CHKERRQ(ierr); 102049b5e25fSSatish Balay 102149b5e25fSSatish Balay if (!a->solve_work) { 1022d0f46423SBarry Smith ierr = PetscMalloc((inA->rmap->N+inA->rmap->bs)*sizeof(PetscScalar),&a->solve_work);CHKERRQ(ierr); 1023d0f46423SBarry Smith ierr = PetscLogObjectMemory(inA,(inA->rmap->N+inA->rmap->bs)*sizeof(PetscScalar));CHKERRQ(ierr); 102449b5e25fSSatish Balay } 102549b5e25fSSatish Balay 1026719d5645SBarry Smith ierr = MatCholeskyFactorNumeric(outA,inA,info);CHKERRQ(ierr); 102749b5e25fSSatish Balay PetscFunctionReturn(0); 102849b5e25fSSatish Balay } 1029950f1e5bSHong Zhang 103049b5e25fSSatish Balay EXTERN_C_BEGIN 10314a2ae208SSatish Balay #undef __FUNCT__ 10324a2ae208SSatish Balay #define __FUNCT__ "MatSeqSBAIJSetColumnIndices_SeqSBAIJ" 1033be1d678aSKris Buschelman PetscErrorCode PETSCMAT_DLLEXPORT MatSeqSBAIJSetColumnIndices_SeqSBAIJ(Mat mat,PetscInt *indices) 103449b5e25fSSatish Balay { 1035045c9aa0SHong Zhang Mat_SeqSBAIJ *baij = (Mat_SeqSBAIJ *)mat->data; 103613f74950SBarry Smith PetscInt i,nz,n; 103749b5e25fSSatish Balay 103849b5e25fSSatish Balay PetscFunctionBegin; 10396c6c5352SBarry Smith nz = baij->maxnz; 1040d0f46423SBarry Smith n = mat->cmap->n; 104149b5e25fSSatish Balay for (i=0; i<nz; i++) { 104249b5e25fSSatish Balay baij->j[i] = indices[i]; 104349b5e25fSSatish Balay } 10446c6c5352SBarry Smith baij->nz = nz; 104549b5e25fSSatish Balay for (i=0; i<n; i++) { 104649b5e25fSSatish Balay baij->ilen[i] = baij->imax[i]; 104749b5e25fSSatish Balay } 104849b5e25fSSatish Balay PetscFunctionReturn(0); 104949b5e25fSSatish Balay } 105049b5e25fSSatish Balay EXTERN_C_END 105149b5e25fSSatish Balay 10524a2ae208SSatish Balay #undef __FUNCT__ 10534a2ae208SSatish Balay #define __FUNCT__ "MatSeqSBAIJSetColumnIndices" 105449b5e25fSSatish Balay /*@ 105519585528SSatish Balay MatSeqSBAIJSetColumnIndices - Set the column indices for all the rows 105649b5e25fSSatish Balay in the matrix. 105749b5e25fSSatish Balay 105849b5e25fSSatish Balay Input Parameters: 105919585528SSatish Balay + mat - the SeqSBAIJ matrix 106049b5e25fSSatish Balay - indices - the column indices 106149b5e25fSSatish Balay 106249b5e25fSSatish Balay Level: advanced 106349b5e25fSSatish Balay 106449b5e25fSSatish Balay Notes: 106549b5e25fSSatish Balay This can be called if you have precomputed the nonzero structure of the 106649b5e25fSSatish Balay matrix and want to provide it to the matrix object to improve the performance 106749b5e25fSSatish Balay of the MatSetValues() operation. 106849b5e25fSSatish Balay 106949b5e25fSSatish Balay You MUST have set the correct numbers of nonzeros per row in the call to 1070d1be2dadSMatthew Knepley MatCreateSeqSBAIJ(), and the columns indices MUST be sorted. 107149b5e25fSSatish Balay 1072ab9f2c04SSatish Balay MUST be called before any calls to MatSetValues() 107349b5e25fSSatish Balay 1074ab9f2c04SSatish Balay .seealso: MatCreateSeqSBAIJ 107549b5e25fSSatish Balay @*/ 1076be1d678aSKris Buschelman PetscErrorCode PETSCMAT_DLLEXPORT MatSeqSBAIJSetColumnIndices(Mat mat,PetscInt *indices) 107749b5e25fSSatish Balay { 107813f74950SBarry Smith PetscErrorCode ierr,(*f)(Mat,PetscInt *); 107949b5e25fSSatish Balay 108049b5e25fSSatish Balay PetscFunctionBegin; 10814482741eSBarry Smith PetscValidHeaderSpecific(mat,MAT_COOKIE,1); 10824482741eSBarry Smith PetscValidPointer(indices,2); 1083c134de8dSSatish Balay ierr = PetscObjectQueryFunction((PetscObject)mat,"MatSeqSBAIJSetColumnIndices_C",(void (**)(void))&f);CHKERRQ(ierr); 108449b5e25fSSatish Balay if (f) { 108549b5e25fSSatish Balay ierr = (*f)(mat,indices);CHKERRQ(ierr); 108649b5e25fSSatish Balay } else { 1087e005ede5SBarry Smith SETERRQ(PETSC_ERR_SUP,"Wrong type of matrix to set column indices"); 108849b5e25fSSatish Balay } 108949b5e25fSSatish Balay PetscFunctionReturn(0); 109049b5e25fSSatish Balay } 109149b5e25fSSatish Balay 10924a2ae208SSatish Balay #undef __FUNCT__ 10933c896bc6SHong Zhang #define __FUNCT__ "MatCopy_SeqSBAIJ" 10943c896bc6SHong Zhang PetscErrorCode MatCopy_SeqSBAIJ(Mat A,Mat B,MatStructure str) 10953c896bc6SHong Zhang { 10963c896bc6SHong Zhang PetscErrorCode ierr; 10973c896bc6SHong Zhang 10983c896bc6SHong Zhang PetscFunctionBegin; 10993c896bc6SHong Zhang /* If the two matrices have the same copy implementation, use fast copy. */ 11003c896bc6SHong Zhang if (str == SAME_NONZERO_PATTERN && (A->ops->copy == B->ops->copy)) { 11013c896bc6SHong Zhang Mat_SeqSBAIJ *a = (Mat_SeqSBAIJ*)A->data; 11023c896bc6SHong Zhang Mat_SeqSBAIJ *b = (Mat_SeqSBAIJ*)B->data; 11033c896bc6SHong Zhang 1104d0f46423SBarry Smith if (a->i[A->rmap->N] != b->i[B->rmap->N]) { 11053c896bc6SHong Zhang SETERRQ(PETSC_ERR_ARG_INCOMP,"Number of nonzeros in two matrices are different"); 11063c896bc6SHong Zhang } 1107d0f46423SBarry Smith ierr = PetscMemcpy(b->a,a->a,(a->i[A->rmap->N])*sizeof(PetscScalar));CHKERRQ(ierr); 11083c896bc6SHong Zhang } else { 1109f5edf698SHong Zhang ierr = MatGetRowUpperTriangular(A);CHKERRQ(ierr); 11103c896bc6SHong Zhang ierr = MatCopy_Basic(A,B,str);CHKERRQ(ierr); 1111f5edf698SHong Zhang ierr = MatRestoreRowUpperTriangular(A);CHKERRQ(ierr); 11123c896bc6SHong Zhang } 11133c896bc6SHong Zhang PetscFunctionReturn(0); 11143c896bc6SHong Zhang } 11153c896bc6SHong Zhang 11163c896bc6SHong Zhang #undef __FUNCT__ 11174a2ae208SSatish Balay #define __FUNCT__ "MatSetUpPreallocation_SeqSBAIJ" 1118dfbe8321SBarry Smith PetscErrorCode MatSetUpPreallocation_SeqSBAIJ(Mat A) 1119273d9f13SBarry Smith { 1120dfbe8321SBarry Smith PetscErrorCode ierr; 1121273d9f13SBarry Smith 1122273d9f13SBarry Smith PetscFunctionBegin; 1123db4efbfdSBarry Smith ierr = MatSeqSBAIJSetPreallocation_SeqSBAIJ(A,-PetscMax(A->rmap->bs,1),PETSC_DEFAULT,0);CHKERRQ(ierr); 1124273d9f13SBarry Smith PetscFunctionReturn(0); 1125273d9f13SBarry Smith } 1126273d9f13SBarry Smith 1127a6ece127SHong Zhang #undef __FUNCT__ 1128a6ece127SHong Zhang #define __FUNCT__ "MatGetArray_SeqSBAIJ" 1129dfbe8321SBarry Smith PetscErrorCode MatGetArray_SeqSBAIJ(Mat A,PetscScalar *array[]) 1130a6ece127SHong Zhang { 1131a6ece127SHong Zhang Mat_SeqSBAIJ *a = (Mat_SeqSBAIJ*)A->data; 1132a6ece127SHong Zhang PetscFunctionBegin; 1133a6ece127SHong Zhang *array = a->a; 1134a6ece127SHong Zhang PetscFunctionReturn(0); 1135a6ece127SHong Zhang } 1136a6ece127SHong Zhang 1137a6ece127SHong Zhang #undef __FUNCT__ 1138a6ece127SHong Zhang #define __FUNCT__ "MatRestoreArray_SeqSBAIJ" 1139dfbe8321SBarry Smith PetscErrorCode MatRestoreArray_SeqSBAIJ(Mat A,PetscScalar *array[]) 1140a6ece127SHong Zhang { 1141a6ece127SHong Zhang PetscFunctionBegin; 1142a6ece127SHong Zhang PetscFunctionReturn(0); 1143a6ece127SHong Zhang } 1144a6ece127SHong Zhang 114542ee4b1aSHong Zhang #include "petscblaslapack.h" 114642ee4b1aSHong Zhang #undef __FUNCT__ 114742ee4b1aSHong Zhang #define __FUNCT__ "MatAXPY_SeqSBAIJ" 1148f4df32b1SMatthew Knepley PetscErrorCode MatAXPY_SeqSBAIJ(Mat Y,PetscScalar a,Mat X,MatStructure str) 114942ee4b1aSHong Zhang { 115042ee4b1aSHong Zhang Mat_SeqSBAIJ *x=(Mat_SeqSBAIJ *)X->data, *y=(Mat_SeqSBAIJ *)Y->data; 1151dfbe8321SBarry Smith PetscErrorCode ierr; 1152d0f46423SBarry Smith PetscInt i,bs=Y->rmap->bs,bs2,j; 11530805154bSBarry Smith PetscBLASInt one = 1,bnz = PetscBLASIntCast(x->nz); 115442ee4b1aSHong Zhang 115542ee4b1aSHong Zhang PetscFunctionBegin; 115642ee4b1aSHong Zhang if (str == SAME_NONZERO_PATTERN) { 1157f4df32b1SMatthew Knepley PetscScalar alpha = a; 1158f4df32b1SMatthew Knepley BLASaxpy_(&bnz,&alpha,x->a,&one,y->a,&one); 1159c537a176SHong Zhang } else if (str == SUBSET_NONZERO_PATTERN) { /* nonzeros of X is a subset of Y's */ 1160c4319e64SHong Zhang if (y->xtoy && y->XtoY != X) { 1161c4319e64SHong Zhang ierr = PetscFree(y->xtoy);CHKERRQ(ierr); 1162c4319e64SHong Zhang ierr = MatDestroy(y->XtoY);CHKERRQ(ierr); 1163c537a176SHong Zhang } 1164c4319e64SHong Zhang if (!y->xtoy) { /* get xtoy */ 1165c4319e64SHong Zhang ierr = MatAXPYGetxtoy_Private(x->mbs,x->i,x->j,PETSC_NULL, y->i,y->j,PETSC_NULL, &y->xtoy);CHKERRQ(ierr); 1166c4319e64SHong Zhang y->XtoY = X; 1167c537a176SHong Zhang } 1168c4319e64SHong Zhang bs2 = bs*bs; 11696c6c5352SBarry Smith for (i=0; i<x->nz; i++) { 1170c4319e64SHong Zhang j = 0; 1171c4319e64SHong Zhang while (j < bs2){ 1172f4df32b1SMatthew Knepley y->a[bs2*y->xtoy[i]+j] += a*(x->a[bs2*i+j]); 1173c4319e64SHong Zhang j++; 1174c537a176SHong Zhang } 1175c4319e64SHong Zhang } 11761e2582c4SBarry 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); 117742ee4b1aSHong Zhang } else { 1178f5edf698SHong Zhang ierr = MatGetRowUpperTriangular(X);CHKERRQ(ierr); 1179f4df32b1SMatthew Knepley ierr = MatAXPY_Basic(Y,a,X,str);CHKERRQ(ierr); 1180f5edf698SHong Zhang ierr = MatRestoreRowUpperTriangular(X);CHKERRQ(ierr); 118142ee4b1aSHong Zhang } 118242ee4b1aSHong Zhang PetscFunctionReturn(0); 118342ee4b1aSHong Zhang } 118442ee4b1aSHong Zhang 1185efcf0fc3SBarry Smith #undef __FUNCT__ 1186efcf0fc3SBarry Smith #define __FUNCT__ "MatIsSymmetric_SeqSBAIJ" 1187dfbe8321SBarry Smith PetscErrorCode MatIsSymmetric_SeqSBAIJ(Mat A,PetscReal tol,PetscTruth *flg) 1188efcf0fc3SBarry Smith { 1189efcf0fc3SBarry Smith PetscFunctionBegin; 1190efcf0fc3SBarry Smith *flg = PETSC_TRUE; 1191efcf0fc3SBarry Smith PetscFunctionReturn(0); 1192efcf0fc3SBarry Smith } 1193efcf0fc3SBarry Smith 1194efcf0fc3SBarry Smith #undef __FUNCT__ 1195efcf0fc3SBarry Smith #define __FUNCT__ "MatIsStructurallySymmetric_SeqSBAIJ" 1196dfbe8321SBarry Smith PetscErrorCode MatIsStructurallySymmetric_SeqSBAIJ(Mat A,PetscTruth *flg) 1197efcf0fc3SBarry Smith { 1198efcf0fc3SBarry Smith PetscFunctionBegin; 1199efcf0fc3SBarry Smith *flg = PETSC_TRUE; 1200efcf0fc3SBarry Smith PetscFunctionReturn(0); 1201efcf0fc3SBarry Smith } 1202efcf0fc3SBarry Smith 1203efcf0fc3SBarry Smith #undef __FUNCT__ 1204efcf0fc3SBarry Smith #define __FUNCT__ "MatIsHermitian_SeqSBAIJ" 1205ab5e4463SMatthew Knepley PetscErrorCode MatIsHermitian_SeqSBAIJ(Mat A,PetscReal tol,PetscTruth *flg) 1206efcf0fc3SBarry Smith { 1207efcf0fc3SBarry Smith PetscFunctionBegin; 1208efcf0fc3SBarry Smith *flg = PETSC_FALSE; 1209efcf0fc3SBarry Smith PetscFunctionReturn(0); 1210efcf0fc3SBarry Smith } 1211efcf0fc3SBarry Smith 121299cafbc1SBarry Smith #undef __FUNCT__ 121399cafbc1SBarry Smith #define __FUNCT__ "MatRealPart_SeqSBAIJ" 121499cafbc1SBarry Smith PetscErrorCode MatRealPart_SeqSBAIJ(Mat A) 121599cafbc1SBarry Smith { 121699cafbc1SBarry Smith Mat_SeqSBAIJ *a = (Mat_SeqSBAIJ*)A->data; 121799cafbc1SBarry Smith PetscInt i,nz = a->bs2*a->i[a->mbs]; 1218dd6ea824SBarry Smith MatScalar *aa = a->a; 121999cafbc1SBarry Smith 122099cafbc1SBarry Smith PetscFunctionBegin; 122199cafbc1SBarry Smith for (i=0; i<nz; i++) aa[i] = PetscRealPart(aa[i]); 122299cafbc1SBarry Smith PetscFunctionReturn(0); 122399cafbc1SBarry Smith } 122499cafbc1SBarry Smith 122599cafbc1SBarry Smith #undef __FUNCT__ 122699cafbc1SBarry Smith #define __FUNCT__ "MatImaginaryPart_SeqSBAIJ" 122799cafbc1SBarry Smith PetscErrorCode MatImaginaryPart_SeqSBAIJ(Mat A) 122899cafbc1SBarry Smith { 122999cafbc1SBarry Smith Mat_SeqSBAIJ *a = (Mat_SeqSBAIJ*)A->data; 123099cafbc1SBarry Smith PetscInt i,nz = a->bs2*a->i[a->mbs]; 1231dd6ea824SBarry Smith MatScalar *aa = a->a; 123299cafbc1SBarry Smith 123399cafbc1SBarry Smith PetscFunctionBegin; 123499cafbc1SBarry Smith for (i=0; i<nz; i++) aa[i] = PetscImaginaryPart(aa[i]); 123599cafbc1SBarry Smith PetscFunctionReturn(0); 123699cafbc1SBarry Smith } 123799cafbc1SBarry Smith 123849b5e25fSSatish Balay /* -------------------------------------------------------------------*/ 123949b5e25fSSatish Balay static struct _MatOps MatOps_Values = {MatSetValues_SeqSBAIJ, 124049b5e25fSSatish Balay MatGetRow_SeqSBAIJ, 124149b5e25fSSatish Balay MatRestoreRow_SeqSBAIJ, 124249b5e25fSSatish Balay MatMult_SeqSBAIJ_N, 124397304618SKris Buschelman /* 4*/ MatMultAdd_SeqSBAIJ_N, 1244431c96f7SBarry Smith MatMult_SeqSBAIJ_N, /* transpose versions are same as non-transpose versions */ 1245e005ede5SBarry Smith MatMultAdd_SeqSBAIJ_N, 1246db4efbfdSBarry Smith 0, 124749b5e25fSSatish Balay 0, 124849b5e25fSSatish Balay 0, 124997304618SKris Buschelman /*10*/ 0, 125049b5e25fSSatish Balay 0, 1251c078aec8SLisandro Dalcin MatCholeskyFactor_SeqSBAIJ, 1252d06b337dSHong Zhang MatRelax_SeqSBAIJ, 125349b5e25fSSatish Balay MatTranspose_SeqSBAIJ, 125497304618SKris Buschelman /*15*/ MatGetInfo_SeqSBAIJ, 125549b5e25fSSatish Balay MatEqual_SeqSBAIJ, 125649b5e25fSSatish Balay MatGetDiagonal_SeqSBAIJ, 125749b5e25fSSatish Balay MatDiagonalScale_SeqSBAIJ, 125849b5e25fSSatish Balay MatNorm_SeqSBAIJ, 125997304618SKris Buschelman /*20*/ 0, 126049b5e25fSSatish Balay MatAssemblyEnd_SeqSBAIJ, 126149b5e25fSSatish Balay MatSetOption_SeqSBAIJ, 126249b5e25fSSatish Balay MatZeroEntries_SeqSBAIJ, 1263d519adbfSMatthew Knepley /*24*/ 0, 126449b5e25fSSatish Balay 0, 126549b5e25fSSatish Balay 0, 1266db4efbfdSBarry Smith 0, 1267db4efbfdSBarry Smith 0, 1268d519adbfSMatthew Knepley /*29*/ MatSetUpPreallocation_SeqSBAIJ, 1269c464158bSHong Zhang 0, 1270db4efbfdSBarry Smith 0, 1271a6ece127SHong Zhang MatGetArray_SeqSBAIJ, 1272a6ece127SHong Zhang MatRestoreArray_SeqSBAIJ, 1273d519adbfSMatthew Knepley /*34*/ MatDuplicate_SeqSBAIJ, 1274719d5645SBarry Smith 0, 1275719d5645SBarry Smith 0, 127649b5e25fSSatish Balay 0, 1277c84f5b01SHong Zhang MatICCFactor_SeqSBAIJ, 1278d519adbfSMatthew Knepley /*39*/ MatAXPY_SeqSBAIJ, 127949b5e25fSSatish Balay MatGetSubMatrices_SeqSBAIJ, 128049b5e25fSSatish Balay MatIncreaseOverlap_SeqSBAIJ, 128149b5e25fSSatish Balay MatGetValues_SeqSBAIJ, 12823c896bc6SHong Zhang MatCopy_SeqSBAIJ, 1283d519adbfSMatthew Knepley /*44*/ 0, 128449b5e25fSSatish Balay MatScale_SeqSBAIJ, 128549b5e25fSSatish Balay 0, 128649b5e25fSSatish Balay 0, 128749b5e25fSSatish Balay 0, 1288d519adbfSMatthew Knepley /*49*/ 0, 128949b5e25fSSatish Balay MatGetRowIJ_SeqSBAIJ, 129049b5e25fSSatish Balay MatRestoreRowIJ_SeqSBAIJ, 129149b5e25fSSatish Balay 0, 129249b5e25fSSatish Balay 0, 1293d519adbfSMatthew Knepley /*54*/ 0, 129449b5e25fSSatish Balay 0, 129549b5e25fSSatish Balay 0, 129649b5e25fSSatish Balay 0, 129749b5e25fSSatish Balay MatSetValuesBlocked_SeqSBAIJ, 1298d519adbfSMatthew Knepley /*59*/ MatGetSubMatrix_SeqSBAIJ, 129949b5e25fSSatish Balay 0, 130049b5e25fSSatish Balay 0, 1301357abbc8SBarry Smith 0, 1302d959ec07SHong Zhang 0, 1303d519adbfSMatthew Knepley /*64*/ 0, 1304d959ec07SHong Zhang 0, 1305d959ec07SHong Zhang 0, 1306d959ec07SHong Zhang 0, 1307d959ec07SHong Zhang 0, 1308d519adbfSMatthew Knepley /*69*/ MatGetRowMaxAbs_SeqSBAIJ, 13093e0d88b5SBarry Smith 0, 13103e0d88b5SBarry Smith 0, 13113e0d88b5SBarry Smith 0, 13123e0d88b5SBarry Smith 0, 1313d519adbfSMatthew Knepley /*74*/ 0, 13143e0d88b5SBarry Smith 0, 13153e0d88b5SBarry Smith 0, 13163e0d88b5SBarry Smith 0, 13173e0d88b5SBarry Smith 0, 1318d519adbfSMatthew Knepley /*79*/ 0, 13193e0d88b5SBarry Smith 0, 13203e0d88b5SBarry Smith 0, 13213e0d88b5SBarry Smith #if !defined(PETSC_USE_COMPLEX) 132297304618SKris Buschelman MatGetInertia_SeqSBAIJ, 13233e0d88b5SBarry Smith #else 132497304618SKris Buschelman 0, 13253e0d88b5SBarry Smith #endif 1326865e5f61SKris Buschelman MatLoad_SeqSBAIJ, 1327d519adbfSMatthew Knepley /*84*/ MatIsSymmetric_SeqSBAIJ, 1328865e5f61SKris Buschelman MatIsHermitian_SeqSBAIJ, 1329efcf0fc3SBarry Smith MatIsStructurallySymmetric_SeqSBAIJ, 1330865e5f61SKris Buschelman 0, 1331865e5f61SKris Buschelman 0, 1332d519adbfSMatthew Knepley /*89*/ 0, 1333865e5f61SKris Buschelman 0, 1334865e5f61SKris Buschelman 0, 1335865e5f61SKris Buschelman 0, 1336865e5f61SKris Buschelman 0, 1337d519adbfSMatthew Knepley /*94*/ 0, 1338865e5f61SKris Buschelman 0, 1339865e5f61SKris Buschelman 0, 134099cafbc1SBarry Smith 0, 134199cafbc1SBarry Smith 0, 1342d519adbfSMatthew Knepley /*99*/ 0, 134399cafbc1SBarry Smith 0, 134499cafbc1SBarry Smith 0, 134599cafbc1SBarry Smith 0, 134699cafbc1SBarry Smith 0, 1347d519adbfSMatthew Knepley /*104*/0, 134899cafbc1SBarry Smith MatRealPart_SeqSBAIJ, 1349f5edf698SHong Zhang MatImaginaryPart_SeqSBAIJ, 1350f5edf698SHong Zhang MatGetRowUpperTriangular_SeqSBAIJ, 13512af78befSBarry Smith MatRestoreRowUpperTriangular_SeqSBAIJ, 1352d519adbfSMatthew Knepley /*109*/0, 13532af78befSBarry Smith 0, 13542af78befSBarry Smith 0, 13552af78befSBarry Smith 0, 13562af78befSBarry Smith MatMissingDiagonal_SeqSBAIJ 135799cafbc1SBarry Smith }; 1358be1d678aSKris Buschelman 135949b5e25fSSatish Balay EXTERN_C_BEGIN 13604a2ae208SSatish Balay #undef __FUNCT__ 13614a2ae208SSatish Balay #define __FUNCT__ "MatStoreValues_SeqSBAIJ" 1362be1d678aSKris Buschelman PetscErrorCode PETSCMAT_DLLEXPORT MatStoreValues_SeqSBAIJ(Mat mat) 136349b5e25fSSatish Balay { 13644afc71dfSHong Zhang Mat_SeqSBAIJ *aij = (Mat_SeqSBAIJ *)mat->data; 1365d0f46423SBarry Smith PetscInt nz = aij->i[mat->rmap->N]*mat->rmap->bs*aij->bs2; 1366dfbe8321SBarry Smith PetscErrorCode ierr; 136749b5e25fSSatish Balay 136849b5e25fSSatish Balay PetscFunctionBegin; 136949b5e25fSSatish Balay if (aij->nonew != 1) { 1370512a5fc5SBarry Smith SETERRQ(PETSC_ERR_ORDER,"Must call MatSetOption(A,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE);first"); 137149b5e25fSSatish Balay } 137249b5e25fSSatish Balay 137349b5e25fSSatish Balay /* allocate space for values if not already there */ 137449b5e25fSSatish Balay if (!aij->saved_values) { 137587828ca2SBarry Smith ierr = PetscMalloc((nz+1)*sizeof(PetscScalar),&aij->saved_values);CHKERRQ(ierr); 137649b5e25fSSatish Balay } 137749b5e25fSSatish Balay 137849b5e25fSSatish Balay /* copy values over */ 137987828ca2SBarry Smith ierr = PetscMemcpy(aij->saved_values,aij->a,nz*sizeof(PetscScalar));CHKERRQ(ierr); 138049b5e25fSSatish Balay PetscFunctionReturn(0); 138149b5e25fSSatish Balay } 138249b5e25fSSatish Balay EXTERN_C_END 138349b5e25fSSatish Balay 138449b5e25fSSatish Balay EXTERN_C_BEGIN 13854a2ae208SSatish Balay #undef __FUNCT__ 13864a2ae208SSatish Balay #define __FUNCT__ "MatRetrieveValues_SeqSBAIJ" 1387be1d678aSKris Buschelman PetscErrorCode PETSCMAT_DLLEXPORT MatRetrieveValues_SeqSBAIJ(Mat mat) 138849b5e25fSSatish Balay { 13894afc71dfSHong Zhang Mat_SeqSBAIJ *aij = (Mat_SeqSBAIJ *)mat->data; 13906849ba73SBarry Smith PetscErrorCode ierr; 1391d0f46423SBarry Smith PetscInt nz = aij->i[mat->rmap->N]*mat->rmap->bs*aij->bs2; 139249b5e25fSSatish Balay 139349b5e25fSSatish Balay PetscFunctionBegin; 139449b5e25fSSatish Balay if (aij->nonew != 1) { 1395512a5fc5SBarry Smith SETERRQ(PETSC_ERR_ORDER,"Must call MatSetOption(A,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE);first"); 139649b5e25fSSatish Balay } 139749b5e25fSSatish Balay if (!aij->saved_values) { 1398e005ede5SBarry Smith SETERRQ(PETSC_ERR_ORDER,"Must call MatStoreValues(A);first"); 139949b5e25fSSatish Balay } 140049b5e25fSSatish Balay 140149b5e25fSSatish Balay /* copy values over */ 140287828ca2SBarry Smith ierr = PetscMemcpy(aij->a,aij->saved_values,nz*sizeof(PetscScalar));CHKERRQ(ierr); 140349b5e25fSSatish Balay PetscFunctionReturn(0); 140449b5e25fSSatish Balay } 140549b5e25fSSatish Balay EXTERN_C_END 140649b5e25fSSatish Balay 14078549e402SHong Zhang EXTERN_C_BEGIN 14084a2ae208SSatish Balay #undef __FUNCT__ 1409a23d5eceSKris Buschelman #define __FUNCT__ "MatSeqSBAIJSetPreallocation_SeqSBAIJ" 1410be1d678aSKris Buschelman PetscErrorCode PETSCMAT_DLLEXPORT MatSeqSBAIJSetPreallocation_SeqSBAIJ(Mat B,PetscInt bs,PetscInt nz,PetscInt *nnz) 141149b5e25fSSatish Balay { 1412c464158bSHong Zhang Mat_SeqSBAIJ *b = (Mat_SeqSBAIJ*)B->data; 14136849ba73SBarry Smith PetscErrorCode ierr; 1414db4efbfdSBarry Smith PetscInt i,mbs,bs2, newbs = PetscAbs(bs); 141590d69ab7SBarry Smith PetscTruth skipallocation = PETSC_FALSE,flg = PETSC_FALSE; 141649b5e25fSSatish Balay 141749b5e25fSSatish Balay PetscFunctionBegin; 1418273d9f13SBarry Smith B->preallocated = PETSC_TRUE; 1419db4efbfdSBarry Smith if (bs < 0) { 1420db4efbfdSBarry Smith ierr = PetscOptionsBegin(((PetscObject)B)->comm,((PetscObject)B)->prefix,"Options for MPISBAIJ matrix","Mat");CHKERRQ(ierr); 1421db4efbfdSBarry Smith ierr = PetscOptionsInt("-mat_block_size","Set the blocksize used to store the matrix","MatSeqSBAIJSetPreallocation",newbs,&newbs,PETSC_NULL);CHKERRQ(ierr); 1422db4efbfdSBarry Smith ierr = PetscOptionsEnd();CHKERRQ(ierr); 1423db4efbfdSBarry Smith bs = PetscAbs(bs); 1424db4efbfdSBarry Smith } 1425db4efbfdSBarry Smith if (nnz && newbs != bs) { 1426db4efbfdSBarry Smith SETERRQ(PETSC_ERR_ARG_WRONG,"Cannot change blocksize from command line if setting nnz"); 1427db4efbfdSBarry Smith } 1428db4efbfdSBarry Smith bs = newbs; 1429db4efbfdSBarry Smith 14307408324eSLisandro Dalcin ierr = PetscMapSetBlockSize(B->rmap,bs);CHKERRQ(ierr); 14317408324eSLisandro Dalcin ierr = PetscMapSetBlockSize(B->cmap,bs);CHKERRQ(ierr); 1432d0f46423SBarry Smith ierr = PetscMapSetUp(B->rmap);CHKERRQ(ierr); 1433d0f46423SBarry Smith ierr = PetscMapSetUp(B->cmap);CHKERRQ(ierr); 1434899cda47SBarry Smith 1435d0f46423SBarry Smith mbs = B->rmap->N/bs; 143649b5e25fSSatish Balay bs2 = bs*bs; 143749b5e25fSSatish Balay 1438d0f46423SBarry Smith if (mbs*bs != B->rmap->N) { 143929bbc08cSBarry Smith SETERRQ(PETSC_ERR_ARG_SIZ,"Number rows, cols must be divisible by blocksize"); 144049b5e25fSSatish Balay } 144149b5e25fSSatish Balay 1442ab93d7beSBarry Smith if (nz == MAT_SKIP_ALLOCATION) { 1443ab93d7beSBarry Smith skipallocation = PETSC_TRUE; 1444ab93d7beSBarry Smith nz = 0; 1445ab93d7beSBarry Smith } 1446ab93d7beSBarry Smith 1447435da068SBarry Smith if (nz == PETSC_DEFAULT || nz == PETSC_DECIDE) nz = 3; 144877431f27SBarry Smith if (nz < 0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"nz cannot be less than 0: value %D",nz); 144949b5e25fSSatish Balay if (nnz) { 145049b5e25fSSatish Balay for (i=0; i<mbs; i++) { 145177431f27SBarry Smith if (nnz[i] < 0) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"nnz cannot be less than 0: local row %D value %D",i,nnz[i]); 145277431f27SBarry 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); 145349b5e25fSSatish Balay } 145449b5e25fSSatish Balay } 145549b5e25fSSatish Balay 1456db4efbfdSBarry Smith B->ops->mult = MatMult_SeqSBAIJ_N; 1457db4efbfdSBarry Smith B->ops->multadd = MatMultAdd_SeqSBAIJ_N; 1458db4efbfdSBarry Smith B->ops->multtranspose = MatMult_SeqSBAIJ_N; 1459db4efbfdSBarry Smith B->ops->multtransposeadd = MatMultAdd_SeqSBAIJ_N; 146090d69ab7SBarry Smith ierr = PetscOptionsGetTruth(((PetscObject)B)->prefix,"-mat_no_unroll",&flg,PETSC_NULL);CHKERRQ(ierr); 146149b5e25fSSatish Balay if (!flg) { 146249b5e25fSSatish Balay switch (bs) { 146349b5e25fSSatish Balay case 1: 146449b5e25fSSatish Balay B->ops->mult = MatMult_SeqSBAIJ_1; 146549b5e25fSSatish Balay B->ops->multadd = MatMultAdd_SeqSBAIJ_1; 1466431c96f7SBarry Smith B->ops->multtranspose = MatMult_SeqSBAIJ_1; 1467431c96f7SBarry Smith B->ops->multtransposeadd = MatMultAdd_SeqSBAIJ_1; 146849b5e25fSSatish Balay break; 146949b5e25fSSatish Balay case 2: 147049b5e25fSSatish Balay B->ops->mult = MatMult_SeqSBAIJ_2; 147149b5e25fSSatish Balay B->ops->multadd = MatMultAdd_SeqSBAIJ_2; 1472431c96f7SBarry Smith B->ops->multtranspose = MatMult_SeqSBAIJ_2; 1473431c96f7SBarry Smith B->ops->multtransposeadd = MatMultAdd_SeqSBAIJ_2; 147449b5e25fSSatish Balay break; 147549b5e25fSSatish Balay case 3: 147649b5e25fSSatish Balay B->ops->mult = MatMult_SeqSBAIJ_3; 147749b5e25fSSatish Balay B->ops->multadd = MatMultAdd_SeqSBAIJ_3; 1478431c96f7SBarry Smith B->ops->multtranspose = MatMult_SeqSBAIJ_3; 1479431c96f7SBarry Smith B->ops->multtransposeadd = MatMultAdd_SeqSBAIJ_3; 148049b5e25fSSatish Balay break; 148149b5e25fSSatish Balay case 4: 148249b5e25fSSatish Balay B->ops->mult = MatMult_SeqSBAIJ_4; 148349b5e25fSSatish Balay B->ops->multadd = MatMultAdd_SeqSBAIJ_4; 1484431c96f7SBarry Smith B->ops->multtranspose = MatMult_SeqSBAIJ_4; 1485431c96f7SBarry Smith B->ops->multtransposeadd = MatMultAdd_SeqSBAIJ_4; 148649b5e25fSSatish Balay break; 148749b5e25fSSatish Balay case 5: 148849b5e25fSSatish Balay B->ops->mult = MatMult_SeqSBAIJ_5; 148949b5e25fSSatish Balay B->ops->multadd = MatMultAdd_SeqSBAIJ_5; 1490431c96f7SBarry Smith B->ops->multtranspose = MatMult_SeqSBAIJ_5; 1491431c96f7SBarry Smith B->ops->multtransposeadd = MatMultAdd_SeqSBAIJ_5; 149249b5e25fSSatish Balay break; 149349b5e25fSSatish Balay case 6: 149449b5e25fSSatish Balay B->ops->mult = MatMult_SeqSBAIJ_6; 149549b5e25fSSatish Balay B->ops->multadd = MatMultAdd_SeqSBAIJ_6; 1496431c96f7SBarry Smith B->ops->multtranspose = MatMult_SeqSBAIJ_6; 1497431c96f7SBarry Smith B->ops->multtransposeadd = MatMultAdd_SeqSBAIJ_6; 149849b5e25fSSatish Balay break; 149949b5e25fSSatish Balay case 7: 1500de53e5efSHong Zhang B->ops->mult = MatMult_SeqSBAIJ_7; 150149b5e25fSSatish Balay B->ops->multadd = MatMultAdd_SeqSBAIJ_7; 1502431c96f7SBarry Smith B->ops->multtranspose = MatMult_SeqSBAIJ_7; 1503431c96f7SBarry Smith B->ops->multtransposeadd = MatMultAdd_SeqSBAIJ_7; 150449b5e25fSSatish Balay break; 150549b5e25fSSatish Balay } 150649b5e25fSSatish Balay } 150749b5e25fSSatish Balay 150849b5e25fSSatish Balay b->mbs = mbs; 15094afc71dfSHong Zhang b->nbs = mbs; 1510ab93d7beSBarry Smith if (!skipallocation) { 15112ee49352SLisandro Dalcin if (!b->imax) { 1512ab93d7beSBarry Smith ierr = PetscMalloc2(mbs,PetscInt,&b->imax,mbs,PetscInt,&b->ilen);CHKERRQ(ierr); 15132ee49352SLisandro Dalcin ierr = PetscLogObjectMemory(B,2*mbs*sizeof(PetscInt));CHKERRQ(ierr); 15142ee49352SLisandro Dalcin } 151549b5e25fSSatish Balay if (!nnz) { 1516435da068SBarry Smith if (nz == PETSC_DEFAULT || nz == PETSC_DECIDE) nz = 5; 151749b5e25fSSatish Balay else if (nz <= 0) nz = 1; 151849b5e25fSSatish Balay for (i=0; i<mbs; i++) { 15198cef66ccSHong Zhang b->imax[i] = nz; 152049b5e25fSSatish Balay } 1521153ea458SHong Zhang nz = nz*mbs; /* total nz */ 152249b5e25fSSatish Balay } else { 152349b5e25fSSatish Balay nz = 0; 15248cef66ccSHong Zhang for (i=0; i<mbs; i++) {b->imax[i] = nnz[i]; nz += nnz[i];} 152549b5e25fSSatish Balay } 15262ee49352SLisandro Dalcin /* b->ilen will count nonzeros in each block row so far. */ 15272ee49352SLisandro Dalcin for (i=0; i<mbs; i++) { b->ilen[i] = 0;} 15286c6c5352SBarry Smith /* nz=(nz+mbs)/2; */ /* total diagonal and superdiagonal nonzero blocks */ 152949b5e25fSSatish Balay 153049b5e25fSSatish Balay /* allocate the matrix space */ 15312ee49352SLisandro Dalcin ierr = MatSeqXAIJFreeAIJ(B,&b->a,&b->j,&b->i);CHKERRQ(ierr); 1532d0f46423SBarry Smith ierr = PetscMalloc3(bs2*nz,PetscScalar,&b->a,nz,PetscInt,&b->j,B->rmap->N+1,PetscInt,&b->i);CHKERRQ(ierr); 1533d0f46423SBarry Smith ierr = PetscLogObjectMemory(B,(B->rmap->N+1)*sizeof(PetscInt)+nz*(bs2*sizeof(PetscScalar)+sizeof(PetscInt)));CHKERRQ(ierr); 15346c6c5352SBarry Smith ierr = PetscMemzero(b->a,nz*bs2*sizeof(MatScalar));CHKERRQ(ierr); 153513f74950SBarry Smith ierr = PetscMemzero(b->j,nz*sizeof(PetscInt));CHKERRQ(ierr); 153649b5e25fSSatish Balay b->singlemalloc = PETSC_TRUE; 153749b5e25fSSatish Balay 153849b5e25fSSatish Balay /* pointer to beginning of each row */ 153949b5e25fSSatish Balay b->i[0] = 0; 154049b5e25fSSatish Balay for (i=1; i<mbs+1; i++) { 154149b5e25fSSatish Balay b->i[i] = b->i[i-1] + b->imax[i-1]; 154249b5e25fSSatish Balay } 1543e6b907acSBarry Smith b->free_a = PETSC_TRUE; 1544e6b907acSBarry Smith b->free_ij = PETSC_TRUE; 1545e811da20SHong Zhang } else { 1546e6b907acSBarry Smith b->free_a = PETSC_FALSE; 1547e6b907acSBarry Smith b->free_ij = PETSC_FALSE; 1548ab93d7beSBarry Smith } 154949b5e25fSSatish Balay 1550d0f46423SBarry Smith B->rmap->bs = bs; 155149b5e25fSSatish Balay b->bs2 = bs2; 15526c6c5352SBarry Smith b->nz = 0; 15536c6c5352SBarry Smith b->maxnz = nz*bs2; 1554153ea458SHong Zhang 155516cdd363SHong Zhang b->inew = 0; 155616cdd363SHong Zhang b->jnew = 0; 155716cdd363SHong Zhang b->anew = 0; 155816cdd363SHong Zhang b->a2anew = 0; 15591a3463dfSHong Zhang b->permute = PETSC_FALSE; 1560c464158bSHong Zhang PetscFunctionReturn(0); 1561c464158bSHong Zhang } 1562a23d5eceSKris Buschelman EXTERN_C_END 1563153ea458SHong Zhang 1564db4efbfdSBarry Smith #undef __FUNCT__ 1565db4efbfdSBarry Smith #define __FUNCT__ "MatSeqBAIJSetNumericFactorization" 1566db4efbfdSBarry Smith /* 1567db4efbfdSBarry Smith This is used to set the numeric factorization for both Cholesky and ICC symbolic factorization 1568db4efbfdSBarry Smith */ 1569db4efbfdSBarry Smith PetscErrorCode MatSeqSBAIJSetNumericFactorization(Mat B,PetscTruth natural) 1570db4efbfdSBarry Smith { 1571db4efbfdSBarry Smith PetscErrorCode ierr; 157290d69ab7SBarry Smith PetscTruth flg = PETSC_FALSE; 1573db4efbfdSBarry Smith PetscInt bs = B->rmap->bs; 1574db4efbfdSBarry Smith 1575db4efbfdSBarry Smith PetscFunctionBegin; 157690d69ab7SBarry Smith ierr = PetscOptionsGetTruth(((PetscObject)B)->prefix,"-mat_no_unroll",&flg,PETSC_NULL);CHKERRQ(ierr); 1577db4efbfdSBarry Smith if (flg) bs = 8; 1578db4efbfdSBarry Smith 1579db4efbfdSBarry Smith if (!natural) { 1580db4efbfdSBarry Smith switch (bs) { 1581db4efbfdSBarry Smith case 1: 1582db4efbfdSBarry Smith B->ops->choleskyfactornumeric = MatCholeskyFactorNumeric_SeqSBAIJ_1; 1583db4efbfdSBarry Smith break; 1584db4efbfdSBarry Smith case 2: 1585db4efbfdSBarry Smith B->ops->choleskyfactornumeric = MatCholeskyFactorNumeric_SeqSBAIJ_2; 1586db4efbfdSBarry Smith break; 1587db4efbfdSBarry Smith case 3: 1588db4efbfdSBarry Smith B->ops->choleskyfactornumeric = MatCholeskyFactorNumeric_SeqSBAIJ_3; 1589db4efbfdSBarry Smith break; 1590db4efbfdSBarry Smith case 4: 1591db4efbfdSBarry Smith B->ops->choleskyfactornumeric = MatCholeskyFactorNumeric_SeqSBAIJ_4; 1592db4efbfdSBarry Smith break; 1593db4efbfdSBarry Smith case 5: 1594db4efbfdSBarry Smith B->ops->choleskyfactornumeric = MatCholeskyFactorNumeric_SeqSBAIJ_5; 1595db4efbfdSBarry Smith break; 1596db4efbfdSBarry Smith case 6: 1597db4efbfdSBarry Smith B->ops->choleskyfactornumeric = MatCholeskyFactorNumeric_SeqSBAIJ_6; 1598db4efbfdSBarry Smith break; 1599db4efbfdSBarry Smith case 7: 1600db4efbfdSBarry Smith B->ops->choleskyfactornumeric = MatCholeskyFactorNumeric_SeqSBAIJ_7; 1601db4efbfdSBarry Smith break; 1602db4efbfdSBarry Smith default: 1603db4efbfdSBarry Smith B->ops->choleskyfactornumeric = MatCholeskyFactorNumeric_SeqSBAIJ_N; 1604db4efbfdSBarry Smith break; 1605db4efbfdSBarry Smith } 1606db4efbfdSBarry Smith } else { 1607db4efbfdSBarry Smith switch (bs) { 1608db4efbfdSBarry Smith case 1: 1609db4efbfdSBarry Smith B->ops->choleskyfactornumeric = MatCholeskyFactorNumeric_SeqSBAIJ_1_NaturalOrdering; 1610db4efbfdSBarry Smith break; 1611db4efbfdSBarry Smith case 2: 1612db4efbfdSBarry Smith B->ops->choleskyfactornumeric = MatCholeskyFactorNumeric_SeqSBAIJ_2_NaturalOrdering; 1613db4efbfdSBarry Smith break; 1614db4efbfdSBarry Smith case 3: 1615db4efbfdSBarry Smith B->ops->choleskyfactornumeric = MatCholeskyFactorNumeric_SeqSBAIJ_3_NaturalOrdering; 1616db4efbfdSBarry Smith break; 1617db4efbfdSBarry Smith case 4: 1618db4efbfdSBarry Smith B->ops->choleskyfactornumeric = MatCholeskyFactorNumeric_SeqSBAIJ_4_NaturalOrdering; 1619db4efbfdSBarry Smith break; 1620db4efbfdSBarry Smith case 5: 1621db4efbfdSBarry Smith B->ops->choleskyfactornumeric = MatCholeskyFactorNumeric_SeqSBAIJ_5_NaturalOrdering; 1622db4efbfdSBarry Smith break; 1623db4efbfdSBarry Smith case 6: 1624db4efbfdSBarry Smith B->ops->choleskyfactornumeric = MatCholeskyFactorNumeric_SeqSBAIJ_6_NaturalOrdering; 1625db4efbfdSBarry Smith break; 1626db4efbfdSBarry Smith case 7: 1627db4efbfdSBarry Smith B->ops->choleskyfactornumeric = MatCholeskyFactorNumeric_SeqSBAIJ_7_NaturalOrdering; 1628db4efbfdSBarry Smith break; 1629db4efbfdSBarry Smith default: 1630db4efbfdSBarry Smith B->ops->choleskyfactornumeric = MatCholeskyFactorNumeric_SeqSBAIJ_N_NaturalOrdering; 1631db4efbfdSBarry Smith break; 1632db4efbfdSBarry Smith } 1633db4efbfdSBarry Smith } 1634db4efbfdSBarry Smith PetscFunctionReturn(0); 1635db4efbfdSBarry Smith } 1636db4efbfdSBarry Smith 1637d769727bSBarry Smith EXTERN_C_BEGIN 1638f69a0ea3SMatthew Knepley EXTERN PetscErrorCode PETSCMAT_DLLEXPORT MatConvert_SeqSBAIJ_SeqAIJ(Mat, MatType,MatReuse,Mat*); 1639f69a0ea3SMatthew Knepley EXTERN PetscErrorCode PETSCMAT_DLLEXPORT MatConvert_SeqSBAIJ_SeqBAIJ(Mat, MatType,MatReuse,Mat*); 1640d769727bSBarry Smith EXTERN_C_END 1641d769727bSBarry Smith 1642e631078cSBarry Smith 1643e631078cSBarry Smith EXTERN_C_BEGIN 16445c9eb25fSBarry Smith #undef __FUNCT__ 16455c9eb25fSBarry Smith #define __FUNCT__ "MatGetFactor_seqsbaij_petsc" 16465c9eb25fSBarry Smith PetscErrorCode MatGetFactor_seqsbaij_petsc(Mat A,MatFactorType ftype,Mat *B) 16475c9eb25fSBarry Smith { 1648d0f46423SBarry Smith PetscInt n = A->rmap->n; 16495c9eb25fSBarry Smith PetscErrorCode ierr; 16505c9eb25fSBarry Smith 16515c9eb25fSBarry Smith PetscFunctionBegin; 16525c9eb25fSBarry Smith ierr = MatCreate(((PetscObject)A)->comm,B);CHKERRQ(ierr); 16535c9eb25fSBarry Smith ierr = MatSetSizes(*B,n,n,n,n);CHKERRQ(ierr); 16545c9eb25fSBarry Smith if (ftype == MAT_FACTOR_CHOLESKY || ftype == MAT_FACTOR_ICC) { 16555c9eb25fSBarry Smith ierr = MatSetType(*B,MATSEQSBAIJ);CHKERRQ(ierr); 16565c9eb25fSBarry Smith ierr = MatSeqSBAIJSetPreallocation(*B,1,MAT_SKIP_ALLOCATION,PETSC_NULL);CHKERRQ(ierr); 1657db4efbfdSBarry Smith (*B)->ops->choleskyfactorsymbolic = MatCholeskyFactorSymbolic_SeqSBAIJ; 1658db4efbfdSBarry Smith (*B)->ops->iccfactorsymbolic = MatICCFactorSymbolic_SeqSBAIJ; 16595c9eb25fSBarry Smith } else SETERRQ(PETSC_ERR_SUP,"Factor type not supported"); 1660719d5645SBarry Smith (*B)->factor = ftype; 16615c9eb25fSBarry Smith PetscFunctionReturn(0); 16625c9eb25fSBarry Smith } 1663e631078cSBarry Smith EXTERN_C_END 16645c9eb25fSBarry Smith 16655c9eb25fSBarry Smith EXTERN_C_BEGIN 1666db4efbfdSBarry Smith #undef __FUNCT__ 1667db4efbfdSBarry Smith #define __FUNCT__ "MatGetFactorAvailable_seqsbaij_petsc" 1668db4efbfdSBarry Smith PetscErrorCode MatGetFactorAvailable_seqsbaij_petsc(Mat A,MatFactorType ftype,PetscTruth *flg) 1669db4efbfdSBarry Smith { 1670db4efbfdSBarry Smith PetscFunctionBegin; 1671db4efbfdSBarry Smith if (ftype == MAT_FACTOR_CHOLESKY || ftype == MAT_FACTOR_ICC) { 1672db4efbfdSBarry Smith *flg = PETSC_TRUE; 1673db4efbfdSBarry Smith } else { 1674db4efbfdSBarry Smith *flg = PETSC_FALSE; 1675db4efbfdSBarry Smith } 1676db4efbfdSBarry Smith PetscFunctionReturn(0); 1677db4efbfdSBarry Smith } 1678db4efbfdSBarry Smith EXTERN_C_END 1679db4efbfdSBarry Smith 1680db4efbfdSBarry Smith EXTERN_C_BEGIN 1681611f576cSBarry Smith #if defined(PETSC_HAVE_MUMPS) 16825c9eb25fSBarry Smith extern PetscErrorCode MatGetFactor_seqsbaij_mumps(Mat,MatFactorType,Mat*); 1683611f576cSBarry Smith #endif 1684611f576cSBarry Smith #if defined(PETSC_HAVE_SPOOLES) 16855c9eb25fSBarry Smith extern PetscErrorCode MatGetFactor_seqsbaij_spooles(Mat,MatFactorType,Mat*); 1686611f576cSBarry Smith #endif 1687b5e56a35SBarry Smith #if defined(PETSC_HAVE_PASTIX) 1688b5e56a35SBarry Smith extern PetscErrorCode MatGetFactor_seqsbaij_pastix(Mat,MatFactorType,Mat*); 1689b5e56a35SBarry Smith #endif 16905c9eb25fSBarry Smith EXTERN_C_END 16915c9eb25fSBarry Smith 16920bad9183SKris Buschelman /*MC 1693fafad747SKris Buschelman MATSEQSBAIJ - MATSEQSBAIJ = "seqsbaij" - A matrix type to be used for sequential symmetric block sparse matrices, 16940bad9183SKris Buschelman based on block compressed sparse row format. Only the upper triangular portion of the matrix is stored. 16950bad9183SKris Buschelman 16960bad9183SKris Buschelman Options Database Keys: 16970bad9183SKris Buschelman . -mat_type seqsbaij - sets the matrix type to "seqsbaij" during a call to MatSetFromOptions() 16980bad9183SKris Buschelman 16990bad9183SKris Buschelman Level: beginner 17000bad9183SKris Buschelman 17010bad9183SKris Buschelman .seealso: MatCreateSeqSBAIJ 17020bad9183SKris Buschelman M*/ 17030bad9183SKris Buschelman 1704a23d5eceSKris Buschelman EXTERN_C_BEGIN 1705a23d5eceSKris Buschelman #undef __FUNCT__ 1706a23d5eceSKris Buschelman #define __FUNCT__ "MatCreate_SeqSBAIJ" 1707be1d678aSKris Buschelman PetscErrorCode PETSCMAT_DLLEXPORT MatCreate_SeqSBAIJ(Mat B) 1708a23d5eceSKris Buschelman { 1709a23d5eceSKris Buschelman Mat_SeqSBAIJ *b; 1710dfbe8321SBarry Smith PetscErrorCode ierr; 171113f74950SBarry Smith PetscMPIInt size; 17120def2e27SBarry Smith PetscTruth no_unroll = PETSC_FALSE,no_inode = PETSC_FALSE; 1713a23d5eceSKris Buschelman 1714a23d5eceSKris Buschelman PetscFunctionBegin; 17157adad957SLisandro Dalcin ierr = MPI_Comm_size(((PetscObject)B)->comm,&size);CHKERRQ(ierr); 1716a23d5eceSKris Buschelman if (size > 1) SETERRQ(PETSC_ERR_ARG_WRONG,"Comm must be of size 1"); 1717a23d5eceSKris Buschelman 171838f2d2fdSLisandro Dalcin ierr = PetscNewLog(B,Mat_SeqSBAIJ,&b);CHKERRQ(ierr); 1719a23d5eceSKris Buschelman B->data = (void*)b; 1720a23d5eceSKris Buschelman ierr = PetscMemcpy(B->ops,&MatOps_Values,sizeof(struct _MatOps));CHKERRQ(ierr); 1721a23d5eceSKris Buschelman B->ops->destroy = MatDestroy_SeqSBAIJ; 1722a23d5eceSKris Buschelman B->ops->view = MatView_SeqSBAIJ; 1723a23d5eceSKris Buschelman B->mapping = 0; 1724a23d5eceSKris Buschelman b->row = 0; 1725a23d5eceSKris Buschelman b->icol = 0; 1726a23d5eceSKris Buschelman b->reallocs = 0; 1727a23d5eceSKris Buschelman b->saved_values = 0; 17280def2e27SBarry Smith b->inode.limit = 5; 17290def2e27SBarry Smith b->inode.max_limit = 5; 1730a23d5eceSKris Buschelman 1731a23d5eceSKris Buschelman b->roworiented = PETSC_TRUE; 1732a23d5eceSKris Buschelman b->nonew = 0; 1733a23d5eceSKris Buschelman b->diag = 0; 1734a23d5eceSKris Buschelman b->solve_work = 0; 1735a23d5eceSKris Buschelman b->mult_work = 0; 1736a23d5eceSKris Buschelman B->spptr = 0; 1737a9817697SBarry Smith b->keepnonzeropattern = PETSC_FALSE; 1738a23d5eceSKris Buschelman b->xtoy = 0; 1739a23d5eceSKris Buschelman b->XtoY = 0; 1740a23d5eceSKris Buschelman 1741a23d5eceSKris Buschelman b->inew = 0; 1742a23d5eceSKris Buschelman b->jnew = 0; 1743a23d5eceSKris Buschelman b->anew = 0; 1744a23d5eceSKris Buschelman b->a2anew = 0; 1745a23d5eceSKris Buschelman b->permute = PETSC_FALSE; 1746a23d5eceSKris Buschelman 1747941593c8SHong Zhang b->ignore_ltriangular = PETSC_FALSE; 174890d69ab7SBarry Smith ierr = PetscOptionsGetTruth(((PetscObject)B)->prefix,"-mat_ignore_lower_triangular",&b->ignore_ltriangular,PETSC_NULL);CHKERRQ(ierr); 1749941593c8SHong Zhang 1750f5edf698SHong Zhang b->getrow_utriangular = PETSC_FALSE; 175190d69ab7SBarry Smith ierr = PetscOptionsGetTruth(((PetscObject)B)->prefix,"-mat_getrow_uppertriangular",&b->getrow_utriangular,PETSC_NULL);CHKERRQ(ierr); 1752f5edf698SHong Zhang 1753b5e56a35SBarry Smith #if defined(PETSC_HAVE_PASTIX) 1754b5e56a35SBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatGetFactor_seqsbaij_pastix_C", 1755b5e56a35SBarry Smith "MatGetFactor_seqsbaij_pastix", 1756b5e56a35SBarry Smith MatGetFactor_seqsbaij_pastix);CHKERRQ(ierr); 1757b5e56a35SBarry Smith #endif 1758611f576cSBarry Smith #if defined(PETSC_HAVE_SPOOLES) 17595c9eb25fSBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatGetFactor_seqsbaij_spooles_C", 17605c9eb25fSBarry Smith "MatGetFactor_seqsbaij_spooles", 17615c9eb25fSBarry Smith MatGetFactor_seqsbaij_spooles);CHKERRQ(ierr); 1762611f576cSBarry Smith #endif 1763611f576cSBarry Smith #if defined(PETSC_HAVE_MUMPS) 17645c9eb25fSBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatGetFactor_seqsbaij_mumps_C", 17655c9eb25fSBarry Smith "MatGetFactor_seqsbaij_mumps", 17665c9eb25fSBarry Smith MatGetFactor_seqsbaij_mumps);CHKERRQ(ierr); 1767611f576cSBarry Smith #endif 1768db4efbfdSBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatGetFactorAvailable_seqsbaij_petsc_C", 1769db4efbfdSBarry Smith "MatGetFactorAvailable_seqsbaij_petsc", 1770db4efbfdSBarry Smith MatGetFactorAvailable_seqsbaij_petsc);CHKERRQ(ierr); 17715c9eb25fSBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatGetFactor_seqsbaij_petsc_C", 17725c9eb25fSBarry Smith "MatGetFactor_seqsbaij_petsc", 17735c9eb25fSBarry Smith MatGetFactor_seqsbaij_petsc);CHKERRQ(ierr); 1774a23d5eceSKris Buschelman ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatStoreValues_C", 1775a23d5eceSKris Buschelman "MatStoreValues_SeqSBAIJ", 1776a23d5eceSKris Buschelman MatStoreValues_SeqSBAIJ);CHKERRQ(ierr); 1777a23d5eceSKris Buschelman ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatRetrieveValues_C", 1778a23d5eceSKris Buschelman "MatRetrieveValues_SeqSBAIJ", 1779a23d5eceSKris Buschelman (void*)MatRetrieveValues_SeqSBAIJ);CHKERRQ(ierr); 1780a23d5eceSKris Buschelman ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatSeqSBAIJSetColumnIndices_C", 1781a23d5eceSKris Buschelman "MatSeqSBAIJSetColumnIndices_SeqSBAIJ", 1782a23d5eceSKris Buschelman MatSeqSBAIJSetColumnIndices_SeqSBAIJ);CHKERRQ(ierr); 17834e5e7fe4SHong Zhang ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatConvert_seqsbaij_seqaij_C", 17844e5e7fe4SHong Zhang "MatConvert_SeqSBAIJ_SeqAIJ", 17854e5e7fe4SHong Zhang MatConvert_SeqSBAIJ_SeqAIJ);CHKERRQ(ierr); 1786a0e1a404SHong Zhang ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatConvert_seqsbaij_seqbaij_C", 1787a0e1a404SHong Zhang "MatConvert_SeqSBAIJ_SeqBAIJ", 1788a0e1a404SHong Zhang MatConvert_SeqSBAIJ_SeqBAIJ);CHKERRQ(ierr); 1789a23d5eceSKris Buschelman ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatSeqSBAIJSetPreallocation_C", 1790a23d5eceSKris Buschelman "MatSeqSBAIJSetPreallocation_SeqSBAIJ", 1791a23d5eceSKris Buschelman MatSeqSBAIJSetPreallocation_SeqSBAIJ);CHKERRQ(ierr); 179223ce1328SBarry Smith 179323ce1328SBarry Smith B->symmetric = PETSC_TRUE; 179423ce1328SBarry Smith B->structurally_symmetric = PETSC_TRUE; 179523ce1328SBarry Smith B->symmetric_set = PETSC_TRUE; 179623ce1328SBarry Smith B->structurally_symmetric_set = PETSC_TRUE; 179717667f90SBarry Smith ierr = PetscObjectChangeTypeName((PetscObject)B,MATSEQSBAIJ);CHKERRQ(ierr); 17980def2e27SBarry Smith 17990def2e27SBarry Smith ierr = PetscOptionsBegin(((PetscObject)B)->comm,((PetscObject)B)->prefix,"Options for SEQSBAIJ matrix","Mat");CHKERRQ(ierr); 18000def2e27SBarry Smith ierr = PetscOptionsTruth("-mat_no_unroll","Do not optimize for inodes (slower)",PETSC_NULL,no_unroll,&no_unroll,PETSC_NULL);CHKERRQ(ierr); 18010def2e27SBarry Smith if (no_unroll) {ierr = PetscInfo(B,"Not using Inode routines due to -mat_no_unroll\n");CHKERRQ(ierr);} 18020def2e27SBarry Smith ierr = PetscOptionsTruth("-mat_no_inode","Do not optimize for inodes (slower)",PETSC_NULL,no_inode,&no_inode,PETSC_NULL);CHKERRQ(ierr); 18030def2e27SBarry Smith if (no_inode) {ierr = PetscInfo(B,"Not using Inode routines due to -mat_no_inode\n");CHKERRQ(ierr);} 18040def2e27SBarry Smith ierr = PetscOptionsInt("-mat_inode_limit","Do not use inodes larger then this value",PETSC_NULL,b->inode.limit,&b->inode.limit,PETSC_NULL);CHKERRQ(ierr); 18050def2e27SBarry Smith ierr = PetscOptionsEnd();CHKERRQ(ierr); 18060def2e27SBarry Smith b->inode.use = (PetscTruth)(!(no_unroll || no_inode)); 18070def2e27SBarry Smith if (b->inode.limit > b->inode.max_limit) b->inode.limit = b->inode.max_limit; 18080def2e27SBarry Smith 1809a23d5eceSKris Buschelman PetscFunctionReturn(0); 1810a23d5eceSKris Buschelman } 1811a23d5eceSKris Buschelman EXTERN_C_END 1812a23d5eceSKris Buschelman 1813a23d5eceSKris Buschelman #undef __FUNCT__ 1814a23d5eceSKris Buschelman #define __FUNCT__ "MatSeqSBAIJSetPreallocation" 1815a23d5eceSKris Buschelman /*@C 1816a23d5eceSKris Buschelman MatSeqSBAIJSetPreallocation - Creates a sparse symmetric matrix in block AIJ (block 1817a23d5eceSKris Buschelman compressed row) format. For good matrix assembly performance the 1818a23d5eceSKris Buschelman user should preallocate the matrix storage by setting the parameter nz 1819a23d5eceSKris Buschelman (or the array nnz). By setting these parameters accurately, performance 1820a23d5eceSKris Buschelman during matrix assembly can be increased by more than a factor of 50. 1821a23d5eceSKris Buschelman 1822a23d5eceSKris Buschelman Collective on Mat 1823a23d5eceSKris Buschelman 1824a23d5eceSKris Buschelman Input Parameters: 1825a23d5eceSKris Buschelman + A - the symmetric matrix 1826a23d5eceSKris Buschelman . bs - size of block 1827a23d5eceSKris Buschelman . nz - number of block nonzeros per block row (same for all rows) 1828a23d5eceSKris Buschelman - nnz - array containing the number of block nonzeros in the upper triangular plus 1829a23d5eceSKris Buschelman diagonal portion of each block (possibly different for each block row) or PETSC_NULL 1830a23d5eceSKris Buschelman 1831a23d5eceSKris Buschelman Options Database Keys: 1832a23d5eceSKris Buschelman . -mat_no_unroll - uses code that does not unroll the loops in the 1833a23d5eceSKris Buschelman block calculations (much slower) 1834db4efbfdSBarry Smith . -mat_block_size - size of the blocks to use (only works if a negative bs is passed in 1835a23d5eceSKris Buschelman 1836a23d5eceSKris Buschelman Level: intermediate 1837a23d5eceSKris Buschelman 1838a23d5eceSKris Buschelman Notes: 1839a23d5eceSKris Buschelman Specify the preallocated storage with either nz or nnz (not both). 1840a23d5eceSKris Buschelman Set nz=PETSC_DEFAULT and nnz=PETSC_NULL for PETSc to control dynamic memory 1841a23d5eceSKris Buschelman allocation. For additional details, see the users manual chapter on 1842a23d5eceSKris Buschelman matrices. 1843a23d5eceSKris Buschelman 1844aa95bbe8SBarry Smith You can call MatGetInfo() to get information on how effective the preallocation was; 1845aa95bbe8SBarry Smith for example the fields mallocs,nz_allocated,nz_used,nz_unneeded; 1846aa95bbe8SBarry Smith You can also run with the option -info and look for messages with the string 1847aa95bbe8SBarry Smith malloc in them to see if additional memory allocation was needed. 1848aa95bbe8SBarry Smith 184949a6f317SBarry Smith If the nnz parameter is given then the nz parameter is ignored 185049a6f317SBarry Smith 185149a6f317SBarry Smith 1852a23d5eceSKris Buschelman .seealso: MatCreate(), MatCreateSeqAIJ(), MatSetValues(), MatCreateMPISBAIJ() 1853a23d5eceSKris Buschelman @*/ 1854be1d678aSKris Buschelman PetscErrorCode PETSCMAT_DLLEXPORT MatSeqSBAIJSetPreallocation(Mat B,PetscInt bs,PetscInt nz,const PetscInt nnz[]) 185513f74950SBarry Smith { 185613f74950SBarry Smith PetscErrorCode ierr,(*f)(Mat,PetscInt,PetscInt,const PetscInt[]); 1857a23d5eceSKris Buschelman 1858a23d5eceSKris Buschelman PetscFunctionBegin; 1859a23d5eceSKris Buschelman ierr = PetscObjectQueryFunction((PetscObject)B,"MatSeqSBAIJSetPreallocation_C",(void (**)(void))&f);CHKERRQ(ierr); 1860a23d5eceSKris Buschelman if (f) { 1861a23d5eceSKris Buschelman ierr = (*f)(B,bs,nz,nnz);CHKERRQ(ierr); 1862a23d5eceSKris Buschelman } 1863a23d5eceSKris Buschelman PetscFunctionReturn(0); 1864a23d5eceSKris Buschelman } 186549b5e25fSSatish Balay 18664a2ae208SSatish Balay #undef __FUNCT__ 18674a2ae208SSatish Balay #define __FUNCT__ "MatCreateSeqSBAIJ" 1868c464158bSHong Zhang /*@C 1869c464158bSHong Zhang MatCreateSeqSBAIJ - Creates a sparse symmetric matrix in block AIJ (block 1870c464158bSHong Zhang compressed row) format. For good matrix assembly performance the 1871c464158bSHong Zhang user should preallocate the matrix storage by setting the parameter nz 1872c464158bSHong Zhang (or the array nnz). By setting these parameters accurately, performance 1873c464158bSHong Zhang during matrix assembly can be increased by more than a factor of 50. 187449b5e25fSSatish Balay 1875c464158bSHong Zhang Collective on MPI_Comm 1876c464158bSHong Zhang 1877c464158bSHong Zhang Input Parameters: 1878c464158bSHong Zhang + comm - MPI communicator, set to PETSC_COMM_SELF 1879c464158bSHong Zhang . bs - size of block 1880c464158bSHong Zhang . m - number of rows, or number of columns 1881c464158bSHong Zhang . nz - number of block nonzeros per block row (same for all rows) 1882744e8345SSatish Balay - nnz - array containing the number of block nonzeros in the upper triangular plus 1883744e8345SSatish Balay diagonal portion of each block (possibly different for each block row) or PETSC_NULL 1884c464158bSHong Zhang 1885c464158bSHong Zhang Output Parameter: 1886c464158bSHong Zhang . A - the symmetric matrix 1887c464158bSHong Zhang 1888c464158bSHong Zhang Options Database Keys: 1889c464158bSHong Zhang . -mat_no_unroll - uses code that does not unroll the loops in the 1890c464158bSHong Zhang block calculations (much slower) 1891c464158bSHong Zhang . -mat_block_size - size of the blocks to use 1892c464158bSHong Zhang 1893c464158bSHong Zhang Level: intermediate 1894c464158bSHong Zhang 1895175b88e8SBarry Smith It is recommended that one use the MatCreate(), MatSetType() and/or MatSetFromOptions(), 1896ae1d86c5SBarry Smith MatXXXXSetPreallocation() paradgm instead of this routine directly. 1897175b88e8SBarry Smith [MatXXXXSetPreallocation() is, for example, MatSeqAIJSetPreallocation] 1898175b88e8SBarry Smith 1899c464158bSHong Zhang Notes: 19006d6d819aSHong Zhang The number of rows and columns must be divisible by blocksize. 19016d6d819aSHong Zhang This matrix type does not support complex Hermitian operation. 1902c464158bSHong Zhang 1903c464158bSHong Zhang Specify the preallocated storage with either nz or nnz (not both). 1904c464158bSHong Zhang Set nz=PETSC_DEFAULT and nnz=PETSC_NULL for PETSc to control dynamic memory 1905c464158bSHong Zhang allocation. For additional details, see the users manual chapter on 1906c464158bSHong Zhang matrices. 1907c464158bSHong Zhang 190849a6f317SBarry Smith If the nnz parameter is given then the nz parameter is ignored 190949a6f317SBarry Smith 1910c464158bSHong Zhang .seealso: MatCreate(), MatCreateSeqAIJ(), MatSetValues(), MatCreateMPISBAIJ() 1911c464158bSHong Zhang @*/ 1912be1d678aSKris Buschelman PetscErrorCode PETSCMAT_DLLEXPORT MatCreateSeqSBAIJ(MPI_Comm comm,PetscInt bs,PetscInt m,PetscInt n,PetscInt nz,const PetscInt nnz[],Mat *A) 1913c464158bSHong Zhang { 1914dfbe8321SBarry Smith PetscErrorCode ierr; 1915c464158bSHong Zhang 1916c464158bSHong Zhang PetscFunctionBegin; 1917f69a0ea3SMatthew Knepley ierr = MatCreate(comm,A);CHKERRQ(ierr); 1918f69a0ea3SMatthew Knepley ierr = MatSetSizes(*A,m,n,m,n);CHKERRQ(ierr); 1919c464158bSHong Zhang ierr = MatSetType(*A,MATSEQSBAIJ);CHKERRQ(ierr); 1920ab93d7beSBarry Smith ierr = MatSeqSBAIJSetPreallocation_SeqSBAIJ(*A,bs,nz,(PetscInt*)nnz);CHKERRQ(ierr); 192149b5e25fSSatish Balay PetscFunctionReturn(0); 192249b5e25fSSatish Balay } 192349b5e25fSSatish Balay 19244a2ae208SSatish Balay #undef __FUNCT__ 19254a2ae208SSatish Balay #define __FUNCT__ "MatDuplicate_SeqSBAIJ" 1926dfbe8321SBarry Smith PetscErrorCode MatDuplicate_SeqSBAIJ(Mat A,MatDuplicateOption cpvalues,Mat *B) 192749b5e25fSSatish Balay { 192849b5e25fSSatish Balay Mat C; 192949b5e25fSSatish Balay Mat_SeqSBAIJ *c,*a = (Mat_SeqSBAIJ*)A->data; 19306849ba73SBarry Smith PetscErrorCode ierr; 1931b40805acSSatish Balay PetscInt i,mbs = a->mbs,nz = a->nz,bs2 =a->bs2; 193249b5e25fSSatish Balay 193349b5e25fSSatish Balay PetscFunctionBegin; 193429bbc08cSBarry Smith if (a->i[mbs] != nz) SETERRQ(PETSC_ERR_PLIB,"Corrupt matrix"); 193549b5e25fSSatish Balay 193649b5e25fSSatish Balay *B = 0; 19377adad957SLisandro Dalcin ierr = MatCreate(((PetscObject)A)->comm,&C);CHKERRQ(ierr); 1938d0f46423SBarry Smith ierr = MatSetSizes(C,A->rmap->N,A->cmap->n,A->rmap->N,A->cmap->n);CHKERRQ(ierr); 19397adad957SLisandro Dalcin ierr = MatSetType(C,((PetscObject)A)->type_name);CHKERRQ(ierr); 19401d5dac46SHong Zhang ierr = PetscMemcpy(C->ops,A->ops,sizeof(struct _MatOps));CHKERRQ(ierr); 1941692f9cbeSHong Zhang c = (Mat_SeqSBAIJ*)C->data; 1942692f9cbeSHong Zhang 1943273d9f13SBarry Smith C->preallocated = PETSC_TRUE; 194449b5e25fSSatish Balay C->factor = A->factor; 194549b5e25fSSatish Balay c->row = 0; 194649b5e25fSSatish Balay c->icol = 0; 194749b5e25fSSatish Balay c->saved_values = 0; 1948a9817697SBarry Smith c->keepnonzeropattern = a->keepnonzeropattern; 194949b5e25fSSatish Balay C->assembled = PETSC_TRUE; 195049b5e25fSSatish Balay 1951d0f46423SBarry Smith ierr = PetscMapCopy(((PetscObject)A)->comm,A->rmap,C->rmap);CHKERRQ(ierr); 1952d0f46423SBarry Smith ierr = PetscMapCopy(((PetscObject)A)->comm,A->cmap,C->cmap);CHKERRQ(ierr); 195349b5e25fSSatish Balay c->bs2 = a->bs2; 195449b5e25fSSatish Balay c->mbs = a->mbs; 195549b5e25fSSatish Balay c->nbs = a->nbs; 195649b5e25fSSatish Balay 19578777fc3fSSatish Balay ierr = PetscMalloc2((mbs+1),PetscInt,&c->imax,(mbs+1),PetscInt,&c->ilen);CHKERRQ(ierr); 195849b5e25fSSatish Balay for (i=0; i<mbs; i++) { 195949b5e25fSSatish Balay c->imax[i] = a->imax[i]; 196049b5e25fSSatish Balay c->ilen[i] = a->ilen[i]; 196149b5e25fSSatish Balay } 196249b5e25fSSatish Balay 196349b5e25fSSatish Balay /* allocate the matrix space */ 1964b40805acSSatish Balay ierr = PetscMalloc3(bs2*nz,MatScalar,&c->a,nz,PetscInt,&c->j,mbs+1,PetscInt,&c->i);CHKERRQ(ierr); 196549b5e25fSSatish Balay c->singlemalloc = PETSC_TRUE; 196613f74950SBarry Smith ierr = PetscMemcpy(c->i,a->i,(mbs+1)*sizeof(PetscInt));CHKERRQ(ierr); 1967b40805acSSatish Balay ierr = PetscLogObjectMemory(C,(mbs+1)*sizeof(PetscInt) + nz*(bs2*sizeof(MatScalar) + sizeof(PetscInt)));CHKERRQ(ierr); 196849b5e25fSSatish Balay if (mbs > 0) { 196913f74950SBarry Smith ierr = PetscMemcpy(c->j,a->j,nz*sizeof(PetscInt));CHKERRQ(ierr); 197049b5e25fSSatish Balay if (cpvalues == MAT_COPY_VALUES) { 197149b5e25fSSatish Balay ierr = PetscMemcpy(c->a,a->a,bs2*nz*sizeof(MatScalar));CHKERRQ(ierr); 197249b5e25fSSatish Balay } else { 197349b5e25fSSatish Balay ierr = PetscMemzero(c->a,bs2*nz*sizeof(MatScalar));CHKERRQ(ierr); 197449b5e25fSSatish Balay } 197549b5e25fSSatish Balay } 197649b5e25fSSatish Balay 197749b5e25fSSatish Balay c->roworiented = a->roworiented; 197849b5e25fSSatish Balay c->nonew = a->nonew; 197949b5e25fSSatish Balay 198049b5e25fSSatish Balay if (a->diag) { 198113f74950SBarry Smith ierr = PetscMalloc((mbs+1)*sizeof(PetscInt),&c->diag);CHKERRQ(ierr); 198252e6d16bSBarry Smith ierr = PetscLogObjectMemory(C,(mbs+1)*sizeof(PetscInt));CHKERRQ(ierr); 198349b5e25fSSatish Balay for (i=0; i<mbs; i++) { 198449b5e25fSSatish Balay c->diag[i] = a->diag[i]; 198549b5e25fSSatish Balay } 198649b5e25fSSatish Balay } else c->diag = 0; 19876c6c5352SBarry Smith c->nz = a->nz; 19886c6c5352SBarry Smith c->maxnz = a->maxnz; 198949b5e25fSSatish Balay c->solve_work = 0; 199049b5e25fSSatish Balay c->mult_work = 0; 1991e6b907acSBarry Smith c->free_a = PETSC_TRUE; 1992e6b907acSBarry Smith c->free_ij = PETSC_TRUE; 199349b5e25fSSatish Balay *B = C; 19947adad957SLisandro Dalcin ierr = PetscFListDuplicate(((PetscObject)A)->qlist,&((PetscObject)C)->qlist);CHKERRQ(ierr); 199549b5e25fSSatish Balay PetscFunctionReturn(0); 199649b5e25fSSatish Balay } 199749b5e25fSSatish Balay 19984a2ae208SSatish Balay #undef __FUNCT__ 19994a2ae208SSatish Balay #define __FUNCT__ "MatLoad_SeqSBAIJ" 2000a313700dSBarry Smith PetscErrorCode MatLoad_SeqSBAIJ(PetscViewer viewer, const MatType type,Mat *A) 200149b5e25fSSatish Balay { 200249b5e25fSSatish Balay Mat_SeqSBAIJ *a; 200349b5e25fSSatish Balay Mat B; 20046849ba73SBarry Smith PetscErrorCode ierr; 200513f74950SBarry Smith int fd; 200613f74950SBarry Smith PetscMPIInt size; 200713f74950SBarry Smith PetscInt i,nz,header[4],*rowlengths=0,M,N,bs=1; 200813f74950SBarry Smith PetscInt *mask,mbs,*jj,j,rowcount,nzcount,k,*s_browlengths,maskcount; 200913f74950SBarry Smith PetscInt kmax,jcount,block,idx,point,nzcountb,extra_rows; 201013f74950SBarry Smith PetscInt *masked,nmask,tmp,bs2,ishift; 201187828ca2SBarry Smith PetscScalar *aa; 201249b5e25fSSatish Balay MPI_Comm comm = ((PetscObject)viewer)->comm; 201349b5e25fSSatish Balay 201449b5e25fSSatish Balay PetscFunctionBegin; 2015b0a32e0cSBarry Smith ierr = PetscOptionsGetInt(PETSC_NULL,"-matload_block_size",&bs,PETSC_NULL);CHKERRQ(ierr); 201649b5e25fSSatish Balay bs2 = bs*bs; 201749b5e25fSSatish Balay 201849b5e25fSSatish Balay ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); 201929bbc08cSBarry Smith if (size > 1) SETERRQ(PETSC_ERR_ARG_WRONG,"view must have one processor"); 2020b0a32e0cSBarry Smith ierr = PetscViewerBinaryGetDescriptor(viewer,&fd);CHKERRQ(ierr); 202149b5e25fSSatish Balay ierr = PetscBinaryRead(fd,header,4,PETSC_INT);CHKERRQ(ierr); 2022552e946dSBarry Smith if (header[0] != MAT_FILE_COOKIE) SETERRQ(PETSC_ERR_FILE_UNEXPECTED,"not Mat object"); 202349b5e25fSSatish Balay M = header[1]; N = header[2]; nz = header[3]; 202449b5e25fSSatish Balay 202549b5e25fSSatish Balay if (header[3] < 0) { 202629bbc08cSBarry Smith SETERRQ(PETSC_ERR_FILE_UNEXPECTED,"Matrix stored in special format, cannot load as SeqSBAIJ"); 202749b5e25fSSatish Balay } 202849b5e25fSSatish Balay 202929bbc08cSBarry Smith if (M != N) SETERRQ(PETSC_ERR_SUP,"Can only do square matrices"); 203049b5e25fSSatish Balay 203149b5e25fSSatish Balay /* 203249b5e25fSSatish Balay This code adds extra rows to make sure the number of rows is 203349b5e25fSSatish Balay divisible by the blocksize 203449b5e25fSSatish Balay */ 203549b5e25fSSatish Balay mbs = M/bs; 203649b5e25fSSatish Balay extra_rows = bs - M + bs*(mbs); 203749b5e25fSSatish Balay if (extra_rows == bs) extra_rows = 0; 203849b5e25fSSatish Balay else mbs++; 203949b5e25fSSatish Balay if (extra_rows) { 20401e2582c4SBarry Smith ierr = PetscInfo(viewer,"Padding loaded matrix to match blocksize\n");CHKERRQ(ierr); 204149b5e25fSSatish Balay } 204249b5e25fSSatish Balay 204349b5e25fSSatish Balay /* read in row lengths */ 204413f74950SBarry Smith ierr = PetscMalloc((M+extra_rows)*sizeof(PetscInt),&rowlengths);CHKERRQ(ierr); 204549b5e25fSSatish Balay ierr = PetscBinaryRead(fd,rowlengths,M,PETSC_INT);CHKERRQ(ierr); 204649b5e25fSSatish Balay for (i=0; i<extra_rows; i++) rowlengths[M+i] = 1; 204749b5e25fSSatish Balay 204849b5e25fSSatish Balay /* read in column indices */ 204913f74950SBarry Smith ierr = PetscMalloc((nz+extra_rows)*sizeof(PetscInt),&jj);CHKERRQ(ierr); 205049b5e25fSSatish Balay ierr = PetscBinaryRead(fd,jj,nz,PETSC_INT);CHKERRQ(ierr); 205149b5e25fSSatish Balay for (i=0; i<extra_rows; i++) jj[nz+i] = M+i; 205249b5e25fSSatish Balay 205349b5e25fSSatish Balay /* loop over row lengths determining block row lengths */ 205413f74950SBarry Smith ierr = PetscMalloc(mbs*sizeof(PetscInt),&s_browlengths);CHKERRQ(ierr); 205513f74950SBarry Smith ierr = PetscMemzero(s_browlengths,mbs*sizeof(PetscInt));CHKERRQ(ierr); 205613f74950SBarry Smith ierr = PetscMalloc(2*mbs*sizeof(PetscInt),&mask);CHKERRQ(ierr); 205713f74950SBarry Smith ierr = PetscMemzero(mask,mbs*sizeof(PetscInt));CHKERRQ(ierr); 205849b5e25fSSatish Balay masked = mask + mbs; 205949b5e25fSSatish Balay rowcount = 0; nzcount = 0; 206049b5e25fSSatish Balay for (i=0; i<mbs; i++) { 206149b5e25fSSatish Balay nmask = 0; 206249b5e25fSSatish Balay for (j=0; j<bs; j++) { 206349b5e25fSSatish Balay kmax = rowlengths[rowcount]; 206449b5e25fSSatish Balay for (k=0; k<kmax; k++) { 20652d703238SHong Zhang tmp = jj[nzcount++]/bs; /* block col. index */ 206603630b6eSHong Zhang if (!mask[tmp] && tmp >= i) {masked[nmask++] = tmp; mask[tmp] = 1;} 206749b5e25fSSatish Balay } 206849b5e25fSSatish Balay rowcount++; 206949b5e25fSSatish Balay } 2070574b2666SHong Zhang s_browlengths[i] += nmask; 2071574b2666SHong Zhang 207249b5e25fSSatish Balay /* zero out the mask elements we set */ 207349b5e25fSSatish Balay for (j=0; j<nmask; j++) mask[masked[j]] = 0; 207449b5e25fSSatish Balay } 207549b5e25fSSatish Balay 207649b5e25fSSatish Balay /* create our matrix */ 2077f69a0ea3SMatthew Knepley ierr = MatCreate(comm,&B);CHKERRQ(ierr); 2078f69a0ea3SMatthew Knepley ierr = MatSetSizes(B,M+extra_rows,N+extra_rows,M+extra_rows,N+extra_rows);CHKERRQ(ierr); 20799abb65ffSKris Buschelman ierr = MatSetType(B,type);CHKERRQ(ierr); 2080ab93d7beSBarry Smith ierr = MatSeqSBAIJSetPreallocation_SeqSBAIJ(B,bs,0,s_browlengths);CHKERRQ(ierr); 208149b5e25fSSatish Balay a = (Mat_SeqSBAIJ*)B->data; 208249b5e25fSSatish Balay 208349b5e25fSSatish Balay /* set matrix "i" values */ 208449b5e25fSSatish Balay a->i[0] = 0; 208549b5e25fSSatish Balay for (i=1; i<= mbs; i++) { 2086574b2666SHong Zhang a->i[i] = a->i[i-1] + s_browlengths[i-1]; 2087574b2666SHong Zhang a->ilen[i-1] = s_browlengths[i-1]; 208849b5e25fSSatish Balay } 20896c6c5352SBarry Smith a->nz = a->i[mbs]; 209049b5e25fSSatish Balay 209149b5e25fSSatish Balay /* read in nonzero values */ 209287828ca2SBarry Smith ierr = PetscMalloc((nz+extra_rows)*sizeof(PetscScalar),&aa);CHKERRQ(ierr); 209349b5e25fSSatish Balay ierr = PetscBinaryRead(fd,aa,nz,PETSC_SCALAR);CHKERRQ(ierr); 209449b5e25fSSatish Balay for (i=0; i<extra_rows; i++) aa[nz+i] = 1.0; 209549b5e25fSSatish Balay 209649b5e25fSSatish Balay /* set "a" and "j" values into matrix */ 209749b5e25fSSatish Balay nzcount = 0; jcount = 0; 209849b5e25fSSatish Balay for (i=0; i<mbs; i++) { 209949b5e25fSSatish Balay nzcountb = nzcount; 210049b5e25fSSatish Balay nmask = 0; 210149b5e25fSSatish Balay for (j=0; j<bs; j++) { 210249b5e25fSSatish Balay kmax = rowlengths[i*bs+j]; 210349b5e25fSSatish Balay for (k=0; k<kmax; k++) { 21042d703238SHong Zhang tmp = jj[nzcount++]/bs; /* block col. index */ 210503630b6eSHong Zhang if (!mask[tmp] && tmp >= i) { masked[nmask++] = tmp; mask[tmp] = 1;} 21062d703238SHong Zhang } 21072d703238SHong Zhang } 21082d703238SHong Zhang /* sort the masked values */ 21092d703238SHong Zhang ierr = PetscSortInt(nmask,masked);CHKERRQ(ierr); 21102d703238SHong Zhang 21112d703238SHong Zhang /* set "j" values into matrix */ 21122d703238SHong Zhang maskcount = 1; 21132d703238SHong Zhang for (j=0; j<nmask; j++) { 211449b5e25fSSatish Balay a->j[jcount++] = masked[j]; 211549b5e25fSSatish Balay mask[masked[j]] = maskcount++; 211649b5e25fSSatish Balay } 2117574b2666SHong Zhang 211849b5e25fSSatish Balay /* set "a" values into matrix */ 211949b5e25fSSatish Balay ishift = bs2*a->i[i]; 212049b5e25fSSatish Balay for (j=0; j<bs; j++) { 212149b5e25fSSatish Balay kmax = rowlengths[i*bs+j]; 212249b5e25fSSatish Balay for (k=0; k<kmax; k++) { 2123574b2666SHong Zhang tmp = jj[nzcountb]/bs ; /* block col. index */ 2124574b2666SHong Zhang if (tmp >= i){ 212549b5e25fSSatish Balay block = mask[tmp] - 1; 212649b5e25fSSatish Balay point = jj[nzcountb] - bs*tmp; 212749b5e25fSSatish Balay idx = ishift + bs2*block + j + bs*point; 2128574b2666SHong Zhang a->a[idx] = aa[nzcountb]; 2129574b2666SHong Zhang } 2130574b2666SHong Zhang nzcountb++; 213149b5e25fSSatish Balay } 213249b5e25fSSatish Balay } 213349b5e25fSSatish Balay /* zero out the mask elements we set */ 213449b5e25fSSatish Balay for (j=0; j<nmask; j++) mask[masked[j]] = 0; 213549b5e25fSSatish Balay } 21366c6c5352SBarry Smith if (jcount != a->nz) SETERRQ(PETSC_ERR_FILE_UNEXPECTED,"Bad binary matrix"); 213749b5e25fSSatish Balay 213849b5e25fSSatish Balay ierr = PetscFree(rowlengths);CHKERRQ(ierr); 2139574b2666SHong Zhang ierr = PetscFree(s_browlengths);CHKERRQ(ierr); 214049b5e25fSSatish Balay ierr = PetscFree(aa);CHKERRQ(ierr); 214149b5e25fSSatish Balay ierr = PetscFree(jj);CHKERRQ(ierr); 214249b5e25fSSatish Balay ierr = PetscFree(mask);CHKERRQ(ierr); 214349b5e25fSSatish Balay 21449abb65ffSKris Buschelman ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 21459abb65ffSKris Buschelman ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 214649b5e25fSSatish Balay ierr = MatView_Private(B);CHKERRQ(ierr); 21479abb65ffSKris Buschelman *A = B; 214849b5e25fSSatish Balay PetscFunctionReturn(0); 214949b5e25fSSatish Balay } 2150574b2666SHong Zhang 21510def2e27SBarry Smith 21520def2e27SBarry Smith 2153d06b337dSHong Zhang #undef __FUNCT__ 2154d06b337dSHong Zhang #define __FUNCT__ "MatRelax_SeqSBAIJ" 215513f74950SBarry Smith PetscErrorCode MatRelax_SeqSBAIJ(Mat A,Vec bb,PetscReal omega,MatSORType flag,PetscReal fshift,PetscInt its,PetscInt lits,Vec xx) 2156d06b337dSHong Zhang { 2157d06b337dSHong Zhang Mat_SeqSBAIJ *a = (Mat_SeqSBAIJ*)A->data; 21589e2a9236SBarry Smith const MatScalar *aa=a->a,*v,*v1,*aidiag; 21599e2a9236SBarry Smith PetscScalar *x,*b,*t,sum; 2160061b2667SBarry Smith MatScalar tmp; 21616849ba73SBarry Smith PetscErrorCode ierr; 2162061b2667SBarry Smith PetscInt m=a->mbs,bs=A->rmap->bs,j; 2163061b2667SBarry Smith const PetscInt *ai=a->i,*aj=a->j,*vj,*vj1; 2164061b2667SBarry Smith PetscInt nz,nz1,i; 2165d06b337dSHong Zhang 2166d06b337dSHong Zhang PetscFunctionBegin; 216751f519a2SBarry Smith if (flag & SOR_EISENSTAT) SETERRQ(PETSC_ERR_SUP,"No support yet for Eisenstat"); 216851f519a2SBarry Smith 2169b965ef7fSBarry Smith its = its*lits; 217077431f27SBarry Smith if (its <= 0) SETERRQ2(PETSC_ERR_ARG_WRONG,"Relaxation requires global its %D and local its %D both positive",its,lits); 2171d06b337dSHong Zhang 2172061b2667SBarry Smith if (bs > 1) SETERRQ(PETSC_ERR_SUP,"SSOR for block size > 1 is not yet implemented"); 2173d06b337dSHong Zhang 21741ebc52fbSHong Zhang ierr = VecGetArray(xx,&x);CHKERRQ(ierr); 2175d06b337dSHong Zhang if (xx != bb) { 21761ebc52fbSHong Zhang ierr = VecGetArray(bb,&b);CHKERRQ(ierr); 2177d06b337dSHong Zhang } else { 2178d06b337dSHong Zhang b = x; 2179d06b337dSHong Zhang } 2180d06b337dSHong Zhang 2181061b2667SBarry Smith if (!a->idiagvalid) { 2182061b2667SBarry Smith if (!a->idiag) { 2183061b2667SBarry Smith ierr = PetscMalloc(m*sizeof(PetscScalar),&a->idiag);CHKERRQ(ierr); 2184061b2667SBarry Smith } 2185061b2667SBarry Smith for (i=0; i<a->mbs; i++) a->idiag[i] = 1.0/a->a[a->i[i]]; 2186061b2667SBarry Smith a->idiagvalid = PETSC_TRUE; 2187061b2667SBarry Smith } 2188061b2667SBarry Smith 2189e2ee2a47SBarry Smith if (!a->relax_work) { 2190e2ee2a47SBarry Smith ierr = PetscMalloc(m*sizeof(PetscScalar),&a->relax_work);CHKERRQ(ierr); 2191e2ee2a47SBarry Smith } 2192e2ee2a47SBarry Smith t = a->relax_work; 2193d06b337dSHong Zhang 21949e2a9236SBarry Smith aidiag = a->idiag; 2195d06b337dSHong Zhang if (flag & SOR_ZERO_INITIAL_GUESS) { 21962798e883SHong Zhang if (flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP){ 2197290bbb0aSBarry Smith ierr = PetscMemcpy(t,b,m*sizeof(PetscScalar));CHKERRQ(ierr); 2198d06b337dSHong Zhang 21999e2a9236SBarry Smith v = aa + 1; 22009e2a9236SBarry Smith vj = aj + 1; 2201d06b337dSHong Zhang for (i=0; i<m; i++){ 2202d06b337dSHong Zhang nz = ai[i+1] - ai[i] - 1; 22039e2a9236SBarry Smith tmp = - (x[i] = omega*t[i]*aidiag[i]); 2204061b2667SBarry Smith for (j=0; j<nz; j++) { 22059e2a9236SBarry Smith t[vj[j]] += tmp*v[j]; 2206d06b337dSHong Zhang } 22079e2a9236SBarry Smith v += nz + 1; 22089e2a9236SBarry Smith vj += nz + 1; 2209d06b337dSHong Zhang } 2210061b2667SBarry Smith ierr = PetscLogFlops(2*a->nz);CHKERRQ(ierr); 2211061b2667SBarry Smith } 2212d06b337dSHong Zhang 22132798e883SHong Zhang if (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP){ 2214*b2843cf1SBarry Smith int nz2; 221595d750ceSBarry Smith if (!(flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP)){ 221695d750ceSBarry Smith t = b; 2217d06b337dSHong Zhang } 221895d750ceSBarry Smith 2219a2d7c930SBarry Smith v = aa + ai[m-1] + 1; 2220a2d7c930SBarry Smith vj = aj + ai[m-1] + 1; 2221a2d7c930SBarry Smith nz = 0; 2222d06b337dSHong Zhang for (i=m-1; i>=0; i--){ 22239e2a9236SBarry Smith sum = 0.0; 2224*b2843cf1SBarry Smith nz2 = ai[i] - ai[i-1] - 1; 2225*b2843cf1SBarry Smith PETSC_Prefetch(v-nz2-1,0,1); 2226*b2843cf1SBarry Smith PETSC_Prefetch(vj-nz2-1,0,1); 22279e2a9236SBarry Smith PetscSparseDensePlusDot(sum,x,v,vj,nz); 22289e2a9236SBarry Smith sum = t[i] - sum; 22299e2a9236SBarry Smith x[i] = (1-omega)*x[i] + omega*sum*aidiag[i]; 2230*b2843cf1SBarry Smith nz = nz2; 22319e2a9236SBarry Smith v -= nz + 1; 22329e2a9236SBarry Smith vj -= nz + 1; 2233d06b337dSHong Zhang } 223495d750ceSBarry Smith t = a->relax_work; 2235061b2667SBarry Smith ierr = PetscLogFlops(2*a->nz);CHKERRQ(ierr); 2236d06b337dSHong Zhang } 2237d06b337dSHong Zhang its--; 2238d06b337dSHong Zhang } 2239d06b337dSHong Zhang 2240d06b337dSHong Zhang while (its--) { 224144706875SHong Zhang /* 224244706875SHong Zhang forward sweep: 224344706875SHong Zhang for i=0,...,m-1: 224444706875SHong Zhang sum[i] = (b[i] - U(i,:)x )/d[i]; 224544706875SHong Zhang x[i] = (1-omega)x[i] + omega*sum[i]; 224644706875SHong Zhang b = b - x[i]*U^T(i,:); 2247d06b337dSHong Zhang 224844706875SHong Zhang */ 22492798e883SHong Zhang if (flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP){ 2250290bbb0aSBarry Smith ierr = PetscMemcpy(t,b,m*sizeof(PetscScalar));CHKERRQ(ierr); 2251d06b337dSHong Zhang 2252d06b337dSHong Zhang for (i=0; i<m; i++){ 2253d06b337dSHong Zhang v = aa + ai[i] + 1; v1=v; 2254d06b337dSHong Zhang vj = aj + ai[i] + 1; vj1=vj; 2255d06b337dSHong Zhang nz = ai[i+1] - ai[i] - 1; nz1=nz; 2256d06b337dSHong Zhang sum = t[i]; 2257dc0b31edSSatish Balay ierr = PetscLogFlops(4.0*nz-2);CHKERRQ(ierr); 2258d06b337dSHong Zhang while (nz1--) sum -= (*v1++)*x[*vj1++]; 22599e2a9236SBarry Smith x[i] = (1-omega)*x[i] + omega*sum*aidiag[i]; 2260d06b337dSHong Zhang while (nz--) t[*vj++] -= x[i]*(*v++); 2261d06b337dSHong Zhang } 2262d06b337dSHong Zhang } 2263d06b337dSHong Zhang 22642798e883SHong Zhang if (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP){ 226544706875SHong Zhang /* 226644706875SHong Zhang backward sweep: 226744706875SHong Zhang b = b - x[i]*U^T(i,:), i=0,...,n-2 226844706875SHong Zhang for i=m-1,...,0: 226944706875SHong Zhang sum[i] = (b[i] - U(i,:)x )/d[i]; 227044706875SHong Zhang x[i] = (1-omega)x[i] + omega*sum[i]; 227144706875SHong Zhang */ 227295d750ceSBarry Smith /* if there was a forward sweep done above then I thing the next two for loops are not needed */ 2273290bbb0aSBarry Smith ierr = PetscMemcpy(t,b,m*sizeof(PetscScalar));CHKERRQ(ierr); 2274d06b337dSHong Zhang 2275d06b337dSHong Zhang for (i=0; i<m-1; i++){ /* update rhs */ 2276d06b337dSHong Zhang v = aa + ai[i] + 1; 2277d06b337dSHong Zhang vj = aj + ai[i] + 1; 2278d06b337dSHong Zhang nz = ai[i+1] - ai[i] - 1; 2279dc0b31edSSatish Balay ierr = PetscLogFlops(2.0*nz-1);CHKERRQ(ierr); 2280e6b907acSBarry Smith while (nz--) t[*vj++] -= x[i]*(*v++); 2281d06b337dSHong Zhang } 2282d06b337dSHong Zhang for (i=m-1; i>=0; i--){ 2283d06b337dSHong Zhang v = aa + ai[i] + 1; 2284d06b337dSHong Zhang vj = aj + ai[i] + 1; 2285d06b337dSHong Zhang nz = ai[i+1] - ai[i] - 1; 2286dc0b31edSSatish Balay ierr = PetscLogFlops(2.0*nz-1);CHKERRQ(ierr); 2287d06b337dSHong Zhang sum = t[i]; 2288d06b337dSHong Zhang while (nz--) sum -= x[*vj++]*(*v++); 22899e2a9236SBarry Smith x[i] = (1-omega)*x[i] + omega*sum*aidiag[i]; 2290d06b337dSHong Zhang } 2291d06b337dSHong Zhang } 2292d06b337dSHong Zhang } 2293d06b337dSHong Zhang 22941ebc52fbSHong Zhang ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr); 2295d06b337dSHong Zhang if (bb != xx) { 22961ebc52fbSHong Zhang ierr = VecRestoreArray(bb,&b);CHKERRQ(ierr); 2297d06b337dSHong Zhang } 2298d06b337dSHong Zhang PetscFunctionReturn(0); 2299d06b337dSHong Zhang } 2300d06b337dSHong Zhang 2301c75a6043SHong Zhang #undef __FUNCT__ 2302c75a6043SHong Zhang #define __FUNCT__ "MatCreateSeqSBAIJWithArrays" 2303c75a6043SHong Zhang /*@ 2304c75a6043SHong Zhang MatCreateSeqSBAIJWithArrays - Creates an sequential SBAIJ matrix using matrix elements 2305c75a6043SHong Zhang (upper triangular entries in CSR format) provided by the user. 2306c75a6043SHong Zhang 2307c75a6043SHong Zhang Collective on MPI_Comm 2308c75a6043SHong Zhang 2309c75a6043SHong Zhang Input Parameters: 2310c75a6043SHong Zhang + comm - must be an MPI communicator of size 1 2311c75a6043SHong Zhang . bs - size of block 2312c75a6043SHong Zhang . m - number of rows 2313c75a6043SHong Zhang . n - number of columns 2314c75a6043SHong Zhang . i - row indices 2315c75a6043SHong Zhang . j - column indices 2316c75a6043SHong Zhang - a - matrix values 2317c75a6043SHong Zhang 2318c75a6043SHong Zhang Output Parameter: 2319c75a6043SHong Zhang . mat - the matrix 2320c75a6043SHong Zhang 2321c75a6043SHong Zhang Level: intermediate 2322c75a6043SHong Zhang 2323c75a6043SHong Zhang Notes: 2324c75a6043SHong Zhang The i, j, and a arrays are not copied by this routine, the user must free these arrays 2325c75a6043SHong Zhang once the matrix is destroyed 2326c75a6043SHong Zhang 2327c75a6043SHong Zhang You cannot set new nonzero locations into this matrix, that will generate an error. 2328c75a6043SHong Zhang 2329c75a6043SHong Zhang The i and j indices are 0 based 2330c75a6043SHong Zhang 2331c75a6043SHong Zhang .seealso: MatCreate(), MatCreateMPISBAIJ(), MatCreateSeqSBAIJ() 2332c75a6043SHong Zhang 2333c75a6043SHong Zhang @*/ 2334c75a6043SHong Zhang PetscErrorCode PETSCMAT_DLLEXPORT MatCreateSeqSBAIJWithArrays(MPI_Comm comm,PetscInt bs,PetscInt m,PetscInt n,PetscInt* i,PetscInt*j,PetscScalar *a,Mat *mat) 2335c75a6043SHong Zhang { 2336c75a6043SHong Zhang PetscErrorCode ierr; 2337c75a6043SHong Zhang PetscInt ii; 2338c75a6043SHong Zhang Mat_SeqSBAIJ *sbaij; 2339c75a6043SHong Zhang 2340c75a6043SHong Zhang PetscFunctionBegin; 2341c75a6043SHong Zhang if (bs != 1) SETERRQ1(PETSC_ERR_SUP,"block size %D > 1 is not supported yet",bs); 2342c75a6043SHong Zhang if (i[0]) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"i (row indices) must start with 0"); 2343c75a6043SHong Zhang 2344c75a6043SHong Zhang ierr = MatCreate(comm,mat);CHKERRQ(ierr); 2345c75a6043SHong Zhang ierr = MatSetSizes(*mat,m,n,m,n);CHKERRQ(ierr); 2346c75a6043SHong Zhang ierr = MatSetType(*mat,MATSEQSBAIJ);CHKERRQ(ierr); 2347c75a6043SHong Zhang ierr = MatSeqSBAIJSetPreallocation_SeqSBAIJ(*mat,bs,MAT_SKIP_ALLOCATION,0);CHKERRQ(ierr); 2348c75a6043SHong Zhang sbaij = (Mat_SeqSBAIJ*)(*mat)->data; 2349c75a6043SHong Zhang ierr = PetscMalloc2(m,PetscInt,&sbaij->imax,m,PetscInt,&sbaij->ilen);CHKERRQ(ierr); 2350c75a6043SHong Zhang 2351c75a6043SHong Zhang sbaij->i = i; 2352c75a6043SHong Zhang sbaij->j = j; 2353c75a6043SHong Zhang sbaij->a = a; 2354c75a6043SHong Zhang sbaij->singlemalloc = PETSC_FALSE; 2355c75a6043SHong Zhang sbaij->nonew = -1; /*this indicates that inserting a new value in the matrix that generates a new nonzero is an error*/ 2356e6b907acSBarry Smith sbaij->free_a = PETSC_FALSE; 2357e6b907acSBarry Smith sbaij->free_ij = PETSC_FALSE; 2358c75a6043SHong Zhang 2359c75a6043SHong Zhang for (ii=0; ii<m; ii++) { 2360c75a6043SHong Zhang sbaij->ilen[ii] = sbaij->imax[ii] = i[ii+1] - i[ii]; 2361c75a6043SHong Zhang #if defined(PETSC_USE_DEBUG) 2362c75a6043SHong 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]); 2363c75a6043SHong Zhang #endif 2364c75a6043SHong Zhang } 2365c75a6043SHong Zhang #if defined(PETSC_USE_DEBUG) 2366c75a6043SHong Zhang for (ii=0; ii<sbaij->i[m]; ii++) { 2367c75a6043SHong Zhang if (j[ii] < 0) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"Negative column index at location = %d index = %d",ii,j[ii]); 2368c75a6043SHong Zhang if (j[ii] > n - 1) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"Column index to large at location = %d index = %d",ii,j[ii]); 2369c75a6043SHong Zhang } 2370c75a6043SHong Zhang #endif 2371c75a6043SHong Zhang 2372c75a6043SHong Zhang ierr = MatAssemblyBegin(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2373c75a6043SHong Zhang ierr = MatAssemblyEnd(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2374c75a6043SHong Zhang PetscFunctionReturn(0); 2375c75a6043SHong Zhang } 2376d06b337dSHong Zhang 2377d06b337dSHong Zhang 2378d06b337dSHong Zhang 237949b5e25fSSatish Balay 238049b5e25fSSatish Balay 2381