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