xref: /petsc/src/mat/impls/baij/seq/baij.c (revision 14db4f741bf9e876b68fbbaa8c00e674e0f1650c)
1bba1ac68SSatish Balay /*$Id: baij.c,v 1.245 2001/08/07 03:02:55 balay Exp bsmith $*/
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
1387828ca2SBarry Smith    When MatScalar == PetscScalar 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) {
21694ee7fc8SKris Buschelman       PetscTruth sse_enabled_local,sse_enabled_global;
217bd648c37SKris Buschelman       int        ierr;
21894ee7fc8SKris Buschelman 
21994ee7fc8SKris Buschelman       sse_enabled_local  = PETSC_FALSE;
22094ee7fc8SKris Buschelman       sse_enabled_global = PETSC_FALSE;
22194ee7fc8SKris Buschelman 
22294ee7fc8SKris Buschelman       ierr = PetscSSEIsEnabled(A->comm,&sse_enabled_local,&sse_enabled_global);CHKERRQ(ierr);
223e64df4b9SKris Buschelman #if defined(PETSC_HAVE_SSE)
22494ee7fc8SKris Buschelman       if (sse_enabled_local) {
22554138f6bSKris Buschelman           a->single_precision_solves = PETSC_TRUE;
22654138f6bSKris Buschelman           A->ops->solve              = MatSolve_SeqBAIJ_Update;
22754138f6bSKris Buschelman           A->ops->solvetranspose     = MatSolveTranspose_SeqBAIJ_Update;
228cf242676SKris Buschelman           PetscLogInfo(A,"MatSetOption_SeqBAIJ:Option MAT_USE_SINGLE_PRECISION_SOLVES set\n");
22954138f6bSKris Buschelman           break;
23094ee7fc8SKris Buschelman       } else {
23194ee7fc8SKris Buschelman         PetscLogInfo(A,"MatSetOption_SeqBAIJ:Option MAT_USE_SINGLE_PRECISION_SOLVES ignored\n");
2328661488fSKris Buschelman       }
233e64df4b9SKris Buschelman #else
234bd648c37SKris Buschelman       PetscLogInfo(A,"MatSetOption_SeqBAIJ:Option MAT_USE_SINGLE_PRECISION_SOLVES ignored\n");
235e64df4b9SKris Buschelman #endif
236bd648c37SKris Buschelman     }
237bd648c37SKris Buschelman     break;
238aa275fccSKris Buschelman   default:
23929bbc08cSBarry Smith     SETERRQ(PETSC_ERR_SUP,"unknown option");
2402d61bbb3SSatish Balay   }
2412d61bbb3SSatish Balay   PetscFunctionReturn(0);
2422d61bbb3SSatish Balay }
2432d61bbb3SSatish Balay 
2444a2ae208SSatish Balay #undef __FUNCT__
2454a2ae208SSatish Balay #define __FUNCT__ "MatGetRow_SeqBAIJ"
24687828ca2SBarry Smith int MatGetRow_SeqBAIJ(Mat A,int row,int *nz,int **idx,PetscScalar **v)
2472d61bbb3SSatish Balay {
2482d61bbb3SSatish Balay   Mat_SeqBAIJ  *a = (Mat_SeqBAIJ*)A->data;
24982502324SSatish Balay   int          itmp,i,j,k,M,*ai,*aj,bs,bn,bp,*idx_i,bs2,ierr;
2503f1db9ecSBarry Smith   MatScalar    *aa,*aa_i;
25187828ca2SBarry Smith   PetscScalar  *v_i;
2522d61bbb3SSatish Balay 
2532d61bbb3SSatish Balay   PetscFunctionBegin;
2542d61bbb3SSatish Balay   bs  = a->bs;
2552d61bbb3SSatish Balay   ai  = a->i;
2562d61bbb3SSatish Balay   aj  = a->j;
2572d61bbb3SSatish Balay   aa  = a->a;
2582d61bbb3SSatish Balay   bs2 = a->bs2;
2592d61bbb3SSatish Balay 
260273d9f13SBarry Smith   if (row < 0 || row >= A->m) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Row out of range");
2612d61bbb3SSatish Balay 
2622d61bbb3SSatish Balay   bn  = row/bs;   /* Block number */
2632d61bbb3SSatish Balay   bp  = row % bs; /* Block Position */
2642d61bbb3SSatish Balay   M   = ai[bn+1] - ai[bn];
2652d61bbb3SSatish Balay   *nz = bs*M;
2662d61bbb3SSatish Balay 
2672d61bbb3SSatish Balay   if (v) {
2682d61bbb3SSatish Balay     *v = 0;
2692d61bbb3SSatish Balay     if (*nz) {
27087828ca2SBarry Smith       ierr = PetscMalloc((*nz)*sizeof(PetscScalar),v);CHKERRQ(ierr);
2712d61bbb3SSatish Balay       for (i=0; i<M; i++) { /* for each block in the block row */
2722d61bbb3SSatish Balay         v_i  = *v + i*bs;
2732d61bbb3SSatish Balay         aa_i = aa + bs2*(ai[bn] + i);
2742d61bbb3SSatish Balay         for (j=bp,k=0; j<bs2; j+=bs,k++) {v_i[k] = aa_i[j];}
2752d61bbb3SSatish Balay       }
2762d61bbb3SSatish Balay     }
2772d61bbb3SSatish Balay   }
2782d61bbb3SSatish Balay 
2792d61bbb3SSatish Balay   if (idx) {
2802d61bbb3SSatish Balay     *idx = 0;
2812d61bbb3SSatish Balay     if (*nz) {
282b0a32e0cSBarry Smith       ierr = PetscMalloc((*nz)*sizeof(int),idx);CHKERRQ(ierr);
2832d61bbb3SSatish Balay       for (i=0; i<M; i++) { /* for each block in the block row */
2842d61bbb3SSatish Balay         idx_i = *idx + i*bs;
2852d61bbb3SSatish Balay         itmp  = bs*aj[ai[bn] + i];
2862d61bbb3SSatish Balay         for (j=0; j<bs; j++) {idx_i[j] = itmp++;}
2872d61bbb3SSatish Balay       }
2882d61bbb3SSatish Balay     }
2892d61bbb3SSatish Balay   }
2902d61bbb3SSatish Balay   PetscFunctionReturn(0);
2912d61bbb3SSatish Balay }
2922d61bbb3SSatish Balay 
2934a2ae208SSatish Balay #undef __FUNCT__
2944a2ae208SSatish Balay #define __FUNCT__ "MatRestoreRow_SeqBAIJ"
29587828ca2SBarry Smith int MatRestoreRow_SeqBAIJ(Mat A,int row,int *nz,int **idx,PetscScalar **v)
2962d61bbb3SSatish Balay {
297606d414cSSatish Balay   int ierr;
298606d414cSSatish Balay 
2992d61bbb3SSatish Balay   PetscFunctionBegin;
300606d414cSSatish Balay   if (idx) {if (*idx) {ierr = PetscFree(*idx);CHKERRQ(ierr);}}
301606d414cSSatish Balay   if (v)   {if (*v)   {ierr = PetscFree(*v);CHKERRQ(ierr);}}
3022d61bbb3SSatish Balay   PetscFunctionReturn(0);
3032d61bbb3SSatish Balay }
3042d61bbb3SSatish Balay 
3054a2ae208SSatish Balay #undef __FUNCT__
3064a2ae208SSatish Balay #define __FUNCT__ "MatTranspose_SeqBAIJ"
3072d61bbb3SSatish Balay int MatTranspose_SeqBAIJ(Mat A,Mat *B)
3082d61bbb3SSatish Balay {
3092d61bbb3SSatish Balay   Mat_SeqBAIJ *a=(Mat_SeqBAIJ *)A->data;
3102d61bbb3SSatish Balay   Mat         C;
3112d61bbb3SSatish Balay   int         i,j,k,ierr,*aj=a->j,*ai=a->i,bs=a->bs,mbs=a->mbs,nbs=a->nbs,len,*col;
312273d9f13SBarry Smith   int         *rows,*cols,bs2=a->bs2;
31387828ca2SBarry Smith   PetscScalar *array;
3142d61bbb3SSatish Balay 
3152d61bbb3SSatish Balay   PetscFunctionBegin;
31629bbc08cSBarry Smith   if (!B && mbs!=nbs) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Square matrix only for in-place");
317b0a32e0cSBarry Smith   ierr = PetscMalloc((1+nbs)*sizeof(int),&col);CHKERRQ(ierr);
318549d3d68SSatish Balay   ierr = PetscMemzero(col,(1+nbs)*sizeof(int));CHKERRQ(ierr);
3192d61bbb3SSatish Balay 
320375fe846SBarry Smith #if defined(PETSC_USE_MAT_SINGLE)
32187828ca2SBarry Smith   ierr = PetscMalloc(a->bs2*a->nz*sizeof(PetscScalar),&array);CHKERRQ(ierr);
32287828ca2SBarry Smith   for (i=0; i<a->bs2*a->nz; i++) array[i] = (PetscScalar)a->a[i];
323375fe846SBarry Smith #else
3243eda8832SBarry Smith   array = a->a;
325375fe846SBarry Smith #endif
326375fe846SBarry Smith 
3272d61bbb3SSatish Balay   for (i=0; i<ai[mbs]; i++) col[aj[i]] += 1;
328273d9f13SBarry Smith   ierr = MatCreateSeqBAIJ(A->comm,bs,A->n,A->m,PETSC_NULL,col,&C);CHKERRQ(ierr);
329606d414cSSatish Balay   ierr = PetscFree(col);CHKERRQ(ierr);
330b0a32e0cSBarry Smith   ierr = PetscMalloc(2*bs*sizeof(int),&rows);CHKERRQ(ierr);
3312d61bbb3SSatish Balay   cols = rows + bs;
3322d61bbb3SSatish Balay   for (i=0; i<mbs; i++) {
3332d61bbb3SSatish Balay     cols[0] = i*bs;
3342d61bbb3SSatish Balay     for (k=1; k<bs; k++) cols[k] = cols[k-1] + 1;
3352d61bbb3SSatish Balay     len = ai[i+1] - ai[i];
3362d61bbb3SSatish Balay     for (j=0; j<len; j++) {
3372d61bbb3SSatish Balay       rows[0] = (*aj++)*bs;
3382d61bbb3SSatish Balay       for (k=1; k<bs; k++) rows[k] = rows[k-1] + 1;
3392d61bbb3SSatish Balay       ierr = MatSetValues(C,bs,rows,bs,cols,array,INSERT_VALUES);CHKERRQ(ierr);
3402d61bbb3SSatish Balay       array += bs2;
3412d61bbb3SSatish Balay     }
3422d61bbb3SSatish Balay   }
343606d414cSSatish Balay   ierr = PetscFree(rows);CHKERRQ(ierr);
344375fe846SBarry Smith #if defined(PETSC_USE_MAT_SINGLE)
345375fe846SBarry Smith   ierr = PetscFree(array);
346375fe846SBarry Smith #endif
3472d61bbb3SSatish Balay 
3482d61bbb3SSatish Balay   ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
3492d61bbb3SSatish Balay   ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
3502d61bbb3SSatish Balay 
351c4992f7dSBarry Smith   if (B) {
3522d61bbb3SSatish Balay     *B = C;
3532d61bbb3SSatish Balay   } else {
354273d9f13SBarry Smith     ierr = MatHeaderCopy(A,C);CHKERRQ(ierr);
3552d61bbb3SSatish Balay   }
3562d61bbb3SSatish Balay   PetscFunctionReturn(0);
3572d61bbb3SSatish Balay }
3582d61bbb3SSatish Balay 
3594a2ae208SSatish Balay #undef __FUNCT__
3604a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqBAIJ_Binary"
361b0a32e0cSBarry Smith static int MatView_SeqBAIJ_Binary(Mat A,PetscViewer viewer)
3622593348eSBarry Smith {
363b6490206SBarry Smith   Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)A->data;
3649df24120SSatish Balay   int         i,fd,*col_lens,ierr,bs = a->bs,count,*jj,j,k,l,bs2=a->bs2;
36587828ca2SBarry Smith   PetscScalar *aa;
366ce6f0cecSBarry Smith   FILE        *file;
3672593348eSBarry Smith 
3683a40ed3dSBarry Smith   PetscFunctionBegin;
369b0a32e0cSBarry Smith   ierr        = PetscViewerBinaryGetDescriptor(viewer,&fd);CHKERRQ(ierr);
370b0a32e0cSBarry Smith   ierr        = PetscMalloc((4+A->m)*sizeof(int),&col_lens);CHKERRQ(ierr);
371552e946dSBarry Smith   col_lens[0] = MAT_FILE_COOKIE;
3723b2fbd54SBarry Smith 
373273d9f13SBarry Smith   col_lens[1] = A->m;
374273d9f13SBarry Smith   col_lens[2] = A->n;
3757e67e3f9SSatish Balay   col_lens[3] = a->nz*bs2;
3762593348eSBarry Smith 
3772593348eSBarry Smith   /* store lengths of each row and write (including header) to file */
378b6490206SBarry Smith   count = 0;
379b6490206SBarry Smith   for (i=0; i<a->mbs; i++) {
380b6490206SBarry Smith     for (j=0; j<bs; j++) {
381b6490206SBarry Smith       col_lens[4+count++] = bs*(a->i[i+1] - a->i[i]);
382b6490206SBarry Smith     }
3832593348eSBarry Smith   }
384273d9f13SBarry Smith   ierr = PetscBinaryWrite(fd,col_lens,4+A->m,PETSC_INT,1);CHKERRQ(ierr);
385606d414cSSatish Balay   ierr = PetscFree(col_lens);CHKERRQ(ierr);
3862593348eSBarry Smith 
3872593348eSBarry Smith   /* store column indices (zero start index) */
388b0a32e0cSBarry Smith   ierr  = PetscMalloc((a->nz+1)*bs2*sizeof(int),&jj);CHKERRQ(ierr);
389b6490206SBarry Smith   count = 0;
390b6490206SBarry Smith   for (i=0; i<a->mbs; i++) {
391b6490206SBarry Smith     for (j=0; j<bs; j++) {
392b6490206SBarry Smith       for (k=a->i[i]; k<a->i[i+1]; k++) {
393b6490206SBarry Smith         for (l=0; l<bs; l++) {
394b6490206SBarry Smith           jj[count++] = bs*a->j[k] + l;
3952593348eSBarry Smith         }
3962593348eSBarry Smith       }
397b6490206SBarry Smith     }
398b6490206SBarry Smith   }
3990752156aSBarry Smith   ierr = PetscBinaryWrite(fd,jj,bs2*a->nz,PETSC_INT,0);CHKERRQ(ierr);
400606d414cSSatish Balay   ierr = PetscFree(jj);CHKERRQ(ierr);
4012593348eSBarry Smith 
4022593348eSBarry Smith   /* store nonzero values */
40387828ca2SBarry Smith   ierr  = PetscMalloc((a->nz+1)*bs2*sizeof(PetscScalar),&aa);CHKERRQ(ierr);
404b6490206SBarry Smith   count = 0;
405b6490206SBarry Smith   for (i=0; i<a->mbs; i++) {
406b6490206SBarry Smith     for (j=0; j<bs; j++) {
407b6490206SBarry Smith       for (k=a->i[i]; k<a->i[i+1]; k++) {
408b6490206SBarry Smith         for (l=0; l<bs; l++) {
4097e67e3f9SSatish Balay           aa[count++] = a->a[bs2*k + l*bs + j];
410b6490206SBarry Smith         }
411b6490206SBarry Smith       }
412b6490206SBarry Smith     }
413b6490206SBarry Smith   }
4140752156aSBarry Smith   ierr = PetscBinaryWrite(fd,aa,bs2*a->nz,PETSC_SCALAR,0);CHKERRQ(ierr);
415606d414cSSatish Balay   ierr = PetscFree(aa);CHKERRQ(ierr);
416ce6f0cecSBarry Smith 
417b0a32e0cSBarry Smith   ierr = PetscViewerBinaryGetInfoPointer(viewer,&file);CHKERRQ(ierr);
418ce6f0cecSBarry Smith   if (file) {
419ce6f0cecSBarry Smith     fprintf(file,"-matload_block_size %d\n",a->bs);
420ce6f0cecSBarry Smith   }
4213a40ed3dSBarry Smith   PetscFunctionReturn(0);
4222593348eSBarry Smith }
4232593348eSBarry Smith 
4244a2ae208SSatish Balay #undef __FUNCT__
4254a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqBAIJ_ASCII"
426b0a32e0cSBarry Smith static int MatView_SeqBAIJ_ASCII(Mat A,PetscViewer viewer)
4272593348eSBarry Smith {
428b6490206SBarry Smith   Mat_SeqBAIJ       *a = (Mat_SeqBAIJ*)A->data;
429fb9695e5SSatish Balay   int               ierr,i,j,bs = a->bs,k,l,bs2=a->bs2;
430f3ef73ceSBarry Smith   PetscViewerFormat format;
4312593348eSBarry Smith 
4323a40ed3dSBarry Smith   PetscFunctionBegin;
433b0a32e0cSBarry Smith   ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr);
434fb9695e5SSatish Balay   if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_LONG) {
435b0a32e0cSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  block size is %d\n",bs);CHKERRQ(ierr);
436fb9695e5SSatish Balay   } else if (format == PETSC_VIEWER_ASCII_MATLAB) {
43729bbc08cSBarry Smith     SETERRQ(PETSC_ERR_SUP,"Matlab format not supported");
438fb9695e5SSatish Balay   } else if (format == PETSC_VIEWER_ASCII_COMMON) {
439b0a32e0cSBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_NO);CHKERRQ(ierr);
44044cd7ae7SLois Curfman McInnes     for (i=0; i<a->mbs; i++) {
44144cd7ae7SLois Curfman McInnes       for (j=0; j<bs; j++) {
442b0a32e0cSBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"row %d:",i*bs+j);CHKERRQ(ierr);
44344cd7ae7SLois Curfman McInnes         for (k=a->i[i]; k<a->i[i+1]; k++) {
44444cd7ae7SLois Curfman McInnes           for (l=0; l<bs; l++) {
445aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
4460e6d2581SBarry Smith             if (PetscImaginaryPart(a->a[bs2*k + l*bs + j]) > 0.0 && PetscRealPart(a->a[bs2*k + l*bs + j]) != 0.0) {
447b0a32e0cSBarry Smith               ierr = PetscViewerASCIIPrintf(viewer," %d %g + %gi",bs*a->j[k]+l,
4480e6d2581SBarry Smith                       PetscRealPart(a->a[bs2*k + l*bs + j]),PetscImaginaryPart(a->a[bs2*k + l*bs + j]));CHKERRQ(ierr);
4490e6d2581SBarry Smith             } else if (PetscImaginaryPart(a->a[bs2*k + l*bs + j]) < 0.0 && PetscRealPart(a->a[bs2*k + l*bs + j]) != 0.0) {
450b0a32e0cSBarry Smith               ierr = PetscViewerASCIIPrintf(viewer," %d %g - %gi",bs*a->j[k]+l,
4510e6d2581SBarry Smith                       PetscRealPart(a->a[bs2*k + l*bs + j]),-PetscImaginaryPart(a->a[bs2*k + l*bs + j]));CHKERRQ(ierr);
4520e6d2581SBarry Smith             } else if (PetscRealPart(a->a[bs2*k + l*bs + j]) != 0.0) {
453b0a32e0cSBarry Smith               ierr = PetscViewerASCIIPrintf(viewer," %d %g ",bs*a->j[k]+l,PetscRealPart(a->a[bs2*k + l*bs + j]));CHKERRQ(ierr);
4540ef38995SBarry Smith             }
45544cd7ae7SLois Curfman McInnes #else
4560ef38995SBarry Smith             if (a->a[bs2*k + l*bs + j] != 0.0) {
457b0a32e0cSBarry Smith               ierr = PetscViewerASCIIPrintf(viewer," %d %g ",bs*a->j[k]+l,a->a[bs2*k + l*bs + j]);CHKERRQ(ierr);
4580ef38995SBarry Smith             }
45944cd7ae7SLois Curfman McInnes #endif
46044cd7ae7SLois Curfman McInnes           }
46144cd7ae7SLois Curfman McInnes         }
462b0a32e0cSBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
46344cd7ae7SLois Curfman McInnes       }
46444cd7ae7SLois Curfman McInnes     }
465b0a32e0cSBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_YES);CHKERRQ(ierr);
4660ef38995SBarry Smith   } else {
467b0a32e0cSBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_NO);CHKERRQ(ierr);
468b6490206SBarry Smith     for (i=0; i<a->mbs; i++) {
469b6490206SBarry Smith       for (j=0; j<bs; j++) {
470b0a32e0cSBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"row %d:",i*bs+j);CHKERRQ(ierr);
471b6490206SBarry Smith         for (k=a->i[i]; k<a->i[i+1]; k++) {
472b6490206SBarry Smith           for (l=0; l<bs; l++) {
473aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
4740e6d2581SBarry Smith             if (PetscImaginaryPart(a->a[bs2*k + l*bs + j]) > 0.0) {
475b0a32e0cSBarry Smith               ierr = PetscViewerASCIIPrintf(viewer," %d %g + %g i",bs*a->j[k]+l,
4760e6d2581SBarry Smith                 PetscRealPart(a->a[bs2*k + l*bs + j]),PetscImaginaryPart(a->a[bs2*k + l*bs + j]));CHKERRQ(ierr);
4770e6d2581SBarry Smith             } else if (PetscImaginaryPart(a->a[bs2*k + l*bs + j]) < 0.0) {
478b0a32e0cSBarry Smith               ierr = PetscViewerASCIIPrintf(viewer," %d %g - %g i",bs*a->j[k]+l,
4790e6d2581SBarry Smith                 PetscRealPart(a->a[bs2*k + l*bs + j]),-PetscImaginaryPart(a->a[bs2*k + l*bs + j]));CHKERRQ(ierr);
4800ef38995SBarry Smith             } else {
481b0a32e0cSBarry Smith               ierr = PetscViewerASCIIPrintf(viewer," %d %g ",bs*a->j[k]+l,PetscRealPart(a->a[bs2*k + l*bs + j]));CHKERRQ(ierr);
48288685aaeSLois Curfman McInnes             }
48388685aaeSLois Curfman McInnes #else
484b0a32e0cSBarry Smith             ierr = PetscViewerASCIIPrintf(viewer," %d %g ",bs*a->j[k]+l,a->a[bs2*k + l*bs + j]);CHKERRQ(ierr);
48588685aaeSLois Curfman McInnes #endif
4862593348eSBarry Smith           }
4872593348eSBarry Smith         }
488b0a32e0cSBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
4892593348eSBarry Smith       }
4902593348eSBarry Smith     }
491b0a32e0cSBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_YES);CHKERRQ(ierr);
492b6490206SBarry Smith   }
493b0a32e0cSBarry Smith   ierr = PetscViewerFlush(viewer);CHKERRQ(ierr);
4943a40ed3dSBarry Smith   PetscFunctionReturn(0);
4952593348eSBarry Smith }
4962593348eSBarry Smith 
4974a2ae208SSatish Balay #undef __FUNCT__
4984a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqBAIJ_Draw_Zoom"
499b0a32e0cSBarry Smith static int MatView_SeqBAIJ_Draw_Zoom(PetscDraw draw,void *Aa)
5003270192aSSatish Balay {
50177ed5343SBarry Smith   Mat          A = (Mat) Aa;
5023270192aSSatish Balay   Mat_SeqBAIJ  *a=(Mat_SeqBAIJ*)A->data;
503b65db4caSBarry Smith   int          row,ierr,i,j,k,l,mbs=a->mbs,color,bs=a->bs,bs2=a->bs2;
5040e6d2581SBarry Smith   PetscReal    xl,yl,xr,yr,x_l,x_r,y_l,y_r;
5053f1db9ecSBarry Smith   MatScalar    *aa;
506b0a32e0cSBarry Smith   PetscViewer  viewer;
5073270192aSSatish Balay 
5083a40ed3dSBarry Smith   PetscFunctionBegin;
5093270192aSSatish Balay 
510b65db4caSBarry Smith   /* still need to add support for contour plot of nonzeros; see MatView_SeqAIJ_Draw_Zoom()*/
51177ed5343SBarry Smith   ierr = PetscObjectQuery((PetscObject)A,"Zoomviewer",(PetscObject*)&viewer);CHKERRQ(ierr);
51277ed5343SBarry Smith 
513b0a32e0cSBarry Smith   ierr = PetscDrawGetCoordinates(draw,&xl,&yl,&xr,&yr);CHKERRQ(ierr);
51477ed5343SBarry Smith 
5153270192aSSatish Balay   /* loop over matrix elements drawing boxes */
516b0a32e0cSBarry Smith   color = PETSC_DRAW_BLUE;
5173270192aSSatish Balay   for (i=0,row=0; i<mbs; i++,row+=bs) {
5183270192aSSatish Balay     for (j=a->i[i]; j<a->i[i+1]; j++) {
519273d9f13SBarry Smith       y_l = A->m - row - 1.0; y_r = y_l + 1.0;
5203270192aSSatish Balay       x_l = a->j[j]*bs; x_r = x_l + 1.0;
5213270192aSSatish Balay       aa = a->a + j*bs2;
5223270192aSSatish Balay       for (k=0; k<bs; k++) {
5233270192aSSatish Balay         for (l=0; l<bs; l++) {
5240e6d2581SBarry Smith           if (PetscRealPart(*aa++) >=  0.) continue;
525b0a32e0cSBarry Smith           ierr = PetscDrawRectangle(draw,x_l+k,y_l-l,x_r+k,y_r-l,color,color,color,color);CHKERRQ(ierr);
5263270192aSSatish Balay         }
5273270192aSSatish Balay       }
5283270192aSSatish Balay     }
5293270192aSSatish Balay   }
530b0a32e0cSBarry Smith   color = PETSC_DRAW_CYAN;
5313270192aSSatish Balay   for (i=0,row=0; i<mbs; i++,row+=bs) {
5323270192aSSatish Balay     for (j=a->i[i]; j<a->i[i+1]; j++) {
533273d9f13SBarry Smith       y_l = A->m - row - 1.0; y_r = y_l + 1.0;
5343270192aSSatish Balay       x_l = a->j[j]*bs; x_r = x_l + 1.0;
5353270192aSSatish Balay       aa = a->a + j*bs2;
5363270192aSSatish Balay       for (k=0; k<bs; k++) {
5373270192aSSatish Balay         for (l=0; l<bs; l++) {
5380e6d2581SBarry Smith           if (PetscRealPart(*aa++) != 0.) continue;
539b0a32e0cSBarry Smith           ierr = PetscDrawRectangle(draw,x_l+k,y_l-l,x_r+k,y_r-l,color,color,color,color);CHKERRQ(ierr);
5403270192aSSatish Balay         }
5413270192aSSatish Balay       }
5423270192aSSatish Balay     }
5433270192aSSatish Balay   }
5443270192aSSatish Balay 
545b0a32e0cSBarry Smith   color = PETSC_DRAW_RED;
5463270192aSSatish Balay   for (i=0,row=0; i<mbs; i++,row+=bs) {
5473270192aSSatish Balay     for (j=a->i[i]; j<a->i[i+1]; j++) {
548273d9f13SBarry Smith       y_l = A->m - row - 1.0; y_r = y_l + 1.0;
5493270192aSSatish Balay       x_l = a->j[j]*bs; x_r = x_l + 1.0;
5503270192aSSatish Balay       aa = a->a + j*bs2;
5513270192aSSatish Balay       for (k=0; k<bs; k++) {
5523270192aSSatish Balay         for (l=0; l<bs; l++) {
5530e6d2581SBarry Smith           if (PetscRealPart(*aa++) <= 0.) continue;
554b0a32e0cSBarry Smith           ierr = PetscDrawRectangle(draw,x_l+k,y_l-l,x_r+k,y_r-l,color,color,color,color);CHKERRQ(ierr);
5553270192aSSatish Balay         }
5563270192aSSatish Balay       }
5573270192aSSatish Balay     }
5583270192aSSatish Balay   }
55977ed5343SBarry Smith   PetscFunctionReturn(0);
56077ed5343SBarry Smith }
5613270192aSSatish Balay 
5624a2ae208SSatish Balay #undef __FUNCT__
5634a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqBAIJ_Draw"
564b0a32e0cSBarry Smith static int MatView_SeqBAIJ_Draw(Mat A,PetscViewer viewer)
56577ed5343SBarry Smith {
5667dce120fSSatish Balay   int          ierr;
5670e6d2581SBarry Smith   PetscReal    xl,yl,xr,yr,w,h;
568b0a32e0cSBarry Smith   PetscDraw    draw;
56977ed5343SBarry Smith   PetscTruth   isnull;
5703270192aSSatish Balay 
57177ed5343SBarry Smith   PetscFunctionBegin;
57277ed5343SBarry Smith 
573b0a32e0cSBarry Smith   ierr = PetscViewerDrawGetDraw(viewer,0,&draw);CHKERRQ(ierr);
574b0a32e0cSBarry Smith   ierr = PetscDrawIsNull(draw,&isnull);CHKERRQ(ierr); if (isnull) PetscFunctionReturn(0);
57577ed5343SBarry Smith 
57677ed5343SBarry Smith   ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",(PetscObject)viewer);CHKERRQ(ierr);
577273d9f13SBarry Smith   xr  = A->n; yr = A->m; h = yr/10.0; w = xr/10.0;
57877ed5343SBarry Smith   xr += w;    yr += h;  xl = -w;     yl = -h;
579b0a32e0cSBarry Smith   ierr = PetscDrawSetCoordinates(draw,xl,yl,xr,yr);CHKERRQ(ierr);
580b0a32e0cSBarry Smith   ierr = PetscDrawZoom(draw,MatView_SeqBAIJ_Draw_Zoom,A);CHKERRQ(ierr);
58177ed5343SBarry Smith   ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",PETSC_NULL);CHKERRQ(ierr);
5823a40ed3dSBarry Smith   PetscFunctionReturn(0);
5833270192aSSatish Balay }
5843270192aSSatish Balay 
5854a2ae208SSatish Balay #undef __FUNCT__
5864a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqBAIJ"
587b0a32e0cSBarry Smith int MatView_SeqBAIJ(Mat A,PetscViewer viewer)
5882593348eSBarry Smith {
58919bcc07fSBarry Smith   int        ierr;
5906831982aSBarry Smith   PetscTruth issocket,isascii,isbinary,isdraw;
5912593348eSBarry Smith 
5923a40ed3dSBarry Smith   PetscFunctionBegin;
593b0a32e0cSBarry Smith   ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_SOCKET,&issocket);CHKERRQ(ierr);
594b0a32e0cSBarry Smith   ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&isascii);CHKERRQ(ierr);
595fb9695e5SSatish Balay   ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_BINARY,&isbinary);CHKERRQ(ierr);
596fb9695e5SSatish Balay   ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_DRAW,&isdraw);CHKERRQ(ierr);
5970f5bd95cSBarry Smith   if (issocket) {
59829bbc08cSBarry Smith     SETERRQ(PETSC_ERR_SUP,"Socket viewer not supported");
5990f5bd95cSBarry Smith   } else if (isascii){
6003a40ed3dSBarry Smith     ierr = MatView_SeqBAIJ_ASCII(A,viewer);CHKERRQ(ierr);
6010f5bd95cSBarry Smith   } else if (isbinary) {
6023a40ed3dSBarry Smith     ierr = MatView_SeqBAIJ_Binary(A,viewer);CHKERRQ(ierr);
6030f5bd95cSBarry Smith   } else if (isdraw) {
6043a40ed3dSBarry Smith     ierr = MatView_SeqBAIJ_Draw(A,viewer);CHKERRQ(ierr);
6055cd90555SBarry Smith   } else {
60629bbc08cSBarry Smith     SETERRQ1(1,"Viewer type %s not supported by SeqBAIJ matrices",((PetscObject)viewer)->type_name);
6072593348eSBarry Smith   }
6083a40ed3dSBarry Smith   PetscFunctionReturn(0);
6092593348eSBarry Smith }
610b6490206SBarry Smith 
611cd0e1443SSatish Balay 
6124a2ae208SSatish Balay #undef __FUNCT__
6134a2ae208SSatish Balay #define __FUNCT__ "MatGetValues_SeqBAIJ"
61487828ca2SBarry Smith int MatGetValues_SeqBAIJ(Mat A,int m,int *im,int n,int *in,PetscScalar *v)
615cd0e1443SSatish Balay {
616cd0e1443SSatish Balay   Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)A->data;
6172d61bbb3SSatish Balay   int        *rp,k,low,high,t,row,nrow,i,col,l,*aj = a->j;
6182d61bbb3SSatish Balay   int        *ai = a->i,*ailen = a->ilen;
6192d61bbb3SSatish Balay   int        brow,bcol,ridx,cidx,bs=a->bs,bs2=a->bs2;
6203f1db9ecSBarry Smith   MatScalar  *ap,*aa = a->a,zero = 0.0;
621cd0e1443SSatish Balay 
6223a40ed3dSBarry Smith   PetscFunctionBegin;
6232d61bbb3SSatish Balay   for (k=0; k<m; k++) { /* loop over rows */
624cd0e1443SSatish Balay     row  = im[k]; brow = row/bs;
62529bbc08cSBarry Smith     if (row < 0) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Negative row");
626273d9f13SBarry Smith     if (row >= A->m) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Row too large");
6272d61bbb3SSatish Balay     rp   = aj + ai[brow] ; ap = aa + bs2*ai[brow] ;
6282c3acbe9SBarry Smith     nrow = ailen[brow];
6292d61bbb3SSatish Balay     for (l=0; l<n; l++) { /* loop over columns */
63029bbc08cSBarry Smith       if (in[l] < 0) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Negative column");
631273d9f13SBarry Smith       if (in[l] >= A->n) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Column too large");
6322d61bbb3SSatish Balay       col  = in[l] ;
6332d61bbb3SSatish Balay       bcol = col/bs;
6342d61bbb3SSatish Balay       cidx = col%bs;
6352d61bbb3SSatish Balay       ridx = row%bs;
6362d61bbb3SSatish Balay       high = nrow;
6372d61bbb3SSatish Balay       low  = 0; /* assume unsorted */
6382d61bbb3SSatish Balay       while (high-low > 5) {
639cd0e1443SSatish Balay         t = (low+high)/2;
640cd0e1443SSatish Balay         if (rp[t] > bcol) high = t;
641cd0e1443SSatish Balay         else             low  = t;
642cd0e1443SSatish Balay       }
643cd0e1443SSatish Balay       for (i=low; i<high; i++) {
644cd0e1443SSatish Balay         if (rp[i] > bcol) break;
645cd0e1443SSatish Balay         if (rp[i] == bcol) {
6462d61bbb3SSatish Balay           *v++ = ap[bs2*i+bs*cidx+ridx];
6472d61bbb3SSatish Balay           goto finished;
648cd0e1443SSatish Balay         }
649cd0e1443SSatish Balay       }
6502d61bbb3SSatish Balay       *v++ = zero;
6512d61bbb3SSatish Balay       finished:;
652cd0e1443SSatish Balay     }
653cd0e1443SSatish Balay   }
6543a40ed3dSBarry Smith   PetscFunctionReturn(0);
655cd0e1443SSatish Balay }
656cd0e1443SSatish Balay 
65795d5f7c2SBarry Smith #if defined(PETSC_USE_MAT_SINGLE)
6584a2ae208SSatish Balay #undef __FUNCT__
6594a2ae208SSatish Balay #define __FUNCT__ "MatSetValuesBlocked_SeqBAIJ"
66087828ca2SBarry Smith int MatSetValuesBlocked_SeqBAIJ(Mat mat,int m,int *im,int n,int *in,PetscScalar *v,InsertMode addv)
66195d5f7c2SBarry Smith {
662563b5814SBarry Smith   Mat_SeqBAIJ *b = (Mat_SeqBAIJ*)mat->data;
663563b5814SBarry Smith   int         ierr,i,N = m*n*b->bs2;
664563b5814SBarry Smith   MatScalar   *vsingle;
66595d5f7c2SBarry Smith 
66695d5f7c2SBarry Smith   PetscFunctionBegin;
667563b5814SBarry Smith   if (N > b->setvalueslen) {
668563b5814SBarry Smith     if (b->setvaluescopy) {ierr = PetscFree(b->setvaluescopy);CHKERRQ(ierr);}
669b0a32e0cSBarry Smith     ierr = PetscMalloc(N*sizeof(MatScalar),&b->setvaluescopy);CHKERRQ(ierr);
670563b5814SBarry Smith     b->setvalueslen  = N;
671563b5814SBarry Smith   }
672563b5814SBarry Smith   vsingle = b->setvaluescopy;
67395d5f7c2SBarry Smith   for (i=0; i<N; i++) {
67495d5f7c2SBarry Smith     vsingle[i] = v[i];
67595d5f7c2SBarry Smith   }
67695d5f7c2SBarry Smith   ierr = MatSetValuesBlocked_SeqBAIJ_MatScalar(mat,m,im,n,in,vsingle,addv);CHKERRQ(ierr);
67795d5f7c2SBarry Smith   PetscFunctionReturn(0);
67895d5f7c2SBarry Smith }
67995d5f7c2SBarry Smith #endif
68095d5f7c2SBarry Smith 
6812d61bbb3SSatish Balay 
6824a2ae208SSatish Balay #undef __FUNCT__
6834a2ae208SSatish Balay #define __FUNCT__ "MatSetValuesBlocked_SeqBAIJ"
68495d5f7c2SBarry Smith int MatSetValuesBlocked_SeqBAIJ_MatScalar(Mat A,int m,int *im,int n,int *in,MatScalar *v,InsertMode is)
68592c4ed94SBarry Smith {
68692c4ed94SBarry Smith   Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)A->data;
6878a84c255SSatish Balay   int         *rp,k,low,high,t,ii,jj,row,nrow,i,col,l,rmax,N,sorted=a->sorted;
688273d9f13SBarry Smith   int         *imax=a->imax,*ai=a->i,*ailen=a->ilen;
689549d3d68SSatish Balay   int         *aj=a->j,nonew=a->nonew,bs2=a->bs2,bs=a->bs,stepval,ierr;
690273d9f13SBarry Smith   PetscTruth  roworiented=a->roworiented;
69195d5f7c2SBarry Smith   MatScalar   *value = v,*ap,*aa = a->a,*bap;
69292c4ed94SBarry Smith 
6933a40ed3dSBarry Smith   PetscFunctionBegin;
6940e324ae4SSatish Balay   if (roworiented) {
6950e324ae4SSatish Balay     stepval = (n-1)*bs;
6960e324ae4SSatish Balay   } else {
6970e324ae4SSatish Balay     stepval = (m-1)*bs;
6980e324ae4SSatish Balay   }
69992c4ed94SBarry Smith   for (k=0; k<m; k++) { /* loop over added rows */
70092c4ed94SBarry Smith     row  = im[k];
7015ef9f2a5SBarry Smith     if (row < 0) continue;
702aa482453SBarry Smith #if defined(PETSC_USE_BOPT_g)
70329bbc08cSBarry Smith     if (row >= a->mbs) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Row too large");
70492c4ed94SBarry Smith #endif
70592c4ed94SBarry Smith     rp   = aj + ai[row];
70692c4ed94SBarry Smith     ap   = aa + bs2*ai[row];
70792c4ed94SBarry Smith     rmax = imax[row];
70892c4ed94SBarry Smith     nrow = ailen[row];
70992c4ed94SBarry Smith     low  = 0;
71092c4ed94SBarry Smith     for (l=0; l<n; l++) { /* loop over added columns */
7115ef9f2a5SBarry Smith       if (in[l] < 0) continue;
712aa482453SBarry Smith #if defined(PETSC_USE_BOPT_g)
71329bbc08cSBarry Smith       if (in[l] >= a->nbs) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Column too large");
71492c4ed94SBarry Smith #endif
71592c4ed94SBarry Smith       col = in[l];
71692c4ed94SBarry Smith       if (roworiented) {
7170e324ae4SSatish Balay         value = v + k*(stepval+bs)*bs + l*bs;
7180e324ae4SSatish Balay       } else {
7190e324ae4SSatish Balay         value = v + l*(stepval+bs)*bs + k*bs;
72092c4ed94SBarry Smith       }
72192c4ed94SBarry Smith       if (!sorted) low = 0; high = nrow;
72292c4ed94SBarry Smith       while (high-low > 7) {
72392c4ed94SBarry Smith         t = (low+high)/2;
72492c4ed94SBarry Smith         if (rp[t] > col) high = t;
72592c4ed94SBarry Smith         else             low  = t;
72692c4ed94SBarry Smith       }
72792c4ed94SBarry Smith       for (i=low; i<high; i++) {
72892c4ed94SBarry Smith         if (rp[i] > col) break;
72992c4ed94SBarry Smith         if (rp[i] == col) {
7308a84c255SSatish Balay           bap  = ap +  bs2*i;
7310e324ae4SSatish Balay           if (roworiented) {
7328a84c255SSatish Balay             if (is == ADD_VALUES) {
733dd9472c6SBarry Smith               for (ii=0; ii<bs; ii++,value+=stepval) {
734dd9472c6SBarry Smith                 for (jj=ii; jj<bs2; jj+=bs) {
7358a84c255SSatish Balay                   bap[jj] += *value++;
736dd9472c6SBarry Smith                 }
737dd9472c6SBarry Smith               }
7380e324ae4SSatish Balay             } else {
739dd9472c6SBarry Smith               for (ii=0; ii<bs; ii++,value+=stepval) {
740dd9472c6SBarry Smith                 for (jj=ii; jj<bs2; jj+=bs) {
7410e324ae4SSatish Balay                   bap[jj] = *value++;
7428a84c255SSatish Balay                 }
743dd9472c6SBarry Smith               }
744dd9472c6SBarry Smith             }
7450e324ae4SSatish Balay           } else {
7460e324ae4SSatish Balay             if (is == ADD_VALUES) {
747dd9472c6SBarry Smith               for (ii=0; ii<bs; ii++,value+=stepval) {
748dd9472c6SBarry Smith                 for (jj=0; jj<bs; jj++) {
7490e324ae4SSatish Balay                   *bap++ += *value++;
750dd9472c6SBarry Smith                 }
751dd9472c6SBarry Smith               }
7520e324ae4SSatish Balay             } else {
753dd9472c6SBarry Smith               for (ii=0; ii<bs; ii++,value+=stepval) {
754dd9472c6SBarry Smith                 for (jj=0; jj<bs; jj++) {
7550e324ae4SSatish Balay                   *bap++  = *value++;
7560e324ae4SSatish Balay                 }
7578a84c255SSatish Balay               }
758dd9472c6SBarry Smith             }
759dd9472c6SBarry Smith           }
760f1241b54SBarry Smith           goto noinsert2;
76192c4ed94SBarry Smith         }
76292c4ed94SBarry Smith       }
76389280ab3SLois Curfman McInnes       if (nonew == 1) goto noinsert2;
76429bbc08cSBarry Smith       else if (nonew == -1) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Inserting a new nonzero in the matrix");
76592c4ed94SBarry Smith       if (nrow >= rmax) {
76692c4ed94SBarry Smith         /* there is no extra room in row, therefore enlarge */
76792c4ed94SBarry Smith         int       new_nz = ai[a->mbs] + CHUNKSIZE,len,*new_i,*new_j;
7683f1db9ecSBarry Smith         MatScalar *new_a;
76992c4ed94SBarry Smith 
77029bbc08cSBarry Smith         if (nonew == -2) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Inserting a new nonzero in the matrix");
77189280ab3SLois Curfman McInnes 
77292c4ed94SBarry Smith         /* malloc new storage space */
7733f1db9ecSBarry Smith         len     = new_nz*(sizeof(int)+bs2*sizeof(MatScalar))+(a->mbs+1)*sizeof(int);
774b0a32e0cSBarry Smith 	ierr    = PetscMalloc(len,&new_a);CHKERRQ(ierr);
77592c4ed94SBarry Smith         new_j   = (int*)(new_a + bs2*new_nz);
77692c4ed94SBarry Smith         new_i   = new_j + new_nz;
77792c4ed94SBarry Smith 
77892c4ed94SBarry Smith         /* copy over old data into new slots */
77992c4ed94SBarry Smith         for (ii=0; ii<row+1; ii++) {new_i[ii] = ai[ii];}
78092c4ed94SBarry Smith         for (ii=row+1; ii<a->mbs+1; ii++) {new_i[ii] = ai[ii]+CHUNKSIZE;}
781549d3d68SSatish Balay         ierr = PetscMemcpy(new_j,aj,(ai[row]+nrow)*sizeof(int));CHKERRQ(ierr);
78292c4ed94SBarry Smith         len  = (new_nz - CHUNKSIZE - ai[row] - nrow);
783549d3d68SSatish Balay         ierr = PetscMemcpy(new_j+ai[row]+nrow+CHUNKSIZE,aj+ai[row]+nrow,len*sizeof(int));CHKERRQ(ierr);
784549d3d68SSatish Balay         ierr = PetscMemcpy(new_a,aa,(ai[row]+nrow)*bs2*sizeof(MatScalar));CHKERRQ(ierr);
785549d3d68SSatish Balay         ierr = PetscMemzero(new_a+bs2*(ai[row]+nrow),bs2*CHUNKSIZE*sizeof(MatScalar));CHKERRQ(ierr);
786549d3d68SSatish Balay         ierr = PetscMemcpy(new_a+bs2*(ai[row]+nrow+CHUNKSIZE),aa+bs2*(ai[row]+nrow),bs2*len*sizeof(MatScalar));CHKERRQ(ierr);
78792c4ed94SBarry Smith         /* free up old matrix storage */
788606d414cSSatish Balay         ierr = PetscFree(a->a);CHKERRQ(ierr);
789606d414cSSatish Balay         if (!a->singlemalloc) {
790606d414cSSatish Balay           ierr = PetscFree(a->i);CHKERRQ(ierr);
791606d414cSSatish Balay           ierr = PetscFree(a->j);CHKERRQ(ierr);
792606d414cSSatish Balay         }
79392c4ed94SBarry Smith         aa = a->a = new_a; ai = a->i = new_i; aj = a->j = new_j;
794c4992f7dSBarry Smith         a->singlemalloc = PETSC_TRUE;
79592c4ed94SBarry Smith 
79692c4ed94SBarry Smith         rp   = aj + ai[row]; ap = aa + bs2*ai[row];
79792c4ed94SBarry Smith         rmax = imax[row] = imax[row] + CHUNKSIZE;
798b0a32e0cSBarry Smith         PetscLogObjectMemory(A,CHUNKSIZE*(sizeof(int) + bs2*sizeof(MatScalar)));
79992c4ed94SBarry Smith         a->maxnz += bs2*CHUNKSIZE;
80092c4ed94SBarry Smith         a->reallocs++;
80192c4ed94SBarry Smith         a->nz++;
80292c4ed94SBarry Smith       }
80392c4ed94SBarry Smith       N = nrow++ - 1;
80492c4ed94SBarry Smith       /* shift up all the later entries in this row */
80592c4ed94SBarry Smith       for (ii=N; ii>=i; ii--) {
80692c4ed94SBarry Smith         rp[ii+1] = rp[ii];
807549d3d68SSatish Balay         ierr = PetscMemcpy(ap+bs2*(ii+1),ap+bs2*(ii),bs2*sizeof(MatScalar));CHKERRQ(ierr);
80892c4ed94SBarry Smith       }
809549d3d68SSatish Balay       if (N >= i) {
810549d3d68SSatish Balay         ierr = PetscMemzero(ap+bs2*i,bs2*sizeof(MatScalar));CHKERRQ(ierr);
811549d3d68SSatish Balay       }
81292c4ed94SBarry Smith       rp[i] = col;
8138a84c255SSatish Balay       bap   = ap +  bs2*i;
8140e324ae4SSatish Balay       if (roworiented) {
815dd9472c6SBarry Smith         for (ii=0; ii<bs; ii++,value+=stepval) {
816dd9472c6SBarry Smith           for (jj=ii; jj<bs2; jj+=bs) {
8170e324ae4SSatish Balay             bap[jj] = *value++;
818dd9472c6SBarry Smith           }
819dd9472c6SBarry Smith         }
8200e324ae4SSatish Balay       } else {
821dd9472c6SBarry Smith         for (ii=0; ii<bs; ii++,value+=stepval) {
822dd9472c6SBarry Smith           for (jj=0; jj<bs; jj++) {
8230e324ae4SSatish Balay             *bap++  = *value++;
8240e324ae4SSatish Balay           }
825dd9472c6SBarry Smith         }
826dd9472c6SBarry Smith       }
827f1241b54SBarry Smith       noinsert2:;
82892c4ed94SBarry Smith       low = i;
82992c4ed94SBarry Smith     }
83092c4ed94SBarry Smith     ailen[row] = nrow;
83192c4ed94SBarry Smith   }
8323a40ed3dSBarry Smith   PetscFunctionReturn(0);
83392c4ed94SBarry Smith }
83492c4ed94SBarry Smith 
835f2501298SSatish Balay 
8364a2ae208SSatish Balay #undef __FUNCT__
8374a2ae208SSatish Balay #define __FUNCT__ "MatAssemblyEnd_SeqBAIJ"
8388f6be9afSLois Curfman McInnes int MatAssemblyEnd_SeqBAIJ(Mat A,MatAssemblyType mode)
839584200bdSSatish Balay {
840584200bdSSatish Balay   Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)A->data;
841584200bdSSatish Balay   int        fshift = 0,i,j,*ai = a->i,*aj = a->j,*imax = a->imax;
842273d9f13SBarry Smith   int        m = A->m,*ip,N,*ailen = a->ilen;
843549d3d68SSatish Balay   int        mbs = a->mbs,bs2 = a->bs2,rmax = 0,ierr;
8443f1db9ecSBarry Smith   MatScalar  *aa = a->a,*ap;
845584200bdSSatish Balay 
8463a40ed3dSBarry Smith   PetscFunctionBegin;
8473a40ed3dSBarry Smith   if (mode == MAT_FLUSH_ASSEMBLY) PetscFunctionReturn(0);
848584200bdSSatish Balay 
84943ee02c3SBarry Smith   if (m) rmax = ailen[0];
850584200bdSSatish Balay   for (i=1; i<mbs; i++) {
851584200bdSSatish Balay     /* move each row back by the amount of empty slots (fshift) before it*/
852584200bdSSatish Balay     fshift += imax[i-1] - ailen[i-1];
853d402145bSBarry Smith     rmax   = PetscMax(rmax,ailen[i]);
854584200bdSSatish Balay     if (fshift) {
855a7c10996SSatish Balay       ip = aj + ai[i]; ap = aa + bs2*ai[i];
856584200bdSSatish Balay       N = ailen[i];
857584200bdSSatish Balay       for (j=0; j<N; j++) {
858584200bdSSatish Balay         ip[j-fshift] = ip[j];
859549d3d68SSatish Balay         ierr = PetscMemcpy(ap+(j-fshift)*bs2,ap+j*bs2,bs2*sizeof(MatScalar));CHKERRQ(ierr);
860584200bdSSatish Balay       }
861584200bdSSatish Balay     }
862584200bdSSatish Balay     ai[i] = ai[i-1] + ailen[i-1];
863584200bdSSatish Balay   }
864584200bdSSatish Balay   if (mbs) {
865584200bdSSatish Balay     fshift += imax[mbs-1] - ailen[mbs-1];
866584200bdSSatish Balay     ai[mbs] = ai[mbs-1] + ailen[mbs-1];
867584200bdSSatish Balay   }
868584200bdSSatish Balay   /* reset ilen and imax for each row */
869584200bdSSatish Balay   for (i=0; i<mbs; i++) {
870584200bdSSatish Balay     ailen[i] = imax[i] = ai[i+1] - ai[i];
871584200bdSSatish Balay   }
872a7c10996SSatish Balay   a->nz = ai[mbs];
873584200bdSSatish Balay 
874584200bdSSatish Balay   /* diagonals may have moved, so kill the diagonal pointers */
875584200bdSSatish Balay   if (fshift && a->diag) {
876606d414cSSatish Balay     ierr = PetscFree(a->diag);CHKERRQ(ierr);
877b0a32e0cSBarry Smith     PetscLogObjectMemory(A,-(m+1)*sizeof(int));
878584200bdSSatish Balay     a->diag = 0;
879584200bdSSatish Balay   }
880bba1ac68SSatish Balay   PetscLogInfo(A,"MatAssemblyEnd_SeqBAIJ:Matrix size: %d X %d, block size %d; storage space: %d unneeded, %d used\n",m,A->n,a->bs,fshift*bs2,a->nz*bs2);
881bba1ac68SSatish Balay   PetscLogInfo(A,"MatAssemblyEnd_SeqBAIJ:Number of mallocs during MatSetValues is %d\n",a->reallocs);
882b0a32e0cSBarry Smith   PetscLogInfo(A,"MatAssemblyEnd_SeqBAIJ:Most nonzeros blocks in any row is %d\n",rmax);
883e2f3b5e9SSatish Balay   a->reallocs          = 0;
8840e6d2581SBarry Smith   A->info.nz_unneeded  = (PetscReal)fshift*bs2;
8854e220ebcSLois Curfman McInnes 
8863a40ed3dSBarry Smith   PetscFunctionReturn(0);
887584200bdSSatish Balay }
888584200bdSSatish Balay 
8895a838052SSatish Balay 
890bea157c4SSatish Balay 
891bea157c4SSatish Balay /*
892bea157c4SSatish Balay    This function returns an array of flags which indicate the locations of contiguous
893bea157c4SSatish Balay    blocks that should be zeroed. for eg: if bs = 3  and is = [0,1,2,3,5,6,7,8,9]
894bea157c4SSatish Balay    then the resulting sizes = [3,1,1,3,1] correspondig to sets [(0,1,2),(3),(5),(6,7,8),(9)]
895bea157c4SSatish Balay    Assume: sizes should be long enough to hold all the values.
896bea157c4SSatish Balay */
8974a2ae208SSatish Balay #undef __FUNCT__
8984a2ae208SSatish Balay #define __FUNCT__ "MatZeroRows_SeqBAIJ_Check_Blocks"
899bea157c4SSatish Balay static int MatZeroRows_SeqBAIJ_Check_Blocks(int idx[],int n,int bs,int sizes[], int *bs_max)
900d9b7c43dSSatish Balay {
901bea157c4SSatish Balay   int        i,j,k,row;
902bea157c4SSatish Balay   PetscTruth flg;
9033a40ed3dSBarry Smith 
904433994e6SBarry Smith   PetscFunctionBegin;
905bea157c4SSatish Balay   for (i=0,j=0; i<n; j++) {
906bea157c4SSatish Balay     row = idx[i];
907bea157c4SSatish Balay     if (row%bs!=0) { /* Not the begining of a block */
908bea157c4SSatish Balay       sizes[j] = 1;
909bea157c4SSatish Balay       i++;
910e4fda26cSSatish Balay     } else if (i+bs > n) { /* complete block doesn't exist (at idx end) */
911bea157c4SSatish Balay       sizes[j] = 1;         /* Also makes sure atleast 'bs' values exist for next else */
912bea157c4SSatish Balay       i++;
913bea157c4SSatish Balay     } else { /* Begining of the block, so check if the complete block exists */
914bea157c4SSatish Balay       flg = PETSC_TRUE;
915bea157c4SSatish Balay       for (k=1; k<bs; k++) {
916bea157c4SSatish Balay         if (row+k != idx[i+k]) { /* break in the block */
917bea157c4SSatish Balay           flg = PETSC_FALSE;
918bea157c4SSatish Balay           break;
919d9b7c43dSSatish Balay         }
920bea157c4SSatish Balay       }
921bea157c4SSatish Balay       if (flg == PETSC_TRUE) { /* No break in the bs */
922bea157c4SSatish Balay         sizes[j] = bs;
923bea157c4SSatish Balay         i+= bs;
924bea157c4SSatish Balay       } else {
925bea157c4SSatish Balay         sizes[j] = 1;
926bea157c4SSatish Balay         i++;
927bea157c4SSatish Balay       }
928bea157c4SSatish Balay     }
929bea157c4SSatish Balay   }
930bea157c4SSatish Balay   *bs_max = j;
9313a40ed3dSBarry Smith   PetscFunctionReturn(0);
932d9b7c43dSSatish Balay }
933d9b7c43dSSatish Balay 
9344a2ae208SSatish Balay #undef __FUNCT__
9354a2ae208SSatish Balay #define __FUNCT__ "MatZeroRows_SeqBAIJ"
93687828ca2SBarry Smith int MatZeroRows_SeqBAIJ(Mat A,IS is,PetscScalar *diag)
937d9b7c43dSSatish Balay {
938d9b7c43dSSatish Balay   Mat_SeqBAIJ *baij=(Mat_SeqBAIJ*)A->data;
939b6815fffSBarry Smith   int         ierr,i,j,k,count,is_n,*is_idx,*rows;
940bea157c4SSatish Balay   int         bs=baij->bs,bs2=baij->bs2,*sizes,row,bs_max;
94187828ca2SBarry Smith   PetscScalar zero = 0.0;
9423f1db9ecSBarry Smith   MatScalar   *aa;
943d9b7c43dSSatish Balay 
9443a40ed3dSBarry Smith   PetscFunctionBegin;
945d9b7c43dSSatish Balay   /* Make a copy of the IS and  sort it */
946b9b97703SBarry Smith   ierr = ISGetLocalSize(is,&is_n);CHKERRQ(ierr);
947d9b7c43dSSatish Balay   ierr = ISGetIndices(is,&is_idx);CHKERRQ(ierr);
948d9b7c43dSSatish Balay 
949bea157c4SSatish Balay   /* allocate memory for rows,sizes */
950b0a32e0cSBarry Smith   ierr  = PetscMalloc((3*is_n+1)*sizeof(int),&rows);CHKERRQ(ierr);
951bea157c4SSatish Balay   sizes = rows + is_n;
952bea157c4SSatish Balay 
953563b5814SBarry Smith   /* copy IS values to rows, and sort them */
954bea157c4SSatish Balay   for (i=0; i<is_n; i++) { rows[i] = is_idx[i]; }
955bea157c4SSatish Balay   ierr = PetscSortInt(is_n,rows);CHKERRQ(ierr);
956dffd3267SBarry Smith   if (baij->keepzeroedrows) {
957dffd3267SBarry Smith     for (i=0; i<is_n; i++) { sizes[i] = 1; }
958dffd3267SBarry Smith     bs_max = is_n;
959dffd3267SBarry Smith   } else {
960bea157c4SSatish Balay     ierr = MatZeroRows_SeqBAIJ_Check_Blocks(rows,is_n,bs,sizes,&bs_max);CHKERRQ(ierr);
961dffd3267SBarry Smith   }
962b97a56abSSatish Balay   ierr = ISRestoreIndices(is,&is_idx);CHKERRQ(ierr);
963bea157c4SSatish Balay 
964bea157c4SSatish Balay   for (i=0,j=0; i<bs_max; j+=sizes[i],i++) {
965bea157c4SSatish Balay     row   = rows[j];
966273d9f13SBarry Smith     if (row < 0 || row > A->m) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"row %d out of range",row);
967bea157c4SSatish Balay     count = (baij->i[row/bs +1] - baij->i[row/bs])*bs;
968bea157c4SSatish Balay     aa    = baij->a + baij->i[row/bs]*bs2 + (row%bs);
969dffd3267SBarry Smith     if (sizes[i] == bs && !baij->keepzeroedrows) {
970bea157c4SSatish Balay       if (diag) {
971bea157c4SSatish Balay         if (baij->ilen[row/bs] > 0) {
972bea157c4SSatish Balay           baij->ilen[row/bs]       = 1;
973bea157c4SSatish Balay           baij->j[baij->i[row/bs]] = row/bs;
974bea157c4SSatish Balay           ierr = PetscMemzero(aa,count*bs*sizeof(MatScalar));CHKERRQ(ierr);
975a07cd24cSSatish Balay         }
976563b5814SBarry Smith         /* Now insert all the diagonal values for this bs */
977bea157c4SSatish Balay         for (k=0; k<bs; k++) {
978bea157c4SSatish Balay           ierr = (*A->ops->setvalues)(A,1,rows+j+k,1,rows+j+k,diag,INSERT_VALUES);CHKERRQ(ierr);
979bea157c4SSatish Balay         }
980bea157c4SSatish Balay       } else { /* (!diag) */
981bea157c4SSatish Balay         baij->ilen[row/bs] = 0;
982bea157c4SSatish Balay       } /* end (!diag) */
983bea157c4SSatish Balay     } else { /* (sizes[i] != bs) */
984aa482453SBarry Smith #if defined (PETSC_USE_DEBUG)
98529bbc08cSBarry Smith       if (sizes[i] != 1) SETERRQ(1,"Internal Error. Value should be 1");
986bea157c4SSatish Balay #endif
987bea157c4SSatish Balay       for (k=0; k<count; k++) {
988d9b7c43dSSatish Balay         aa[0] =  zero;
989d9b7c43dSSatish Balay         aa    += bs;
990d9b7c43dSSatish Balay       }
991d9b7c43dSSatish Balay       if (diag) {
992f830108cSBarry Smith         ierr = (*A->ops->setvalues)(A,1,rows+j,1,rows+j,diag,INSERT_VALUES);CHKERRQ(ierr);
993d9b7c43dSSatish Balay       }
994d9b7c43dSSatish Balay     }
995bea157c4SSatish Balay   }
996bea157c4SSatish Balay 
997606d414cSSatish Balay   ierr = PetscFree(rows);CHKERRQ(ierr);
9989a8dea36SBarry Smith   ierr = MatAssemblyEnd_SeqBAIJ(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
9993a40ed3dSBarry Smith   PetscFunctionReturn(0);
1000d9b7c43dSSatish Balay }
10011c351548SSatish Balay 
10024a2ae208SSatish Balay #undef __FUNCT__
10034a2ae208SSatish Balay #define __FUNCT__ "MatSetValues_SeqBAIJ"
100487828ca2SBarry Smith int MatSetValues_SeqBAIJ(Mat A,int m,int *im,int n,int *in,PetscScalar *v,InsertMode is)
10052d61bbb3SSatish Balay {
10062d61bbb3SSatish Balay   Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)A->data;
10072d61bbb3SSatish Balay   int         *rp,k,low,high,t,ii,row,nrow,i,col,l,rmax,N,sorted=a->sorted;
1008273d9f13SBarry Smith   int         *imax=a->imax,*ai=a->i,*ailen=a->ilen;
10092d61bbb3SSatish Balay   int         *aj=a->j,nonew=a->nonew,bs=a->bs,brow,bcol;
1010549d3d68SSatish Balay   int         ridx,cidx,bs2=a->bs2,ierr;
1011273d9f13SBarry Smith   PetscTruth  roworiented=a->roworiented;
10123f1db9ecSBarry Smith   MatScalar   *ap,value,*aa=a->a,*bap;
10132d61bbb3SSatish Balay 
10142d61bbb3SSatish Balay   PetscFunctionBegin;
10152d61bbb3SSatish Balay   for (k=0; k<m; k++) { /* loop over added rows */
10162d61bbb3SSatish Balay     row  = im[k]; brow = row/bs;
10175ef9f2a5SBarry Smith     if (row < 0) continue;
1018aa482453SBarry Smith #if defined(PETSC_USE_BOPT_g)
1019273d9f13SBarry Smith     if (row >= A->m) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"Row too large: row %d max %d",row,A->m);
10202d61bbb3SSatish Balay #endif
10212d61bbb3SSatish Balay     rp   = aj + ai[brow];
10222d61bbb3SSatish Balay     ap   = aa + bs2*ai[brow];
10232d61bbb3SSatish Balay     rmax = imax[brow];
10242d61bbb3SSatish Balay     nrow = ailen[brow];
10252d61bbb3SSatish Balay     low  = 0;
10262d61bbb3SSatish Balay     for (l=0; l<n; l++) { /* loop over added columns */
10275ef9f2a5SBarry Smith       if (in[l] < 0) continue;
1028aa482453SBarry Smith #if defined(PETSC_USE_BOPT_g)
1029273d9f13SBarry Smith       if (in[l] >= A->n) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"Column too large: col %d max %d",in[l],A->n);
10302d61bbb3SSatish Balay #endif
10312d61bbb3SSatish Balay       col = in[l]; bcol = col/bs;
10322d61bbb3SSatish Balay       ridx = row % bs; cidx = col % bs;
10332d61bbb3SSatish Balay       if (roworiented) {
10345ef9f2a5SBarry Smith         value = v[l + k*n];
10352d61bbb3SSatish Balay       } else {
10362d61bbb3SSatish Balay         value = v[k + l*m];
10372d61bbb3SSatish Balay       }
10382d61bbb3SSatish Balay       if (!sorted) low = 0; high = nrow;
10392d61bbb3SSatish Balay       while (high-low > 7) {
10402d61bbb3SSatish Balay         t = (low+high)/2;
10412d61bbb3SSatish Balay         if (rp[t] > bcol) high = t;
10422d61bbb3SSatish Balay         else              low  = t;
10432d61bbb3SSatish Balay       }
10442d61bbb3SSatish Balay       for (i=low; i<high; i++) {
10452d61bbb3SSatish Balay         if (rp[i] > bcol) break;
10462d61bbb3SSatish Balay         if (rp[i] == bcol) {
10472d61bbb3SSatish Balay           bap  = ap +  bs2*i + bs*cidx + ridx;
10482d61bbb3SSatish Balay           if (is == ADD_VALUES) *bap += value;
10492d61bbb3SSatish Balay           else                  *bap  = value;
10502d61bbb3SSatish Balay           goto noinsert1;
10512d61bbb3SSatish Balay         }
10522d61bbb3SSatish Balay       }
10532d61bbb3SSatish Balay       if (nonew == 1) goto noinsert1;
105429bbc08cSBarry Smith       else if (nonew == -1) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Inserting a new nonzero in the matrix");
10552d61bbb3SSatish Balay       if (nrow >= rmax) {
10562d61bbb3SSatish Balay         /* there is no extra room in row, therefore enlarge */
10572d61bbb3SSatish Balay         int       new_nz = ai[a->mbs] + CHUNKSIZE,len,*new_i,*new_j;
10583f1db9ecSBarry Smith         MatScalar *new_a;
10592d61bbb3SSatish Balay 
106029bbc08cSBarry Smith         if (nonew == -2) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Inserting a new nonzero in the matrix");
10612d61bbb3SSatish Balay 
10622d61bbb3SSatish Balay         /* Malloc new storage space */
10633f1db9ecSBarry Smith         len     = new_nz*(sizeof(int)+bs2*sizeof(MatScalar))+(a->mbs+1)*sizeof(int);
1064b0a32e0cSBarry Smith 	ierr    = PetscMalloc(len,&new_a);CHKERRQ(ierr);
10652d61bbb3SSatish Balay         new_j   = (int*)(new_a + bs2*new_nz);
10662d61bbb3SSatish Balay         new_i   = new_j + new_nz;
10672d61bbb3SSatish Balay 
10682d61bbb3SSatish Balay         /* copy over old data into new slots */
10692d61bbb3SSatish Balay         for (ii=0; ii<brow+1; ii++) {new_i[ii] = ai[ii];}
10702d61bbb3SSatish Balay         for (ii=brow+1; ii<a->mbs+1; ii++) {new_i[ii] = ai[ii]+CHUNKSIZE;}
1071549d3d68SSatish Balay         ierr = PetscMemcpy(new_j,aj,(ai[brow]+nrow)*sizeof(int));CHKERRQ(ierr);
10722d61bbb3SSatish Balay         len  = (new_nz - CHUNKSIZE - ai[brow] - nrow);
1073549d3d68SSatish Balay         ierr = PetscMemcpy(new_j+ai[brow]+nrow+CHUNKSIZE,aj+ai[brow]+nrow,len*sizeof(int));CHKERRQ(ierr);
1074549d3d68SSatish Balay         ierr = PetscMemcpy(new_a,aa,(ai[brow]+nrow)*bs2*sizeof(MatScalar));CHKERRQ(ierr);
1075549d3d68SSatish Balay         ierr = PetscMemzero(new_a+bs2*(ai[brow]+nrow),bs2*CHUNKSIZE*sizeof(MatScalar));CHKERRQ(ierr);
1076549d3d68SSatish Balay         ierr = PetscMemcpy(new_a+bs2*(ai[brow]+nrow+CHUNKSIZE),aa+bs2*(ai[brow]+nrow),bs2*len*sizeof(MatScalar));CHKERRQ(ierr);
10772d61bbb3SSatish Balay         /* free up old matrix storage */
1078606d414cSSatish Balay         ierr = PetscFree(a->a);CHKERRQ(ierr);
1079606d414cSSatish Balay         if (!a->singlemalloc) {
1080606d414cSSatish Balay           ierr = PetscFree(a->i);CHKERRQ(ierr);
1081606d414cSSatish Balay           ierr = PetscFree(a->j);CHKERRQ(ierr);
1082606d414cSSatish Balay         }
10832d61bbb3SSatish Balay         aa = a->a = new_a; ai = a->i = new_i; aj = a->j = new_j;
1084c4992f7dSBarry Smith         a->singlemalloc = PETSC_TRUE;
10852d61bbb3SSatish Balay 
10862d61bbb3SSatish Balay         rp   = aj + ai[brow]; ap = aa + bs2*ai[brow];
10872d61bbb3SSatish Balay         rmax = imax[brow] = imax[brow] + CHUNKSIZE;
1088b0a32e0cSBarry Smith         PetscLogObjectMemory(A,CHUNKSIZE*(sizeof(int) + bs2*sizeof(MatScalar)));
10892d61bbb3SSatish Balay         a->maxnz += bs2*CHUNKSIZE;
10902d61bbb3SSatish Balay         a->reallocs++;
10912d61bbb3SSatish Balay         a->nz++;
10922d61bbb3SSatish Balay       }
10932d61bbb3SSatish Balay       N = nrow++ - 1;
10942d61bbb3SSatish Balay       /* shift up all the later entries in this row */
10952d61bbb3SSatish Balay       for (ii=N; ii>=i; ii--) {
10962d61bbb3SSatish Balay         rp[ii+1] = rp[ii];
1097549d3d68SSatish Balay         ierr     = PetscMemcpy(ap+bs2*(ii+1),ap+bs2*(ii),bs2*sizeof(MatScalar));CHKERRQ(ierr);
10982d61bbb3SSatish Balay       }
1099549d3d68SSatish Balay       if (N>=i) {
1100549d3d68SSatish Balay         ierr = PetscMemzero(ap+bs2*i,bs2*sizeof(MatScalar));CHKERRQ(ierr);
1101549d3d68SSatish Balay       }
11022d61bbb3SSatish Balay       rp[i]                      = bcol;
11032d61bbb3SSatish Balay       ap[bs2*i + bs*cidx + ridx] = value;
11042d61bbb3SSatish Balay       noinsert1:;
11052d61bbb3SSatish Balay       low = i;
11062d61bbb3SSatish Balay     }
11072d61bbb3SSatish Balay     ailen[brow] = nrow;
11082d61bbb3SSatish Balay   }
11092d61bbb3SSatish Balay   PetscFunctionReturn(0);
11102d61bbb3SSatish Balay }
11112d61bbb3SSatish Balay 
11122d61bbb3SSatish Balay 
11134a2ae208SSatish Balay #undef __FUNCT__
11144a2ae208SSatish Balay #define __FUNCT__ "MatILUFactor_SeqBAIJ"
11155ef9f2a5SBarry Smith int MatILUFactor_SeqBAIJ(Mat inA,IS row,IS col,MatILUInfo *info)
11162d61bbb3SSatish Balay {
11172d61bbb3SSatish Balay   Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)inA->data;
11182d61bbb3SSatish Balay   Mat         outA;
11192d61bbb3SSatish Balay   int         ierr;
1120667159a5SBarry Smith   PetscTruth  row_identity,col_identity;
11212d61bbb3SSatish Balay 
11222d61bbb3SSatish Balay   PetscFunctionBegin;
112329bbc08cSBarry Smith   if (info && info->levels != 0) SETERRQ(PETSC_ERR_SUP,"Only levels = 0 supported for in-place ILU");
1124667159a5SBarry Smith   ierr = ISIdentity(row,&row_identity);CHKERRQ(ierr);
1125667159a5SBarry Smith   ierr = ISIdentity(col,&col_identity);CHKERRQ(ierr);
1126667159a5SBarry Smith   if (!row_identity || !col_identity) {
112729bbc08cSBarry Smith     SETERRQ(1,"Row and column permutations must be identity for in-place ILU");
1128667159a5SBarry Smith   }
11292d61bbb3SSatish Balay 
11302d61bbb3SSatish Balay   outA          = inA;
11312d61bbb3SSatish Balay   inA->factor   = FACTOR_LU;
11322d61bbb3SSatish Balay 
11332d61bbb3SSatish Balay   if (!a->diag) {
1134c4992f7dSBarry Smith     ierr = MatMarkDiagonal_SeqBAIJ(inA);CHKERRQ(ierr);
11352d61bbb3SSatish Balay   }
1136cf242676SKris Buschelman 
1137c38d4ed2SBarry Smith   a->row        = row;
1138c38d4ed2SBarry Smith   a->col        = col;
1139c38d4ed2SBarry Smith   ierr          = PetscObjectReference((PetscObject)row);CHKERRQ(ierr);
1140c38d4ed2SBarry Smith   ierr          = PetscObjectReference((PetscObject)col);CHKERRQ(ierr);
1141c38d4ed2SBarry Smith 
1142c38d4ed2SBarry Smith   /* Create the invert permutation so that it can be used in MatLUFactorNumeric() */
11434c49b128SBarry Smith   ierr = ISInvertPermutation(col,PETSC_DECIDE,&a->icol);CHKERRQ(ierr);
1144b0a32e0cSBarry Smith   PetscLogObjectParent(inA,a->icol);
1145c38d4ed2SBarry Smith 
1146cf242676SKris Buschelman   /*
1147cf242676SKris Buschelman       Blocksize 2, 3, 4, 5, 6 and 7 have a special faster factorization/solver
1148cf242676SKris Buschelman       for ILU(0) factorization with natural ordering
1149cf242676SKris Buschelman   */
1150cf242676SKris Buschelman   if (a->bs < 8) {
1151cf242676SKris Buschelman     ierr = MatSeqBAIJ_UpdateFactorNumeric_NaturalOrdering(inA);CHKERRQ(ierr);
1152cf242676SKris Buschelman   } else {
1153c38d4ed2SBarry Smith     if (!a->solve_work) {
115487828ca2SBarry Smith       ierr = PetscMalloc((inA->m+a->bs)*sizeof(PetscScalar),&a->solve_work);CHKERRQ(ierr);
115587828ca2SBarry Smith       PetscLogObjectMemory(inA,(inA->m+a->bs)*sizeof(PetscScalar));
1156c38d4ed2SBarry Smith     }
11572d61bbb3SSatish Balay   }
11582d61bbb3SSatish Balay 
1159667159a5SBarry Smith   ierr = MatLUFactorNumeric(inA,&outA);CHKERRQ(ierr);
1160667159a5SBarry Smith 
11612d61bbb3SSatish Balay   PetscFunctionReturn(0);
11622d61bbb3SSatish Balay }
11634a2ae208SSatish Balay #undef __FUNCT__
11644a2ae208SSatish Balay #define __FUNCT__ "MatPrintHelp_SeqBAIJ"
1165ba4ca20aSSatish Balay int MatPrintHelp_SeqBAIJ(Mat A)
1166ba4ca20aSSatish Balay {
1167c38d4ed2SBarry Smith   static PetscTruth called = PETSC_FALSE;
1168ba4ca20aSSatish Balay   MPI_Comm          comm = A->comm;
1169d132466eSBarry Smith   int               ierr;
1170ba4ca20aSSatish Balay 
11713a40ed3dSBarry Smith   PetscFunctionBegin;
1172c38d4ed2SBarry Smith   if (called) {PetscFunctionReturn(0);} else called = PETSC_TRUE;
1173d132466eSBarry Smith   ierr = (*PetscHelpPrintf)(comm," Options for MATSEQBAIJ and MATMPIBAIJ matrix formats (the defaults):\n");CHKERRQ(ierr);
1174d132466eSBarry Smith   ierr = (*PetscHelpPrintf)(comm,"  -mat_block_size <block_size>\n");CHKERRQ(ierr);
11753a40ed3dSBarry Smith   PetscFunctionReturn(0);
1176ba4ca20aSSatish Balay }
1177d9b7c43dSSatish Balay 
1178fb2e594dSBarry Smith EXTERN_C_BEGIN
11794a2ae208SSatish Balay #undef __FUNCT__
11804a2ae208SSatish Balay #define __FUNCT__ "MatSeqBAIJSetColumnIndices_SeqBAIJ"
118127a8da17SBarry Smith int MatSeqBAIJSetColumnIndices_SeqBAIJ(Mat mat,int *indices)
118227a8da17SBarry Smith {
118327a8da17SBarry Smith   Mat_SeqBAIJ *baij = (Mat_SeqBAIJ *)mat->data;
1184*14db4f74SSatish Balay   int         i,nz,nbs;
118527a8da17SBarry Smith 
118627a8da17SBarry Smith   PetscFunctionBegin;
1187*14db4f74SSatish Balay   nz  = baij->maxnz/baij->bs2;
1188*14db4f74SSatish Balay   nbs = baij->nbs;
118927a8da17SBarry Smith   for (i=0; i<nz; i++) {
119027a8da17SBarry Smith     baij->j[i] = indices[i];
119127a8da17SBarry Smith   }
119227a8da17SBarry Smith   baij->nz = nz;
1193*14db4f74SSatish Balay   for (i=0; i<nbs; i++) {
119427a8da17SBarry Smith     baij->ilen[i] = baij->imax[i];
119527a8da17SBarry Smith   }
119627a8da17SBarry Smith 
119727a8da17SBarry Smith   PetscFunctionReturn(0);
119827a8da17SBarry Smith }
1199fb2e594dSBarry Smith EXTERN_C_END
120027a8da17SBarry Smith 
12014a2ae208SSatish Balay #undef __FUNCT__
12024a2ae208SSatish Balay #define __FUNCT__ "MatSeqBAIJSetColumnIndices"
120327a8da17SBarry Smith /*@
120427a8da17SBarry Smith     MatSeqBAIJSetColumnIndices - Set the column indices for all the rows
120527a8da17SBarry Smith        in the matrix.
120627a8da17SBarry Smith 
120727a8da17SBarry Smith   Input Parameters:
120827a8da17SBarry Smith +  mat - the SeqBAIJ matrix
120927a8da17SBarry Smith -  indices - the column indices
121027a8da17SBarry Smith 
121115091d37SBarry Smith   Level: advanced
121215091d37SBarry Smith 
121327a8da17SBarry Smith   Notes:
121427a8da17SBarry Smith     This can be called if you have precomputed the nonzero structure of the
121527a8da17SBarry Smith   matrix and want to provide it to the matrix object to improve the performance
121627a8da17SBarry Smith   of the MatSetValues() operation.
121727a8da17SBarry Smith 
121827a8da17SBarry Smith     You MUST have set the correct numbers of nonzeros per row in the call to
121927a8da17SBarry Smith   MatCreateSeqBAIJ().
122027a8da17SBarry Smith 
122127a8da17SBarry Smith     MUST be called before any calls to MatSetValues();
122227a8da17SBarry Smith 
122327a8da17SBarry Smith @*/
122427a8da17SBarry Smith int MatSeqBAIJSetColumnIndices(Mat mat,int *indices)
122527a8da17SBarry Smith {
122627a8da17SBarry Smith   int ierr,(*f)(Mat,int *);
122727a8da17SBarry Smith 
122827a8da17SBarry Smith   PetscFunctionBegin;
122927a8da17SBarry Smith   PetscValidHeaderSpecific(mat,MAT_COOKIE);
1230c134de8dSSatish Balay   ierr = PetscObjectQueryFunction((PetscObject)mat,"MatSeqBAIJSetColumnIndices_C",(void (**)(void))&f);CHKERRQ(ierr);
123127a8da17SBarry Smith   if (f) {
123227a8da17SBarry Smith     ierr = (*f)(mat,indices);CHKERRQ(ierr);
123327a8da17SBarry Smith   } else {
123429bbc08cSBarry Smith     SETERRQ(1,"Wrong type of matrix to set column indices");
123527a8da17SBarry Smith   }
123627a8da17SBarry Smith   PetscFunctionReturn(0);
123727a8da17SBarry Smith }
123827a8da17SBarry Smith 
12394a2ae208SSatish Balay #undef __FUNCT__
12404a2ae208SSatish Balay #define __FUNCT__ "MatGetRowMax_SeqBAIJ"
1241273d9f13SBarry Smith int MatGetRowMax_SeqBAIJ(Mat A,Vec v)
1242273d9f13SBarry Smith {
1243273d9f13SBarry Smith   Mat_SeqBAIJ  *a = (Mat_SeqBAIJ*)A->data;
1244273d9f13SBarry Smith   int          ierr,i,j,n,row,bs,*ai,*aj,mbs;
1245273d9f13SBarry Smith   PetscReal    atmp;
124687828ca2SBarry Smith   PetscScalar  *x,zero = 0.0;
1247273d9f13SBarry Smith   MatScalar    *aa;
1248273d9f13SBarry Smith   int          ncols,brow,krow,kcol;
1249273d9f13SBarry Smith 
1250273d9f13SBarry Smith   PetscFunctionBegin;
1251273d9f13SBarry Smith   if (A->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1252273d9f13SBarry Smith   bs   = a->bs;
1253273d9f13SBarry Smith   aa   = a->a;
1254273d9f13SBarry Smith   ai   = a->i;
1255273d9f13SBarry Smith   aj   = a->j;
1256273d9f13SBarry Smith   mbs = a->mbs;
1257273d9f13SBarry Smith 
1258273d9f13SBarry Smith   ierr = VecSet(&zero,v);CHKERRQ(ierr);
1259273d9f13SBarry Smith   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
1260273d9f13SBarry Smith   ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr);
1261273d9f13SBarry Smith   if (n != A->m) SETERRQ(PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector");
1262273d9f13SBarry Smith   for (i=0; i<mbs; i++) {
1263273d9f13SBarry Smith     ncols = ai[1] - ai[0]; ai++;
1264273d9f13SBarry Smith     brow  = bs*i;
1265273d9f13SBarry Smith     for (j=0; j<ncols; j++){
1266273d9f13SBarry Smith       /* bcol = bs*(*aj); */
1267273d9f13SBarry Smith       for (kcol=0; kcol<bs; kcol++){
1268273d9f13SBarry Smith         for (krow=0; krow<bs; krow++){
1269273d9f13SBarry Smith           atmp = PetscAbsScalar(*aa); aa++;
1270273d9f13SBarry Smith           row = brow + krow;    /* row index */
1271273d9f13SBarry Smith           /* printf("val[%d,%d]: %g\n",row,bcol+kcol,atmp); */
1272273d9f13SBarry Smith           if (PetscAbsScalar(x[row]) < atmp) x[row] = atmp;
1273273d9f13SBarry Smith         }
1274273d9f13SBarry Smith       }
1275273d9f13SBarry Smith       aj++;
1276273d9f13SBarry Smith     }
1277273d9f13SBarry Smith   }
1278273d9f13SBarry Smith   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
1279273d9f13SBarry Smith   PetscFunctionReturn(0);
1280273d9f13SBarry Smith }
1281273d9f13SBarry Smith 
12824a2ae208SSatish Balay #undef __FUNCT__
12834a2ae208SSatish Balay #define __FUNCT__ "MatSetUpPreallocation_SeqBAIJ"
1284273d9f13SBarry Smith int MatSetUpPreallocation_SeqBAIJ(Mat A)
1285273d9f13SBarry Smith {
1286273d9f13SBarry Smith   int        ierr;
1287273d9f13SBarry Smith 
1288273d9f13SBarry Smith   PetscFunctionBegin;
1289273d9f13SBarry Smith   ierr =  MatSeqBAIJSetPreallocation(A,1,PETSC_DEFAULT,0);CHKERRQ(ierr);
1290273d9f13SBarry Smith   PetscFunctionReturn(0);
1291273d9f13SBarry Smith }
1292273d9f13SBarry Smith 
12934a2ae208SSatish Balay #undef __FUNCT__
12944a2ae208SSatish Balay #define __FUNCT__ "MatGetArray_SeqBAIJ"
129587828ca2SBarry Smith int MatGetArray_SeqBAIJ(Mat A,PetscScalar **array)
1296f2a5309cSSatish Balay {
1297f2a5309cSSatish Balay   Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)A->data;
1298f2a5309cSSatish Balay   PetscFunctionBegin;
1299f2a5309cSSatish Balay   *array = a->a;
1300f2a5309cSSatish Balay   PetscFunctionReturn(0);
1301f2a5309cSSatish Balay }
1302f2a5309cSSatish Balay 
13034a2ae208SSatish Balay #undef __FUNCT__
13044a2ae208SSatish Balay #define __FUNCT__ "MatRestoreArray_SeqBAIJ"
130587828ca2SBarry Smith int MatRestoreArray_SeqBAIJ(Mat A,PetscScalar **array)
1306f2a5309cSSatish Balay {
1307f2a5309cSSatish Balay   PetscFunctionBegin;
1308f2a5309cSSatish Balay   PetscFunctionReturn(0);
1309f2a5309cSSatish Balay }
1310f2a5309cSSatish Balay 
13112593348eSBarry Smith /* -------------------------------------------------------------------*/
1312cc2dc46cSBarry Smith static struct _MatOps MatOps_Values = {MatSetValues_SeqBAIJ,
1313cc2dc46cSBarry Smith        MatGetRow_SeqBAIJ,
1314cc2dc46cSBarry Smith        MatRestoreRow_SeqBAIJ,
1315cc2dc46cSBarry Smith        MatMult_SeqBAIJ_N,
1316cc2dc46cSBarry Smith        MatMultAdd_SeqBAIJ_N,
13177c922b88SBarry Smith        MatMultTranspose_SeqBAIJ,
13187c922b88SBarry Smith        MatMultTransposeAdd_SeqBAIJ,
1319cc2dc46cSBarry Smith        MatSolve_SeqBAIJ_N,
1320cc2dc46cSBarry Smith        0,
1321cc2dc46cSBarry Smith        0,
1322cc2dc46cSBarry Smith        0,
1323cc2dc46cSBarry Smith        MatLUFactor_SeqBAIJ,
1324cc2dc46cSBarry Smith        0,
1325b6490206SBarry Smith        0,
1326f2501298SSatish Balay        MatTranspose_SeqBAIJ,
1327cc2dc46cSBarry Smith        MatGetInfo_SeqBAIJ,
1328cc2dc46cSBarry Smith        MatEqual_SeqBAIJ,
1329cc2dc46cSBarry Smith        MatGetDiagonal_SeqBAIJ,
1330cc2dc46cSBarry Smith        MatDiagonalScale_SeqBAIJ,
1331cc2dc46cSBarry Smith        MatNorm_SeqBAIJ,
1332b6490206SBarry Smith        0,
1333cc2dc46cSBarry Smith        MatAssemblyEnd_SeqBAIJ,
1334cc2dc46cSBarry Smith        0,
1335cc2dc46cSBarry Smith        MatSetOption_SeqBAIJ,
1336cc2dc46cSBarry Smith        MatZeroEntries_SeqBAIJ,
1337cc2dc46cSBarry Smith        MatZeroRows_SeqBAIJ,
1338cc2dc46cSBarry Smith        MatLUFactorSymbolic_SeqBAIJ,
1339cc2dc46cSBarry Smith        MatLUFactorNumeric_SeqBAIJ_N,
1340cc2dc46cSBarry Smith        0,
1341cc2dc46cSBarry Smith        0,
1342273d9f13SBarry Smith        MatSetUpPreallocation_SeqBAIJ,
1343cc2dc46cSBarry Smith        MatILUFactorSymbolic_SeqBAIJ,
1344cc2dc46cSBarry Smith        0,
1345f2a5309cSSatish Balay        MatGetArray_SeqBAIJ,
1346f2a5309cSSatish Balay        MatRestoreArray_SeqBAIJ,
13472e8a6d31SBarry Smith        MatDuplicate_SeqBAIJ,
1348cc2dc46cSBarry Smith        0,
1349cc2dc46cSBarry Smith        0,
1350cc2dc46cSBarry Smith        MatILUFactor_SeqBAIJ,
1351cc2dc46cSBarry Smith        0,
1352cc2dc46cSBarry Smith        0,
1353cc2dc46cSBarry Smith        MatGetSubMatrices_SeqBAIJ,
1354cc2dc46cSBarry Smith        MatIncreaseOverlap_SeqBAIJ,
1355cc2dc46cSBarry Smith        MatGetValues_SeqBAIJ,
1356cc2dc46cSBarry Smith        0,
1357cc2dc46cSBarry Smith        MatPrintHelp_SeqBAIJ,
1358cc2dc46cSBarry Smith        MatScale_SeqBAIJ,
1359cc2dc46cSBarry Smith        0,
1360cc2dc46cSBarry Smith        0,
1361cc2dc46cSBarry Smith        0,
1362cc2dc46cSBarry Smith        MatGetBlockSize_SeqBAIJ,
13633b2fbd54SBarry Smith        MatGetRowIJ_SeqBAIJ,
136492c4ed94SBarry Smith        MatRestoreRowIJ_SeqBAIJ,
1365cc2dc46cSBarry Smith        0,
1366cc2dc46cSBarry Smith        0,
1367cc2dc46cSBarry Smith        0,
1368cc2dc46cSBarry Smith        0,
1369cc2dc46cSBarry Smith        0,
1370cc2dc46cSBarry Smith        0,
1371d3825aa8SBarry Smith        MatSetValuesBlocked_SeqBAIJ,
1372cc2dc46cSBarry Smith        MatGetSubMatrix_SeqBAIJ,
1373b9b97703SBarry Smith        MatDestroy_SeqBAIJ,
1374b9b97703SBarry Smith        MatView_SeqBAIJ,
13753a64cc32SBarry Smith        MatGetPetscMaps_Petsc,
1376273d9f13SBarry Smith        0,
1377273d9f13SBarry Smith        0,
1378273d9f13SBarry Smith        0,
1379273d9f13SBarry Smith        0,
1380273d9f13SBarry Smith        0,
1381273d9f13SBarry Smith        0,
1382273d9f13SBarry Smith        MatGetRowMax_SeqBAIJ,
1383273d9f13SBarry Smith        MatConvert_Basic};
13842593348eSBarry Smith 
13853e90b805SBarry Smith EXTERN_C_BEGIN
13864a2ae208SSatish Balay #undef __FUNCT__
13874a2ae208SSatish Balay #define __FUNCT__ "MatStoreValues_SeqBAIJ"
13883e90b805SBarry Smith int MatStoreValues_SeqBAIJ(Mat mat)
13893e90b805SBarry Smith {
13903e90b805SBarry Smith   Mat_SeqBAIJ *aij = (Mat_SeqBAIJ *)mat->data;
1391273d9f13SBarry Smith   int         nz = aij->i[mat->m]*aij->bs*aij->bs2;
1392d132466eSBarry Smith   int         ierr;
13933e90b805SBarry Smith 
13943e90b805SBarry Smith   PetscFunctionBegin;
13953e90b805SBarry Smith   if (aij->nonew != 1) {
139629bbc08cSBarry Smith     SETERRQ(1,"Must call MatSetOption(A,MAT_NO_NEW_NONZERO_LOCATIONS);first");
13973e90b805SBarry Smith   }
13983e90b805SBarry Smith 
13993e90b805SBarry Smith   /* allocate space for values if not already there */
14003e90b805SBarry Smith   if (!aij->saved_values) {
140187828ca2SBarry Smith     ierr = PetscMalloc((nz+1)*sizeof(PetscScalar),&aij->saved_values);CHKERRQ(ierr);
14023e90b805SBarry Smith   }
14033e90b805SBarry Smith 
14043e90b805SBarry Smith   /* copy values over */
140587828ca2SBarry Smith   ierr = PetscMemcpy(aij->saved_values,aij->a,nz*sizeof(PetscScalar));CHKERRQ(ierr);
14063e90b805SBarry Smith   PetscFunctionReturn(0);
14073e90b805SBarry Smith }
14083e90b805SBarry Smith EXTERN_C_END
14093e90b805SBarry Smith 
14103e90b805SBarry Smith EXTERN_C_BEGIN
14114a2ae208SSatish Balay #undef __FUNCT__
14124a2ae208SSatish Balay #define __FUNCT__ "MatRetrieveValues_SeqBAIJ"
141332e87ba3SBarry Smith int MatRetrieveValues_SeqBAIJ(Mat mat)
14143e90b805SBarry Smith {
14153e90b805SBarry Smith   Mat_SeqBAIJ *aij = (Mat_SeqBAIJ *)mat->data;
1416273d9f13SBarry Smith   int         nz = aij->i[mat->m]*aij->bs*aij->bs2,ierr;
14173e90b805SBarry Smith 
14183e90b805SBarry Smith   PetscFunctionBegin;
14193e90b805SBarry Smith   if (aij->nonew != 1) {
142029bbc08cSBarry Smith     SETERRQ(1,"Must call MatSetOption(A,MAT_NO_NEW_NONZERO_LOCATIONS);first");
14213e90b805SBarry Smith   }
14223e90b805SBarry Smith   if (!aij->saved_values) {
142329bbc08cSBarry Smith     SETERRQ(1,"Must call MatStoreValues(A);first");
14243e90b805SBarry Smith   }
14253e90b805SBarry Smith 
14263e90b805SBarry Smith   /* copy values over */
142787828ca2SBarry Smith   ierr = PetscMemcpy(aij->a,aij->saved_values,nz*sizeof(PetscScalar));CHKERRQ(ierr);
14283e90b805SBarry Smith   PetscFunctionReturn(0);
14293e90b805SBarry Smith }
14303e90b805SBarry Smith EXTERN_C_END
14313e90b805SBarry Smith 
1432273d9f13SBarry Smith EXTERN_C_BEGIN
1433273d9f13SBarry Smith extern int MatConvert_SeqBAIJ_SeqAIJ(Mat,MatType,Mat*);
1434273d9f13SBarry Smith EXTERN_C_END
1435273d9f13SBarry Smith 
1436273d9f13SBarry Smith EXTERN_C_BEGIN
14374a2ae208SSatish Balay #undef __FUNCT__
14384a2ae208SSatish Balay #define __FUNCT__ "MatCreate_SeqBAIJ"
1439273d9f13SBarry Smith int MatCreate_SeqBAIJ(Mat B)
14402593348eSBarry Smith {
1441273d9f13SBarry Smith   int         ierr,size;
1442b6490206SBarry Smith   Mat_SeqBAIJ *b;
14433b2fbd54SBarry Smith 
14443a40ed3dSBarry Smith   PetscFunctionBegin;
1445273d9f13SBarry Smith   ierr = MPI_Comm_size(B->comm,&size);CHKERRQ(ierr);
144629bbc08cSBarry Smith   if (size > 1) SETERRQ(PETSC_ERR_ARG_WRONG,"Comm must be of size 1");
1447b6490206SBarry Smith 
1448273d9f13SBarry Smith   B->m = B->M = PetscMax(B->m,B->M);
1449273d9f13SBarry Smith   B->n = B->N = PetscMax(B->n,B->N);
1450b0a32e0cSBarry Smith   ierr    = PetscNew(Mat_SeqBAIJ,&b);CHKERRQ(ierr);
1451b0a32e0cSBarry Smith   B->data = (void*)b;
1452549d3d68SSatish Balay   ierr    = PetscMemzero(b,sizeof(Mat_SeqBAIJ));CHKERRQ(ierr);
1453549d3d68SSatish Balay   ierr    = PetscMemcpy(B->ops,&MatOps_Values,sizeof(struct _MatOps));CHKERRQ(ierr);
14542593348eSBarry Smith   B->factor           = 0;
14552593348eSBarry Smith   B->lupivotthreshold = 1.0;
145690f02eecSBarry Smith   B->mapping          = 0;
14572593348eSBarry Smith   b->row              = 0;
14582593348eSBarry Smith   b->col              = 0;
1459e51c0b9cSSatish Balay   b->icol             = 0;
14602593348eSBarry Smith   b->reallocs         = 0;
14613e90b805SBarry Smith   b->saved_values     = 0;
1462cfce73b9SSatish Balay #if defined(PETSC_USE_MAT_SINGLE)
1463563b5814SBarry Smith   b->setvalueslen     = 0;
1464563b5814SBarry Smith   b->setvaluescopy    = PETSC_NULL;
1465563b5814SBarry Smith #endif
14668661488fSKris Buschelman   b->single_precision_solves = PETSC_FALSE;
14672593348eSBarry Smith 
14683a64cc32SBarry Smith   ierr = PetscMapCreateMPI(B->comm,B->m,B->m,&B->rmap);CHKERRQ(ierr);
14693a64cc32SBarry Smith   ierr = PetscMapCreateMPI(B->comm,B->n,B->n,&B->cmap);CHKERRQ(ierr);
1470a5ae1ecdSBarry Smith 
1471c4992f7dSBarry Smith   b->sorted           = PETSC_FALSE;
1472c4992f7dSBarry Smith   b->roworiented      = PETSC_TRUE;
14732593348eSBarry Smith   b->nonew            = 0;
14742593348eSBarry Smith   b->diag             = 0;
14752593348eSBarry Smith   b->solve_work       = 0;
1476de6a44a3SBarry Smith   b->mult_work        = 0;
14772593348eSBarry Smith   b->spptr            = 0;
14780e6d2581SBarry Smith   B->info.nz_unneeded = (PetscReal)b->maxnz;
1479883fce79SBarry Smith   b->keepzeroedrows   = PETSC_FALSE;
14804e220ebcSLois Curfman McInnes 
1481f1af5d2fSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatStoreValues_C",
14823e90b805SBarry Smith                                      "MatStoreValues_SeqBAIJ",
1483bc4b532fSSatish Balay                                       MatStoreValues_SeqBAIJ);CHKERRQ(ierr);
1484f1af5d2fSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatRetrieveValues_C",
14853e90b805SBarry Smith                                      "MatRetrieveValues_SeqBAIJ",
1486bc4b532fSSatish Balay                                       MatRetrieveValues_SeqBAIJ);CHKERRQ(ierr);
1487f1af5d2fSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatSeqBAIJSetColumnIndices_C",
148827a8da17SBarry Smith                                      "MatSeqBAIJSetColumnIndices_SeqBAIJ",
1489bc4b532fSSatish Balay                                       MatSeqBAIJSetColumnIndices_SeqBAIJ);CHKERRQ(ierr);
1490273d9f13SBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatConvert_SeqBAIJ_SeqAIJ_C",
1491273d9f13SBarry Smith                                      "MatConvert_SeqBAIJ_SeqAIJ",
1492273d9f13SBarry Smith                                       MatConvert_SeqBAIJ_SeqAIJ);CHKERRQ(ierr);
14933a40ed3dSBarry Smith   PetscFunctionReturn(0);
14942593348eSBarry Smith }
1495273d9f13SBarry Smith EXTERN_C_END
14962593348eSBarry Smith 
14974a2ae208SSatish Balay #undef __FUNCT__
14984a2ae208SSatish Balay #define __FUNCT__ "MatDuplicate_SeqBAIJ"
14992e8a6d31SBarry Smith int MatDuplicate_SeqBAIJ(Mat A,MatDuplicateOption cpvalues,Mat *B)
15002593348eSBarry Smith {
15012593348eSBarry Smith   Mat         C;
1502b6490206SBarry Smith   Mat_SeqBAIJ *c,*a = (Mat_SeqBAIJ*)A->data;
150327a8da17SBarry Smith   int         i,len,mbs = a->mbs,nz = a->nz,bs2 =a->bs2,ierr;
1504de6a44a3SBarry Smith 
15053a40ed3dSBarry Smith   PetscFunctionBegin;
150629bbc08cSBarry Smith   if (a->i[mbs] != nz) SETERRQ(PETSC_ERR_PLIB,"Corrupt matrix");
15072593348eSBarry Smith 
15082593348eSBarry Smith   *B = 0;
1509273d9f13SBarry Smith   ierr = MatCreate(A->comm,A->m,A->n,A->m,A->n,&C);CHKERRQ(ierr);
1510273d9f13SBarry Smith   ierr = MatSetType(C,MATSEQBAIJ);CHKERRQ(ierr);
1511273d9f13SBarry Smith   c    = (Mat_SeqBAIJ*)C->data;
151244cd7ae7SLois Curfman McInnes 
1513b6490206SBarry Smith   c->bs         = a->bs;
15149df24120SSatish Balay   c->bs2        = a->bs2;
1515b6490206SBarry Smith   c->mbs        = a->mbs;
1516b6490206SBarry Smith   c->nbs        = a->nbs;
151735d8aa7fSBarry Smith   ierr = PetscMemcpy(C->ops,A->ops,sizeof(struct _MatOps));CHKERRQ(ierr);
15182593348eSBarry Smith 
1519b0a32e0cSBarry Smith   ierr = PetscMalloc((mbs+1)*sizeof(int),&c->imax);CHKERRQ(ierr);
1520b0a32e0cSBarry Smith   ierr = PetscMalloc((mbs+1)*sizeof(int),&c->ilen);CHKERRQ(ierr);
1521b6490206SBarry Smith   for (i=0; i<mbs; i++) {
15222593348eSBarry Smith     c->imax[i] = a->imax[i];
15232593348eSBarry Smith     c->ilen[i] = a->ilen[i];
15242593348eSBarry Smith   }
15252593348eSBarry Smith 
15262593348eSBarry Smith   /* allocate the matrix space */
1527c4992f7dSBarry Smith   c->singlemalloc = PETSC_TRUE;
15283f1db9ecSBarry Smith   len  = (mbs+1)*sizeof(int) + nz*(bs2*sizeof(MatScalar) + sizeof(int));
1529b0a32e0cSBarry Smith   ierr = PetscMalloc(len,&c->a);CHKERRQ(ierr);
15307e67e3f9SSatish Balay   c->j = (int*)(c->a + nz*bs2);
1531de6a44a3SBarry Smith   c->i = c->j + nz;
1532549d3d68SSatish Balay   ierr = PetscMemcpy(c->i,a->i,(mbs+1)*sizeof(int));CHKERRQ(ierr);
1533b6490206SBarry Smith   if (mbs > 0) {
1534549d3d68SSatish Balay     ierr = PetscMemcpy(c->j,a->j,nz*sizeof(int));CHKERRQ(ierr);
15352e8a6d31SBarry Smith     if (cpvalues == MAT_COPY_VALUES) {
1536549d3d68SSatish Balay       ierr = PetscMemcpy(c->a,a->a,bs2*nz*sizeof(MatScalar));CHKERRQ(ierr);
15372e8a6d31SBarry Smith     } else {
1538549d3d68SSatish Balay       ierr = PetscMemzero(c->a,bs2*nz*sizeof(MatScalar));CHKERRQ(ierr);
15392593348eSBarry Smith     }
15402593348eSBarry Smith   }
15412593348eSBarry Smith 
1542b0a32e0cSBarry Smith   PetscLogObjectMemory(C,len+2*(mbs+1)*sizeof(int)+sizeof(struct _p_Mat)+sizeof(Mat_SeqBAIJ));
15432593348eSBarry Smith   c->sorted      = a->sorted;
15442593348eSBarry Smith   c->roworiented = a->roworiented;
15452593348eSBarry Smith   c->nonew       = a->nonew;
15462593348eSBarry Smith 
15472593348eSBarry Smith   if (a->diag) {
1548b0a32e0cSBarry Smith     ierr = PetscMalloc((mbs+1)*sizeof(int),&c->diag);CHKERRQ(ierr);
1549b0a32e0cSBarry Smith     PetscLogObjectMemory(C,(mbs+1)*sizeof(int));
1550b6490206SBarry Smith     for (i=0; i<mbs; i++) {
15512593348eSBarry Smith       c->diag[i] = a->diag[i];
15522593348eSBarry Smith     }
155398305bb5SBarry Smith   } else c->diag        = 0;
15542593348eSBarry Smith   c->nz                 = a->nz;
15552593348eSBarry Smith   c->maxnz              = a->maxnz;
15562593348eSBarry Smith   c->solve_work         = 0;
15572593348eSBarry Smith   c->spptr              = 0;      /* Dangerous -I'm throwing away a->spptr */
15587fc0212eSBarry Smith   c->mult_work          = 0;
1559273d9f13SBarry Smith   C->preallocated       = PETSC_TRUE;
1560273d9f13SBarry Smith   C->assembled          = PETSC_TRUE;
15612593348eSBarry Smith   *B = C;
1562b0a32e0cSBarry Smith   ierr = PetscFListDuplicate(A->qlist,&C->qlist);CHKERRQ(ierr);
15633a40ed3dSBarry Smith   PetscFunctionReturn(0);
15642593348eSBarry Smith }
15652593348eSBarry Smith 
1566273d9f13SBarry Smith EXTERN_C_BEGIN
15674a2ae208SSatish Balay #undef __FUNCT__
15684a2ae208SSatish Balay #define __FUNCT__ "MatLoad_SeqBAIJ"
1569b0a32e0cSBarry Smith int MatLoad_SeqBAIJ(PetscViewer viewer,MatType type,Mat *A)
15702593348eSBarry Smith {
1571b6490206SBarry Smith   Mat_SeqBAIJ  *a;
15722593348eSBarry Smith   Mat          B;
1573f1af5d2fSBarry Smith   int          i,nz,ierr,fd,header[4],size,*rowlengths=0,M,N,bs=1;
1574b6490206SBarry Smith   int          *mask,mbs,*jj,j,rowcount,nzcount,k,*browlengths,maskcount;
157535aab85fSBarry Smith   int          kmax,jcount,block,idx,point,nzcountb,extra_rows;
1576a7c10996SSatish Balay   int          *masked,nmask,tmp,bs2,ishift;
157787828ca2SBarry Smith   PetscScalar  *aa;
157819bcc07fSBarry Smith   MPI_Comm     comm = ((PetscObject)viewer)->comm;
15792593348eSBarry Smith 
15803a40ed3dSBarry Smith   PetscFunctionBegin;
1581b0a32e0cSBarry Smith   ierr = PetscOptionsGetInt(PETSC_NULL,"-matload_block_size",&bs,PETSC_NULL);CHKERRQ(ierr);
1582de6a44a3SBarry Smith   bs2  = bs*bs;
1583b6490206SBarry Smith 
1584d132466eSBarry Smith   ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr);
158529bbc08cSBarry Smith   if (size > 1) SETERRQ(PETSC_ERR_ARG_WRONG,"view must have one processor");
1586b0a32e0cSBarry Smith   ierr = PetscViewerBinaryGetDescriptor(viewer,&fd);CHKERRQ(ierr);
15870752156aSBarry Smith   ierr = PetscBinaryRead(fd,header,4,PETSC_INT);CHKERRQ(ierr);
1588552e946dSBarry Smith   if (header[0] != MAT_FILE_COOKIE) SETERRQ(PETSC_ERR_FILE_UNEXPECTED,"not Mat object");
15892593348eSBarry Smith   M = header[1]; N = header[2]; nz = header[3];
15902593348eSBarry Smith 
1591d64ed03dSBarry Smith   if (header[3] < 0) {
159229bbc08cSBarry Smith     SETERRQ(PETSC_ERR_FILE_UNEXPECTED,"Matrix stored in special format, cannot load as SeqBAIJ");
1593d64ed03dSBarry Smith   }
1594d64ed03dSBarry Smith 
159529bbc08cSBarry Smith   if (M != N) SETERRQ(PETSC_ERR_SUP,"Can only do square matrices");
159635aab85fSBarry Smith 
159735aab85fSBarry Smith   /*
159835aab85fSBarry Smith      This code adds extra rows to make sure the number of rows is
159935aab85fSBarry Smith     divisible by the blocksize
160035aab85fSBarry Smith   */
1601b6490206SBarry Smith   mbs        = M/bs;
160235aab85fSBarry Smith   extra_rows = bs - M + bs*(mbs);
160335aab85fSBarry Smith   if (extra_rows == bs) extra_rows = 0;
160435aab85fSBarry Smith   else                  mbs++;
160535aab85fSBarry Smith   if (extra_rows) {
1606b0a32e0cSBarry Smith     PetscLogInfo(0,"MatLoad_SeqBAIJ:Padding loaded matrix to match blocksize\n");
160735aab85fSBarry Smith   }
1608b6490206SBarry Smith 
16092593348eSBarry Smith   /* read in row lengths */
1610b0a32e0cSBarry Smith   ierr = PetscMalloc((M+extra_rows)*sizeof(int),&rowlengths);CHKERRQ(ierr);
16110752156aSBarry Smith   ierr = PetscBinaryRead(fd,rowlengths,M,PETSC_INT);CHKERRQ(ierr);
161235aab85fSBarry Smith   for (i=0; i<extra_rows; i++) rowlengths[M+i] = 1;
16132593348eSBarry Smith 
1614b6490206SBarry Smith   /* read in column indices */
1615b0a32e0cSBarry Smith   ierr = PetscMalloc((nz+extra_rows)*sizeof(int),&jj);CHKERRQ(ierr);
16160752156aSBarry Smith   ierr = PetscBinaryRead(fd,jj,nz,PETSC_INT);CHKERRQ(ierr);
161735aab85fSBarry Smith   for (i=0; i<extra_rows; i++) jj[nz+i] = M+i;
1618b6490206SBarry Smith 
1619b6490206SBarry Smith   /* loop over row lengths determining block row lengths */
1620b0a32e0cSBarry Smith   ierr     = PetscMalloc(mbs*sizeof(int),&browlengths);CHKERRQ(ierr);
1621549d3d68SSatish Balay   ierr     = PetscMemzero(browlengths,mbs*sizeof(int));CHKERRQ(ierr);
1622b0a32e0cSBarry Smith   ierr     = PetscMalloc(2*mbs*sizeof(int),&mask);CHKERRQ(ierr);
1623549d3d68SSatish Balay   ierr     = PetscMemzero(mask,mbs*sizeof(int));CHKERRQ(ierr);
162435aab85fSBarry Smith   masked   = mask + mbs;
1625b6490206SBarry Smith   rowcount = 0; nzcount = 0;
1626b6490206SBarry Smith   for (i=0; i<mbs; i++) {
162735aab85fSBarry Smith     nmask = 0;
1628b6490206SBarry Smith     for (j=0; j<bs; j++) {
1629b6490206SBarry Smith       kmax = rowlengths[rowcount];
1630b6490206SBarry Smith       for (k=0; k<kmax; k++) {
163135aab85fSBarry Smith         tmp = jj[nzcount++]/bs;
163235aab85fSBarry Smith         if (!mask[tmp]) {masked[nmask++] = tmp; mask[tmp] = 1;}
1633b6490206SBarry Smith       }
1634b6490206SBarry Smith       rowcount++;
1635b6490206SBarry Smith     }
163635aab85fSBarry Smith     browlengths[i] += nmask;
163735aab85fSBarry Smith     /* zero out the mask elements we set */
163835aab85fSBarry Smith     for (j=0; j<nmask; j++) mask[masked[j]] = 0;
1639b6490206SBarry Smith   }
1640b6490206SBarry Smith 
16412593348eSBarry Smith   /* create our matrix */
16423eee16b0SBarry Smith   ierr = MatCreateSeqBAIJ(comm,bs,M+extra_rows,N+extra_rows,0,browlengths,A);CHKERRQ(ierr);
16432593348eSBarry Smith   B = *A;
1644b6490206SBarry Smith   a = (Mat_SeqBAIJ*)B->data;
16452593348eSBarry Smith 
16462593348eSBarry Smith   /* set matrix "i" values */
1647de6a44a3SBarry Smith   a->i[0] = 0;
1648b6490206SBarry Smith   for (i=1; i<= mbs; i++) {
1649b6490206SBarry Smith     a->i[i]      = a->i[i-1] + browlengths[i-1];
1650b6490206SBarry Smith     a->ilen[i-1] = browlengths[i-1];
16512593348eSBarry Smith   }
1652b6490206SBarry Smith   a->nz         = 0;
1653b6490206SBarry Smith   for (i=0; i<mbs; i++) a->nz += browlengths[i];
16542593348eSBarry Smith 
1655b6490206SBarry Smith   /* read in nonzero values */
165687828ca2SBarry Smith   ierr = PetscMalloc((nz+extra_rows)*sizeof(PetscScalar),&aa);CHKERRQ(ierr);
16570752156aSBarry Smith   ierr = PetscBinaryRead(fd,aa,nz,PETSC_SCALAR);CHKERRQ(ierr);
165835aab85fSBarry Smith   for (i=0; i<extra_rows; i++) aa[nz+i] = 1.0;
1659b6490206SBarry Smith 
1660b6490206SBarry Smith   /* set "a" and "j" values into matrix */
1661b6490206SBarry Smith   nzcount = 0; jcount = 0;
1662b6490206SBarry Smith   for (i=0; i<mbs; i++) {
1663b6490206SBarry Smith     nzcountb = nzcount;
166435aab85fSBarry Smith     nmask    = 0;
1665b6490206SBarry Smith     for (j=0; j<bs; j++) {
1666b6490206SBarry Smith       kmax = rowlengths[i*bs+j];
1667b6490206SBarry Smith       for (k=0; k<kmax; k++) {
166835aab85fSBarry Smith         tmp = jj[nzcount++]/bs;
166935aab85fSBarry Smith 	if (!mask[tmp]) { masked[nmask++] = tmp; mask[tmp] = 1;}
1670b6490206SBarry Smith       }
1671b6490206SBarry Smith     }
1672de6a44a3SBarry Smith     /* sort the masked values */
1673433994e6SBarry Smith     ierr = PetscSortInt(nmask,masked);CHKERRQ(ierr);
1674de6a44a3SBarry Smith 
1675b6490206SBarry Smith     /* set "j" values into matrix */
1676b6490206SBarry Smith     maskcount = 1;
167735aab85fSBarry Smith     for (j=0; j<nmask; j++) {
167835aab85fSBarry Smith       a->j[jcount++]  = masked[j];
1679de6a44a3SBarry Smith       mask[masked[j]] = maskcount++;
1680b6490206SBarry Smith     }
1681b6490206SBarry Smith     /* set "a" values into matrix */
1682de6a44a3SBarry Smith     ishift = bs2*a->i[i];
1683b6490206SBarry Smith     for (j=0; j<bs; j++) {
1684b6490206SBarry Smith       kmax = rowlengths[i*bs+j];
1685b6490206SBarry Smith       for (k=0; k<kmax; k++) {
1686de6a44a3SBarry Smith         tmp       = jj[nzcountb]/bs ;
1687de6a44a3SBarry Smith         block     = mask[tmp] - 1;
1688de6a44a3SBarry Smith         point     = jj[nzcountb] - bs*tmp;
1689de6a44a3SBarry Smith         idx       = ishift + bs2*block + j + bs*point;
1690375fe846SBarry Smith         a->a[idx] = (MatScalar)aa[nzcountb++];
1691b6490206SBarry Smith       }
1692b6490206SBarry Smith     }
169335aab85fSBarry Smith     /* zero out the mask elements we set */
169435aab85fSBarry Smith     for (j=0; j<nmask; j++) mask[masked[j]] = 0;
1695b6490206SBarry Smith   }
169629bbc08cSBarry Smith   if (jcount != a->nz) SETERRQ(PETSC_ERR_FILE_UNEXPECTED,"Bad binary matrix");
1697b6490206SBarry Smith 
1698606d414cSSatish Balay   ierr = PetscFree(rowlengths);CHKERRQ(ierr);
1699606d414cSSatish Balay   ierr = PetscFree(browlengths);CHKERRQ(ierr);
1700606d414cSSatish Balay   ierr = PetscFree(aa);CHKERRQ(ierr);
1701606d414cSSatish Balay   ierr = PetscFree(jj);CHKERRQ(ierr);
1702606d414cSSatish Balay   ierr = PetscFree(mask);CHKERRQ(ierr);
1703b6490206SBarry Smith 
1704b6490206SBarry Smith   B->assembled = PETSC_TRUE;
1705de6a44a3SBarry Smith 
17069c01be13SBarry Smith   ierr = MatView_Private(B);CHKERRQ(ierr);
17073a40ed3dSBarry Smith   PetscFunctionReturn(0);
17082593348eSBarry Smith }
1709273d9f13SBarry Smith EXTERN_C_END
17102593348eSBarry Smith 
17114a2ae208SSatish Balay #undef __FUNCT__
17124a2ae208SSatish Balay #define __FUNCT__ "MatCreateSeqBAIJ"
1713273d9f13SBarry Smith /*@C
1714273d9f13SBarry Smith    MatCreateSeqBAIJ - Creates a sparse matrix in block AIJ (block
1715273d9f13SBarry Smith    compressed row) format.  For good matrix assembly performance the
1716273d9f13SBarry Smith    user should preallocate the matrix storage by setting the parameter nz
1717273d9f13SBarry Smith    (or the array nnz).  By setting these parameters accurately, performance
1718273d9f13SBarry Smith    during matrix assembly can be increased by more than a factor of 50.
17192593348eSBarry Smith 
1720273d9f13SBarry Smith    Collective on MPI_Comm
1721273d9f13SBarry Smith 
1722273d9f13SBarry Smith    Input Parameters:
1723273d9f13SBarry Smith +  comm - MPI communicator, set to PETSC_COMM_SELF
1724273d9f13SBarry Smith .  bs - size of block
1725273d9f13SBarry Smith .  m - number of rows
1726273d9f13SBarry Smith .  n - number of columns
172735d8aa7fSBarry Smith .  nz - number of nonzero blocks  per block row (same for all rows)
172835d8aa7fSBarry Smith -  nnz - array containing the number of nonzero blocks in the various block rows
1729273d9f13SBarry Smith          (possibly different for each block row) or PETSC_NULL
1730273d9f13SBarry Smith 
1731273d9f13SBarry Smith    Output Parameter:
1732273d9f13SBarry Smith .  A - the matrix
1733273d9f13SBarry Smith 
1734273d9f13SBarry Smith    Options Database Keys:
1735273d9f13SBarry Smith .   -mat_no_unroll - uses code that does not unroll the loops in the
1736273d9f13SBarry Smith                      block calculations (much slower)
1737273d9f13SBarry Smith .    -mat_block_size - size of the blocks to use
1738273d9f13SBarry Smith 
1739273d9f13SBarry Smith    Level: intermediate
1740273d9f13SBarry Smith 
1741273d9f13SBarry Smith    Notes:
174235d8aa7fSBarry Smith    A nonzero block is any block that as 1 or more nonzeros in it
174335d8aa7fSBarry Smith 
1744273d9f13SBarry Smith    The block AIJ format is fully compatible with standard Fortran 77
1745273d9f13SBarry Smith    storage.  That is, the stored row and column indices can begin at
1746273d9f13SBarry Smith    either one (as in Fortran) or zero.  See the users' manual for details.
1747273d9f13SBarry Smith 
1748273d9f13SBarry Smith    Specify the preallocated storage with either nz or nnz (not both).
1749273d9f13SBarry Smith    Set nz=PETSC_DEFAULT and nnz=PETSC_NULL for PETSc to control dynamic memory
1750273d9f13SBarry Smith    allocation.  For additional details, see the users manual chapter on
1751273d9f13SBarry Smith    matrices.
1752273d9f13SBarry Smith 
1753273d9f13SBarry Smith .seealso: MatCreate(), MatCreateSeqAIJ(), MatSetValues(), MatCreateMPIBAIJ()
1754273d9f13SBarry Smith @*/
1755273d9f13SBarry Smith int MatCreateSeqBAIJ(MPI_Comm comm,int bs,int m,int n,int nz,int *nnz,Mat *A)
1756273d9f13SBarry Smith {
1757273d9f13SBarry Smith   int ierr;
1758273d9f13SBarry Smith 
1759273d9f13SBarry Smith   PetscFunctionBegin;
1760273d9f13SBarry Smith   ierr = MatCreate(comm,m,n,m,n,A);CHKERRQ(ierr);
1761273d9f13SBarry Smith   ierr = MatSetType(*A,MATSEQBAIJ);CHKERRQ(ierr);
1762273d9f13SBarry Smith   ierr = MatSeqBAIJSetPreallocation(*A,bs,nz,nnz);CHKERRQ(ierr);
1763273d9f13SBarry Smith   PetscFunctionReturn(0);
1764273d9f13SBarry Smith }
1765273d9f13SBarry Smith 
17664a2ae208SSatish Balay #undef __FUNCT__
17674a2ae208SSatish Balay #define __FUNCT__ "MatSeqBAIJSetPreallocation"
1768273d9f13SBarry Smith /*@C
1769273d9f13SBarry Smith    MatSeqBAIJSetPreallocation - Sets the block size and expected nonzeros
1770273d9f13SBarry Smith    per row in the matrix. For good matrix assembly performance the
1771273d9f13SBarry Smith    user should preallocate the matrix storage by setting the parameter nz
1772273d9f13SBarry Smith    (or the array nnz).  By setting these parameters accurately, performance
1773273d9f13SBarry Smith    during matrix assembly can be increased by more than a factor of 50.
1774273d9f13SBarry Smith 
1775273d9f13SBarry Smith    Collective on MPI_Comm
1776273d9f13SBarry Smith 
1777273d9f13SBarry Smith    Input Parameters:
1778273d9f13SBarry Smith +  A - the matrix
1779273d9f13SBarry Smith .  bs - size of block
1780273d9f13SBarry Smith .  nz - number of block nonzeros per block row (same for all rows)
1781273d9f13SBarry Smith -  nnz - array containing the number of block nonzeros in the various block rows
1782273d9f13SBarry Smith          (possibly different for each block row) or PETSC_NULL
1783273d9f13SBarry Smith 
1784273d9f13SBarry Smith    Options Database Keys:
1785273d9f13SBarry Smith .   -mat_no_unroll - uses code that does not unroll the loops in the
1786273d9f13SBarry Smith                      block calculations (much slower)
1787273d9f13SBarry Smith .    -mat_block_size - size of the blocks to use
1788273d9f13SBarry Smith 
1789273d9f13SBarry Smith    Level: intermediate
1790273d9f13SBarry Smith 
1791273d9f13SBarry Smith    Notes:
1792273d9f13SBarry Smith    The block AIJ format is fully compatible with standard Fortran 77
1793273d9f13SBarry Smith    storage.  That is, the stored row and column indices can begin at
1794273d9f13SBarry Smith    either one (as in Fortran) or zero.  See the users' manual for details.
1795273d9f13SBarry Smith 
1796273d9f13SBarry Smith    Specify the preallocated storage with either nz or nnz (not both).
1797273d9f13SBarry Smith    Set nz=PETSC_DEFAULT and nnz=PETSC_NULL for PETSc to control dynamic memory
1798273d9f13SBarry Smith    allocation.  For additional details, see the users manual chapter on
1799273d9f13SBarry Smith    matrices.
1800273d9f13SBarry Smith 
1801273d9f13SBarry Smith .seealso: MatCreate(), MatCreateSeqAIJ(), MatSetValues(), MatCreateMPIBAIJ()
1802273d9f13SBarry Smith @*/
1803273d9f13SBarry Smith int MatSeqBAIJSetPreallocation(Mat B,int bs,int nz,int *nnz)
1804273d9f13SBarry Smith {
1805273d9f13SBarry Smith   Mat_SeqBAIJ *b;
1806273d9f13SBarry Smith   int         i,len,ierr,mbs,nbs,bs2,newbs = bs;
1807273d9f13SBarry Smith   PetscTruth  flg;
1808273d9f13SBarry Smith 
1809273d9f13SBarry Smith   PetscFunctionBegin;
1810273d9f13SBarry Smith   ierr = PetscTypeCompare((PetscObject)B,MATSEQBAIJ,&flg);CHKERRQ(ierr);
1811273d9f13SBarry Smith   if (!flg) PetscFunctionReturn(0);
1812273d9f13SBarry Smith 
1813273d9f13SBarry Smith   B->preallocated = PETSC_TRUE;
1814b0a32e0cSBarry Smith   ierr = PetscOptionsGetInt(B->prefix,"-mat_block_size",&newbs,PETSC_NULL);CHKERRQ(ierr);
1815273d9f13SBarry Smith   if (nnz && newbs != bs) {
1816273d9f13SBarry Smith     SETERRQ(1,"Cannot change blocksize from command line if setting nnz");
1817273d9f13SBarry Smith   }
1818273d9f13SBarry Smith   bs   = newbs;
1819273d9f13SBarry Smith 
1820273d9f13SBarry Smith   mbs  = B->m/bs;
1821273d9f13SBarry Smith   nbs  = B->n/bs;
1822273d9f13SBarry Smith   bs2  = bs*bs;
1823273d9f13SBarry Smith 
1824273d9f13SBarry Smith   if (mbs*bs!=B->m || nbs*bs!=B->n) {
182535d8aa7fSBarry Smith     SETERRQ3(PETSC_ERR_ARG_SIZ,"Number rows %d, cols %d must be divisible by blocksize %d",B->m,B->n,bs);
1826273d9f13SBarry Smith   }
1827273d9f13SBarry Smith 
1828435da068SBarry Smith   if (nz == PETSC_DEFAULT || nz == PETSC_DECIDE) nz = 5;
1829435da068SBarry Smith   if (nz < 0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"nz cannot be less than 0: value %d",nz);
1830273d9f13SBarry Smith   if (nnz) {
1831273d9f13SBarry Smith     for (i=0; i<mbs; i++) {
1832273d9f13SBarry Smith       if (nnz[i] < 0) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"nnz cannot be less than 0: local row %d value %d",i,nnz[i]);
18333a7fca6bSBarry 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);
1834273d9f13SBarry Smith     }
1835273d9f13SBarry Smith   }
1836273d9f13SBarry Smith 
1837273d9f13SBarry Smith   b       = (Mat_SeqBAIJ*)B->data;
1838b0a32e0cSBarry Smith   ierr    = PetscOptionsHasName(PETSC_NULL,"-mat_no_unroll",&flg);CHKERRQ(ierr);
183954138f6bSKris Buschelman   B->ops->solve               = MatSolve_SeqBAIJ_Update;
184054138f6bSKris Buschelman   B->ops->solvetranspose      = MatSolveTranspose_SeqBAIJ_Update;
1841273d9f13SBarry Smith   if (!flg) {
1842273d9f13SBarry Smith     switch (bs) {
1843273d9f13SBarry Smith     case 1:
1844273d9f13SBarry Smith       B->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_1;
1845273d9f13SBarry Smith       B->ops->mult            = MatMult_SeqBAIJ_1;
1846273d9f13SBarry Smith       B->ops->multadd         = MatMultAdd_SeqBAIJ_1;
1847273d9f13SBarry Smith       break;
1848273d9f13SBarry Smith     case 2:
1849273d9f13SBarry Smith       B->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_2;
1850273d9f13SBarry Smith       B->ops->mult            = MatMult_SeqBAIJ_2;
1851273d9f13SBarry Smith       B->ops->multadd         = MatMultAdd_SeqBAIJ_2;
1852273d9f13SBarry Smith       break;
1853273d9f13SBarry Smith     case 3:
1854273d9f13SBarry Smith       B->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_3;
1855273d9f13SBarry Smith       B->ops->mult            = MatMult_SeqBAIJ_3;
1856273d9f13SBarry Smith       B->ops->multadd         = MatMultAdd_SeqBAIJ_3;
1857273d9f13SBarry Smith       break;
1858273d9f13SBarry Smith     case 4:
1859273d9f13SBarry Smith       B->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_4;
1860273d9f13SBarry Smith       B->ops->mult            = MatMult_SeqBAIJ_4;
1861273d9f13SBarry Smith       B->ops->multadd         = MatMultAdd_SeqBAIJ_4;
1862273d9f13SBarry Smith       break;
1863273d9f13SBarry Smith     case 5:
1864273d9f13SBarry Smith       B->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_5;
1865273d9f13SBarry Smith       B->ops->mult            = MatMult_SeqBAIJ_5;
1866273d9f13SBarry Smith       B->ops->multadd         = MatMultAdd_SeqBAIJ_5;
1867273d9f13SBarry Smith       break;
1868273d9f13SBarry Smith     case 6:
1869273d9f13SBarry Smith       B->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_6;
1870273d9f13SBarry Smith       B->ops->mult            = MatMult_SeqBAIJ_6;
1871273d9f13SBarry Smith       B->ops->multadd         = MatMultAdd_SeqBAIJ_6;
1872273d9f13SBarry Smith       break;
1873273d9f13SBarry Smith     case 7:
187454138f6bSKris Buschelman       B->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_7;
1875273d9f13SBarry Smith       B->ops->mult            = MatMult_SeqBAIJ_7;
1876273d9f13SBarry Smith       B->ops->multadd         = MatMultAdd_SeqBAIJ_7;
1877273d9f13SBarry Smith       break;
1878273d9f13SBarry Smith     default:
187954138f6bSKris Buschelman       B->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_N;
1880273d9f13SBarry Smith       B->ops->mult            = MatMult_SeqBAIJ_N;
1881273d9f13SBarry Smith       B->ops->multadd         = MatMultAdd_SeqBAIJ_N;
1882273d9f13SBarry Smith       break;
1883273d9f13SBarry Smith     }
1884273d9f13SBarry Smith   }
1885273d9f13SBarry Smith   b->bs      = bs;
1886273d9f13SBarry Smith   b->mbs     = mbs;
1887273d9f13SBarry Smith   b->nbs     = nbs;
1888b0a32e0cSBarry Smith   ierr = PetscMalloc((mbs+1)*sizeof(int),&b->imax);CHKERRQ(ierr);
1889273d9f13SBarry Smith   if (!nnz) {
1890435da068SBarry Smith     if (nz == PETSC_DEFAULT || nz == PETSC_DECIDE) nz = 5;
1891273d9f13SBarry Smith     else if (nz <= 0)        nz = 1;
1892273d9f13SBarry Smith     for (i=0; i<mbs; i++) b->imax[i] = nz;
1893273d9f13SBarry Smith     nz = nz*mbs;
1894273d9f13SBarry Smith   } else {
1895273d9f13SBarry Smith     nz = 0;
1896273d9f13SBarry Smith     for (i=0; i<mbs; i++) {b->imax[i] = nnz[i]; nz += nnz[i];}
1897273d9f13SBarry Smith   }
1898273d9f13SBarry Smith 
1899273d9f13SBarry Smith   /* allocate the matrix space */
1900273d9f13SBarry Smith   len   = nz*sizeof(int) + nz*bs2*sizeof(MatScalar) + (B->m+1)*sizeof(int);
1901b0a32e0cSBarry Smith   ierr  = PetscMalloc(len,&b->a);CHKERRQ(ierr);
1902273d9f13SBarry Smith   ierr  = PetscMemzero(b->a,nz*bs2*sizeof(MatScalar));CHKERRQ(ierr);
1903273d9f13SBarry Smith   b->j  = (int*)(b->a + nz*bs2);
1904273d9f13SBarry Smith   ierr = PetscMemzero(b->j,nz*sizeof(int));CHKERRQ(ierr);
1905273d9f13SBarry Smith   b->i  = b->j + nz;
1906273d9f13SBarry Smith   b->singlemalloc = PETSC_TRUE;
1907273d9f13SBarry Smith 
1908273d9f13SBarry Smith   b->i[0] = 0;
1909273d9f13SBarry Smith   for (i=1; i<mbs+1; i++) {
1910273d9f13SBarry Smith     b->i[i] = b->i[i-1] + b->imax[i-1];
1911273d9f13SBarry Smith   }
1912273d9f13SBarry Smith 
1913273d9f13SBarry Smith   /* b->ilen will count nonzeros in each block row so far. */
191416d6aa21SSatish Balay   ierr = PetscMalloc((mbs+1)*sizeof(int),&b->ilen);CHKERRQ(ierr);
1915b0a32e0cSBarry Smith   PetscLogObjectMemory(B,len+2*(mbs+1)*sizeof(int)+sizeof(struct _p_Mat)+sizeof(Mat_SeqBAIJ));
1916273d9f13SBarry Smith   for (i=0; i<mbs; i++) { b->ilen[i] = 0;}
1917273d9f13SBarry Smith 
1918273d9f13SBarry Smith   b->bs               = bs;
1919273d9f13SBarry Smith   b->bs2              = bs2;
1920273d9f13SBarry Smith   b->mbs              = mbs;
1921273d9f13SBarry Smith   b->nz               = 0;
1922273d9f13SBarry Smith   b->maxnz            = nz*bs2;
1923273d9f13SBarry Smith   B->info.nz_unneeded = (PetscReal)b->maxnz;
1924273d9f13SBarry Smith   PetscFunctionReturn(0);
1925273d9f13SBarry Smith }
19262593348eSBarry Smith 
1927