xref: /petsc/src/mat/impls/baij/seq/baij.c (revision 4f1ab113834a080a3aec87dd5ed4279d2c883c90)
1*4f1ab113SKris Buschelman /*$Id: baij.c,v 1.230 2001/06/22 19:05:58 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
1495d5f7c2SBarry Smith    not exist. Otherwise ..._MatScalar() takes matrix elements 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 defined(PETSC_USE_MAT_SINGLE)
216bd648c37SKris Buschelman     if (a->bs==4) {
217bd648c37SKris Buschelman       PetscTruth sse_enabled;
218bd648c37SKris Buschelman       int ierr;
219bd648c37SKris Buschelman       ierr = PetscSSEIsEnabled(&sse_enabled);CHKERRQ(ierr);
220bd648c37SKris Buschelman       if (sse_enabled) {
221*4f1ab113SKris Buschelman         a->singleprecisionsolves = PETSC_TRUE;
222bd648c37SKris Buschelman       } else {
223bd648c37SKris Buschelman         PetscLogInfo(A,"MatSetOption_SeqBAIJ:Option MAT_USE_SINGLE_PRECISION_SOLVES ignored\n");
224bd648c37SKris Buschelman       }
225bd648c37SKris Buschelman     } else {
226bd648c37SKris Buschelman       PetscLogInfo(A,"MatSetOption_SeqBAIJ:Option MAT_USE_SINGLE_PRECISION_SOLVES ignored\n");
227bd648c37SKris Buschelman     }
228bd648c37SKris Buschelman #else
229bd648c37SKris Buschelman     PetscLogInfo(A,"MatSetOption_SeqBAIJ:Option MAT_USE_SINGLE_PRECISION_SOLVES ignored\n");
230bd648c37SKris Buschelman #endif
231bd648c37SKris Buschelman     break;
232aa275fccSKris Buschelman   default:
23329bbc08cSBarry Smith     SETERRQ(PETSC_ERR_SUP,"unknown option");
2342d61bbb3SSatish Balay   }
2352d61bbb3SSatish Balay   PetscFunctionReturn(0);
2362d61bbb3SSatish Balay }
2372d61bbb3SSatish Balay 
2384a2ae208SSatish Balay #undef __FUNCT__
2394a2ae208SSatish Balay #define __FUNCT__ "MatGetOwnershipRange_SeqBAIJ"
2402d61bbb3SSatish Balay int MatGetOwnershipRange_SeqBAIJ(Mat A,int *m,int *n)
2412d61bbb3SSatish Balay {
2422d61bbb3SSatish Balay   PetscFunctionBegin;
2434c49b128SBarry Smith   if (m) *m = 0;
244273d9f13SBarry Smith   if (n) *n = A->m;
2452d61bbb3SSatish Balay   PetscFunctionReturn(0);
2462d61bbb3SSatish Balay }
2472d61bbb3SSatish Balay 
2484a2ae208SSatish Balay #undef __FUNCT__
2494a2ae208SSatish Balay #define __FUNCT__ "MatGetRow_SeqBAIJ"
2502d61bbb3SSatish Balay int MatGetRow_SeqBAIJ(Mat A,int row,int *nz,int **idx,Scalar **v)
2512d61bbb3SSatish Balay {
2522d61bbb3SSatish Balay   Mat_SeqBAIJ  *a = (Mat_SeqBAIJ*)A->data;
25382502324SSatish Balay   int          itmp,i,j,k,M,*ai,*aj,bs,bn,bp,*idx_i,bs2,ierr;
2543f1db9ecSBarry Smith   MatScalar    *aa,*aa_i;
2553f1db9ecSBarry Smith   Scalar       *v_i;
2562d61bbb3SSatish Balay 
2572d61bbb3SSatish Balay   PetscFunctionBegin;
2582d61bbb3SSatish Balay   bs  = a->bs;
2592d61bbb3SSatish Balay   ai  = a->i;
2602d61bbb3SSatish Balay   aj  = a->j;
2612d61bbb3SSatish Balay   aa  = a->a;
2622d61bbb3SSatish Balay   bs2 = a->bs2;
2632d61bbb3SSatish Balay 
264273d9f13SBarry Smith   if (row < 0 || row >= A->m) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Row out of range");
2652d61bbb3SSatish Balay 
2662d61bbb3SSatish Balay   bn  = row/bs;   /* Block number */
2672d61bbb3SSatish Balay   bp  = row % bs; /* Block Position */
2682d61bbb3SSatish Balay   M   = ai[bn+1] - ai[bn];
2692d61bbb3SSatish Balay   *nz = bs*M;
2702d61bbb3SSatish Balay 
2712d61bbb3SSatish Balay   if (v) {
2722d61bbb3SSatish Balay     *v = 0;
2732d61bbb3SSatish Balay     if (*nz) {
274b0a32e0cSBarry Smith       ierr = PetscMalloc((*nz)*sizeof(Scalar),v);CHKERRQ(ierr);
2752d61bbb3SSatish Balay       for (i=0; i<M; i++) { /* for each block in the block row */
2762d61bbb3SSatish Balay         v_i  = *v + i*bs;
2772d61bbb3SSatish Balay         aa_i = aa + bs2*(ai[bn] + i);
2782d61bbb3SSatish Balay         for (j=bp,k=0; j<bs2; j+=bs,k++) {v_i[k] = aa_i[j];}
2792d61bbb3SSatish Balay       }
2802d61bbb3SSatish Balay     }
2812d61bbb3SSatish Balay   }
2822d61bbb3SSatish Balay 
2832d61bbb3SSatish Balay   if (idx) {
2842d61bbb3SSatish Balay     *idx = 0;
2852d61bbb3SSatish Balay     if (*nz) {
286b0a32e0cSBarry Smith       ierr = PetscMalloc((*nz)*sizeof(int),idx);CHKERRQ(ierr);
2872d61bbb3SSatish Balay       for (i=0; i<M; i++) { /* for each block in the block row */
2882d61bbb3SSatish Balay         idx_i = *idx + i*bs;
2892d61bbb3SSatish Balay         itmp  = bs*aj[ai[bn] + i];
2902d61bbb3SSatish Balay         for (j=0; j<bs; j++) {idx_i[j] = itmp++;}
2912d61bbb3SSatish Balay       }
2922d61bbb3SSatish Balay     }
2932d61bbb3SSatish Balay   }
2942d61bbb3SSatish Balay   PetscFunctionReturn(0);
2952d61bbb3SSatish Balay }
2962d61bbb3SSatish Balay 
2974a2ae208SSatish Balay #undef __FUNCT__
2984a2ae208SSatish Balay #define __FUNCT__ "MatRestoreRow_SeqBAIJ"
2992d61bbb3SSatish Balay int MatRestoreRow_SeqBAIJ(Mat A,int row,int *nz,int **idx,Scalar **v)
3002d61bbb3SSatish Balay {
301606d414cSSatish Balay   int ierr;
302606d414cSSatish Balay 
3032d61bbb3SSatish Balay   PetscFunctionBegin;
304606d414cSSatish Balay   if (idx) {if (*idx) {ierr = PetscFree(*idx);CHKERRQ(ierr);}}
305606d414cSSatish Balay   if (v)   {if (*v)   {ierr = PetscFree(*v);CHKERRQ(ierr);}}
3062d61bbb3SSatish Balay   PetscFunctionReturn(0);
3072d61bbb3SSatish Balay }
3082d61bbb3SSatish Balay 
3094a2ae208SSatish Balay #undef __FUNCT__
3104a2ae208SSatish Balay #define __FUNCT__ "MatTranspose_SeqBAIJ"
3112d61bbb3SSatish Balay int MatTranspose_SeqBAIJ(Mat A,Mat *B)
3122d61bbb3SSatish Balay {
3132d61bbb3SSatish Balay   Mat_SeqBAIJ *a=(Mat_SeqBAIJ *)A->data;
3142d61bbb3SSatish Balay   Mat         C;
3152d61bbb3SSatish Balay   int         i,j,k,ierr,*aj=a->j,*ai=a->i,bs=a->bs,mbs=a->mbs,nbs=a->nbs,len,*col;
316273d9f13SBarry Smith   int         *rows,*cols,bs2=a->bs2;
317375fe846SBarry Smith   Scalar      *array;
3182d61bbb3SSatish Balay 
3192d61bbb3SSatish Balay   PetscFunctionBegin;
32029bbc08cSBarry Smith   if (!B && mbs!=nbs) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Square matrix only for in-place");
321b0a32e0cSBarry Smith   ierr = PetscMalloc((1+nbs)*sizeof(int),&col);CHKERRQ(ierr);
322549d3d68SSatish Balay   ierr = PetscMemzero(col,(1+nbs)*sizeof(int));CHKERRQ(ierr);
3232d61bbb3SSatish Balay 
324375fe846SBarry Smith #if defined(PETSC_USE_MAT_SINGLE)
325b0a32e0cSBarry Smith   ierr = PetscMalloc(a->bs2*a->nz*sizeof(Scalar),&array);CHKERRQ(ierr);
326375fe846SBarry Smith   for (i=0; i<a->bs2*a->nz; i++) array[i] = (Scalar)a->a[i];
327375fe846SBarry Smith #else
3283eda8832SBarry Smith   array = a->a;
329375fe846SBarry Smith #endif
330375fe846SBarry Smith 
3312d61bbb3SSatish Balay   for (i=0; i<ai[mbs]; i++) col[aj[i]] += 1;
332273d9f13SBarry Smith   ierr = MatCreateSeqBAIJ(A->comm,bs,A->n,A->m,PETSC_NULL,col,&C);CHKERRQ(ierr);
333606d414cSSatish Balay   ierr = PetscFree(col);CHKERRQ(ierr);
334b0a32e0cSBarry Smith   ierr = PetscMalloc(2*bs*sizeof(int),&rows);CHKERRQ(ierr);
3352d61bbb3SSatish Balay   cols = rows + bs;
3362d61bbb3SSatish Balay   for (i=0; i<mbs; i++) {
3372d61bbb3SSatish Balay     cols[0] = i*bs;
3382d61bbb3SSatish Balay     for (k=1; k<bs; k++) cols[k] = cols[k-1] + 1;
3392d61bbb3SSatish Balay     len = ai[i+1] - ai[i];
3402d61bbb3SSatish Balay     for (j=0; j<len; j++) {
3412d61bbb3SSatish Balay       rows[0] = (*aj++)*bs;
3422d61bbb3SSatish Balay       for (k=1; k<bs; k++) rows[k] = rows[k-1] + 1;
3432d61bbb3SSatish Balay       ierr = MatSetValues(C,bs,rows,bs,cols,array,INSERT_VALUES);CHKERRQ(ierr);
3442d61bbb3SSatish Balay       array += bs2;
3452d61bbb3SSatish Balay     }
3462d61bbb3SSatish Balay   }
347606d414cSSatish Balay   ierr = PetscFree(rows);CHKERRQ(ierr);
348375fe846SBarry Smith #if defined(PETSC_USE_MAT_SINGLE)
349375fe846SBarry Smith   ierr = PetscFree(array);
350375fe846SBarry Smith #endif
3512d61bbb3SSatish Balay 
3522d61bbb3SSatish Balay   ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
3532d61bbb3SSatish Balay   ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
3542d61bbb3SSatish Balay 
355c4992f7dSBarry Smith   if (B) {
3562d61bbb3SSatish Balay     *B = C;
3572d61bbb3SSatish Balay   } else {
358273d9f13SBarry Smith     ierr = MatHeaderCopy(A,C);CHKERRQ(ierr);
3592d61bbb3SSatish Balay   }
3602d61bbb3SSatish Balay   PetscFunctionReturn(0);
3612d61bbb3SSatish Balay }
3622d61bbb3SSatish Balay 
3634a2ae208SSatish Balay #undef __FUNCT__
3644a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqBAIJ_Binary"
365b0a32e0cSBarry Smith static int MatView_SeqBAIJ_Binary(Mat A,PetscViewer viewer)
3662593348eSBarry Smith {
367b6490206SBarry Smith   Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)A->data;
3689df24120SSatish Balay   int         i,fd,*col_lens,ierr,bs = a->bs,count,*jj,j,k,l,bs2=a->bs2;
369b6490206SBarry Smith   Scalar      *aa;
370ce6f0cecSBarry Smith   FILE        *file;
3712593348eSBarry Smith 
3723a40ed3dSBarry Smith   PetscFunctionBegin;
373b0a32e0cSBarry Smith   ierr        = PetscViewerBinaryGetDescriptor(viewer,&fd);CHKERRQ(ierr);
374b0a32e0cSBarry Smith   ierr        = PetscMalloc((4+A->m)*sizeof(int),&col_lens);CHKERRQ(ierr);
3752593348eSBarry Smith   col_lens[0] = MAT_COOKIE;
3763b2fbd54SBarry Smith 
377273d9f13SBarry Smith   col_lens[1] = A->m;
378273d9f13SBarry Smith   col_lens[2] = A->n;
3797e67e3f9SSatish Balay   col_lens[3] = a->nz*bs2;
3802593348eSBarry Smith 
3812593348eSBarry Smith   /* store lengths of each row and write (including header) to file */
382b6490206SBarry Smith   count = 0;
383b6490206SBarry Smith   for (i=0; i<a->mbs; i++) {
384b6490206SBarry Smith     for (j=0; j<bs; j++) {
385b6490206SBarry Smith       col_lens[4+count++] = bs*(a->i[i+1] - a->i[i]);
386b6490206SBarry Smith     }
3872593348eSBarry Smith   }
388273d9f13SBarry Smith   ierr = PetscBinaryWrite(fd,col_lens,4+A->m,PETSC_INT,1);CHKERRQ(ierr);
389606d414cSSatish Balay   ierr = PetscFree(col_lens);CHKERRQ(ierr);
3902593348eSBarry Smith 
3912593348eSBarry Smith   /* store column indices (zero start index) */
392b0a32e0cSBarry Smith   ierr  = PetscMalloc((a->nz+1)*bs2*sizeof(int),&jj);CHKERRQ(ierr);
393b6490206SBarry Smith   count = 0;
394b6490206SBarry Smith   for (i=0; i<a->mbs; i++) {
395b6490206SBarry Smith     for (j=0; j<bs; j++) {
396b6490206SBarry Smith       for (k=a->i[i]; k<a->i[i+1]; k++) {
397b6490206SBarry Smith         for (l=0; l<bs; l++) {
398b6490206SBarry Smith           jj[count++] = bs*a->j[k] + l;
3992593348eSBarry Smith         }
4002593348eSBarry Smith       }
401b6490206SBarry Smith     }
402b6490206SBarry Smith   }
4030752156aSBarry Smith   ierr = PetscBinaryWrite(fd,jj,bs2*a->nz,PETSC_INT,0);CHKERRQ(ierr);
404606d414cSSatish Balay   ierr = PetscFree(jj);CHKERRQ(ierr);
4052593348eSBarry Smith 
4062593348eSBarry Smith   /* store nonzero values */
407b0a32e0cSBarry Smith   ierr  = PetscMalloc((a->nz+1)*bs2*sizeof(Scalar),&aa);CHKERRQ(ierr);
408b6490206SBarry Smith   count = 0;
409b6490206SBarry Smith   for (i=0; i<a->mbs; i++) {
410b6490206SBarry Smith     for (j=0; j<bs; j++) {
411b6490206SBarry Smith       for (k=a->i[i]; k<a->i[i+1]; k++) {
412b6490206SBarry Smith         for (l=0; l<bs; l++) {
4137e67e3f9SSatish Balay           aa[count++] = a->a[bs2*k + l*bs + j];
414b6490206SBarry Smith         }
415b6490206SBarry Smith       }
416b6490206SBarry Smith     }
417b6490206SBarry Smith   }
4180752156aSBarry Smith   ierr = PetscBinaryWrite(fd,aa,bs2*a->nz,PETSC_SCALAR,0);CHKERRQ(ierr);
419606d414cSSatish Balay   ierr = PetscFree(aa);CHKERRQ(ierr);
420ce6f0cecSBarry Smith 
421b0a32e0cSBarry Smith   ierr = PetscViewerBinaryGetInfoPointer(viewer,&file);CHKERRQ(ierr);
422ce6f0cecSBarry Smith   if (file) {
423ce6f0cecSBarry Smith     fprintf(file,"-matload_block_size %d\n",a->bs);
424ce6f0cecSBarry Smith   }
4253a40ed3dSBarry Smith   PetscFunctionReturn(0);
4262593348eSBarry Smith }
4272593348eSBarry Smith 
4284a2ae208SSatish Balay #undef __FUNCT__
4294a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqBAIJ_ASCII"
430b0a32e0cSBarry Smith static int MatView_SeqBAIJ_ASCII(Mat A,PetscViewer viewer)
4312593348eSBarry Smith {
432b6490206SBarry Smith   Mat_SeqBAIJ       *a = (Mat_SeqBAIJ*)A->data;
433fb9695e5SSatish Balay   int               ierr,i,j,bs = a->bs,k,l,bs2=a->bs2;
434f3ef73ceSBarry Smith   PetscViewerFormat format;
4352593348eSBarry Smith 
4363a40ed3dSBarry Smith   PetscFunctionBegin;
437b0a32e0cSBarry Smith   ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr);
438fb9695e5SSatish Balay   if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_LONG) {
439b0a32e0cSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  block size is %d\n",bs);CHKERRQ(ierr);
440fb9695e5SSatish Balay   } else if (format == PETSC_VIEWER_ASCII_MATLAB) {
44129bbc08cSBarry Smith     SETERRQ(PETSC_ERR_SUP,"Matlab format not supported");
442fb9695e5SSatish Balay   } else if (format == PETSC_VIEWER_ASCII_COMMON) {
443b0a32e0cSBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_NO);CHKERRQ(ierr);
44444cd7ae7SLois Curfman McInnes     for (i=0; i<a->mbs; i++) {
44544cd7ae7SLois Curfman McInnes       for (j=0; j<bs; j++) {
446b0a32e0cSBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"row %d:",i*bs+j);CHKERRQ(ierr);
44744cd7ae7SLois Curfman McInnes         for (k=a->i[i]; k<a->i[i+1]; k++) {
44844cd7ae7SLois Curfman McInnes           for (l=0; l<bs; l++) {
449aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
4500e6d2581SBarry Smith             if (PetscImaginaryPart(a->a[bs2*k + l*bs + j]) > 0.0 && PetscRealPart(a->a[bs2*k + l*bs + j]) != 0.0) {
451b0a32e0cSBarry Smith               ierr = PetscViewerASCIIPrintf(viewer," %d %g + %gi",bs*a->j[k]+l,
4520e6d2581SBarry Smith                       PetscRealPart(a->a[bs2*k + l*bs + j]),PetscImaginaryPart(a->a[bs2*k + l*bs + j]));CHKERRQ(ierr);
4530e6d2581SBarry Smith             } else if (PetscImaginaryPart(a->a[bs2*k + l*bs + j]) < 0.0 && PetscRealPart(a->a[bs2*k + l*bs + j]) != 0.0) {
454b0a32e0cSBarry Smith               ierr = PetscViewerASCIIPrintf(viewer," %d %g - %gi",bs*a->j[k]+l,
4550e6d2581SBarry Smith                       PetscRealPart(a->a[bs2*k + l*bs + j]),-PetscImaginaryPart(a->a[bs2*k + l*bs + j]));CHKERRQ(ierr);
4560e6d2581SBarry Smith             } else if (PetscRealPart(a->a[bs2*k + l*bs + j]) != 0.0) {
457b0a32e0cSBarry Smith               ierr = PetscViewerASCIIPrintf(viewer," %d %g ",bs*a->j[k]+l,PetscRealPart(a->a[bs2*k + l*bs + j]));CHKERRQ(ierr);
4580ef38995SBarry Smith             }
45944cd7ae7SLois Curfman McInnes #else
4600ef38995SBarry Smith             if (a->a[bs2*k + l*bs + j] != 0.0) {
461b0a32e0cSBarry Smith               ierr = PetscViewerASCIIPrintf(viewer," %d %g ",bs*a->j[k]+l,a->a[bs2*k + l*bs + j]);CHKERRQ(ierr);
4620ef38995SBarry Smith             }
46344cd7ae7SLois Curfman McInnes #endif
46444cd7ae7SLois Curfman McInnes           }
46544cd7ae7SLois Curfman McInnes         }
466b0a32e0cSBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
46744cd7ae7SLois Curfman McInnes       }
46844cd7ae7SLois Curfman McInnes     }
469b0a32e0cSBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_YES);CHKERRQ(ierr);
4700ef38995SBarry Smith   } else {
471b0a32e0cSBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_NO);CHKERRQ(ierr);
472b6490206SBarry Smith     for (i=0; i<a->mbs; i++) {
473b6490206SBarry Smith       for (j=0; j<bs; j++) {
474b0a32e0cSBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"row %d:",i*bs+j);CHKERRQ(ierr);
475b6490206SBarry Smith         for (k=a->i[i]; k<a->i[i+1]; k++) {
476b6490206SBarry Smith           for (l=0; l<bs; l++) {
477aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
4780e6d2581SBarry Smith             if (PetscImaginaryPart(a->a[bs2*k + l*bs + j]) > 0.0) {
479b0a32e0cSBarry Smith               ierr = PetscViewerASCIIPrintf(viewer," %d %g + %g i",bs*a->j[k]+l,
4800e6d2581SBarry Smith                 PetscRealPart(a->a[bs2*k + l*bs + j]),PetscImaginaryPart(a->a[bs2*k + l*bs + j]));CHKERRQ(ierr);
4810e6d2581SBarry Smith             } else if (PetscImaginaryPart(a->a[bs2*k + l*bs + j]) < 0.0) {
482b0a32e0cSBarry Smith               ierr = PetscViewerASCIIPrintf(viewer," %d %g - %g i",bs*a->j[k]+l,
4830e6d2581SBarry Smith                 PetscRealPart(a->a[bs2*k + l*bs + j]),-PetscImaginaryPart(a->a[bs2*k + l*bs + j]));CHKERRQ(ierr);
4840ef38995SBarry Smith             } else {
485b0a32e0cSBarry Smith               ierr = PetscViewerASCIIPrintf(viewer," %d %g ",bs*a->j[k]+l,PetscRealPart(a->a[bs2*k + l*bs + j]));CHKERRQ(ierr);
48688685aaeSLois Curfman McInnes             }
48788685aaeSLois Curfman McInnes #else
488b0a32e0cSBarry Smith             ierr = PetscViewerASCIIPrintf(viewer," %d %g ",bs*a->j[k]+l,a->a[bs2*k + l*bs + j]);CHKERRQ(ierr);
48988685aaeSLois Curfman McInnes #endif
4902593348eSBarry Smith           }
4912593348eSBarry Smith         }
492b0a32e0cSBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
4932593348eSBarry Smith       }
4942593348eSBarry Smith     }
495b0a32e0cSBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_YES);CHKERRQ(ierr);
496b6490206SBarry Smith   }
497b0a32e0cSBarry Smith   ierr = PetscViewerFlush(viewer);CHKERRQ(ierr);
4983a40ed3dSBarry Smith   PetscFunctionReturn(0);
4992593348eSBarry Smith }
5002593348eSBarry Smith 
5014a2ae208SSatish Balay #undef __FUNCT__
5024a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqBAIJ_Draw_Zoom"
503b0a32e0cSBarry Smith static int MatView_SeqBAIJ_Draw_Zoom(PetscDraw draw,void *Aa)
5043270192aSSatish Balay {
50577ed5343SBarry Smith   Mat          A = (Mat) Aa;
5063270192aSSatish Balay   Mat_SeqBAIJ  *a=(Mat_SeqBAIJ*)A->data;
507b65db4caSBarry Smith   int          row,ierr,i,j,k,l,mbs=a->mbs,color,bs=a->bs,bs2=a->bs2;
5080e6d2581SBarry Smith   PetscReal    xl,yl,xr,yr,x_l,x_r,y_l,y_r;
5093f1db9ecSBarry Smith   MatScalar    *aa;
510b0a32e0cSBarry Smith   PetscViewer  viewer;
5113270192aSSatish Balay 
5123a40ed3dSBarry Smith   PetscFunctionBegin;
5133270192aSSatish Balay 
514b65db4caSBarry Smith   /* still need to add support for contour plot of nonzeros; see MatView_SeqAIJ_Draw_Zoom()*/
51577ed5343SBarry Smith   ierr = PetscObjectQuery((PetscObject)A,"Zoomviewer",(PetscObject*)&viewer);CHKERRQ(ierr);
51677ed5343SBarry Smith 
517b0a32e0cSBarry Smith   ierr = PetscDrawGetCoordinates(draw,&xl,&yl,&xr,&yr);CHKERRQ(ierr);
51877ed5343SBarry Smith 
5193270192aSSatish Balay   /* loop over matrix elements drawing boxes */
520b0a32e0cSBarry Smith   color = PETSC_DRAW_BLUE;
5213270192aSSatish Balay   for (i=0,row=0; i<mbs; i++,row+=bs) {
5223270192aSSatish Balay     for (j=a->i[i]; j<a->i[i+1]; j++) {
523273d9f13SBarry Smith       y_l = A->m - row - 1.0; y_r = y_l + 1.0;
5243270192aSSatish Balay       x_l = a->j[j]*bs; x_r = x_l + 1.0;
5253270192aSSatish Balay       aa = a->a + j*bs2;
5263270192aSSatish Balay       for (k=0; k<bs; k++) {
5273270192aSSatish Balay         for (l=0; l<bs; l++) {
5280e6d2581SBarry Smith           if (PetscRealPart(*aa++) >=  0.) continue;
529b0a32e0cSBarry Smith           ierr = PetscDrawRectangle(draw,x_l+k,y_l-l,x_r+k,y_r-l,color,color,color,color);CHKERRQ(ierr);
5303270192aSSatish Balay         }
5313270192aSSatish Balay       }
5323270192aSSatish Balay     }
5333270192aSSatish Balay   }
534b0a32e0cSBarry Smith   color = PETSC_DRAW_CYAN;
5353270192aSSatish Balay   for (i=0,row=0; i<mbs; i++,row+=bs) {
5363270192aSSatish Balay     for (j=a->i[i]; j<a->i[i+1]; j++) {
537273d9f13SBarry Smith       y_l = A->m - row - 1.0; y_r = y_l + 1.0;
5383270192aSSatish Balay       x_l = a->j[j]*bs; x_r = x_l + 1.0;
5393270192aSSatish Balay       aa = a->a + j*bs2;
5403270192aSSatish Balay       for (k=0; k<bs; k++) {
5413270192aSSatish Balay         for (l=0; l<bs; l++) {
5420e6d2581SBarry Smith           if (PetscRealPart(*aa++) != 0.) continue;
543b0a32e0cSBarry Smith           ierr = PetscDrawRectangle(draw,x_l+k,y_l-l,x_r+k,y_r-l,color,color,color,color);CHKERRQ(ierr);
5443270192aSSatish Balay         }
5453270192aSSatish Balay       }
5463270192aSSatish Balay     }
5473270192aSSatish Balay   }
5483270192aSSatish Balay 
549b0a32e0cSBarry Smith   color = PETSC_DRAW_RED;
5503270192aSSatish Balay   for (i=0,row=0; i<mbs; i++,row+=bs) {
5513270192aSSatish Balay     for (j=a->i[i]; j<a->i[i+1]; j++) {
552273d9f13SBarry Smith       y_l = A->m - row - 1.0; y_r = y_l + 1.0;
5533270192aSSatish Balay       x_l = a->j[j]*bs; x_r = x_l + 1.0;
5543270192aSSatish Balay       aa = a->a + j*bs2;
5553270192aSSatish Balay       for (k=0; k<bs; k++) {
5563270192aSSatish Balay         for (l=0; l<bs; l++) {
5570e6d2581SBarry Smith           if (PetscRealPart(*aa++) <= 0.) continue;
558b0a32e0cSBarry Smith           ierr = PetscDrawRectangle(draw,x_l+k,y_l-l,x_r+k,y_r-l,color,color,color,color);CHKERRQ(ierr);
5593270192aSSatish Balay         }
5603270192aSSatish Balay       }
5613270192aSSatish Balay     }
5623270192aSSatish Balay   }
56377ed5343SBarry Smith   PetscFunctionReturn(0);
56477ed5343SBarry Smith }
5653270192aSSatish Balay 
5664a2ae208SSatish Balay #undef __FUNCT__
5674a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqBAIJ_Draw"
568b0a32e0cSBarry Smith static int MatView_SeqBAIJ_Draw(Mat A,PetscViewer viewer)
56977ed5343SBarry Smith {
5707dce120fSSatish Balay   int          ierr;
5710e6d2581SBarry Smith   PetscReal    xl,yl,xr,yr,w,h;
572b0a32e0cSBarry Smith   PetscDraw    draw;
57377ed5343SBarry Smith   PetscTruth   isnull;
5743270192aSSatish Balay 
57577ed5343SBarry Smith   PetscFunctionBegin;
57677ed5343SBarry Smith 
577b0a32e0cSBarry Smith   ierr = PetscViewerDrawGetDraw(viewer,0,&draw);CHKERRQ(ierr);
578b0a32e0cSBarry Smith   ierr = PetscDrawIsNull(draw,&isnull);CHKERRQ(ierr); if (isnull) PetscFunctionReturn(0);
57977ed5343SBarry Smith 
58077ed5343SBarry Smith   ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",(PetscObject)viewer);CHKERRQ(ierr);
581273d9f13SBarry Smith   xr  = A->n; yr = A->m; h = yr/10.0; w = xr/10.0;
58277ed5343SBarry Smith   xr += w;    yr += h;  xl = -w;     yl = -h;
583b0a32e0cSBarry Smith   ierr = PetscDrawSetCoordinates(draw,xl,yl,xr,yr);CHKERRQ(ierr);
584b0a32e0cSBarry Smith   ierr = PetscDrawZoom(draw,MatView_SeqBAIJ_Draw_Zoom,A);CHKERRQ(ierr);
58577ed5343SBarry Smith   ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",PETSC_NULL);CHKERRQ(ierr);
5863a40ed3dSBarry Smith   PetscFunctionReturn(0);
5873270192aSSatish Balay }
5883270192aSSatish Balay 
5894a2ae208SSatish Balay #undef __FUNCT__
5904a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqBAIJ"
591b0a32e0cSBarry Smith int MatView_SeqBAIJ(Mat A,PetscViewer viewer)
5922593348eSBarry Smith {
59319bcc07fSBarry Smith   int        ierr;
5946831982aSBarry Smith   PetscTruth issocket,isascii,isbinary,isdraw;
5952593348eSBarry Smith 
5963a40ed3dSBarry Smith   PetscFunctionBegin;
597b0a32e0cSBarry Smith   ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_SOCKET,&issocket);CHKERRQ(ierr);
598b0a32e0cSBarry Smith   ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&isascii);CHKERRQ(ierr);
599fb9695e5SSatish Balay   ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_BINARY,&isbinary);CHKERRQ(ierr);
600fb9695e5SSatish Balay   ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_DRAW,&isdraw);CHKERRQ(ierr);
6010f5bd95cSBarry Smith   if (issocket) {
60229bbc08cSBarry Smith     SETERRQ(PETSC_ERR_SUP,"Socket viewer not supported");
6030f5bd95cSBarry Smith   } else if (isascii){
6043a40ed3dSBarry Smith     ierr = MatView_SeqBAIJ_ASCII(A,viewer);CHKERRQ(ierr);
6050f5bd95cSBarry Smith   } else if (isbinary) {
6063a40ed3dSBarry Smith     ierr = MatView_SeqBAIJ_Binary(A,viewer);CHKERRQ(ierr);
6070f5bd95cSBarry Smith   } else if (isdraw) {
6083a40ed3dSBarry Smith     ierr = MatView_SeqBAIJ_Draw(A,viewer);CHKERRQ(ierr);
6095cd90555SBarry Smith   } else {
61029bbc08cSBarry Smith     SETERRQ1(1,"Viewer type %s not supported by SeqBAIJ matrices",((PetscObject)viewer)->type_name);
6112593348eSBarry Smith   }
6123a40ed3dSBarry Smith   PetscFunctionReturn(0);
6132593348eSBarry Smith }
614b6490206SBarry Smith 
615cd0e1443SSatish Balay 
6164a2ae208SSatish Balay #undef __FUNCT__
6174a2ae208SSatish Balay #define __FUNCT__ "MatGetValues_SeqBAIJ"
6182d61bbb3SSatish Balay int MatGetValues_SeqBAIJ(Mat A,int m,int *im,int n,int *in,Scalar *v)
619cd0e1443SSatish Balay {
620cd0e1443SSatish Balay   Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)A->data;
6212d61bbb3SSatish Balay   int        *rp,k,low,high,t,row,nrow,i,col,l,*aj = a->j;
6222d61bbb3SSatish Balay   int        *ai = a->i,*ailen = a->ilen;
6232d61bbb3SSatish Balay   int        brow,bcol,ridx,cidx,bs=a->bs,bs2=a->bs2;
6243f1db9ecSBarry Smith   MatScalar  *ap,*aa = a->a,zero = 0.0;
625cd0e1443SSatish Balay 
6263a40ed3dSBarry Smith   PetscFunctionBegin;
6272d61bbb3SSatish Balay   for (k=0; k<m; k++) { /* loop over rows */
628cd0e1443SSatish Balay     row  = im[k]; brow = row/bs;
62929bbc08cSBarry Smith     if (row < 0) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Negative row");
630273d9f13SBarry Smith     if (row >= A->m) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Row too large");
6312d61bbb3SSatish Balay     rp   = aj + ai[brow] ; ap = aa + bs2*ai[brow] ;
6322c3acbe9SBarry Smith     nrow = ailen[brow];
6332d61bbb3SSatish Balay     for (l=0; l<n; l++) { /* loop over columns */
63429bbc08cSBarry Smith       if (in[l] < 0) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Negative column");
635273d9f13SBarry Smith       if (in[l] >= A->n) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Column too large");
6362d61bbb3SSatish Balay       col  = in[l] ;
6372d61bbb3SSatish Balay       bcol = col/bs;
6382d61bbb3SSatish Balay       cidx = col%bs;
6392d61bbb3SSatish Balay       ridx = row%bs;
6402d61bbb3SSatish Balay       high = nrow;
6412d61bbb3SSatish Balay       low  = 0; /* assume unsorted */
6422d61bbb3SSatish Balay       while (high-low > 5) {
643cd0e1443SSatish Balay         t = (low+high)/2;
644cd0e1443SSatish Balay         if (rp[t] > bcol) high = t;
645cd0e1443SSatish Balay         else             low  = t;
646cd0e1443SSatish Balay       }
647cd0e1443SSatish Balay       for (i=low; i<high; i++) {
648cd0e1443SSatish Balay         if (rp[i] > bcol) break;
649cd0e1443SSatish Balay         if (rp[i] == bcol) {
6502d61bbb3SSatish Balay           *v++ = ap[bs2*i+bs*cidx+ridx];
6512d61bbb3SSatish Balay           goto finished;
652cd0e1443SSatish Balay         }
653cd0e1443SSatish Balay       }
6542d61bbb3SSatish Balay       *v++ = zero;
6552d61bbb3SSatish Balay       finished:;
656cd0e1443SSatish Balay     }
657cd0e1443SSatish Balay   }
6583a40ed3dSBarry Smith   PetscFunctionReturn(0);
659cd0e1443SSatish Balay }
660cd0e1443SSatish Balay 
66195d5f7c2SBarry Smith #if defined(PETSC_USE_MAT_SINGLE)
6624a2ae208SSatish Balay #undef __FUNCT__
6634a2ae208SSatish Balay #define __FUNCT__ "MatSetValuesBlocked_SeqBAIJ"
66495d5f7c2SBarry Smith int MatSetValuesBlocked_SeqBAIJ(Mat mat,int m,int *im,int n,int *in,Scalar *v,InsertMode addv)
66595d5f7c2SBarry Smith {
666563b5814SBarry Smith   Mat_SeqBAIJ *b = (Mat_SeqBAIJ*)mat->data;
667563b5814SBarry Smith   int         ierr,i,N = m*n*b->bs2;
668563b5814SBarry Smith   MatScalar   *vsingle;
66995d5f7c2SBarry Smith 
67095d5f7c2SBarry Smith   PetscFunctionBegin;
671563b5814SBarry Smith   if (N > b->setvalueslen) {
672563b5814SBarry Smith     if (b->setvaluescopy) {ierr = PetscFree(b->setvaluescopy);CHKERRQ(ierr);}
673b0a32e0cSBarry Smith     ierr = PetscMalloc(N*sizeof(MatScalar),&b->setvaluescopy);CHKERRQ(ierr);
674563b5814SBarry Smith     b->setvalueslen  = N;
675563b5814SBarry Smith   }
676563b5814SBarry Smith   vsingle = b->setvaluescopy;
67795d5f7c2SBarry Smith   for (i=0; i<N; i++) {
67895d5f7c2SBarry Smith     vsingle[i] = v[i];
67995d5f7c2SBarry Smith   }
68095d5f7c2SBarry Smith   ierr = MatSetValuesBlocked_SeqBAIJ_MatScalar(mat,m,im,n,in,vsingle,addv);CHKERRQ(ierr);
68195d5f7c2SBarry Smith   PetscFunctionReturn(0);
68295d5f7c2SBarry Smith }
68395d5f7c2SBarry Smith #endif
68495d5f7c2SBarry Smith 
6852d61bbb3SSatish Balay 
6864a2ae208SSatish Balay #undef __FUNCT__
6874a2ae208SSatish Balay #define __FUNCT__ "MatSetValuesBlocked_SeqBAIJ"
68895d5f7c2SBarry Smith int MatSetValuesBlocked_SeqBAIJ_MatScalar(Mat A,int m,int *im,int n,int *in,MatScalar *v,InsertMode is)
68992c4ed94SBarry Smith {
69092c4ed94SBarry Smith   Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)A->data;
6918a84c255SSatish Balay   int         *rp,k,low,high,t,ii,jj,row,nrow,i,col,l,rmax,N,sorted=a->sorted;
692273d9f13SBarry Smith   int         *imax=a->imax,*ai=a->i,*ailen=a->ilen;
693549d3d68SSatish Balay   int         *aj=a->j,nonew=a->nonew,bs2=a->bs2,bs=a->bs,stepval,ierr;
694273d9f13SBarry Smith   PetscTruth  roworiented=a->roworiented;
69595d5f7c2SBarry Smith   MatScalar   *value = v,*ap,*aa = a->a,*bap;
69692c4ed94SBarry Smith 
6973a40ed3dSBarry Smith   PetscFunctionBegin;
6980e324ae4SSatish Balay   if (roworiented) {
6990e324ae4SSatish Balay     stepval = (n-1)*bs;
7000e324ae4SSatish Balay   } else {
7010e324ae4SSatish Balay     stepval = (m-1)*bs;
7020e324ae4SSatish Balay   }
70392c4ed94SBarry Smith   for (k=0; k<m; k++) { /* loop over added rows */
70492c4ed94SBarry Smith     row  = im[k];
7055ef9f2a5SBarry Smith     if (row < 0) continue;
706aa482453SBarry Smith #if defined(PETSC_USE_BOPT_g)
70729bbc08cSBarry Smith     if (row >= a->mbs) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Row too large");
70892c4ed94SBarry Smith #endif
70992c4ed94SBarry Smith     rp   = aj + ai[row];
71092c4ed94SBarry Smith     ap   = aa + bs2*ai[row];
71192c4ed94SBarry Smith     rmax = imax[row];
71292c4ed94SBarry Smith     nrow = ailen[row];
71392c4ed94SBarry Smith     low  = 0;
71492c4ed94SBarry Smith     for (l=0; l<n; l++) { /* loop over added columns */
7155ef9f2a5SBarry Smith       if (in[l] < 0) continue;
716aa482453SBarry Smith #if defined(PETSC_USE_BOPT_g)
71729bbc08cSBarry Smith       if (in[l] >= a->nbs) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Column too large");
71892c4ed94SBarry Smith #endif
71992c4ed94SBarry Smith       col = in[l];
72092c4ed94SBarry Smith       if (roworiented) {
7210e324ae4SSatish Balay         value = v + k*(stepval+bs)*bs + l*bs;
7220e324ae4SSatish Balay       } else {
7230e324ae4SSatish Balay         value = v + l*(stepval+bs)*bs + k*bs;
72492c4ed94SBarry Smith       }
72592c4ed94SBarry Smith       if (!sorted) low = 0; high = nrow;
72692c4ed94SBarry Smith       while (high-low > 7) {
72792c4ed94SBarry Smith         t = (low+high)/2;
72892c4ed94SBarry Smith         if (rp[t] > col) high = t;
72992c4ed94SBarry Smith         else             low  = t;
73092c4ed94SBarry Smith       }
73192c4ed94SBarry Smith       for (i=low; i<high; i++) {
73292c4ed94SBarry Smith         if (rp[i] > col) break;
73392c4ed94SBarry Smith         if (rp[i] == col) {
7348a84c255SSatish Balay           bap  = ap +  bs2*i;
7350e324ae4SSatish Balay           if (roworiented) {
7368a84c255SSatish Balay             if (is == ADD_VALUES) {
737dd9472c6SBarry Smith               for (ii=0; ii<bs; ii++,value+=stepval) {
738dd9472c6SBarry Smith                 for (jj=ii; jj<bs2; jj+=bs) {
7398a84c255SSatish Balay                   bap[jj] += *value++;
740dd9472c6SBarry Smith                 }
741dd9472c6SBarry Smith               }
7420e324ae4SSatish Balay             } else {
743dd9472c6SBarry Smith               for (ii=0; ii<bs; ii++,value+=stepval) {
744dd9472c6SBarry Smith                 for (jj=ii; jj<bs2; jj+=bs) {
7450e324ae4SSatish Balay                   bap[jj] = *value++;
7468a84c255SSatish Balay                 }
747dd9472c6SBarry Smith               }
748dd9472c6SBarry Smith             }
7490e324ae4SSatish Balay           } else {
7500e324ae4SSatish Balay             if (is == ADD_VALUES) {
751dd9472c6SBarry Smith               for (ii=0; ii<bs; ii++,value+=stepval) {
752dd9472c6SBarry Smith                 for (jj=0; jj<bs; jj++) {
7530e324ae4SSatish Balay                   *bap++ += *value++;
754dd9472c6SBarry Smith                 }
755dd9472c6SBarry Smith               }
7560e324ae4SSatish Balay             } else {
757dd9472c6SBarry Smith               for (ii=0; ii<bs; ii++,value+=stepval) {
758dd9472c6SBarry Smith                 for (jj=0; jj<bs; jj++) {
7590e324ae4SSatish Balay                   *bap++  = *value++;
7600e324ae4SSatish Balay                 }
7618a84c255SSatish Balay               }
762dd9472c6SBarry Smith             }
763dd9472c6SBarry Smith           }
764f1241b54SBarry Smith           goto noinsert2;
76592c4ed94SBarry Smith         }
76692c4ed94SBarry Smith       }
76789280ab3SLois Curfman McInnes       if (nonew == 1) goto noinsert2;
76829bbc08cSBarry Smith       else if (nonew == -1) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Inserting a new nonzero in the matrix");
76992c4ed94SBarry Smith       if (nrow >= rmax) {
77092c4ed94SBarry Smith         /* there is no extra room in row, therefore enlarge */
77192c4ed94SBarry Smith         int       new_nz = ai[a->mbs] + CHUNKSIZE,len,*new_i,*new_j;
7723f1db9ecSBarry Smith         MatScalar *new_a;
77392c4ed94SBarry Smith 
77429bbc08cSBarry Smith         if (nonew == -2) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Inserting a new nonzero in the matrix");
77589280ab3SLois Curfman McInnes 
77692c4ed94SBarry Smith         /* malloc new storage space */
7773f1db9ecSBarry Smith         len     = new_nz*(sizeof(int)+bs2*sizeof(MatScalar))+(a->mbs+1)*sizeof(int);
778b0a32e0cSBarry Smith 	ierr    = PetscMalloc(len,&new_a);CHKERRQ(ierr);
77992c4ed94SBarry Smith         new_j   = (int*)(new_a + bs2*new_nz);
78092c4ed94SBarry Smith         new_i   = new_j + new_nz;
78192c4ed94SBarry Smith 
78292c4ed94SBarry Smith         /* copy over old data into new slots */
78392c4ed94SBarry Smith         for (ii=0; ii<row+1; ii++) {new_i[ii] = ai[ii];}
78492c4ed94SBarry Smith         for (ii=row+1; ii<a->mbs+1; ii++) {new_i[ii] = ai[ii]+CHUNKSIZE;}
785549d3d68SSatish Balay         ierr = PetscMemcpy(new_j,aj,(ai[row]+nrow)*sizeof(int));CHKERRQ(ierr);
78692c4ed94SBarry Smith         len  = (new_nz - CHUNKSIZE - ai[row] - nrow);
787549d3d68SSatish Balay         ierr = PetscMemcpy(new_j+ai[row]+nrow+CHUNKSIZE,aj+ai[row]+nrow,len*sizeof(int));CHKERRQ(ierr);
788549d3d68SSatish Balay         ierr = PetscMemcpy(new_a,aa,(ai[row]+nrow)*bs2*sizeof(MatScalar));CHKERRQ(ierr);
789549d3d68SSatish Balay         ierr = PetscMemzero(new_a+bs2*(ai[row]+nrow),bs2*CHUNKSIZE*sizeof(MatScalar));CHKERRQ(ierr);
790549d3d68SSatish Balay         ierr = PetscMemcpy(new_a+bs2*(ai[row]+nrow+CHUNKSIZE),aa+bs2*(ai[row]+nrow),bs2*len*sizeof(MatScalar));CHKERRQ(ierr);
79192c4ed94SBarry Smith         /* free up old matrix storage */
792606d414cSSatish Balay         ierr = PetscFree(a->a);CHKERRQ(ierr);
793606d414cSSatish Balay         if (!a->singlemalloc) {
794606d414cSSatish Balay           ierr = PetscFree(a->i);CHKERRQ(ierr);
795606d414cSSatish Balay           ierr = PetscFree(a->j);CHKERRQ(ierr);
796606d414cSSatish Balay         }
79792c4ed94SBarry Smith         aa = a->a = new_a; ai = a->i = new_i; aj = a->j = new_j;
798c4992f7dSBarry Smith         a->singlemalloc = PETSC_TRUE;
79992c4ed94SBarry Smith 
80092c4ed94SBarry Smith         rp   = aj + ai[row]; ap = aa + bs2*ai[row];
80192c4ed94SBarry Smith         rmax = imax[row] = imax[row] + CHUNKSIZE;
802b0a32e0cSBarry Smith         PetscLogObjectMemory(A,CHUNKSIZE*(sizeof(int) + bs2*sizeof(MatScalar)));
80392c4ed94SBarry Smith         a->maxnz += bs2*CHUNKSIZE;
80492c4ed94SBarry Smith         a->reallocs++;
80592c4ed94SBarry Smith         a->nz++;
80692c4ed94SBarry Smith       }
80792c4ed94SBarry Smith       N = nrow++ - 1;
80892c4ed94SBarry Smith       /* shift up all the later entries in this row */
80992c4ed94SBarry Smith       for (ii=N; ii>=i; ii--) {
81092c4ed94SBarry Smith         rp[ii+1] = rp[ii];
811549d3d68SSatish Balay         ierr = PetscMemcpy(ap+bs2*(ii+1),ap+bs2*(ii),bs2*sizeof(MatScalar));CHKERRQ(ierr);
81292c4ed94SBarry Smith       }
813549d3d68SSatish Balay       if (N >= i) {
814549d3d68SSatish Balay         ierr = PetscMemzero(ap+bs2*i,bs2*sizeof(MatScalar));CHKERRQ(ierr);
815549d3d68SSatish Balay       }
81692c4ed94SBarry Smith       rp[i] = col;
8178a84c255SSatish Balay       bap   = ap +  bs2*i;
8180e324ae4SSatish Balay       if (roworiented) {
819dd9472c6SBarry Smith         for (ii=0; ii<bs; ii++,value+=stepval) {
820dd9472c6SBarry Smith           for (jj=ii; jj<bs2; jj+=bs) {
8210e324ae4SSatish Balay             bap[jj] = *value++;
822dd9472c6SBarry Smith           }
823dd9472c6SBarry Smith         }
8240e324ae4SSatish Balay       } else {
825dd9472c6SBarry Smith         for (ii=0; ii<bs; ii++,value+=stepval) {
826dd9472c6SBarry Smith           for (jj=0; jj<bs; jj++) {
8270e324ae4SSatish Balay             *bap++  = *value++;
8280e324ae4SSatish Balay           }
829dd9472c6SBarry Smith         }
830dd9472c6SBarry Smith       }
831f1241b54SBarry Smith       noinsert2:;
83292c4ed94SBarry Smith       low = i;
83392c4ed94SBarry Smith     }
83492c4ed94SBarry Smith     ailen[row] = nrow;
83592c4ed94SBarry Smith   }
8363a40ed3dSBarry Smith   PetscFunctionReturn(0);
83792c4ed94SBarry Smith }
83892c4ed94SBarry Smith 
839f2501298SSatish Balay 
8404a2ae208SSatish Balay #undef __FUNCT__
8414a2ae208SSatish Balay #define __FUNCT__ "MatAssemblyEnd_SeqBAIJ"
8428f6be9afSLois Curfman McInnes int MatAssemblyEnd_SeqBAIJ(Mat A,MatAssemblyType mode)
843584200bdSSatish Balay {
844584200bdSSatish Balay   Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)A->data;
845584200bdSSatish Balay   int        fshift = 0,i,j,*ai = a->i,*aj = a->j,*imax = a->imax;
846273d9f13SBarry Smith   int        m = A->m,*ip,N,*ailen = a->ilen;
847549d3d68SSatish Balay   int        mbs = a->mbs,bs2 = a->bs2,rmax = 0,ierr;
8483f1db9ecSBarry Smith   MatScalar  *aa = a->a,*ap;
849584200bdSSatish Balay 
8503a40ed3dSBarry Smith   PetscFunctionBegin;
8513a40ed3dSBarry Smith   if (mode == MAT_FLUSH_ASSEMBLY) PetscFunctionReturn(0);
852584200bdSSatish Balay 
85343ee02c3SBarry Smith   if (m) rmax = ailen[0];
854584200bdSSatish Balay   for (i=1; i<mbs; i++) {
855584200bdSSatish Balay     /* move each row back by the amount of empty slots (fshift) before it*/
856584200bdSSatish Balay     fshift += imax[i-1] - ailen[i-1];
857d402145bSBarry Smith     rmax   = PetscMax(rmax,ailen[i]);
858584200bdSSatish Balay     if (fshift) {
859a7c10996SSatish Balay       ip = aj + ai[i]; ap = aa + bs2*ai[i];
860584200bdSSatish Balay       N = ailen[i];
861584200bdSSatish Balay       for (j=0; j<N; j++) {
862584200bdSSatish Balay         ip[j-fshift] = ip[j];
863549d3d68SSatish Balay         ierr = PetscMemcpy(ap+(j-fshift)*bs2,ap+j*bs2,bs2*sizeof(MatScalar));CHKERRQ(ierr);
864584200bdSSatish Balay       }
865584200bdSSatish Balay     }
866584200bdSSatish Balay     ai[i] = ai[i-1] + ailen[i-1];
867584200bdSSatish Balay   }
868584200bdSSatish Balay   if (mbs) {
869584200bdSSatish Balay     fshift += imax[mbs-1] - ailen[mbs-1];
870584200bdSSatish Balay     ai[mbs] = ai[mbs-1] + ailen[mbs-1];
871584200bdSSatish Balay   }
872584200bdSSatish Balay   /* reset ilen and imax for each row */
873584200bdSSatish Balay   for (i=0; i<mbs; i++) {
874584200bdSSatish Balay     ailen[i] = imax[i] = ai[i+1] - ai[i];
875584200bdSSatish Balay   }
876a7c10996SSatish Balay   a->nz = ai[mbs];
877584200bdSSatish Balay 
878584200bdSSatish Balay   /* diagonals may have moved, so kill the diagonal pointers */
879584200bdSSatish Balay   if (fshift && a->diag) {
880606d414cSSatish Balay     ierr = PetscFree(a->diag);CHKERRQ(ierr);
881b0a32e0cSBarry Smith     PetscLogObjectMemory(A,-(m+1)*sizeof(int));
882584200bdSSatish Balay     a->diag = 0;
883584200bdSSatish Balay   }
884b0a32e0cSBarry Smith   PetscLogInfo(A,"MatAssemblyEnd_SeqBAIJ:Matrix size: %d X %d, block size %d; storage space: %d unneeded, %d used\n",
885273d9f13SBarry Smith            m,A->n,a->bs,fshift*bs2,a->nz*bs2);
886b0a32e0cSBarry Smith   PetscLogInfo(A,"MatAssemblyEnd_SeqBAIJ:Number of mallocs during MatSetValues is %d\n",
887584200bdSSatish Balay            a->reallocs);
888b0a32e0cSBarry Smith   PetscLogInfo(A,"MatAssemblyEnd_SeqBAIJ:Most nonzeros blocks in any row is %d\n",rmax);
889e2f3b5e9SSatish Balay   a->reallocs          = 0;
8900e6d2581SBarry Smith   A->info.nz_unneeded  = (PetscReal)fshift*bs2;
8914e220ebcSLois Curfman McInnes 
8923a40ed3dSBarry Smith   PetscFunctionReturn(0);
893584200bdSSatish Balay }
894584200bdSSatish Balay 
8955a838052SSatish Balay 
896bea157c4SSatish Balay 
897bea157c4SSatish Balay /*
898bea157c4SSatish Balay    This function returns an array of flags which indicate the locations of contiguous
899bea157c4SSatish Balay    blocks that should be zeroed. for eg: if bs = 3  and is = [0,1,2,3,5,6,7,8,9]
900bea157c4SSatish Balay    then the resulting sizes = [3,1,1,3,1] correspondig to sets [(0,1,2),(3),(5),(6,7,8),(9)]
901bea157c4SSatish Balay    Assume: sizes should be long enough to hold all the values.
902bea157c4SSatish Balay */
9034a2ae208SSatish Balay #undef __FUNCT__
9044a2ae208SSatish Balay #define __FUNCT__ "MatZeroRows_SeqBAIJ_Check_Blocks"
905bea157c4SSatish Balay static int MatZeroRows_SeqBAIJ_Check_Blocks(int idx[],int n,int bs,int sizes[], int *bs_max)
906d9b7c43dSSatish Balay {
907bea157c4SSatish Balay   int        i,j,k,row;
908bea157c4SSatish Balay   PetscTruth flg;
9093a40ed3dSBarry Smith 
910433994e6SBarry Smith   PetscFunctionBegin;
911bea157c4SSatish Balay   for (i=0,j=0; i<n; j++) {
912bea157c4SSatish Balay     row = idx[i];
913bea157c4SSatish Balay     if (row%bs!=0) { /* Not the begining of a block */
914bea157c4SSatish Balay       sizes[j] = 1;
915bea157c4SSatish Balay       i++;
916e4fda26cSSatish Balay     } else if (i+bs > n) { /* complete block doesn't exist (at idx end) */
917bea157c4SSatish Balay       sizes[j] = 1;         /* Also makes sure atleast 'bs' values exist for next else */
918bea157c4SSatish Balay       i++;
919bea157c4SSatish Balay     } else { /* Begining of the block, so check if the complete block exists */
920bea157c4SSatish Balay       flg = PETSC_TRUE;
921bea157c4SSatish Balay       for (k=1; k<bs; k++) {
922bea157c4SSatish Balay         if (row+k != idx[i+k]) { /* break in the block */
923bea157c4SSatish Balay           flg = PETSC_FALSE;
924bea157c4SSatish Balay           break;
925d9b7c43dSSatish Balay         }
926bea157c4SSatish Balay       }
927bea157c4SSatish Balay       if (flg == PETSC_TRUE) { /* No break in the bs */
928bea157c4SSatish Balay         sizes[j] = bs;
929bea157c4SSatish Balay         i+= bs;
930bea157c4SSatish Balay       } else {
931bea157c4SSatish Balay         sizes[j] = 1;
932bea157c4SSatish Balay         i++;
933bea157c4SSatish Balay       }
934bea157c4SSatish Balay     }
935bea157c4SSatish Balay   }
936bea157c4SSatish Balay   *bs_max = j;
9373a40ed3dSBarry Smith   PetscFunctionReturn(0);
938d9b7c43dSSatish Balay }
939d9b7c43dSSatish Balay 
9404a2ae208SSatish Balay #undef __FUNCT__
9414a2ae208SSatish Balay #define __FUNCT__ "MatZeroRows_SeqBAIJ"
9428f6be9afSLois Curfman McInnes int MatZeroRows_SeqBAIJ(Mat A,IS is,Scalar *diag)
943d9b7c43dSSatish Balay {
944d9b7c43dSSatish Balay   Mat_SeqBAIJ *baij=(Mat_SeqBAIJ*)A->data;
945b6815fffSBarry Smith   int         ierr,i,j,k,count,is_n,*is_idx,*rows;
946bea157c4SSatish Balay   int         bs=baij->bs,bs2=baij->bs2,*sizes,row,bs_max;
9473f1db9ecSBarry Smith   Scalar      zero = 0.0;
9483f1db9ecSBarry Smith   MatScalar   *aa;
949d9b7c43dSSatish Balay 
9503a40ed3dSBarry Smith   PetscFunctionBegin;
951d9b7c43dSSatish Balay   /* Make a copy of the IS and  sort it */
952b9b97703SBarry Smith   ierr = ISGetLocalSize(is,&is_n);CHKERRQ(ierr);
953d9b7c43dSSatish Balay   ierr = ISGetIndices(is,&is_idx);CHKERRQ(ierr);
954d9b7c43dSSatish Balay 
955bea157c4SSatish Balay   /* allocate memory for rows,sizes */
956b0a32e0cSBarry Smith   ierr  = PetscMalloc((3*is_n+1)*sizeof(int),&rows);CHKERRQ(ierr);
957bea157c4SSatish Balay   sizes = rows + is_n;
958bea157c4SSatish Balay 
959563b5814SBarry Smith   /* copy IS values to rows, and sort them */
960bea157c4SSatish Balay   for (i=0; i<is_n; i++) { rows[i] = is_idx[i]; }
961bea157c4SSatish Balay   ierr = PetscSortInt(is_n,rows);CHKERRQ(ierr);
962dffd3267SBarry Smith   if (baij->keepzeroedrows) {
963dffd3267SBarry Smith     for (i=0; i<is_n; i++) { sizes[i] = 1; }
964dffd3267SBarry Smith     bs_max = is_n;
965dffd3267SBarry Smith   } else {
966bea157c4SSatish Balay     ierr = MatZeroRows_SeqBAIJ_Check_Blocks(rows,is_n,bs,sizes,&bs_max);CHKERRQ(ierr);
967dffd3267SBarry Smith   }
968b97a56abSSatish Balay   ierr = ISRestoreIndices(is,&is_idx);CHKERRQ(ierr);
969bea157c4SSatish Balay 
970bea157c4SSatish Balay   for (i=0,j=0; i<bs_max; j+=sizes[i],i++) {
971bea157c4SSatish Balay     row   = rows[j];
972273d9f13SBarry Smith     if (row < 0 || row > A->m) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"row %d out of range",row);
973bea157c4SSatish Balay     count = (baij->i[row/bs +1] - baij->i[row/bs])*bs;
974bea157c4SSatish Balay     aa    = baij->a + baij->i[row/bs]*bs2 + (row%bs);
975dffd3267SBarry Smith     if (sizes[i] == bs && !baij->keepzeroedrows) {
976bea157c4SSatish Balay       if (diag) {
977bea157c4SSatish Balay         if (baij->ilen[row/bs] > 0) {
978bea157c4SSatish Balay           baij->ilen[row/bs]       = 1;
979bea157c4SSatish Balay           baij->j[baij->i[row/bs]] = row/bs;
980bea157c4SSatish Balay           ierr = PetscMemzero(aa,count*bs*sizeof(MatScalar));CHKERRQ(ierr);
981a07cd24cSSatish Balay         }
982563b5814SBarry Smith         /* Now insert all the diagonal values for this bs */
983bea157c4SSatish Balay         for (k=0; k<bs; k++) {
984bea157c4SSatish Balay           ierr = (*A->ops->setvalues)(A,1,rows+j+k,1,rows+j+k,diag,INSERT_VALUES);CHKERRQ(ierr);
985bea157c4SSatish Balay         }
986bea157c4SSatish Balay       } else { /* (!diag) */
987bea157c4SSatish Balay         baij->ilen[row/bs] = 0;
988bea157c4SSatish Balay       } /* end (!diag) */
989bea157c4SSatish Balay     } else { /* (sizes[i] != bs) */
990aa482453SBarry Smith #if defined (PETSC_USE_DEBUG)
99129bbc08cSBarry Smith       if (sizes[i] != 1) SETERRQ(1,"Internal Error. Value should be 1");
992bea157c4SSatish Balay #endif
993bea157c4SSatish Balay       for (k=0; k<count; k++) {
994d9b7c43dSSatish Balay         aa[0] =  zero;
995d9b7c43dSSatish Balay         aa    += bs;
996d9b7c43dSSatish Balay       }
997d9b7c43dSSatish Balay       if (diag) {
998f830108cSBarry Smith         ierr = (*A->ops->setvalues)(A,1,rows+j,1,rows+j,diag,INSERT_VALUES);CHKERRQ(ierr);
999d9b7c43dSSatish Balay       }
1000d9b7c43dSSatish Balay     }
1001bea157c4SSatish Balay   }
1002bea157c4SSatish Balay 
1003606d414cSSatish Balay   ierr = PetscFree(rows);CHKERRQ(ierr);
10049a8dea36SBarry Smith   ierr = MatAssemblyEnd_SeqBAIJ(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
10053a40ed3dSBarry Smith   PetscFunctionReturn(0);
1006d9b7c43dSSatish Balay }
10071c351548SSatish Balay 
10084a2ae208SSatish Balay #undef __FUNCT__
10094a2ae208SSatish Balay #define __FUNCT__ "MatSetValues_SeqBAIJ"
10102d61bbb3SSatish Balay int MatSetValues_SeqBAIJ(Mat A,int m,int *im,int n,int *in,Scalar *v,InsertMode is)
10112d61bbb3SSatish Balay {
10122d61bbb3SSatish Balay   Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)A->data;
10132d61bbb3SSatish Balay   int         *rp,k,low,high,t,ii,row,nrow,i,col,l,rmax,N,sorted=a->sorted;
1014273d9f13SBarry Smith   int         *imax=a->imax,*ai=a->i,*ailen=a->ilen;
10152d61bbb3SSatish Balay   int         *aj=a->j,nonew=a->nonew,bs=a->bs,brow,bcol;
1016549d3d68SSatish Balay   int         ridx,cidx,bs2=a->bs2,ierr;
1017273d9f13SBarry Smith   PetscTruth  roworiented=a->roworiented;
10183f1db9ecSBarry Smith   MatScalar   *ap,value,*aa=a->a,*bap;
10192d61bbb3SSatish Balay 
10202d61bbb3SSatish Balay   PetscFunctionBegin;
10212d61bbb3SSatish Balay   for (k=0; k<m; k++) { /* loop over added rows */
10222d61bbb3SSatish Balay     row  = im[k]; brow = row/bs;
10235ef9f2a5SBarry Smith     if (row < 0) continue;
1024aa482453SBarry Smith #if defined(PETSC_USE_BOPT_g)
1025273d9f13SBarry Smith     if (row >= A->m) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"Row too large: row %d max %d",row,A->m);
10262d61bbb3SSatish Balay #endif
10272d61bbb3SSatish Balay     rp   = aj + ai[brow];
10282d61bbb3SSatish Balay     ap   = aa + bs2*ai[brow];
10292d61bbb3SSatish Balay     rmax = imax[brow];
10302d61bbb3SSatish Balay     nrow = ailen[brow];
10312d61bbb3SSatish Balay     low  = 0;
10322d61bbb3SSatish Balay     for (l=0; l<n; l++) { /* loop over added columns */
10335ef9f2a5SBarry Smith       if (in[l] < 0) continue;
1034aa482453SBarry Smith #if defined(PETSC_USE_BOPT_g)
1035273d9f13SBarry Smith       if (in[l] >= A->n) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"Column too large: col %d max %d",in[l],A->n);
10362d61bbb3SSatish Balay #endif
10372d61bbb3SSatish Balay       col = in[l]; bcol = col/bs;
10382d61bbb3SSatish Balay       ridx = row % bs; cidx = col % bs;
10392d61bbb3SSatish Balay       if (roworiented) {
10405ef9f2a5SBarry Smith         value = v[l + k*n];
10412d61bbb3SSatish Balay       } else {
10422d61bbb3SSatish Balay         value = v[k + l*m];
10432d61bbb3SSatish Balay       }
10442d61bbb3SSatish Balay       if (!sorted) low = 0; high = nrow;
10452d61bbb3SSatish Balay       while (high-low > 7) {
10462d61bbb3SSatish Balay         t = (low+high)/2;
10472d61bbb3SSatish Balay         if (rp[t] > bcol) high = t;
10482d61bbb3SSatish Balay         else              low  = t;
10492d61bbb3SSatish Balay       }
10502d61bbb3SSatish Balay       for (i=low; i<high; i++) {
10512d61bbb3SSatish Balay         if (rp[i] > bcol) break;
10522d61bbb3SSatish Balay         if (rp[i] == bcol) {
10532d61bbb3SSatish Balay           bap  = ap +  bs2*i + bs*cidx + ridx;
10542d61bbb3SSatish Balay           if (is == ADD_VALUES) *bap += value;
10552d61bbb3SSatish Balay           else                  *bap  = value;
10562d61bbb3SSatish Balay           goto noinsert1;
10572d61bbb3SSatish Balay         }
10582d61bbb3SSatish Balay       }
10592d61bbb3SSatish Balay       if (nonew == 1) goto noinsert1;
106029bbc08cSBarry Smith       else if (nonew == -1) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Inserting a new nonzero in the matrix");
10612d61bbb3SSatish Balay       if (nrow >= rmax) {
10622d61bbb3SSatish Balay         /* there is no extra room in row, therefore enlarge */
10632d61bbb3SSatish Balay         int       new_nz = ai[a->mbs] + CHUNKSIZE,len,*new_i,*new_j;
10643f1db9ecSBarry Smith         MatScalar *new_a;
10652d61bbb3SSatish Balay 
106629bbc08cSBarry Smith         if (nonew == -2) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Inserting a new nonzero in the matrix");
10672d61bbb3SSatish Balay 
10682d61bbb3SSatish Balay         /* Malloc new storage space */
10693f1db9ecSBarry Smith         len     = new_nz*(sizeof(int)+bs2*sizeof(MatScalar))+(a->mbs+1)*sizeof(int);
1070b0a32e0cSBarry Smith 	ierr    = PetscMalloc(len,&new_a);CHKERRQ(ierr);
10712d61bbb3SSatish Balay         new_j   = (int*)(new_a + bs2*new_nz);
10722d61bbb3SSatish Balay         new_i   = new_j + new_nz;
10732d61bbb3SSatish Balay 
10742d61bbb3SSatish Balay         /* copy over old data into new slots */
10752d61bbb3SSatish Balay         for (ii=0; ii<brow+1; ii++) {new_i[ii] = ai[ii];}
10762d61bbb3SSatish Balay         for (ii=brow+1; ii<a->mbs+1; ii++) {new_i[ii] = ai[ii]+CHUNKSIZE;}
1077549d3d68SSatish Balay         ierr = PetscMemcpy(new_j,aj,(ai[brow]+nrow)*sizeof(int));CHKERRQ(ierr);
10782d61bbb3SSatish Balay         len  = (new_nz - CHUNKSIZE - ai[brow] - nrow);
1079549d3d68SSatish Balay         ierr = PetscMemcpy(new_j+ai[brow]+nrow+CHUNKSIZE,aj+ai[brow]+nrow,len*sizeof(int));CHKERRQ(ierr);
1080549d3d68SSatish Balay         ierr = PetscMemcpy(new_a,aa,(ai[brow]+nrow)*bs2*sizeof(MatScalar));CHKERRQ(ierr);
1081549d3d68SSatish Balay         ierr = PetscMemzero(new_a+bs2*(ai[brow]+nrow),bs2*CHUNKSIZE*sizeof(MatScalar));CHKERRQ(ierr);
1082549d3d68SSatish Balay         ierr = PetscMemcpy(new_a+bs2*(ai[brow]+nrow+CHUNKSIZE),aa+bs2*(ai[brow]+nrow),bs2*len*sizeof(MatScalar));CHKERRQ(ierr);
10832d61bbb3SSatish Balay         /* free up old matrix storage */
1084606d414cSSatish Balay         ierr = PetscFree(a->a);CHKERRQ(ierr);
1085606d414cSSatish Balay         if (!a->singlemalloc) {
1086606d414cSSatish Balay           ierr = PetscFree(a->i);CHKERRQ(ierr);
1087606d414cSSatish Balay           ierr = PetscFree(a->j);CHKERRQ(ierr);
1088606d414cSSatish Balay         }
10892d61bbb3SSatish Balay         aa = a->a = new_a; ai = a->i = new_i; aj = a->j = new_j;
1090c4992f7dSBarry Smith         a->singlemalloc = PETSC_TRUE;
10912d61bbb3SSatish Balay 
10922d61bbb3SSatish Balay         rp   = aj + ai[brow]; ap = aa + bs2*ai[brow];
10932d61bbb3SSatish Balay         rmax = imax[brow] = imax[brow] + CHUNKSIZE;
1094b0a32e0cSBarry Smith         PetscLogObjectMemory(A,CHUNKSIZE*(sizeof(int) + bs2*sizeof(MatScalar)));
10952d61bbb3SSatish Balay         a->maxnz += bs2*CHUNKSIZE;
10962d61bbb3SSatish Balay         a->reallocs++;
10972d61bbb3SSatish Balay         a->nz++;
10982d61bbb3SSatish Balay       }
10992d61bbb3SSatish Balay       N = nrow++ - 1;
11002d61bbb3SSatish Balay       /* shift up all the later entries in this row */
11012d61bbb3SSatish Balay       for (ii=N; ii>=i; ii--) {
11022d61bbb3SSatish Balay         rp[ii+1] = rp[ii];
1103549d3d68SSatish Balay         ierr     = PetscMemcpy(ap+bs2*(ii+1),ap+bs2*(ii),bs2*sizeof(MatScalar));CHKERRQ(ierr);
11042d61bbb3SSatish Balay       }
1105549d3d68SSatish Balay       if (N>=i) {
1106549d3d68SSatish Balay         ierr = PetscMemzero(ap+bs2*i,bs2*sizeof(MatScalar));CHKERRQ(ierr);
1107549d3d68SSatish Balay       }
11082d61bbb3SSatish Balay       rp[i]                      = bcol;
11092d61bbb3SSatish Balay       ap[bs2*i + bs*cidx + ridx] = value;
11102d61bbb3SSatish Balay       noinsert1:;
11112d61bbb3SSatish Balay       low = i;
11122d61bbb3SSatish Balay     }
11132d61bbb3SSatish Balay     ailen[brow] = nrow;
11142d61bbb3SSatish Balay   }
11152d61bbb3SSatish Balay   PetscFunctionReturn(0);
11162d61bbb3SSatish Balay }
11172d61bbb3SSatish Balay 
1118b9b97703SBarry Smith EXTERN int MatLUFactorSymbolic_SeqBAIJ(Mat,IS,IS,MatLUInfo*,Mat*);
1119b9b97703SBarry Smith EXTERN int MatLUFactor_SeqBAIJ(Mat,IS,IS,MatLUInfo*);
1120ca44d042SBarry Smith EXTERN int MatIncreaseOverlap_SeqBAIJ(Mat,int,IS*,int);
1121ca44d042SBarry Smith EXTERN int MatGetSubMatrix_SeqBAIJ(Mat,IS,IS,int,MatReuse,Mat*);
1122ca44d042SBarry Smith EXTERN int MatGetSubMatrices_SeqBAIJ(Mat,int,IS*,IS*,MatReuse,Mat**);
1123ca44d042SBarry Smith EXTERN int MatMultTranspose_SeqBAIJ(Mat,Vec,Vec);
1124ca44d042SBarry Smith EXTERN int MatMultTransposeAdd_SeqBAIJ(Mat,Vec,Vec,Vec);
1125ca44d042SBarry Smith EXTERN int MatScale_SeqBAIJ(Scalar*,Mat);
1126ca44d042SBarry Smith EXTERN int MatNorm_SeqBAIJ(Mat,NormType,PetscReal *);
1127ca44d042SBarry Smith EXTERN int MatEqual_SeqBAIJ(Mat,Mat,PetscTruth*);
1128ca44d042SBarry Smith EXTERN int MatGetDiagonal_SeqBAIJ(Mat,Vec);
1129ca44d042SBarry Smith EXTERN int MatDiagonalScale_SeqBAIJ(Mat,Vec,Vec);
1130ca44d042SBarry Smith EXTERN int MatGetInfo_SeqBAIJ(Mat,MatInfoType,MatInfo *);
1131ca44d042SBarry Smith EXTERN int MatZeroEntries_SeqBAIJ(Mat);
11322d61bbb3SSatish Balay 
1133ca44d042SBarry Smith EXTERN int MatSolve_SeqBAIJ_N(Mat,Vec,Vec);
1134ca44d042SBarry Smith EXTERN int MatSolve_SeqBAIJ_1(Mat,Vec,Vec);
1135ca44d042SBarry Smith EXTERN int MatSolve_SeqBAIJ_2(Mat,Vec,Vec);
1136ca44d042SBarry Smith EXTERN int MatSolve_SeqBAIJ_3(Mat,Vec,Vec);
1137ca44d042SBarry Smith EXTERN int MatSolve_SeqBAIJ_4(Mat,Vec,Vec);
1138ca44d042SBarry Smith EXTERN int MatSolve_SeqBAIJ_5(Mat,Vec,Vec);
1139ca44d042SBarry Smith EXTERN int MatSolve_SeqBAIJ_6(Mat,Vec,Vec);
1140ca44d042SBarry Smith EXTERN int MatSolve_SeqBAIJ_7(Mat,Vec,Vec);
1141ca44d042SBarry Smith EXTERN int MatSolveTranspose_SeqBAIJ_7(Mat,Vec,Vec);
1142ca44d042SBarry Smith EXTERN int MatSolveTranspose_SeqBAIJ_6(Mat,Vec,Vec);
1143ca44d042SBarry Smith EXTERN int MatSolveTranspose_SeqBAIJ_5(Mat,Vec,Vec);
1144ca44d042SBarry Smith EXTERN int MatSolveTranspose_SeqBAIJ_4(Mat,Vec,Vec);
1145ca44d042SBarry Smith EXTERN int MatSolveTranspose_SeqBAIJ_3(Mat,Vec,Vec);
1146ca44d042SBarry Smith EXTERN int MatSolveTranspose_SeqBAIJ_2(Mat,Vec,Vec);
1147ca44d042SBarry Smith EXTERN int MatSolveTranspose_SeqBAIJ_1(Mat,Vec,Vec);
11482d61bbb3SSatish Balay 
1149ca44d042SBarry Smith EXTERN int MatLUFactorNumeric_SeqBAIJ_N(Mat,Mat*);
1150ca44d042SBarry Smith EXTERN int MatLUFactorNumeric_SeqBAIJ_1(Mat,Mat*);
1151ca44d042SBarry Smith EXTERN int MatLUFactorNumeric_SeqBAIJ_2(Mat,Mat*);
1152ca44d042SBarry Smith EXTERN int MatLUFactorNumeric_SeqBAIJ_3(Mat,Mat*);
1153ca44d042SBarry Smith EXTERN int MatLUFactorNumeric_SeqBAIJ_4(Mat,Mat*);
1154ca44d042SBarry Smith EXTERN int MatLUFactorNumeric_SeqBAIJ_5(Mat,Mat*);
1155ca44d042SBarry Smith EXTERN int MatLUFactorNumeric_SeqBAIJ_6(Mat,Mat*);
11562d61bbb3SSatish Balay 
1157ca44d042SBarry Smith EXTERN int MatMult_SeqBAIJ_1(Mat,Vec,Vec);
1158ca44d042SBarry Smith EXTERN int MatMult_SeqBAIJ_2(Mat,Vec,Vec);
1159ca44d042SBarry Smith EXTERN int MatMult_SeqBAIJ_3(Mat,Vec,Vec);
1160ca44d042SBarry Smith EXTERN int MatMult_SeqBAIJ_4(Mat,Vec,Vec);
1161ca44d042SBarry Smith EXTERN int MatMult_SeqBAIJ_5(Mat,Vec,Vec);
1162ca44d042SBarry Smith EXTERN int MatMult_SeqBAIJ_6(Mat,Vec,Vec);
1163ca44d042SBarry Smith EXTERN int MatMult_SeqBAIJ_7(Mat,Vec,Vec);
1164ca44d042SBarry Smith EXTERN int MatMult_SeqBAIJ_N(Mat,Vec,Vec);
11652d61bbb3SSatish Balay 
1166ca44d042SBarry Smith EXTERN int MatMultAdd_SeqBAIJ_1(Mat,Vec,Vec,Vec);
1167ca44d042SBarry Smith EXTERN int MatMultAdd_SeqBAIJ_2(Mat,Vec,Vec,Vec);
1168ca44d042SBarry Smith EXTERN int MatMultAdd_SeqBAIJ_3(Mat,Vec,Vec,Vec);
1169ca44d042SBarry Smith EXTERN int MatMultAdd_SeqBAIJ_4(Mat,Vec,Vec,Vec);
1170ca44d042SBarry Smith EXTERN int MatMultAdd_SeqBAIJ_5(Mat,Vec,Vec,Vec);
1171ca44d042SBarry Smith EXTERN int MatMultAdd_SeqBAIJ_6(Mat,Vec,Vec,Vec);
1172ca44d042SBarry Smith EXTERN int MatMultAdd_SeqBAIJ_7(Mat,Vec,Vec,Vec);
1173ca44d042SBarry Smith EXTERN int MatMultAdd_SeqBAIJ_N(Mat,Vec,Vec,Vec);
11742d61bbb3SSatish Balay 
11754a2ae208SSatish Balay #undef __FUNCT__
11764a2ae208SSatish Balay #define __FUNCT__ "MatILUFactor_SeqBAIJ"
11775ef9f2a5SBarry Smith int MatILUFactor_SeqBAIJ(Mat inA,IS row,IS col,MatILUInfo *info)
11782d61bbb3SSatish Balay {
11792d61bbb3SSatish Balay   Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)inA->data;
11802d61bbb3SSatish Balay   Mat         outA;
11812d61bbb3SSatish Balay   int         ierr;
1182667159a5SBarry Smith   PetscTruth  row_identity,col_identity;
11832d61bbb3SSatish Balay 
11842d61bbb3SSatish Balay   PetscFunctionBegin;
118529bbc08cSBarry Smith   if (info && info->levels != 0) SETERRQ(PETSC_ERR_SUP,"Only levels = 0 supported for in-place ILU");
1186667159a5SBarry Smith   ierr = ISIdentity(row,&row_identity);CHKERRQ(ierr);
1187667159a5SBarry Smith   ierr = ISIdentity(col,&col_identity);CHKERRQ(ierr);
1188667159a5SBarry Smith   if (!row_identity || !col_identity) {
118929bbc08cSBarry Smith     SETERRQ(1,"Row and column permutations must be identity for in-place ILU");
1190667159a5SBarry Smith   }
11912d61bbb3SSatish Balay 
11922d61bbb3SSatish Balay   outA          = inA;
11932d61bbb3SSatish Balay   inA->factor   = FACTOR_LU;
11942d61bbb3SSatish Balay 
11952d61bbb3SSatish Balay   if (!a->diag) {
1196c4992f7dSBarry Smith     ierr = MatMarkDiagonal_SeqBAIJ(inA);CHKERRQ(ierr);
11972d61bbb3SSatish Balay   }
11982d61bbb3SSatish Balay   /*
119915091d37SBarry Smith       Blocksize 2, 3, 4, 5, 6 and 7 have a special faster factorization/solver
120015091d37SBarry Smith       for ILU(0) factorization with natural ordering
12012d61bbb3SSatish Balay   */
120215091d37SBarry Smith   switch (a->bs) {
1203f1af5d2fSBarry Smith   case 1:
1204e37c484bSBarry Smith     inA->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_1;
1205e37c484bSBarry Smith     inA->ops->solve           = MatSolve_SeqBAIJ_1_NaturalOrdering;
1206e37c484bSBarry Smith     inA->ops->solvetranspose  = MatSolveTranspose_SeqBAIJ_1_NaturalOrdering;
1207b0a32e0cSBarry Smith     PetscLogInfo(inA,"MatILUFactor_SeqBAIJ:Using special in-place natural ordering factor and solve BS=1\n");
120815091d37SBarry Smith   case 2:
120915091d37SBarry Smith     inA->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_2_NaturalOrdering;
121015091d37SBarry Smith     inA->ops->solve           = MatSolve_SeqBAIJ_2_NaturalOrdering;
12117c922b88SBarry Smith     inA->ops->solvetranspose  = MatSolveTranspose_SeqBAIJ_2_NaturalOrdering;
1212b0a32e0cSBarry Smith     PetscLogInfo(inA,"MatILUFactor_SeqBAIJ:Using special in-place natural ordering factor and solve BS=2\n");
121315091d37SBarry Smith     break;
121415091d37SBarry Smith   case 3:
121515091d37SBarry Smith     inA->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_3_NaturalOrdering;
121615091d37SBarry Smith     inA->ops->solve           = MatSolve_SeqBAIJ_3_NaturalOrdering;
12177c922b88SBarry Smith     inA->ops->solvetranspose  = MatSolveTranspose_SeqBAIJ_3_NaturalOrdering;
1218b0a32e0cSBarry Smith     PetscLogInfo(inA,"MatILUFactor_SeqBAIJ:Using special in-place natural ordering factor and solve BS=3\n");
121915091d37SBarry Smith     break;
122015091d37SBarry Smith   case 4:
122135662bc6SKris Buschelman #if defined(PETSC_HAVE_SSE)
1222*4f1ab113SKris Buschelman     {
122335662bc6SKris Buschelman       PetscTruth sse_enabled;
122435662bc6SKris Buschelman       ierr = PetscSSEIsEnabled(&sse_enabled);CHKERRQ(ierr);
122535662bc6SKris Buschelman       if (sse_enabled) {
122635662bc6SKris Buschelman         inA->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_4_NaturalOrdering_SSE;
122735662bc6SKris Buschelman       } else {
1228667159a5SBarry Smith         inA->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_4_NaturalOrdering;
122935662bc6SKris Buschelman       }
1230*4f1ab113SKris Buschelman     }
123135662bc6SKris Buschelman #else
123235662bc6SKris Buschelman     inA->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_4_NaturalOrdering;
123335662bc6SKris Buschelman #endif
1234f830108cSBarry Smith     inA->ops->solve           = MatSolve_SeqBAIJ_4_NaturalOrdering;
12357c922b88SBarry Smith     inA->ops->solvetranspose  = MatSolveTranspose_SeqBAIJ_4_NaturalOrdering;
1236b0a32e0cSBarry Smith     PetscLogInfo(inA,"MatILUFactor_SeqBAIJ:Using special in-place natural ordering factor and solve BS=4\n");
123715091d37SBarry Smith     break;
123815091d37SBarry Smith   case 5:
1239667159a5SBarry Smith     inA->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_5_NaturalOrdering;
1240667159a5SBarry Smith     inA->ops->solve           = MatSolve_SeqBAIJ_5_NaturalOrdering;
12417c922b88SBarry Smith     inA->ops->solvetranspose  = MatSolveTranspose_SeqBAIJ_5_NaturalOrdering;
1242b0a32e0cSBarry Smith     PetscLogInfo(inA,"MatILUFactor_SeqBAIJ:Using special in-place natural ordering factor and solve BS=5\n");
124315091d37SBarry Smith     break;
124415091d37SBarry Smith   case 6:
124515091d37SBarry Smith     inA->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_6_NaturalOrdering;
124615091d37SBarry Smith     inA->ops->solve           = MatSolve_SeqBAIJ_6_NaturalOrdering;
12477c922b88SBarry Smith     inA->ops->solvetranspose  = MatSolveTranspose_SeqBAIJ_6_NaturalOrdering;
1248b0a32e0cSBarry Smith     PetscLogInfo(inA,"MatILUFactor_SeqBAIJ:Using special in-place natural ordering factor and solve BS=6\n");
124915091d37SBarry Smith     break;
125015091d37SBarry Smith   case 7:
125115091d37SBarry Smith     inA->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_7_NaturalOrdering;
12527c922b88SBarry Smith     inA->ops->solvetranspose  = MatSolveTranspose_SeqBAIJ_7_NaturalOrdering;
125315091d37SBarry Smith     inA->ops->solve           = MatSolve_SeqBAIJ_7_NaturalOrdering;
1254b0a32e0cSBarry Smith     PetscLogInfo(inA,"MatILUFactor_SeqBAIJ:Using special in-place natural ordering factor and solve BS=7\n");
125515091d37SBarry Smith     break;
1256c38d4ed2SBarry Smith   default:
1257c38d4ed2SBarry Smith     a->row        = row;
1258c38d4ed2SBarry Smith     a->col        = col;
1259c38d4ed2SBarry Smith     ierr          = PetscObjectReference((PetscObject)row);CHKERRQ(ierr);
1260c38d4ed2SBarry Smith     ierr          = PetscObjectReference((PetscObject)col);CHKERRQ(ierr);
1261c38d4ed2SBarry Smith 
1262c38d4ed2SBarry Smith     /* Create the invert permutation so that it can be used in MatLUFactorNumeric() */
12634c49b128SBarry Smith     ierr = ISInvertPermutation(col,PETSC_DECIDE,&a->icol);CHKERRQ(ierr);
1264b0a32e0cSBarry Smith     PetscLogObjectParent(inA,a->icol);
1265c38d4ed2SBarry Smith 
1266c38d4ed2SBarry Smith     if (!a->solve_work) {
1267b0a32e0cSBarry Smith       ierr = PetscMalloc((inA->m+a->bs)*sizeof(Scalar),&a->solve_work);CHKERRQ(ierr);
1268b0a32e0cSBarry Smith       PetscLogObjectMemory(inA,(inA->m+a->bs)*sizeof(Scalar));
1269c38d4ed2SBarry Smith     }
12702d61bbb3SSatish Balay   }
12712d61bbb3SSatish Balay 
1272667159a5SBarry Smith   ierr = MatLUFactorNumeric(inA,&outA);CHKERRQ(ierr);
1273667159a5SBarry Smith 
12742d61bbb3SSatish Balay   PetscFunctionReturn(0);
12752d61bbb3SSatish Balay }
12764a2ae208SSatish Balay #undef __FUNCT__
12774a2ae208SSatish Balay #define __FUNCT__ "MatPrintHelp_SeqBAIJ"
1278ba4ca20aSSatish Balay int MatPrintHelp_SeqBAIJ(Mat A)
1279ba4ca20aSSatish Balay {
1280c38d4ed2SBarry Smith   static PetscTruth called = PETSC_FALSE;
1281ba4ca20aSSatish Balay   MPI_Comm          comm = A->comm;
1282d132466eSBarry Smith   int               ierr;
1283ba4ca20aSSatish Balay 
12843a40ed3dSBarry Smith   PetscFunctionBegin;
1285c38d4ed2SBarry Smith   if (called) {PetscFunctionReturn(0);} else called = PETSC_TRUE;
1286d132466eSBarry Smith   ierr = (*PetscHelpPrintf)(comm," Options for MATSEQBAIJ and MATMPIBAIJ matrix formats (the defaults):\n");CHKERRQ(ierr);
1287d132466eSBarry Smith   ierr = (*PetscHelpPrintf)(comm,"  -mat_block_size <block_size>\n");CHKERRQ(ierr);
12883a40ed3dSBarry Smith   PetscFunctionReturn(0);
1289ba4ca20aSSatish Balay }
1290d9b7c43dSSatish Balay 
1291fb2e594dSBarry Smith EXTERN_C_BEGIN
12924a2ae208SSatish Balay #undef __FUNCT__
12934a2ae208SSatish Balay #define __FUNCT__ "MatSeqBAIJSetColumnIndices_SeqBAIJ"
129427a8da17SBarry Smith int MatSeqBAIJSetColumnIndices_SeqBAIJ(Mat mat,int *indices)
129527a8da17SBarry Smith {
129627a8da17SBarry Smith   Mat_SeqBAIJ *baij = (Mat_SeqBAIJ *)mat->data;
129727a8da17SBarry Smith   int         i,nz,n;
129827a8da17SBarry Smith 
129927a8da17SBarry Smith   PetscFunctionBegin;
130027a8da17SBarry Smith   nz = baij->maxnz;
1301273d9f13SBarry Smith   n  = mat->n;
130227a8da17SBarry Smith   for (i=0; i<nz; i++) {
130327a8da17SBarry Smith     baij->j[i] = indices[i];
130427a8da17SBarry Smith   }
130527a8da17SBarry Smith   baij->nz = nz;
130627a8da17SBarry Smith   for (i=0; i<n; i++) {
130727a8da17SBarry Smith     baij->ilen[i] = baij->imax[i];
130827a8da17SBarry Smith   }
130927a8da17SBarry Smith 
131027a8da17SBarry Smith   PetscFunctionReturn(0);
131127a8da17SBarry Smith }
1312fb2e594dSBarry Smith EXTERN_C_END
131327a8da17SBarry Smith 
13144a2ae208SSatish Balay #undef __FUNCT__
13154a2ae208SSatish Balay #define __FUNCT__ "MatSeqBAIJSetColumnIndices"
131627a8da17SBarry Smith /*@
131727a8da17SBarry Smith     MatSeqBAIJSetColumnIndices - Set the column indices for all the rows
131827a8da17SBarry Smith        in the matrix.
131927a8da17SBarry Smith 
132027a8da17SBarry Smith   Input Parameters:
132127a8da17SBarry Smith +  mat - the SeqBAIJ matrix
132227a8da17SBarry Smith -  indices - the column indices
132327a8da17SBarry Smith 
132415091d37SBarry Smith   Level: advanced
132515091d37SBarry Smith 
132627a8da17SBarry Smith   Notes:
132727a8da17SBarry Smith     This can be called if you have precomputed the nonzero structure of the
132827a8da17SBarry Smith   matrix and want to provide it to the matrix object to improve the performance
132927a8da17SBarry Smith   of the MatSetValues() operation.
133027a8da17SBarry Smith 
133127a8da17SBarry Smith     You MUST have set the correct numbers of nonzeros per row in the call to
133227a8da17SBarry Smith   MatCreateSeqBAIJ().
133327a8da17SBarry Smith 
133427a8da17SBarry Smith     MUST be called before any calls to MatSetValues();
133527a8da17SBarry Smith 
133627a8da17SBarry Smith @*/
133727a8da17SBarry Smith int MatSeqBAIJSetColumnIndices(Mat mat,int *indices)
133827a8da17SBarry Smith {
133927a8da17SBarry Smith   int ierr,(*f)(Mat,int *);
134027a8da17SBarry Smith 
134127a8da17SBarry Smith   PetscFunctionBegin;
134227a8da17SBarry Smith   PetscValidHeaderSpecific(mat,MAT_COOKIE);
1343b9617806SBarry Smith   ierr = PetscObjectQueryFunction((PetscObject)mat,"MatSeqBAIJSetColumnIndices_C",(void (**)())&f);CHKERRQ(ierr);
134427a8da17SBarry Smith   if (f) {
134527a8da17SBarry Smith     ierr = (*f)(mat,indices);CHKERRQ(ierr);
134627a8da17SBarry Smith   } else {
134729bbc08cSBarry Smith     SETERRQ(1,"Wrong type of matrix to set column indices");
134827a8da17SBarry Smith   }
134927a8da17SBarry Smith   PetscFunctionReturn(0);
135027a8da17SBarry Smith }
135127a8da17SBarry Smith 
13524a2ae208SSatish Balay #undef __FUNCT__
13534a2ae208SSatish Balay #define __FUNCT__ "MatGetRowMax_SeqBAIJ"
1354273d9f13SBarry Smith int MatGetRowMax_SeqBAIJ(Mat A,Vec v)
1355273d9f13SBarry Smith {
1356273d9f13SBarry Smith   Mat_SeqBAIJ  *a = (Mat_SeqBAIJ*)A->data;
1357273d9f13SBarry Smith   int          ierr,i,j,n,row,bs,*ai,*aj,mbs;
1358273d9f13SBarry Smith   PetscReal    atmp;
1359273d9f13SBarry Smith   Scalar       *x,zero = 0.0;
1360273d9f13SBarry Smith   MatScalar    *aa;
1361273d9f13SBarry Smith   int          ncols,brow,krow,kcol;
1362273d9f13SBarry Smith 
1363273d9f13SBarry Smith   PetscFunctionBegin;
1364273d9f13SBarry Smith   if (A->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1365273d9f13SBarry Smith   bs   = a->bs;
1366273d9f13SBarry Smith   aa   = a->a;
1367273d9f13SBarry Smith   ai   = a->i;
1368273d9f13SBarry Smith   aj   = a->j;
1369273d9f13SBarry Smith   mbs = a->mbs;
1370273d9f13SBarry Smith 
1371273d9f13SBarry Smith   ierr = VecSet(&zero,v);CHKERRQ(ierr);
1372273d9f13SBarry Smith   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
1373273d9f13SBarry Smith   ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr);
1374273d9f13SBarry Smith   if (n != A->m) SETERRQ(PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector");
1375273d9f13SBarry Smith   for (i=0; i<mbs; i++) {
1376273d9f13SBarry Smith     ncols = ai[1] - ai[0]; ai++;
1377273d9f13SBarry Smith     brow  = bs*i;
1378273d9f13SBarry Smith     for (j=0; j<ncols; j++){
1379273d9f13SBarry Smith       /* bcol = bs*(*aj); */
1380273d9f13SBarry Smith       for (kcol=0; kcol<bs; kcol++){
1381273d9f13SBarry Smith         for (krow=0; krow<bs; krow++){
1382273d9f13SBarry Smith           atmp = PetscAbsScalar(*aa); aa++;
1383273d9f13SBarry Smith           row = brow + krow;    /* row index */
1384273d9f13SBarry Smith           /* printf("val[%d,%d]: %g\n",row,bcol+kcol,atmp); */
1385273d9f13SBarry Smith           if (PetscAbsScalar(x[row]) < atmp) x[row] = atmp;
1386273d9f13SBarry Smith         }
1387273d9f13SBarry Smith       }
1388273d9f13SBarry Smith       aj++;
1389273d9f13SBarry Smith     }
1390273d9f13SBarry Smith   }
1391273d9f13SBarry Smith   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
1392273d9f13SBarry Smith   PetscFunctionReturn(0);
1393273d9f13SBarry Smith }
1394273d9f13SBarry Smith 
13954a2ae208SSatish Balay #undef __FUNCT__
13964a2ae208SSatish Balay #define __FUNCT__ "MatSetUpPreallocation_SeqBAIJ"
1397273d9f13SBarry Smith int MatSetUpPreallocation_SeqBAIJ(Mat A)
1398273d9f13SBarry Smith {
1399273d9f13SBarry Smith   int        ierr;
1400273d9f13SBarry Smith 
1401273d9f13SBarry Smith   PetscFunctionBegin;
1402273d9f13SBarry Smith   ierr =  MatSeqBAIJSetPreallocation(A,1,PETSC_DEFAULT,0);CHKERRQ(ierr);
1403273d9f13SBarry Smith   PetscFunctionReturn(0);
1404273d9f13SBarry Smith }
1405273d9f13SBarry Smith 
14064a2ae208SSatish Balay #undef __FUNCT__
14074a2ae208SSatish Balay #define __FUNCT__ "MatGetArray_SeqBAIJ"
1408f2a5309cSSatish Balay int MatGetArray_SeqBAIJ(Mat A,Scalar **array)
1409f2a5309cSSatish Balay {
1410f2a5309cSSatish Balay   Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)A->data;
1411f2a5309cSSatish Balay   PetscFunctionBegin;
1412f2a5309cSSatish Balay   *array = a->a;
1413f2a5309cSSatish Balay   PetscFunctionReturn(0);
1414f2a5309cSSatish Balay }
1415f2a5309cSSatish Balay 
14164a2ae208SSatish Balay #undef __FUNCT__
14174a2ae208SSatish Balay #define __FUNCT__ "MatRestoreArray_SeqBAIJ"
1418f2a5309cSSatish Balay int MatRestoreArray_SeqBAIJ(Mat A,Scalar **array)
1419f2a5309cSSatish Balay {
1420f2a5309cSSatish Balay   PetscFunctionBegin;
1421f2a5309cSSatish Balay   PetscFunctionReturn(0);
1422f2a5309cSSatish Balay }
1423f2a5309cSSatish Balay 
14242593348eSBarry Smith /* -------------------------------------------------------------------*/
1425cc2dc46cSBarry Smith static struct _MatOps MatOps_Values = {MatSetValues_SeqBAIJ,
1426cc2dc46cSBarry Smith        MatGetRow_SeqBAIJ,
1427cc2dc46cSBarry Smith        MatRestoreRow_SeqBAIJ,
1428cc2dc46cSBarry Smith        MatMult_SeqBAIJ_N,
1429cc2dc46cSBarry Smith        MatMultAdd_SeqBAIJ_N,
14307c922b88SBarry Smith        MatMultTranspose_SeqBAIJ,
14317c922b88SBarry Smith        MatMultTransposeAdd_SeqBAIJ,
1432cc2dc46cSBarry Smith        MatSolve_SeqBAIJ_N,
1433cc2dc46cSBarry Smith        0,
1434cc2dc46cSBarry Smith        0,
1435cc2dc46cSBarry Smith        0,
1436cc2dc46cSBarry Smith        MatLUFactor_SeqBAIJ,
1437cc2dc46cSBarry Smith        0,
1438b6490206SBarry Smith        0,
1439f2501298SSatish Balay        MatTranspose_SeqBAIJ,
1440cc2dc46cSBarry Smith        MatGetInfo_SeqBAIJ,
1441cc2dc46cSBarry Smith        MatEqual_SeqBAIJ,
1442cc2dc46cSBarry Smith        MatGetDiagonal_SeqBAIJ,
1443cc2dc46cSBarry Smith        MatDiagonalScale_SeqBAIJ,
1444cc2dc46cSBarry Smith        MatNorm_SeqBAIJ,
1445b6490206SBarry Smith        0,
1446cc2dc46cSBarry Smith        MatAssemblyEnd_SeqBAIJ,
1447cc2dc46cSBarry Smith        0,
1448cc2dc46cSBarry Smith        MatSetOption_SeqBAIJ,
1449cc2dc46cSBarry Smith        MatZeroEntries_SeqBAIJ,
1450cc2dc46cSBarry Smith        MatZeroRows_SeqBAIJ,
1451cc2dc46cSBarry Smith        MatLUFactorSymbolic_SeqBAIJ,
1452cc2dc46cSBarry Smith        MatLUFactorNumeric_SeqBAIJ_N,
1453cc2dc46cSBarry Smith        0,
1454cc2dc46cSBarry Smith        0,
1455273d9f13SBarry Smith        MatSetUpPreallocation_SeqBAIJ,
1456273d9f13SBarry Smith        0,
1457cc2dc46cSBarry Smith        MatGetOwnershipRange_SeqBAIJ,
1458cc2dc46cSBarry Smith        MatILUFactorSymbolic_SeqBAIJ,
1459cc2dc46cSBarry Smith        0,
1460f2a5309cSSatish Balay        MatGetArray_SeqBAIJ,
1461f2a5309cSSatish Balay        MatRestoreArray_SeqBAIJ,
14622e8a6d31SBarry Smith        MatDuplicate_SeqBAIJ,
1463cc2dc46cSBarry Smith        0,
1464cc2dc46cSBarry Smith        0,
1465cc2dc46cSBarry Smith        MatILUFactor_SeqBAIJ,
1466cc2dc46cSBarry Smith        0,
1467cc2dc46cSBarry Smith        0,
1468cc2dc46cSBarry Smith        MatGetSubMatrices_SeqBAIJ,
1469cc2dc46cSBarry Smith        MatIncreaseOverlap_SeqBAIJ,
1470cc2dc46cSBarry Smith        MatGetValues_SeqBAIJ,
1471cc2dc46cSBarry Smith        0,
1472cc2dc46cSBarry Smith        MatPrintHelp_SeqBAIJ,
1473cc2dc46cSBarry Smith        MatScale_SeqBAIJ,
1474cc2dc46cSBarry Smith        0,
1475cc2dc46cSBarry Smith        0,
1476cc2dc46cSBarry Smith        0,
1477cc2dc46cSBarry Smith        MatGetBlockSize_SeqBAIJ,
14783b2fbd54SBarry Smith        MatGetRowIJ_SeqBAIJ,
147992c4ed94SBarry Smith        MatRestoreRowIJ_SeqBAIJ,
1480cc2dc46cSBarry Smith        0,
1481cc2dc46cSBarry Smith        0,
1482cc2dc46cSBarry Smith        0,
1483cc2dc46cSBarry Smith        0,
1484cc2dc46cSBarry Smith        0,
1485cc2dc46cSBarry Smith        0,
1486d3825aa8SBarry Smith        MatSetValuesBlocked_SeqBAIJ,
1487cc2dc46cSBarry Smith        MatGetSubMatrix_SeqBAIJ,
1488b9b97703SBarry Smith        MatDestroy_SeqBAIJ,
1489b9b97703SBarry Smith        MatView_SeqBAIJ,
1490273d9f13SBarry Smith        MatGetMaps_Petsc,
1491273d9f13SBarry Smith        0,
1492273d9f13SBarry Smith        0,
1493273d9f13SBarry Smith        0,
1494273d9f13SBarry Smith        0,
1495273d9f13SBarry Smith        0,
1496273d9f13SBarry Smith        0,
1497273d9f13SBarry Smith        MatGetRowMax_SeqBAIJ,
1498273d9f13SBarry Smith        MatConvert_Basic};
14992593348eSBarry Smith 
15003e90b805SBarry Smith EXTERN_C_BEGIN
15014a2ae208SSatish Balay #undef __FUNCT__
15024a2ae208SSatish Balay #define __FUNCT__ "MatStoreValues_SeqBAIJ"
15033e90b805SBarry Smith int MatStoreValues_SeqBAIJ(Mat mat)
15043e90b805SBarry Smith {
15053e90b805SBarry Smith   Mat_SeqBAIJ *aij = (Mat_SeqBAIJ *)mat->data;
1506273d9f13SBarry Smith   int         nz = aij->i[mat->m]*aij->bs*aij->bs2;
1507d132466eSBarry Smith   int         ierr;
15083e90b805SBarry Smith 
15093e90b805SBarry Smith   PetscFunctionBegin;
15103e90b805SBarry Smith   if (aij->nonew != 1) {
151129bbc08cSBarry Smith     SETERRQ(1,"Must call MatSetOption(A,MAT_NO_NEW_NONZERO_LOCATIONS);first");
15123e90b805SBarry Smith   }
15133e90b805SBarry Smith 
15143e90b805SBarry Smith   /* allocate space for values if not already there */
15153e90b805SBarry Smith   if (!aij->saved_values) {
1516f2a5309cSSatish Balay     ierr = PetscMalloc((nz+1)*sizeof(Scalar),&aij->saved_values);CHKERRQ(ierr);
15173e90b805SBarry Smith   }
15183e90b805SBarry Smith 
15193e90b805SBarry Smith   /* copy values over */
1520d132466eSBarry Smith   ierr = PetscMemcpy(aij->saved_values,aij->a,nz*sizeof(Scalar));CHKERRQ(ierr);
15213e90b805SBarry Smith   PetscFunctionReturn(0);
15223e90b805SBarry Smith }
15233e90b805SBarry Smith EXTERN_C_END
15243e90b805SBarry Smith 
15253e90b805SBarry Smith EXTERN_C_BEGIN
15264a2ae208SSatish Balay #undef __FUNCT__
15274a2ae208SSatish Balay #define __FUNCT__ "MatRetrieveValues_SeqBAIJ"
152832e87ba3SBarry Smith int MatRetrieveValues_SeqBAIJ(Mat mat)
15293e90b805SBarry Smith {
15303e90b805SBarry Smith   Mat_SeqBAIJ *aij = (Mat_SeqBAIJ *)mat->data;
1531273d9f13SBarry Smith   int         nz = aij->i[mat->m]*aij->bs*aij->bs2,ierr;
15323e90b805SBarry Smith 
15333e90b805SBarry Smith   PetscFunctionBegin;
15343e90b805SBarry Smith   if (aij->nonew != 1) {
153529bbc08cSBarry Smith     SETERRQ(1,"Must call MatSetOption(A,MAT_NO_NEW_NONZERO_LOCATIONS);first");
15363e90b805SBarry Smith   }
15373e90b805SBarry Smith   if (!aij->saved_values) {
153829bbc08cSBarry Smith     SETERRQ(1,"Must call MatStoreValues(A);first");
15393e90b805SBarry Smith   }
15403e90b805SBarry Smith 
15413e90b805SBarry Smith   /* copy values over */
1542549d3d68SSatish Balay   ierr = PetscMemcpy(aij->a,aij->saved_values,nz*sizeof(Scalar));CHKERRQ(ierr);
15433e90b805SBarry Smith   PetscFunctionReturn(0);
15443e90b805SBarry Smith }
15453e90b805SBarry Smith EXTERN_C_END
15463e90b805SBarry Smith 
1547273d9f13SBarry Smith EXTERN_C_BEGIN
1548273d9f13SBarry Smith extern int MatConvert_SeqBAIJ_SeqAIJ(Mat,MatType,Mat*);
1549273d9f13SBarry Smith EXTERN_C_END
1550273d9f13SBarry Smith 
1551273d9f13SBarry Smith EXTERN_C_BEGIN
15524a2ae208SSatish Balay #undef __FUNCT__
15534a2ae208SSatish Balay #define __FUNCT__ "MatCreate_SeqBAIJ"
1554273d9f13SBarry Smith int MatCreate_SeqBAIJ(Mat B)
15552593348eSBarry Smith {
1556273d9f13SBarry Smith   int         ierr,size;
1557b6490206SBarry Smith   Mat_SeqBAIJ *b;
15583b2fbd54SBarry Smith 
15593a40ed3dSBarry Smith   PetscFunctionBegin;
1560273d9f13SBarry Smith   ierr = MPI_Comm_size(B->comm,&size);CHKERRQ(ierr);
156129bbc08cSBarry Smith   if (size > 1) SETERRQ(PETSC_ERR_ARG_WRONG,"Comm must be of size 1");
1562b6490206SBarry Smith 
1563273d9f13SBarry Smith   B->m = B->M = PetscMax(B->m,B->M);
1564273d9f13SBarry Smith   B->n = B->N = PetscMax(B->n,B->N);
1565b0a32e0cSBarry Smith   ierr    = PetscNew(Mat_SeqBAIJ,&b);CHKERRQ(ierr);
1566b0a32e0cSBarry Smith   B->data = (void*)b;
1567549d3d68SSatish Balay   ierr    = PetscMemzero(b,sizeof(Mat_SeqBAIJ));CHKERRQ(ierr);
1568549d3d68SSatish Balay   ierr    = PetscMemcpy(B->ops,&MatOps_Values,sizeof(struct _MatOps));CHKERRQ(ierr);
15692593348eSBarry Smith   B->factor           = 0;
15702593348eSBarry Smith   B->lupivotthreshold = 1.0;
157190f02eecSBarry Smith   B->mapping          = 0;
15722593348eSBarry Smith   b->row              = 0;
15732593348eSBarry Smith   b->col              = 0;
1574e51c0b9cSSatish Balay   b->icol             = 0;
15752593348eSBarry Smith   b->reallocs         = 0;
15763e90b805SBarry Smith   b->saved_values     = 0;
1577cfce73b9SSatish Balay #if defined(PETSC_USE_MAT_SINGLE)
1578563b5814SBarry Smith   b->setvalueslen     = 0;
1579563b5814SBarry Smith   b->setvaluescopy    = PETSC_NULL;
1580563b5814SBarry Smith #endif
15812593348eSBarry Smith 
1582273d9f13SBarry Smith   ierr = MapCreateMPI(B->comm,B->m,B->m,&B->rmap);CHKERRQ(ierr);
1583273d9f13SBarry Smith   ierr = MapCreateMPI(B->comm,B->n,B->n,&B->cmap);CHKERRQ(ierr);
1584a5ae1ecdSBarry Smith 
1585c4992f7dSBarry Smith   b->sorted           = PETSC_FALSE;
1586c4992f7dSBarry Smith   b->roworiented      = PETSC_TRUE;
15872593348eSBarry Smith   b->nonew            = 0;
15882593348eSBarry Smith   b->diag             = 0;
15892593348eSBarry Smith   b->solve_work       = 0;
1590de6a44a3SBarry Smith   b->mult_work        = 0;
15912593348eSBarry Smith   b->spptr            = 0;
15920e6d2581SBarry Smith   B->info.nz_unneeded = (PetscReal)b->maxnz;
1593883fce79SBarry Smith   b->keepzeroedrows   = PETSC_FALSE;
15944e220ebcSLois Curfman McInnes 
1595f1af5d2fSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatStoreValues_C",
15963e90b805SBarry Smith                                      "MatStoreValues_SeqBAIJ",
1597bc4b532fSSatish Balay                                       MatStoreValues_SeqBAIJ);CHKERRQ(ierr);
1598f1af5d2fSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatRetrieveValues_C",
15993e90b805SBarry Smith                                      "MatRetrieveValues_SeqBAIJ",
1600bc4b532fSSatish Balay                                       MatRetrieveValues_SeqBAIJ);CHKERRQ(ierr);
1601f1af5d2fSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatSeqBAIJSetColumnIndices_C",
160227a8da17SBarry Smith                                      "MatSeqBAIJSetColumnIndices_SeqBAIJ",
1603bc4b532fSSatish Balay                                       MatSeqBAIJSetColumnIndices_SeqBAIJ);CHKERRQ(ierr);
1604273d9f13SBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatConvert_SeqBAIJ_SeqAIJ_C",
1605273d9f13SBarry Smith                                      "MatConvert_SeqBAIJ_SeqAIJ",
1606273d9f13SBarry Smith                                       MatConvert_SeqBAIJ_SeqAIJ);CHKERRQ(ierr);
16073a40ed3dSBarry Smith   PetscFunctionReturn(0);
16082593348eSBarry Smith }
1609273d9f13SBarry Smith EXTERN_C_END
16102593348eSBarry Smith 
16114a2ae208SSatish Balay #undef __FUNCT__
16124a2ae208SSatish Balay #define __FUNCT__ "MatDuplicate_SeqBAIJ"
16132e8a6d31SBarry Smith int MatDuplicate_SeqBAIJ(Mat A,MatDuplicateOption cpvalues,Mat *B)
16142593348eSBarry Smith {
16152593348eSBarry Smith   Mat         C;
1616b6490206SBarry Smith   Mat_SeqBAIJ *c,*a = (Mat_SeqBAIJ*)A->data;
161727a8da17SBarry Smith   int         i,len,mbs = a->mbs,nz = a->nz,bs2 =a->bs2,ierr;
1618de6a44a3SBarry Smith 
16193a40ed3dSBarry Smith   PetscFunctionBegin;
162029bbc08cSBarry Smith   if (a->i[mbs] != nz) SETERRQ(PETSC_ERR_PLIB,"Corrupt matrix");
16212593348eSBarry Smith 
16222593348eSBarry Smith   *B = 0;
1623273d9f13SBarry Smith   ierr = MatCreate(A->comm,A->m,A->n,A->m,A->n,&C);CHKERRQ(ierr);
1624273d9f13SBarry Smith   ierr = MatSetType(C,MATSEQBAIJ);CHKERRQ(ierr);
1625273d9f13SBarry Smith   c    = (Mat_SeqBAIJ*)C->data;
162644cd7ae7SLois Curfman McInnes 
1627b6490206SBarry Smith   c->bs         = a->bs;
16289df24120SSatish Balay   c->bs2        = a->bs2;
1629b6490206SBarry Smith   c->mbs        = a->mbs;
1630b6490206SBarry Smith   c->nbs        = a->nbs;
163135d8aa7fSBarry Smith   ierr = PetscMemcpy(C->ops,A->ops,sizeof(struct _MatOps));CHKERRQ(ierr);
16322593348eSBarry Smith 
1633b0a32e0cSBarry Smith   ierr = PetscMalloc((mbs+1)*sizeof(int),&c->imax);CHKERRQ(ierr);
1634b0a32e0cSBarry Smith   ierr = PetscMalloc((mbs+1)*sizeof(int),&c->ilen);CHKERRQ(ierr);
1635b6490206SBarry Smith   for (i=0; i<mbs; i++) {
16362593348eSBarry Smith     c->imax[i] = a->imax[i];
16372593348eSBarry Smith     c->ilen[i] = a->ilen[i];
16382593348eSBarry Smith   }
16392593348eSBarry Smith 
16402593348eSBarry Smith   /* allocate the matrix space */
1641c4992f7dSBarry Smith   c->singlemalloc = PETSC_TRUE;
16423f1db9ecSBarry Smith   len  = (mbs+1)*sizeof(int) + nz*(bs2*sizeof(MatScalar) + sizeof(int));
1643b0a32e0cSBarry Smith   ierr = PetscMalloc(len,&c->a);CHKERRQ(ierr);
16447e67e3f9SSatish Balay   c->j = (int*)(c->a + nz*bs2);
1645de6a44a3SBarry Smith   c->i = c->j + nz;
1646549d3d68SSatish Balay   ierr = PetscMemcpy(c->i,a->i,(mbs+1)*sizeof(int));CHKERRQ(ierr);
1647b6490206SBarry Smith   if (mbs > 0) {
1648549d3d68SSatish Balay     ierr = PetscMemcpy(c->j,a->j,nz*sizeof(int));CHKERRQ(ierr);
16492e8a6d31SBarry Smith     if (cpvalues == MAT_COPY_VALUES) {
1650549d3d68SSatish Balay       ierr = PetscMemcpy(c->a,a->a,bs2*nz*sizeof(MatScalar));CHKERRQ(ierr);
16512e8a6d31SBarry Smith     } else {
1652549d3d68SSatish Balay       ierr = PetscMemzero(c->a,bs2*nz*sizeof(MatScalar));CHKERRQ(ierr);
16532593348eSBarry Smith     }
16542593348eSBarry Smith   }
16552593348eSBarry Smith 
1656b0a32e0cSBarry Smith   PetscLogObjectMemory(C,len+2*(mbs+1)*sizeof(int)+sizeof(struct _p_Mat)+sizeof(Mat_SeqBAIJ));
16572593348eSBarry Smith   c->sorted      = a->sorted;
16582593348eSBarry Smith   c->roworiented = a->roworiented;
16592593348eSBarry Smith   c->nonew       = a->nonew;
16602593348eSBarry Smith 
16612593348eSBarry Smith   if (a->diag) {
1662b0a32e0cSBarry Smith     ierr = PetscMalloc((mbs+1)*sizeof(int),&c->diag);CHKERRQ(ierr);
1663b0a32e0cSBarry Smith     PetscLogObjectMemory(C,(mbs+1)*sizeof(int));
1664b6490206SBarry Smith     for (i=0; i<mbs; i++) {
16652593348eSBarry Smith       c->diag[i] = a->diag[i];
16662593348eSBarry Smith     }
166798305bb5SBarry Smith   } else c->diag        = 0;
16682593348eSBarry Smith   c->nz                 = a->nz;
16692593348eSBarry Smith   c->maxnz              = a->maxnz;
16702593348eSBarry Smith   c->solve_work         = 0;
16712593348eSBarry Smith   c->spptr              = 0;      /* Dangerous -I'm throwing away a->spptr */
16727fc0212eSBarry Smith   c->mult_work          = 0;
1673273d9f13SBarry Smith   C->preallocated       = PETSC_TRUE;
1674273d9f13SBarry Smith   C->assembled          = PETSC_TRUE;
16752593348eSBarry Smith   *B = C;
1676b0a32e0cSBarry Smith   ierr = PetscFListDuplicate(A->qlist,&C->qlist);CHKERRQ(ierr);
16773a40ed3dSBarry Smith   PetscFunctionReturn(0);
16782593348eSBarry Smith }
16792593348eSBarry Smith 
1680273d9f13SBarry Smith EXTERN_C_BEGIN
16814a2ae208SSatish Balay #undef __FUNCT__
16824a2ae208SSatish Balay #define __FUNCT__ "MatLoad_SeqBAIJ"
1683b0a32e0cSBarry Smith int MatLoad_SeqBAIJ(PetscViewer viewer,MatType type,Mat *A)
16842593348eSBarry Smith {
1685b6490206SBarry Smith   Mat_SeqBAIJ  *a;
16862593348eSBarry Smith   Mat          B;
1687f1af5d2fSBarry Smith   int          i,nz,ierr,fd,header[4],size,*rowlengths=0,M,N,bs=1;
1688b6490206SBarry Smith   int          *mask,mbs,*jj,j,rowcount,nzcount,k,*browlengths,maskcount;
168935aab85fSBarry Smith   int          kmax,jcount,block,idx,point,nzcountb,extra_rows;
1690a7c10996SSatish Balay   int          *masked,nmask,tmp,bs2,ishift;
1691b6490206SBarry Smith   Scalar       *aa;
169219bcc07fSBarry Smith   MPI_Comm     comm = ((PetscObject)viewer)->comm;
16932593348eSBarry Smith 
16943a40ed3dSBarry Smith   PetscFunctionBegin;
1695b0a32e0cSBarry Smith   ierr = PetscOptionsGetInt(PETSC_NULL,"-matload_block_size",&bs,PETSC_NULL);CHKERRQ(ierr);
1696de6a44a3SBarry Smith   bs2  = bs*bs;
1697b6490206SBarry Smith 
1698d132466eSBarry Smith   ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr);
169929bbc08cSBarry Smith   if (size > 1) SETERRQ(PETSC_ERR_ARG_WRONG,"view must have one processor");
1700b0a32e0cSBarry Smith   ierr = PetscViewerBinaryGetDescriptor(viewer,&fd);CHKERRQ(ierr);
17010752156aSBarry Smith   ierr = PetscBinaryRead(fd,header,4,PETSC_INT);CHKERRQ(ierr);
170229bbc08cSBarry Smith   if (header[0] != MAT_COOKIE) SETERRQ(PETSC_ERR_FILE_UNEXPECTED,"not Mat object");
17032593348eSBarry Smith   M = header[1]; N = header[2]; nz = header[3];
17042593348eSBarry Smith 
1705d64ed03dSBarry Smith   if (header[3] < 0) {
170629bbc08cSBarry Smith     SETERRQ(PETSC_ERR_FILE_UNEXPECTED,"Matrix stored in special format, cannot load as SeqBAIJ");
1707d64ed03dSBarry Smith   }
1708d64ed03dSBarry Smith 
170929bbc08cSBarry Smith   if (M != N) SETERRQ(PETSC_ERR_SUP,"Can only do square matrices");
171035aab85fSBarry Smith 
171135aab85fSBarry Smith   /*
171235aab85fSBarry Smith      This code adds extra rows to make sure the number of rows is
171335aab85fSBarry Smith     divisible by the blocksize
171435aab85fSBarry Smith   */
1715b6490206SBarry Smith   mbs        = M/bs;
171635aab85fSBarry Smith   extra_rows = bs - M + bs*(mbs);
171735aab85fSBarry Smith   if (extra_rows == bs) extra_rows = 0;
171835aab85fSBarry Smith   else                  mbs++;
171935aab85fSBarry Smith   if (extra_rows) {
1720b0a32e0cSBarry Smith     PetscLogInfo(0,"MatLoad_SeqBAIJ:Padding loaded matrix to match blocksize\n");
172135aab85fSBarry Smith   }
1722b6490206SBarry Smith 
17232593348eSBarry Smith   /* read in row lengths */
1724b0a32e0cSBarry Smith   ierr = PetscMalloc((M+extra_rows)*sizeof(int),&rowlengths);CHKERRQ(ierr);
17250752156aSBarry Smith   ierr = PetscBinaryRead(fd,rowlengths,M,PETSC_INT);CHKERRQ(ierr);
172635aab85fSBarry Smith   for (i=0; i<extra_rows; i++) rowlengths[M+i] = 1;
17272593348eSBarry Smith 
1728b6490206SBarry Smith   /* read in column indices */
1729b0a32e0cSBarry Smith   ierr = PetscMalloc((nz+extra_rows)*sizeof(int),&jj);CHKERRQ(ierr);
17300752156aSBarry Smith   ierr = PetscBinaryRead(fd,jj,nz,PETSC_INT);CHKERRQ(ierr);
173135aab85fSBarry Smith   for (i=0; i<extra_rows; i++) jj[nz+i] = M+i;
1732b6490206SBarry Smith 
1733b6490206SBarry Smith   /* loop over row lengths determining block row lengths */
1734b0a32e0cSBarry Smith   ierr     = PetscMalloc(mbs*sizeof(int),&browlengths);CHKERRQ(ierr);
1735549d3d68SSatish Balay   ierr     = PetscMemzero(browlengths,mbs*sizeof(int));CHKERRQ(ierr);
1736b0a32e0cSBarry Smith   ierr     = PetscMalloc(2*mbs*sizeof(int),&mask);CHKERRQ(ierr);
1737549d3d68SSatish Balay   ierr     = PetscMemzero(mask,mbs*sizeof(int));CHKERRQ(ierr);
173835aab85fSBarry Smith   masked   = mask + mbs;
1739b6490206SBarry Smith   rowcount = 0; nzcount = 0;
1740b6490206SBarry Smith   for (i=0; i<mbs; i++) {
174135aab85fSBarry Smith     nmask = 0;
1742b6490206SBarry Smith     for (j=0; j<bs; j++) {
1743b6490206SBarry Smith       kmax = rowlengths[rowcount];
1744b6490206SBarry Smith       for (k=0; k<kmax; k++) {
174535aab85fSBarry Smith         tmp = jj[nzcount++]/bs;
174635aab85fSBarry Smith         if (!mask[tmp]) {masked[nmask++] = tmp; mask[tmp] = 1;}
1747b6490206SBarry Smith       }
1748b6490206SBarry Smith       rowcount++;
1749b6490206SBarry Smith     }
175035aab85fSBarry Smith     browlengths[i] += nmask;
175135aab85fSBarry Smith     /* zero out the mask elements we set */
175235aab85fSBarry Smith     for (j=0; j<nmask; j++) mask[masked[j]] = 0;
1753b6490206SBarry Smith   }
1754b6490206SBarry Smith 
17552593348eSBarry Smith   /* create our matrix */
17563eee16b0SBarry Smith   ierr = MatCreateSeqBAIJ(comm,bs,M+extra_rows,N+extra_rows,0,browlengths,A);CHKERRQ(ierr);
17572593348eSBarry Smith   B = *A;
1758b6490206SBarry Smith   a = (Mat_SeqBAIJ*)B->data;
17592593348eSBarry Smith 
17602593348eSBarry Smith   /* set matrix "i" values */
1761de6a44a3SBarry Smith   a->i[0] = 0;
1762b6490206SBarry Smith   for (i=1; i<= mbs; i++) {
1763b6490206SBarry Smith     a->i[i]      = a->i[i-1] + browlengths[i-1];
1764b6490206SBarry Smith     a->ilen[i-1] = browlengths[i-1];
17652593348eSBarry Smith   }
1766b6490206SBarry Smith   a->nz         = 0;
1767b6490206SBarry Smith   for (i=0; i<mbs; i++) a->nz += browlengths[i];
17682593348eSBarry Smith 
1769b6490206SBarry Smith   /* read in nonzero values */
1770b0a32e0cSBarry Smith   ierr = PetscMalloc((nz+extra_rows)*sizeof(Scalar),&aa);CHKERRQ(ierr);
17710752156aSBarry Smith   ierr = PetscBinaryRead(fd,aa,nz,PETSC_SCALAR);CHKERRQ(ierr);
177235aab85fSBarry Smith   for (i=0; i<extra_rows; i++) aa[nz+i] = 1.0;
1773b6490206SBarry Smith 
1774b6490206SBarry Smith   /* set "a" and "j" values into matrix */
1775b6490206SBarry Smith   nzcount = 0; jcount = 0;
1776b6490206SBarry Smith   for (i=0; i<mbs; i++) {
1777b6490206SBarry Smith     nzcountb = nzcount;
177835aab85fSBarry Smith     nmask    = 0;
1779b6490206SBarry Smith     for (j=0; j<bs; j++) {
1780b6490206SBarry Smith       kmax = rowlengths[i*bs+j];
1781b6490206SBarry Smith       for (k=0; k<kmax; k++) {
178235aab85fSBarry Smith         tmp = jj[nzcount++]/bs;
178335aab85fSBarry Smith 	if (!mask[tmp]) { masked[nmask++] = tmp; mask[tmp] = 1;}
1784b6490206SBarry Smith       }
1785b6490206SBarry Smith     }
1786de6a44a3SBarry Smith     /* sort the masked values */
1787433994e6SBarry Smith     ierr = PetscSortInt(nmask,masked);CHKERRQ(ierr);
1788de6a44a3SBarry Smith 
1789b6490206SBarry Smith     /* set "j" values into matrix */
1790b6490206SBarry Smith     maskcount = 1;
179135aab85fSBarry Smith     for (j=0; j<nmask; j++) {
179235aab85fSBarry Smith       a->j[jcount++]  = masked[j];
1793de6a44a3SBarry Smith       mask[masked[j]] = maskcount++;
1794b6490206SBarry Smith     }
1795b6490206SBarry Smith     /* set "a" values into matrix */
1796de6a44a3SBarry Smith     ishift = bs2*a->i[i];
1797b6490206SBarry Smith     for (j=0; j<bs; j++) {
1798b6490206SBarry Smith       kmax = rowlengths[i*bs+j];
1799b6490206SBarry Smith       for (k=0; k<kmax; k++) {
1800de6a44a3SBarry Smith         tmp       = jj[nzcountb]/bs ;
1801de6a44a3SBarry Smith         block     = mask[tmp] - 1;
1802de6a44a3SBarry Smith         point     = jj[nzcountb] - bs*tmp;
1803de6a44a3SBarry Smith         idx       = ishift + bs2*block + j + bs*point;
1804375fe846SBarry Smith         a->a[idx] = (MatScalar)aa[nzcountb++];
1805b6490206SBarry Smith       }
1806b6490206SBarry Smith     }
180735aab85fSBarry Smith     /* zero out the mask elements we set */
180835aab85fSBarry Smith     for (j=0; j<nmask; j++) mask[masked[j]] = 0;
1809b6490206SBarry Smith   }
181029bbc08cSBarry Smith   if (jcount != a->nz) SETERRQ(PETSC_ERR_FILE_UNEXPECTED,"Bad binary matrix");
1811b6490206SBarry Smith 
1812606d414cSSatish Balay   ierr = PetscFree(rowlengths);CHKERRQ(ierr);
1813606d414cSSatish Balay   ierr = PetscFree(browlengths);CHKERRQ(ierr);
1814606d414cSSatish Balay   ierr = PetscFree(aa);CHKERRQ(ierr);
1815606d414cSSatish Balay   ierr = PetscFree(jj);CHKERRQ(ierr);
1816606d414cSSatish Balay   ierr = PetscFree(mask);CHKERRQ(ierr);
1817b6490206SBarry Smith 
1818b6490206SBarry Smith   B->assembled = PETSC_TRUE;
1819de6a44a3SBarry Smith 
18209c01be13SBarry Smith   ierr = MatView_Private(B);CHKERRQ(ierr);
18213a40ed3dSBarry Smith   PetscFunctionReturn(0);
18222593348eSBarry Smith }
1823273d9f13SBarry Smith EXTERN_C_END
18242593348eSBarry Smith 
18254a2ae208SSatish Balay #undef __FUNCT__
18264a2ae208SSatish Balay #define __FUNCT__ "MatCreateSeqBAIJ"
1827273d9f13SBarry Smith /*@C
1828273d9f13SBarry Smith    MatCreateSeqBAIJ - Creates a sparse matrix in block AIJ (block
1829273d9f13SBarry Smith    compressed row) format.  For good matrix assembly performance the
1830273d9f13SBarry Smith    user should preallocate the matrix storage by setting the parameter nz
1831273d9f13SBarry Smith    (or the array nnz).  By setting these parameters accurately, performance
1832273d9f13SBarry Smith    during matrix assembly can be increased by more than a factor of 50.
18332593348eSBarry Smith 
1834273d9f13SBarry Smith    Collective on MPI_Comm
1835273d9f13SBarry Smith 
1836273d9f13SBarry Smith    Input Parameters:
1837273d9f13SBarry Smith +  comm - MPI communicator, set to PETSC_COMM_SELF
1838273d9f13SBarry Smith .  bs - size of block
1839273d9f13SBarry Smith .  m - number of rows
1840273d9f13SBarry Smith .  n - number of columns
184135d8aa7fSBarry Smith .  nz - number of nonzero blocks  per block row (same for all rows)
184235d8aa7fSBarry Smith -  nnz - array containing the number of nonzero blocks in the various block rows
1843273d9f13SBarry Smith          (possibly different for each block row) or PETSC_NULL
1844273d9f13SBarry Smith 
1845273d9f13SBarry Smith    Output Parameter:
1846273d9f13SBarry Smith .  A - the matrix
1847273d9f13SBarry Smith 
1848273d9f13SBarry Smith    Options Database Keys:
1849273d9f13SBarry Smith .   -mat_no_unroll - uses code that does not unroll the loops in the
1850273d9f13SBarry Smith                      block calculations (much slower)
1851273d9f13SBarry Smith .    -mat_block_size - size of the blocks to use
1852273d9f13SBarry Smith 
1853273d9f13SBarry Smith    Level: intermediate
1854273d9f13SBarry Smith 
1855273d9f13SBarry Smith    Notes:
185635d8aa7fSBarry Smith    A nonzero block is any block that as 1 or more nonzeros in it
185735d8aa7fSBarry Smith 
1858273d9f13SBarry Smith    The block AIJ format is fully compatible with standard Fortran 77
1859273d9f13SBarry Smith    storage.  That is, the stored row and column indices can begin at
1860273d9f13SBarry Smith    either one (as in Fortran) or zero.  See the users' manual for details.
1861273d9f13SBarry Smith 
1862273d9f13SBarry Smith    Specify the preallocated storage with either nz or nnz (not both).
1863273d9f13SBarry Smith    Set nz=PETSC_DEFAULT and nnz=PETSC_NULL for PETSc to control dynamic memory
1864273d9f13SBarry Smith    allocation.  For additional details, see the users manual chapter on
1865273d9f13SBarry Smith    matrices.
1866273d9f13SBarry Smith 
1867273d9f13SBarry Smith .seealso: MatCreate(), MatCreateSeqAIJ(), MatSetValues(), MatCreateMPIBAIJ()
1868273d9f13SBarry Smith @*/
1869273d9f13SBarry Smith int MatCreateSeqBAIJ(MPI_Comm comm,int bs,int m,int n,int nz,int *nnz,Mat *A)
1870273d9f13SBarry Smith {
1871273d9f13SBarry Smith   int ierr;
1872273d9f13SBarry Smith 
1873273d9f13SBarry Smith   PetscFunctionBegin;
1874273d9f13SBarry Smith   ierr = MatCreate(comm,m,n,m,n,A);CHKERRQ(ierr);
1875273d9f13SBarry Smith   ierr = MatSetType(*A,MATSEQBAIJ);CHKERRQ(ierr);
1876273d9f13SBarry Smith   ierr = MatSeqBAIJSetPreallocation(*A,bs,nz,nnz);CHKERRQ(ierr);
1877273d9f13SBarry Smith   PetscFunctionReturn(0);
1878273d9f13SBarry Smith }
1879273d9f13SBarry Smith 
18804a2ae208SSatish Balay #undef __FUNCT__
18814a2ae208SSatish Balay #define __FUNCT__ "MatSeqBAIJSetPreallocation"
1882273d9f13SBarry Smith /*@C
1883273d9f13SBarry Smith    MatSeqBAIJSetPreallocation - Sets the block size and expected nonzeros
1884273d9f13SBarry Smith    per row in the matrix. For good matrix assembly performance the
1885273d9f13SBarry Smith    user should preallocate the matrix storage by setting the parameter nz
1886273d9f13SBarry Smith    (or the array nnz).  By setting these parameters accurately, performance
1887273d9f13SBarry Smith    during matrix assembly can be increased by more than a factor of 50.
1888273d9f13SBarry Smith 
1889273d9f13SBarry Smith    Collective on MPI_Comm
1890273d9f13SBarry Smith 
1891273d9f13SBarry Smith    Input Parameters:
1892273d9f13SBarry Smith +  A - the matrix
1893273d9f13SBarry Smith .  bs - size of block
1894273d9f13SBarry Smith .  nz - number of block nonzeros per block row (same for all rows)
1895273d9f13SBarry Smith -  nnz - array containing the number of block nonzeros in the various block rows
1896273d9f13SBarry Smith          (possibly different for each block row) or PETSC_NULL
1897273d9f13SBarry Smith 
1898273d9f13SBarry Smith    Options Database Keys:
1899273d9f13SBarry Smith .   -mat_no_unroll - uses code that does not unroll the loops in the
1900273d9f13SBarry Smith                      block calculations (much slower)
1901273d9f13SBarry Smith .    -mat_block_size - size of the blocks to use
1902273d9f13SBarry Smith 
1903273d9f13SBarry Smith    Level: intermediate
1904273d9f13SBarry Smith 
1905273d9f13SBarry Smith    Notes:
1906273d9f13SBarry Smith    The block AIJ format is fully compatible with standard Fortran 77
1907273d9f13SBarry Smith    storage.  That is, the stored row and column indices can begin at
1908273d9f13SBarry Smith    either one (as in Fortran) or zero.  See the users' manual for details.
1909273d9f13SBarry Smith 
1910273d9f13SBarry Smith    Specify the preallocated storage with either nz or nnz (not both).
1911273d9f13SBarry Smith    Set nz=PETSC_DEFAULT and nnz=PETSC_NULL for PETSc to control dynamic memory
1912273d9f13SBarry Smith    allocation.  For additional details, see the users manual chapter on
1913273d9f13SBarry Smith    matrices.
1914273d9f13SBarry Smith 
1915273d9f13SBarry Smith .seealso: MatCreate(), MatCreateSeqAIJ(), MatSetValues(), MatCreateMPIBAIJ()
1916273d9f13SBarry Smith @*/
1917273d9f13SBarry Smith int MatSeqBAIJSetPreallocation(Mat B,int bs,int nz,int *nnz)
1918273d9f13SBarry Smith {
1919273d9f13SBarry Smith   Mat_SeqBAIJ *b;
1920273d9f13SBarry Smith   int         i,len,ierr,mbs,nbs,bs2,newbs = bs;
1921273d9f13SBarry Smith   PetscTruth  flg;
1922273d9f13SBarry Smith 
1923273d9f13SBarry Smith   PetscFunctionBegin;
1924273d9f13SBarry Smith   ierr = PetscTypeCompare((PetscObject)B,MATSEQBAIJ,&flg);CHKERRQ(ierr);
1925273d9f13SBarry Smith   if (!flg) PetscFunctionReturn(0);
1926273d9f13SBarry Smith 
1927273d9f13SBarry Smith   B->preallocated = PETSC_TRUE;
1928b0a32e0cSBarry Smith   ierr = PetscOptionsGetInt(B->prefix,"-mat_block_size",&newbs,PETSC_NULL);CHKERRQ(ierr);
1929273d9f13SBarry Smith   if (nnz && newbs != bs) {
1930273d9f13SBarry Smith     SETERRQ(1,"Cannot change blocksize from command line if setting nnz");
1931273d9f13SBarry Smith   }
1932273d9f13SBarry Smith   bs   = newbs;
1933273d9f13SBarry Smith 
1934273d9f13SBarry Smith   mbs  = B->m/bs;
1935273d9f13SBarry Smith   nbs  = B->n/bs;
1936273d9f13SBarry Smith   bs2  = bs*bs;
1937273d9f13SBarry Smith 
1938273d9f13SBarry Smith   if (mbs*bs!=B->m || nbs*bs!=B->n) {
193935d8aa7fSBarry Smith     SETERRQ3(PETSC_ERR_ARG_SIZ,"Number rows %d, cols %d must be divisible by blocksize %d",B->m,B->n,bs);
1940273d9f13SBarry Smith   }
1941273d9f13SBarry Smith 
1942435da068SBarry Smith   if (nz == PETSC_DEFAULT || nz == PETSC_DECIDE) nz = 5;
1943435da068SBarry Smith   if (nz < 0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"nz cannot be less than 0: value %d",nz);
1944273d9f13SBarry Smith   if (nnz) {
1945273d9f13SBarry Smith     for (i=0; i<mbs; i++) {
1946273d9f13SBarry Smith       if (nnz[i] < 0) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"nnz cannot be less than 0: local row %d value %d",i,nnz[i]);
19473a7fca6bSBarry 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);
1948273d9f13SBarry Smith     }
1949273d9f13SBarry Smith   }
1950273d9f13SBarry Smith 
1951273d9f13SBarry Smith   b       = (Mat_SeqBAIJ*)B->data;
1952b0a32e0cSBarry Smith   ierr    = PetscOptionsHasName(PETSC_NULL,"-mat_no_unroll",&flg);CHKERRQ(ierr);
1953273d9f13SBarry Smith   if (!flg) {
1954273d9f13SBarry Smith     switch (bs) {
1955273d9f13SBarry Smith     case 1:
1956273d9f13SBarry Smith       B->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_1;
1957273d9f13SBarry Smith       B->ops->solve           = MatSolve_SeqBAIJ_1;
1958273d9f13SBarry Smith       B->ops->solvetranspose  = MatSolveTranspose_SeqBAIJ_1;
1959273d9f13SBarry Smith       B->ops->mult            = MatMult_SeqBAIJ_1;
1960273d9f13SBarry Smith       B->ops->multadd         = MatMultAdd_SeqBAIJ_1;
1961273d9f13SBarry Smith       break;
1962273d9f13SBarry Smith     case 2:
1963273d9f13SBarry Smith       B->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_2;
1964273d9f13SBarry Smith       B->ops->solve           = MatSolve_SeqBAIJ_2;
1965273d9f13SBarry Smith       B->ops->solvetranspose  = MatSolveTranspose_SeqBAIJ_2;
1966273d9f13SBarry Smith       B->ops->mult            = MatMult_SeqBAIJ_2;
1967273d9f13SBarry Smith       B->ops->multadd         = MatMultAdd_SeqBAIJ_2;
1968273d9f13SBarry Smith       break;
1969273d9f13SBarry Smith     case 3:
1970273d9f13SBarry Smith       B->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_3;
1971273d9f13SBarry Smith       B->ops->solve           = MatSolve_SeqBAIJ_3;
1972273d9f13SBarry Smith       B->ops->solvetranspose  = MatSolveTranspose_SeqBAIJ_3;
1973273d9f13SBarry Smith       B->ops->mult            = MatMult_SeqBAIJ_3;
1974273d9f13SBarry Smith       B->ops->multadd         = MatMultAdd_SeqBAIJ_3;
1975273d9f13SBarry Smith       break;
1976273d9f13SBarry Smith     case 4:
1977273d9f13SBarry Smith       B->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_4;
1978273d9f13SBarry Smith       B->ops->solve           = MatSolve_SeqBAIJ_4;
1979273d9f13SBarry Smith       B->ops->solvetranspose  = MatSolveTranspose_SeqBAIJ_4;
1980273d9f13SBarry Smith       B->ops->mult            = MatMult_SeqBAIJ_4;
1981273d9f13SBarry Smith       B->ops->multadd         = MatMultAdd_SeqBAIJ_4;
1982273d9f13SBarry Smith       break;
1983273d9f13SBarry Smith     case 5:
1984273d9f13SBarry Smith       B->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_5;
1985273d9f13SBarry Smith       B->ops->solve           = MatSolve_SeqBAIJ_5;
1986273d9f13SBarry Smith       B->ops->solvetranspose  = MatSolveTranspose_SeqBAIJ_5;
1987273d9f13SBarry Smith       B->ops->mult            = MatMult_SeqBAIJ_5;
1988273d9f13SBarry Smith       B->ops->multadd         = MatMultAdd_SeqBAIJ_5;
1989273d9f13SBarry Smith       break;
1990273d9f13SBarry Smith     case 6:
1991273d9f13SBarry Smith       B->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_6;
1992273d9f13SBarry Smith       B->ops->solve           = MatSolve_SeqBAIJ_6;
1993273d9f13SBarry Smith       B->ops->solvetranspose  = MatSolveTranspose_SeqBAIJ_6;
1994273d9f13SBarry Smith       B->ops->mult            = MatMult_SeqBAIJ_6;
1995273d9f13SBarry Smith       B->ops->multadd         = MatMultAdd_SeqBAIJ_6;
1996273d9f13SBarry Smith       break;
1997273d9f13SBarry Smith     case 7:
1998273d9f13SBarry Smith       B->ops->mult            = MatMult_SeqBAIJ_7;
1999273d9f13SBarry Smith       B->ops->solve           = MatSolve_SeqBAIJ_7;
2000273d9f13SBarry Smith       B->ops->solvetranspose  = MatSolveTranspose_SeqBAIJ_7;
2001273d9f13SBarry Smith       B->ops->multadd         = MatMultAdd_SeqBAIJ_7;
2002273d9f13SBarry Smith       break;
2003273d9f13SBarry Smith     default:
2004273d9f13SBarry Smith       B->ops->mult            = MatMult_SeqBAIJ_N;
2005273d9f13SBarry Smith       B->ops->solve           = MatSolve_SeqBAIJ_N;
2006273d9f13SBarry Smith       B->ops->multadd         = MatMultAdd_SeqBAIJ_N;
2007273d9f13SBarry Smith       break;
2008273d9f13SBarry Smith     }
2009273d9f13SBarry Smith   }
2010273d9f13SBarry Smith   b->bs      = bs;
2011273d9f13SBarry Smith   b->mbs     = mbs;
2012273d9f13SBarry Smith   b->nbs     = nbs;
2013b0a32e0cSBarry Smith   ierr = PetscMalloc((mbs+1)*sizeof(int),&b->imax);CHKERRQ(ierr);
2014273d9f13SBarry Smith   if (!nnz) {
2015435da068SBarry Smith     if (nz == PETSC_DEFAULT || nz == PETSC_DECIDE) nz = 5;
2016273d9f13SBarry Smith     else if (nz <= 0)        nz = 1;
2017273d9f13SBarry Smith     for (i=0; i<mbs; i++) b->imax[i] = nz;
2018273d9f13SBarry Smith     nz = nz*mbs;
2019273d9f13SBarry Smith   } else {
2020273d9f13SBarry Smith     nz = 0;
2021273d9f13SBarry Smith     for (i=0; i<mbs; i++) {b->imax[i] = nnz[i]; nz += nnz[i];}
2022273d9f13SBarry Smith   }
2023273d9f13SBarry Smith 
2024273d9f13SBarry Smith   /* allocate the matrix space */
2025273d9f13SBarry Smith   len   = nz*sizeof(int) + nz*bs2*sizeof(MatScalar) + (B->m+1)*sizeof(int);
2026b0a32e0cSBarry Smith   ierr  = PetscMalloc(len,&b->a);CHKERRQ(ierr);
2027273d9f13SBarry Smith   ierr  = PetscMemzero(b->a,nz*bs2*sizeof(MatScalar));CHKERRQ(ierr);
2028273d9f13SBarry Smith   b->j  = (int*)(b->a + nz*bs2);
2029273d9f13SBarry Smith   ierr = PetscMemzero(b->j,nz*sizeof(int));CHKERRQ(ierr);
2030273d9f13SBarry Smith   b->i  = b->j + nz;
2031273d9f13SBarry Smith   b->singlemalloc = PETSC_TRUE;
2032273d9f13SBarry Smith 
2033273d9f13SBarry Smith   b->i[0] = 0;
2034273d9f13SBarry Smith   for (i=1; i<mbs+1; i++) {
2035273d9f13SBarry Smith     b->i[i] = b->i[i-1] + b->imax[i-1];
2036273d9f13SBarry Smith   }
2037273d9f13SBarry Smith 
2038273d9f13SBarry Smith   /* b->ilen will count nonzeros in each block row so far. */
203916d6aa21SSatish Balay   ierr = PetscMalloc((mbs+1)*sizeof(int),&b->ilen);CHKERRQ(ierr);
2040b0a32e0cSBarry Smith   PetscLogObjectMemory(B,len+2*(mbs+1)*sizeof(int)+sizeof(struct _p_Mat)+sizeof(Mat_SeqBAIJ));
2041273d9f13SBarry Smith   for (i=0; i<mbs; i++) { b->ilen[i] = 0;}
2042273d9f13SBarry Smith 
2043273d9f13SBarry Smith   b->bs               = bs;
2044273d9f13SBarry Smith   b->bs2              = bs2;
2045273d9f13SBarry Smith   b->mbs              = mbs;
2046273d9f13SBarry Smith   b->nz               = 0;
2047273d9f13SBarry Smith   b->maxnz            = nz*bs2;
2048273d9f13SBarry Smith   B->info.nz_unneeded = (PetscReal)b->maxnz;
2049273d9f13SBarry Smith   PetscFunctionReturn(0);
2050273d9f13SBarry Smith }
20512593348eSBarry Smith 
2052