xref: /petsc/src/mat/impls/baij/seq/baij.c (revision 54138f6b3f52447056571583551f7dcee5898a63)
1*54138f6bSKris Buschelman /*$Id: baij.c,v 1.235 2001/07/12 01:48:59 buschelm Exp buschelm $*/
22593348eSBarry Smith 
32593348eSBarry Smith /*
4b6490206SBarry Smith     Defines the basic matrix operations for the BAIJ (compressed row)
52593348eSBarry Smith   matrix storage format.
62593348eSBarry Smith */
7a2ccead7SSatish Balay #include "petscsys.h"                     /*I "petscmat.h" I*/
870f55243SBarry Smith #include "src/mat/impls/baij/seq/baij.h"
91a6a6d98SBarry Smith #include "src/vec/vecimpl.h"
101a6a6d98SBarry Smith #include "src/inline/spops.h"
113b547af2SSatish Balay 
1295d5f7c2SBarry Smith /*  UGLY, ugly, ugly
1395d5f7c2SBarry Smith    When MatScalar == Scalar the function MatSetValuesBlocked_SeqBAIJ_MatScalar() does
143477af42SKris Buschelman    not exist. Otherwise ..._MatScalar() takes matrix dlements in single precision and
1595d5f7c2SBarry Smith    inserts them into the single precision data structure. The function MatSetValuesBlocked_SeqBAIJ()
1695d5f7c2SBarry Smith    converts the entries into single precision and then calls ..._MatScalar() to put them
1795d5f7c2SBarry Smith    into the single precision data structures.
1895d5f7c2SBarry Smith */
1995d5f7c2SBarry Smith #if defined(PETSC_USE_MAT_SINGLE)
20ca44d042SBarry Smith EXTERN int MatSetValuesBlocked_SeqBAIJ_MatScalar(Mat,int,int*,int,int*,MatScalar*,InsertMode);
2195d5f7c2SBarry Smith #else
2295d5f7c2SBarry Smith #define MatSetValuesBlocked_SeqBAIJ_MatScalar MatSetValuesBlocked_SeqBAIJ
2395d5f7c2SBarry Smith #endif
2495d5f7c2SBarry Smith 
252d61bbb3SSatish Balay #define CHUNKSIZE  10
26de6a44a3SBarry Smith 
27be5855fcSBarry Smith /*
28be5855fcSBarry Smith      Checks for missing diagonals
29be5855fcSBarry Smith */
304a2ae208SSatish Balay #undef __FUNCT__
314a2ae208SSatish Balay #define __FUNCT__ "MatMissingDiagonal_SeqBAIJ"
32c4992f7dSBarry Smith int MatMissingDiagonal_SeqBAIJ(Mat A)
33be5855fcSBarry Smith {
34be5855fcSBarry Smith   Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)A->data;
35883fce79SBarry Smith   int         *diag,*jj = a->j,i,ierr;
36be5855fcSBarry Smith 
37be5855fcSBarry Smith   PetscFunctionBegin;
38c4992f7dSBarry Smith   ierr = MatMarkDiagonal_SeqBAIJ(A);CHKERRQ(ierr);
39883fce79SBarry Smith   diag = a->diag;
400e8e8aceSBarry Smith   for (i=0; i<a->mbs; i++) {
41be5855fcSBarry Smith     if (jj[diag[i]] != i) {
4229bbc08cSBarry Smith       SETERRQ1(1,"Matrix is missing diagonal number %d",i);
43be5855fcSBarry Smith     }
44be5855fcSBarry Smith   }
45be5855fcSBarry Smith   PetscFunctionReturn(0);
46be5855fcSBarry Smith }
47be5855fcSBarry Smith 
484a2ae208SSatish Balay #undef __FUNCT__
494a2ae208SSatish Balay #define __FUNCT__ "MatMarkDiagonal_SeqBAIJ"
50c4992f7dSBarry Smith int MatMarkDiagonal_SeqBAIJ(Mat A)
51de6a44a3SBarry Smith {
52de6a44a3SBarry Smith   Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)A->data;
5382502324SSatish Balay   int         i,j,*diag,m = a->mbs,ierr;
54de6a44a3SBarry Smith 
553a40ed3dSBarry Smith   PetscFunctionBegin;
56883fce79SBarry Smith   if (a->diag) PetscFunctionReturn(0);
57883fce79SBarry Smith 
58b0a32e0cSBarry Smith   ierr = PetscMalloc((m+1)*sizeof(int),&diag);CHKERRQ(ierr);
59b0a32e0cSBarry Smith   PetscLogObjectMemory(A,(m+1)*sizeof(int));
607fc0212eSBarry Smith   for (i=0; i<m; i++) {
61ecc615b2SBarry Smith     diag[i] = a->i[i+1];
62de6a44a3SBarry Smith     for (j=a->i[i]; j<a->i[i+1]; j++) {
63de6a44a3SBarry Smith       if (a->j[j] == i) {
64de6a44a3SBarry Smith         diag[i] = j;
65de6a44a3SBarry Smith         break;
66de6a44a3SBarry Smith       }
67de6a44a3SBarry Smith     }
68de6a44a3SBarry Smith   }
69de6a44a3SBarry Smith   a->diag = diag;
703a40ed3dSBarry Smith   PetscFunctionReturn(0);
71de6a44a3SBarry Smith }
722593348eSBarry Smith 
732593348eSBarry Smith 
74ca44d042SBarry Smith EXTERN int MatToSymmetricIJ_SeqAIJ(int,int*,int*,int,int,int**,int**);
753b2fbd54SBarry Smith 
764a2ae208SSatish Balay #undef __FUNCT__
774a2ae208SSatish Balay #define __FUNCT__ "MatGetRowIJ_SeqBAIJ"
780e6d2581SBarry Smith static int MatGetRowIJ_SeqBAIJ(Mat A,int oshift,PetscTruth symmetric,int *nn,int **ia,int **ja,PetscTruth *done)
793b2fbd54SBarry Smith {
803b2fbd54SBarry Smith   Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)A->data;
813b2fbd54SBarry Smith   int         ierr,n = a->mbs,i;
823b2fbd54SBarry Smith 
833a40ed3dSBarry Smith   PetscFunctionBegin;
843b2fbd54SBarry Smith   *nn = n;
853a40ed3dSBarry Smith   if (!ia) PetscFunctionReturn(0);
863b2fbd54SBarry Smith   if (symmetric) {
873b2fbd54SBarry Smith     ierr = MatToSymmetricIJ_SeqAIJ(n,a->i,a->j,0,oshift,ia,ja);CHKERRQ(ierr);
883b2fbd54SBarry Smith   } else if (oshift == 1) {
893b2fbd54SBarry Smith     /* temporarily add 1 to i and j indices */
90435da068SBarry Smith     int nz = a->i[n];
913b2fbd54SBarry Smith     for (i=0; i<nz; i++) a->j[i]++;
923b2fbd54SBarry Smith     for (i=0; i<n+1; i++) a->i[i]++;
933b2fbd54SBarry Smith     *ia = a->i; *ja = a->j;
943b2fbd54SBarry Smith   } else {
953b2fbd54SBarry Smith     *ia = a->i; *ja = a->j;
963b2fbd54SBarry Smith   }
973b2fbd54SBarry Smith 
983a40ed3dSBarry Smith   PetscFunctionReturn(0);
993b2fbd54SBarry Smith }
1003b2fbd54SBarry Smith 
1014a2ae208SSatish Balay #undef __FUNCT__
1024a2ae208SSatish Balay #define __FUNCT__ "MatRestoreRowIJ_SeqBAIJ"
103435da068SBarry Smith static int MatRestoreRowIJ_SeqBAIJ(Mat A,int oshift,PetscTruth symmetric,int *nn,int **ia,int **ja,PetscTruth *done)
1043b2fbd54SBarry Smith {
1053b2fbd54SBarry Smith   Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)A->data;
106606d414cSSatish Balay   int         i,n = a->mbs,ierr;
1073b2fbd54SBarry Smith 
1083a40ed3dSBarry Smith   PetscFunctionBegin;
1093a40ed3dSBarry Smith   if (!ia) PetscFunctionReturn(0);
1103b2fbd54SBarry Smith   if (symmetric) {
111606d414cSSatish Balay     ierr = PetscFree(*ia);CHKERRQ(ierr);
112606d414cSSatish Balay     ierr = PetscFree(*ja);CHKERRQ(ierr);
113af5da2bfSBarry Smith   } else if (oshift == 1) {
114435da068SBarry Smith     int nz = a->i[n]-1;
1153b2fbd54SBarry Smith     for (i=0; i<nz; i++) a->j[i]--;
1163b2fbd54SBarry Smith     for (i=0; i<n+1; i++) a->i[i]--;
1173b2fbd54SBarry Smith   }
1183a40ed3dSBarry Smith   PetscFunctionReturn(0);
1193b2fbd54SBarry Smith }
1203b2fbd54SBarry Smith 
1214a2ae208SSatish Balay #undef __FUNCT__
1224a2ae208SSatish Balay #define __FUNCT__ "MatGetBlockSize_SeqBAIJ"
1232d61bbb3SSatish Balay int MatGetBlockSize_SeqBAIJ(Mat mat,int *bs)
1242d61bbb3SSatish Balay {
1252d61bbb3SSatish Balay   Mat_SeqBAIJ *baij = (Mat_SeqBAIJ*)mat->data;
1262d61bbb3SSatish Balay 
1272d61bbb3SSatish Balay   PetscFunctionBegin;
1282d61bbb3SSatish Balay   *bs = baij->bs;
1292d61bbb3SSatish Balay   PetscFunctionReturn(0);
1302d61bbb3SSatish Balay }
1312d61bbb3SSatish Balay 
1322d61bbb3SSatish Balay 
1334a2ae208SSatish Balay #undef __FUNCT__
1344a2ae208SSatish Balay #define __FUNCT__ "MatDestroy_SeqBAIJ"
135e1311b90SBarry Smith int MatDestroy_SeqBAIJ(Mat A)
1362d61bbb3SSatish Balay {
1372d61bbb3SSatish Balay   Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)A->data;
138e51c0b9cSSatish Balay   int         ierr;
1392d61bbb3SSatish Balay 
140433994e6SBarry Smith   PetscFunctionBegin;
141aa482453SBarry Smith #if defined(PETSC_USE_LOG)
142b0a32e0cSBarry Smith   PetscLogObjectState((PetscObject)A,"Rows=%d, Cols=%d, NZ=%d",A->m,A->n,a->nz);
1432d61bbb3SSatish Balay #endif
144606d414cSSatish Balay   ierr = PetscFree(a->a);CHKERRQ(ierr);
145606d414cSSatish Balay   if (!a->singlemalloc) {
146606d414cSSatish Balay     ierr = PetscFree(a->i);CHKERRQ(ierr);
147606d414cSSatish Balay     ierr = PetscFree(a->j);CHKERRQ(ierr);
148606d414cSSatish Balay   }
149c38d4ed2SBarry Smith   if (a->row) {
150c38d4ed2SBarry Smith     ierr = ISDestroy(a->row);CHKERRQ(ierr);
151c38d4ed2SBarry Smith   }
152c38d4ed2SBarry Smith   if (a->col) {
153c38d4ed2SBarry Smith     ierr = ISDestroy(a->col);CHKERRQ(ierr);
154c38d4ed2SBarry Smith   }
155606d414cSSatish Balay   if (a->diag) {ierr = PetscFree(a->diag);CHKERRQ(ierr);}
156606d414cSSatish Balay   if (a->ilen) {ierr = PetscFree(a->ilen);CHKERRQ(ierr);}
157606d414cSSatish Balay   if (a->imax) {ierr = PetscFree(a->imax);CHKERRQ(ierr);}
158606d414cSSatish Balay   if (a->solve_work) {ierr = PetscFree(a->solve_work);CHKERRQ(ierr);}
159606d414cSSatish Balay   if (a->mult_work) {ierr = PetscFree(a->mult_work);CHKERRQ(ierr);}
160e51c0b9cSSatish Balay   if (a->icol) {ierr = ISDestroy(a->icol);CHKERRQ(ierr);}
161606d414cSSatish Balay   if (a->saved_values) {ierr = PetscFree(a->saved_values);CHKERRQ(ierr);}
162563b5814SBarry Smith #if defined(PETSC_USE_MAT_SINGLE)
163563b5814SBarry Smith   if (a->setvaluescopy) {ierr = PetscFree(a->setvaluescopy);CHKERRQ(ierr);}
164563b5814SBarry Smith #endif
165606d414cSSatish Balay   ierr = PetscFree(a);CHKERRQ(ierr);
1662d61bbb3SSatish Balay   PetscFunctionReturn(0);
1672d61bbb3SSatish Balay }
1682d61bbb3SSatish Balay 
1694a2ae208SSatish Balay #undef __FUNCT__
1704a2ae208SSatish Balay #define __FUNCT__ "MatSetOption_SeqBAIJ"
1712d61bbb3SSatish Balay int MatSetOption_SeqBAIJ(Mat A,MatOption op)
1722d61bbb3SSatish Balay {
1732d61bbb3SSatish Balay   Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)A->data;
1742d61bbb3SSatish Balay 
1752d61bbb3SSatish Balay   PetscFunctionBegin;
176aa275fccSKris Buschelman   switch (op) {
177aa275fccSKris Buschelman   case MAT_ROW_ORIENTED:
178aa275fccSKris Buschelman     a->roworiented    = PETSC_TRUE;
179aa275fccSKris Buschelman     break;
180aa275fccSKris Buschelman   case MAT_COLUMN_ORIENTED:
181aa275fccSKris Buschelman     a->roworiented    = PETSC_FALSE;
182aa275fccSKris Buschelman     break;
183aa275fccSKris Buschelman   case MAT_COLUMNS_SORTED:
184aa275fccSKris Buschelman     a->sorted         = PETSC_TRUE;
185aa275fccSKris Buschelman     break;
186aa275fccSKris Buschelman   case MAT_COLUMNS_UNSORTED:
187aa275fccSKris Buschelman     a->sorted         = PETSC_FALSE;
188aa275fccSKris Buschelman     break;
189aa275fccSKris Buschelman   case MAT_KEEP_ZEROED_ROWS:
190aa275fccSKris Buschelman     a->keepzeroedrows = PETSC_TRUE;
191aa275fccSKris Buschelman     break;
192aa275fccSKris Buschelman   case MAT_NO_NEW_NONZERO_LOCATIONS:
193aa275fccSKris Buschelman     a->nonew          = 1;
194aa275fccSKris Buschelman     break;
195aa275fccSKris Buschelman   case MAT_NEW_NONZERO_LOCATION_ERR:
196aa275fccSKris Buschelman     a->nonew          = -1;
197aa275fccSKris Buschelman     break;
198aa275fccSKris Buschelman   case MAT_NEW_NONZERO_ALLOCATION_ERR:
199aa275fccSKris Buschelman     a->nonew          = -2;
200aa275fccSKris Buschelman     break;
201aa275fccSKris Buschelman   case MAT_YES_NEW_NONZERO_LOCATIONS:
202aa275fccSKris Buschelman     a->nonew          = 0;
203aa275fccSKris Buschelman     break;
204aa275fccSKris Buschelman   case MAT_ROWS_SORTED:
205aa275fccSKris Buschelman   case MAT_ROWS_UNSORTED:
206aa275fccSKris Buschelman   case MAT_YES_NEW_DIAGONALS:
207aa275fccSKris Buschelman   case MAT_IGNORE_OFF_PROC_ENTRIES:
208aa275fccSKris Buschelman   case MAT_USE_HASH_TABLE:
209b0a32e0cSBarry Smith     PetscLogInfo(A,"MatSetOption_SeqBAIJ:Option ignored\n");
210aa275fccSKris Buschelman     break;
211aa275fccSKris Buschelman   case MAT_NO_NEW_DIAGONALS:
21229bbc08cSBarry Smith     SETERRQ(PETSC_ERR_SUP,"MAT_NO_NEW_DIAGONALS");
213bd648c37SKris Buschelman     break;
214bd648c37SKris Buschelman   case MAT_USE_SINGLE_PRECISION_SOLVES:
215bd648c37SKris Buschelman     if (a->bs==4) {
2168661488fSKris Buschelman       PetscTruth sse_enabled,single_prec,flg;
217bd648c37SKris Buschelman       int        ierr;
218*54138f6bSKris Buschelman 
219bd648c37SKris Buschelman       ierr = PetscSSEIsEnabled(&sse_enabled);CHKERRQ(ierr);
2208661488fSKris Buschelman       ierr = PetscOptionsGetLogical(PETSC_NULL,"-mat_single_precision_solves",&single_prec,&flg);CHKERRQ(ierr);
221*54138f6bSKris Buschelman       if (sse_enabled && flg && single_prec) {
222*54138f6bSKris Buschelman           a->single_precision_solves = PETSC_TRUE;
223*54138f6bSKris Buschelman           A->ops->solve              = MatSolve_SeqBAIJ_Update;
224*54138f6bSKris Buschelman           A->ops->solvetranspose     = MatSolveTranspose_SeqBAIJ_Update;
225*54138f6bSKris Buschelman           break;
2268661488fSKris Buschelman       }
227bd648c37SKris Buschelman       PetscLogInfo(A,"MatSetOption_SeqBAIJ:Option MAT_USE_SINGLE_PRECISION_SOLVES ignored\n");
228bd648c37SKris Buschelman     }
229bd648c37SKris Buschelman     break;
230aa275fccSKris Buschelman   default:
23129bbc08cSBarry Smith     SETERRQ(PETSC_ERR_SUP,"unknown option");
2322d61bbb3SSatish Balay   }
2332d61bbb3SSatish Balay   PetscFunctionReturn(0);
2342d61bbb3SSatish Balay }
2352d61bbb3SSatish Balay 
2364a2ae208SSatish Balay #undef __FUNCT__
2374a2ae208SSatish Balay #define __FUNCT__ "MatGetOwnershipRange_SeqBAIJ"
2382d61bbb3SSatish Balay int MatGetOwnershipRange_SeqBAIJ(Mat A,int *m,int *n)
2392d61bbb3SSatish Balay {
2402d61bbb3SSatish Balay   PetscFunctionBegin;
2414c49b128SBarry Smith   if (m) *m = 0;
242273d9f13SBarry Smith   if (n) *n = A->m;
2432d61bbb3SSatish Balay   PetscFunctionReturn(0);
2442d61bbb3SSatish Balay }
2452d61bbb3SSatish Balay 
2464a2ae208SSatish Balay #undef __FUNCT__
2474a2ae208SSatish Balay #define __FUNCT__ "MatGetRow_SeqBAIJ"
2482d61bbb3SSatish Balay int MatGetRow_SeqBAIJ(Mat A,int row,int *nz,int **idx,Scalar **v)
2492d61bbb3SSatish Balay {
2502d61bbb3SSatish Balay   Mat_SeqBAIJ  *a = (Mat_SeqBAIJ*)A->data;
25182502324SSatish Balay   int          itmp,i,j,k,M,*ai,*aj,bs,bn,bp,*idx_i,bs2,ierr;
2523f1db9ecSBarry Smith   MatScalar    *aa,*aa_i;
2533f1db9ecSBarry Smith   Scalar       *v_i;
2542d61bbb3SSatish Balay 
2552d61bbb3SSatish Balay   PetscFunctionBegin;
2562d61bbb3SSatish Balay   bs  = a->bs;
2572d61bbb3SSatish Balay   ai  = a->i;
2582d61bbb3SSatish Balay   aj  = a->j;
2592d61bbb3SSatish Balay   aa  = a->a;
2602d61bbb3SSatish Balay   bs2 = a->bs2;
2612d61bbb3SSatish Balay 
262273d9f13SBarry Smith   if (row < 0 || row >= A->m) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Row out of range");
2632d61bbb3SSatish Balay 
2642d61bbb3SSatish Balay   bn  = row/bs;   /* Block number */
2652d61bbb3SSatish Balay   bp  = row % bs; /* Block Position */
2662d61bbb3SSatish Balay   M   = ai[bn+1] - ai[bn];
2672d61bbb3SSatish Balay   *nz = bs*M;
2682d61bbb3SSatish Balay 
2692d61bbb3SSatish Balay   if (v) {
2702d61bbb3SSatish Balay     *v = 0;
2712d61bbb3SSatish Balay     if (*nz) {
272b0a32e0cSBarry Smith       ierr = PetscMalloc((*nz)*sizeof(Scalar),v);CHKERRQ(ierr);
2732d61bbb3SSatish Balay       for (i=0; i<M; i++) { /* for each block in the block row */
2742d61bbb3SSatish Balay         v_i  = *v + i*bs;
2752d61bbb3SSatish Balay         aa_i = aa + bs2*(ai[bn] + i);
2762d61bbb3SSatish Balay         for (j=bp,k=0; j<bs2; j+=bs,k++) {v_i[k] = aa_i[j];}
2772d61bbb3SSatish Balay       }
2782d61bbb3SSatish Balay     }
2792d61bbb3SSatish Balay   }
2802d61bbb3SSatish Balay 
2812d61bbb3SSatish Balay   if (idx) {
2822d61bbb3SSatish Balay     *idx = 0;
2832d61bbb3SSatish Balay     if (*nz) {
284b0a32e0cSBarry Smith       ierr = PetscMalloc((*nz)*sizeof(int),idx);CHKERRQ(ierr);
2852d61bbb3SSatish Balay       for (i=0; i<M; i++) { /* for each block in the block row */
2862d61bbb3SSatish Balay         idx_i = *idx + i*bs;
2872d61bbb3SSatish Balay         itmp  = bs*aj[ai[bn] + i];
2882d61bbb3SSatish Balay         for (j=0; j<bs; j++) {idx_i[j] = itmp++;}
2892d61bbb3SSatish Balay       }
2902d61bbb3SSatish Balay     }
2912d61bbb3SSatish Balay   }
2922d61bbb3SSatish Balay   PetscFunctionReturn(0);
2932d61bbb3SSatish Balay }
2942d61bbb3SSatish Balay 
2954a2ae208SSatish Balay #undef __FUNCT__
2964a2ae208SSatish Balay #define __FUNCT__ "MatRestoreRow_SeqBAIJ"
2972d61bbb3SSatish Balay int MatRestoreRow_SeqBAIJ(Mat A,int row,int *nz,int **idx,Scalar **v)
2982d61bbb3SSatish Balay {
299606d414cSSatish Balay   int ierr;
300606d414cSSatish Balay 
3012d61bbb3SSatish Balay   PetscFunctionBegin;
302606d414cSSatish Balay   if (idx) {if (*idx) {ierr = PetscFree(*idx);CHKERRQ(ierr);}}
303606d414cSSatish Balay   if (v)   {if (*v)   {ierr = PetscFree(*v);CHKERRQ(ierr);}}
3042d61bbb3SSatish Balay   PetscFunctionReturn(0);
3052d61bbb3SSatish Balay }
3062d61bbb3SSatish Balay 
3074a2ae208SSatish Balay #undef __FUNCT__
3084a2ae208SSatish Balay #define __FUNCT__ "MatTranspose_SeqBAIJ"
3092d61bbb3SSatish Balay int MatTranspose_SeqBAIJ(Mat A,Mat *B)
3102d61bbb3SSatish Balay {
3112d61bbb3SSatish Balay   Mat_SeqBAIJ *a=(Mat_SeqBAIJ *)A->data;
3122d61bbb3SSatish Balay   Mat         C;
3132d61bbb3SSatish Balay   int         i,j,k,ierr,*aj=a->j,*ai=a->i,bs=a->bs,mbs=a->mbs,nbs=a->nbs,len,*col;
314273d9f13SBarry Smith   int         *rows,*cols,bs2=a->bs2;
315375fe846SBarry Smith   Scalar      *array;
3162d61bbb3SSatish Balay 
3172d61bbb3SSatish Balay   PetscFunctionBegin;
31829bbc08cSBarry Smith   if (!B && mbs!=nbs) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Square matrix only for in-place");
319b0a32e0cSBarry Smith   ierr = PetscMalloc((1+nbs)*sizeof(int),&col);CHKERRQ(ierr);
320549d3d68SSatish Balay   ierr = PetscMemzero(col,(1+nbs)*sizeof(int));CHKERRQ(ierr);
3212d61bbb3SSatish Balay 
322375fe846SBarry Smith #if defined(PETSC_USE_MAT_SINGLE)
323b0a32e0cSBarry Smith   ierr = PetscMalloc(a->bs2*a->nz*sizeof(Scalar),&array);CHKERRQ(ierr);
324375fe846SBarry Smith   for (i=0; i<a->bs2*a->nz; i++) array[i] = (Scalar)a->a[i];
325375fe846SBarry Smith #else
3263eda8832SBarry Smith   array = a->a;
327375fe846SBarry Smith #endif
328375fe846SBarry Smith 
3292d61bbb3SSatish Balay   for (i=0; i<ai[mbs]; i++) col[aj[i]] += 1;
330273d9f13SBarry Smith   ierr = MatCreateSeqBAIJ(A->comm,bs,A->n,A->m,PETSC_NULL,col,&C);CHKERRQ(ierr);
331606d414cSSatish Balay   ierr = PetscFree(col);CHKERRQ(ierr);
332b0a32e0cSBarry Smith   ierr = PetscMalloc(2*bs*sizeof(int),&rows);CHKERRQ(ierr);
3332d61bbb3SSatish Balay   cols = rows + bs;
3342d61bbb3SSatish Balay   for (i=0; i<mbs; i++) {
3352d61bbb3SSatish Balay     cols[0] = i*bs;
3362d61bbb3SSatish Balay     for (k=1; k<bs; k++) cols[k] = cols[k-1] + 1;
3372d61bbb3SSatish Balay     len = ai[i+1] - ai[i];
3382d61bbb3SSatish Balay     for (j=0; j<len; j++) {
3392d61bbb3SSatish Balay       rows[0] = (*aj++)*bs;
3402d61bbb3SSatish Balay       for (k=1; k<bs; k++) rows[k] = rows[k-1] + 1;
3412d61bbb3SSatish Balay       ierr = MatSetValues(C,bs,rows,bs,cols,array,INSERT_VALUES);CHKERRQ(ierr);
3422d61bbb3SSatish Balay       array += bs2;
3432d61bbb3SSatish Balay     }
3442d61bbb3SSatish Balay   }
345606d414cSSatish Balay   ierr = PetscFree(rows);CHKERRQ(ierr);
346375fe846SBarry Smith #if defined(PETSC_USE_MAT_SINGLE)
347375fe846SBarry Smith   ierr = PetscFree(array);
348375fe846SBarry Smith #endif
3492d61bbb3SSatish Balay 
3502d61bbb3SSatish Balay   ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
3512d61bbb3SSatish Balay   ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
3522d61bbb3SSatish Balay 
353c4992f7dSBarry Smith   if (B) {
3542d61bbb3SSatish Balay     *B = C;
3552d61bbb3SSatish Balay   } else {
356273d9f13SBarry Smith     ierr = MatHeaderCopy(A,C);CHKERRQ(ierr);
3572d61bbb3SSatish Balay   }
3582d61bbb3SSatish Balay   PetscFunctionReturn(0);
3592d61bbb3SSatish Balay }
3602d61bbb3SSatish Balay 
3614a2ae208SSatish Balay #undef __FUNCT__
3624a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqBAIJ_Binary"
363b0a32e0cSBarry Smith static int MatView_SeqBAIJ_Binary(Mat A,PetscViewer viewer)
3642593348eSBarry Smith {
365b6490206SBarry Smith   Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)A->data;
3669df24120SSatish Balay   int         i,fd,*col_lens,ierr,bs = a->bs,count,*jj,j,k,l,bs2=a->bs2;
367b6490206SBarry Smith   Scalar      *aa;
368ce6f0cecSBarry Smith   FILE        *file;
3692593348eSBarry Smith 
3703a40ed3dSBarry Smith   PetscFunctionBegin;
371b0a32e0cSBarry Smith   ierr        = PetscViewerBinaryGetDescriptor(viewer,&fd);CHKERRQ(ierr);
372b0a32e0cSBarry Smith   ierr        = PetscMalloc((4+A->m)*sizeof(int),&col_lens);CHKERRQ(ierr);
3732593348eSBarry Smith   col_lens[0] = MAT_COOKIE;
3743b2fbd54SBarry Smith 
375273d9f13SBarry Smith   col_lens[1] = A->m;
376273d9f13SBarry Smith   col_lens[2] = A->n;
3777e67e3f9SSatish Balay   col_lens[3] = a->nz*bs2;
3782593348eSBarry Smith 
3792593348eSBarry Smith   /* store lengths of each row and write (including header) to file */
380b6490206SBarry Smith   count = 0;
381b6490206SBarry Smith   for (i=0; i<a->mbs; i++) {
382b6490206SBarry Smith     for (j=0; j<bs; j++) {
383b6490206SBarry Smith       col_lens[4+count++] = bs*(a->i[i+1] - a->i[i]);
384b6490206SBarry Smith     }
3852593348eSBarry Smith   }
386273d9f13SBarry Smith   ierr = PetscBinaryWrite(fd,col_lens,4+A->m,PETSC_INT,1);CHKERRQ(ierr);
387606d414cSSatish Balay   ierr = PetscFree(col_lens);CHKERRQ(ierr);
3882593348eSBarry Smith 
3892593348eSBarry Smith   /* store column indices (zero start index) */
390b0a32e0cSBarry Smith   ierr  = PetscMalloc((a->nz+1)*bs2*sizeof(int),&jj);CHKERRQ(ierr);
391b6490206SBarry Smith   count = 0;
392b6490206SBarry Smith   for (i=0; i<a->mbs; i++) {
393b6490206SBarry Smith     for (j=0; j<bs; j++) {
394b6490206SBarry Smith       for (k=a->i[i]; k<a->i[i+1]; k++) {
395b6490206SBarry Smith         for (l=0; l<bs; l++) {
396b6490206SBarry Smith           jj[count++] = bs*a->j[k] + l;
3972593348eSBarry Smith         }
3982593348eSBarry Smith       }
399b6490206SBarry Smith     }
400b6490206SBarry Smith   }
4010752156aSBarry Smith   ierr = PetscBinaryWrite(fd,jj,bs2*a->nz,PETSC_INT,0);CHKERRQ(ierr);
402606d414cSSatish Balay   ierr = PetscFree(jj);CHKERRQ(ierr);
4032593348eSBarry Smith 
4042593348eSBarry Smith   /* store nonzero values */
405b0a32e0cSBarry Smith   ierr  = PetscMalloc((a->nz+1)*bs2*sizeof(Scalar),&aa);CHKERRQ(ierr);
406b6490206SBarry Smith   count = 0;
407b6490206SBarry Smith   for (i=0; i<a->mbs; i++) {
408b6490206SBarry Smith     for (j=0; j<bs; j++) {
409b6490206SBarry Smith       for (k=a->i[i]; k<a->i[i+1]; k++) {
410b6490206SBarry Smith         for (l=0; l<bs; l++) {
4117e67e3f9SSatish Balay           aa[count++] = a->a[bs2*k + l*bs + j];
412b6490206SBarry Smith         }
413b6490206SBarry Smith       }
414b6490206SBarry Smith     }
415b6490206SBarry Smith   }
4160752156aSBarry Smith   ierr = PetscBinaryWrite(fd,aa,bs2*a->nz,PETSC_SCALAR,0);CHKERRQ(ierr);
417606d414cSSatish Balay   ierr = PetscFree(aa);CHKERRQ(ierr);
418ce6f0cecSBarry Smith 
419b0a32e0cSBarry Smith   ierr = PetscViewerBinaryGetInfoPointer(viewer,&file);CHKERRQ(ierr);
420ce6f0cecSBarry Smith   if (file) {
421ce6f0cecSBarry Smith     fprintf(file,"-matload_block_size %d\n",a->bs);
422ce6f0cecSBarry Smith   }
4233a40ed3dSBarry Smith   PetscFunctionReturn(0);
4242593348eSBarry Smith }
4252593348eSBarry Smith 
4264a2ae208SSatish Balay #undef __FUNCT__
4274a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqBAIJ_ASCII"
428b0a32e0cSBarry Smith static int MatView_SeqBAIJ_ASCII(Mat A,PetscViewer viewer)
4292593348eSBarry Smith {
430b6490206SBarry Smith   Mat_SeqBAIJ       *a = (Mat_SeqBAIJ*)A->data;
431fb9695e5SSatish Balay   int               ierr,i,j,bs = a->bs,k,l,bs2=a->bs2;
432f3ef73ceSBarry Smith   PetscViewerFormat format;
4332593348eSBarry Smith 
4343a40ed3dSBarry Smith   PetscFunctionBegin;
435b0a32e0cSBarry Smith   ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr);
436fb9695e5SSatish Balay   if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_LONG) {
437b0a32e0cSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  block size is %d\n",bs);CHKERRQ(ierr);
438fb9695e5SSatish Balay   } else if (format == PETSC_VIEWER_ASCII_MATLAB) {
43929bbc08cSBarry Smith     SETERRQ(PETSC_ERR_SUP,"Matlab format not supported");
440fb9695e5SSatish Balay   } else if (format == PETSC_VIEWER_ASCII_COMMON) {
441b0a32e0cSBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_NO);CHKERRQ(ierr);
44244cd7ae7SLois Curfman McInnes     for (i=0; i<a->mbs; i++) {
44344cd7ae7SLois Curfman McInnes       for (j=0; j<bs; j++) {
444b0a32e0cSBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"row %d:",i*bs+j);CHKERRQ(ierr);
44544cd7ae7SLois Curfman McInnes         for (k=a->i[i]; k<a->i[i+1]; k++) {
44644cd7ae7SLois Curfman McInnes           for (l=0; l<bs; l++) {
447aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
4480e6d2581SBarry Smith             if (PetscImaginaryPart(a->a[bs2*k + l*bs + j]) > 0.0 && PetscRealPart(a->a[bs2*k + l*bs + j]) != 0.0) {
449b0a32e0cSBarry Smith               ierr = PetscViewerASCIIPrintf(viewer," %d %g + %gi",bs*a->j[k]+l,
4500e6d2581SBarry Smith                       PetscRealPart(a->a[bs2*k + l*bs + j]),PetscImaginaryPart(a->a[bs2*k + l*bs + j]));CHKERRQ(ierr);
4510e6d2581SBarry Smith             } else if (PetscImaginaryPart(a->a[bs2*k + l*bs + j]) < 0.0 && PetscRealPart(a->a[bs2*k + l*bs + j]) != 0.0) {
452b0a32e0cSBarry Smith               ierr = PetscViewerASCIIPrintf(viewer," %d %g - %gi",bs*a->j[k]+l,
4530e6d2581SBarry Smith                       PetscRealPart(a->a[bs2*k + l*bs + j]),-PetscImaginaryPart(a->a[bs2*k + l*bs + j]));CHKERRQ(ierr);
4540e6d2581SBarry Smith             } else if (PetscRealPart(a->a[bs2*k + l*bs + j]) != 0.0) {
455b0a32e0cSBarry Smith               ierr = PetscViewerASCIIPrintf(viewer," %d %g ",bs*a->j[k]+l,PetscRealPart(a->a[bs2*k + l*bs + j]));CHKERRQ(ierr);
4560ef38995SBarry Smith             }
45744cd7ae7SLois Curfman McInnes #else
4580ef38995SBarry Smith             if (a->a[bs2*k + l*bs + j] != 0.0) {
459b0a32e0cSBarry Smith               ierr = PetscViewerASCIIPrintf(viewer," %d %g ",bs*a->j[k]+l,a->a[bs2*k + l*bs + j]);CHKERRQ(ierr);
4600ef38995SBarry Smith             }
46144cd7ae7SLois Curfman McInnes #endif
46244cd7ae7SLois Curfman McInnes           }
46344cd7ae7SLois Curfman McInnes         }
464b0a32e0cSBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
46544cd7ae7SLois Curfman McInnes       }
46644cd7ae7SLois Curfman McInnes     }
467b0a32e0cSBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_YES);CHKERRQ(ierr);
4680ef38995SBarry Smith   } else {
469b0a32e0cSBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_NO);CHKERRQ(ierr);
470b6490206SBarry Smith     for (i=0; i<a->mbs; i++) {
471b6490206SBarry Smith       for (j=0; j<bs; j++) {
472b0a32e0cSBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"row %d:",i*bs+j);CHKERRQ(ierr);
473b6490206SBarry Smith         for (k=a->i[i]; k<a->i[i+1]; k++) {
474b6490206SBarry Smith           for (l=0; l<bs; l++) {
475aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
4760e6d2581SBarry Smith             if (PetscImaginaryPart(a->a[bs2*k + l*bs + j]) > 0.0) {
477b0a32e0cSBarry Smith               ierr = PetscViewerASCIIPrintf(viewer," %d %g + %g i",bs*a->j[k]+l,
4780e6d2581SBarry Smith                 PetscRealPart(a->a[bs2*k + l*bs + j]),PetscImaginaryPart(a->a[bs2*k + l*bs + j]));CHKERRQ(ierr);
4790e6d2581SBarry Smith             } else if (PetscImaginaryPart(a->a[bs2*k + l*bs + j]) < 0.0) {
480b0a32e0cSBarry Smith               ierr = PetscViewerASCIIPrintf(viewer," %d %g - %g i",bs*a->j[k]+l,
4810e6d2581SBarry Smith                 PetscRealPart(a->a[bs2*k + l*bs + j]),-PetscImaginaryPart(a->a[bs2*k + l*bs + j]));CHKERRQ(ierr);
4820ef38995SBarry Smith             } else {
483b0a32e0cSBarry Smith               ierr = PetscViewerASCIIPrintf(viewer," %d %g ",bs*a->j[k]+l,PetscRealPart(a->a[bs2*k + l*bs + j]));CHKERRQ(ierr);
48488685aaeSLois Curfman McInnes             }
48588685aaeSLois Curfman McInnes #else
486b0a32e0cSBarry Smith             ierr = PetscViewerASCIIPrintf(viewer," %d %g ",bs*a->j[k]+l,a->a[bs2*k + l*bs + j]);CHKERRQ(ierr);
48788685aaeSLois Curfman McInnes #endif
4882593348eSBarry Smith           }
4892593348eSBarry Smith         }
490b0a32e0cSBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
4912593348eSBarry Smith       }
4922593348eSBarry Smith     }
493b0a32e0cSBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_YES);CHKERRQ(ierr);
494b6490206SBarry Smith   }
495b0a32e0cSBarry Smith   ierr = PetscViewerFlush(viewer);CHKERRQ(ierr);
4963a40ed3dSBarry Smith   PetscFunctionReturn(0);
4972593348eSBarry Smith }
4982593348eSBarry Smith 
4994a2ae208SSatish Balay #undef __FUNCT__
5004a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqBAIJ_Draw_Zoom"
501b0a32e0cSBarry Smith static int MatView_SeqBAIJ_Draw_Zoom(PetscDraw draw,void *Aa)
5023270192aSSatish Balay {
50377ed5343SBarry Smith   Mat          A = (Mat) Aa;
5043270192aSSatish Balay   Mat_SeqBAIJ  *a=(Mat_SeqBAIJ*)A->data;
505b65db4caSBarry Smith   int          row,ierr,i,j,k,l,mbs=a->mbs,color,bs=a->bs,bs2=a->bs2;
5060e6d2581SBarry Smith   PetscReal    xl,yl,xr,yr,x_l,x_r,y_l,y_r;
5073f1db9ecSBarry Smith   MatScalar    *aa;
508b0a32e0cSBarry Smith   PetscViewer  viewer;
5093270192aSSatish Balay 
5103a40ed3dSBarry Smith   PetscFunctionBegin;
5113270192aSSatish Balay 
512b65db4caSBarry Smith   /* still need to add support for contour plot of nonzeros; see MatView_SeqAIJ_Draw_Zoom()*/
51377ed5343SBarry Smith   ierr = PetscObjectQuery((PetscObject)A,"Zoomviewer",(PetscObject*)&viewer);CHKERRQ(ierr);
51477ed5343SBarry Smith 
515b0a32e0cSBarry Smith   ierr = PetscDrawGetCoordinates(draw,&xl,&yl,&xr,&yr);CHKERRQ(ierr);
51677ed5343SBarry Smith 
5173270192aSSatish Balay   /* loop over matrix elements drawing boxes */
518b0a32e0cSBarry Smith   color = PETSC_DRAW_BLUE;
5193270192aSSatish Balay   for (i=0,row=0; i<mbs; i++,row+=bs) {
5203270192aSSatish Balay     for (j=a->i[i]; j<a->i[i+1]; j++) {
521273d9f13SBarry Smith       y_l = A->m - row - 1.0; y_r = y_l + 1.0;
5223270192aSSatish Balay       x_l = a->j[j]*bs; x_r = x_l + 1.0;
5233270192aSSatish Balay       aa = a->a + j*bs2;
5243270192aSSatish Balay       for (k=0; k<bs; k++) {
5253270192aSSatish Balay         for (l=0; l<bs; l++) {
5260e6d2581SBarry Smith           if (PetscRealPart(*aa++) >=  0.) continue;
527b0a32e0cSBarry Smith           ierr = PetscDrawRectangle(draw,x_l+k,y_l-l,x_r+k,y_r-l,color,color,color,color);CHKERRQ(ierr);
5283270192aSSatish Balay         }
5293270192aSSatish Balay       }
5303270192aSSatish Balay     }
5313270192aSSatish Balay   }
532b0a32e0cSBarry Smith   color = PETSC_DRAW_CYAN;
5333270192aSSatish Balay   for (i=0,row=0; i<mbs; i++,row+=bs) {
5343270192aSSatish Balay     for (j=a->i[i]; j<a->i[i+1]; j++) {
535273d9f13SBarry Smith       y_l = A->m - row - 1.0; y_r = y_l + 1.0;
5363270192aSSatish Balay       x_l = a->j[j]*bs; x_r = x_l + 1.0;
5373270192aSSatish Balay       aa = a->a + j*bs2;
5383270192aSSatish Balay       for (k=0; k<bs; k++) {
5393270192aSSatish Balay         for (l=0; l<bs; l++) {
5400e6d2581SBarry Smith           if (PetscRealPart(*aa++) != 0.) continue;
541b0a32e0cSBarry Smith           ierr = PetscDrawRectangle(draw,x_l+k,y_l-l,x_r+k,y_r-l,color,color,color,color);CHKERRQ(ierr);
5423270192aSSatish Balay         }
5433270192aSSatish Balay       }
5443270192aSSatish Balay     }
5453270192aSSatish Balay   }
5463270192aSSatish Balay 
547b0a32e0cSBarry Smith   color = PETSC_DRAW_RED;
5483270192aSSatish Balay   for (i=0,row=0; i<mbs; i++,row+=bs) {
5493270192aSSatish Balay     for (j=a->i[i]; j<a->i[i+1]; j++) {
550273d9f13SBarry Smith       y_l = A->m - row - 1.0; y_r = y_l + 1.0;
5513270192aSSatish Balay       x_l = a->j[j]*bs; x_r = x_l + 1.0;
5523270192aSSatish Balay       aa = a->a + j*bs2;
5533270192aSSatish Balay       for (k=0; k<bs; k++) {
5543270192aSSatish Balay         for (l=0; l<bs; l++) {
5550e6d2581SBarry Smith           if (PetscRealPart(*aa++) <= 0.) continue;
556b0a32e0cSBarry Smith           ierr = PetscDrawRectangle(draw,x_l+k,y_l-l,x_r+k,y_r-l,color,color,color,color);CHKERRQ(ierr);
5573270192aSSatish Balay         }
5583270192aSSatish Balay       }
5593270192aSSatish Balay     }
5603270192aSSatish Balay   }
56177ed5343SBarry Smith   PetscFunctionReturn(0);
56277ed5343SBarry Smith }
5633270192aSSatish Balay 
5644a2ae208SSatish Balay #undef __FUNCT__
5654a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqBAIJ_Draw"
566b0a32e0cSBarry Smith static int MatView_SeqBAIJ_Draw(Mat A,PetscViewer viewer)
56777ed5343SBarry Smith {
5687dce120fSSatish Balay   int          ierr;
5690e6d2581SBarry Smith   PetscReal    xl,yl,xr,yr,w,h;
570b0a32e0cSBarry Smith   PetscDraw    draw;
57177ed5343SBarry Smith   PetscTruth   isnull;
5723270192aSSatish Balay 
57377ed5343SBarry Smith   PetscFunctionBegin;
57477ed5343SBarry Smith 
575b0a32e0cSBarry Smith   ierr = PetscViewerDrawGetDraw(viewer,0,&draw);CHKERRQ(ierr);
576b0a32e0cSBarry Smith   ierr = PetscDrawIsNull(draw,&isnull);CHKERRQ(ierr); if (isnull) PetscFunctionReturn(0);
57777ed5343SBarry Smith 
57877ed5343SBarry Smith   ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",(PetscObject)viewer);CHKERRQ(ierr);
579273d9f13SBarry Smith   xr  = A->n; yr = A->m; h = yr/10.0; w = xr/10.0;
58077ed5343SBarry Smith   xr += w;    yr += h;  xl = -w;     yl = -h;
581b0a32e0cSBarry Smith   ierr = PetscDrawSetCoordinates(draw,xl,yl,xr,yr);CHKERRQ(ierr);
582b0a32e0cSBarry Smith   ierr = PetscDrawZoom(draw,MatView_SeqBAIJ_Draw_Zoom,A);CHKERRQ(ierr);
58377ed5343SBarry Smith   ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",PETSC_NULL);CHKERRQ(ierr);
5843a40ed3dSBarry Smith   PetscFunctionReturn(0);
5853270192aSSatish Balay }
5863270192aSSatish Balay 
5874a2ae208SSatish Balay #undef __FUNCT__
5884a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqBAIJ"
589b0a32e0cSBarry Smith int MatView_SeqBAIJ(Mat A,PetscViewer viewer)
5902593348eSBarry Smith {
59119bcc07fSBarry Smith   int        ierr;
5926831982aSBarry Smith   PetscTruth issocket,isascii,isbinary,isdraw;
5932593348eSBarry Smith 
5943a40ed3dSBarry Smith   PetscFunctionBegin;
595b0a32e0cSBarry Smith   ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_SOCKET,&issocket);CHKERRQ(ierr);
596b0a32e0cSBarry Smith   ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&isascii);CHKERRQ(ierr);
597fb9695e5SSatish Balay   ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_BINARY,&isbinary);CHKERRQ(ierr);
598fb9695e5SSatish Balay   ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_DRAW,&isdraw);CHKERRQ(ierr);
5990f5bd95cSBarry Smith   if (issocket) {
60029bbc08cSBarry Smith     SETERRQ(PETSC_ERR_SUP,"Socket viewer not supported");
6010f5bd95cSBarry Smith   } else if (isascii){
6023a40ed3dSBarry Smith     ierr = MatView_SeqBAIJ_ASCII(A,viewer);CHKERRQ(ierr);
6030f5bd95cSBarry Smith   } else if (isbinary) {
6043a40ed3dSBarry Smith     ierr = MatView_SeqBAIJ_Binary(A,viewer);CHKERRQ(ierr);
6050f5bd95cSBarry Smith   } else if (isdraw) {
6063a40ed3dSBarry Smith     ierr = MatView_SeqBAIJ_Draw(A,viewer);CHKERRQ(ierr);
6075cd90555SBarry Smith   } else {
60829bbc08cSBarry Smith     SETERRQ1(1,"Viewer type %s not supported by SeqBAIJ matrices",((PetscObject)viewer)->type_name);
6092593348eSBarry Smith   }
6103a40ed3dSBarry Smith   PetscFunctionReturn(0);
6112593348eSBarry Smith }
612b6490206SBarry Smith 
613cd0e1443SSatish Balay 
6144a2ae208SSatish Balay #undef __FUNCT__
6154a2ae208SSatish Balay #define __FUNCT__ "MatGetValues_SeqBAIJ"
6162d61bbb3SSatish Balay int MatGetValues_SeqBAIJ(Mat A,int m,int *im,int n,int *in,Scalar *v)
617cd0e1443SSatish Balay {
618cd0e1443SSatish Balay   Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)A->data;
6192d61bbb3SSatish Balay   int        *rp,k,low,high,t,row,nrow,i,col,l,*aj = a->j;
6202d61bbb3SSatish Balay   int        *ai = a->i,*ailen = a->ilen;
6212d61bbb3SSatish Balay   int        brow,bcol,ridx,cidx,bs=a->bs,bs2=a->bs2;
6223f1db9ecSBarry Smith   MatScalar  *ap,*aa = a->a,zero = 0.0;
623cd0e1443SSatish Balay 
6243a40ed3dSBarry Smith   PetscFunctionBegin;
6252d61bbb3SSatish Balay   for (k=0; k<m; k++) { /* loop over rows */
626cd0e1443SSatish Balay     row  = im[k]; brow = row/bs;
62729bbc08cSBarry Smith     if (row < 0) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Negative row");
628273d9f13SBarry Smith     if (row >= A->m) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Row too large");
6292d61bbb3SSatish Balay     rp   = aj + ai[brow] ; ap = aa + bs2*ai[brow] ;
6302c3acbe9SBarry Smith     nrow = ailen[brow];
6312d61bbb3SSatish Balay     for (l=0; l<n; l++) { /* loop over columns */
63229bbc08cSBarry Smith       if (in[l] < 0) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Negative column");
633273d9f13SBarry Smith       if (in[l] >= A->n) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Column too large");
6342d61bbb3SSatish Balay       col  = in[l] ;
6352d61bbb3SSatish Balay       bcol = col/bs;
6362d61bbb3SSatish Balay       cidx = col%bs;
6372d61bbb3SSatish Balay       ridx = row%bs;
6382d61bbb3SSatish Balay       high = nrow;
6392d61bbb3SSatish Balay       low  = 0; /* assume unsorted */
6402d61bbb3SSatish Balay       while (high-low > 5) {
641cd0e1443SSatish Balay         t = (low+high)/2;
642cd0e1443SSatish Balay         if (rp[t] > bcol) high = t;
643cd0e1443SSatish Balay         else             low  = t;
644cd0e1443SSatish Balay       }
645cd0e1443SSatish Balay       for (i=low; i<high; i++) {
646cd0e1443SSatish Balay         if (rp[i] > bcol) break;
647cd0e1443SSatish Balay         if (rp[i] == bcol) {
6482d61bbb3SSatish Balay           *v++ = ap[bs2*i+bs*cidx+ridx];
6492d61bbb3SSatish Balay           goto finished;
650cd0e1443SSatish Balay         }
651cd0e1443SSatish Balay       }
6522d61bbb3SSatish Balay       *v++ = zero;
6532d61bbb3SSatish Balay       finished:;
654cd0e1443SSatish Balay     }
655cd0e1443SSatish Balay   }
6563a40ed3dSBarry Smith   PetscFunctionReturn(0);
657cd0e1443SSatish Balay }
658cd0e1443SSatish Balay 
65995d5f7c2SBarry Smith #if defined(PETSC_USE_MAT_SINGLE)
6604a2ae208SSatish Balay #undef __FUNCT__
6614a2ae208SSatish Balay #define __FUNCT__ "MatSetValuesBlocked_SeqBAIJ"
66295d5f7c2SBarry Smith int MatSetValuesBlocked_SeqBAIJ(Mat mat,int m,int *im,int n,int *in,Scalar *v,InsertMode addv)
66395d5f7c2SBarry Smith {
664563b5814SBarry Smith   Mat_SeqBAIJ *b = (Mat_SeqBAIJ*)mat->data;
665563b5814SBarry Smith   int         ierr,i,N = m*n*b->bs2;
666563b5814SBarry Smith   MatScalar   *vsingle;
66795d5f7c2SBarry Smith 
66895d5f7c2SBarry Smith   PetscFunctionBegin;
669563b5814SBarry Smith   if (N > b->setvalueslen) {
670563b5814SBarry Smith     if (b->setvaluescopy) {ierr = PetscFree(b->setvaluescopy);CHKERRQ(ierr);}
671b0a32e0cSBarry Smith     ierr = PetscMalloc(N*sizeof(MatScalar),&b->setvaluescopy);CHKERRQ(ierr);
672563b5814SBarry Smith     b->setvalueslen  = N;
673563b5814SBarry Smith   }
674563b5814SBarry Smith   vsingle = b->setvaluescopy;
67595d5f7c2SBarry Smith   for (i=0; i<N; i++) {
67695d5f7c2SBarry Smith     vsingle[i] = v[i];
67795d5f7c2SBarry Smith   }
67895d5f7c2SBarry Smith   ierr = MatSetValuesBlocked_SeqBAIJ_MatScalar(mat,m,im,n,in,vsingle,addv);CHKERRQ(ierr);
67995d5f7c2SBarry Smith   PetscFunctionReturn(0);
68095d5f7c2SBarry Smith }
68195d5f7c2SBarry Smith #endif
68295d5f7c2SBarry Smith 
6832d61bbb3SSatish Balay 
6844a2ae208SSatish Balay #undef __FUNCT__
6854a2ae208SSatish Balay #define __FUNCT__ "MatSetValuesBlocked_SeqBAIJ"
68695d5f7c2SBarry Smith int MatSetValuesBlocked_SeqBAIJ_MatScalar(Mat A,int m,int *im,int n,int *in,MatScalar *v,InsertMode is)
68792c4ed94SBarry Smith {
68892c4ed94SBarry Smith   Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)A->data;
6898a84c255SSatish Balay   int         *rp,k,low,high,t,ii,jj,row,nrow,i,col,l,rmax,N,sorted=a->sorted;
690273d9f13SBarry Smith   int         *imax=a->imax,*ai=a->i,*ailen=a->ilen;
691549d3d68SSatish Balay   int         *aj=a->j,nonew=a->nonew,bs2=a->bs2,bs=a->bs,stepval,ierr;
692273d9f13SBarry Smith   PetscTruth  roworiented=a->roworiented;
69395d5f7c2SBarry Smith   MatScalar   *value = v,*ap,*aa = a->a,*bap;
69492c4ed94SBarry Smith 
6953a40ed3dSBarry Smith   PetscFunctionBegin;
6960e324ae4SSatish Balay   if (roworiented) {
6970e324ae4SSatish Balay     stepval = (n-1)*bs;
6980e324ae4SSatish Balay   } else {
6990e324ae4SSatish Balay     stepval = (m-1)*bs;
7000e324ae4SSatish Balay   }
70192c4ed94SBarry Smith   for (k=0; k<m; k++) { /* loop over added rows */
70292c4ed94SBarry Smith     row  = im[k];
7035ef9f2a5SBarry Smith     if (row < 0) continue;
704aa482453SBarry Smith #if defined(PETSC_USE_BOPT_g)
70529bbc08cSBarry Smith     if (row >= a->mbs) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Row too large");
70692c4ed94SBarry Smith #endif
70792c4ed94SBarry Smith     rp   = aj + ai[row];
70892c4ed94SBarry Smith     ap   = aa + bs2*ai[row];
70992c4ed94SBarry Smith     rmax = imax[row];
71092c4ed94SBarry Smith     nrow = ailen[row];
71192c4ed94SBarry Smith     low  = 0;
71292c4ed94SBarry Smith     for (l=0; l<n; l++) { /* loop over added columns */
7135ef9f2a5SBarry Smith       if (in[l] < 0) continue;
714aa482453SBarry Smith #if defined(PETSC_USE_BOPT_g)
71529bbc08cSBarry Smith       if (in[l] >= a->nbs) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Column too large");
71692c4ed94SBarry Smith #endif
71792c4ed94SBarry Smith       col = in[l];
71892c4ed94SBarry Smith       if (roworiented) {
7190e324ae4SSatish Balay         value = v + k*(stepval+bs)*bs + l*bs;
7200e324ae4SSatish Balay       } else {
7210e324ae4SSatish Balay         value = v + l*(stepval+bs)*bs + k*bs;
72292c4ed94SBarry Smith       }
72392c4ed94SBarry Smith       if (!sorted) low = 0; high = nrow;
72492c4ed94SBarry Smith       while (high-low > 7) {
72592c4ed94SBarry Smith         t = (low+high)/2;
72692c4ed94SBarry Smith         if (rp[t] > col) high = t;
72792c4ed94SBarry Smith         else             low  = t;
72892c4ed94SBarry Smith       }
72992c4ed94SBarry Smith       for (i=low; i<high; i++) {
73092c4ed94SBarry Smith         if (rp[i] > col) break;
73192c4ed94SBarry Smith         if (rp[i] == col) {
7328a84c255SSatish Balay           bap  = ap +  bs2*i;
7330e324ae4SSatish Balay           if (roworiented) {
7348a84c255SSatish Balay             if (is == ADD_VALUES) {
735dd9472c6SBarry Smith               for (ii=0; ii<bs; ii++,value+=stepval) {
736dd9472c6SBarry Smith                 for (jj=ii; jj<bs2; jj+=bs) {
7378a84c255SSatish Balay                   bap[jj] += *value++;
738dd9472c6SBarry Smith                 }
739dd9472c6SBarry Smith               }
7400e324ae4SSatish Balay             } else {
741dd9472c6SBarry Smith               for (ii=0; ii<bs; ii++,value+=stepval) {
742dd9472c6SBarry Smith                 for (jj=ii; jj<bs2; jj+=bs) {
7430e324ae4SSatish Balay                   bap[jj] = *value++;
7448a84c255SSatish Balay                 }
745dd9472c6SBarry Smith               }
746dd9472c6SBarry Smith             }
7470e324ae4SSatish Balay           } else {
7480e324ae4SSatish Balay             if (is == ADD_VALUES) {
749dd9472c6SBarry Smith               for (ii=0; ii<bs; ii++,value+=stepval) {
750dd9472c6SBarry Smith                 for (jj=0; jj<bs; jj++) {
7510e324ae4SSatish Balay                   *bap++ += *value++;
752dd9472c6SBarry Smith                 }
753dd9472c6SBarry Smith               }
7540e324ae4SSatish Balay             } else {
755dd9472c6SBarry Smith               for (ii=0; ii<bs; ii++,value+=stepval) {
756dd9472c6SBarry Smith                 for (jj=0; jj<bs; jj++) {
7570e324ae4SSatish Balay                   *bap++  = *value++;
7580e324ae4SSatish Balay                 }
7598a84c255SSatish Balay               }
760dd9472c6SBarry Smith             }
761dd9472c6SBarry Smith           }
762f1241b54SBarry Smith           goto noinsert2;
76392c4ed94SBarry Smith         }
76492c4ed94SBarry Smith       }
76589280ab3SLois Curfman McInnes       if (nonew == 1) goto noinsert2;
76629bbc08cSBarry Smith       else if (nonew == -1) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Inserting a new nonzero in the matrix");
76792c4ed94SBarry Smith       if (nrow >= rmax) {
76892c4ed94SBarry Smith         /* there is no extra room in row, therefore enlarge */
76992c4ed94SBarry Smith         int       new_nz = ai[a->mbs] + CHUNKSIZE,len,*new_i,*new_j;
7703f1db9ecSBarry Smith         MatScalar *new_a;
77192c4ed94SBarry Smith 
77229bbc08cSBarry Smith         if (nonew == -2) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Inserting a new nonzero in the matrix");
77389280ab3SLois Curfman McInnes 
77492c4ed94SBarry Smith         /* malloc new storage space */
7753f1db9ecSBarry Smith         len     = new_nz*(sizeof(int)+bs2*sizeof(MatScalar))+(a->mbs+1)*sizeof(int);
776b0a32e0cSBarry Smith 	ierr    = PetscMalloc(len,&new_a);CHKERRQ(ierr);
77792c4ed94SBarry Smith         new_j   = (int*)(new_a + bs2*new_nz);
77892c4ed94SBarry Smith         new_i   = new_j + new_nz;
77992c4ed94SBarry Smith 
78092c4ed94SBarry Smith         /* copy over old data into new slots */
78192c4ed94SBarry Smith         for (ii=0; ii<row+1; ii++) {new_i[ii] = ai[ii];}
78292c4ed94SBarry Smith         for (ii=row+1; ii<a->mbs+1; ii++) {new_i[ii] = ai[ii]+CHUNKSIZE;}
783549d3d68SSatish Balay         ierr = PetscMemcpy(new_j,aj,(ai[row]+nrow)*sizeof(int));CHKERRQ(ierr);
78492c4ed94SBarry Smith         len  = (new_nz - CHUNKSIZE - ai[row] - nrow);
785549d3d68SSatish Balay         ierr = PetscMemcpy(new_j+ai[row]+nrow+CHUNKSIZE,aj+ai[row]+nrow,len*sizeof(int));CHKERRQ(ierr);
786549d3d68SSatish Balay         ierr = PetscMemcpy(new_a,aa,(ai[row]+nrow)*bs2*sizeof(MatScalar));CHKERRQ(ierr);
787549d3d68SSatish Balay         ierr = PetscMemzero(new_a+bs2*(ai[row]+nrow),bs2*CHUNKSIZE*sizeof(MatScalar));CHKERRQ(ierr);
788549d3d68SSatish Balay         ierr = PetscMemcpy(new_a+bs2*(ai[row]+nrow+CHUNKSIZE),aa+bs2*(ai[row]+nrow),bs2*len*sizeof(MatScalar));CHKERRQ(ierr);
78992c4ed94SBarry Smith         /* free up old matrix storage */
790606d414cSSatish Balay         ierr = PetscFree(a->a);CHKERRQ(ierr);
791606d414cSSatish Balay         if (!a->singlemalloc) {
792606d414cSSatish Balay           ierr = PetscFree(a->i);CHKERRQ(ierr);
793606d414cSSatish Balay           ierr = PetscFree(a->j);CHKERRQ(ierr);
794606d414cSSatish Balay         }
79592c4ed94SBarry Smith         aa = a->a = new_a; ai = a->i = new_i; aj = a->j = new_j;
796c4992f7dSBarry Smith         a->singlemalloc = PETSC_TRUE;
79792c4ed94SBarry Smith 
79892c4ed94SBarry Smith         rp   = aj + ai[row]; ap = aa + bs2*ai[row];
79992c4ed94SBarry Smith         rmax = imax[row] = imax[row] + CHUNKSIZE;
800b0a32e0cSBarry Smith         PetscLogObjectMemory(A,CHUNKSIZE*(sizeof(int) + bs2*sizeof(MatScalar)));
80192c4ed94SBarry Smith         a->maxnz += bs2*CHUNKSIZE;
80292c4ed94SBarry Smith         a->reallocs++;
80392c4ed94SBarry Smith         a->nz++;
80492c4ed94SBarry Smith       }
80592c4ed94SBarry Smith       N = nrow++ - 1;
80692c4ed94SBarry Smith       /* shift up all the later entries in this row */
80792c4ed94SBarry Smith       for (ii=N; ii>=i; ii--) {
80892c4ed94SBarry Smith         rp[ii+1] = rp[ii];
809549d3d68SSatish Balay         ierr = PetscMemcpy(ap+bs2*(ii+1),ap+bs2*(ii),bs2*sizeof(MatScalar));CHKERRQ(ierr);
81092c4ed94SBarry Smith       }
811549d3d68SSatish Balay       if (N >= i) {
812549d3d68SSatish Balay         ierr = PetscMemzero(ap+bs2*i,bs2*sizeof(MatScalar));CHKERRQ(ierr);
813549d3d68SSatish Balay       }
81492c4ed94SBarry Smith       rp[i] = col;
8158a84c255SSatish Balay       bap   = ap +  bs2*i;
8160e324ae4SSatish Balay       if (roworiented) {
817dd9472c6SBarry Smith         for (ii=0; ii<bs; ii++,value+=stepval) {
818dd9472c6SBarry Smith           for (jj=ii; jj<bs2; jj+=bs) {
8190e324ae4SSatish Balay             bap[jj] = *value++;
820dd9472c6SBarry Smith           }
821dd9472c6SBarry Smith         }
8220e324ae4SSatish Balay       } else {
823dd9472c6SBarry Smith         for (ii=0; ii<bs; ii++,value+=stepval) {
824dd9472c6SBarry Smith           for (jj=0; jj<bs; jj++) {
8250e324ae4SSatish Balay             *bap++  = *value++;
8260e324ae4SSatish Balay           }
827dd9472c6SBarry Smith         }
828dd9472c6SBarry Smith       }
829f1241b54SBarry Smith       noinsert2:;
83092c4ed94SBarry Smith       low = i;
83192c4ed94SBarry Smith     }
83292c4ed94SBarry Smith     ailen[row] = nrow;
83392c4ed94SBarry Smith   }
8343a40ed3dSBarry Smith   PetscFunctionReturn(0);
83592c4ed94SBarry Smith }
83692c4ed94SBarry Smith 
837f2501298SSatish Balay 
8384a2ae208SSatish Balay #undef __FUNCT__
8394a2ae208SSatish Balay #define __FUNCT__ "MatAssemblyEnd_SeqBAIJ"
8408f6be9afSLois Curfman McInnes int MatAssemblyEnd_SeqBAIJ(Mat A,MatAssemblyType mode)
841584200bdSSatish Balay {
842584200bdSSatish Balay   Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)A->data;
843584200bdSSatish Balay   int        fshift = 0,i,j,*ai = a->i,*aj = a->j,*imax = a->imax;
844273d9f13SBarry Smith   int        m = A->m,*ip,N,*ailen = a->ilen;
845549d3d68SSatish Balay   int        mbs = a->mbs,bs2 = a->bs2,rmax = 0,ierr;
8463f1db9ecSBarry Smith   MatScalar  *aa = a->a,*ap;
847584200bdSSatish Balay 
8483a40ed3dSBarry Smith   PetscFunctionBegin;
8493a40ed3dSBarry Smith   if (mode == MAT_FLUSH_ASSEMBLY) PetscFunctionReturn(0);
850584200bdSSatish Balay 
85143ee02c3SBarry Smith   if (m) rmax = ailen[0];
852584200bdSSatish Balay   for (i=1; i<mbs; i++) {
853584200bdSSatish Balay     /* move each row back by the amount of empty slots (fshift) before it*/
854584200bdSSatish Balay     fshift += imax[i-1] - ailen[i-1];
855d402145bSBarry Smith     rmax   = PetscMax(rmax,ailen[i]);
856584200bdSSatish Balay     if (fshift) {
857a7c10996SSatish Balay       ip = aj + ai[i]; ap = aa + bs2*ai[i];
858584200bdSSatish Balay       N = ailen[i];
859584200bdSSatish Balay       for (j=0; j<N; j++) {
860584200bdSSatish Balay         ip[j-fshift] = ip[j];
861549d3d68SSatish Balay         ierr = PetscMemcpy(ap+(j-fshift)*bs2,ap+j*bs2,bs2*sizeof(MatScalar));CHKERRQ(ierr);
862584200bdSSatish Balay       }
863584200bdSSatish Balay     }
864584200bdSSatish Balay     ai[i] = ai[i-1] + ailen[i-1];
865584200bdSSatish Balay   }
866584200bdSSatish Balay   if (mbs) {
867584200bdSSatish Balay     fshift += imax[mbs-1] - ailen[mbs-1];
868584200bdSSatish Balay     ai[mbs] = ai[mbs-1] + ailen[mbs-1];
869584200bdSSatish Balay   }
870584200bdSSatish Balay   /* reset ilen and imax for each row */
871584200bdSSatish Balay   for (i=0; i<mbs; i++) {
872584200bdSSatish Balay     ailen[i] = imax[i] = ai[i+1] - ai[i];
873584200bdSSatish Balay   }
874a7c10996SSatish Balay   a->nz = ai[mbs];
875584200bdSSatish Balay 
876584200bdSSatish Balay   /* diagonals may have moved, so kill the diagonal pointers */
877584200bdSSatish Balay   if (fshift && a->diag) {
878606d414cSSatish Balay     ierr = PetscFree(a->diag);CHKERRQ(ierr);
879b0a32e0cSBarry Smith     PetscLogObjectMemory(A,-(m+1)*sizeof(int));
880584200bdSSatish Balay     a->diag = 0;
881584200bdSSatish Balay   }
882b0a32e0cSBarry Smith   PetscLogInfo(A,"MatAssemblyEnd_SeqBAIJ:Matrix size: %d X %d, block size %d; storage space: %d unneeded, %d used\n",
883273d9f13SBarry Smith            m,A->n,a->bs,fshift*bs2,a->nz*bs2);
884b0a32e0cSBarry Smith   PetscLogInfo(A,"MatAssemblyEnd_SeqBAIJ:Number of mallocs during MatSetValues is %d\n",
885584200bdSSatish Balay            a->reallocs);
886b0a32e0cSBarry Smith   PetscLogInfo(A,"MatAssemblyEnd_SeqBAIJ:Most nonzeros blocks in any row is %d\n",rmax);
887e2f3b5e9SSatish Balay   a->reallocs          = 0;
8880e6d2581SBarry Smith   A->info.nz_unneeded  = (PetscReal)fshift*bs2;
8894e220ebcSLois Curfman McInnes 
8903a40ed3dSBarry Smith   PetscFunctionReturn(0);
891584200bdSSatish Balay }
892584200bdSSatish Balay 
8935a838052SSatish Balay 
894bea157c4SSatish Balay 
895bea157c4SSatish Balay /*
896bea157c4SSatish Balay    This function returns an array of flags which indicate the locations of contiguous
897bea157c4SSatish Balay    blocks that should be zeroed. for eg: if bs = 3  and is = [0,1,2,3,5,6,7,8,9]
898bea157c4SSatish Balay    then the resulting sizes = [3,1,1,3,1] correspondig to sets [(0,1,2),(3),(5),(6,7,8),(9)]
899bea157c4SSatish Balay    Assume: sizes should be long enough to hold all the values.
900bea157c4SSatish Balay */
9014a2ae208SSatish Balay #undef __FUNCT__
9024a2ae208SSatish Balay #define __FUNCT__ "MatZeroRows_SeqBAIJ_Check_Blocks"
903bea157c4SSatish Balay static int MatZeroRows_SeqBAIJ_Check_Blocks(int idx[],int n,int bs,int sizes[], int *bs_max)
904d9b7c43dSSatish Balay {
905bea157c4SSatish Balay   int        i,j,k,row;
906bea157c4SSatish Balay   PetscTruth flg;
9073a40ed3dSBarry Smith 
908433994e6SBarry Smith   PetscFunctionBegin;
909bea157c4SSatish Balay   for (i=0,j=0; i<n; j++) {
910bea157c4SSatish Balay     row = idx[i];
911bea157c4SSatish Balay     if (row%bs!=0) { /* Not the begining of a block */
912bea157c4SSatish Balay       sizes[j] = 1;
913bea157c4SSatish Balay       i++;
914e4fda26cSSatish Balay     } else if (i+bs > n) { /* complete block doesn't exist (at idx end) */
915bea157c4SSatish Balay       sizes[j] = 1;         /* Also makes sure atleast 'bs' values exist for next else */
916bea157c4SSatish Balay       i++;
917bea157c4SSatish Balay     } else { /* Begining of the block, so check if the complete block exists */
918bea157c4SSatish Balay       flg = PETSC_TRUE;
919bea157c4SSatish Balay       for (k=1; k<bs; k++) {
920bea157c4SSatish Balay         if (row+k != idx[i+k]) { /* break in the block */
921bea157c4SSatish Balay           flg = PETSC_FALSE;
922bea157c4SSatish Balay           break;
923d9b7c43dSSatish Balay         }
924bea157c4SSatish Balay       }
925bea157c4SSatish Balay       if (flg == PETSC_TRUE) { /* No break in the bs */
926bea157c4SSatish Balay         sizes[j] = bs;
927bea157c4SSatish Balay         i+= bs;
928bea157c4SSatish Balay       } else {
929bea157c4SSatish Balay         sizes[j] = 1;
930bea157c4SSatish Balay         i++;
931bea157c4SSatish Balay       }
932bea157c4SSatish Balay     }
933bea157c4SSatish Balay   }
934bea157c4SSatish Balay   *bs_max = j;
9353a40ed3dSBarry Smith   PetscFunctionReturn(0);
936d9b7c43dSSatish Balay }
937d9b7c43dSSatish Balay 
9384a2ae208SSatish Balay #undef __FUNCT__
9394a2ae208SSatish Balay #define __FUNCT__ "MatZeroRows_SeqBAIJ"
9408f6be9afSLois Curfman McInnes int MatZeroRows_SeqBAIJ(Mat A,IS is,Scalar *diag)
941d9b7c43dSSatish Balay {
942d9b7c43dSSatish Balay   Mat_SeqBAIJ *baij=(Mat_SeqBAIJ*)A->data;
943b6815fffSBarry Smith   int         ierr,i,j,k,count,is_n,*is_idx,*rows;
944bea157c4SSatish Balay   int         bs=baij->bs,bs2=baij->bs2,*sizes,row,bs_max;
9453f1db9ecSBarry Smith   Scalar      zero = 0.0;
9463f1db9ecSBarry Smith   MatScalar   *aa;
947d9b7c43dSSatish Balay 
9483a40ed3dSBarry Smith   PetscFunctionBegin;
949d9b7c43dSSatish Balay   /* Make a copy of the IS and  sort it */
950b9b97703SBarry Smith   ierr = ISGetLocalSize(is,&is_n);CHKERRQ(ierr);
951d9b7c43dSSatish Balay   ierr = ISGetIndices(is,&is_idx);CHKERRQ(ierr);
952d9b7c43dSSatish Balay 
953bea157c4SSatish Balay   /* allocate memory for rows,sizes */
954b0a32e0cSBarry Smith   ierr  = PetscMalloc((3*is_n+1)*sizeof(int),&rows);CHKERRQ(ierr);
955bea157c4SSatish Balay   sizes = rows + is_n;
956bea157c4SSatish Balay 
957563b5814SBarry Smith   /* copy IS values to rows, and sort them */
958bea157c4SSatish Balay   for (i=0; i<is_n; i++) { rows[i] = is_idx[i]; }
959bea157c4SSatish Balay   ierr = PetscSortInt(is_n,rows);CHKERRQ(ierr);
960dffd3267SBarry Smith   if (baij->keepzeroedrows) {
961dffd3267SBarry Smith     for (i=0; i<is_n; i++) { sizes[i] = 1; }
962dffd3267SBarry Smith     bs_max = is_n;
963dffd3267SBarry Smith   } else {
964bea157c4SSatish Balay     ierr = MatZeroRows_SeqBAIJ_Check_Blocks(rows,is_n,bs,sizes,&bs_max);CHKERRQ(ierr);
965dffd3267SBarry Smith   }
966b97a56abSSatish Balay   ierr = ISRestoreIndices(is,&is_idx);CHKERRQ(ierr);
967bea157c4SSatish Balay 
968bea157c4SSatish Balay   for (i=0,j=0; i<bs_max; j+=sizes[i],i++) {
969bea157c4SSatish Balay     row   = rows[j];
970273d9f13SBarry Smith     if (row < 0 || row > A->m) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"row %d out of range",row);
971bea157c4SSatish Balay     count = (baij->i[row/bs +1] - baij->i[row/bs])*bs;
972bea157c4SSatish Balay     aa    = baij->a + baij->i[row/bs]*bs2 + (row%bs);
973dffd3267SBarry Smith     if (sizes[i] == bs && !baij->keepzeroedrows) {
974bea157c4SSatish Balay       if (diag) {
975bea157c4SSatish Balay         if (baij->ilen[row/bs] > 0) {
976bea157c4SSatish Balay           baij->ilen[row/bs]       = 1;
977bea157c4SSatish Balay           baij->j[baij->i[row/bs]] = row/bs;
978bea157c4SSatish Balay           ierr = PetscMemzero(aa,count*bs*sizeof(MatScalar));CHKERRQ(ierr);
979a07cd24cSSatish Balay         }
980563b5814SBarry Smith         /* Now insert all the diagonal values for this bs */
981bea157c4SSatish Balay         for (k=0; k<bs; k++) {
982bea157c4SSatish Balay           ierr = (*A->ops->setvalues)(A,1,rows+j+k,1,rows+j+k,diag,INSERT_VALUES);CHKERRQ(ierr);
983bea157c4SSatish Balay         }
984bea157c4SSatish Balay       } else { /* (!diag) */
985bea157c4SSatish Balay         baij->ilen[row/bs] = 0;
986bea157c4SSatish Balay       } /* end (!diag) */
987bea157c4SSatish Balay     } else { /* (sizes[i] != bs) */
988aa482453SBarry Smith #if defined (PETSC_USE_DEBUG)
98929bbc08cSBarry Smith       if (sizes[i] != 1) SETERRQ(1,"Internal Error. Value should be 1");
990bea157c4SSatish Balay #endif
991bea157c4SSatish Balay       for (k=0; k<count; k++) {
992d9b7c43dSSatish Balay         aa[0] =  zero;
993d9b7c43dSSatish Balay         aa    += bs;
994d9b7c43dSSatish Balay       }
995d9b7c43dSSatish Balay       if (diag) {
996f830108cSBarry Smith         ierr = (*A->ops->setvalues)(A,1,rows+j,1,rows+j,diag,INSERT_VALUES);CHKERRQ(ierr);
997d9b7c43dSSatish Balay       }
998d9b7c43dSSatish Balay     }
999bea157c4SSatish Balay   }
1000bea157c4SSatish Balay 
1001606d414cSSatish Balay   ierr = PetscFree(rows);CHKERRQ(ierr);
10029a8dea36SBarry Smith   ierr = MatAssemblyEnd_SeqBAIJ(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
10033a40ed3dSBarry Smith   PetscFunctionReturn(0);
1004d9b7c43dSSatish Balay }
10051c351548SSatish Balay 
10064a2ae208SSatish Balay #undef __FUNCT__
10074a2ae208SSatish Balay #define __FUNCT__ "MatSetValues_SeqBAIJ"
10082d61bbb3SSatish Balay int MatSetValues_SeqBAIJ(Mat A,int m,int *im,int n,int *in,Scalar *v,InsertMode is)
10092d61bbb3SSatish Balay {
10102d61bbb3SSatish Balay   Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)A->data;
10112d61bbb3SSatish Balay   int         *rp,k,low,high,t,ii,row,nrow,i,col,l,rmax,N,sorted=a->sorted;
1012273d9f13SBarry Smith   int         *imax=a->imax,*ai=a->i,*ailen=a->ilen;
10132d61bbb3SSatish Balay   int         *aj=a->j,nonew=a->nonew,bs=a->bs,brow,bcol;
1014549d3d68SSatish Balay   int         ridx,cidx,bs2=a->bs2,ierr;
1015273d9f13SBarry Smith   PetscTruth  roworiented=a->roworiented;
10163f1db9ecSBarry Smith   MatScalar   *ap,value,*aa=a->a,*bap;
10172d61bbb3SSatish Balay 
10182d61bbb3SSatish Balay   PetscFunctionBegin;
10192d61bbb3SSatish Balay   for (k=0; k<m; k++) { /* loop over added rows */
10202d61bbb3SSatish Balay     row  = im[k]; brow = row/bs;
10215ef9f2a5SBarry Smith     if (row < 0) continue;
1022aa482453SBarry Smith #if defined(PETSC_USE_BOPT_g)
1023273d9f13SBarry Smith     if (row >= A->m) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"Row too large: row %d max %d",row,A->m);
10242d61bbb3SSatish Balay #endif
10252d61bbb3SSatish Balay     rp   = aj + ai[brow];
10262d61bbb3SSatish Balay     ap   = aa + bs2*ai[brow];
10272d61bbb3SSatish Balay     rmax = imax[brow];
10282d61bbb3SSatish Balay     nrow = ailen[brow];
10292d61bbb3SSatish Balay     low  = 0;
10302d61bbb3SSatish Balay     for (l=0; l<n; l++) { /* loop over added columns */
10315ef9f2a5SBarry Smith       if (in[l] < 0) continue;
1032aa482453SBarry Smith #if defined(PETSC_USE_BOPT_g)
1033273d9f13SBarry Smith       if (in[l] >= A->n) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"Column too large: col %d max %d",in[l],A->n);
10342d61bbb3SSatish Balay #endif
10352d61bbb3SSatish Balay       col = in[l]; bcol = col/bs;
10362d61bbb3SSatish Balay       ridx = row % bs; cidx = col % bs;
10372d61bbb3SSatish Balay       if (roworiented) {
10385ef9f2a5SBarry Smith         value = v[l + k*n];
10392d61bbb3SSatish Balay       } else {
10402d61bbb3SSatish Balay         value = v[k + l*m];
10412d61bbb3SSatish Balay       }
10422d61bbb3SSatish Balay       if (!sorted) low = 0; high = nrow;
10432d61bbb3SSatish Balay       while (high-low > 7) {
10442d61bbb3SSatish Balay         t = (low+high)/2;
10452d61bbb3SSatish Balay         if (rp[t] > bcol) high = t;
10462d61bbb3SSatish Balay         else              low  = t;
10472d61bbb3SSatish Balay       }
10482d61bbb3SSatish Balay       for (i=low; i<high; i++) {
10492d61bbb3SSatish Balay         if (rp[i] > bcol) break;
10502d61bbb3SSatish Balay         if (rp[i] == bcol) {
10512d61bbb3SSatish Balay           bap  = ap +  bs2*i + bs*cidx + ridx;
10522d61bbb3SSatish Balay           if (is == ADD_VALUES) *bap += value;
10532d61bbb3SSatish Balay           else                  *bap  = value;
10542d61bbb3SSatish Balay           goto noinsert1;
10552d61bbb3SSatish Balay         }
10562d61bbb3SSatish Balay       }
10572d61bbb3SSatish Balay       if (nonew == 1) goto noinsert1;
105829bbc08cSBarry Smith       else if (nonew == -1) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Inserting a new nonzero in the matrix");
10592d61bbb3SSatish Balay       if (nrow >= rmax) {
10602d61bbb3SSatish Balay         /* there is no extra room in row, therefore enlarge */
10612d61bbb3SSatish Balay         int       new_nz = ai[a->mbs] + CHUNKSIZE,len,*new_i,*new_j;
10623f1db9ecSBarry Smith         MatScalar *new_a;
10632d61bbb3SSatish Balay 
106429bbc08cSBarry Smith         if (nonew == -2) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Inserting a new nonzero in the matrix");
10652d61bbb3SSatish Balay 
10662d61bbb3SSatish Balay         /* Malloc new storage space */
10673f1db9ecSBarry Smith         len     = new_nz*(sizeof(int)+bs2*sizeof(MatScalar))+(a->mbs+1)*sizeof(int);
1068b0a32e0cSBarry Smith 	ierr    = PetscMalloc(len,&new_a);CHKERRQ(ierr);
10692d61bbb3SSatish Balay         new_j   = (int*)(new_a + bs2*new_nz);
10702d61bbb3SSatish Balay         new_i   = new_j + new_nz;
10712d61bbb3SSatish Balay 
10722d61bbb3SSatish Balay         /* copy over old data into new slots */
10732d61bbb3SSatish Balay         for (ii=0; ii<brow+1; ii++) {new_i[ii] = ai[ii];}
10742d61bbb3SSatish Balay         for (ii=brow+1; ii<a->mbs+1; ii++) {new_i[ii] = ai[ii]+CHUNKSIZE;}
1075549d3d68SSatish Balay         ierr = PetscMemcpy(new_j,aj,(ai[brow]+nrow)*sizeof(int));CHKERRQ(ierr);
10762d61bbb3SSatish Balay         len  = (new_nz - CHUNKSIZE - ai[brow] - nrow);
1077549d3d68SSatish Balay         ierr = PetscMemcpy(new_j+ai[brow]+nrow+CHUNKSIZE,aj+ai[brow]+nrow,len*sizeof(int));CHKERRQ(ierr);
1078549d3d68SSatish Balay         ierr = PetscMemcpy(new_a,aa,(ai[brow]+nrow)*bs2*sizeof(MatScalar));CHKERRQ(ierr);
1079549d3d68SSatish Balay         ierr = PetscMemzero(new_a+bs2*(ai[brow]+nrow),bs2*CHUNKSIZE*sizeof(MatScalar));CHKERRQ(ierr);
1080549d3d68SSatish Balay         ierr = PetscMemcpy(new_a+bs2*(ai[brow]+nrow+CHUNKSIZE),aa+bs2*(ai[brow]+nrow),bs2*len*sizeof(MatScalar));CHKERRQ(ierr);
10812d61bbb3SSatish Balay         /* free up old matrix storage */
1082606d414cSSatish Balay         ierr = PetscFree(a->a);CHKERRQ(ierr);
1083606d414cSSatish Balay         if (!a->singlemalloc) {
1084606d414cSSatish Balay           ierr = PetscFree(a->i);CHKERRQ(ierr);
1085606d414cSSatish Balay           ierr = PetscFree(a->j);CHKERRQ(ierr);
1086606d414cSSatish Balay         }
10872d61bbb3SSatish Balay         aa = a->a = new_a; ai = a->i = new_i; aj = a->j = new_j;
1088c4992f7dSBarry Smith         a->singlemalloc = PETSC_TRUE;
10892d61bbb3SSatish Balay 
10902d61bbb3SSatish Balay         rp   = aj + ai[brow]; ap = aa + bs2*ai[brow];
10912d61bbb3SSatish Balay         rmax = imax[brow] = imax[brow] + CHUNKSIZE;
1092b0a32e0cSBarry Smith         PetscLogObjectMemory(A,CHUNKSIZE*(sizeof(int) + bs2*sizeof(MatScalar)));
10932d61bbb3SSatish Balay         a->maxnz += bs2*CHUNKSIZE;
10942d61bbb3SSatish Balay         a->reallocs++;
10952d61bbb3SSatish Balay         a->nz++;
10962d61bbb3SSatish Balay       }
10972d61bbb3SSatish Balay       N = nrow++ - 1;
10982d61bbb3SSatish Balay       /* shift up all the later entries in this row */
10992d61bbb3SSatish Balay       for (ii=N; ii>=i; ii--) {
11002d61bbb3SSatish Balay         rp[ii+1] = rp[ii];
1101549d3d68SSatish Balay         ierr     = PetscMemcpy(ap+bs2*(ii+1),ap+bs2*(ii),bs2*sizeof(MatScalar));CHKERRQ(ierr);
11022d61bbb3SSatish Balay       }
1103549d3d68SSatish Balay       if (N>=i) {
1104549d3d68SSatish Balay         ierr = PetscMemzero(ap+bs2*i,bs2*sizeof(MatScalar));CHKERRQ(ierr);
1105549d3d68SSatish Balay       }
11062d61bbb3SSatish Balay       rp[i]                      = bcol;
11072d61bbb3SSatish Balay       ap[bs2*i + bs*cidx + ridx] = value;
11082d61bbb3SSatish Balay       noinsert1:;
11092d61bbb3SSatish Balay       low = i;
11102d61bbb3SSatish Balay     }
11112d61bbb3SSatish Balay     ailen[brow] = nrow;
11122d61bbb3SSatish Balay   }
11132d61bbb3SSatish Balay   PetscFunctionReturn(0);
11142d61bbb3SSatish Balay }
11152d61bbb3SSatish Balay 
11162d61bbb3SSatish Balay 
11174a2ae208SSatish Balay #undef __FUNCT__
11184a2ae208SSatish Balay #define __FUNCT__ "MatILUFactor_SeqBAIJ"
11195ef9f2a5SBarry Smith int MatILUFactor_SeqBAIJ(Mat inA,IS row,IS col,MatILUInfo *info)
11202d61bbb3SSatish Balay {
11212d61bbb3SSatish Balay   Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)inA->data;
11222d61bbb3SSatish Balay   Mat         outA;
11232d61bbb3SSatish Balay   int         ierr;
1124667159a5SBarry Smith   PetscTruth  row_identity,col_identity;
11252d61bbb3SSatish Balay 
11262d61bbb3SSatish Balay   PetscFunctionBegin;
112729bbc08cSBarry Smith   if (info && info->levels != 0) SETERRQ(PETSC_ERR_SUP,"Only levels = 0 supported for in-place ILU");
1128667159a5SBarry Smith   ierr = ISIdentity(row,&row_identity);CHKERRQ(ierr);
1129667159a5SBarry Smith   ierr = ISIdentity(col,&col_identity);CHKERRQ(ierr);
1130667159a5SBarry Smith   if (!row_identity || !col_identity) {
113129bbc08cSBarry Smith     SETERRQ(1,"Row and column permutations must be identity for in-place ILU");
1132667159a5SBarry Smith   }
11332d61bbb3SSatish Balay 
11342d61bbb3SSatish Balay   outA          = inA;
11352d61bbb3SSatish Balay   inA->factor   = FACTOR_LU;
11362d61bbb3SSatish Balay 
11372d61bbb3SSatish Balay   if (!a->diag) {
1138c4992f7dSBarry Smith     ierr = MatMarkDiagonal_SeqBAIJ(inA);CHKERRQ(ierr);
11392d61bbb3SSatish Balay   }
11402d61bbb3SSatish Balay   /*
114115091d37SBarry Smith       Blocksize 2, 3, 4, 5, 6 and 7 have a special faster factorization/solver
114215091d37SBarry Smith       for ILU(0) factorization with natural ordering
11432d61bbb3SSatish Balay   */
11448661488fSKris Buschelman   if (a->bs < 8) {
1145*54138f6bSKris Buschelman     ierr = MatSeqBAIJ_UpdateFactor_NaturalOrdering(inA);CHKERRQ(ierr);
11463477af42SKris Buschelman   } else {
1147c38d4ed2SBarry Smith     a->row        = row;
1148c38d4ed2SBarry Smith     a->col        = col;
1149c38d4ed2SBarry Smith     ierr          = PetscObjectReference((PetscObject)row);CHKERRQ(ierr);
1150c38d4ed2SBarry Smith     ierr          = PetscObjectReference((PetscObject)col);CHKERRQ(ierr);
1151c38d4ed2SBarry Smith 
1152c38d4ed2SBarry Smith     /* Create the invert permutation so that it can be used in MatLUFactorNumeric() */
11534c49b128SBarry Smith     ierr = ISInvertPermutation(col,PETSC_DECIDE,&a->icol);CHKERRQ(ierr);
1154b0a32e0cSBarry Smith     PetscLogObjectParent(inA,a->icol);
1155c38d4ed2SBarry Smith 
1156c38d4ed2SBarry Smith     if (!a->solve_work) {
1157b0a32e0cSBarry Smith       ierr = PetscMalloc((inA->m+a->bs)*sizeof(Scalar),&a->solve_work);CHKERRQ(ierr);
1158b0a32e0cSBarry Smith       PetscLogObjectMemory(inA,(inA->m+a->bs)*sizeof(Scalar));
1159c38d4ed2SBarry Smith     }
11602d61bbb3SSatish Balay   }
11612d61bbb3SSatish Balay 
1162667159a5SBarry Smith   ierr = MatLUFactorNumeric(inA,&outA);CHKERRQ(ierr);
1163667159a5SBarry Smith 
11642d61bbb3SSatish Balay   PetscFunctionReturn(0);
11652d61bbb3SSatish Balay }
11664a2ae208SSatish Balay #undef __FUNCT__
11674a2ae208SSatish Balay #define __FUNCT__ "MatPrintHelp_SeqBAIJ"
1168ba4ca20aSSatish Balay int MatPrintHelp_SeqBAIJ(Mat A)
1169ba4ca20aSSatish Balay {
1170c38d4ed2SBarry Smith   static PetscTruth called = PETSC_FALSE;
1171ba4ca20aSSatish Balay   MPI_Comm          comm = A->comm;
1172d132466eSBarry Smith   int               ierr;
1173ba4ca20aSSatish Balay 
11743a40ed3dSBarry Smith   PetscFunctionBegin;
1175c38d4ed2SBarry Smith   if (called) {PetscFunctionReturn(0);} else called = PETSC_TRUE;
1176d132466eSBarry Smith   ierr = (*PetscHelpPrintf)(comm," Options for MATSEQBAIJ and MATMPIBAIJ matrix formats (the defaults):\n");CHKERRQ(ierr);
1177d132466eSBarry Smith   ierr = (*PetscHelpPrintf)(comm,"  -mat_block_size <block_size>\n");CHKERRQ(ierr);
11783a40ed3dSBarry Smith   PetscFunctionReturn(0);
1179ba4ca20aSSatish Balay }
1180d9b7c43dSSatish Balay 
1181fb2e594dSBarry Smith EXTERN_C_BEGIN
11824a2ae208SSatish Balay #undef __FUNCT__
11834a2ae208SSatish Balay #define __FUNCT__ "MatSeqBAIJSetColumnIndices_SeqBAIJ"
118427a8da17SBarry Smith int MatSeqBAIJSetColumnIndices_SeqBAIJ(Mat mat,int *indices)
118527a8da17SBarry Smith {
118627a8da17SBarry Smith   Mat_SeqBAIJ *baij = (Mat_SeqBAIJ *)mat->data;
118727a8da17SBarry Smith   int         i,nz,n;
118827a8da17SBarry Smith 
118927a8da17SBarry Smith   PetscFunctionBegin;
119027a8da17SBarry Smith   nz = baij->maxnz;
1191273d9f13SBarry Smith   n  = mat->n;
119227a8da17SBarry Smith   for (i=0; i<nz; i++) {
119327a8da17SBarry Smith     baij->j[i] = indices[i];
119427a8da17SBarry Smith   }
119527a8da17SBarry Smith   baij->nz = nz;
119627a8da17SBarry Smith   for (i=0; i<n; i++) {
119727a8da17SBarry Smith     baij->ilen[i] = baij->imax[i];
119827a8da17SBarry Smith   }
119927a8da17SBarry Smith 
120027a8da17SBarry Smith   PetscFunctionReturn(0);
120127a8da17SBarry Smith }
1202fb2e594dSBarry Smith EXTERN_C_END
120327a8da17SBarry Smith 
12044a2ae208SSatish Balay #undef __FUNCT__
12054a2ae208SSatish Balay #define __FUNCT__ "MatSeqBAIJSetColumnIndices"
120627a8da17SBarry Smith /*@
120727a8da17SBarry Smith     MatSeqBAIJSetColumnIndices - Set the column indices for all the rows
120827a8da17SBarry Smith        in the matrix.
120927a8da17SBarry Smith 
121027a8da17SBarry Smith   Input Parameters:
121127a8da17SBarry Smith +  mat - the SeqBAIJ matrix
121227a8da17SBarry Smith -  indices - the column indices
121327a8da17SBarry Smith 
121415091d37SBarry Smith   Level: advanced
121515091d37SBarry Smith 
121627a8da17SBarry Smith   Notes:
121727a8da17SBarry Smith     This can be called if you have precomputed the nonzero structure of the
121827a8da17SBarry Smith   matrix and want to provide it to the matrix object to improve the performance
121927a8da17SBarry Smith   of the MatSetValues() operation.
122027a8da17SBarry Smith 
122127a8da17SBarry Smith     You MUST have set the correct numbers of nonzeros per row in the call to
122227a8da17SBarry Smith   MatCreateSeqBAIJ().
122327a8da17SBarry Smith 
122427a8da17SBarry Smith     MUST be called before any calls to MatSetValues();
122527a8da17SBarry Smith 
122627a8da17SBarry Smith @*/
122727a8da17SBarry Smith int MatSeqBAIJSetColumnIndices(Mat mat,int *indices)
122827a8da17SBarry Smith {
122927a8da17SBarry Smith   int ierr,(*f)(Mat,int *);
123027a8da17SBarry Smith 
123127a8da17SBarry Smith   PetscFunctionBegin;
123227a8da17SBarry Smith   PetscValidHeaderSpecific(mat,MAT_COOKIE);
1233b9617806SBarry Smith   ierr = PetscObjectQueryFunction((PetscObject)mat,"MatSeqBAIJSetColumnIndices_C",(void (**)())&f);CHKERRQ(ierr);
123427a8da17SBarry Smith   if (f) {
123527a8da17SBarry Smith     ierr = (*f)(mat,indices);CHKERRQ(ierr);
123627a8da17SBarry Smith   } else {
123729bbc08cSBarry Smith     SETERRQ(1,"Wrong type of matrix to set column indices");
123827a8da17SBarry Smith   }
123927a8da17SBarry Smith   PetscFunctionReturn(0);
124027a8da17SBarry Smith }
124127a8da17SBarry Smith 
12424a2ae208SSatish Balay #undef __FUNCT__
12434a2ae208SSatish Balay #define __FUNCT__ "MatGetRowMax_SeqBAIJ"
1244273d9f13SBarry Smith int MatGetRowMax_SeqBAIJ(Mat A,Vec v)
1245273d9f13SBarry Smith {
1246273d9f13SBarry Smith   Mat_SeqBAIJ  *a = (Mat_SeqBAIJ*)A->data;
1247273d9f13SBarry Smith   int          ierr,i,j,n,row,bs,*ai,*aj,mbs;
1248273d9f13SBarry Smith   PetscReal    atmp;
1249273d9f13SBarry Smith   Scalar       *x,zero = 0.0;
1250273d9f13SBarry Smith   MatScalar    *aa;
1251273d9f13SBarry Smith   int          ncols,brow,krow,kcol;
1252273d9f13SBarry Smith 
1253273d9f13SBarry Smith   PetscFunctionBegin;
1254273d9f13SBarry Smith   if (A->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1255273d9f13SBarry Smith   bs   = a->bs;
1256273d9f13SBarry Smith   aa   = a->a;
1257273d9f13SBarry Smith   ai   = a->i;
1258273d9f13SBarry Smith   aj   = a->j;
1259273d9f13SBarry Smith   mbs = a->mbs;
1260273d9f13SBarry Smith 
1261273d9f13SBarry Smith   ierr = VecSet(&zero,v);CHKERRQ(ierr);
1262273d9f13SBarry Smith   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
1263273d9f13SBarry Smith   ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr);
1264273d9f13SBarry Smith   if (n != A->m) SETERRQ(PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector");
1265273d9f13SBarry Smith   for (i=0; i<mbs; i++) {
1266273d9f13SBarry Smith     ncols = ai[1] - ai[0]; ai++;
1267273d9f13SBarry Smith     brow  = bs*i;
1268273d9f13SBarry Smith     for (j=0; j<ncols; j++){
1269273d9f13SBarry Smith       /* bcol = bs*(*aj); */
1270273d9f13SBarry Smith       for (kcol=0; kcol<bs; kcol++){
1271273d9f13SBarry Smith         for (krow=0; krow<bs; krow++){
1272273d9f13SBarry Smith           atmp = PetscAbsScalar(*aa); aa++;
1273273d9f13SBarry Smith           row = brow + krow;    /* row index */
1274273d9f13SBarry Smith           /* printf("val[%d,%d]: %g\n",row,bcol+kcol,atmp); */
1275273d9f13SBarry Smith           if (PetscAbsScalar(x[row]) < atmp) x[row] = atmp;
1276273d9f13SBarry Smith         }
1277273d9f13SBarry Smith       }
1278273d9f13SBarry Smith       aj++;
1279273d9f13SBarry Smith     }
1280273d9f13SBarry Smith   }
1281273d9f13SBarry Smith   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
1282273d9f13SBarry Smith   PetscFunctionReturn(0);
1283273d9f13SBarry Smith }
1284273d9f13SBarry Smith 
12854a2ae208SSatish Balay #undef __FUNCT__
12864a2ae208SSatish Balay #define __FUNCT__ "MatSetUpPreallocation_SeqBAIJ"
1287273d9f13SBarry Smith int MatSetUpPreallocation_SeqBAIJ(Mat A)
1288273d9f13SBarry Smith {
1289273d9f13SBarry Smith   int        ierr;
1290273d9f13SBarry Smith 
1291273d9f13SBarry Smith   PetscFunctionBegin;
1292273d9f13SBarry Smith   ierr =  MatSeqBAIJSetPreallocation(A,1,PETSC_DEFAULT,0);CHKERRQ(ierr);
1293273d9f13SBarry Smith   PetscFunctionReturn(0);
1294273d9f13SBarry Smith }
1295273d9f13SBarry Smith 
12964a2ae208SSatish Balay #undef __FUNCT__
12974a2ae208SSatish Balay #define __FUNCT__ "MatGetArray_SeqBAIJ"
1298f2a5309cSSatish Balay int MatGetArray_SeqBAIJ(Mat A,Scalar **array)
1299f2a5309cSSatish Balay {
1300f2a5309cSSatish Balay   Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)A->data;
1301f2a5309cSSatish Balay   PetscFunctionBegin;
1302f2a5309cSSatish Balay   *array = a->a;
1303f2a5309cSSatish Balay   PetscFunctionReturn(0);
1304f2a5309cSSatish Balay }
1305f2a5309cSSatish Balay 
13064a2ae208SSatish Balay #undef __FUNCT__
13074a2ae208SSatish Balay #define __FUNCT__ "MatRestoreArray_SeqBAIJ"
1308f2a5309cSSatish Balay int MatRestoreArray_SeqBAIJ(Mat A,Scalar **array)
1309f2a5309cSSatish Balay {
1310f2a5309cSSatish Balay   PetscFunctionBegin;
1311f2a5309cSSatish Balay   PetscFunctionReturn(0);
1312f2a5309cSSatish Balay }
1313f2a5309cSSatish Balay 
13142593348eSBarry Smith /* -------------------------------------------------------------------*/
1315cc2dc46cSBarry Smith static struct _MatOps MatOps_Values = {MatSetValues_SeqBAIJ,
1316cc2dc46cSBarry Smith        MatGetRow_SeqBAIJ,
1317cc2dc46cSBarry Smith        MatRestoreRow_SeqBAIJ,
1318cc2dc46cSBarry Smith        MatMult_SeqBAIJ_N,
1319cc2dc46cSBarry Smith        MatMultAdd_SeqBAIJ_N,
13207c922b88SBarry Smith        MatMultTranspose_SeqBAIJ,
13217c922b88SBarry Smith        MatMultTransposeAdd_SeqBAIJ,
1322cc2dc46cSBarry Smith        MatSolve_SeqBAIJ_N,
1323cc2dc46cSBarry Smith        0,
1324cc2dc46cSBarry Smith        0,
1325cc2dc46cSBarry Smith        0,
1326cc2dc46cSBarry Smith        MatLUFactor_SeqBAIJ,
1327cc2dc46cSBarry Smith        0,
1328b6490206SBarry Smith        0,
1329f2501298SSatish Balay        MatTranspose_SeqBAIJ,
1330cc2dc46cSBarry Smith        MatGetInfo_SeqBAIJ,
1331cc2dc46cSBarry Smith        MatEqual_SeqBAIJ,
1332cc2dc46cSBarry Smith        MatGetDiagonal_SeqBAIJ,
1333cc2dc46cSBarry Smith        MatDiagonalScale_SeqBAIJ,
1334cc2dc46cSBarry Smith        MatNorm_SeqBAIJ,
1335b6490206SBarry Smith        0,
1336cc2dc46cSBarry Smith        MatAssemblyEnd_SeqBAIJ,
1337cc2dc46cSBarry Smith        0,
1338cc2dc46cSBarry Smith        MatSetOption_SeqBAIJ,
1339cc2dc46cSBarry Smith        MatZeroEntries_SeqBAIJ,
1340cc2dc46cSBarry Smith        MatZeroRows_SeqBAIJ,
1341cc2dc46cSBarry Smith        MatLUFactorSymbolic_SeqBAIJ,
1342cc2dc46cSBarry Smith        MatLUFactorNumeric_SeqBAIJ_N,
1343cc2dc46cSBarry Smith        0,
1344cc2dc46cSBarry Smith        0,
1345273d9f13SBarry Smith        MatSetUpPreallocation_SeqBAIJ,
1346273d9f13SBarry Smith        0,
1347cc2dc46cSBarry Smith        MatGetOwnershipRange_SeqBAIJ,
1348cc2dc46cSBarry Smith        MatILUFactorSymbolic_SeqBAIJ,
1349cc2dc46cSBarry Smith        0,
1350f2a5309cSSatish Balay        MatGetArray_SeqBAIJ,
1351f2a5309cSSatish Balay        MatRestoreArray_SeqBAIJ,
13522e8a6d31SBarry Smith        MatDuplicate_SeqBAIJ,
1353cc2dc46cSBarry Smith        0,
1354cc2dc46cSBarry Smith        0,
1355cc2dc46cSBarry Smith        MatILUFactor_SeqBAIJ,
1356cc2dc46cSBarry Smith        0,
1357cc2dc46cSBarry Smith        0,
1358cc2dc46cSBarry Smith        MatGetSubMatrices_SeqBAIJ,
1359cc2dc46cSBarry Smith        MatIncreaseOverlap_SeqBAIJ,
1360cc2dc46cSBarry Smith        MatGetValues_SeqBAIJ,
1361cc2dc46cSBarry Smith        0,
1362cc2dc46cSBarry Smith        MatPrintHelp_SeqBAIJ,
1363cc2dc46cSBarry Smith        MatScale_SeqBAIJ,
1364cc2dc46cSBarry Smith        0,
1365cc2dc46cSBarry Smith        0,
1366cc2dc46cSBarry Smith        0,
1367cc2dc46cSBarry Smith        MatGetBlockSize_SeqBAIJ,
13683b2fbd54SBarry Smith        MatGetRowIJ_SeqBAIJ,
136992c4ed94SBarry Smith        MatRestoreRowIJ_SeqBAIJ,
1370cc2dc46cSBarry Smith        0,
1371cc2dc46cSBarry Smith        0,
1372cc2dc46cSBarry Smith        0,
1373cc2dc46cSBarry Smith        0,
1374cc2dc46cSBarry Smith        0,
1375cc2dc46cSBarry Smith        0,
1376d3825aa8SBarry Smith        MatSetValuesBlocked_SeqBAIJ,
1377cc2dc46cSBarry Smith        MatGetSubMatrix_SeqBAIJ,
1378b9b97703SBarry Smith        MatDestroy_SeqBAIJ,
1379b9b97703SBarry Smith        MatView_SeqBAIJ,
1380273d9f13SBarry Smith        MatGetMaps_Petsc,
1381273d9f13SBarry Smith        0,
1382273d9f13SBarry Smith        0,
1383273d9f13SBarry Smith        0,
1384273d9f13SBarry Smith        0,
1385273d9f13SBarry Smith        0,
1386273d9f13SBarry Smith        0,
1387273d9f13SBarry Smith        MatGetRowMax_SeqBAIJ,
1388273d9f13SBarry Smith        MatConvert_Basic};
13892593348eSBarry Smith 
13903e90b805SBarry Smith EXTERN_C_BEGIN
13914a2ae208SSatish Balay #undef __FUNCT__
13924a2ae208SSatish Balay #define __FUNCT__ "MatStoreValues_SeqBAIJ"
13933e90b805SBarry Smith int MatStoreValues_SeqBAIJ(Mat mat)
13943e90b805SBarry Smith {
13953e90b805SBarry Smith   Mat_SeqBAIJ *aij = (Mat_SeqBAIJ *)mat->data;
1396273d9f13SBarry Smith   int         nz = aij->i[mat->m]*aij->bs*aij->bs2;
1397d132466eSBarry Smith   int         ierr;
13983e90b805SBarry Smith 
13993e90b805SBarry Smith   PetscFunctionBegin;
14003e90b805SBarry Smith   if (aij->nonew != 1) {
140129bbc08cSBarry Smith     SETERRQ(1,"Must call MatSetOption(A,MAT_NO_NEW_NONZERO_LOCATIONS);first");
14023e90b805SBarry Smith   }
14033e90b805SBarry Smith 
14043e90b805SBarry Smith   /* allocate space for values if not already there */
14053e90b805SBarry Smith   if (!aij->saved_values) {
1406f2a5309cSSatish Balay     ierr = PetscMalloc((nz+1)*sizeof(Scalar),&aij->saved_values);CHKERRQ(ierr);
14073e90b805SBarry Smith   }
14083e90b805SBarry Smith 
14093e90b805SBarry Smith   /* copy values over */
1410d132466eSBarry Smith   ierr = PetscMemcpy(aij->saved_values,aij->a,nz*sizeof(Scalar));CHKERRQ(ierr);
14113e90b805SBarry Smith   PetscFunctionReturn(0);
14123e90b805SBarry Smith }
14133e90b805SBarry Smith EXTERN_C_END
14143e90b805SBarry Smith 
14153e90b805SBarry Smith EXTERN_C_BEGIN
14164a2ae208SSatish Balay #undef __FUNCT__
14174a2ae208SSatish Balay #define __FUNCT__ "MatRetrieveValues_SeqBAIJ"
141832e87ba3SBarry Smith int MatRetrieveValues_SeqBAIJ(Mat mat)
14193e90b805SBarry Smith {
14203e90b805SBarry Smith   Mat_SeqBAIJ *aij = (Mat_SeqBAIJ *)mat->data;
1421273d9f13SBarry Smith   int         nz = aij->i[mat->m]*aij->bs*aij->bs2,ierr;
14223e90b805SBarry Smith 
14233e90b805SBarry Smith   PetscFunctionBegin;
14243e90b805SBarry Smith   if (aij->nonew != 1) {
142529bbc08cSBarry Smith     SETERRQ(1,"Must call MatSetOption(A,MAT_NO_NEW_NONZERO_LOCATIONS);first");
14263e90b805SBarry Smith   }
14273e90b805SBarry Smith   if (!aij->saved_values) {
142829bbc08cSBarry Smith     SETERRQ(1,"Must call MatStoreValues(A);first");
14293e90b805SBarry Smith   }
14303e90b805SBarry Smith 
14313e90b805SBarry Smith   /* copy values over */
1432549d3d68SSatish Balay   ierr = PetscMemcpy(aij->a,aij->saved_values,nz*sizeof(Scalar));CHKERRQ(ierr);
14333e90b805SBarry Smith   PetscFunctionReturn(0);
14343e90b805SBarry Smith }
14353e90b805SBarry Smith EXTERN_C_END
14363e90b805SBarry Smith 
1437273d9f13SBarry Smith EXTERN_C_BEGIN
1438273d9f13SBarry Smith extern int MatConvert_SeqBAIJ_SeqAIJ(Mat,MatType,Mat*);
1439273d9f13SBarry Smith EXTERN_C_END
1440273d9f13SBarry Smith 
1441273d9f13SBarry Smith EXTERN_C_BEGIN
14424a2ae208SSatish Balay #undef __FUNCT__
14434a2ae208SSatish Balay #define __FUNCT__ "MatCreate_SeqBAIJ"
1444273d9f13SBarry Smith int MatCreate_SeqBAIJ(Mat B)
14452593348eSBarry Smith {
1446273d9f13SBarry Smith   int         ierr,size;
1447b6490206SBarry Smith   Mat_SeqBAIJ *b;
14483b2fbd54SBarry Smith 
14493a40ed3dSBarry Smith   PetscFunctionBegin;
1450273d9f13SBarry Smith   ierr = MPI_Comm_size(B->comm,&size);CHKERRQ(ierr);
145129bbc08cSBarry Smith   if (size > 1) SETERRQ(PETSC_ERR_ARG_WRONG,"Comm must be of size 1");
1452b6490206SBarry Smith 
1453273d9f13SBarry Smith   B->m = B->M = PetscMax(B->m,B->M);
1454273d9f13SBarry Smith   B->n = B->N = PetscMax(B->n,B->N);
1455b0a32e0cSBarry Smith   ierr    = PetscNew(Mat_SeqBAIJ,&b);CHKERRQ(ierr);
1456b0a32e0cSBarry Smith   B->data = (void*)b;
1457549d3d68SSatish Balay   ierr    = PetscMemzero(b,sizeof(Mat_SeqBAIJ));CHKERRQ(ierr);
1458549d3d68SSatish Balay   ierr    = PetscMemcpy(B->ops,&MatOps_Values,sizeof(struct _MatOps));CHKERRQ(ierr);
14592593348eSBarry Smith   B->factor           = 0;
14602593348eSBarry Smith   B->lupivotthreshold = 1.0;
146190f02eecSBarry Smith   B->mapping          = 0;
14622593348eSBarry Smith   b->row              = 0;
14632593348eSBarry Smith   b->col              = 0;
1464e51c0b9cSSatish Balay   b->icol             = 0;
14652593348eSBarry Smith   b->reallocs         = 0;
14663e90b805SBarry Smith   b->saved_values     = 0;
1467cfce73b9SSatish Balay #if defined(PETSC_USE_MAT_SINGLE)
1468563b5814SBarry Smith   b->setvalueslen     = 0;
1469563b5814SBarry Smith   b->setvaluescopy    = PETSC_NULL;
1470563b5814SBarry Smith #endif
14718661488fSKris Buschelman   b->single_precision_solves = PETSC_FALSE;
14722593348eSBarry Smith 
1473273d9f13SBarry Smith   ierr = MapCreateMPI(B->comm,B->m,B->m,&B->rmap);CHKERRQ(ierr);
1474273d9f13SBarry Smith   ierr = MapCreateMPI(B->comm,B->n,B->n,&B->cmap);CHKERRQ(ierr);
1475a5ae1ecdSBarry Smith 
1476c4992f7dSBarry Smith   b->sorted           = PETSC_FALSE;
1477c4992f7dSBarry Smith   b->roworiented      = PETSC_TRUE;
14782593348eSBarry Smith   b->nonew            = 0;
14792593348eSBarry Smith   b->diag             = 0;
14802593348eSBarry Smith   b->solve_work       = 0;
1481de6a44a3SBarry Smith   b->mult_work        = 0;
14822593348eSBarry Smith   b->spptr            = 0;
14830e6d2581SBarry Smith   B->info.nz_unneeded = (PetscReal)b->maxnz;
1484883fce79SBarry Smith   b->keepzeroedrows   = PETSC_FALSE;
14854e220ebcSLois Curfman McInnes 
1486f1af5d2fSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatStoreValues_C",
14873e90b805SBarry Smith                                      "MatStoreValues_SeqBAIJ",
1488bc4b532fSSatish Balay                                       MatStoreValues_SeqBAIJ);CHKERRQ(ierr);
1489f1af5d2fSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatRetrieveValues_C",
14903e90b805SBarry Smith                                      "MatRetrieveValues_SeqBAIJ",
1491bc4b532fSSatish Balay                                       MatRetrieveValues_SeqBAIJ);CHKERRQ(ierr);
1492f1af5d2fSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatSeqBAIJSetColumnIndices_C",
149327a8da17SBarry Smith                                      "MatSeqBAIJSetColumnIndices_SeqBAIJ",
1494bc4b532fSSatish Balay                                       MatSeqBAIJSetColumnIndices_SeqBAIJ);CHKERRQ(ierr);
1495273d9f13SBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatConvert_SeqBAIJ_SeqAIJ_C",
1496273d9f13SBarry Smith                                      "MatConvert_SeqBAIJ_SeqAIJ",
1497273d9f13SBarry Smith                                       MatConvert_SeqBAIJ_SeqAIJ);CHKERRQ(ierr);
14983a40ed3dSBarry Smith   PetscFunctionReturn(0);
14992593348eSBarry Smith }
1500273d9f13SBarry Smith EXTERN_C_END
15012593348eSBarry Smith 
15024a2ae208SSatish Balay #undef __FUNCT__
15034a2ae208SSatish Balay #define __FUNCT__ "MatDuplicate_SeqBAIJ"
15042e8a6d31SBarry Smith int MatDuplicate_SeqBAIJ(Mat A,MatDuplicateOption cpvalues,Mat *B)
15052593348eSBarry Smith {
15062593348eSBarry Smith   Mat         C;
1507b6490206SBarry Smith   Mat_SeqBAIJ *c,*a = (Mat_SeqBAIJ*)A->data;
150827a8da17SBarry Smith   int         i,len,mbs = a->mbs,nz = a->nz,bs2 =a->bs2,ierr;
1509de6a44a3SBarry Smith 
15103a40ed3dSBarry Smith   PetscFunctionBegin;
151129bbc08cSBarry Smith   if (a->i[mbs] != nz) SETERRQ(PETSC_ERR_PLIB,"Corrupt matrix");
15122593348eSBarry Smith 
15132593348eSBarry Smith   *B = 0;
1514273d9f13SBarry Smith   ierr = MatCreate(A->comm,A->m,A->n,A->m,A->n,&C);CHKERRQ(ierr);
1515273d9f13SBarry Smith   ierr = MatSetType(C,MATSEQBAIJ);CHKERRQ(ierr);
1516273d9f13SBarry Smith   c    = (Mat_SeqBAIJ*)C->data;
151744cd7ae7SLois Curfman McInnes 
1518b6490206SBarry Smith   c->bs         = a->bs;
15199df24120SSatish Balay   c->bs2        = a->bs2;
1520b6490206SBarry Smith   c->mbs        = a->mbs;
1521b6490206SBarry Smith   c->nbs        = a->nbs;
152235d8aa7fSBarry Smith   ierr = PetscMemcpy(C->ops,A->ops,sizeof(struct _MatOps));CHKERRQ(ierr);
15232593348eSBarry Smith 
1524b0a32e0cSBarry Smith   ierr = PetscMalloc((mbs+1)*sizeof(int),&c->imax);CHKERRQ(ierr);
1525b0a32e0cSBarry Smith   ierr = PetscMalloc((mbs+1)*sizeof(int),&c->ilen);CHKERRQ(ierr);
1526b6490206SBarry Smith   for (i=0; i<mbs; i++) {
15272593348eSBarry Smith     c->imax[i] = a->imax[i];
15282593348eSBarry Smith     c->ilen[i] = a->ilen[i];
15292593348eSBarry Smith   }
15302593348eSBarry Smith 
15312593348eSBarry Smith   /* allocate the matrix space */
1532c4992f7dSBarry Smith   c->singlemalloc = PETSC_TRUE;
15333f1db9ecSBarry Smith   len  = (mbs+1)*sizeof(int) + nz*(bs2*sizeof(MatScalar) + sizeof(int));
1534b0a32e0cSBarry Smith   ierr = PetscMalloc(len,&c->a);CHKERRQ(ierr);
15357e67e3f9SSatish Balay   c->j = (int*)(c->a + nz*bs2);
1536de6a44a3SBarry Smith   c->i = c->j + nz;
1537549d3d68SSatish Balay   ierr = PetscMemcpy(c->i,a->i,(mbs+1)*sizeof(int));CHKERRQ(ierr);
1538b6490206SBarry Smith   if (mbs > 0) {
1539549d3d68SSatish Balay     ierr = PetscMemcpy(c->j,a->j,nz*sizeof(int));CHKERRQ(ierr);
15402e8a6d31SBarry Smith     if (cpvalues == MAT_COPY_VALUES) {
1541549d3d68SSatish Balay       ierr = PetscMemcpy(c->a,a->a,bs2*nz*sizeof(MatScalar));CHKERRQ(ierr);
15422e8a6d31SBarry Smith     } else {
1543549d3d68SSatish Balay       ierr = PetscMemzero(c->a,bs2*nz*sizeof(MatScalar));CHKERRQ(ierr);
15442593348eSBarry Smith     }
15452593348eSBarry Smith   }
15462593348eSBarry Smith 
1547b0a32e0cSBarry Smith   PetscLogObjectMemory(C,len+2*(mbs+1)*sizeof(int)+sizeof(struct _p_Mat)+sizeof(Mat_SeqBAIJ));
15482593348eSBarry Smith   c->sorted      = a->sorted;
15492593348eSBarry Smith   c->roworiented = a->roworiented;
15502593348eSBarry Smith   c->nonew       = a->nonew;
15512593348eSBarry Smith 
15522593348eSBarry Smith   if (a->diag) {
1553b0a32e0cSBarry Smith     ierr = PetscMalloc((mbs+1)*sizeof(int),&c->diag);CHKERRQ(ierr);
1554b0a32e0cSBarry Smith     PetscLogObjectMemory(C,(mbs+1)*sizeof(int));
1555b6490206SBarry Smith     for (i=0; i<mbs; i++) {
15562593348eSBarry Smith       c->diag[i] = a->diag[i];
15572593348eSBarry Smith     }
155898305bb5SBarry Smith   } else c->diag        = 0;
15592593348eSBarry Smith   c->nz                 = a->nz;
15602593348eSBarry Smith   c->maxnz              = a->maxnz;
15612593348eSBarry Smith   c->solve_work         = 0;
15622593348eSBarry Smith   c->spptr              = 0;      /* Dangerous -I'm throwing away a->spptr */
15637fc0212eSBarry Smith   c->mult_work          = 0;
1564273d9f13SBarry Smith   C->preallocated       = PETSC_TRUE;
1565273d9f13SBarry Smith   C->assembled          = PETSC_TRUE;
15662593348eSBarry Smith   *B = C;
1567b0a32e0cSBarry Smith   ierr = PetscFListDuplicate(A->qlist,&C->qlist);CHKERRQ(ierr);
15683a40ed3dSBarry Smith   PetscFunctionReturn(0);
15692593348eSBarry Smith }
15702593348eSBarry Smith 
1571273d9f13SBarry Smith EXTERN_C_BEGIN
15724a2ae208SSatish Balay #undef __FUNCT__
15734a2ae208SSatish Balay #define __FUNCT__ "MatLoad_SeqBAIJ"
1574b0a32e0cSBarry Smith int MatLoad_SeqBAIJ(PetscViewer viewer,MatType type,Mat *A)
15752593348eSBarry Smith {
1576b6490206SBarry Smith   Mat_SeqBAIJ  *a;
15772593348eSBarry Smith   Mat          B;
1578f1af5d2fSBarry Smith   int          i,nz,ierr,fd,header[4],size,*rowlengths=0,M,N,bs=1;
1579b6490206SBarry Smith   int          *mask,mbs,*jj,j,rowcount,nzcount,k,*browlengths,maskcount;
158035aab85fSBarry Smith   int          kmax,jcount,block,idx,point,nzcountb,extra_rows;
1581a7c10996SSatish Balay   int          *masked,nmask,tmp,bs2,ishift;
1582b6490206SBarry Smith   Scalar       *aa;
158319bcc07fSBarry Smith   MPI_Comm     comm = ((PetscObject)viewer)->comm;
15842593348eSBarry Smith 
15853a40ed3dSBarry Smith   PetscFunctionBegin;
1586b0a32e0cSBarry Smith   ierr = PetscOptionsGetInt(PETSC_NULL,"-matload_block_size",&bs,PETSC_NULL);CHKERRQ(ierr);
1587de6a44a3SBarry Smith   bs2  = bs*bs;
1588b6490206SBarry Smith 
1589d132466eSBarry Smith   ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr);
159029bbc08cSBarry Smith   if (size > 1) SETERRQ(PETSC_ERR_ARG_WRONG,"view must have one processor");
1591b0a32e0cSBarry Smith   ierr = PetscViewerBinaryGetDescriptor(viewer,&fd);CHKERRQ(ierr);
15920752156aSBarry Smith   ierr = PetscBinaryRead(fd,header,4,PETSC_INT);CHKERRQ(ierr);
159329bbc08cSBarry Smith   if (header[0] != MAT_COOKIE) SETERRQ(PETSC_ERR_FILE_UNEXPECTED,"not Mat object");
15942593348eSBarry Smith   M = header[1]; N = header[2]; nz = header[3];
15952593348eSBarry Smith 
1596d64ed03dSBarry Smith   if (header[3] < 0) {
159729bbc08cSBarry Smith     SETERRQ(PETSC_ERR_FILE_UNEXPECTED,"Matrix stored in special format, cannot load as SeqBAIJ");
1598d64ed03dSBarry Smith   }
1599d64ed03dSBarry Smith 
160029bbc08cSBarry Smith   if (M != N) SETERRQ(PETSC_ERR_SUP,"Can only do square matrices");
160135aab85fSBarry Smith 
160235aab85fSBarry Smith   /*
160335aab85fSBarry Smith      This code adds extra rows to make sure the number of rows is
160435aab85fSBarry Smith     divisible by the blocksize
160535aab85fSBarry Smith   */
1606b6490206SBarry Smith   mbs        = M/bs;
160735aab85fSBarry Smith   extra_rows = bs - M + bs*(mbs);
160835aab85fSBarry Smith   if (extra_rows == bs) extra_rows = 0;
160935aab85fSBarry Smith   else                  mbs++;
161035aab85fSBarry Smith   if (extra_rows) {
1611b0a32e0cSBarry Smith     PetscLogInfo(0,"MatLoad_SeqBAIJ:Padding loaded matrix to match blocksize\n");
161235aab85fSBarry Smith   }
1613b6490206SBarry Smith 
16142593348eSBarry Smith   /* read in row lengths */
1615b0a32e0cSBarry Smith   ierr = PetscMalloc((M+extra_rows)*sizeof(int),&rowlengths);CHKERRQ(ierr);
16160752156aSBarry Smith   ierr = PetscBinaryRead(fd,rowlengths,M,PETSC_INT);CHKERRQ(ierr);
161735aab85fSBarry Smith   for (i=0; i<extra_rows; i++) rowlengths[M+i] = 1;
16182593348eSBarry Smith 
1619b6490206SBarry Smith   /* read in column indices */
1620b0a32e0cSBarry Smith   ierr = PetscMalloc((nz+extra_rows)*sizeof(int),&jj);CHKERRQ(ierr);
16210752156aSBarry Smith   ierr = PetscBinaryRead(fd,jj,nz,PETSC_INT);CHKERRQ(ierr);
162235aab85fSBarry Smith   for (i=0; i<extra_rows; i++) jj[nz+i] = M+i;
1623b6490206SBarry Smith 
1624b6490206SBarry Smith   /* loop over row lengths determining block row lengths */
1625b0a32e0cSBarry Smith   ierr     = PetscMalloc(mbs*sizeof(int),&browlengths);CHKERRQ(ierr);
1626549d3d68SSatish Balay   ierr     = PetscMemzero(browlengths,mbs*sizeof(int));CHKERRQ(ierr);
1627b0a32e0cSBarry Smith   ierr     = PetscMalloc(2*mbs*sizeof(int),&mask);CHKERRQ(ierr);
1628549d3d68SSatish Balay   ierr     = PetscMemzero(mask,mbs*sizeof(int));CHKERRQ(ierr);
162935aab85fSBarry Smith   masked   = mask + mbs;
1630b6490206SBarry Smith   rowcount = 0; nzcount = 0;
1631b6490206SBarry Smith   for (i=0; i<mbs; i++) {
163235aab85fSBarry Smith     nmask = 0;
1633b6490206SBarry Smith     for (j=0; j<bs; j++) {
1634b6490206SBarry Smith       kmax = rowlengths[rowcount];
1635b6490206SBarry Smith       for (k=0; k<kmax; k++) {
163635aab85fSBarry Smith         tmp = jj[nzcount++]/bs;
163735aab85fSBarry Smith         if (!mask[tmp]) {masked[nmask++] = tmp; mask[tmp] = 1;}
1638b6490206SBarry Smith       }
1639b6490206SBarry Smith       rowcount++;
1640b6490206SBarry Smith     }
164135aab85fSBarry Smith     browlengths[i] += nmask;
164235aab85fSBarry Smith     /* zero out the mask elements we set */
164335aab85fSBarry Smith     for (j=0; j<nmask; j++) mask[masked[j]] = 0;
1644b6490206SBarry Smith   }
1645b6490206SBarry Smith 
16462593348eSBarry Smith   /* create our matrix */
16473eee16b0SBarry Smith   ierr = MatCreateSeqBAIJ(comm,bs,M+extra_rows,N+extra_rows,0,browlengths,A);CHKERRQ(ierr);
16482593348eSBarry Smith   B = *A;
1649b6490206SBarry Smith   a = (Mat_SeqBAIJ*)B->data;
16502593348eSBarry Smith 
16512593348eSBarry Smith   /* set matrix "i" values */
1652de6a44a3SBarry Smith   a->i[0] = 0;
1653b6490206SBarry Smith   for (i=1; i<= mbs; i++) {
1654b6490206SBarry Smith     a->i[i]      = a->i[i-1] + browlengths[i-1];
1655b6490206SBarry Smith     a->ilen[i-1] = browlengths[i-1];
16562593348eSBarry Smith   }
1657b6490206SBarry Smith   a->nz         = 0;
1658b6490206SBarry Smith   for (i=0; i<mbs; i++) a->nz += browlengths[i];
16592593348eSBarry Smith 
1660b6490206SBarry Smith   /* read in nonzero values */
1661b0a32e0cSBarry Smith   ierr = PetscMalloc((nz+extra_rows)*sizeof(Scalar),&aa);CHKERRQ(ierr);
16620752156aSBarry Smith   ierr = PetscBinaryRead(fd,aa,nz,PETSC_SCALAR);CHKERRQ(ierr);
166335aab85fSBarry Smith   for (i=0; i<extra_rows; i++) aa[nz+i] = 1.0;
1664b6490206SBarry Smith 
1665b6490206SBarry Smith   /* set "a" and "j" values into matrix */
1666b6490206SBarry Smith   nzcount = 0; jcount = 0;
1667b6490206SBarry Smith   for (i=0; i<mbs; i++) {
1668b6490206SBarry Smith     nzcountb = nzcount;
166935aab85fSBarry Smith     nmask    = 0;
1670b6490206SBarry Smith     for (j=0; j<bs; j++) {
1671b6490206SBarry Smith       kmax = rowlengths[i*bs+j];
1672b6490206SBarry Smith       for (k=0; k<kmax; k++) {
167335aab85fSBarry Smith         tmp = jj[nzcount++]/bs;
167435aab85fSBarry Smith 	if (!mask[tmp]) { masked[nmask++] = tmp; mask[tmp] = 1;}
1675b6490206SBarry Smith       }
1676b6490206SBarry Smith     }
1677de6a44a3SBarry Smith     /* sort the masked values */
1678433994e6SBarry Smith     ierr = PetscSortInt(nmask,masked);CHKERRQ(ierr);
1679de6a44a3SBarry Smith 
1680b6490206SBarry Smith     /* set "j" values into matrix */
1681b6490206SBarry Smith     maskcount = 1;
168235aab85fSBarry Smith     for (j=0; j<nmask; j++) {
168335aab85fSBarry Smith       a->j[jcount++]  = masked[j];
1684de6a44a3SBarry Smith       mask[masked[j]] = maskcount++;
1685b6490206SBarry Smith     }
1686b6490206SBarry Smith     /* set "a" values into matrix */
1687de6a44a3SBarry Smith     ishift = bs2*a->i[i];
1688b6490206SBarry Smith     for (j=0; j<bs; j++) {
1689b6490206SBarry Smith       kmax = rowlengths[i*bs+j];
1690b6490206SBarry Smith       for (k=0; k<kmax; k++) {
1691de6a44a3SBarry Smith         tmp       = jj[nzcountb]/bs ;
1692de6a44a3SBarry Smith         block     = mask[tmp] - 1;
1693de6a44a3SBarry Smith         point     = jj[nzcountb] - bs*tmp;
1694de6a44a3SBarry Smith         idx       = ishift + bs2*block + j + bs*point;
1695375fe846SBarry Smith         a->a[idx] = (MatScalar)aa[nzcountb++];
1696b6490206SBarry Smith       }
1697b6490206SBarry Smith     }
169835aab85fSBarry Smith     /* zero out the mask elements we set */
169935aab85fSBarry Smith     for (j=0; j<nmask; j++) mask[masked[j]] = 0;
1700b6490206SBarry Smith   }
170129bbc08cSBarry Smith   if (jcount != a->nz) SETERRQ(PETSC_ERR_FILE_UNEXPECTED,"Bad binary matrix");
1702b6490206SBarry Smith 
1703606d414cSSatish Balay   ierr = PetscFree(rowlengths);CHKERRQ(ierr);
1704606d414cSSatish Balay   ierr = PetscFree(browlengths);CHKERRQ(ierr);
1705606d414cSSatish Balay   ierr = PetscFree(aa);CHKERRQ(ierr);
1706606d414cSSatish Balay   ierr = PetscFree(jj);CHKERRQ(ierr);
1707606d414cSSatish Balay   ierr = PetscFree(mask);CHKERRQ(ierr);
1708b6490206SBarry Smith 
1709b6490206SBarry Smith   B->assembled = PETSC_TRUE;
1710de6a44a3SBarry Smith 
17119c01be13SBarry Smith   ierr = MatView_Private(B);CHKERRQ(ierr);
17123a40ed3dSBarry Smith   PetscFunctionReturn(0);
17132593348eSBarry Smith }
1714273d9f13SBarry Smith EXTERN_C_END
17152593348eSBarry Smith 
17164a2ae208SSatish Balay #undef __FUNCT__
17174a2ae208SSatish Balay #define __FUNCT__ "MatCreateSeqBAIJ"
1718273d9f13SBarry Smith /*@C
1719273d9f13SBarry Smith    MatCreateSeqBAIJ - Creates a sparse matrix in block AIJ (block
1720273d9f13SBarry Smith    compressed row) format.  For good matrix assembly performance the
1721273d9f13SBarry Smith    user should preallocate the matrix storage by setting the parameter nz
1722273d9f13SBarry Smith    (or the array nnz).  By setting these parameters accurately, performance
1723273d9f13SBarry Smith    during matrix assembly can be increased by more than a factor of 50.
17242593348eSBarry Smith 
1725273d9f13SBarry Smith    Collective on MPI_Comm
1726273d9f13SBarry Smith 
1727273d9f13SBarry Smith    Input Parameters:
1728273d9f13SBarry Smith +  comm - MPI communicator, set to PETSC_COMM_SELF
1729273d9f13SBarry Smith .  bs - size of block
1730273d9f13SBarry Smith .  m - number of rows
1731273d9f13SBarry Smith .  n - number of columns
173235d8aa7fSBarry Smith .  nz - number of nonzero blocks  per block row (same for all rows)
173335d8aa7fSBarry Smith -  nnz - array containing the number of nonzero blocks in the various block rows
1734273d9f13SBarry Smith          (possibly different for each block row) or PETSC_NULL
1735273d9f13SBarry Smith 
1736273d9f13SBarry Smith    Output Parameter:
1737273d9f13SBarry Smith .  A - the matrix
1738273d9f13SBarry Smith 
1739273d9f13SBarry Smith    Options Database Keys:
1740273d9f13SBarry Smith .   -mat_no_unroll - uses code that does not unroll the loops in the
1741273d9f13SBarry Smith                      block calculations (much slower)
1742273d9f13SBarry Smith .    -mat_block_size - size of the blocks to use
1743273d9f13SBarry Smith 
1744273d9f13SBarry Smith    Level: intermediate
1745273d9f13SBarry Smith 
1746273d9f13SBarry Smith    Notes:
174735d8aa7fSBarry Smith    A nonzero block is any block that as 1 or more nonzeros in it
174835d8aa7fSBarry Smith 
1749273d9f13SBarry Smith    The block AIJ format is fully compatible with standard Fortran 77
1750273d9f13SBarry Smith    storage.  That is, the stored row and column indices can begin at
1751273d9f13SBarry Smith    either one (as in Fortran) or zero.  See the users' manual for details.
1752273d9f13SBarry Smith 
1753273d9f13SBarry Smith    Specify the preallocated storage with either nz or nnz (not both).
1754273d9f13SBarry Smith    Set nz=PETSC_DEFAULT and nnz=PETSC_NULL for PETSc to control dynamic memory
1755273d9f13SBarry Smith    allocation.  For additional details, see the users manual chapter on
1756273d9f13SBarry Smith    matrices.
1757273d9f13SBarry Smith 
1758273d9f13SBarry Smith .seealso: MatCreate(), MatCreateSeqAIJ(), MatSetValues(), MatCreateMPIBAIJ()
1759273d9f13SBarry Smith @*/
1760273d9f13SBarry Smith int MatCreateSeqBAIJ(MPI_Comm comm,int bs,int m,int n,int nz,int *nnz,Mat *A)
1761273d9f13SBarry Smith {
1762273d9f13SBarry Smith   int ierr;
1763273d9f13SBarry Smith 
1764273d9f13SBarry Smith   PetscFunctionBegin;
1765273d9f13SBarry Smith   ierr = MatCreate(comm,m,n,m,n,A);CHKERRQ(ierr);
1766273d9f13SBarry Smith   ierr = MatSetType(*A,MATSEQBAIJ);CHKERRQ(ierr);
1767273d9f13SBarry Smith   ierr = MatSeqBAIJSetPreallocation(*A,bs,nz,nnz);CHKERRQ(ierr);
1768273d9f13SBarry Smith   PetscFunctionReturn(0);
1769273d9f13SBarry Smith }
1770273d9f13SBarry Smith 
17714a2ae208SSatish Balay #undef __FUNCT__
17724a2ae208SSatish Balay #define __FUNCT__ "MatSeqBAIJSetPreallocation"
1773273d9f13SBarry Smith /*@C
1774273d9f13SBarry Smith    MatSeqBAIJSetPreallocation - Sets the block size and expected nonzeros
1775273d9f13SBarry Smith    per row in the matrix. For good matrix assembly performance the
1776273d9f13SBarry Smith    user should preallocate the matrix storage by setting the parameter nz
1777273d9f13SBarry Smith    (or the array nnz).  By setting these parameters accurately, performance
1778273d9f13SBarry Smith    during matrix assembly can be increased by more than a factor of 50.
1779273d9f13SBarry Smith 
1780273d9f13SBarry Smith    Collective on MPI_Comm
1781273d9f13SBarry Smith 
1782273d9f13SBarry Smith    Input Parameters:
1783273d9f13SBarry Smith +  A - the matrix
1784273d9f13SBarry Smith .  bs - size of block
1785273d9f13SBarry Smith .  nz - number of block nonzeros per block row (same for all rows)
1786273d9f13SBarry Smith -  nnz - array containing the number of block nonzeros in the various block rows
1787273d9f13SBarry Smith          (possibly different for each block row) or PETSC_NULL
1788273d9f13SBarry Smith 
1789273d9f13SBarry Smith    Options Database Keys:
1790273d9f13SBarry Smith .   -mat_no_unroll - uses code that does not unroll the loops in the
1791273d9f13SBarry Smith                      block calculations (much slower)
1792273d9f13SBarry Smith .    -mat_block_size - size of the blocks to use
1793273d9f13SBarry Smith 
1794273d9f13SBarry Smith    Level: intermediate
1795273d9f13SBarry Smith 
1796273d9f13SBarry Smith    Notes:
1797273d9f13SBarry Smith    The block AIJ format is fully compatible with standard Fortran 77
1798273d9f13SBarry Smith    storage.  That is, the stored row and column indices can begin at
1799273d9f13SBarry Smith    either one (as in Fortran) or zero.  See the users' manual for details.
1800273d9f13SBarry Smith 
1801273d9f13SBarry Smith    Specify the preallocated storage with either nz or nnz (not both).
1802273d9f13SBarry Smith    Set nz=PETSC_DEFAULT and nnz=PETSC_NULL for PETSc to control dynamic memory
1803273d9f13SBarry Smith    allocation.  For additional details, see the users manual chapter on
1804273d9f13SBarry Smith    matrices.
1805273d9f13SBarry Smith 
1806273d9f13SBarry Smith .seealso: MatCreate(), MatCreateSeqAIJ(), MatSetValues(), MatCreateMPIBAIJ()
1807273d9f13SBarry Smith @*/
1808273d9f13SBarry Smith int MatSeqBAIJSetPreallocation(Mat B,int bs,int nz,int *nnz)
1809273d9f13SBarry Smith {
1810273d9f13SBarry Smith   Mat_SeqBAIJ *b;
1811273d9f13SBarry Smith   int         i,len,ierr,mbs,nbs,bs2,newbs = bs;
1812273d9f13SBarry Smith   PetscTruth  flg;
1813273d9f13SBarry Smith 
1814273d9f13SBarry Smith   PetscFunctionBegin;
1815273d9f13SBarry Smith   ierr = PetscTypeCompare((PetscObject)B,MATSEQBAIJ,&flg);CHKERRQ(ierr);
1816273d9f13SBarry Smith   if (!flg) PetscFunctionReturn(0);
1817273d9f13SBarry Smith 
1818273d9f13SBarry Smith   B->preallocated = PETSC_TRUE;
1819b0a32e0cSBarry Smith   ierr = PetscOptionsGetInt(B->prefix,"-mat_block_size",&newbs,PETSC_NULL);CHKERRQ(ierr);
1820273d9f13SBarry Smith   if (nnz && newbs != bs) {
1821273d9f13SBarry Smith     SETERRQ(1,"Cannot change blocksize from command line if setting nnz");
1822273d9f13SBarry Smith   }
1823273d9f13SBarry Smith   bs   = newbs;
1824273d9f13SBarry Smith 
1825273d9f13SBarry Smith   mbs  = B->m/bs;
1826273d9f13SBarry Smith   nbs  = B->n/bs;
1827273d9f13SBarry Smith   bs2  = bs*bs;
1828273d9f13SBarry Smith 
1829273d9f13SBarry Smith   if (mbs*bs!=B->m || nbs*bs!=B->n) {
183035d8aa7fSBarry Smith     SETERRQ3(PETSC_ERR_ARG_SIZ,"Number rows %d, cols %d must be divisible by blocksize %d",B->m,B->n,bs);
1831273d9f13SBarry Smith   }
1832273d9f13SBarry Smith 
1833435da068SBarry Smith   if (nz == PETSC_DEFAULT || nz == PETSC_DECIDE) nz = 5;
1834435da068SBarry Smith   if (nz < 0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"nz cannot be less than 0: value %d",nz);
1835273d9f13SBarry Smith   if (nnz) {
1836273d9f13SBarry Smith     for (i=0; i<mbs; i++) {
1837273d9f13SBarry Smith       if (nnz[i] < 0) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"nnz cannot be less than 0: local row %d value %d",i,nnz[i]);
18383a7fca6bSBarry Smith       if (nnz[i] > nbs) SETERRQ3(PETSC_ERR_ARG_OUTOFRANGE,"nnz cannot be greater than block row length: local row %d value %d rowlength %d",i,nnz[i],nbs);
1839273d9f13SBarry Smith     }
1840273d9f13SBarry Smith   }
1841273d9f13SBarry Smith 
1842273d9f13SBarry Smith   b       = (Mat_SeqBAIJ*)B->data;
1843b0a32e0cSBarry Smith   ierr    = PetscOptionsHasName(PETSC_NULL,"-mat_no_unroll",&flg);CHKERRQ(ierr);
1844*54138f6bSKris Buschelman   B->ops->solve               = MatSolve_SeqBAIJ_Update;
1845*54138f6bSKris Buschelman   B->ops->solvetranspose      = MatSolveTranspose_SeqBAIJ_Update;
1846273d9f13SBarry Smith   if (!flg) {
1847273d9f13SBarry Smith     switch (bs) {
1848273d9f13SBarry Smith     case 1:
1849273d9f13SBarry Smith       B->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_1;
1850273d9f13SBarry Smith       B->ops->mult            = MatMult_SeqBAIJ_1;
1851273d9f13SBarry Smith       B->ops->multadd         = MatMultAdd_SeqBAIJ_1;
1852273d9f13SBarry Smith       break;
1853273d9f13SBarry Smith     case 2:
1854273d9f13SBarry Smith       B->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_2;
1855273d9f13SBarry Smith       B->ops->mult            = MatMult_SeqBAIJ_2;
1856273d9f13SBarry Smith       B->ops->multadd         = MatMultAdd_SeqBAIJ_2;
1857273d9f13SBarry Smith       break;
1858273d9f13SBarry Smith     case 3:
1859273d9f13SBarry Smith       B->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_3;
1860273d9f13SBarry Smith       B->ops->mult            = MatMult_SeqBAIJ_3;
1861273d9f13SBarry Smith       B->ops->multadd         = MatMultAdd_SeqBAIJ_3;
1862273d9f13SBarry Smith       break;
1863273d9f13SBarry Smith     case 4:
1864273d9f13SBarry Smith       B->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_4;
1865273d9f13SBarry Smith       B->ops->mult            = MatMult_SeqBAIJ_4;
1866273d9f13SBarry Smith       B->ops->multadd         = MatMultAdd_SeqBAIJ_4;
1867273d9f13SBarry Smith       break;
1868273d9f13SBarry Smith     case 5:
1869273d9f13SBarry Smith       B->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_5;
1870273d9f13SBarry Smith       B->ops->mult            = MatMult_SeqBAIJ_5;
1871273d9f13SBarry Smith       B->ops->multadd         = MatMultAdd_SeqBAIJ_5;
1872273d9f13SBarry Smith       break;
1873273d9f13SBarry Smith     case 6:
1874273d9f13SBarry Smith       B->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_6;
1875273d9f13SBarry Smith       B->ops->mult            = MatMult_SeqBAIJ_6;
1876273d9f13SBarry Smith       B->ops->multadd         = MatMultAdd_SeqBAIJ_6;
1877273d9f13SBarry Smith       break;
1878273d9f13SBarry Smith     case 7:
1879*54138f6bSKris Buschelman       B->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_7;
1880273d9f13SBarry Smith       B->ops->mult            = MatMult_SeqBAIJ_7;
1881273d9f13SBarry Smith       B->ops->multadd         = MatMultAdd_SeqBAIJ_7;
1882273d9f13SBarry Smith       break;
1883273d9f13SBarry Smith     default:
1884*54138f6bSKris Buschelman       B->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_N;
1885273d9f13SBarry Smith       B->ops->mult            = MatMult_SeqBAIJ_N;
1886273d9f13SBarry Smith       B->ops->multadd         = MatMultAdd_SeqBAIJ_N;
1887273d9f13SBarry Smith       break;
1888273d9f13SBarry Smith     }
1889273d9f13SBarry Smith   }
1890273d9f13SBarry Smith   b->bs      = bs;
1891273d9f13SBarry Smith   b->mbs     = mbs;
1892273d9f13SBarry Smith   b->nbs     = nbs;
1893b0a32e0cSBarry Smith   ierr = PetscMalloc((mbs+1)*sizeof(int),&b->imax);CHKERRQ(ierr);
1894273d9f13SBarry Smith   if (!nnz) {
1895435da068SBarry Smith     if (nz == PETSC_DEFAULT || nz == PETSC_DECIDE) nz = 5;
1896273d9f13SBarry Smith     else if (nz <= 0)        nz = 1;
1897273d9f13SBarry Smith     for (i=0; i<mbs; i++) b->imax[i] = nz;
1898273d9f13SBarry Smith     nz = nz*mbs;
1899273d9f13SBarry Smith   } else {
1900273d9f13SBarry Smith     nz = 0;
1901273d9f13SBarry Smith     for (i=0; i<mbs; i++) {b->imax[i] = nnz[i]; nz += nnz[i];}
1902273d9f13SBarry Smith   }
1903273d9f13SBarry Smith 
1904273d9f13SBarry Smith   /* allocate the matrix space */
1905273d9f13SBarry Smith   len   = nz*sizeof(int) + nz*bs2*sizeof(MatScalar) + (B->m+1)*sizeof(int);
1906b0a32e0cSBarry Smith   ierr  = PetscMalloc(len,&b->a);CHKERRQ(ierr);
1907273d9f13SBarry Smith   ierr  = PetscMemzero(b->a,nz*bs2*sizeof(MatScalar));CHKERRQ(ierr);
1908273d9f13SBarry Smith   b->j  = (int*)(b->a + nz*bs2);
1909273d9f13SBarry Smith   ierr = PetscMemzero(b->j,nz*sizeof(int));CHKERRQ(ierr);
1910273d9f13SBarry Smith   b->i  = b->j + nz;
1911273d9f13SBarry Smith   b->singlemalloc = PETSC_TRUE;
1912273d9f13SBarry Smith 
1913273d9f13SBarry Smith   b->i[0] = 0;
1914273d9f13SBarry Smith   for (i=1; i<mbs+1; i++) {
1915273d9f13SBarry Smith     b->i[i] = b->i[i-1] + b->imax[i-1];
1916273d9f13SBarry Smith   }
1917273d9f13SBarry Smith 
1918273d9f13SBarry Smith   /* b->ilen will count nonzeros in each block row so far. */
191916d6aa21SSatish Balay   ierr = PetscMalloc((mbs+1)*sizeof(int),&b->ilen);CHKERRQ(ierr);
1920b0a32e0cSBarry Smith   PetscLogObjectMemory(B,len+2*(mbs+1)*sizeof(int)+sizeof(struct _p_Mat)+sizeof(Mat_SeqBAIJ));
1921273d9f13SBarry Smith   for (i=0; i<mbs; i++) { b->ilen[i] = 0;}
1922273d9f13SBarry Smith 
1923273d9f13SBarry Smith   b->bs               = bs;
1924273d9f13SBarry Smith   b->bs2              = bs2;
1925273d9f13SBarry Smith   b->mbs              = mbs;
1926273d9f13SBarry Smith   b->nz               = 0;
1927273d9f13SBarry Smith   b->maxnz            = nz*bs2;
1928273d9f13SBarry Smith   B->info.nz_unneeded = (PetscReal)b->maxnz;
1929273d9f13SBarry Smith   PetscFunctionReturn(0);
1930273d9f13SBarry Smith }
19312593348eSBarry Smith 
1932