xref: /petsc/src/mat/impls/baij/seq/baij.c (revision e64df4b98185206ab144cab1547c141d9eb27ccb)
1*e64df4b9SKris Buschelman /*$Id: baij.c,v 1.237 2001/07/13 14:58:36 buschelm Exp buschelm $*/
22593348eSBarry Smith 
32593348eSBarry Smith /*
4b6490206SBarry Smith     Defines the basic matrix operations for the BAIJ (compressed row)
52593348eSBarry Smith   matrix storage format.
62593348eSBarry Smith */
7a2ccead7SSatish Balay #include "petscsys.h"                     /*I "petscmat.h" I*/
870f55243SBarry Smith #include "src/mat/impls/baij/seq/baij.h"
91a6a6d98SBarry Smith #include "src/vec/vecimpl.h"
101a6a6d98SBarry Smith #include "src/inline/spops.h"
113b547af2SSatish Balay 
1295d5f7c2SBarry Smith /*  UGLY, ugly, ugly
1395d5f7c2SBarry Smith    When MatScalar == Scalar the function MatSetValuesBlocked_SeqBAIJ_MatScalar() does
143477af42SKris Buschelman    not exist. Otherwise ..._MatScalar() takes matrix dlements in single precision and
1595d5f7c2SBarry Smith    inserts them into the single precision data structure. The function MatSetValuesBlocked_SeqBAIJ()
1695d5f7c2SBarry Smith    converts the entries into single precision and then calls ..._MatScalar() to put them
1795d5f7c2SBarry Smith    into the single precision data structures.
1895d5f7c2SBarry Smith */
1995d5f7c2SBarry Smith #if defined(PETSC_USE_MAT_SINGLE)
20ca44d042SBarry Smith EXTERN int MatSetValuesBlocked_SeqBAIJ_MatScalar(Mat,int,int*,int,int*,MatScalar*,InsertMode);
2195d5f7c2SBarry Smith #else
2295d5f7c2SBarry Smith #define MatSetValuesBlocked_SeqBAIJ_MatScalar MatSetValuesBlocked_SeqBAIJ
2395d5f7c2SBarry Smith #endif
2495d5f7c2SBarry Smith 
252d61bbb3SSatish Balay #define CHUNKSIZE  10
26de6a44a3SBarry Smith 
27be5855fcSBarry Smith /*
28be5855fcSBarry Smith      Checks for missing diagonals
29be5855fcSBarry Smith */
304a2ae208SSatish Balay #undef __FUNCT__
314a2ae208SSatish Balay #define __FUNCT__ "MatMissingDiagonal_SeqBAIJ"
32c4992f7dSBarry Smith int MatMissingDiagonal_SeqBAIJ(Mat A)
33be5855fcSBarry Smith {
34be5855fcSBarry Smith   Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)A->data;
35883fce79SBarry Smith   int         *diag,*jj = a->j,i,ierr;
36be5855fcSBarry Smith 
37be5855fcSBarry Smith   PetscFunctionBegin;
38c4992f7dSBarry Smith   ierr = MatMarkDiagonal_SeqBAIJ(A);CHKERRQ(ierr);
39883fce79SBarry Smith   diag = a->diag;
400e8e8aceSBarry Smith   for (i=0; i<a->mbs; i++) {
41be5855fcSBarry Smith     if (jj[diag[i]] != i) {
4229bbc08cSBarry Smith       SETERRQ1(1,"Matrix is missing diagonal number %d",i);
43be5855fcSBarry Smith     }
44be5855fcSBarry Smith   }
45be5855fcSBarry Smith   PetscFunctionReturn(0);
46be5855fcSBarry Smith }
47be5855fcSBarry Smith 
484a2ae208SSatish Balay #undef __FUNCT__
494a2ae208SSatish Balay #define __FUNCT__ "MatMarkDiagonal_SeqBAIJ"
50c4992f7dSBarry Smith int MatMarkDiagonal_SeqBAIJ(Mat A)
51de6a44a3SBarry Smith {
52de6a44a3SBarry Smith   Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)A->data;
5382502324SSatish Balay   int         i,j,*diag,m = a->mbs,ierr;
54de6a44a3SBarry Smith 
553a40ed3dSBarry Smith   PetscFunctionBegin;
56883fce79SBarry Smith   if (a->diag) PetscFunctionReturn(0);
57883fce79SBarry Smith 
58b0a32e0cSBarry Smith   ierr = PetscMalloc((m+1)*sizeof(int),&diag);CHKERRQ(ierr);
59b0a32e0cSBarry Smith   PetscLogObjectMemory(A,(m+1)*sizeof(int));
607fc0212eSBarry Smith   for (i=0; i<m; i++) {
61ecc615b2SBarry Smith     diag[i] = a->i[i+1];
62de6a44a3SBarry Smith     for (j=a->i[i]; j<a->i[i+1]; j++) {
63de6a44a3SBarry Smith       if (a->j[j] == i) {
64de6a44a3SBarry Smith         diag[i] = j;
65de6a44a3SBarry Smith         break;
66de6a44a3SBarry Smith       }
67de6a44a3SBarry Smith     }
68de6a44a3SBarry Smith   }
69de6a44a3SBarry Smith   a->diag = diag;
703a40ed3dSBarry Smith   PetscFunctionReturn(0);
71de6a44a3SBarry Smith }
722593348eSBarry Smith 
732593348eSBarry Smith 
74ca44d042SBarry Smith EXTERN int MatToSymmetricIJ_SeqAIJ(int,int*,int*,int,int,int**,int**);
753b2fbd54SBarry Smith 
764a2ae208SSatish Balay #undef __FUNCT__
774a2ae208SSatish Balay #define __FUNCT__ "MatGetRowIJ_SeqBAIJ"
780e6d2581SBarry Smith static int MatGetRowIJ_SeqBAIJ(Mat A,int oshift,PetscTruth symmetric,int *nn,int **ia,int **ja,PetscTruth *done)
793b2fbd54SBarry Smith {
803b2fbd54SBarry Smith   Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)A->data;
813b2fbd54SBarry Smith   int         ierr,n = a->mbs,i;
823b2fbd54SBarry Smith 
833a40ed3dSBarry Smith   PetscFunctionBegin;
843b2fbd54SBarry Smith   *nn = n;
853a40ed3dSBarry Smith   if (!ia) PetscFunctionReturn(0);
863b2fbd54SBarry Smith   if (symmetric) {
873b2fbd54SBarry Smith     ierr = MatToSymmetricIJ_SeqAIJ(n,a->i,a->j,0,oshift,ia,ja);CHKERRQ(ierr);
883b2fbd54SBarry Smith   } else if (oshift == 1) {
893b2fbd54SBarry Smith     /* temporarily add 1 to i and j indices */
90435da068SBarry Smith     int nz = a->i[n];
913b2fbd54SBarry Smith     for (i=0; i<nz; i++) a->j[i]++;
923b2fbd54SBarry Smith     for (i=0; i<n+1; i++) a->i[i]++;
933b2fbd54SBarry Smith     *ia = a->i; *ja = a->j;
943b2fbd54SBarry Smith   } else {
953b2fbd54SBarry Smith     *ia = a->i; *ja = a->j;
963b2fbd54SBarry Smith   }
973b2fbd54SBarry Smith 
983a40ed3dSBarry Smith   PetscFunctionReturn(0);
993b2fbd54SBarry Smith }
1003b2fbd54SBarry Smith 
1014a2ae208SSatish Balay #undef __FUNCT__
1024a2ae208SSatish Balay #define __FUNCT__ "MatRestoreRowIJ_SeqBAIJ"
103435da068SBarry Smith static int MatRestoreRowIJ_SeqBAIJ(Mat A,int oshift,PetscTruth symmetric,int *nn,int **ia,int **ja,PetscTruth *done)
1043b2fbd54SBarry Smith {
1053b2fbd54SBarry Smith   Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)A->data;
106606d414cSSatish Balay   int         i,n = a->mbs,ierr;
1073b2fbd54SBarry Smith 
1083a40ed3dSBarry Smith   PetscFunctionBegin;
1093a40ed3dSBarry Smith   if (!ia) PetscFunctionReturn(0);
1103b2fbd54SBarry Smith   if (symmetric) {
111606d414cSSatish Balay     ierr = PetscFree(*ia);CHKERRQ(ierr);
112606d414cSSatish Balay     ierr = PetscFree(*ja);CHKERRQ(ierr);
113af5da2bfSBarry Smith   } else if (oshift == 1) {
114435da068SBarry Smith     int nz = a->i[n]-1;
1153b2fbd54SBarry Smith     for (i=0; i<nz; i++) a->j[i]--;
1163b2fbd54SBarry Smith     for (i=0; i<n+1; i++) a->i[i]--;
1173b2fbd54SBarry Smith   }
1183a40ed3dSBarry Smith   PetscFunctionReturn(0);
1193b2fbd54SBarry Smith }
1203b2fbd54SBarry Smith 
1214a2ae208SSatish Balay #undef __FUNCT__
1224a2ae208SSatish Balay #define __FUNCT__ "MatGetBlockSize_SeqBAIJ"
1232d61bbb3SSatish Balay int MatGetBlockSize_SeqBAIJ(Mat mat,int *bs)
1242d61bbb3SSatish Balay {
1252d61bbb3SSatish Balay   Mat_SeqBAIJ *baij = (Mat_SeqBAIJ*)mat->data;
1262d61bbb3SSatish Balay 
1272d61bbb3SSatish Balay   PetscFunctionBegin;
1282d61bbb3SSatish Balay   *bs = baij->bs;
1292d61bbb3SSatish Balay   PetscFunctionReturn(0);
1302d61bbb3SSatish Balay }
1312d61bbb3SSatish Balay 
1322d61bbb3SSatish Balay 
1334a2ae208SSatish Balay #undef __FUNCT__
1344a2ae208SSatish Balay #define __FUNCT__ "MatDestroy_SeqBAIJ"
135e1311b90SBarry Smith int MatDestroy_SeqBAIJ(Mat A)
1362d61bbb3SSatish Balay {
1372d61bbb3SSatish Balay   Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)A->data;
138e51c0b9cSSatish Balay   int         ierr;
1392d61bbb3SSatish Balay 
140433994e6SBarry Smith   PetscFunctionBegin;
141aa482453SBarry Smith #if defined(PETSC_USE_LOG)
142b0a32e0cSBarry Smith   PetscLogObjectState((PetscObject)A,"Rows=%d, Cols=%d, NZ=%d",A->m,A->n,a->nz);
1432d61bbb3SSatish Balay #endif
144606d414cSSatish Balay   ierr = PetscFree(a->a);CHKERRQ(ierr);
145606d414cSSatish Balay   if (!a->singlemalloc) {
146606d414cSSatish Balay     ierr = PetscFree(a->i);CHKERRQ(ierr);
147606d414cSSatish Balay     ierr = PetscFree(a->j);CHKERRQ(ierr);
148606d414cSSatish Balay   }
149c38d4ed2SBarry Smith   if (a->row) {
150c38d4ed2SBarry Smith     ierr = ISDestroy(a->row);CHKERRQ(ierr);
151c38d4ed2SBarry Smith   }
152c38d4ed2SBarry Smith   if (a->col) {
153c38d4ed2SBarry Smith     ierr = ISDestroy(a->col);CHKERRQ(ierr);
154c38d4ed2SBarry Smith   }
155606d414cSSatish Balay   if (a->diag) {ierr = PetscFree(a->diag);CHKERRQ(ierr);}
156606d414cSSatish Balay   if (a->ilen) {ierr = PetscFree(a->ilen);CHKERRQ(ierr);}
157606d414cSSatish Balay   if (a->imax) {ierr = PetscFree(a->imax);CHKERRQ(ierr);}
158606d414cSSatish Balay   if (a->solve_work) {ierr = PetscFree(a->solve_work);CHKERRQ(ierr);}
159606d414cSSatish Balay   if (a->mult_work) {ierr = PetscFree(a->mult_work);CHKERRQ(ierr);}
160e51c0b9cSSatish Balay   if (a->icol) {ierr = ISDestroy(a->icol);CHKERRQ(ierr);}
161606d414cSSatish Balay   if (a->saved_values) {ierr = PetscFree(a->saved_values);CHKERRQ(ierr);}
162563b5814SBarry Smith #if defined(PETSC_USE_MAT_SINGLE)
163563b5814SBarry Smith   if (a->setvaluescopy) {ierr = PetscFree(a->setvaluescopy);CHKERRQ(ierr);}
164563b5814SBarry Smith #endif
165606d414cSSatish Balay   ierr = PetscFree(a);CHKERRQ(ierr);
1662d61bbb3SSatish Balay   PetscFunctionReturn(0);
1672d61bbb3SSatish Balay }
1682d61bbb3SSatish Balay 
1694a2ae208SSatish Balay #undef __FUNCT__
1704a2ae208SSatish Balay #define __FUNCT__ "MatSetOption_SeqBAIJ"
1712d61bbb3SSatish Balay int MatSetOption_SeqBAIJ(Mat A,MatOption op)
1722d61bbb3SSatish Balay {
1732d61bbb3SSatish Balay   Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)A->data;
1742d61bbb3SSatish Balay 
1752d61bbb3SSatish Balay   PetscFunctionBegin;
176aa275fccSKris Buschelman   switch (op) {
177aa275fccSKris Buschelman   case MAT_ROW_ORIENTED:
178aa275fccSKris Buschelman     a->roworiented    = PETSC_TRUE;
179aa275fccSKris Buschelman     break;
180aa275fccSKris Buschelman   case MAT_COLUMN_ORIENTED:
181aa275fccSKris Buschelman     a->roworiented    = PETSC_FALSE;
182aa275fccSKris Buschelman     break;
183aa275fccSKris Buschelman   case MAT_COLUMNS_SORTED:
184aa275fccSKris Buschelman     a->sorted         = PETSC_TRUE;
185aa275fccSKris Buschelman     break;
186aa275fccSKris Buschelman   case MAT_COLUMNS_UNSORTED:
187aa275fccSKris Buschelman     a->sorted         = PETSC_FALSE;
188aa275fccSKris Buschelman     break;
189aa275fccSKris Buschelman   case MAT_KEEP_ZEROED_ROWS:
190aa275fccSKris Buschelman     a->keepzeroedrows = PETSC_TRUE;
191aa275fccSKris Buschelman     break;
192aa275fccSKris Buschelman   case MAT_NO_NEW_NONZERO_LOCATIONS:
193aa275fccSKris Buschelman     a->nonew          = 1;
194aa275fccSKris Buschelman     break;
195aa275fccSKris Buschelman   case MAT_NEW_NONZERO_LOCATION_ERR:
196aa275fccSKris Buschelman     a->nonew          = -1;
197aa275fccSKris Buschelman     break;
198aa275fccSKris Buschelman   case MAT_NEW_NONZERO_ALLOCATION_ERR:
199aa275fccSKris Buschelman     a->nonew          = -2;
200aa275fccSKris Buschelman     break;
201aa275fccSKris Buschelman   case MAT_YES_NEW_NONZERO_LOCATIONS:
202aa275fccSKris Buschelman     a->nonew          = 0;
203aa275fccSKris Buschelman     break;
204aa275fccSKris Buschelman   case MAT_ROWS_SORTED:
205aa275fccSKris Buschelman   case MAT_ROWS_UNSORTED:
206aa275fccSKris Buschelman   case MAT_YES_NEW_DIAGONALS:
207aa275fccSKris Buschelman   case MAT_IGNORE_OFF_PROC_ENTRIES:
208aa275fccSKris Buschelman   case MAT_USE_HASH_TABLE:
209b0a32e0cSBarry Smith     PetscLogInfo(A,"MatSetOption_SeqBAIJ:Option ignored\n");
210aa275fccSKris Buschelman     break;
211aa275fccSKris Buschelman   case MAT_NO_NEW_DIAGONALS:
21229bbc08cSBarry Smith     SETERRQ(PETSC_ERR_SUP,"MAT_NO_NEW_DIAGONALS");
213bd648c37SKris Buschelman     break;
214bd648c37SKris Buschelman   case MAT_USE_SINGLE_PRECISION_SOLVES:
215bd648c37SKris Buschelman     if (a->bs==4) {
216*e64df4b9SKris Buschelman       PetscTruth sse_enabled=PETSC_FALSE;
217bd648c37SKris Buschelman       int        ierr;
218bd648c37SKris Buschelman       ierr = PetscSSEIsEnabled(&sse_enabled);CHKERRQ(ierr);
219*e64df4b9SKris Buschelman #if defined(PETSC_HAVE_SSE)
220*e64df4b9SKris Buschelman       if (sse_enabled) {
22154138f6bSKris Buschelman           a->single_precision_solves = PETSC_TRUE;
22254138f6bSKris Buschelman           A->ops->solve              = MatSolve_SeqBAIJ_Update;
22354138f6bSKris Buschelman           A->ops->solvetranspose     = MatSolveTranspose_SeqBAIJ_Update;
22454138f6bSKris Buschelman           break;
2258661488fSKris Buschelman       }
226*e64df4b9SKris Buschelman #else
227bd648c37SKris Buschelman       PetscLogInfo(A,"MatSetOption_SeqBAIJ:Option MAT_USE_SINGLE_PRECISION_SOLVES ignored\n");
228*e64df4b9SKris Buschelman #endif
229bd648c37SKris Buschelman     }
230bd648c37SKris Buschelman     break;
231aa275fccSKris Buschelman   default:
23229bbc08cSBarry Smith     SETERRQ(PETSC_ERR_SUP,"unknown option");
2332d61bbb3SSatish Balay   }
2342d61bbb3SSatish Balay   PetscFunctionReturn(0);
2352d61bbb3SSatish Balay }
2362d61bbb3SSatish Balay 
2374a2ae208SSatish Balay #undef __FUNCT__
2384a2ae208SSatish Balay #define __FUNCT__ "MatGetOwnershipRange_SeqBAIJ"
2392d61bbb3SSatish Balay int MatGetOwnershipRange_SeqBAIJ(Mat A,int *m,int *n)
2402d61bbb3SSatish Balay {
2412d61bbb3SSatish Balay   PetscFunctionBegin;
2424c49b128SBarry Smith   if (m) *m = 0;
243273d9f13SBarry Smith   if (n) *n = A->m;
2442d61bbb3SSatish Balay   PetscFunctionReturn(0);
2452d61bbb3SSatish Balay }
2462d61bbb3SSatish Balay 
2474a2ae208SSatish Balay #undef __FUNCT__
2484a2ae208SSatish Balay #define __FUNCT__ "MatGetRow_SeqBAIJ"
2492d61bbb3SSatish Balay int MatGetRow_SeqBAIJ(Mat A,int row,int *nz,int **idx,Scalar **v)
2502d61bbb3SSatish Balay {
2512d61bbb3SSatish Balay   Mat_SeqBAIJ  *a = (Mat_SeqBAIJ*)A->data;
25282502324SSatish Balay   int          itmp,i,j,k,M,*ai,*aj,bs,bn,bp,*idx_i,bs2,ierr;
2533f1db9ecSBarry Smith   MatScalar    *aa,*aa_i;
2543f1db9ecSBarry Smith   Scalar       *v_i;
2552d61bbb3SSatish Balay 
2562d61bbb3SSatish Balay   PetscFunctionBegin;
2572d61bbb3SSatish Balay   bs  = a->bs;
2582d61bbb3SSatish Balay   ai  = a->i;
2592d61bbb3SSatish Balay   aj  = a->j;
2602d61bbb3SSatish Balay   aa  = a->a;
2612d61bbb3SSatish Balay   bs2 = a->bs2;
2622d61bbb3SSatish Balay 
263273d9f13SBarry Smith   if (row < 0 || row >= A->m) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Row out of range");
2642d61bbb3SSatish Balay 
2652d61bbb3SSatish Balay   bn  = row/bs;   /* Block number */
2662d61bbb3SSatish Balay   bp  = row % bs; /* Block Position */
2672d61bbb3SSatish Balay   M   = ai[bn+1] - ai[bn];
2682d61bbb3SSatish Balay   *nz = bs*M;
2692d61bbb3SSatish Balay 
2702d61bbb3SSatish Balay   if (v) {
2712d61bbb3SSatish Balay     *v = 0;
2722d61bbb3SSatish Balay     if (*nz) {
273b0a32e0cSBarry Smith       ierr = PetscMalloc((*nz)*sizeof(Scalar),v);CHKERRQ(ierr);
2742d61bbb3SSatish Balay       for (i=0; i<M; i++) { /* for each block in the block row */
2752d61bbb3SSatish Balay         v_i  = *v + i*bs;
2762d61bbb3SSatish Balay         aa_i = aa + bs2*(ai[bn] + i);
2772d61bbb3SSatish Balay         for (j=bp,k=0; j<bs2; j+=bs,k++) {v_i[k] = aa_i[j];}
2782d61bbb3SSatish Balay       }
2792d61bbb3SSatish Balay     }
2802d61bbb3SSatish Balay   }
2812d61bbb3SSatish Balay 
2822d61bbb3SSatish Balay   if (idx) {
2832d61bbb3SSatish Balay     *idx = 0;
2842d61bbb3SSatish Balay     if (*nz) {
285b0a32e0cSBarry Smith       ierr = PetscMalloc((*nz)*sizeof(int),idx);CHKERRQ(ierr);
2862d61bbb3SSatish Balay       for (i=0; i<M; i++) { /* for each block in the block row */
2872d61bbb3SSatish Balay         idx_i = *idx + i*bs;
2882d61bbb3SSatish Balay         itmp  = bs*aj[ai[bn] + i];
2892d61bbb3SSatish Balay         for (j=0; j<bs; j++) {idx_i[j] = itmp++;}
2902d61bbb3SSatish Balay       }
2912d61bbb3SSatish Balay     }
2922d61bbb3SSatish Balay   }
2932d61bbb3SSatish Balay   PetscFunctionReturn(0);
2942d61bbb3SSatish Balay }
2952d61bbb3SSatish Balay 
2964a2ae208SSatish Balay #undef __FUNCT__
2974a2ae208SSatish Balay #define __FUNCT__ "MatRestoreRow_SeqBAIJ"
2982d61bbb3SSatish Balay int MatRestoreRow_SeqBAIJ(Mat A,int row,int *nz,int **idx,Scalar **v)
2992d61bbb3SSatish Balay {
300606d414cSSatish Balay   int ierr;
301606d414cSSatish Balay 
3022d61bbb3SSatish Balay   PetscFunctionBegin;
303606d414cSSatish Balay   if (idx) {if (*idx) {ierr = PetscFree(*idx);CHKERRQ(ierr);}}
304606d414cSSatish Balay   if (v)   {if (*v)   {ierr = PetscFree(*v);CHKERRQ(ierr);}}
3052d61bbb3SSatish Balay   PetscFunctionReturn(0);
3062d61bbb3SSatish Balay }
3072d61bbb3SSatish Balay 
3084a2ae208SSatish Balay #undef __FUNCT__
3094a2ae208SSatish Balay #define __FUNCT__ "MatTranspose_SeqBAIJ"
3102d61bbb3SSatish Balay int MatTranspose_SeqBAIJ(Mat A,Mat *B)
3112d61bbb3SSatish Balay {
3122d61bbb3SSatish Balay   Mat_SeqBAIJ *a=(Mat_SeqBAIJ *)A->data;
3132d61bbb3SSatish Balay   Mat         C;
3142d61bbb3SSatish Balay   int         i,j,k,ierr,*aj=a->j,*ai=a->i,bs=a->bs,mbs=a->mbs,nbs=a->nbs,len,*col;
315273d9f13SBarry Smith   int         *rows,*cols,bs2=a->bs2;
316375fe846SBarry Smith   Scalar      *array;
3172d61bbb3SSatish Balay 
3182d61bbb3SSatish Balay   PetscFunctionBegin;
31929bbc08cSBarry Smith   if (!B && mbs!=nbs) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Square matrix only for in-place");
320b0a32e0cSBarry Smith   ierr = PetscMalloc((1+nbs)*sizeof(int),&col);CHKERRQ(ierr);
321549d3d68SSatish Balay   ierr = PetscMemzero(col,(1+nbs)*sizeof(int));CHKERRQ(ierr);
3222d61bbb3SSatish Balay 
323375fe846SBarry Smith #if defined(PETSC_USE_MAT_SINGLE)
324b0a32e0cSBarry Smith   ierr = PetscMalloc(a->bs2*a->nz*sizeof(Scalar),&array);CHKERRQ(ierr);
325375fe846SBarry Smith   for (i=0; i<a->bs2*a->nz; i++) array[i] = (Scalar)a->a[i];
326375fe846SBarry Smith #else
3273eda8832SBarry Smith   array = a->a;
328375fe846SBarry Smith #endif
329375fe846SBarry Smith 
3302d61bbb3SSatish Balay   for (i=0; i<ai[mbs]; i++) col[aj[i]] += 1;
331273d9f13SBarry Smith   ierr = MatCreateSeqBAIJ(A->comm,bs,A->n,A->m,PETSC_NULL,col,&C);CHKERRQ(ierr);
332606d414cSSatish Balay   ierr = PetscFree(col);CHKERRQ(ierr);
333b0a32e0cSBarry Smith   ierr = PetscMalloc(2*bs*sizeof(int),&rows);CHKERRQ(ierr);
3342d61bbb3SSatish Balay   cols = rows + bs;
3352d61bbb3SSatish Balay   for (i=0; i<mbs; i++) {
3362d61bbb3SSatish Balay     cols[0] = i*bs;
3372d61bbb3SSatish Balay     for (k=1; k<bs; k++) cols[k] = cols[k-1] + 1;
3382d61bbb3SSatish Balay     len = ai[i+1] - ai[i];
3392d61bbb3SSatish Balay     for (j=0; j<len; j++) {
3402d61bbb3SSatish Balay       rows[0] = (*aj++)*bs;
3412d61bbb3SSatish Balay       for (k=1; k<bs; k++) rows[k] = rows[k-1] + 1;
3422d61bbb3SSatish Balay       ierr = MatSetValues(C,bs,rows,bs,cols,array,INSERT_VALUES);CHKERRQ(ierr);
3432d61bbb3SSatish Balay       array += bs2;
3442d61bbb3SSatish Balay     }
3452d61bbb3SSatish Balay   }
346606d414cSSatish Balay   ierr = PetscFree(rows);CHKERRQ(ierr);
347375fe846SBarry Smith #if defined(PETSC_USE_MAT_SINGLE)
348375fe846SBarry Smith   ierr = PetscFree(array);
349375fe846SBarry Smith #endif
3502d61bbb3SSatish Balay 
3512d61bbb3SSatish Balay   ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
3522d61bbb3SSatish Balay   ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
3532d61bbb3SSatish Balay 
354c4992f7dSBarry Smith   if (B) {
3552d61bbb3SSatish Balay     *B = C;
3562d61bbb3SSatish Balay   } else {
357273d9f13SBarry Smith     ierr = MatHeaderCopy(A,C);CHKERRQ(ierr);
3582d61bbb3SSatish Balay   }
3592d61bbb3SSatish Balay   PetscFunctionReturn(0);
3602d61bbb3SSatish Balay }
3612d61bbb3SSatish Balay 
3624a2ae208SSatish Balay #undef __FUNCT__
3634a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqBAIJ_Binary"
364b0a32e0cSBarry Smith static int MatView_SeqBAIJ_Binary(Mat A,PetscViewer viewer)
3652593348eSBarry Smith {
366b6490206SBarry Smith   Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)A->data;
3679df24120SSatish Balay   int         i,fd,*col_lens,ierr,bs = a->bs,count,*jj,j,k,l,bs2=a->bs2;
368b6490206SBarry Smith   Scalar      *aa;
369ce6f0cecSBarry Smith   FILE        *file;
3702593348eSBarry Smith 
3713a40ed3dSBarry Smith   PetscFunctionBegin;
372b0a32e0cSBarry Smith   ierr        = PetscViewerBinaryGetDescriptor(viewer,&fd);CHKERRQ(ierr);
373b0a32e0cSBarry Smith   ierr        = PetscMalloc((4+A->m)*sizeof(int),&col_lens);CHKERRQ(ierr);
3742593348eSBarry Smith   col_lens[0] = MAT_COOKIE;
3753b2fbd54SBarry Smith 
376273d9f13SBarry Smith   col_lens[1] = A->m;
377273d9f13SBarry Smith   col_lens[2] = A->n;
3787e67e3f9SSatish Balay   col_lens[3] = a->nz*bs2;
3792593348eSBarry Smith 
3802593348eSBarry Smith   /* store lengths of each row and write (including header) to file */
381b6490206SBarry Smith   count = 0;
382b6490206SBarry Smith   for (i=0; i<a->mbs; i++) {
383b6490206SBarry Smith     for (j=0; j<bs; j++) {
384b6490206SBarry Smith       col_lens[4+count++] = bs*(a->i[i+1] - a->i[i]);
385b6490206SBarry Smith     }
3862593348eSBarry Smith   }
387273d9f13SBarry Smith   ierr = PetscBinaryWrite(fd,col_lens,4+A->m,PETSC_INT,1);CHKERRQ(ierr);
388606d414cSSatish Balay   ierr = PetscFree(col_lens);CHKERRQ(ierr);
3892593348eSBarry Smith 
3902593348eSBarry Smith   /* store column indices (zero start index) */
391b0a32e0cSBarry Smith   ierr  = PetscMalloc((a->nz+1)*bs2*sizeof(int),&jj);CHKERRQ(ierr);
392b6490206SBarry Smith   count = 0;
393b6490206SBarry Smith   for (i=0; i<a->mbs; i++) {
394b6490206SBarry Smith     for (j=0; j<bs; j++) {
395b6490206SBarry Smith       for (k=a->i[i]; k<a->i[i+1]; k++) {
396b6490206SBarry Smith         for (l=0; l<bs; l++) {
397b6490206SBarry Smith           jj[count++] = bs*a->j[k] + l;
3982593348eSBarry Smith         }
3992593348eSBarry Smith       }
400b6490206SBarry Smith     }
401b6490206SBarry Smith   }
4020752156aSBarry Smith   ierr = PetscBinaryWrite(fd,jj,bs2*a->nz,PETSC_INT,0);CHKERRQ(ierr);
403606d414cSSatish Balay   ierr = PetscFree(jj);CHKERRQ(ierr);
4042593348eSBarry Smith 
4052593348eSBarry Smith   /* store nonzero values */
406b0a32e0cSBarry Smith   ierr  = PetscMalloc((a->nz+1)*bs2*sizeof(Scalar),&aa);CHKERRQ(ierr);
407b6490206SBarry Smith   count = 0;
408b6490206SBarry Smith   for (i=0; i<a->mbs; i++) {
409b6490206SBarry Smith     for (j=0; j<bs; j++) {
410b6490206SBarry Smith       for (k=a->i[i]; k<a->i[i+1]; k++) {
411b6490206SBarry Smith         for (l=0; l<bs; l++) {
4127e67e3f9SSatish Balay           aa[count++] = a->a[bs2*k + l*bs + j];
413b6490206SBarry Smith         }
414b6490206SBarry Smith       }
415b6490206SBarry Smith     }
416b6490206SBarry Smith   }
4170752156aSBarry Smith   ierr = PetscBinaryWrite(fd,aa,bs2*a->nz,PETSC_SCALAR,0);CHKERRQ(ierr);
418606d414cSSatish Balay   ierr = PetscFree(aa);CHKERRQ(ierr);
419ce6f0cecSBarry Smith 
420b0a32e0cSBarry Smith   ierr = PetscViewerBinaryGetInfoPointer(viewer,&file);CHKERRQ(ierr);
421ce6f0cecSBarry Smith   if (file) {
422ce6f0cecSBarry Smith     fprintf(file,"-matload_block_size %d\n",a->bs);
423ce6f0cecSBarry Smith   }
4243a40ed3dSBarry Smith   PetscFunctionReturn(0);
4252593348eSBarry Smith }
4262593348eSBarry Smith 
4274a2ae208SSatish Balay #undef __FUNCT__
4284a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqBAIJ_ASCII"
429b0a32e0cSBarry Smith static int MatView_SeqBAIJ_ASCII(Mat A,PetscViewer viewer)
4302593348eSBarry Smith {
431b6490206SBarry Smith   Mat_SeqBAIJ       *a = (Mat_SeqBAIJ*)A->data;
432fb9695e5SSatish Balay   int               ierr,i,j,bs = a->bs,k,l,bs2=a->bs2;
433f3ef73ceSBarry Smith   PetscViewerFormat format;
4342593348eSBarry Smith 
4353a40ed3dSBarry Smith   PetscFunctionBegin;
436b0a32e0cSBarry Smith   ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr);
437fb9695e5SSatish Balay   if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_LONG) {
438b0a32e0cSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  block size is %d\n",bs);CHKERRQ(ierr);
439fb9695e5SSatish Balay   } else if (format == PETSC_VIEWER_ASCII_MATLAB) {
44029bbc08cSBarry Smith     SETERRQ(PETSC_ERR_SUP,"Matlab format not supported");
441fb9695e5SSatish Balay   } else if (format == PETSC_VIEWER_ASCII_COMMON) {
442b0a32e0cSBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_NO);CHKERRQ(ierr);
44344cd7ae7SLois Curfman McInnes     for (i=0; i<a->mbs; i++) {
44444cd7ae7SLois Curfman McInnes       for (j=0; j<bs; j++) {
445b0a32e0cSBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"row %d:",i*bs+j);CHKERRQ(ierr);
44644cd7ae7SLois Curfman McInnes         for (k=a->i[i]; k<a->i[i+1]; k++) {
44744cd7ae7SLois Curfman McInnes           for (l=0; l<bs; l++) {
448aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
4490e6d2581SBarry Smith             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 (PetscImaginaryPart(a->a[bs2*k + l*bs + j]) < 0.0 && PetscRealPart(a->a[bs2*k + l*bs + j]) != 0.0) {
453b0a32e0cSBarry Smith               ierr = PetscViewerASCIIPrintf(viewer," %d %g - %gi",bs*a->j[k]+l,
4540e6d2581SBarry Smith                       PetscRealPart(a->a[bs2*k + l*bs + j]),-PetscImaginaryPart(a->a[bs2*k + l*bs + j]));CHKERRQ(ierr);
4550e6d2581SBarry Smith             } else if (PetscRealPart(a->a[bs2*k + l*bs + j]) != 0.0) {
456b0a32e0cSBarry Smith               ierr = PetscViewerASCIIPrintf(viewer," %d %g ",bs*a->j[k]+l,PetscRealPart(a->a[bs2*k + l*bs + j]));CHKERRQ(ierr);
4570ef38995SBarry Smith             }
45844cd7ae7SLois Curfman McInnes #else
4590ef38995SBarry Smith             if (a->a[bs2*k + l*bs + j] != 0.0) {
460b0a32e0cSBarry Smith               ierr = PetscViewerASCIIPrintf(viewer," %d %g ",bs*a->j[k]+l,a->a[bs2*k + l*bs + j]);CHKERRQ(ierr);
4610ef38995SBarry Smith             }
46244cd7ae7SLois Curfman McInnes #endif
46344cd7ae7SLois Curfman McInnes           }
46444cd7ae7SLois Curfman McInnes         }
465b0a32e0cSBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
46644cd7ae7SLois Curfman McInnes       }
46744cd7ae7SLois Curfman McInnes     }
468b0a32e0cSBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_YES);CHKERRQ(ierr);
4690ef38995SBarry Smith   } else {
470b0a32e0cSBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_NO);CHKERRQ(ierr);
471b6490206SBarry Smith     for (i=0; i<a->mbs; i++) {
472b6490206SBarry Smith       for (j=0; j<bs; j++) {
473b0a32e0cSBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"row %d:",i*bs+j);CHKERRQ(ierr);
474b6490206SBarry Smith         for (k=a->i[i]; k<a->i[i+1]; k++) {
475b6490206SBarry Smith           for (l=0; l<bs; l++) {
476aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
4770e6d2581SBarry Smith             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);
4800e6d2581SBarry Smith             } else if (PetscImaginaryPart(a->a[bs2*k + l*bs + j]) < 0.0) {
481b0a32e0cSBarry Smith               ierr = PetscViewerASCIIPrintf(viewer," %d %g - %g i",bs*a->j[k]+l,
4820e6d2581SBarry Smith                 PetscRealPart(a->a[bs2*k + l*bs + j]),-PetscImaginaryPart(a->a[bs2*k + l*bs + j]));CHKERRQ(ierr);
4830ef38995SBarry Smith             } else {
484b0a32e0cSBarry Smith               ierr = PetscViewerASCIIPrintf(viewer," %d %g ",bs*a->j[k]+l,PetscRealPart(a->a[bs2*k + l*bs + j]));CHKERRQ(ierr);
48588685aaeSLois Curfman McInnes             }
48688685aaeSLois Curfman McInnes #else
487b0a32e0cSBarry Smith             ierr = PetscViewerASCIIPrintf(viewer," %d %g ",bs*a->j[k]+l,a->a[bs2*k + l*bs + j]);CHKERRQ(ierr);
48888685aaeSLois Curfman McInnes #endif
4892593348eSBarry Smith           }
4902593348eSBarry Smith         }
491b0a32e0cSBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
4922593348eSBarry Smith       }
4932593348eSBarry Smith     }
494b0a32e0cSBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_YES);CHKERRQ(ierr);
495b6490206SBarry Smith   }
496b0a32e0cSBarry Smith   ierr = PetscViewerFlush(viewer);CHKERRQ(ierr);
4973a40ed3dSBarry Smith   PetscFunctionReturn(0);
4982593348eSBarry Smith }
4992593348eSBarry Smith 
5004a2ae208SSatish Balay #undef __FUNCT__
5014a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqBAIJ_Draw_Zoom"
502b0a32e0cSBarry Smith static int MatView_SeqBAIJ_Draw_Zoom(PetscDraw draw,void *Aa)
5033270192aSSatish Balay {
50477ed5343SBarry Smith   Mat          A = (Mat) Aa;
5053270192aSSatish Balay   Mat_SeqBAIJ  *a=(Mat_SeqBAIJ*)A->data;
506b65db4caSBarry Smith   int          row,ierr,i,j,k,l,mbs=a->mbs,color,bs=a->bs,bs2=a->bs2;
5070e6d2581SBarry Smith   PetscReal    xl,yl,xr,yr,x_l,x_r,y_l,y_r;
5083f1db9ecSBarry Smith   MatScalar    *aa;
509b0a32e0cSBarry Smith   PetscViewer  viewer;
5103270192aSSatish Balay 
5113a40ed3dSBarry Smith   PetscFunctionBegin;
5123270192aSSatish Balay 
513b65db4caSBarry Smith   /* still need to add support for contour plot of nonzeros; see MatView_SeqAIJ_Draw_Zoom()*/
51477ed5343SBarry Smith   ierr = PetscObjectQuery((PetscObject)A,"Zoomviewer",(PetscObject*)&viewer);CHKERRQ(ierr);
51577ed5343SBarry Smith 
516b0a32e0cSBarry Smith   ierr = PetscDrawGetCoordinates(draw,&xl,&yl,&xr,&yr);CHKERRQ(ierr);
51777ed5343SBarry Smith 
5183270192aSSatish Balay   /* loop over matrix elements drawing boxes */
519b0a32e0cSBarry Smith   color = PETSC_DRAW_BLUE;
5203270192aSSatish Balay   for (i=0,row=0; i<mbs; i++,row+=bs) {
5213270192aSSatish Balay     for (j=a->i[i]; j<a->i[i+1]; j++) {
522273d9f13SBarry Smith       y_l = A->m - row - 1.0; y_r = y_l + 1.0;
5233270192aSSatish Balay       x_l = a->j[j]*bs; x_r = x_l + 1.0;
5243270192aSSatish Balay       aa = a->a + j*bs2;
5253270192aSSatish Balay       for (k=0; k<bs; k++) {
5263270192aSSatish Balay         for (l=0; l<bs; l++) {
5270e6d2581SBarry Smith           if (PetscRealPart(*aa++) >=  0.) continue;
528b0a32e0cSBarry Smith           ierr = PetscDrawRectangle(draw,x_l+k,y_l-l,x_r+k,y_r-l,color,color,color,color);CHKERRQ(ierr);
5293270192aSSatish Balay         }
5303270192aSSatish Balay       }
5313270192aSSatish Balay     }
5323270192aSSatish Balay   }
533b0a32e0cSBarry Smith   color = PETSC_DRAW_CYAN;
5343270192aSSatish Balay   for (i=0,row=0; i<mbs; i++,row+=bs) {
5353270192aSSatish Balay     for (j=a->i[i]; j<a->i[i+1]; j++) {
536273d9f13SBarry Smith       y_l = A->m - row - 1.0; y_r = y_l + 1.0;
5373270192aSSatish Balay       x_l = a->j[j]*bs; x_r = x_l + 1.0;
5383270192aSSatish Balay       aa = a->a + j*bs2;
5393270192aSSatish Balay       for (k=0; k<bs; k++) {
5403270192aSSatish Balay         for (l=0; l<bs; l++) {
5410e6d2581SBarry Smith           if (PetscRealPart(*aa++) != 0.) continue;
542b0a32e0cSBarry Smith           ierr = PetscDrawRectangle(draw,x_l+k,y_l-l,x_r+k,y_r-l,color,color,color,color);CHKERRQ(ierr);
5433270192aSSatish Balay         }
5443270192aSSatish Balay       }
5453270192aSSatish Balay     }
5463270192aSSatish Balay   }
5473270192aSSatish Balay 
548b0a32e0cSBarry Smith   color = PETSC_DRAW_RED;
5493270192aSSatish Balay   for (i=0,row=0; i<mbs; i++,row+=bs) {
5503270192aSSatish Balay     for (j=a->i[i]; j<a->i[i+1]; j++) {
551273d9f13SBarry Smith       y_l = A->m - row - 1.0; y_r = y_l + 1.0;
5523270192aSSatish Balay       x_l = a->j[j]*bs; x_r = x_l + 1.0;
5533270192aSSatish Balay       aa = a->a + j*bs2;
5543270192aSSatish Balay       for (k=0; k<bs; k++) {
5553270192aSSatish Balay         for (l=0; l<bs; l++) {
5560e6d2581SBarry Smith           if (PetscRealPart(*aa++) <= 0.) continue;
557b0a32e0cSBarry Smith           ierr = PetscDrawRectangle(draw,x_l+k,y_l-l,x_r+k,y_r-l,color,color,color,color);CHKERRQ(ierr);
5583270192aSSatish Balay         }
5593270192aSSatish Balay       }
5603270192aSSatish Balay     }
5613270192aSSatish Balay   }
56277ed5343SBarry Smith   PetscFunctionReturn(0);
56377ed5343SBarry Smith }
5643270192aSSatish Balay 
5654a2ae208SSatish Balay #undef __FUNCT__
5664a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqBAIJ_Draw"
567b0a32e0cSBarry Smith static int MatView_SeqBAIJ_Draw(Mat A,PetscViewer viewer)
56877ed5343SBarry Smith {
5697dce120fSSatish Balay   int          ierr;
5700e6d2581SBarry Smith   PetscReal    xl,yl,xr,yr,w,h;
571b0a32e0cSBarry Smith   PetscDraw    draw;
57277ed5343SBarry Smith   PetscTruth   isnull;
5733270192aSSatish Balay 
57477ed5343SBarry Smith   PetscFunctionBegin;
57577ed5343SBarry Smith 
576b0a32e0cSBarry Smith   ierr = PetscViewerDrawGetDraw(viewer,0,&draw);CHKERRQ(ierr);
577b0a32e0cSBarry Smith   ierr = PetscDrawIsNull(draw,&isnull);CHKERRQ(ierr); if (isnull) PetscFunctionReturn(0);
57877ed5343SBarry Smith 
57977ed5343SBarry Smith   ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",(PetscObject)viewer);CHKERRQ(ierr);
580273d9f13SBarry Smith   xr  = A->n; yr = A->m; h = yr/10.0; w = xr/10.0;
58177ed5343SBarry Smith   xr += w;    yr += h;  xl = -w;     yl = -h;
582b0a32e0cSBarry Smith   ierr = PetscDrawSetCoordinates(draw,xl,yl,xr,yr);CHKERRQ(ierr);
583b0a32e0cSBarry Smith   ierr = PetscDrawZoom(draw,MatView_SeqBAIJ_Draw_Zoom,A);CHKERRQ(ierr);
58477ed5343SBarry Smith   ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",PETSC_NULL);CHKERRQ(ierr);
5853a40ed3dSBarry Smith   PetscFunctionReturn(0);
5863270192aSSatish Balay }
5873270192aSSatish Balay 
5884a2ae208SSatish Balay #undef __FUNCT__
5894a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqBAIJ"
590b0a32e0cSBarry Smith int MatView_SeqBAIJ(Mat A,PetscViewer viewer)
5912593348eSBarry Smith {
59219bcc07fSBarry Smith   int        ierr;
5936831982aSBarry Smith   PetscTruth issocket,isascii,isbinary,isdraw;
5942593348eSBarry Smith 
5953a40ed3dSBarry Smith   PetscFunctionBegin;
596b0a32e0cSBarry Smith   ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_SOCKET,&issocket);CHKERRQ(ierr);
597b0a32e0cSBarry Smith   ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&isascii);CHKERRQ(ierr);
598fb9695e5SSatish Balay   ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_BINARY,&isbinary);CHKERRQ(ierr);
599fb9695e5SSatish Balay   ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_DRAW,&isdraw);CHKERRQ(ierr);
6000f5bd95cSBarry Smith   if (issocket) {
60129bbc08cSBarry Smith     SETERRQ(PETSC_ERR_SUP,"Socket viewer not supported");
6020f5bd95cSBarry Smith   } else if (isascii){
6033a40ed3dSBarry Smith     ierr = MatView_SeqBAIJ_ASCII(A,viewer);CHKERRQ(ierr);
6040f5bd95cSBarry Smith   } else if (isbinary) {
6053a40ed3dSBarry Smith     ierr = MatView_SeqBAIJ_Binary(A,viewer);CHKERRQ(ierr);
6060f5bd95cSBarry Smith   } else if (isdraw) {
6073a40ed3dSBarry Smith     ierr = MatView_SeqBAIJ_Draw(A,viewer);CHKERRQ(ierr);
6085cd90555SBarry Smith   } else {
60929bbc08cSBarry Smith     SETERRQ1(1,"Viewer type %s not supported by SeqBAIJ matrices",((PetscObject)viewer)->type_name);
6102593348eSBarry Smith   }
6113a40ed3dSBarry Smith   PetscFunctionReturn(0);
6122593348eSBarry Smith }
613b6490206SBarry Smith 
614cd0e1443SSatish Balay 
6154a2ae208SSatish Balay #undef __FUNCT__
6164a2ae208SSatish Balay #define __FUNCT__ "MatGetValues_SeqBAIJ"
6172d61bbb3SSatish Balay int MatGetValues_SeqBAIJ(Mat A,int m,int *im,int n,int *in,Scalar *v)
618cd0e1443SSatish Balay {
619cd0e1443SSatish Balay   Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)A->data;
6202d61bbb3SSatish Balay   int        *rp,k,low,high,t,row,nrow,i,col,l,*aj = a->j;
6212d61bbb3SSatish Balay   int        *ai = a->i,*ailen = a->ilen;
6222d61bbb3SSatish Balay   int        brow,bcol,ridx,cidx,bs=a->bs,bs2=a->bs2;
6233f1db9ecSBarry Smith   MatScalar  *ap,*aa = a->a,zero = 0.0;
624cd0e1443SSatish Balay 
6253a40ed3dSBarry Smith   PetscFunctionBegin;
6262d61bbb3SSatish Balay   for (k=0; k<m; k++) { /* loop over rows */
627cd0e1443SSatish Balay     row  = im[k]; brow = row/bs;
62829bbc08cSBarry Smith     if (row < 0) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Negative row");
629273d9f13SBarry Smith     if (row >= A->m) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Row too large");
6302d61bbb3SSatish Balay     rp   = aj + ai[brow] ; ap = aa + bs2*ai[brow] ;
6312c3acbe9SBarry Smith     nrow = ailen[brow];
6322d61bbb3SSatish Balay     for (l=0; l<n; l++) { /* loop over columns */
63329bbc08cSBarry Smith       if (in[l] < 0) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Negative column");
634273d9f13SBarry Smith       if (in[l] >= A->n) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Column too large");
6352d61bbb3SSatish Balay       col  = in[l] ;
6362d61bbb3SSatish Balay       bcol = col/bs;
6372d61bbb3SSatish Balay       cidx = col%bs;
6382d61bbb3SSatish Balay       ridx = row%bs;
6392d61bbb3SSatish Balay       high = nrow;
6402d61bbb3SSatish Balay       low  = 0; /* assume unsorted */
6412d61bbb3SSatish Balay       while (high-low > 5) {
642cd0e1443SSatish Balay         t = (low+high)/2;
643cd0e1443SSatish Balay         if (rp[t] > bcol) high = t;
644cd0e1443SSatish Balay         else             low  = t;
645cd0e1443SSatish Balay       }
646cd0e1443SSatish Balay       for (i=low; i<high; i++) {
647cd0e1443SSatish Balay         if (rp[i] > bcol) break;
648cd0e1443SSatish Balay         if (rp[i] == bcol) {
6492d61bbb3SSatish Balay           *v++ = ap[bs2*i+bs*cidx+ridx];
6502d61bbb3SSatish Balay           goto finished;
651cd0e1443SSatish Balay         }
652cd0e1443SSatish Balay       }
6532d61bbb3SSatish Balay       *v++ = zero;
6542d61bbb3SSatish Balay       finished:;
655cd0e1443SSatish Balay     }
656cd0e1443SSatish Balay   }
6573a40ed3dSBarry Smith   PetscFunctionReturn(0);
658cd0e1443SSatish Balay }
659cd0e1443SSatish Balay 
66095d5f7c2SBarry Smith #if defined(PETSC_USE_MAT_SINGLE)
6614a2ae208SSatish Balay #undef __FUNCT__
6624a2ae208SSatish Balay #define __FUNCT__ "MatSetValuesBlocked_SeqBAIJ"
66395d5f7c2SBarry Smith int MatSetValuesBlocked_SeqBAIJ(Mat mat,int m,int *im,int n,int *in,Scalar *v,InsertMode addv)
66495d5f7c2SBarry Smith {
665563b5814SBarry Smith   Mat_SeqBAIJ *b = (Mat_SeqBAIJ*)mat->data;
666563b5814SBarry Smith   int         ierr,i,N = m*n*b->bs2;
667563b5814SBarry Smith   MatScalar   *vsingle;
66895d5f7c2SBarry Smith 
66995d5f7c2SBarry Smith   PetscFunctionBegin;
670563b5814SBarry Smith   if (N > b->setvalueslen) {
671563b5814SBarry Smith     if (b->setvaluescopy) {ierr = PetscFree(b->setvaluescopy);CHKERRQ(ierr);}
672b0a32e0cSBarry Smith     ierr = PetscMalloc(N*sizeof(MatScalar),&b->setvaluescopy);CHKERRQ(ierr);
673563b5814SBarry Smith     b->setvalueslen  = N;
674563b5814SBarry Smith   }
675563b5814SBarry Smith   vsingle = b->setvaluescopy;
67695d5f7c2SBarry Smith   for (i=0; i<N; i++) {
67795d5f7c2SBarry Smith     vsingle[i] = v[i];
67895d5f7c2SBarry Smith   }
67995d5f7c2SBarry Smith   ierr = MatSetValuesBlocked_SeqBAIJ_MatScalar(mat,m,im,n,in,vsingle,addv);CHKERRQ(ierr);
68095d5f7c2SBarry Smith   PetscFunctionReturn(0);
68195d5f7c2SBarry Smith }
68295d5f7c2SBarry Smith #endif
68395d5f7c2SBarry Smith 
6842d61bbb3SSatish Balay 
6854a2ae208SSatish Balay #undef __FUNCT__
6864a2ae208SSatish Balay #define __FUNCT__ "MatSetValuesBlocked_SeqBAIJ"
68795d5f7c2SBarry Smith int MatSetValuesBlocked_SeqBAIJ_MatScalar(Mat A,int m,int *im,int n,int *in,MatScalar *v,InsertMode is)
68892c4ed94SBarry Smith {
68992c4ed94SBarry Smith   Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)A->data;
6908a84c255SSatish Balay   int         *rp,k,low,high,t,ii,jj,row,nrow,i,col,l,rmax,N,sorted=a->sorted;
691273d9f13SBarry Smith   int         *imax=a->imax,*ai=a->i,*ailen=a->ilen;
692549d3d68SSatish Balay   int         *aj=a->j,nonew=a->nonew,bs2=a->bs2,bs=a->bs,stepval,ierr;
693273d9f13SBarry Smith   PetscTruth  roworiented=a->roworiented;
69495d5f7c2SBarry Smith   MatScalar   *value = v,*ap,*aa = a->a,*bap;
69592c4ed94SBarry Smith 
6963a40ed3dSBarry Smith   PetscFunctionBegin;
6970e324ae4SSatish Balay   if (roworiented) {
6980e324ae4SSatish Balay     stepval = (n-1)*bs;
6990e324ae4SSatish Balay   } else {
7000e324ae4SSatish Balay     stepval = (m-1)*bs;
7010e324ae4SSatish Balay   }
70292c4ed94SBarry Smith   for (k=0; k<m; k++) { /* loop over added rows */
70392c4ed94SBarry Smith     row  = im[k];
7045ef9f2a5SBarry Smith     if (row < 0) continue;
705aa482453SBarry Smith #if defined(PETSC_USE_BOPT_g)
70629bbc08cSBarry Smith     if (row >= a->mbs) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Row too large");
70792c4ed94SBarry Smith #endif
70892c4ed94SBarry Smith     rp   = aj + ai[row];
70992c4ed94SBarry Smith     ap   = aa + bs2*ai[row];
71092c4ed94SBarry Smith     rmax = imax[row];
71192c4ed94SBarry Smith     nrow = ailen[row];
71292c4ed94SBarry Smith     low  = 0;
71392c4ed94SBarry Smith     for (l=0; l<n; l++) { /* loop over added columns */
7145ef9f2a5SBarry Smith       if (in[l] < 0) continue;
715aa482453SBarry Smith #if defined(PETSC_USE_BOPT_g)
71629bbc08cSBarry Smith       if (in[l] >= a->nbs) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Column too large");
71792c4ed94SBarry Smith #endif
71892c4ed94SBarry Smith       col = in[l];
71992c4ed94SBarry Smith       if (roworiented) {
7200e324ae4SSatish Balay         value = v + k*(stepval+bs)*bs + l*bs;
7210e324ae4SSatish Balay       } else {
7220e324ae4SSatish Balay         value = v + l*(stepval+bs)*bs + k*bs;
72392c4ed94SBarry Smith       }
72492c4ed94SBarry Smith       if (!sorted) low = 0; high = nrow;
72592c4ed94SBarry Smith       while (high-low > 7) {
72692c4ed94SBarry Smith         t = (low+high)/2;
72792c4ed94SBarry Smith         if (rp[t] > col) high = t;
72892c4ed94SBarry Smith         else             low  = t;
72992c4ed94SBarry Smith       }
73092c4ed94SBarry Smith       for (i=low; i<high; i++) {
73192c4ed94SBarry Smith         if (rp[i] > col) break;
73292c4ed94SBarry Smith         if (rp[i] == col) {
7338a84c255SSatish Balay           bap  = ap +  bs2*i;
7340e324ae4SSatish Balay           if (roworiented) {
7358a84c255SSatish Balay             if (is == ADD_VALUES) {
736dd9472c6SBarry Smith               for (ii=0; ii<bs; ii++,value+=stepval) {
737dd9472c6SBarry Smith                 for (jj=ii; jj<bs2; jj+=bs) {
7388a84c255SSatish Balay                   bap[jj] += *value++;
739dd9472c6SBarry Smith                 }
740dd9472c6SBarry Smith               }
7410e324ae4SSatish Balay             } else {
742dd9472c6SBarry Smith               for (ii=0; ii<bs; ii++,value+=stepval) {
743dd9472c6SBarry Smith                 for (jj=ii; jj<bs2; jj+=bs) {
7440e324ae4SSatish Balay                   bap[jj] = *value++;
7458a84c255SSatish Balay                 }
746dd9472c6SBarry Smith               }
747dd9472c6SBarry Smith             }
7480e324ae4SSatish Balay           } else {
7490e324ae4SSatish Balay             if (is == ADD_VALUES) {
750dd9472c6SBarry Smith               for (ii=0; ii<bs; ii++,value+=stepval) {
751dd9472c6SBarry Smith                 for (jj=0; jj<bs; jj++) {
7520e324ae4SSatish Balay                   *bap++ += *value++;
753dd9472c6SBarry Smith                 }
754dd9472c6SBarry Smith               }
7550e324ae4SSatish Balay             } else {
756dd9472c6SBarry Smith               for (ii=0; ii<bs; ii++,value+=stepval) {
757dd9472c6SBarry Smith                 for (jj=0; jj<bs; jj++) {
7580e324ae4SSatish Balay                   *bap++  = *value++;
7590e324ae4SSatish Balay                 }
7608a84c255SSatish Balay               }
761dd9472c6SBarry Smith             }
762dd9472c6SBarry Smith           }
763f1241b54SBarry Smith           goto noinsert2;
76492c4ed94SBarry Smith         }
76592c4ed94SBarry Smith       }
76689280ab3SLois Curfman McInnes       if (nonew == 1) goto noinsert2;
76729bbc08cSBarry Smith       else if (nonew == -1) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Inserting a new nonzero in the matrix");
76892c4ed94SBarry Smith       if (nrow >= rmax) {
76992c4ed94SBarry Smith         /* there is no extra room in row, therefore enlarge */
77092c4ed94SBarry Smith         int       new_nz = ai[a->mbs] + CHUNKSIZE,len,*new_i,*new_j;
7713f1db9ecSBarry Smith         MatScalar *new_a;
77292c4ed94SBarry Smith 
77329bbc08cSBarry Smith         if (nonew == -2) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Inserting a new nonzero in the matrix");
77489280ab3SLois Curfman McInnes 
77592c4ed94SBarry Smith         /* malloc new storage space */
7763f1db9ecSBarry Smith         len     = new_nz*(sizeof(int)+bs2*sizeof(MatScalar))+(a->mbs+1)*sizeof(int);
777b0a32e0cSBarry Smith 	ierr    = PetscMalloc(len,&new_a);CHKERRQ(ierr);
77892c4ed94SBarry Smith         new_j   = (int*)(new_a + bs2*new_nz);
77992c4ed94SBarry Smith         new_i   = new_j + new_nz;
78092c4ed94SBarry Smith 
78192c4ed94SBarry Smith         /* copy over old data into new slots */
78292c4ed94SBarry Smith         for (ii=0; ii<row+1; ii++) {new_i[ii] = ai[ii];}
78392c4ed94SBarry Smith         for (ii=row+1; ii<a->mbs+1; ii++) {new_i[ii] = ai[ii]+CHUNKSIZE;}
784549d3d68SSatish Balay         ierr = PetscMemcpy(new_j,aj,(ai[row]+nrow)*sizeof(int));CHKERRQ(ierr);
78592c4ed94SBarry Smith         len  = (new_nz - CHUNKSIZE - ai[row] - nrow);
786549d3d68SSatish Balay         ierr = PetscMemcpy(new_j+ai[row]+nrow+CHUNKSIZE,aj+ai[row]+nrow,len*sizeof(int));CHKERRQ(ierr);
787549d3d68SSatish Balay         ierr = PetscMemcpy(new_a,aa,(ai[row]+nrow)*bs2*sizeof(MatScalar));CHKERRQ(ierr);
788549d3d68SSatish Balay         ierr = PetscMemzero(new_a+bs2*(ai[row]+nrow),bs2*CHUNKSIZE*sizeof(MatScalar));CHKERRQ(ierr);
789549d3d68SSatish Balay         ierr = PetscMemcpy(new_a+bs2*(ai[row]+nrow+CHUNKSIZE),aa+bs2*(ai[row]+nrow),bs2*len*sizeof(MatScalar));CHKERRQ(ierr);
79092c4ed94SBarry Smith         /* free up old matrix storage */
791606d414cSSatish Balay         ierr = PetscFree(a->a);CHKERRQ(ierr);
792606d414cSSatish Balay         if (!a->singlemalloc) {
793606d414cSSatish Balay           ierr = PetscFree(a->i);CHKERRQ(ierr);
794606d414cSSatish Balay           ierr = PetscFree(a->j);CHKERRQ(ierr);
795606d414cSSatish Balay         }
79692c4ed94SBarry Smith         aa = a->a = new_a; ai = a->i = new_i; aj = a->j = new_j;
797c4992f7dSBarry Smith         a->singlemalloc = PETSC_TRUE;
79892c4ed94SBarry Smith 
79992c4ed94SBarry Smith         rp   = aj + ai[row]; ap = aa + bs2*ai[row];
80092c4ed94SBarry Smith         rmax = imax[row] = imax[row] + CHUNKSIZE;
801b0a32e0cSBarry Smith         PetscLogObjectMemory(A,CHUNKSIZE*(sizeof(int) + bs2*sizeof(MatScalar)));
80292c4ed94SBarry Smith         a->maxnz += bs2*CHUNKSIZE;
80392c4ed94SBarry Smith         a->reallocs++;
80492c4ed94SBarry Smith         a->nz++;
80592c4ed94SBarry Smith       }
80692c4ed94SBarry Smith       N = nrow++ - 1;
80792c4ed94SBarry Smith       /* shift up all the later entries in this row */
80892c4ed94SBarry Smith       for (ii=N; ii>=i; ii--) {
80992c4ed94SBarry Smith         rp[ii+1] = rp[ii];
810549d3d68SSatish Balay         ierr = PetscMemcpy(ap+bs2*(ii+1),ap+bs2*(ii),bs2*sizeof(MatScalar));CHKERRQ(ierr);
81192c4ed94SBarry Smith       }
812549d3d68SSatish Balay       if (N >= i) {
813549d3d68SSatish Balay         ierr = PetscMemzero(ap+bs2*i,bs2*sizeof(MatScalar));CHKERRQ(ierr);
814549d3d68SSatish Balay       }
81592c4ed94SBarry Smith       rp[i] = col;
8168a84c255SSatish Balay       bap   = ap +  bs2*i;
8170e324ae4SSatish Balay       if (roworiented) {
818dd9472c6SBarry Smith         for (ii=0; ii<bs; ii++,value+=stepval) {
819dd9472c6SBarry Smith           for (jj=ii; jj<bs2; jj+=bs) {
8200e324ae4SSatish Balay             bap[jj] = *value++;
821dd9472c6SBarry Smith           }
822dd9472c6SBarry Smith         }
8230e324ae4SSatish Balay       } else {
824dd9472c6SBarry Smith         for (ii=0; ii<bs; ii++,value+=stepval) {
825dd9472c6SBarry Smith           for (jj=0; jj<bs; jj++) {
8260e324ae4SSatish Balay             *bap++  = *value++;
8270e324ae4SSatish Balay           }
828dd9472c6SBarry Smith         }
829dd9472c6SBarry Smith       }
830f1241b54SBarry Smith       noinsert2:;
83192c4ed94SBarry Smith       low = i;
83292c4ed94SBarry Smith     }
83392c4ed94SBarry Smith     ailen[row] = nrow;
83492c4ed94SBarry Smith   }
8353a40ed3dSBarry Smith   PetscFunctionReturn(0);
83692c4ed94SBarry Smith }
83792c4ed94SBarry Smith 
838f2501298SSatish Balay 
8394a2ae208SSatish Balay #undef __FUNCT__
8404a2ae208SSatish Balay #define __FUNCT__ "MatAssemblyEnd_SeqBAIJ"
8418f6be9afSLois Curfman McInnes int MatAssemblyEnd_SeqBAIJ(Mat A,MatAssemblyType mode)
842584200bdSSatish Balay {
843584200bdSSatish Balay   Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)A->data;
844584200bdSSatish Balay   int        fshift = 0,i,j,*ai = a->i,*aj = a->j,*imax = a->imax;
845273d9f13SBarry Smith   int        m = A->m,*ip,N,*ailen = a->ilen;
846549d3d68SSatish Balay   int        mbs = a->mbs,bs2 = a->bs2,rmax = 0,ierr;
8473f1db9ecSBarry Smith   MatScalar  *aa = a->a,*ap;
848584200bdSSatish Balay 
8493a40ed3dSBarry Smith   PetscFunctionBegin;
8503a40ed3dSBarry Smith   if (mode == MAT_FLUSH_ASSEMBLY) PetscFunctionReturn(0);
851584200bdSSatish Balay 
85243ee02c3SBarry Smith   if (m) rmax = ailen[0];
853584200bdSSatish Balay   for (i=1; i<mbs; i++) {
854584200bdSSatish Balay     /* move each row back by the amount of empty slots (fshift) before it*/
855584200bdSSatish Balay     fshift += imax[i-1] - ailen[i-1];
856d402145bSBarry Smith     rmax   = PetscMax(rmax,ailen[i]);
857584200bdSSatish Balay     if (fshift) {
858a7c10996SSatish Balay       ip = aj + ai[i]; ap = aa + bs2*ai[i];
859584200bdSSatish Balay       N = ailen[i];
860584200bdSSatish Balay       for (j=0; j<N; j++) {
861584200bdSSatish Balay         ip[j-fshift] = ip[j];
862549d3d68SSatish Balay         ierr = PetscMemcpy(ap+(j-fshift)*bs2,ap+j*bs2,bs2*sizeof(MatScalar));CHKERRQ(ierr);
863584200bdSSatish Balay       }
864584200bdSSatish Balay     }
865584200bdSSatish Balay     ai[i] = ai[i-1] + ailen[i-1];
866584200bdSSatish Balay   }
867584200bdSSatish Balay   if (mbs) {
868584200bdSSatish Balay     fshift += imax[mbs-1] - ailen[mbs-1];
869584200bdSSatish Balay     ai[mbs] = ai[mbs-1] + ailen[mbs-1];
870584200bdSSatish Balay   }
871584200bdSSatish Balay   /* reset ilen and imax for each row */
872584200bdSSatish Balay   for (i=0; i<mbs; i++) {
873584200bdSSatish Balay     ailen[i] = imax[i] = ai[i+1] - ai[i];
874584200bdSSatish Balay   }
875a7c10996SSatish Balay   a->nz = ai[mbs];
876584200bdSSatish Balay 
877584200bdSSatish Balay   /* diagonals may have moved, so kill the diagonal pointers */
878584200bdSSatish Balay   if (fshift && a->diag) {
879606d414cSSatish Balay     ierr = PetscFree(a->diag);CHKERRQ(ierr);
880b0a32e0cSBarry Smith     PetscLogObjectMemory(A,-(m+1)*sizeof(int));
881584200bdSSatish Balay     a->diag = 0;
882584200bdSSatish Balay   }
883b0a32e0cSBarry Smith   PetscLogInfo(A,"MatAssemblyEnd_SeqBAIJ:Matrix size: %d X %d, block size %d; storage space: %d unneeded, %d used\n",
884273d9f13SBarry Smith            m,A->n,a->bs,fshift*bs2,a->nz*bs2);
885b0a32e0cSBarry Smith   PetscLogInfo(A,"MatAssemblyEnd_SeqBAIJ:Number of mallocs during MatSetValues is %d\n",
886584200bdSSatish Balay            a->reallocs);
887b0a32e0cSBarry Smith   PetscLogInfo(A,"MatAssemblyEnd_SeqBAIJ:Most nonzeros blocks in any row is %d\n",rmax);
888e2f3b5e9SSatish Balay   a->reallocs          = 0;
8890e6d2581SBarry Smith   A->info.nz_unneeded  = (PetscReal)fshift*bs2;
8904e220ebcSLois Curfman McInnes 
8913a40ed3dSBarry Smith   PetscFunctionReturn(0);
892584200bdSSatish Balay }
893584200bdSSatish Balay 
8945a838052SSatish Balay 
895bea157c4SSatish Balay 
896bea157c4SSatish Balay /*
897bea157c4SSatish Balay    This function returns an array of flags which indicate the locations of contiguous
898bea157c4SSatish Balay    blocks that should be zeroed. for eg: if bs = 3  and is = [0,1,2,3,5,6,7,8,9]
899bea157c4SSatish Balay    then the resulting sizes = [3,1,1,3,1] correspondig to sets [(0,1,2),(3),(5),(6,7,8),(9)]
900bea157c4SSatish Balay    Assume: sizes should be long enough to hold all the values.
901bea157c4SSatish Balay */
9024a2ae208SSatish Balay #undef __FUNCT__
9034a2ae208SSatish Balay #define __FUNCT__ "MatZeroRows_SeqBAIJ_Check_Blocks"
904bea157c4SSatish Balay static int MatZeroRows_SeqBAIJ_Check_Blocks(int idx[],int n,int bs,int sizes[], int *bs_max)
905d9b7c43dSSatish Balay {
906bea157c4SSatish Balay   int        i,j,k,row;
907bea157c4SSatish Balay   PetscTruth flg;
9083a40ed3dSBarry Smith 
909433994e6SBarry Smith   PetscFunctionBegin;
910bea157c4SSatish Balay   for (i=0,j=0; i<n; j++) {
911bea157c4SSatish Balay     row = idx[i];
912bea157c4SSatish Balay     if (row%bs!=0) { /* Not the begining of a block */
913bea157c4SSatish Balay       sizes[j] = 1;
914bea157c4SSatish Balay       i++;
915e4fda26cSSatish Balay     } else if (i+bs > n) { /* complete block doesn't exist (at idx end) */
916bea157c4SSatish Balay       sizes[j] = 1;         /* Also makes sure atleast 'bs' values exist for next else */
917bea157c4SSatish Balay       i++;
918bea157c4SSatish Balay     } else { /* Begining of the block, so check if the complete block exists */
919bea157c4SSatish Balay       flg = PETSC_TRUE;
920bea157c4SSatish Balay       for (k=1; k<bs; k++) {
921bea157c4SSatish Balay         if (row+k != idx[i+k]) { /* break in the block */
922bea157c4SSatish Balay           flg = PETSC_FALSE;
923bea157c4SSatish Balay           break;
924d9b7c43dSSatish Balay         }
925bea157c4SSatish Balay       }
926bea157c4SSatish Balay       if (flg == PETSC_TRUE) { /* No break in the bs */
927bea157c4SSatish Balay         sizes[j] = bs;
928bea157c4SSatish Balay         i+= bs;
929bea157c4SSatish Balay       } else {
930bea157c4SSatish Balay         sizes[j] = 1;
931bea157c4SSatish Balay         i++;
932bea157c4SSatish Balay       }
933bea157c4SSatish Balay     }
934bea157c4SSatish Balay   }
935bea157c4SSatish Balay   *bs_max = j;
9363a40ed3dSBarry Smith   PetscFunctionReturn(0);
937d9b7c43dSSatish Balay }
938d9b7c43dSSatish Balay 
9394a2ae208SSatish Balay #undef __FUNCT__
9404a2ae208SSatish Balay #define __FUNCT__ "MatZeroRows_SeqBAIJ"
9418f6be9afSLois Curfman McInnes int MatZeroRows_SeqBAIJ(Mat A,IS is,Scalar *diag)
942d9b7c43dSSatish Balay {
943d9b7c43dSSatish Balay   Mat_SeqBAIJ *baij=(Mat_SeqBAIJ*)A->data;
944b6815fffSBarry Smith   int         ierr,i,j,k,count,is_n,*is_idx,*rows;
945bea157c4SSatish Balay   int         bs=baij->bs,bs2=baij->bs2,*sizes,row,bs_max;
9463f1db9ecSBarry Smith   Scalar      zero = 0.0;
9473f1db9ecSBarry Smith   MatScalar   *aa;
948d9b7c43dSSatish Balay 
9493a40ed3dSBarry Smith   PetscFunctionBegin;
950d9b7c43dSSatish Balay   /* Make a copy of the IS and  sort it */
951b9b97703SBarry Smith   ierr = ISGetLocalSize(is,&is_n);CHKERRQ(ierr);
952d9b7c43dSSatish Balay   ierr = ISGetIndices(is,&is_idx);CHKERRQ(ierr);
953d9b7c43dSSatish Balay 
954bea157c4SSatish Balay   /* allocate memory for rows,sizes */
955b0a32e0cSBarry Smith   ierr  = PetscMalloc((3*is_n+1)*sizeof(int),&rows);CHKERRQ(ierr);
956bea157c4SSatish Balay   sizes = rows + is_n;
957bea157c4SSatish Balay 
958563b5814SBarry Smith   /* copy IS values to rows, and sort them */
959bea157c4SSatish Balay   for (i=0; i<is_n; i++) { rows[i] = is_idx[i]; }
960bea157c4SSatish Balay   ierr = PetscSortInt(is_n,rows);CHKERRQ(ierr);
961dffd3267SBarry Smith   if (baij->keepzeroedrows) {
962dffd3267SBarry Smith     for (i=0; i<is_n; i++) { sizes[i] = 1; }
963dffd3267SBarry Smith     bs_max = is_n;
964dffd3267SBarry Smith   } else {
965bea157c4SSatish Balay     ierr = MatZeroRows_SeqBAIJ_Check_Blocks(rows,is_n,bs,sizes,&bs_max);CHKERRQ(ierr);
966dffd3267SBarry Smith   }
967b97a56abSSatish Balay   ierr = ISRestoreIndices(is,&is_idx);CHKERRQ(ierr);
968bea157c4SSatish Balay 
969bea157c4SSatish Balay   for (i=0,j=0; i<bs_max; j+=sizes[i],i++) {
970bea157c4SSatish Balay     row   = rows[j];
971273d9f13SBarry Smith     if (row < 0 || row > A->m) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"row %d out of range",row);
972bea157c4SSatish Balay     count = (baij->i[row/bs +1] - baij->i[row/bs])*bs;
973bea157c4SSatish Balay     aa    = baij->a + baij->i[row/bs]*bs2 + (row%bs);
974dffd3267SBarry Smith     if (sizes[i] == bs && !baij->keepzeroedrows) {
975bea157c4SSatish Balay       if (diag) {
976bea157c4SSatish Balay         if (baij->ilen[row/bs] > 0) {
977bea157c4SSatish Balay           baij->ilen[row/bs]       = 1;
978bea157c4SSatish Balay           baij->j[baij->i[row/bs]] = row/bs;
979bea157c4SSatish Balay           ierr = PetscMemzero(aa,count*bs*sizeof(MatScalar));CHKERRQ(ierr);
980a07cd24cSSatish Balay         }
981563b5814SBarry Smith         /* Now insert all the diagonal values for this bs */
982bea157c4SSatish Balay         for (k=0; k<bs; k++) {
983bea157c4SSatish Balay           ierr = (*A->ops->setvalues)(A,1,rows+j+k,1,rows+j+k,diag,INSERT_VALUES);CHKERRQ(ierr);
984bea157c4SSatish Balay         }
985bea157c4SSatish Balay       } else { /* (!diag) */
986bea157c4SSatish Balay         baij->ilen[row/bs] = 0;
987bea157c4SSatish Balay       } /* end (!diag) */
988bea157c4SSatish Balay     } else { /* (sizes[i] != bs) */
989aa482453SBarry Smith #if defined (PETSC_USE_DEBUG)
99029bbc08cSBarry Smith       if (sizes[i] != 1) SETERRQ(1,"Internal Error. Value should be 1");
991bea157c4SSatish Balay #endif
992bea157c4SSatish Balay       for (k=0; k<count; k++) {
993d9b7c43dSSatish Balay         aa[0] =  zero;
994d9b7c43dSSatish Balay         aa    += bs;
995d9b7c43dSSatish Balay       }
996d9b7c43dSSatish Balay       if (diag) {
997f830108cSBarry Smith         ierr = (*A->ops->setvalues)(A,1,rows+j,1,rows+j,diag,INSERT_VALUES);CHKERRQ(ierr);
998d9b7c43dSSatish Balay       }
999d9b7c43dSSatish Balay     }
1000bea157c4SSatish Balay   }
1001bea157c4SSatish Balay 
1002606d414cSSatish Balay   ierr = PetscFree(rows);CHKERRQ(ierr);
10039a8dea36SBarry Smith   ierr = MatAssemblyEnd_SeqBAIJ(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
10043a40ed3dSBarry Smith   PetscFunctionReturn(0);
1005d9b7c43dSSatish Balay }
10061c351548SSatish Balay 
10074a2ae208SSatish Balay #undef __FUNCT__
10084a2ae208SSatish Balay #define __FUNCT__ "MatSetValues_SeqBAIJ"
10092d61bbb3SSatish Balay int MatSetValues_SeqBAIJ(Mat A,int m,int *im,int n,int *in,Scalar *v,InsertMode is)
10102d61bbb3SSatish Balay {
10112d61bbb3SSatish Balay   Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)A->data;
10122d61bbb3SSatish Balay   int         *rp,k,low,high,t,ii,row,nrow,i,col,l,rmax,N,sorted=a->sorted;
1013273d9f13SBarry Smith   int         *imax=a->imax,*ai=a->i,*ailen=a->ilen;
10142d61bbb3SSatish Balay   int         *aj=a->j,nonew=a->nonew,bs=a->bs,brow,bcol;
1015549d3d68SSatish Balay   int         ridx,cidx,bs2=a->bs2,ierr;
1016273d9f13SBarry Smith   PetscTruth  roworiented=a->roworiented;
10173f1db9ecSBarry Smith   MatScalar   *ap,value,*aa=a->a,*bap;
10182d61bbb3SSatish Balay 
10192d61bbb3SSatish Balay   PetscFunctionBegin;
10202d61bbb3SSatish Balay   for (k=0; k<m; k++) { /* loop over added rows */
10212d61bbb3SSatish Balay     row  = im[k]; brow = row/bs;
10225ef9f2a5SBarry Smith     if (row < 0) continue;
1023aa482453SBarry Smith #if defined(PETSC_USE_BOPT_g)
1024273d9f13SBarry Smith     if (row >= A->m) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"Row too large: row %d max %d",row,A->m);
10252d61bbb3SSatish Balay #endif
10262d61bbb3SSatish Balay     rp   = aj + ai[brow];
10272d61bbb3SSatish Balay     ap   = aa + bs2*ai[brow];
10282d61bbb3SSatish Balay     rmax = imax[brow];
10292d61bbb3SSatish Balay     nrow = ailen[brow];
10302d61bbb3SSatish Balay     low  = 0;
10312d61bbb3SSatish Balay     for (l=0; l<n; l++) { /* loop over added columns */
10325ef9f2a5SBarry Smith       if (in[l] < 0) continue;
1033aa482453SBarry Smith #if defined(PETSC_USE_BOPT_g)
1034273d9f13SBarry Smith       if (in[l] >= A->n) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"Column too large: col %d max %d",in[l],A->n);
10352d61bbb3SSatish Balay #endif
10362d61bbb3SSatish Balay       col = in[l]; bcol = col/bs;
10372d61bbb3SSatish Balay       ridx = row % bs; cidx = col % bs;
10382d61bbb3SSatish Balay       if (roworiented) {
10395ef9f2a5SBarry Smith         value = v[l + k*n];
10402d61bbb3SSatish Balay       } else {
10412d61bbb3SSatish Balay         value = v[k + l*m];
10422d61bbb3SSatish Balay       }
10432d61bbb3SSatish Balay       if (!sorted) low = 0; high = nrow;
10442d61bbb3SSatish Balay       while (high-low > 7) {
10452d61bbb3SSatish Balay         t = (low+high)/2;
10462d61bbb3SSatish Balay         if (rp[t] > bcol) high = t;
10472d61bbb3SSatish Balay         else              low  = t;
10482d61bbb3SSatish Balay       }
10492d61bbb3SSatish Balay       for (i=low; i<high; i++) {
10502d61bbb3SSatish Balay         if (rp[i] > bcol) break;
10512d61bbb3SSatish Balay         if (rp[i] == bcol) {
10522d61bbb3SSatish Balay           bap  = ap +  bs2*i + bs*cidx + ridx;
10532d61bbb3SSatish Balay           if (is == ADD_VALUES) *bap += value;
10542d61bbb3SSatish Balay           else                  *bap  = value;
10552d61bbb3SSatish Balay           goto noinsert1;
10562d61bbb3SSatish Balay         }
10572d61bbb3SSatish Balay       }
10582d61bbb3SSatish Balay       if (nonew == 1) goto noinsert1;
105929bbc08cSBarry Smith       else if (nonew == -1) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Inserting a new nonzero in the matrix");
10602d61bbb3SSatish Balay       if (nrow >= rmax) {
10612d61bbb3SSatish Balay         /* there is no extra room in row, therefore enlarge */
10622d61bbb3SSatish Balay         int       new_nz = ai[a->mbs] + CHUNKSIZE,len,*new_i,*new_j;
10633f1db9ecSBarry Smith         MatScalar *new_a;
10642d61bbb3SSatish Balay 
106529bbc08cSBarry Smith         if (nonew == -2) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Inserting a new nonzero in the matrix");
10662d61bbb3SSatish Balay 
10672d61bbb3SSatish Balay         /* Malloc new storage space */
10683f1db9ecSBarry Smith         len     = new_nz*(sizeof(int)+bs2*sizeof(MatScalar))+(a->mbs+1)*sizeof(int);
1069b0a32e0cSBarry Smith 	ierr    = PetscMalloc(len,&new_a);CHKERRQ(ierr);
10702d61bbb3SSatish Balay         new_j   = (int*)(new_a + bs2*new_nz);
10712d61bbb3SSatish Balay         new_i   = new_j + new_nz;
10722d61bbb3SSatish Balay 
10732d61bbb3SSatish Balay         /* copy over old data into new slots */
10742d61bbb3SSatish Balay         for (ii=0; ii<brow+1; ii++) {new_i[ii] = ai[ii];}
10752d61bbb3SSatish Balay         for (ii=brow+1; ii<a->mbs+1; ii++) {new_i[ii] = ai[ii]+CHUNKSIZE;}
1076549d3d68SSatish Balay         ierr = PetscMemcpy(new_j,aj,(ai[brow]+nrow)*sizeof(int));CHKERRQ(ierr);
10772d61bbb3SSatish Balay         len  = (new_nz - CHUNKSIZE - ai[brow] - nrow);
1078549d3d68SSatish Balay         ierr = PetscMemcpy(new_j+ai[brow]+nrow+CHUNKSIZE,aj+ai[brow]+nrow,len*sizeof(int));CHKERRQ(ierr);
1079549d3d68SSatish Balay         ierr = PetscMemcpy(new_a,aa,(ai[brow]+nrow)*bs2*sizeof(MatScalar));CHKERRQ(ierr);
1080549d3d68SSatish Balay         ierr = PetscMemzero(new_a+bs2*(ai[brow]+nrow),bs2*CHUNKSIZE*sizeof(MatScalar));CHKERRQ(ierr);
1081549d3d68SSatish Balay         ierr = PetscMemcpy(new_a+bs2*(ai[brow]+nrow+CHUNKSIZE),aa+bs2*(ai[brow]+nrow),bs2*len*sizeof(MatScalar));CHKERRQ(ierr);
10822d61bbb3SSatish Balay         /* free up old matrix storage */
1083606d414cSSatish Balay         ierr = PetscFree(a->a);CHKERRQ(ierr);
1084606d414cSSatish Balay         if (!a->singlemalloc) {
1085606d414cSSatish Balay           ierr = PetscFree(a->i);CHKERRQ(ierr);
1086606d414cSSatish Balay           ierr = PetscFree(a->j);CHKERRQ(ierr);
1087606d414cSSatish Balay         }
10882d61bbb3SSatish Balay         aa = a->a = new_a; ai = a->i = new_i; aj = a->j = new_j;
1089c4992f7dSBarry Smith         a->singlemalloc = PETSC_TRUE;
10902d61bbb3SSatish Balay 
10912d61bbb3SSatish Balay         rp   = aj + ai[brow]; ap = aa + bs2*ai[brow];
10922d61bbb3SSatish Balay         rmax = imax[brow] = imax[brow] + CHUNKSIZE;
1093b0a32e0cSBarry Smith         PetscLogObjectMemory(A,CHUNKSIZE*(sizeof(int) + bs2*sizeof(MatScalar)));
10942d61bbb3SSatish Balay         a->maxnz += bs2*CHUNKSIZE;
10952d61bbb3SSatish Balay         a->reallocs++;
10962d61bbb3SSatish Balay         a->nz++;
10972d61bbb3SSatish Balay       }
10982d61bbb3SSatish Balay       N = nrow++ - 1;
10992d61bbb3SSatish Balay       /* shift up all the later entries in this row */
11002d61bbb3SSatish Balay       for (ii=N; ii>=i; ii--) {
11012d61bbb3SSatish Balay         rp[ii+1] = rp[ii];
1102549d3d68SSatish Balay         ierr     = PetscMemcpy(ap+bs2*(ii+1),ap+bs2*(ii),bs2*sizeof(MatScalar));CHKERRQ(ierr);
11032d61bbb3SSatish Balay       }
1104549d3d68SSatish Balay       if (N>=i) {
1105549d3d68SSatish Balay         ierr = PetscMemzero(ap+bs2*i,bs2*sizeof(MatScalar));CHKERRQ(ierr);
1106549d3d68SSatish Balay       }
11072d61bbb3SSatish Balay       rp[i]                      = bcol;
11082d61bbb3SSatish Balay       ap[bs2*i + bs*cidx + ridx] = value;
11092d61bbb3SSatish Balay       noinsert1:;
11102d61bbb3SSatish Balay       low = i;
11112d61bbb3SSatish Balay     }
11122d61bbb3SSatish Balay     ailen[brow] = nrow;
11132d61bbb3SSatish Balay   }
11142d61bbb3SSatish Balay   PetscFunctionReturn(0);
11152d61bbb3SSatish Balay }
11162d61bbb3SSatish Balay 
11172d61bbb3SSatish Balay 
11184a2ae208SSatish Balay #undef __FUNCT__
11194a2ae208SSatish Balay #define __FUNCT__ "MatILUFactor_SeqBAIJ"
11205ef9f2a5SBarry Smith int MatILUFactor_SeqBAIJ(Mat inA,IS row,IS col,MatILUInfo *info)
11212d61bbb3SSatish Balay {
11222d61bbb3SSatish Balay   Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)inA->data;
11232d61bbb3SSatish Balay   Mat         outA;
11242d61bbb3SSatish Balay   int         ierr;
1125667159a5SBarry Smith   PetscTruth  row_identity,col_identity;
11262d61bbb3SSatish Balay 
11272d61bbb3SSatish Balay   PetscFunctionBegin;
112829bbc08cSBarry Smith   if (info && info->levels != 0) SETERRQ(PETSC_ERR_SUP,"Only levels = 0 supported for in-place ILU");
1129667159a5SBarry Smith   ierr = ISIdentity(row,&row_identity);CHKERRQ(ierr);
1130667159a5SBarry Smith   ierr = ISIdentity(col,&col_identity);CHKERRQ(ierr);
1131667159a5SBarry Smith   if (!row_identity || !col_identity) {
113229bbc08cSBarry Smith     SETERRQ(1,"Row and column permutations must be identity for in-place ILU");
1133667159a5SBarry Smith   }
11342d61bbb3SSatish Balay 
11352d61bbb3SSatish Balay   outA          = inA;
11362d61bbb3SSatish Balay   inA->factor   = FACTOR_LU;
11372d61bbb3SSatish Balay 
11382d61bbb3SSatish Balay   if (!a->diag) {
1139c4992f7dSBarry Smith     ierr = MatMarkDiagonal_SeqBAIJ(inA);CHKERRQ(ierr);
11402d61bbb3SSatish Balay   }
11412d61bbb3SSatish Balay   /*
114215091d37SBarry Smith       Blocksize 2, 3, 4, 5, 6 and 7 have a special faster factorization/solver
114315091d37SBarry Smith       for ILU(0) factorization with natural ordering
11442d61bbb3SSatish Balay   */
11458661488fSKris Buschelman   if (a->bs < 8) {
114654138f6bSKris Buschelman     ierr = MatSeqBAIJ_UpdateFactor_NaturalOrdering(inA);CHKERRQ(ierr);
11473477af42SKris Buschelman   } else {
1148c38d4ed2SBarry Smith     a->row        = row;
1149c38d4ed2SBarry Smith     a->col        = col;
1150c38d4ed2SBarry Smith     ierr          = PetscObjectReference((PetscObject)row);CHKERRQ(ierr);
1151c38d4ed2SBarry Smith     ierr          = PetscObjectReference((PetscObject)col);CHKERRQ(ierr);
1152c38d4ed2SBarry Smith 
1153c38d4ed2SBarry Smith     /* Create the invert permutation so that it can be used in MatLUFactorNumeric() */
11544c49b128SBarry Smith     ierr = ISInvertPermutation(col,PETSC_DECIDE,&a->icol);CHKERRQ(ierr);
1155b0a32e0cSBarry Smith     PetscLogObjectParent(inA,a->icol);
1156c38d4ed2SBarry Smith 
1157c38d4ed2SBarry Smith     if (!a->solve_work) {
1158b0a32e0cSBarry Smith       ierr = PetscMalloc((inA->m+a->bs)*sizeof(Scalar),&a->solve_work);CHKERRQ(ierr);
1159b0a32e0cSBarry Smith       PetscLogObjectMemory(inA,(inA->m+a->bs)*sizeof(Scalar));
1160c38d4ed2SBarry Smith     }
11612d61bbb3SSatish Balay   }
11622d61bbb3SSatish Balay 
1163667159a5SBarry Smith   ierr = MatLUFactorNumeric(inA,&outA);CHKERRQ(ierr);
1164667159a5SBarry Smith 
11652d61bbb3SSatish Balay   PetscFunctionReturn(0);
11662d61bbb3SSatish Balay }
11674a2ae208SSatish Balay #undef __FUNCT__
11684a2ae208SSatish Balay #define __FUNCT__ "MatPrintHelp_SeqBAIJ"
1169ba4ca20aSSatish Balay int MatPrintHelp_SeqBAIJ(Mat A)
1170ba4ca20aSSatish Balay {
1171c38d4ed2SBarry Smith   static PetscTruth called = PETSC_FALSE;
1172ba4ca20aSSatish Balay   MPI_Comm          comm = A->comm;
1173d132466eSBarry Smith   int               ierr;
1174ba4ca20aSSatish Balay 
11753a40ed3dSBarry Smith   PetscFunctionBegin;
1176c38d4ed2SBarry Smith   if (called) {PetscFunctionReturn(0);} else called = PETSC_TRUE;
1177d132466eSBarry Smith   ierr = (*PetscHelpPrintf)(comm," Options for MATSEQBAIJ and MATMPIBAIJ matrix formats (the defaults):\n");CHKERRQ(ierr);
1178d132466eSBarry Smith   ierr = (*PetscHelpPrintf)(comm,"  -mat_block_size <block_size>\n");CHKERRQ(ierr);
11793a40ed3dSBarry Smith   PetscFunctionReturn(0);
1180ba4ca20aSSatish Balay }
1181d9b7c43dSSatish Balay 
1182fb2e594dSBarry Smith EXTERN_C_BEGIN
11834a2ae208SSatish Balay #undef __FUNCT__
11844a2ae208SSatish Balay #define __FUNCT__ "MatSeqBAIJSetColumnIndices_SeqBAIJ"
118527a8da17SBarry Smith int MatSeqBAIJSetColumnIndices_SeqBAIJ(Mat mat,int *indices)
118627a8da17SBarry Smith {
118727a8da17SBarry Smith   Mat_SeqBAIJ *baij = (Mat_SeqBAIJ *)mat->data;
118827a8da17SBarry Smith   int         i,nz,n;
118927a8da17SBarry Smith 
119027a8da17SBarry Smith   PetscFunctionBegin;
119127a8da17SBarry Smith   nz = baij->maxnz;
1192273d9f13SBarry Smith   n  = mat->n;
119327a8da17SBarry Smith   for (i=0; i<nz; i++) {
119427a8da17SBarry Smith     baij->j[i] = indices[i];
119527a8da17SBarry Smith   }
119627a8da17SBarry Smith   baij->nz = nz;
119727a8da17SBarry Smith   for (i=0; i<n; i++) {
119827a8da17SBarry Smith     baij->ilen[i] = baij->imax[i];
119927a8da17SBarry Smith   }
120027a8da17SBarry Smith 
120127a8da17SBarry Smith   PetscFunctionReturn(0);
120227a8da17SBarry Smith }
1203fb2e594dSBarry Smith EXTERN_C_END
120427a8da17SBarry Smith 
12054a2ae208SSatish Balay #undef __FUNCT__
12064a2ae208SSatish Balay #define __FUNCT__ "MatSeqBAIJSetColumnIndices"
120727a8da17SBarry Smith /*@
120827a8da17SBarry Smith     MatSeqBAIJSetColumnIndices - Set the column indices for all the rows
120927a8da17SBarry Smith        in the matrix.
121027a8da17SBarry Smith 
121127a8da17SBarry Smith   Input Parameters:
121227a8da17SBarry Smith +  mat - the SeqBAIJ matrix
121327a8da17SBarry Smith -  indices - the column indices
121427a8da17SBarry Smith 
121515091d37SBarry Smith   Level: advanced
121615091d37SBarry Smith 
121727a8da17SBarry Smith   Notes:
121827a8da17SBarry Smith     This can be called if you have precomputed the nonzero structure of the
121927a8da17SBarry Smith   matrix and want to provide it to the matrix object to improve the performance
122027a8da17SBarry Smith   of the MatSetValues() operation.
122127a8da17SBarry Smith 
122227a8da17SBarry Smith     You MUST have set the correct numbers of nonzeros per row in the call to
122327a8da17SBarry Smith   MatCreateSeqBAIJ().
122427a8da17SBarry Smith 
122527a8da17SBarry Smith     MUST be called before any calls to MatSetValues();
122627a8da17SBarry Smith 
122727a8da17SBarry Smith @*/
122827a8da17SBarry Smith int MatSeqBAIJSetColumnIndices(Mat mat,int *indices)
122927a8da17SBarry Smith {
123027a8da17SBarry Smith   int ierr,(*f)(Mat,int *);
123127a8da17SBarry Smith 
123227a8da17SBarry Smith   PetscFunctionBegin;
123327a8da17SBarry Smith   PetscValidHeaderSpecific(mat,MAT_COOKIE);
1234b9617806SBarry Smith   ierr = PetscObjectQueryFunction((PetscObject)mat,"MatSeqBAIJSetColumnIndices_C",(void (**)())&f);CHKERRQ(ierr);
123527a8da17SBarry Smith   if (f) {
123627a8da17SBarry Smith     ierr = (*f)(mat,indices);CHKERRQ(ierr);
123727a8da17SBarry Smith   } else {
123829bbc08cSBarry Smith     SETERRQ(1,"Wrong type of matrix to set column indices");
123927a8da17SBarry Smith   }
124027a8da17SBarry Smith   PetscFunctionReturn(0);
124127a8da17SBarry Smith }
124227a8da17SBarry Smith 
12434a2ae208SSatish Balay #undef __FUNCT__
12444a2ae208SSatish Balay #define __FUNCT__ "MatGetRowMax_SeqBAIJ"
1245273d9f13SBarry Smith int MatGetRowMax_SeqBAIJ(Mat A,Vec v)
1246273d9f13SBarry Smith {
1247273d9f13SBarry Smith   Mat_SeqBAIJ  *a = (Mat_SeqBAIJ*)A->data;
1248273d9f13SBarry Smith   int          ierr,i,j,n,row,bs,*ai,*aj,mbs;
1249273d9f13SBarry Smith   PetscReal    atmp;
1250273d9f13SBarry Smith   Scalar       *x,zero = 0.0;
1251273d9f13SBarry Smith   MatScalar    *aa;
1252273d9f13SBarry Smith   int          ncols,brow,krow,kcol;
1253273d9f13SBarry Smith 
1254273d9f13SBarry Smith   PetscFunctionBegin;
1255273d9f13SBarry Smith   if (A->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1256273d9f13SBarry Smith   bs   = a->bs;
1257273d9f13SBarry Smith   aa   = a->a;
1258273d9f13SBarry Smith   ai   = a->i;
1259273d9f13SBarry Smith   aj   = a->j;
1260273d9f13SBarry Smith   mbs = a->mbs;
1261273d9f13SBarry Smith 
1262273d9f13SBarry Smith   ierr = VecSet(&zero,v);CHKERRQ(ierr);
1263273d9f13SBarry Smith   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
1264273d9f13SBarry Smith   ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr);
1265273d9f13SBarry Smith   if (n != A->m) SETERRQ(PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector");
1266273d9f13SBarry Smith   for (i=0; i<mbs; i++) {
1267273d9f13SBarry Smith     ncols = ai[1] - ai[0]; ai++;
1268273d9f13SBarry Smith     brow  = bs*i;
1269273d9f13SBarry Smith     for (j=0; j<ncols; j++){
1270273d9f13SBarry Smith       /* bcol = bs*(*aj); */
1271273d9f13SBarry Smith       for (kcol=0; kcol<bs; kcol++){
1272273d9f13SBarry Smith         for (krow=0; krow<bs; krow++){
1273273d9f13SBarry Smith           atmp = PetscAbsScalar(*aa); aa++;
1274273d9f13SBarry Smith           row = brow + krow;    /* row index */
1275273d9f13SBarry Smith           /* printf("val[%d,%d]: %g\n",row,bcol+kcol,atmp); */
1276273d9f13SBarry Smith           if (PetscAbsScalar(x[row]) < atmp) x[row] = atmp;
1277273d9f13SBarry Smith         }
1278273d9f13SBarry Smith       }
1279273d9f13SBarry Smith       aj++;
1280273d9f13SBarry Smith     }
1281273d9f13SBarry Smith   }
1282273d9f13SBarry Smith   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
1283273d9f13SBarry Smith   PetscFunctionReturn(0);
1284273d9f13SBarry Smith }
1285273d9f13SBarry Smith 
12864a2ae208SSatish Balay #undef __FUNCT__
12874a2ae208SSatish Balay #define __FUNCT__ "MatSetUpPreallocation_SeqBAIJ"
1288273d9f13SBarry Smith int MatSetUpPreallocation_SeqBAIJ(Mat A)
1289273d9f13SBarry Smith {
1290273d9f13SBarry Smith   int        ierr;
1291273d9f13SBarry Smith 
1292273d9f13SBarry Smith   PetscFunctionBegin;
1293273d9f13SBarry Smith   ierr =  MatSeqBAIJSetPreallocation(A,1,PETSC_DEFAULT,0);CHKERRQ(ierr);
1294273d9f13SBarry Smith   PetscFunctionReturn(0);
1295273d9f13SBarry Smith }
1296273d9f13SBarry Smith 
12974a2ae208SSatish Balay #undef __FUNCT__
12984a2ae208SSatish Balay #define __FUNCT__ "MatGetArray_SeqBAIJ"
1299f2a5309cSSatish Balay int MatGetArray_SeqBAIJ(Mat A,Scalar **array)
1300f2a5309cSSatish Balay {
1301f2a5309cSSatish Balay   Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)A->data;
1302f2a5309cSSatish Balay   PetscFunctionBegin;
1303f2a5309cSSatish Balay   *array = a->a;
1304f2a5309cSSatish Balay   PetscFunctionReturn(0);
1305f2a5309cSSatish Balay }
1306f2a5309cSSatish Balay 
13074a2ae208SSatish Balay #undef __FUNCT__
13084a2ae208SSatish Balay #define __FUNCT__ "MatRestoreArray_SeqBAIJ"
1309f2a5309cSSatish Balay int MatRestoreArray_SeqBAIJ(Mat A,Scalar **array)
1310f2a5309cSSatish Balay {
1311f2a5309cSSatish Balay   PetscFunctionBegin;
1312f2a5309cSSatish Balay   PetscFunctionReturn(0);
1313f2a5309cSSatish Balay }
1314f2a5309cSSatish Balay 
13152593348eSBarry Smith /* -------------------------------------------------------------------*/
1316cc2dc46cSBarry Smith static struct _MatOps MatOps_Values = {MatSetValues_SeqBAIJ,
1317cc2dc46cSBarry Smith        MatGetRow_SeqBAIJ,
1318cc2dc46cSBarry Smith        MatRestoreRow_SeqBAIJ,
1319cc2dc46cSBarry Smith        MatMult_SeqBAIJ_N,
1320cc2dc46cSBarry Smith        MatMultAdd_SeqBAIJ_N,
13217c922b88SBarry Smith        MatMultTranspose_SeqBAIJ,
13227c922b88SBarry Smith        MatMultTransposeAdd_SeqBAIJ,
1323cc2dc46cSBarry Smith        MatSolve_SeqBAIJ_N,
1324cc2dc46cSBarry Smith        0,
1325cc2dc46cSBarry Smith        0,
1326cc2dc46cSBarry Smith        0,
1327cc2dc46cSBarry Smith        MatLUFactor_SeqBAIJ,
1328cc2dc46cSBarry Smith        0,
1329b6490206SBarry Smith        0,
1330f2501298SSatish Balay        MatTranspose_SeqBAIJ,
1331cc2dc46cSBarry Smith        MatGetInfo_SeqBAIJ,
1332cc2dc46cSBarry Smith        MatEqual_SeqBAIJ,
1333cc2dc46cSBarry Smith        MatGetDiagonal_SeqBAIJ,
1334cc2dc46cSBarry Smith        MatDiagonalScale_SeqBAIJ,
1335cc2dc46cSBarry Smith        MatNorm_SeqBAIJ,
1336b6490206SBarry Smith        0,
1337cc2dc46cSBarry Smith        MatAssemblyEnd_SeqBAIJ,
1338cc2dc46cSBarry Smith        0,
1339cc2dc46cSBarry Smith        MatSetOption_SeqBAIJ,
1340cc2dc46cSBarry Smith        MatZeroEntries_SeqBAIJ,
1341cc2dc46cSBarry Smith        MatZeroRows_SeqBAIJ,
1342cc2dc46cSBarry Smith        MatLUFactorSymbolic_SeqBAIJ,
1343cc2dc46cSBarry Smith        MatLUFactorNumeric_SeqBAIJ_N,
1344cc2dc46cSBarry Smith        0,
1345cc2dc46cSBarry Smith        0,
1346273d9f13SBarry Smith        MatSetUpPreallocation_SeqBAIJ,
1347273d9f13SBarry Smith        0,
1348cc2dc46cSBarry Smith        MatGetOwnershipRange_SeqBAIJ,
1349cc2dc46cSBarry Smith        MatILUFactorSymbolic_SeqBAIJ,
1350cc2dc46cSBarry Smith        0,
1351f2a5309cSSatish Balay        MatGetArray_SeqBAIJ,
1352f2a5309cSSatish Balay        MatRestoreArray_SeqBAIJ,
13532e8a6d31SBarry Smith        MatDuplicate_SeqBAIJ,
1354cc2dc46cSBarry Smith        0,
1355cc2dc46cSBarry Smith        0,
1356cc2dc46cSBarry Smith        MatILUFactor_SeqBAIJ,
1357cc2dc46cSBarry Smith        0,
1358cc2dc46cSBarry Smith        0,
1359cc2dc46cSBarry Smith        MatGetSubMatrices_SeqBAIJ,
1360cc2dc46cSBarry Smith        MatIncreaseOverlap_SeqBAIJ,
1361cc2dc46cSBarry Smith        MatGetValues_SeqBAIJ,
1362cc2dc46cSBarry Smith        0,
1363cc2dc46cSBarry Smith        MatPrintHelp_SeqBAIJ,
1364cc2dc46cSBarry Smith        MatScale_SeqBAIJ,
1365cc2dc46cSBarry Smith        0,
1366cc2dc46cSBarry Smith        0,
1367cc2dc46cSBarry Smith        0,
1368cc2dc46cSBarry Smith        MatGetBlockSize_SeqBAIJ,
13693b2fbd54SBarry Smith        MatGetRowIJ_SeqBAIJ,
137092c4ed94SBarry Smith        MatRestoreRowIJ_SeqBAIJ,
1371cc2dc46cSBarry Smith        0,
1372cc2dc46cSBarry Smith        0,
1373cc2dc46cSBarry Smith        0,
1374cc2dc46cSBarry Smith        0,
1375cc2dc46cSBarry Smith        0,
1376cc2dc46cSBarry Smith        0,
1377d3825aa8SBarry Smith        MatSetValuesBlocked_SeqBAIJ,
1378cc2dc46cSBarry Smith        MatGetSubMatrix_SeqBAIJ,
1379b9b97703SBarry Smith        MatDestroy_SeqBAIJ,
1380b9b97703SBarry Smith        MatView_SeqBAIJ,
1381273d9f13SBarry Smith        MatGetMaps_Petsc,
1382273d9f13SBarry Smith        0,
1383273d9f13SBarry Smith        0,
1384273d9f13SBarry Smith        0,
1385273d9f13SBarry Smith        0,
1386273d9f13SBarry Smith        0,
1387273d9f13SBarry Smith        0,
1388273d9f13SBarry Smith        MatGetRowMax_SeqBAIJ,
1389273d9f13SBarry Smith        MatConvert_Basic};
13902593348eSBarry Smith 
13913e90b805SBarry Smith EXTERN_C_BEGIN
13924a2ae208SSatish Balay #undef __FUNCT__
13934a2ae208SSatish Balay #define __FUNCT__ "MatStoreValues_SeqBAIJ"
13943e90b805SBarry Smith int MatStoreValues_SeqBAIJ(Mat mat)
13953e90b805SBarry Smith {
13963e90b805SBarry Smith   Mat_SeqBAIJ *aij = (Mat_SeqBAIJ *)mat->data;
1397273d9f13SBarry Smith   int         nz = aij->i[mat->m]*aij->bs*aij->bs2;
1398d132466eSBarry Smith   int         ierr;
13993e90b805SBarry Smith 
14003e90b805SBarry Smith   PetscFunctionBegin;
14013e90b805SBarry Smith   if (aij->nonew != 1) {
140229bbc08cSBarry Smith     SETERRQ(1,"Must call MatSetOption(A,MAT_NO_NEW_NONZERO_LOCATIONS);first");
14033e90b805SBarry Smith   }
14043e90b805SBarry Smith 
14053e90b805SBarry Smith   /* allocate space for values if not already there */
14063e90b805SBarry Smith   if (!aij->saved_values) {
1407f2a5309cSSatish Balay     ierr = PetscMalloc((nz+1)*sizeof(Scalar),&aij->saved_values);CHKERRQ(ierr);
14083e90b805SBarry Smith   }
14093e90b805SBarry Smith 
14103e90b805SBarry Smith   /* copy values over */
1411d132466eSBarry Smith   ierr = PetscMemcpy(aij->saved_values,aij->a,nz*sizeof(Scalar));CHKERRQ(ierr);
14123e90b805SBarry Smith   PetscFunctionReturn(0);
14133e90b805SBarry Smith }
14143e90b805SBarry Smith EXTERN_C_END
14153e90b805SBarry Smith 
14163e90b805SBarry Smith EXTERN_C_BEGIN
14174a2ae208SSatish Balay #undef __FUNCT__
14184a2ae208SSatish Balay #define __FUNCT__ "MatRetrieveValues_SeqBAIJ"
141932e87ba3SBarry Smith int MatRetrieveValues_SeqBAIJ(Mat mat)
14203e90b805SBarry Smith {
14213e90b805SBarry Smith   Mat_SeqBAIJ *aij = (Mat_SeqBAIJ *)mat->data;
1422273d9f13SBarry Smith   int         nz = aij->i[mat->m]*aij->bs*aij->bs2,ierr;
14233e90b805SBarry Smith 
14243e90b805SBarry Smith   PetscFunctionBegin;
14253e90b805SBarry Smith   if (aij->nonew != 1) {
142629bbc08cSBarry Smith     SETERRQ(1,"Must call MatSetOption(A,MAT_NO_NEW_NONZERO_LOCATIONS);first");
14273e90b805SBarry Smith   }
14283e90b805SBarry Smith   if (!aij->saved_values) {
142929bbc08cSBarry Smith     SETERRQ(1,"Must call MatStoreValues(A);first");
14303e90b805SBarry Smith   }
14313e90b805SBarry Smith 
14323e90b805SBarry Smith   /* copy values over */
1433549d3d68SSatish Balay   ierr = PetscMemcpy(aij->a,aij->saved_values,nz*sizeof(Scalar));CHKERRQ(ierr);
14343e90b805SBarry Smith   PetscFunctionReturn(0);
14353e90b805SBarry Smith }
14363e90b805SBarry Smith EXTERN_C_END
14373e90b805SBarry Smith 
1438273d9f13SBarry Smith EXTERN_C_BEGIN
1439273d9f13SBarry Smith extern int MatConvert_SeqBAIJ_SeqAIJ(Mat,MatType,Mat*);
1440273d9f13SBarry Smith EXTERN_C_END
1441273d9f13SBarry Smith 
1442273d9f13SBarry Smith EXTERN_C_BEGIN
14434a2ae208SSatish Balay #undef __FUNCT__
14444a2ae208SSatish Balay #define __FUNCT__ "MatCreate_SeqBAIJ"
1445273d9f13SBarry Smith int MatCreate_SeqBAIJ(Mat B)
14462593348eSBarry Smith {
1447273d9f13SBarry Smith   int         ierr,size;
1448b6490206SBarry Smith   Mat_SeqBAIJ *b;
14493b2fbd54SBarry Smith 
14503a40ed3dSBarry Smith   PetscFunctionBegin;
1451273d9f13SBarry Smith   ierr = MPI_Comm_size(B->comm,&size);CHKERRQ(ierr);
145229bbc08cSBarry Smith   if (size > 1) SETERRQ(PETSC_ERR_ARG_WRONG,"Comm must be of size 1");
1453b6490206SBarry Smith 
1454273d9f13SBarry Smith   B->m = B->M = PetscMax(B->m,B->M);
1455273d9f13SBarry Smith   B->n = B->N = PetscMax(B->n,B->N);
1456b0a32e0cSBarry Smith   ierr    = PetscNew(Mat_SeqBAIJ,&b);CHKERRQ(ierr);
1457b0a32e0cSBarry Smith   B->data = (void*)b;
1458549d3d68SSatish Balay   ierr    = PetscMemzero(b,sizeof(Mat_SeqBAIJ));CHKERRQ(ierr);
1459549d3d68SSatish Balay   ierr    = PetscMemcpy(B->ops,&MatOps_Values,sizeof(struct _MatOps));CHKERRQ(ierr);
14602593348eSBarry Smith   B->factor           = 0;
14612593348eSBarry Smith   B->lupivotthreshold = 1.0;
146290f02eecSBarry Smith   B->mapping          = 0;
14632593348eSBarry Smith   b->row              = 0;
14642593348eSBarry Smith   b->col              = 0;
1465e51c0b9cSSatish Balay   b->icol             = 0;
14662593348eSBarry Smith   b->reallocs         = 0;
14673e90b805SBarry Smith   b->saved_values     = 0;
1468cfce73b9SSatish Balay #if defined(PETSC_USE_MAT_SINGLE)
1469563b5814SBarry Smith   b->setvalueslen     = 0;
1470563b5814SBarry Smith   b->setvaluescopy    = PETSC_NULL;
1471563b5814SBarry Smith #endif
14728661488fSKris Buschelman   b->single_precision_solves = PETSC_FALSE;
14732593348eSBarry Smith 
1474273d9f13SBarry Smith   ierr = MapCreateMPI(B->comm,B->m,B->m,&B->rmap);CHKERRQ(ierr);
1475273d9f13SBarry Smith   ierr = MapCreateMPI(B->comm,B->n,B->n,&B->cmap);CHKERRQ(ierr);
1476a5ae1ecdSBarry Smith 
1477c4992f7dSBarry Smith   b->sorted           = PETSC_FALSE;
1478c4992f7dSBarry Smith   b->roworiented      = PETSC_TRUE;
14792593348eSBarry Smith   b->nonew            = 0;
14802593348eSBarry Smith   b->diag             = 0;
14812593348eSBarry Smith   b->solve_work       = 0;
1482de6a44a3SBarry Smith   b->mult_work        = 0;
14832593348eSBarry Smith   b->spptr            = 0;
14840e6d2581SBarry Smith   B->info.nz_unneeded = (PetscReal)b->maxnz;
1485883fce79SBarry Smith   b->keepzeroedrows   = PETSC_FALSE;
14864e220ebcSLois Curfman McInnes 
1487f1af5d2fSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatStoreValues_C",
14883e90b805SBarry Smith                                      "MatStoreValues_SeqBAIJ",
1489bc4b532fSSatish Balay                                       MatStoreValues_SeqBAIJ);CHKERRQ(ierr);
1490f1af5d2fSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatRetrieveValues_C",
14913e90b805SBarry Smith                                      "MatRetrieveValues_SeqBAIJ",
1492bc4b532fSSatish Balay                                       MatRetrieveValues_SeqBAIJ);CHKERRQ(ierr);
1493f1af5d2fSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatSeqBAIJSetColumnIndices_C",
149427a8da17SBarry Smith                                      "MatSeqBAIJSetColumnIndices_SeqBAIJ",
1495bc4b532fSSatish Balay                                       MatSeqBAIJSetColumnIndices_SeqBAIJ);CHKERRQ(ierr);
1496273d9f13SBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatConvert_SeqBAIJ_SeqAIJ_C",
1497273d9f13SBarry Smith                                      "MatConvert_SeqBAIJ_SeqAIJ",
1498273d9f13SBarry Smith                                       MatConvert_SeqBAIJ_SeqAIJ);CHKERRQ(ierr);
14993a40ed3dSBarry Smith   PetscFunctionReturn(0);
15002593348eSBarry Smith }
1501273d9f13SBarry Smith EXTERN_C_END
15022593348eSBarry Smith 
15034a2ae208SSatish Balay #undef __FUNCT__
15044a2ae208SSatish Balay #define __FUNCT__ "MatDuplicate_SeqBAIJ"
15052e8a6d31SBarry Smith int MatDuplicate_SeqBAIJ(Mat A,MatDuplicateOption cpvalues,Mat *B)
15062593348eSBarry Smith {
15072593348eSBarry Smith   Mat         C;
1508b6490206SBarry Smith   Mat_SeqBAIJ *c,*a = (Mat_SeqBAIJ*)A->data;
150927a8da17SBarry Smith   int         i,len,mbs = a->mbs,nz = a->nz,bs2 =a->bs2,ierr;
1510de6a44a3SBarry Smith 
15113a40ed3dSBarry Smith   PetscFunctionBegin;
151229bbc08cSBarry Smith   if (a->i[mbs] != nz) SETERRQ(PETSC_ERR_PLIB,"Corrupt matrix");
15132593348eSBarry Smith 
15142593348eSBarry Smith   *B = 0;
1515273d9f13SBarry Smith   ierr = MatCreate(A->comm,A->m,A->n,A->m,A->n,&C);CHKERRQ(ierr);
1516273d9f13SBarry Smith   ierr = MatSetType(C,MATSEQBAIJ);CHKERRQ(ierr);
1517273d9f13SBarry Smith   c    = (Mat_SeqBAIJ*)C->data;
151844cd7ae7SLois Curfman McInnes 
1519b6490206SBarry Smith   c->bs         = a->bs;
15209df24120SSatish Balay   c->bs2        = a->bs2;
1521b6490206SBarry Smith   c->mbs        = a->mbs;
1522b6490206SBarry Smith   c->nbs        = a->nbs;
152335d8aa7fSBarry Smith   ierr = PetscMemcpy(C->ops,A->ops,sizeof(struct _MatOps));CHKERRQ(ierr);
15242593348eSBarry Smith 
1525b0a32e0cSBarry Smith   ierr = PetscMalloc((mbs+1)*sizeof(int),&c->imax);CHKERRQ(ierr);
1526b0a32e0cSBarry Smith   ierr = PetscMalloc((mbs+1)*sizeof(int),&c->ilen);CHKERRQ(ierr);
1527b6490206SBarry Smith   for (i=0; i<mbs; i++) {
15282593348eSBarry Smith     c->imax[i] = a->imax[i];
15292593348eSBarry Smith     c->ilen[i] = a->ilen[i];
15302593348eSBarry Smith   }
15312593348eSBarry Smith 
15322593348eSBarry Smith   /* allocate the matrix space */
1533c4992f7dSBarry Smith   c->singlemalloc = PETSC_TRUE;
15343f1db9ecSBarry Smith   len  = (mbs+1)*sizeof(int) + nz*(bs2*sizeof(MatScalar) + sizeof(int));
1535b0a32e0cSBarry Smith   ierr = PetscMalloc(len,&c->a);CHKERRQ(ierr);
15367e67e3f9SSatish Balay   c->j = (int*)(c->a + nz*bs2);
1537de6a44a3SBarry Smith   c->i = c->j + nz;
1538549d3d68SSatish Balay   ierr = PetscMemcpy(c->i,a->i,(mbs+1)*sizeof(int));CHKERRQ(ierr);
1539b6490206SBarry Smith   if (mbs > 0) {
1540549d3d68SSatish Balay     ierr = PetscMemcpy(c->j,a->j,nz*sizeof(int));CHKERRQ(ierr);
15412e8a6d31SBarry Smith     if (cpvalues == MAT_COPY_VALUES) {
1542549d3d68SSatish Balay       ierr = PetscMemcpy(c->a,a->a,bs2*nz*sizeof(MatScalar));CHKERRQ(ierr);
15432e8a6d31SBarry Smith     } else {
1544549d3d68SSatish Balay       ierr = PetscMemzero(c->a,bs2*nz*sizeof(MatScalar));CHKERRQ(ierr);
15452593348eSBarry Smith     }
15462593348eSBarry Smith   }
15472593348eSBarry Smith 
1548b0a32e0cSBarry Smith   PetscLogObjectMemory(C,len+2*(mbs+1)*sizeof(int)+sizeof(struct _p_Mat)+sizeof(Mat_SeqBAIJ));
15492593348eSBarry Smith   c->sorted      = a->sorted;
15502593348eSBarry Smith   c->roworiented = a->roworiented;
15512593348eSBarry Smith   c->nonew       = a->nonew;
15522593348eSBarry Smith 
15532593348eSBarry Smith   if (a->diag) {
1554b0a32e0cSBarry Smith     ierr = PetscMalloc((mbs+1)*sizeof(int),&c->diag);CHKERRQ(ierr);
1555b0a32e0cSBarry Smith     PetscLogObjectMemory(C,(mbs+1)*sizeof(int));
1556b6490206SBarry Smith     for (i=0; i<mbs; i++) {
15572593348eSBarry Smith       c->diag[i] = a->diag[i];
15582593348eSBarry Smith     }
155998305bb5SBarry Smith   } else c->diag        = 0;
15602593348eSBarry Smith   c->nz                 = a->nz;
15612593348eSBarry Smith   c->maxnz              = a->maxnz;
15622593348eSBarry Smith   c->solve_work         = 0;
15632593348eSBarry Smith   c->spptr              = 0;      /* Dangerous -I'm throwing away a->spptr */
15647fc0212eSBarry Smith   c->mult_work          = 0;
1565273d9f13SBarry Smith   C->preallocated       = PETSC_TRUE;
1566273d9f13SBarry Smith   C->assembled          = PETSC_TRUE;
15672593348eSBarry Smith   *B = C;
1568b0a32e0cSBarry Smith   ierr = PetscFListDuplicate(A->qlist,&C->qlist);CHKERRQ(ierr);
15693a40ed3dSBarry Smith   PetscFunctionReturn(0);
15702593348eSBarry Smith }
15712593348eSBarry Smith 
1572273d9f13SBarry Smith EXTERN_C_BEGIN
15734a2ae208SSatish Balay #undef __FUNCT__
15744a2ae208SSatish Balay #define __FUNCT__ "MatLoad_SeqBAIJ"
1575b0a32e0cSBarry Smith int MatLoad_SeqBAIJ(PetscViewer viewer,MatType type,Mat *A)
15762593348eSBarry Smith {
1577b6490206SBarry Smith   Mat_SeqBAIJ  *a;
15782593348eSBarry Smith   Mat          B;
1579f1af5d2fSBarry Smith   int          i,nz,ierr,fd,header[4],size,*rowlengths=0,M,N,bs=1;
1580b6490206SBarry Smith   int          *mask,mbs,*jj,j,rowcount,nzcount,k,*browlengths,maskcount;
158135aab85fSBarry Smith   int          kmax,jcount,block,idx,point,nzcountb,extra_rows;
1582a7c10996SSatish Balay   int          *masked,nmask,tmp,bs2,ishift;
1583b6490206SBarry Smith   Scalar       *aa;
158419bcc07fSBarry Smith   MPI_Comm     comm = ((PetscObject)viewer)->comm;
15852593348eSBarry Smith 
15863a40ed3dSBarry Smith   PetscFunctionBegin;
1587b0a32e0cSBarry Smith   ierr = PetscOptionsGetInt(PETSC_NULL,"-matload_block_size",&bs,PETSC_NULL);CHKERRQ(ierr);
1588de6a44a3SBarry Smith   bs2  = bs*bs;
1589b6490206SBarry Smith 
1590d132466eSBarry Smith   ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr);
159129bbc08cSBarry Smith   if (size > 1) SETERRQ(PETSC_ERR_ARG_WRONG,"view must have one processor");
1592b0a32e0cSBarry Smith   ierr = PetscViewerBinaryGetDescriptor(viewer,&fd);CHKERRQ(ierr);
15930752156aSBarry Smith   ierr = PetscBinaryRead(fd,header,4,PETSC_INT);CHKERRQ(ierr);
159429bbc08cSBarry Smith   if (header[0] != MAT_COOKIE) SETERRQ(PETSC_ERR_FILE_UNEXPECTED,"not Mat object");
15952593348eSBarry Smith   M = header[1]; N = header[2]; nz = header[3];
15962593348eSBarry Smith 
1597d64ed03dSBarry Smith   if (header[3] < 0) {
159829bbc08cSBarry Smith     SETERRQ(PETSC_ERR_FILE_UNEXPECTED,"Matrix stored in special format, cannot load as SeqBAIJ");
1599d64ed03dSBarry Smith   }
1600d64ed03dSBarry Smith 
160129bbc08cSBarry Smith   if (M != N) SETERRQ(PETSC_ERR_SUP,"Can only do square matrices");
160235aab85fSBarry Smith 
160335aab85fSBarry Smith   /*
160435aab85fSBarry Smith      This code adds extra rows to make sure the number of rows is
160535aab85fSBarry Smith     divisible by the blocksize
160635aab85fSBarry Smith   */
1607b6490206SBarry Smith   mbs        = M/bs;
160835aab85fSBarry Smith   extra_rows = bs - M + bs*(mbs);
160935aab85fSBarry Smith   if (extra_rows == bs) extra_rows = 0;
161035aab85fSBarry Smith   else                  mbs++;
161135aab85fSBarry Smith   if (extra_rows) {
1612b0a32e0cSBarry Smith     PetscLogInfo(0,"MatLoad_SeqBAIJ:Padding loaded matrix to match blocksize\n");
161335aab85fSBarry Smith   }
1614b6490206SBarry Smith 
16152593348eSBarry Smith   /* read in row lengths */
1616b0a32e0cSBarry Smith   ierr = PetscMalloc((M+extra_rows)*sizeof(int),&rowlengths);CHKERRQ(ierr);
16170752156aSBarry Smith   ierr = PetscBinaryRead(fd,rowlengths,M,PETSC_INT);CHKERRQ(ierr);
161835aab85fSBarry Smith   for (i=0; i<extra_rows; i++) rowlengths[M+i] = 1;
16192593348eSBarry Smith 
1620b6490206SBarry Smith   /* read in column indices */
1621b0a32e0cSBarry Smith   ierr = PetscMalloc((nz+extra_rows)*sizeof(int),&jj);CHKERRQ(ierr);
16220752156aSBarry Smith   ierr = PetscBinaryRead(fd,jj,nz,PETSC_INT);CHKERRQ(ierr);
162335aab85fSBarry Smith   for (i=0; i<extra_rows; i++) jj[nz+i] = M+i;
1624b6490206SBarry Smith 
1625b6490206SBarry Smith   /* loop over row lengths determining block row lengths */
1626b0a32e0cSBarry Smith   ierr     = PetscMalloc(mbs*sizeof(int),&browlengths);CHKERRQ(ierr);
1627549d3d68SSatish Balay   ierr     = PetscMemzero(browlengths,mbs*sizeof(int));CHKERRQ(ierr);
1628b0a32e0cSBarry Smith   ierr     = PetscMalloc(2*mbs*sizeof(int),&mask);CHKERRQ(ierr);
1629549d3d68SSatish Balay   ierr     = PetscMemzero(mask,mbs*sizeof(int));CHKERRQ(ierr);
163035aab85fSBarry Smith   masked   = mask + mbs;
1631b6490206SBarry Smith   rowcount = 0; nzcount = 0;
1632b6490206SBarry Smith   for (i=0; i<mbs; i++) {
163335aab85fSBarry Smith     nmask = 0;
1634b6490206SBarry Smith     for (j=0; j<bs; j++) {
1635b6490206SBarry Smith       kmax = rowlengths[rowcount];
1636b6490206SBarry Smith       for (k=0; k<kmax; k++) {
163735aab85fSBarry Smith         tmp = jj[nzcount++]/bs;
163835aab85fSBarry Smith         if (!mask[tmp]) {masked[nmask++] = tmp; mask[tmp] = 1;}
1639b6490206SBarry Smith       }
1640b6490206SBarry Smith       rowcount++;
1641b6490206SBarry Smith     }
164235aab85fSBarry Smith     browlengths[i] += nmask;
164335aab85fSBarry Smith     /* zero out the mask elements we set */
164435aab85fSBarry Smith     for (j=0; j<nmask; j++) mask[masked[j]] = 0;
1645b6490206SBarry Smith   }
1646b6490206SBarry Smith 
16472593348eSBarry Smith   /* create our matrix */
16483eee16b0SBarry Smith   ierr = MatCreateSeqBAIJ(comm,bs,M+extra_rows,N+extra_rows,0,browlengths,A);CHKERRQ(ierr);
16492593348eSBarry Smith   B = *A;
1650b6490206SBarry Smith   a = (Mat_SeqBAIJ*)B->data;
16512593348eSBarry Smith 
16522593348eSBarry Smith   /* set matrix "i" values */
1653de6a44a3SBarry Smith   a->i[0] = 0;
1654b6490206SBarry Smith   for (i=1; i<= mbs; i++) {
1655b6490206SBarry Smith     a->i[i]      = a->i[i-1] + browlengths[i-1];
1656b6490206SBarry Smith     a->ilen[i-1] = browlengths[i-1];
16572593348eSBarry Smith   }
1658b6490206SBarry Smith   a->nz         = 0;
1659b6490206SBarry Smith   for (i=0; i<mbs; i++) a->nz += browlengths[i];
16602593348eSBarry Smith 
1661b6490206SBarry Smith   /* read in nonzero values */
1662b0a32e0cSBarry Smith   ierr = PetscMalloc((nz+extra_rows)*sizeof(Scalar),&aa);CHKERRQ(ierr);
16630752156aSBarry Smith   ierr = PetscBinaryRead(fd,aa,nz,PETSC_SCALAR);CHKERRQ(ierr);
166435aab85fSBarry Smith   for (i=0; i<extra_rows; i++) aa[nz+i] = 1.0;
1665b6490206SBarry Smith 
1666b6490206SBarry Smith   /* set "a" and "j" values into matrix */
1667b6490206SBarry Smith   nzcount = 0; jcount = 0;
1668b6490206SBarry Smith   for (i=0; i<mbs; i++) {
1669b6490206SBarry Smith     nzcountb = nzcount;
167035aab85fSBarry Smith     nmask    = 0;
1671b6490206SBarry Smith     for (j=0; j<bs; j++) {
1672b6490206SBarry Smith       kmax = rowlengths[i*bs+j];
1673b6490206SBarry Smith       for (k=0; k<kmax; k++) {
167435aab85fSBarry Smith         tmp = jj[nzcount++]/bs;
167535aab85fSBarry Smith 	if (!mask[tmp]) { masked[nmask++] = tmp; mask[tmp] = 1;}
1676b6490206SBarry Smith       }
1677b6490206SBarry Smith     }
1678de6a44a3SBarry Smith     /* sort the masked values */
1679433994e6SBarry Smith     ierr = PetscSortInt(nmask,masked);CHKERRQ(ierr);
1680de6a44a3SBarry Smith 
1681b6490206SBarry Smith     /* set "j" values into matrix */
1682b6490206SBarry Smith     maskcount = 1;
168335aab85fSBarry Smith     for (j=0; j<nmask; j++) {
168435aab85fSBarry Smith       a->j[jcount++]  = masked[j];
1685de6a44a3SBarry Smith       mask[masked[j]] = maskcount++;
1686b6490206SBarry Smith     }
1687b6490206SBarry Smith     /* set "a" values into matrix */
1688de6a44a3SBarry Smith     ishift = bs2*a->i[i];
1689b6490206SBarry Smith     for (j=0; j<bs; j++) {
1690b6490206SBarry Smith       kmax = rowlengths[i*bs+j];
1691b6490206SBarry Smith       for (k=0; k<kmax; k++) {
1692de6a44a3SBarry Smith         tmp       = jj[nzcountb]/bs ;
1693de6a44a3SBarry Smith         block     = mask[tmp] - 1;
1694de6a44a3SBarry Smith         point     = jj[nzcountb] - bs*tmp;
1695de6a44a3SBarry Smith         idx       = ishift + bs2*block + j + bs*point;
1696375fe846SBarry Smith         a->a[idx] = (MatScalar)aa[nzcountb++];
1697b6490206SBarry Smith       }
1698b6490206SBarry Smith     }
169935aab85fSBarry Smith     /* zero out the mask elements we set */
170035aab85fSBarry Smith     for (j=0; j<nmask; j++) mask[masked[j]] = 0;
1701b6490206SBarry Smith   }
170229bbc08cSBarry Smith   if (jcount != a->nz) SETERRQ(PETSC_ERR_FILE_UNEXPECTED,"Bad binary matrix");
1703b6490206SBarry Smith 
1704606d414cSSatish Balay   ierr = PetscFree(rowlengths);CHKERRQ(ierr);
1705606d414cSSatish Balay   ierr = PetscFree(browlengths);CHKERRQ(ierr);
1706606d414cSSatish Balay   ierr = PetscFree(aa);CHKERRQ(ierr);
1707606d414cSSatish Balay   ierr = PetscFree(jj);CHKERRQ(ierr);
1708606d414cSSatish Balay   ierr = PetscFree(mask);CHKERRQ(ierr);
1709b6490206SBarry Smith 
1710b6490206SBarry Smith   B->assembled = PETSC_TRUE;
1711de6a44a3SBarry Smith 
17129c01be13SBarry Smith   ierr = MatView_Private(B);CHKERRQ(ierr);
17133a40ed3dSBarry Smith   PetscFunctionReturn(0);
17142593348eSBarry Smith }
1715273d9f13SBarry Smith EXTERN_C_END
17162593348eSBarry Smith 
17174a2ae208SSatish Balay #undef __FUNCT__
17184a2ae208SSatish Balay #define __FUNCT__ "MatCreateSeqBAIJ"
1719273d9f13SBarry Smith /*@C
1720273d9f13SBarry Smith    MatCreateSeqBAIJ - Creates a sparse matrix in block AIJ (block
1721273d9f13SBarry Smith    compressed row) format.  For good matrix assembly performance the
1722273d9f13SBarry Smith    user should preallocate the matrix storage by setting the parameter nz
1723273d9f13SBarry Smith    (or the array nnz).  By setting these parameters accurately, performance
1724273d9f13SBarry Smith    during matrix assembly can be increased by more than a factor of 50.
17252593348eSBarry Smith 
1726273d9f13SBarry Smith    Collective on MPI_Comm
1727273d9f13SBarry Smith 
1728273d9f13SBarry Smith    Input Parameters:
1729273d9f13SBarry Smith +  comm - MPI communicator, set to PETSC_COMM_SELF
1730273d9f13SBarry Smith .  bs - size of block
1731273d9f13SBarry Smith .  m - number of rows
1732273d9f13SBarry Smith .  n - number of columns
173335d8aa7fSBarry Smith .  nz - number of nonzero blocks  per block row (same for all rows)
173435d8aa7fSBarry Smith -  nnz - array containing the number of nonzero blocks in the various block rows
1735273d9f13SBarry Smith          (possibly different for each block row) or PETSC_NULL
1736273d9f13SBarry Smith 
1737273d9f13SBarry Smith    Output Parameter:
1738273d9f13SBarry Smith .  A - the matrix
1739273d9f13SBarry Smith 
1740273d9f13SBarry Smith    Options Database Keys:
1741273d9f13SBarry Smith .   -mat_no_unroll - uses code that does not unroll the loops in the
1742273d9f13SBarry Smith                      block calculations (much slower)
1743273d9f13SBarry Smith .    -mat_block_size - size of the blocks to use
1744273d9f13SBarry Smith 
1745273d9f13SBarry Smith    Level: intermediate
1746273d9f13SBarry Smith 
1747273d9f13SBarry Smith    Notes:
174835d8aa7fSBarry Smith    A nonzero block is any block that as 1 or more nonzeros in it
174935d8aa7fSBarry Smith 
1750273d9f13SBarry Smith    The block AIJ format is fully compatible with standard Fortran 77
1751273d9f13SBarry Smith    storage.  That is, the stored row and column indices can begin at
1752273d9f13SBarry Smith    either one (as in Fortran) or zero.  See the users' manual for details.
1753273d9f13SBarry Smith 
1754273d9f13SBarry Smith    Specify the preallocated storage with either nz or nnz (not both).
1755273d9f13SBarry Smith    Set nz=PETSC_DEFAULT and nnz=PETSC_NULL for PETSc to control dynamic memory
1756273d9f13SBarry Smith    allocation.  For additional details, see the users manual chapter on
1757273d9f13SBarry Smith    matrices.
1758273d9f13SBarry Smith 
1759273d9f13SBarry Smith .seealso: MatCreate(), MatCreateSeqAIJ(), MatSetValues(), MatCreateMPIBAIJ()
1760273d9f13SBarry Smith @*/
1761273d9f13SBarry Smith int MatCreateSeqBAIJ(MPI_Comm comm,int bs,int m,int n,int nz,int *nnz,Mat *A)
1762273d9f13SBarry Smith {
1763273d9f13SBarry Smith   int ierr;
1764273d9f13SBarry Smith 
1765273d9f13SBarry Smith   PetscFunctionBegin;
1766273d9f13SBarry Smith   ierr = MatCreate(comm,m,n,m,n,A);CHKERRQ(ierr);
1767273d9f13SBarry Smith   ierr = MatSetType(*A,MATSEQBAIJ);CHKERRQ(ierr);
1768273d9f13SBarry Smith   ierr = MatSeqBAIJSetPreallocation(*A,bs,nz,nnz);CHKERRQ(ierr);
1769273d9f13SBarry Smith   PetscFunctionReturn(0);
1770273d9f13SBarry Smith }
1771273d9f13SBarry Smith 
17724a2ae208SSatish Balay #undef __FUNCT__
17734a2ae208SSatish Balay #define __FUNCT__ "MatSeqBAIJSetPreallocation"
1774273d9f13SBarry Smith /*@C
1775273d9f13SBarry Smith    MatSeqBAIJSetPreallocation - Sets the block size and expected nonzeros
1776273d9f13SBarry Smith    per row in the matrix. For good matrix assembly performance the
1777273d9f13SBarry Smith    user should preallocate the matrix storage by setting the parameter nz
1778273d9f13SBarry Smith    (or the array nnz).  By setting these parameters accurately, performance
1779273d9f13SBarry Smith    during matrix assembly can be increased by more than a factor of 50.
1780273d9f13SBarry Smith 
1781273d9f13SBarry Smith    Collective on MPI_Comm
1782273d9f13SBarry Smith 
1783273d9f13SBarry Smith    Input Parameters:
1784273d9f13SBarry Smith +  A - the matrix
1785273d9f13SBarry Smith .  bs - size of block
1786273d9f13SBarry Smith .  nz - number of block nonzeros per block row (same for all rows)
1787273d9f13SBarry Smith -  nnz - array containing the number of block nonzeros in the various block rows
1788273d9f13SBarry Smith          (possibly different for each block row) or PETSC_NULL
1789273d9f13SBarry Smith 
1790273d9f13SBarry Smith    Options Database Keys:
1791273d9f13SBarry Smith .   -mat_no_unroll - uses code that does not unroll the loops in the
1792273d9f13SBarry Smith                      block calculations (much slower)
1793273d9f13SBarry Smith .    -mat_block_size - size of the blocks to use
1794273d9f13SBarry Smith 
1795273d9f13SBarry Smith    Level: intermediate
1796273d9f13SBarry Smith 
1797273d9f13SBarry Smith    Notes:
1798273d9f13SBarry Smith    The block AIJ format is fully compatible with standard Fortran 77
1799273d9f13SBarry Smith    storage.  That is, the stored row and column indices can begin at
1800273d9f13SBarry Smith    either one (as in Fortran) or zero.  See the users' manual for details.
1801273d9f13SBarry Smith 
1802273d9f13SBarry Smith    Specify the preallocated storage with either nz or nnz (not both).
1803273d9f13SBarry Smith    Set nz=PETSC_DEFAULT and nnz=PETSC_NULL for PETSc to control dynamic memory
1804273d9f13SBarry Smith    allocation.  For additional details, see the users manual chapter on
1805273d9f13SBarry Smith    matrices.
1806273d9f13SBarry Smith 
1807273d9f13SBarry Smith .seealso: MatCreate(), MatCreateSeqAIJ(), MatSetValues(), MatCreateMPIBAIJ()
1808273d9f13SBarry Smith @*/
1809273d9f13SBarry Smith int MatSeqBAIJSetPreallocation(Mat B,int bs,int nz,int *nnz)
1810273d9f13SBarry Smith {
1811273d9f13SBarry Smith   Mat_SeqBAIJ *b;
1812273d9f13SBarry Smith   int         i,len,ierr,mbs,nbs,bs2,newbs = bs;
1813273d9f13SBarry Smith   PetscTruth  flg;
1814273d9f13SBarry Smith 
1815273d9f13SBarry Smith   PetscFunctionBegin;
1816273d9f13SBarry Smith   ierr = PetscTypeCompare((PetscObject)B,MATSEQBAIJ,&flg);CHKERRQ(ierr);
1817273d9f13SBarry Smith   if (!flg) PetscFunctionReturn(0);
1818273d9f13SBarry Smith 
1819273d9f13SBarry Smith   B->preallocated = PETSC_TRUE;
1820b0a32e0cSBarry Smith   ierr = PetscOptionsGetInt(B->prefix,"-mat_block_size",&newbs,PETSC_NULL);CHKERRQ(ierr);
1821273d9f13SBarry Smith   if (nnz && newbs != bs) {
1822273d9f13SBarry Smith     SETERRQ(1,"Cannot change blocksize from command line if setting nnz");
1823273d9f13SBarry Smith   }
1824273d9f13SBarry Smith   bs   = newbs;
1825273d9f13SBarry Smith 
1826273d9f13SBarry Smith   mbs  = B->m/bs;
1827273d9f13SBarry Smith   nbs  = B->n/bs;
1828273d9f13SBarry Smith   bs2  = bs*bs;
1829273d9f13SBarry Smith 
1830273d9f13SBarry Smith   if (mbs*bs!=B->m || nbs*bs!=B->n) {
183135d8aa7fSBarry Smith     SETERRQ3(PETSC_ERR_ARG_SIZ,"Number rows %d, cols %d must be divisible by blocksize %d",B->m,B->n,bs);
1832273d9f13SBarry Smith   }
1833273d9f13SBarry Smith 
1834435da068SBarry Smith   if (nz == PETSC_DEFAULT || nz == PETSC_DECIDE) nz = 5;
1835435da068SBarry Smith   if (nz < 0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"nz cannot be less than 0: value %d",nz);
1836273d9f13SBarry Smith   if (nnz) {
1837273d9f13SBarry Smith     for (i=0; i<mbs; i++) {
1838273d9f13SBarry Smith       if (nnz[i] < 0) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"nnz cannot be less than 0: local row %d value %d",i,nnz[i]);
18393a7fca6bSBarry 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);
1840273d9f13SBarry Smith     }
1841273d9f13SBarry Smith   }
1842273d9f13SBarry Smith 
1843273d9f13SBarry Smith   b       = (Mat_SeqBAIJ*)B->data;
1844b0a32e0cSBarry Smith   ierr    = PetscOptionsHasName(PETSC_NULL,"-mat_no_unroll",&flg);CHKERRQ(ierr);
184554138f6bSKris Buschelman   B->ops->solve               = MatSolve_SeqBAIJ_Update;
184654138f6bSKris Buschelman   B->ops->solvetranspose      = MatSolveTranspose_SeqBAIJ_Update;
1847273d9f13SBarry Smith   if (!flg) {
1848273d9f13SBarry Smith     switch (bs) {
1849273d9f13SBarry Smith     case 1:
1850273d9f13SBarry Smith       B->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_1;
1851273d9f13SBarry Smith       B->ops->mult            = MatMult_SeqBAIJ_1;
1852273d9f13SBarry Smith       B->ops->multadd         = MatMultAdd_SeqBAIJ_1;
1853273d9f13SBarry Smith       break;
1854273d9f13SBarry Smith     case 2:
1855273d9f13SBarry Smith       B->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_2;
1856273d9f13SBarry Smith       B->ops->mult            = MatMult_SeqBAIJ_2;
1857273d9f13SBarry Smith       B->ops->multadd         = MatMultAdd_SeqBAIJ_2;
1858273d9f13SBarry Smith       break;
1859273d9f13SBarry Smith     case 3:
1860273d9f13SBarry Smith       B->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_3;
1861273d9f13SBarry Smith       B->ops->mult            = MatMult_SeqBAIJ_3;
1862273d9f13SBarry Smith       B->ops->multadd         = MatMultAdd_SeqBAIJ_3;
1863273d9f13SBarry Smith       break;
1864273d9f13SBarry Smith     case 4:
1865273d9f13SBarry Smith       B->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_4;
1866273d9f13SBarry Smith       B->ops->mult            = MatMult_SeqBAIJ_4;
1867273d9f13SBarry Smith       B->ops->multadd         = MatMultAdd_SeqBAIJ_4;
1868273d9f13SBarry Smith       break;
1869273d9f13SBarry Smith     case 5:
1870273d9f13SBarry Smith       B->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_5;
1871273d9f13SBarry Smith       B->ops->mult            = MatMult_SeqBAIJ_5;
1872273d9f13SBarry Smith       B->ops->multadd         = MatMultAdd_SeqBAIJ_5;
1873273d9f13SBarry Smith       break;
1874273d9f13SBarry Smith     case 6:
1875273d9f13SBarry Smith       B->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_6;
1876273d9f13SBarry Smith       B->ops->mult            = MatMult_SeqBAIJ_6;
1877273d9f13SBarry Smith       B->ops->multadd         = MatMultAdd_SeqBAIJ_6;
1878273d9f13SBarry Smith       break;
1879273d9f13SBarry Smith     case 7:
188054138f6bSKris Buschelman       B->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_7;
1881273d9f13SBarry Smith       B->ops->mult            = MatMult_SeqBAIJ_7;
1882273d9f13SBarry Smith       B->ops->multadd         = MatMultAdd_SeqBAIJ_7;
1883273d9f13SBarry Smith       break;
1884273d9f13SBarry Smith     default:
188554138f6bSKris Buschelman       B->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_N;
1886273d9f13SBarry Smith       B->ops->mult            = MatMult_SeqBAIJ_N;
1887273d9f13SBarry Smith       B->ops->multadd         = MatMultAdd_SeqBAIJ_N;
1888273d9f13SBarry Smith       break;
1889273d9f13SBarry Smith     }
1890273d9f13SBarry Smith   }
1891273d9f13SBarry Smith   b->bs      = bs;
1892273d9f13SBarry Smith   b->mbs     = mbs;
1893273d9f13SBarry Smith   b->nbs     = nbs;
1894b0a32e0cSBarry Smith   ierr = PetscMalloc((mbs+1)*sizeof(int),&b->imax);CHKERRQ(ierr);
1895273d9f13SBarry Smith   if (!nnz) {
1896435da068SBarry Smith     if (nz == PETSC_DEFAULT || nz == PETSC_DECIDE) nz = 5;
1897273d9f13SBarry Smith     else if (nz <= 0)        nz = 1;
1898273d9f13SBarry Smith     for (i=0; i<mbs; i++) b->imax[i] = nz;
1899273d9f13SBarry Smith     nz = nz*mbs;
1900273d9f13SBarry Smith   } else {
1901273d9f13SBarry Smith     nz = 0;
1902273d9f13SBarry Smith     for (i=0; i<mbs; i++) {b->imax[i] = nnz[i]; nz += nnz[i];}
1903273d9f13SBarry Smith   }
1904273d9f13SBarry Smith 
1905273d9f13SBarry Smith   /* allocate the matrix space */
1906273d9f13SBarry Smith   len   = nz*sizeof(int) + nz*bs2*sizeof(MatScalar) + (B->m+1)*sizeof(int);
1907b0a32e0cSBarry Smith   ierr  = PetscMalloc(len,&b->a);CHKERRQ(ierr);
1908273d9f13SBarry Smith   ierr  = PetscMemzero(b->a,nz*bs2*sizeof(MatScalar));CHKERRQ(ierr);
1909273d9f13SBarry Smith   b->j  = (int*)(b->a + nz*bs2);
1910273d9f13SBarry Smith   ierr = PetscMemzero(b->j,nz*sizeof(int));CHKERRQ(ierr);
1911273d9f13SBarry Smith   b->i  = b->j + nz;
1912273d9f13SBarry Smith   b->singlemalloc = PETSC_TRUE;
1913273d9f13SBarry Smith 
1914273d9f13SBarry Smith   b->i[0] = 0;
1915273d9f13SBarry Smith   for (i=1; i<mbs+1; i++) {
1916273d9f13SBarry Smith     b->i[i] = b->i[i-1] + b->imax[i-1];
1917273d9f13SBarry Smith   }
1918273d9f13SBarry Smith 
1919273d9f13SBarry Smith   /* b->ilen will count nonzeros in each block row so far. */
192016d6aa21SSatish Balay   ierr = PetscMalloc((mbs+1)*sizeof(int),&b->ilen);CHKERRQ(ierr);
1921b0a32e0cSBarry Smith   PetscLogObjectMemory(B,len+2*(mbs+1)*sizeof(int)+sizeof(struct _p_Mat)+sizeof(Mat_SeqBAIJ));
1922273d9f13SBarry Smith   for (i=0; i<mbs; i++) { b->ilen[i] = 0;}
1923273d9f13SBarry Smith 
1924273d9f13SBarry Smith   b->bs               = bs;
1925273d9f13SBarry Smith   b->bs2              = bs2;
1926273d9f13SBarry Smith   b->mbs              = mbs;
1927273d9f13SBarry Smith   b->nz               = 0;
1928273d9f13SBarry Smith   b->maxnz            = nz*bs2;
1929273d9f13SBarry Smith   B->info.nz_unneeded = (PetscReal)b->maxnz;
1930273d9f13SBarry Smith   PetscFunctionReturn(0);
1931273d9f13SBarry Smith }
19322593348eSBarry Smith 
1933