xref: /petsc/src/mat/impls/baij/seq/baij.c (revision bc4b532f10b058545a135fcfda6be695b68c2ef0)
1*bc4b532fSSatish Balay /*$Id: baij.c,v 1.206 2000/05/04 16:25:36 bsmith Exp balay $*/
22593348eSBarry Smith 
32593348eSBarry Smith /*
4b6490206SBarry Smith     Defines the basic matrix operations for the BAIJ (compressed row)
52593348eSBarry Smith   matrix storage format.
62593348eSBarry Smith */
73369ce9aSBarry Smith #include "sys.h"
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)
2095d5f7c2SBarry 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 */
30be5855fcSBarry Smith #undef __FUNC__
31b2863d3aSBarry Smith #define __FUNC__ /*<a name=""></a>*/"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) {
42be5855fcSBarry Smith       SETERRQ1(1,1,"Matrix is missing diagonal number %d",i);
43be5855fcSBarry Smith     }
44be5855fcSBarry Smith   }
45be5855fcSBarry Smith   PetscFunctionReturn(0);
46be5855fcSBarry Smith }
47be5855fcSBarry Smith 
485615d1e5SSatish Balay #undef __FUNC__
49b2863d3aSBarry Smith #define __FUNC__ /*<a name=""></a>*/"MatMarkDiagonal_SeqBAIJ"
50c4992f7dSBarry Smith int MatMarkDiagonal_SeqBAIJ(Mat A)
51de6a44a3SBarry Smith {
52de6a44a3SBarry Smith   Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)A->data;
537fc0212eSBarry Smith   int         i,j,*diag,m = a->mbs;
54de6a44a3SBarry Smith 
553a40ed3dSBarry Smith   PetscFunctionBegin;
56883fce79SBarry Smith   if (a->diag) PetscFunctionReturn(0);
57883fce79SBarry Smith 
58de6a44a3SBarry Smith   diag = (int*)PetscMalloc((m+1)*sizeof(int));CHKPTRQ(diag);
59de6a44a3SBarry Smith   PLogObjectMemory(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 
743b2fbd54SBarry Smith extern int MatToSymmetricIJ_SeqAIJ(int,int*,int*,int,int,int**,int**);
753b2fbd54SBarry Smith 
765615d1e5SSatish Balay #undef __FUNC__
77b2863d3aSBarry Smith #define __FUNC__ /*<a name=""></a>*/"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 */
903b2fbd54SBarry Smith     int nz = a->i[n] + 1;
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 
1015615d1e5SSatish Balay #undef __FUNC__
102b2863d3aSBarry Smith #define __FUNC__ /*<a name=""></a>*/"MatRestoreRowIJ_SeqBAIJ"
1033b2fbd54SBarry Smith static int MatRestoreRowIJ_SeqBAIJ(Mat A,int oshift,PetscTruth symmetric,int *nn,int **ia,int **ja,
1043b2fbd54SBarry Smith                                 PetscTruth *done)
1053b2fbd54SBarry Smith {
1063b2fbd54SBarry Smith   Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)A->data;
107606d414cSSatish Balay   int         i,n = a->mbs,ierr;
1083b2fbd54SBarry Smith 
1093a40ed3dSBarry Smith   PetscFunctionBegin;
1103a40ed3dSBarry Smith   if (!ia) PetscFunctionReturn(0);
1113b2fbd54SBarry Smith   if (symmetric) {
112606d414cSSatish Balay     ierr = PetscFree(*ia);CHKERRQ(ierr);
113606d414cSSatish Balay     ierr = PetscFree(*ja);CHKERRQ(ierr);
114af5da2bfSBarry Smith   } else if (oshift == 1) {
1153b2fbd54SBarry Smith     int nz = a->i[n];
1163b2fbd54SBarry Smith     for (i=0; i<nz; i++) a->j[i]--;
1173b2fbd54SBarry Smith     for (i=0; i<n+1; i++) a->i[i]--;
1183b2fbd54SBarry Smith   }
1193a40ed3dSBarry Smith   PetscFunctionReturn(0);
1203b2fbd54SBarry Smith }
1213b2fbd54SBarry Smith 
1222d61bbb3SSatish Balay #undef __FUNC__
123b2863d3aSBarry Smith #define __FUNC__ /*<a name=""></a>*/"MatGetBlockSize_SeqBAIJ"
1242d61bbb3SSatish Balay int MatGetBlockSize_SeqBAIJ(Mat mat,int *bs)
1252d61bbb3SSatish Balay {
1262d61bbb3SSatish Balay   Mat_SeqBAIJ *baij = (Mat_SeqBAIJ*)mat->data;
1272d61bbb3SSatish Balay 
1282d61bbb3SSatish Balay   PetscFunctionBegin;
1292d61bbb3SSatish Balay   *bs = baij->bs;
1302d61bbb3SSatish Balay   PetscFunctionReturn(0);
1312d61bbb3SSatish Balay }
1322d61bbb3SSatish Balay 
1332d61bbb3SSatish Balay 
1342d61bbb3SSatish Balay #undef __FUNC__
135b2863d3aSBarry Smith #define __FUNC__ /*<a name=""></a>*/"MatDestroy_SeqBAIJ"
136e1311b90SBarry Smith int MatDestroy_SeqBAIJ(Mat A)
1372d61bbb3SSatish Balay {
1382d61bbb3SSatish Balay   Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)A->data;
139e51c0b9cSSatish Balay   int         ierr;
1402d61bbb3SSatish Balay 
141433994e6SBarry Smith   PetscFunctionBegin;
14294d884c6SBarry Smith   if (A->mapping) {
14394d884c6SBarry Smith     ierr = ISLocalToGlobalMappingDestroy(A->mapping);CHKERRQ(ierr);
14494d884c6SBarry Smith   }
14594d884c6SBarry Smith   if (A->bmapping) {
14694d884c6SBarry Smith     ierr = ISLocalToGlobalMappingDestroy(A->bmapping);CHKERRQ(ierr);
14794d884c6SBarry Smith   }
14861b13de0SBarry Smith   if (A->rmap) {
14961b13de0SBarry Smith     ierr = MapDestroy(A->rmap);CHKERRQ(ierr);
15061b13de0SBarry Smith   }
15161b13de0SBarry Smith   if (A->cmap) {
15261b13de0SBarry Smith     ierr = MapDestroy(A->cmap);CHKERRQ(ierr);
15361b13de0SBarry Smith   }
154aa482453SBarry Smith #if defined(PETSC_USE_LOG)
155e1311b90SBarry Smith   PLogObjectState((PetscObject)A,"Rows=%d, Cols=%d, NZ=%d",a->m,a->n,a->nz);
1562d61bbb3SSatish Balay #endif
157606d414cSSatish Balay   ierr = PetscFree(a->a);CHKERRQ(ierr);
158606d414cSSatish Balay   if (!a->singlemalloc) {
159606d414cSSatish Balay     ierr = PetscFree(a->i);CHKERRQ(ierr);
160606d414cSSatish Balay     ierr = PetscFree(a->j);CHKERRQ(ierr);
161606d414cSSatish Balay   }
162c38d4ed2SBarry Smith   if (a->row) {
163c38d4ed2SBarry Smith     ierr = ISDestroy(a->row);CHKERRQ(ierr);
164c38d4ed2SBarry Smith   }
165c38d4ed2SBarry Smith   if (a->col) {
166c38d4ed2SBarry Smith     ierr = ISDestroy(a->col);CHKERRQ(ierr);
167c38d4ed2SBarry Smith   }
168606d414cSSatish Balay   if (a->diag) {ierr = PetscFree(a->diag);CHKERRQ(ierr);}
169606d414cSSatish Balay   if (a->ilen) {ierr = PetscFree(a->ilen);CHKERRQ(ierr);}
170606d414cSSatish Balay   if (a->imax) {ierr = PetscFree(a->imax);CHKERRQ(ierr);}
171606d414cSSatish Balay   if (a->solve_work) {ierr = PetscFree(a->solve_work);CHKERRQ(ierr);}
172606d414cSSatish Balay   if (a->mult_work) {ierr = PetscFree(a->mult_work);CHKERRQ(ierr);}
173e51c0b9cSSatish Balay   if (a->icol) {ierr = ISDestroy(a->icol);CHKERRQ(ierr);}
174606d414cSSatish Balay   if (a->saved_values) {ierr = PetscFree(a->saved_values);CHKERRQ(ierr);}
175563b5814SBarry Smith #if defined(PETSC_USE_MAT_SINGLE)
176563b5814SBarry Smith   if (a->setvaluescopy) {ierr = PetscFree(a->setvaluescopy);CHKERRQ(ierr);}
177563b5814SBarry Smith #endif
178606d414cSSatish Balay   ierr = PetscFree(a);CHKERRQ(ierr);
1792d61bbb3SSatish Balay   PLogObjectDestroy(A);
1802d61bbb3SSatish Balay   PetscHeaderDestroy(A);
1812d61bbb3SSatish Balay   PetscFunctionReturn(0);
1822d61bbb3SSatish Balay }
1832d61bbb3SSatish Balay 
1842d61bbb3SSatish Balay #undef __FUNC__
185b2863d3aSBarry Smith #define __FUNC__ /*<a name=""></a>*/"MatSetOption_SeqBAIJ"
1862d61bbb3SSatish Balay int MatSetOption_SeqBAIJ(Mat A,MatOption op)
1872d61bbb3SSatish Balay {
1882d61bbb3SSatish Balay   Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)A->data;
1892d61bbb3SSatish Balay 
1902d61bbb3SSatish Balay   PetscFunctionBegin;
191c4992f7dSBarry Smith   if      (op == MAT_ROW_ORIENTED)                 a->roworiented    = PETSC_TRUE;
192c4992f7dSBarry Smith   else if (op == MAT_COLUMN_ORIENTED)              a->roworiented    = PETSC_FALSE;
193c4992f7dSBarry Smith   else if (op == MAT_COLUMNS_SORTED)               a->sorted         = PETSC_TRUE;
194c4992f7dSBarry Smith   else if (op == MAT_COLUMNS_UNSORTED)             a->sorted         = PETSC_FALSE;
195c4992f7dSBarry Smith   else if (op == MAT_KEEP_ZEROED_ROWS)             a->keepzeroedrows = PETSC_TRUE;
1962d61bbb3SSatish Balay   else if (op == MAT_NO_NEW_NONZERO_LOCATIONS)     a->nonew          = 1;
1974787f768SSatish Balay   else if (op == MAT_NEW_NONZERO_LOCATION_ERR)     a->nonew          = -1;
1984787f768SSatish Balay   else if (op == MAT_NEW_NONZERO_ALLOCATION_ERR)   a->nonew          = -2;
1992d61bbb3SSatish Balay   else if (op == MAT_YES_NEW_NONZERO_LOCATIONS)    a->nonew          = 0;
2002d61bbb3SSatish Balay   else if (op == MAT_ROWS_SORTED ||
2012d61bbb3SSatish Balay            op == MAT_ROWS_UNSORTED ||
2022d61bbb3SSatish Balay            op == MAT_SYMMETRIC ||
2032d61bbb3SSatish Balay            op == MAT_STRUCTURALLY_SYMMETRIC ||
2042d61bbb3SSatish Balay            op == MAT_YES_NEW_DIAGONALS ||
205b51ba29fSSatish Balay            op == MAT_IGNORE_OFF_PROC_ENTRIES ||
206b51ba29fSSatish Balay            op == MAT_USE_HASH_TABLE) {
207981c4779SBarry Smith     PLogInfo(A,"MatSetOption_SeqBAIJ:Option ignored\n");
2082d61bbb3SSatish Balay   } else if (op == MAT_NO_NEW_DIAGONALS) {
2092d61bbb3SSatish Balay     SETERRQ(PETSC_ERR_SUP,0,"MAT_NO_NEW_DIAGONALS");
2102d61bbb3SSatish Balay   } else {
2112d61bbb3SSatish Balay     SETERRQ(PETSC_ERR_SUP,0,"unknown option");
2122d61bbb3SSatish Balay   }
2132d61bbb3SSatish Balay   PetscFunctionReturn(0);
2142d61bbb3SSatish Balay }
2152d61bbb3SSatish Balay 
2162d61bbb3SSatish Balay 
2172d61bbb3SSatish Balay #undef __FUNC__
218b2863d3aSBarry Smith #define __FUNC__ /*<a name=""></a>*/"MatGetSize_SeqBAIJ"
2192d61bbb3SSatish Balay int MatGetSize_SeqBAIJ(Mat A,int *m,int *n)
2202d61bbb3SSatish Balay {
2212d61bbb3SSatish Balay   Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)A->data;
2222d61bbb3SSatish Balay 
2232d61bbb3SSatish Balay   PetscFunctionBegin;
2242d61bbb3SSatish Balay   if (m) *m = a->m;
2252d61bbb3SSatish Balay   if (n) *n = a->n;
2262d61bbb3SSatish Balay   PetscFunctionReturn(0);
2272d61bbb3SSatish Balay }
2282d61bbb3SSatish Balay 
2292d61bbb3SSatish Balay #undef __FUNC__
230b2863d3aSBarry Smith #define __FUNC__ /*<a name=""></a>*/"MatGetOwnershipRange_SeqBAIJ"
2312d61bbb3SSatish Balay int MatGetOwnershipRange_SeqBAIJ(Mat A,int *m,int *n)
2322d61bbb3SSatish Balay {
2332d61bbb3SSatish Balay   Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)A->data;
2342d61bbb3SSatish Balay 
2352d61bbb3SSatish Balay   PetscFunctionBegin;
2364c49b128SBarry Smith   if (m) *m = 0;
2374c49b128SBarry Smith   if (n) *n = a->m;
2382d61bbb3SSatish Balay   PetscFunctionReturn(0);
2392d61bbb3SSatish Balay }
2402d61bbb3SSatish Balay 
2412d61bbb3SSatish Balay #undef __FUNC__
242b2863d3aSBarry Smith #define __FUNC__ /*<a name=""></a>*/"MatGetRow_SeqBAIJ"
2432d61bbb3SSatish Balay int MatGetRow_SeqBAIJ(Mat A,int row,int *nz,int **idx,Scalar **v)
2442d61bbb3SSatish Balay {
2452d61bbb3SSatish Balay   Mat_SeqBAIJ  *a = (Mat_SeqBAIJ*)A->data;
2462d61bbb3SSatish Balay   int          itmp,i,j,k,M,*ai,*aj,bs,bn,bp,*idx_i,bs2;
2473f1db9ecSBarry Smith   MatScalar    *aa,*aa_i;
2483f1db9ecSBarry Smith   Scalar       *v_i;
2492d61bbb3SSatish Balay 
2502d61bbb3SSatish Balay   PetscFunctionBegin;
2512d61bbb3SSatish Balay   bs  = a->bs;
2522d61bbb3SSatish Balay   ai  = a->i;
2532d61bbb3SSatish Balay   aj  = a->j;
2542d61bbb3SSatish Balay   aa  = a->a;
2552d61bbb3SSatish Balay   bs2 = a->bs2;
2562d61bbb3SSatish Balay 
2572d61bbb3SSatish Balay   if (row < 0 || row >= a->m) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Row out of range");
2582d61bbb3SSatish Balay 
2592d61bbb3SSatish Balay   bn  = row/bs;   /* Block number */
2602d61bbb3SSatish Balay   bp  = row % bs; /* Block Position */
2612d61bbb3SSatish Balay   M   = ai[bn+1] - ai[bn];
2622d61bbb3SSatish Balay   *nz = bs*M;
2632d61bbb3SSatish Balay 
2642d61bbb3SSatish Balay   if (v) {
2652d61bbb3SSatish Balay     *v = 0;
2662d61bbb3SSatish Balay     if (*nz) {
2672d61bbb3SSatish Balay       *v = (Scalar*)PetscMalloc((*nz)*sizeof(Scalar));CHKPTRQ(*v);
2682d61bbb3SSatish Balay       for (i=0; i<M; i++) { /* for each block in the block row */
2692d61bbb3SSatish Balay         v_i  = *v + i*bs;
2702d61bbb3SSatish Balay         aa_i = aa + bs2*(ai[bn] + i);
2712d61bbb3SSatish Balay         for (j=bp,k=0; j<bs2; j+=bs,k++) {v_i[k] = aa_i[j];}
2722d61bbb3SSatish Balay       }
2732d61bbb3SSatish Balay     }
2742d61bbb3SSatish Balay   }
2752d61bbb3SSatish Balay 
2762d61bbb3SSatish Balay   if (idx) {
2772d61bbb3SSatish Balay     *idx = 0;
2782d61bbb3SSatish Balay     if (*nz) {
2792d61bbb3SSatish Balay       *idx = (int*)PetscMalloc((*nz)*sizeof(int));CHKPTRQ(*idx);
2802d61bbb3SSatish Balay       for (i=0; i<M; i++) { /* for each block in the block row */
2812d61bbb3SSatish Balay         idx_i = *idx + i*bs;
2822d61bbb3SSatish Balay         itmp  = bs*aj[ai[bn] + i];
2832d61bbb3SSatish Balay         for (j=0; j<bs; j++) {idx_i[j] = itmp++;}
2842d61bbb3SSatish Balay       }
2852d61bbb3SSatish Balay     }
2862d61bbb3SSatish Balay   }
2872d61bbb3SSatish Balay   PetscFunctionReturn(0);
2882d61bbb3SSatish Balay }
2892d61bbb3SSatish Balay 
2902d61bbb3SSatish Balay #undef __FUNC__
291b2863d3aSBarry Smith #define __FUNC__ /*<a name=""></a>*/"MatRestoreRow_SeqBAIJ"
2922d61bbb3SSatish Balay int MatRestoreRow_SeqBAIJ(Mat A,int row,int *nz,int **idx,Scalar **v)
2932d61bbb3SSatish Balay {
294606d414cSSatish Balay   int ierr;
295606d414cSSatish Balay 
2962d61bbb3SSatish Balay   PetscFunctionBegin;
297606d414cSSatish Balay   if (idx) {if (*idx) {ierr = PetscFree(*idx);CHKERRQ(ierr);}}
298606d414cSSatish Balay   if (v)   {if (*v)   {ierr = PetscFree(*v);CHKERRQ(ierr);}}
2992d61bbb3SSatish Balay   PetscFunctionReturn(0);
3002d61bbb3SSatish Balay }
3012d61bbb3SSatish Balay 
3022d61bbb3SSatish Balay #undef __FUNC__
303b2863d3aSBarry Smith #define __FUNC__ /*<a name=""></a>*/"MatTranspose_SeqBAIJ"
3042d61bbb3SSatish Balay int MatTranspose_SeqBAIJ(Mat A,Mat *B)
3052d61bbb3SSatish Balay {
3062d61bbb3SSatish Balay   Mat_SeqBAIJ *a=(Mat_SeqBAIJ *)A->data;
3072d61bbb3SSatish Balay   Mat         C;
3082d61bbb3SSatish Balay   int         i,j,k,ierr,*aj=a->j,*ai=a->i,bs=a->bs,mbs=a->mbs,nbs=a->nbs,len,*col;
3090e6d2581SBarry Smith   int         *rows,*cols,bs2=a->bs2,refct;
310375fe846SBarry Smith   Scalar      *array;
3112d61bbb3SSatish Balay 
3122d61bbb3SSatish Balay   PetscFunctionBegin;
3130e6d2581SBarry Smith   if (!B && mbs!=nbs) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Square matrix only for in-place");
3142d61bbb3SSatish Balay   col  = (int*)PetscMalloc((1+nbs)*sizeof(int));CHKPTRQ(col);
315549d3d68SSatish Balay   ierr = PetscMemzero(col,(1+nbs)*sizeof(int));CHKERRQ(ierr);
3162d61bbb3SSatish Balay 
317375fe846SBarry Smith #if defined(PETSC_USE_MAT_SINGLE)
318375fe846SBarry Smith   array = (Scalar *)PetscMalloc(a->bs2*a->nz*sizeof(Scalar));CHKPTRQ(array);
319375fe846SBarry Smith   for (i=0; i<a->bs2*a->nz; i++) array[i] = (Scalar)a->a[i];
320375fe846SBarry Smith #else
3213eda8832SBarry Smith   array = a->a;
322375fe846SBarry Smith #endif
323375fe846SBarry Smith 
3242d61bbb3SSatish Balay   for (i=0; i<ai[mbs]; i++) col[aj[i]] += 1;
3252d61bbb3SSatish Balay   ierr = MatCreateSeqBAIJ(A->comm,bs,a->n,a->m,PETSC_NULL,col,&C);CHKERRQ(ierr);
326606d414cSSatish Balay   ierr = PetscFree(col);CHKERRQ(ierr);
3272d61bbb3SSatish Balay   rows = (int*)PetscMalloc(2*bs*sizeof(int));CHKPTRQ(rows);
3282d61bbb3SSatish Balay   cols = rows + bs;
3292d61bbb3SSatish Balay   for (i=0; i<mbs; i++) {
3302d61bbb3SSatish Balay     cols[0] = i*bs;
3312d61bbb3SSatish Balay     for (k=1; k<bs; k++) cols[k] = cols[k-1] + 1;
3322d61bbb3SSatish Balay     len = ai[i+1] - ai[i];
3332d61bbb3SSatish Balay     for (j=0; j<len; j++) {
3342d61bbb3SSatish Balay       rows[0] = (*aj++)*bs;
3352d61bbb3SSatish Balay       for (k=1; k<bs; k++) rows[k] = rows[k-1] + 1;
3362d61bbb3SSatish Balay       ierr = MatSetValues(C,bs,rows,bs,cols,array,INSERT_VALUES);CHKERRQ(ierr);
3372d61bbb3SSatish Balay       array += bs2;
3382d61bbb3SSatish Balay     }
3392d61bbb3SSatish Balay   }
340606d414cSSatish Balay   ierr = PetscFree(rows);CHKERRQ(ierr);
341375fe846SBarry Smith #if defined(PETSC_USE_MAT_SINGLE)
342375fe846SBarry Smith   ierr = PetscFree(array);
343375fe846SBarry Smith #endif
3442d61bbb3SSatish Balay 
3452d61bbb3SSatish Balay   ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
3462d61bbb3SSatish Balay   ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
3472d61bbb3SSatish Balay 
348c4992f7dSBarry Smith   if (B) {
3492d61bbb3SSatish Balay     *B = C;
3502d61bbb3SSatish Balay   } else {
351f830108cSBarry Smith     PetscOps *Abops;
352cc2dc46cSBarry Smith     MatOps   Aops;
353f830108cSBarry Smith 
3542d61bbb3SSatish Balay     /* This isn't really an in-place transpose */
355606d414cSSatish Balay     ierr = PetscFree(a->a);CHKERRQ(ierr);
356606d414cSSatish Balay     if (!a->singlemalloc) {
357606d414cSSatish Balay       ierr = PetscFree(a->i);CHKERRQ(ierr);
358606d414cSSatish Balay       ierr = PetscFree(a->j);CHKERRQ(ierr);
359606d414cSSatish Balay     }
360606d414cSSatish Balay     if (a->diag) {ierr = PetscFree(a->diag);CHKERRQ(ierr);}
361606d414cSSatish Balay     if (a->ilen) {ierr = PetscFree(a->ilen);CHKERRQ(ierr);}
362606d414cSSatish Balay     if (a->imax) {ierr = PetscFree(a->imax);CHKERRQ(ierr);}
363606d414cSSatish Balay     if (a->solve_work) {ierr = PetscFree(a->solve_work);CHKERRQ(ierr);}
364606d414cSSatish Balay     ierr = PetscFree(a);CHKERRQ(ierr);
365f830108cSBarry Smith 
3667413bad6SBarry Smith 
3677413bad6SBarry Smith     ierr = MapDestroy(A->rmap);CHKERRQ(ierr);
3687413bad6SBarry Smith     ierr = MapDestroy(A->cmap);CHKERRQ(ierr);
3697413bad6SBarry Smith 
370f830108cSBarry Smith     /*
371f830108cSBarry Smith        This is horrible, horrible code. We need to keep the
372f830108cSBarry Smith       A pointers for the bops and ops but copy everything
373f830108cSBarry Smith       else from C.
374f830108cSBarry Smith     */
375f830108cSBarry Smith     Abops    = A->bops;
376f830108cSBarry Smith     Aops     = A->ops;
3770e6d2581SBarry Smith     refct    = A->refct;
378549d3d68SSatish Balay     ierr     = PetscMemcpy(A,C,sizeof(struct _p_Mat));CHKERRQ(ierr);
379f830108cSBarry Smith     A->bops  = Abops;
380f830108cSBarry Smith     A->ops   = Aops;
38127a8da17SBarry Smith     A->qlist = 0;
3820e6d2581SBarry Smith     A->refct = refct;
383f830108cSBarry Smith 
3842d61bbb3SSatish Balay     PetscHeaderDestroy(C);
3852d61bbb3SSatish Balay   }
3862d61bbb3SSatish Balay   PetscFunctionReturn(0);
3872d61bbb3SSatish Balay }
3882d61bbb3SSatish Balay 
3895615d1e5SSatish Balay #undef __FUNC__
390b2863d3aSBarry Smith #define __FUNC__ /*<a name=""></a>*/"MatView_SeqBAIJ_Binary"
391b6490206SBarry Smith static int MatView_SeqBAIJ_Binary(Mat A,Viewer viewer)
3922593348eSBarry Smith {
393b6490206SBarry Smith   Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)A->data;
3949df24120SSatish Balay   int         i,fd,*col_lens,ierr,bs = a->bs,count,*jj,j,k,l,bs2=a->bs2;
395b6490206SBarry Smith   Scalar      *aa;
396ce6f0cecSBarry Smith   FILE        *file;
3972593348eSBarry Smith 
3983a40ed3dSBarry Smith   PetscFunctionBegin;
39990ace30eSBarry Smith   ierr = ViewerBinaryGetDescriptor(viewer,&fd);CHKERRQ(ierr);
4002593348eSBarry Smith   col_lens = (int*)PetscMalloc((4+a->m)*sizeof(int));CHKPTRQ(col_lens);
4012593348eSBarry Smith   col_lens[0] = MAT_COOKIE;
4023b2fbd54SBarry Smith 
4032593348eSBarry Smith   col_lens[1] = a->m;
4042593348eSBarry Smith   col_lens[2] = a->n;
4057e67e3f9SSatish Balay   col_lens[3] = a->nz*bs2;
4062593348eSBarry Smith 
4072593348eSBarry Smith   /* store lengths of each row and write (including header) to file */
408b6490206SBarry Smith   count = 0;
409b6490206SBarry Smith   for (i=0; i<a->mbs; i++) {
410b6490206SBarry Smith     for (j=0; j<bs; j++) {
411b6490206SBarry Smith       col_lens[4+count++] = bs*(a->i[i+1] - a->i[i]);
412b6490206SBarry Smith     }
4132593348eSBarry Smith   }
4140752156aSBarry Smith   ierr = PetscBinaryWrite(fd,col_lens,4+a->m,PETSC_INT,1);CHKERRQ(ierr);
415606d414cSSatish Balay   ierr = PetscFree(col_lens);CHKERRQ(ierr);
4162593348eSBarry Smith 
4172593348eSBarry Smith   /* store column indices (zero start index) */
41866963ce1SSatish Balay   jj = (int*)PetscMalloc((a->nz+1)*bs2*sizeof(int));CHKPTRQ(jj);
419b6490206SBarry Smith   count = 0;
420b6490206SBarry Smith   for (i=0; i<a->mbs; i++) {
421b6490206SBarry Smith     for (j=0; j<bs; j++) {
422b6490206SBarry Smith       for (k=a->i[i]; k<a->i[i+1]; k++) {
423b6490206SBarry Smith         for (l=0; l<bs; l++) {
424b6490206SBarry Smith           jj[count++] = bs*a->j[k] + l;
4252593348eSBarry Smith         }
4262593348eSBarry Smith       }
427b6490206SBarry Smith     }
428b6490206SBarry Smith   }
4290752156aSBarry Smith   ierr = PetscBinaryWrite(fd,jj,bs2*a->nz,PETSC_INT,0);CHKERRQ(ierr);
430606d414cSSatish Balay   ierr = PetscFree(jj);CHKERRQ(ierr);
4312593348eSBarry Smith 
4322593348eSBarry Smith   /* store nonzero values */
43366963ce1SSatish Balay   aa = (Scalar*)PetscMalloc((a->nz+1)*bs2*sizeof(Scalar));CHKPTRQ(aa);
434b6490206SBarry Smith   count = 0;
435b6490206SBarry Smith   for (i=0; i<a->mbs; i++) {
436b6490206SBarry Smith     for (j=0; j<bs; j++) {
437b6490206SBarry Smith       for (k=a->i[i]; k<a->i[i+1]; k++) {
438b6490206SBarry Smith         for (l=0; l<bs; l++) {
4397e67e3f9SSatish Balay           aa[count++] = a->a[bs2*k + l*bs + j];
440b6490206SBarry Smith         }
441b6490206SBarry Smith       }
442b6490206SBarry Smith     }
443b6490206SBarry Smith   }
4440752156aSBarry Smith   ierr = PetscBinaryWrite(fd,aa,bs2*a->nz,PETSC_SCALAR,0);CHKERRQ(ierr);
445606d414cSSatish Balay   ierr = PetscFree(aa);CHKERRQ(ierr);
446ce6f0cecSBarry Smith 
447ce6f0cecSBarry Smith   ierr = ViewerBinaryGetInfoPointer(viewer,&file);CHKERRQ(ierr);
448ce6f0cecSBarry Smith   if (file) {
449ce6f0cecSBarry Smith     fprintf(file,"-matload_block_size %d\n",a->bs);
450ce6f0cecSBarry Smith   }
4513a40ed3dSBarry Smith   PetscFunctionReturn(0);
4522593348eSBarry Smith }
4532593348eSBarry Smith 
4545615d1e5SSatish Balay #undef __FUNC__
455b2863d3aSBarry Smith #define __FUNC__ /*<a name=""></a>*/"MatView_SeqBAIJ_ASCII"
456b6490206SBarry Smith static int MatView_SeqBAIJ_ASCII(Mat A,Viewer viewer)
4572593348eSBarry Smith {
458b6490206SBarry Smith   Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)A->data;
4599df24120SSatish Balay   int         ierr,i,j,format,bs = a->bs,k,l,bs2=a->bs2;
4602593348eSBarry Smith   char        *outputname;
4612593348eSBarry Smith 
4623a40ed3dSBarry Smith   PetscFunctionBegin;
46377ed5343SBarry Smith   ierr = ViewerGetOutputname(viewer,&outputname);CHKERRQ(ierr);
464888f2ed8SSatish Balay   ierr = ViewerGetFormat(viewer,&format);CHKERRQ(ierr);
465639f9d9dSBarry Smith   if (format == VIEWER_FORMAT_ASCII_INFO || format == VIEWER_FORMAT_ASCII_INFO_LONG) {
466d132466eSBarry Smith     ierr = ViewerASCIIPrintf(viewer,"  block size is %d\n",bs);CHKERRQ(ierr);
4670ef38995SBarry Smith   } else if (format == VIEWER_FORMAT_ASCII_MATLAB) {
4686831982aSBarry Smith     SETERRQ(PETSC_ERR_SUP,0,"Matlab format not supported");
4690ef38995SBarry Smith   } else if (format == VIEWER_FORMAT_ASCII_COMMON) {
4706831982aSBarry Smith     ierr = ViewerASCIIUseTabs(viewer,PETSC_NO);CHKERRQ(ierr);
47144cd7ae7SLois Curfman McInnes     for (i=0; i<a->mbs; i++) {
47244cd7ae7SLois Curfman McInnes       for (j=0; j<bs; j++) {
4736831982aSBarry Smith         ierr = ViewerASCIIPrintf(viewer,"row %d:",i*bs+j);CHKERRQ(ierr);
47444cd7ae7SLois Curfman McInnes         for (k=a->i[i]; k<a->i[i+1]; k++) {
47544cd7ae7SLois Curfman McInnes           for (l=0; l<bs; l++) {
476aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
4770e6d2581SBarry Smith             if (PetscImaginaryPart(a->a[bs2*k + l*bs + j]) > 0.0 && PetscRealPart(a->a[bs2*k + l*bs + j]) != 0.0) {
4786831982aSBarry Smith               ierr = ViewerASCIIPrintf(viewer," %d %g + %gi",bs*a->j[k]+l,
4790e6d2581SBarry Smith                       PetscRealPart(a->a[bs2*k + l*bs + j]),PetscImaginaryPart(a->a[bs2*k + l*bs + j]));CHKERRQ(ierr);
4800e6d2581SBarry Smith             } else if (PetscImaginaryPart(a->a[bs2*k + l*bs + j]) < 0.0 && PetscRealPart(a->a[bs2*k + l*bs + j]) != 0.0) {
4816831982aSBarry Smith               ierr = ViewerASCIIPrintf(viewer," %d %g - %gi",bs*a->j[k]+l,
4820e6d2581SBarry Smith                       PetscRealPart(a->a[bs2*k + l*bs + j]),-PetscImaginaryPart(a->a[bs2*k + l*bs + j]));CHKERRQ(ierr);
4830e6d2581SBarry Smith             } else if (PetscRealPart(a->a[bs2*k + l*bs + j]) != 0.0) {
4840e6d2581SBarry Smith               ierr = ViewerASCIIPrintf(viewer," %d %g ",bs*a->j[k]+l,PetscRealPart(a->a[bs2*k + l*bs + j]));CHKERRQ(ierr);
4850ef38995SBarry Smith             }
48644cd7ae7SLois Curfman McInnes #else
4870ef38995SBarry Smith             if (a->a[bs2*k + l*bs + j] != 0.0) {
4886831982aSBarry Smith               ierr = ViewerASCIIPrintf(viewer," %d %g ",bs*a->j[k]+l,a->a[bs2*k + l*bs + j]);CHKERRQ(ierr);
4890ef38995SBarry Smith             }
49044cd7ae7SLois Curfman McInnes #endif
49144cd7ae7SLois Curfman McInnes           }
49244cd7ae7SLois Curfman McInnes         }
4936831982aSBarry Smith         ierr = ViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
49444cd7ae7SLois Curfman McInnes       }
49544cd7ae7SLois Curfman McInnes     }
4966831982aSBarry Smith     ierr = ViewerASCIIUseTabs(viewer,PETSC_YES);CHKERRQ(ierr);
4970ef38995SBarry Smith   } else {
4986831982aSBarry Smith     ierr = ViewerASCIIUseTabs(viewer,PETSC_NO);CHKERRQ(ierr);
499b6490206SBarry Smith     for (i=0; i<a->mbs; i++) {
500b6490206SBarry Smith       for (j=0; j<bs; j++) {
5016831982aSBarry Smith         ierr = ViewerASCIIPrintf(viewer,"row %d:",i*bs+j);CHKERRQ(ierr);
502b6490206SBarry Smith         for (k=a->i[i]; k<a->i[i+1]; k++) {
503b6490206SBarry Smith           for (l=0; l<bs; l++) {
504aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
5050e6d2581SBarry Smith             if (PetscImaginaryPart(a->a[bs2*k + l*bs + j]) > 0.0) {
5066831982aSBarry Smith               ierr = ViewerASCIIPrintf(viewer," %d %g + %g i",bs*a->j[k]+l,
5070e6d2581SBarry Smith                 PetscRealPart(a->a[bs2*k + l*bs + j]),PetscImaginaryPart(a->a[bs2*k + l*bs + j]));CHKERRQ(ierr);
5080e6d2581SBarry Smith             } else if (PetscImaginaryPart(a->a[bs2*k + l*bs + j]) < 0.0) {
5096831982aSBarry Smith               ierr = ViewerASCIIPrintf(viewer," %d %g - %g i",bs*a->j[k]+l,
5100e6d2581SBarry Smith                 PetscRealPart(a->a[bs2*k + l*bs + j]),-PetscImaginaryPart(a->a[bs2*k + l*bs + j]));CHKERRQ(ierr);
5110ef38995SBarry Smith             } else {
5120e6d2581SBarry Smith               ierr = ViewerASCIIPrintf(viewer," %d %g ",bs*a->j[k]+l,PetscRealPart(a->a[bs2*k + l*bs + j]));CHKERRQ(ierr);
51388685aaeSLois Curfman McInnes             }
51488685aaeSLois Curfman McInnes #else
5156831982aSBarry Smith             ierr = ViewerASCIIPrintf(viewer," %d %g ",bs*a->j[k]+l,a->a[bs2*k + l*bs + j]);CHKERRQ(ierr);
51688685aaeSLois Curfman McInnes #endif
5172593348eSBarry Smith           }
5182593348eSBarry Smith         }
5196831982aSBarry Smith         ierr = ViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
5202593348eSBarry Smith       }
5212593348eSBarry Smith     }
5226831982aSBarry Smith     ierr = ViewerASCIIUseTabs(viewer,PETSC_YES);CHKERRQ(ierr);
523b6490206SBarry Smith   }
5246831982aSBarry Smith   ierr = ViewerFlush(viewer);CHKERRQ(ierr);
5253a40ed3dSBarry Smith   PetscFunctionReturn(0);
5262593348eSBarry Smith }
5272593348eSBarry Smith 
5285615d1e5SSatish Balay #undef __FUNC__
529b2863d3aSBarry Smith #define __FUNC__ /*<a name=""></a>*/"MatView_SeqBAIJ_Draw_Zoom"
53077ed5343SBarry Smith static int MatView_SeqBAIJ_Draw_Zoom(Draw draw,void *Aa)
5313270192aSSatish Balay {
53277ed5343SBarry Smith   Mat          A = (Mat) Aa;
5333270192aSSatish Balay   Mat_SeqBAIJ  *a=(Mat_SeqBAIJ*)A->data;
534b65db4caSBarry Smith   int          row,ierr,i,j,k,l,mbs=a->mbs,color,bs=a->bs,bs2=a->bs2;
5350e6d2581SBarry Smith   PetscReal    xl,yl,xr,yr,x_l,x_r,y_l,y_r;
5363f1db9ecSBarry Smith   MatScalar    *aa;
53777ed5343SBarry Smith   Viewer       viewer;
5383270192aSSatish Balay 
5393a40ed3dSBarry Smith   PetscFunctionBegin;
5403270192aSSatish Balay 
541b65db4caSBarry Smith   /* still need to add support for contour plot of nonzeros; see MatView_SeqAIJ_Draw_Zoom()*/
54277ed5343SBarry Smith   ierr = PetscObjectQuery((PetscObject)A,"Zoomviewer",(PetscObject*)&viewer);CHKERRQ(ierr);
54377ed5343SBarry Smith 
54477ed5343SBarry Smith   ierr = DrawGetCoordinates(draw,&xl,&yl,&xr,&yr);CHKERRQ(ierr);
54577ed5343SBarry Smith 
5463270192aSSatish Balay   /* loop over matrix elements drawing boxes */
5473270192aSSatish Balay   color = DRAW_BLUE;
5483270192aSSatish Balay   for (i=0,row=0; i<mbs; i++,row+=bs) {
5493270192aSSatish Balay     for (j=a->i[i]; j<a->i[i+1]; j++) {
5503270192aSSatish Balay       y_l = a->m - row - 1.0; y_r = y_l + 1.0;
5513270192aSSatish Balay       x_l = a->j[j]*bs; x_r = x_l + 1.0;
5523270192aSSatish Balay       aa = a->a + j*bs2;
5533270192aSSatish Balay       for (k=0; k<bs; k++) {
5543270192aSSatish Balay         for (l=0; l<bs; l++) {
5550e6d2581SBarry Smith           if (PetscRealPart(*aa++) >=  0.) continue;
556433994e6SBarry Smith           ierr = DrawRectangle(draw,x_l+k,y_l-l,x_r+k,y_r-l,color,color,color,color);CHKERRQ(ierr);
5573270192aSSatish Balay         }
5583270192aSSatish Balay       }
5593270192aSSatish Balay     }
5603270192aSSatish Balay   }
5613270192aSSatish Balay   color = DRAW_CYAN;
5623270192aSSatish Balay   for (i=0,row=0; i<mbs; i++,row+=bs) {
5633270192aSSatish Balay     for (j=a->i[i]; j<a->i[i+1]; j++) {
5643270192aSSatish Balay       y_l = a->m - row - 1.0; y_r = y_l + 1.0;
5653270192aSSatish Balay       x_l = a->j[j]*bs; x_r = x_l + 1.0;
5663270192aSSatish Balay       aa = a->a + j*bs2;
5673270192aSSatish Balay       for (k=0; k<bs; k++) {
5683270192aSSatish Balay         for (l=0; l<bs; l++) {
5690e6d2581SBarry Smith           if (PetscRealPart(*aa++) != 0.) continue;
570433994e6SBarry Smith           ierr = DrawRectangle(draw,x_l+k,y_l-l,x_r+k,y_r-l,color,color,color,color);CHKERRQ(ierr);
5713270192aSSatish Balay         }
5723270192aSSatish Balay       }
5733270192aSSatish Balay     }
5743270192aSSatish Balay   }
5753270192aSSatish Balay 
5763270192aSSatish Balay   color = DRAW_RED;
5773270192aSSatish Balay   for (i=0,row=0; i<mbs; i++,row+=bs) {
5783270192aSSatish Balay     for (j=a->i[i]; j<a->i[i+1]; j++) {
5793270192aSSatish Balay       y_l = a->m - row - 1.0; y_r = y_l + 1.0;
5803270192aSSatish Balay       x_l = a->j[j]*bs; x_r = x_l + 1.0;
5813270192aSSatish Balay       aa = a->a + j*bs2;
5823270192aSSatish Balay       for (k=0; k<bs; k++) {
5833270192aSSatish Balay         for (l=0; l<bs; l++) {
5840e6d2581SBarry Smith           if (PetscRealPart(*aa++) <= 0.) continue;
585433994e6SBarry Smith           ierr = DrawRectangle(draw,x_l+k,y_l-l,x_r+k,y_r-l,color,color,color,color);CHKERRQ(ierr);
5863270192aSSatish Balay         }
5873270192aSSatish Balay       }
5883270192aSSatish Balay     }
5893270192aSSatish Balay   }
59077ed5343SBarry Smith   PetscFunctionReturn(0);
59177ed5343SBarry Smith }
5923270192aSSatish Balay 
59377ed5343SBarry Smith #undef __FUNC__
594b2863d3aSBarry Smith #define __FUNC__ /*<a name=""></a>*/"MatView_SeqBAIJ_Draw"
59577ed5343SBarry Smith static int MatView_SeqBAIJ_Draw(Mat A,Viewer viewer)
59677ed5343SBarry Smith {
59777ed5343SBarry Smith   Mat_SeqBAIJ  *a=(Mat_SeqBAIJ*)A->data;
5987dce120fSSatish Balay   int          ierr;
5990e6d2581SBarry Smith   PetscReal    xl,yl,xr,yr,w,h;
60077ed5343SBarry Smith   Draw         draw;
60177ed5343SBarry Smith   PetscTruth   isnull;
6023270192aSSatish Balay 
60377ed5343SBarry Smith   PetscFunctionBegin;
60477ed5343SBarry Smith 
60577ed5343SBarry Smith   ierr = ViewerDrawGetDraw(viewer,0,&draw);CHKERRQ(ierr);
60677ed5343SBarry Smith   ierr = DrawIsNull(draw,&isnull);CHKERRQ(ierr); if (isnull) PetscFunctionReturn(0);
60777ed5343SBarry Smith 
60877ed5343SBarry Smith   ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",(PetscObject)viewer);CHKERRQ(ierr);
60977ed5343SBarry Smith   xr  = a->n; yr = a->m; h = yr/10.0; w = xr/10.0;
61077ed5343SBarry Smith   xr += w;    yr += h;  xl = -w;     yl = -h;
6113270192aSSatish Balay   ierr = DrawSetCoordinates(draw,xl,yl,xr,yr);CHKERRQ(ierr);
61277ed5343SBarry Smith   ierr = DrawZoom(draw,MatView_SeqBAIJ_Draw_Zoom,A);CHKERRQ(ierr);
61377ed5343SBarry Smith   ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",PETSC_NULL);CHKERRQ(ierr);
6143a40ed3dSBarry Smith   PetscFunctionReturn(0);
6153270192aSSatish Balay }
6163270192aSSatish Balay 
6175615d1e5SSatish Balay #undef __FUNC__
618b2863d3aSBarry Smith #define __FUNC__ /*<a name=""></a>*/"MatView_SeqBAIJ"
619e1311b90SBarry Smith int MatView_SeqBAIJ(Mat A,Viewer viewer)
6202593348eSBarry Smith {
62119bcc07fSBarry Smith   int        ierr;
6226831982aSBarry Smith   PetscTruth issocket,isascii,isbinary,isdraw;
6232593348eSBarry Smith 
6243a40ed3dSBarry Smith   PetscFunctionBegin;
6256831982aSBarry Smith   ierr = PetscTypeCompare((PetscObject)viewer,SOCKET_VIEWER,&issocket);CHKERRQ(ierr);
6266831982aSBarry Smith   ierr = PetscTypeCompare((PetscObject)viewer,ASCII_VIEWER,&isascii);CHKERRQ(ierr);
6276831982aSBarry Smith   ierr = PetscTypeCompare((PetscObject)viewer,BINARY_VIEWER,&isbinary);CHKERRQ(ierr);
6286831982aSBarry Smith   ierr = PetscTypeCompare((PetscObject)viewer,DRAW_VIEWER,&isdraw);CHKERRQ(ierr);
6290f5bd95cSBarry Smith   if (issocket) {
6307b2a1423SBarry Smith     SETERRQ(PETSC_ERR_SUP,0,"Socket viewer not supported");
6310f5bd95cSBarry Smith   } else if (isascii){
6323a40ed3dSBarry Smith     ierr = MatView_SeqBAIJ_ASCII(A,viewer);CHKERRQ(ierr);
6330f5bd95cSBarry Smith   } else if (isbinary) {
6343a40ed3dSBarry Smith     ierr = MatView_SeqBAIJ_Binary(A,viewer);CHKERRQ(ierr);
6350f5bd95cSBarry Smith   } else if (isdraw) {
6363a40ed3dSBarry Smith     ierr = MatView_SeqBAIJ_Draw(A,viewer);CHKERRQ(ierr);
6375cd90555SBarry Smith   } else {
6380f5bd95cSBarry Smith     SETERRQ1(1,1,"Viewer type %s not supported by SeqBAIJ matrices",((PetscObject)viewer)->type_name);
6392593348eSBarry Smith   }
6403a40ed3dSBarry Smith   PetscFunctionReturn(0);
6412593348eSBarry Smith }
642b6490206SBarry Smith 
643cd0e1443SSatish Balay 
6445615d1e5SSatish Balay #undef __FUNC__
645b2863d3aSBarry Smith #define __FUNC__ /*<a name=""></a>*/"MatGetValues_SeqBAIJ"
6462d61bbb3SSatish Balay int MatGetValues_SeqBAIJ(Mat A,int m,int *im,int n,int *in,Scalar *v)
647cd0e1443SSatish Balay {
648cd0e1443SSatish Balay   Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)A->data;
6492d61bbb3SSatish Balay   int        *rp,k,low,high,t,row,nrow,i,col,l,*aj = a->j;
6502d61bbb3SSatish Balay   int        *ai = a->i,*ailen = a->ilen;
6512d61bbb3SSatish Balay   int        brow,bcol,ridx,cidx,bs=a->bs,bs2=a->bs2;
6523f1db9ecSBarry Smith   MatScalar  *ap,*aa = a->a,zero = 0.0;
653cd0e1443SSatish Balay 
6543a40ed3dSBarry Smith   PetscFunctionBegin;
6552d61bbb3SSatish Balay   for (k=0; k<m; k++) { /* loop over rows */
656cd0e1443SSatish Balay     row  = im[k]; brow = row/bs;
657a8c6a408SBarry Smith     if (row < 0) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Negative row");
658a8c6a408SBarry Smith     if (row >= a->m) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Row too large");
6592d61bbb3SSatish Balay     rp   = aj + ai[brow] ; ap = aa + bs2*ai[brow] ;
6602c3acbe9SBarry Smith     nrow = ailen[brow];
6612d61bbb3SSatish Balay     for (l=0; l<n; l++) { /* loop over columns */
662a8c6a408SBarry Smith       if (in[l] < 0) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Negative column");
663a8c6a408SBarry Smith       if (in[l] >= a->n) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Column too large");
6642d61bbb3SSatish Balay       col  = in[l] ;
6652d61bbb3SSatish Balay       bcol = col/bs;
6662d61bbb3SSatish Balay       cidx = col%bs;
6672d61bbb3SSatish Balay       ridx = row%bs;
6682d61bbb3SSatish Balay       high = nrow;
6692d61bbb3SSatish Balay       low  = 0; /* assume unsorted */
6702d61bbb3SSatish Balay       while (high-low > 5) {
671cd0e1443SSatish Balay         t = (low+high)/2;
672cd0e1443SSatish Balay         if (rp[t] > bcol) high = t;
673cd0e1443SSatish Balay         else             low  = t;
674cd0e1443SSatish Balay       }
675cd0e1443SSatish Balay       for (i=low; i<high; i++) {
676cd0e1443SSatish Balay         if (rp[i] > bcol) break;
677cd0e1443SSatish Balay         if (rp[i] == bcol) {
6782d61bbb3SSatish Balay           *v++ = ap[bs2*i+bs*cidx+ridx];
6792d61bbb3SSatish Balay           goto finished;
680cd0e1443SSatish Balay         }
681cd0e1443SSatish Balay       }
6822d61bbb3SSatish Balay       *v++ = zero;
6832d61bbb3SSatish Balay       finished:;
684cd0e1443SSatish Balay     }
685cd0e1443SSatish Balay   }
6863a40ed3dSBarry Smith   PetscFunctionReturn(0);
687cd0e1443SSatish Balay }
688cd0e1443SSatish Balay 
68995d5f7c2SBarry Smith #if defined(PETSC_USE_MAT_SINGLE)
69095d5f7c2SBarry Smith #undef __FUNC__
69195d5f7c2SBarry Smith #define __FUNC__ /*<a name=""></a>*/"MatSetValuesBlocked_SeqBAIJ"
69295d5f7c2SBarry Smith int MatSetValuesBlocked_SeqBAIJ(Mat mat,int m,int *im,int n,int *in,Scalar *v,InsertMode addv)
69395d5f7c2SBarry Smith {
694563b5814SBarry Smith   Mat_SeqBAIJ *b = (Mat_SeqBAIJ*)mat->data;
695563b5814SBarry Smith   int         ierr,i,N = m*n*b->bs2;
696563b5814SBarry Smith   MatScalar   *vsingle;
69795d5f7c2SBarry Smith 
69895d5f7c2SBarry Smith   PetscFunctionBegin;
699563b5814SBarry Smith   if (N > b->setvalueslen) {
700563b5814SBarry Smith     if (b->setvaluescopy) {ierr = PetscFree(b->setvaluescopy);CHKERRQ(ierr);}
701563b5814SBarry Smith     b->setvaluescopy = (MatScalar*)PetscMalloc(N*sizeof(MatScalar));CHKPTRQ(b->setvaluescopy);
702563b5814SBarry Smith     b->setvalueslen  = N;
703563b5814SBarry Smith   }
704563b5814SBarry Smith   vsingle = b->setvaluescopy;
70595d5f7c2SBarry Smith   for (i=0; i<N; i++) {
70695d5f7c2SBarry Smith     vsingle[i] = v[i];
70795d5f7c2SBarry Smith   }
70895d5f7c2SBarry Smith   ierr = MatSetValuesBlocked_SeqBAIJ_MatScalar(mat,m,im,n,in,vsingle,addv);CHKERRQ(ierr);
70995d5f7c2SBarry Smith   PetscFunctionReturn(0);
71095d5f7c2SBarry Smith }
71195d5f7c2SBarry Smith #endif
71295d5f7c2SBarry Smith 
7132d61bbb3SSatish Balay 
7145615d1e5SSatish Balay #undef __FUNC__
715b2863d3aSBarry Smith #define __FUNC__ /*<a name=""></a>*/"MatSetValuesBlocked_SeqBAIJ"
71695d5f7c2SBarry Smith int MatSetValuesBlocked_SeqBAIJ_MatScalar(Mat A,int m,int *im,int n,int *in,MatScalar *v,InsertMode is)
71792c4ed94SBarry Smith {
71892c4ed94SBarry Smith   Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)A->data;
7198a84c255SSatish Balay   int         *rp,k,low,high,t,ii,jj,row,nrow,i,col,l,rmax,N,sorted=a->sorted;
720dd9472c6SBarry Smith   int         *imax=a->imax,*ai=a->i,*ailen=a->ilen,roworiented=a->roworiented;
721549d3d68SSatish Balay   int         *aj=a->j,nonew=a->nonew,bs2=a->bs2,bs=a->bs,stepval,ierr;
72295d5f7c2SBarry Smith   MatScalar      *value = v,*ap,*aa = a->a,*bap;
72392c4ed94SBarry Smith 
7243a40ed3dSBarry Smith   PetscFunctionBegin;
7250e324ae4SSatish Balay   if (roworiented) {
7260e324ae4SSatish Balay     stepval = (n-1)*bs;
7270e324ae4SSatish Balay   } else {
7280e324ae4SSatish Balay     stepval = (m-1)*bs;
7290e324ae4SSatish Balay   }
73092c4ed94SBarry Smith   for (k=0; k<m; k++) { /* loop over added rows */
73192c4ed94SBarry Smith     row  = im[k];
7325ef9f2a5SBarry Smith     if (row < 0) continue;
733aa482453SBarry Smith #if defined(PETSC_USE_BOPT_g)
734a8c6a408SBarry Smith     if (row >= a->mbs) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Row too large");
73592c4ed94SBarry Smith #endif
73692c4ed94SBarry Smith     rp   = aj + ai[row];
73792c4ed94SBarry Smith     ap   = aa + bs2*ai[row];
73892c4ed94SBarry Smith     rmax = imax[row];
73992c4ed94SBarry Smith     nrow = ailen[row];
74092c4ed94SBarry Smith     low  = 0;
74192c4ed94SBarry Smith     for (l=0; l<n; l++) { /* loop over added columns */
7425ef9f2a5SBarry Smith       if (in[l] < 0) continue;
743aa482453SBarry Smith #if defined(PETSC_USE_BOPT_g)
744a8c6a408SBarry Smith       if (in[l] >= a->nbs) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Column too large");
74592c4ed94SBarry Smith #endif
74692c4ed94SBarry Smith       col = in[l];
74792c4ed94SBarry Smith       if (roworiented) {
7480e324ae4SSatish Balay         value = v + k*(stepval+bs)*bs + l*bs;
7490e324ae4SSatish Balay       } else {
7500e324ae4SSatish Balay         value = v + l*(stepval+bs)*bs + k*bs;
75192c4ed94SBarry Smith       }
75292c4ed94SBarry Smith       if (!sorted) low = 0; high = nrow;
75392c4ed94SBarry Smith       while (high-low > 7) {
75492c4ed94SBarry Smith         t = (low+high)/2;
75592c4ed94SBarry Smith         if (rp[t] > col) high = t;
75692c4ed94SBarry Smith         else             low  = t;
75792c4ed94SBarry Smith       }
75892c4ed94SBarry Smith       for (i=low; i<high; i++) {
75992c4ed94SBarry Smith         if (rp[i] > col) break;
76092c4ed94SBarry Smith         if (rp[i] == col) {
7618a84c255SSatish Balay           bap  = ap +  bs2*i;
7620e324ae4SSatish Balay           if (roworiented) {
7638a84c255SSatish Balay             if (is == ADD_VALUES) {
764dd9472c6SBarry Smith               for (ii=0; ii<bs; ii++,value+=stepval) {
765dd9472c6SBarry Smith                 for (jj=ii; jj<bs2; jj+=bs) {
7668a84c255SSatish Balay                   bap[jj] += *value++;
767dd9472c6SBarry Smith                 }
768dd9472c6SBarry Smith               }
7690e324ae4SSatish Balay             } else {
770dd9472c6SBarry Smith               for (ii=0; ii<bs; ii++,value+=stepval) {
771dd9472c6SBarry Smith                 for (jj=ii; jj<bs2; jj+=bs) {
7720e324ae4SSatish Balay                   bap[jj] = *value++;
7738a84c255SSatish Balay                 }
774dd9472c6SBarry Smith               }
775dd9472c6SBarry Smith             }
7760e324ae4SSatish Balay           } else {
7770e324ae4SSatish Balay             if (is == ADD_VALUES) {
778dd9472c6SBarry Smith               for (ii=0; ii<bs; ii++,value+=stepval) {
779dd9472c6SBarry Smith                 for (jj=0; jj<bs; jj++) {
7800e324ae4SSatish Balay                   *bap++ += *value++;
781dd9472c6SBarry Smith                 }
782dd9472c6SBarry Smith               }
7830e324ae4SSatish Balay             } else {
784dd9472c6SBarry Smith               for (ii=0; ii<bs; ii++,value+=stepval) {
785dd9472c6SBarry Smith                 for (jj=0; jj<bs; jj++) {
7860e324ae4SSatish Balay                   *bap++  = *value++;
7870e324ae4SSatish Balay                 }
7888a84c255SSatish Balay               }
789dd9472c6SBarry Smith             }
790dd9472c6SBarry Smith           }
791f1241b54SBarry Smith           goto noinsert2;
79292c4ed94SBarry Smith         }
79392c4ed94SBarry Smith       }
79489280ab3SLois Curfman McInnes       if (nonew == 1) goto noinsert2;
795a8c6a408SBarry Smith       else if (nonew == -1) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Inserting a new nonzero in the matrix");
79692c4ed94SBarry Smith       if (nrow >= rmax) {
79792c4ed94SBarry Smith         /* there is no extra room in row, therefore enlarge */
79892c4ed94SBarry Smith         int       new_nz = ai[a->mbs] + CHUNKSIZE,len,*new_i,*new_j;
7993f1db9ecSBarry Smith         MatScalar *new_a;
80092c4ed94SBarry Smith 
801a8c6a408SBarry Smith         if (nonew == -2) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Inserting a new nonzero in the matrix");
80289280ab3SLois Curfman McInnes 
80392c4ed94SBarry Smith         /* malloc new storage space */
8043f1db9ecSBarry Smith         len     = new_nz*(sizeof(int)+bs2*sizeof(MatScalar))+(a->mbs+1)*sizeof(int);
8053f1db9ecSBarry Smith         new_a   = (MatScalar*)PetscMalloc(len);CHKPTRQ(new_a);
80692c4ed94SBarry Smith         new_j   = (int*)(new_a + bs2*new_nz);
80792c4ed94SBarry Smith         new_i   = new_j + new_nz;
80892c4ed94SBarry Smith 
80992c4ed94SBarry Smith         /* copy over old data into new slots */
81092c4ed94SBarry Smith         for (ii=0; ii<row+1; ii++) {new_i[ii] = ai[ii];}
81192c4ed94SBarry Smith         for (ii=row+1; ii<a->mbs+1; ii++) {new_i[ii] = ai[ii]+CHUNKSIZE;}
812549d3d68SSatish Balay         ierr = PetscMemcpy(new_j,aj,(ai[row]+nrow)*sizeof(int));CHKERRQ(ierr);
81392c4ed94SBarry Smith         len  = (new_nz - CHUNKSIZE - ai[row] - nrow);
814549d3d68SSatish Balay         ierr = PetscMemcpy(new_j+ai[row]+nrow+CHUNKSIZE,aj+ai[row]+nrow,len*sizeof(int));CHKERRQ(ierr);
815549d3d68SSatish Balay         ierr = PetscMemcpy(new_a,aa,(ai[row]+nrow)*bs2*sizeof(MatScalar));CHKERRQ(ierr);
816549d3d68SSatish Balay         ierr = PetscMemzero(new_a+bs2*(ai[row]+nrow),bs2*CHUNKSIZE*sizeof(MatScalar));CHKERRQ(ierr);
817549d3d68SSatish Balay         ierr = PetscMemcpy(new_a+bs2*(ai[row]+nrow+CHUNKSIZE),aa+bs2*(ai[row]+nrow),bs2*len*sizeof(MatScalar));CHKERRQ(ierr);
81892c4ed94SBarry Smith         /* free up old matrix storage */
819606d414cSSatish Balay         ierr = PetscFree(a->a);CHKERRQ(ierr);
820606d414cSSatish Balay         if (!a->singlemalloc) {
821606d414cSSatish Balay           ierr = PetscFree(a->i);CHKERRQ(ierr);
822606d414cSSatish Balay           ierr = PetscFree(a->j);CHKERRQ(ierr);
823606d414cSSatish Balay         }
82492c4ed94SBarry Smith         aa = a->a = new_a; ai = a->i = new_i; aj = a->j = new_j;
825c4992f7dSBarry Smith         a->singlemalloc = PETSC_TRUE;
82692c4ed94SBarry Smith 
82792c4ed94SBarry Smith         rp   = aj + ai[row]; ap = aa + bs2*ai[row];
82892c4ed94SBarry Smith         rmax = imax[row] = imax[row] + CHUNKSIZE;
8293f1db9ecSBarry Smith         PLogObjectMemory(A,CHUNKSIZE*(sizeof(int) + bs2*sizeof(MatScalar)));
83092c4ed94SBarry Smith         a->maxnz += bs2*CHUNKSIZE;
83192c4ed94SBarry Smith         a->reallocs++;
83292c4ed94SBarry Smith         a->nz++;
83392c4ed94SBarry Smith       }
83492c4ed94SBarry Smith       N = nrow++ - 1;
83592c4ed94SBarry Smith       /* shift up all the later entries in this row */
83692c4ed94SBarry Smith       for (ii=N; ii>=i; ii--) {
83792c4ed94SBarry Smith         rp[ii+1] = rp[ii];
838549d3d68SSatish Balay         ierr = PetscMemcpy(ap+bs2*(ii+1),ap+bs2*(ii),bs2*sizeof(MatScalar));CHKERRQ(ierr);
83992c4ed94SBarry Smith       }
840549d3d68SSatish Balay       if (N >= i) {
841549d3d68SSatish Balay         ierr = PetscMemzero(ap+bs2*i,bs2*sizeof(MatScalar));CHKERRQ(ierr);
842549d3d68SSatish Balay       }
84392c4ed94SBarry Smith       rp[i] = col;
8448a84c255SSatish Balay       bap   = ap +  bs2*i;
8450e324ae4SSatish Balay       if (roworiented) {
846dd9472c6SBarry Smith         for (ii=0; ii<bs; ii++,value+=stepval) {
847dd9472c6SBarry Smith           for (jj=ii; jj<bs2; jj+=bs) {
8480e324ae4SSatish Balay             bap[jj] = *value++;
849dd9472c6SBarry Smith           }
850dd9472c6SBarry Smith         }
8510e324ae4SSatish Balay       } else {
852dd9472c6SBarry Smith         for (ii=0; ii<bs; ii++,value+=stepval) {
853dd9472c6SBarry Smith           for (jj=0; jj<bs; jj++) {
8540e324ae4SSatish Balay             *bap++  = *value++;
8550e324ae4SSatish Balay           }
856dd9472c6SBarry Smith         }
857dd9472c6SBarry Smith       }
858f1241b54SBarry Smith       noinsert2:;
85992c4ed94SBarry Smith       low = i;
86092c4ed94SBarry Smith     }
86192c4ed94SBarry Smith     ailen[row] = nrow;
86292c4ed94SBarry Smith   }
8633a40ed3dSBarry Smith   PetscFunctionReturn(0);
86492c4ed94SBarry Smith }
86592c4ed94SBarry Smith 
866f2501298SSatish Balay 
8675615d1e5SSatish Balay #undef __FUNC__
868b2863d3aSBarry Smith #define __FUNC__ /*<a name=""></a>*/"MatAssemblyEnd_SeqBAIJ"
8698f6be9afSLois Curfman McInnes int MatAssemblyEnd_SeqBAIJ(Mat A,MatAssemblyType mode)
870584200bdSSatish Balay {
871584200bdSSatish Balay   Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)A->data;
872584200bdSSatish Balay   int        fshift = 0,i,j,*ai = a->i,*aj = a->j,*imax = a->imax;
873a7c10996SSatish Balay   int        m = a->m,*ip,N,*ailen = a->ilen;
874549d3d68SSatish Balay   int        mbs = a->mbs,bs2 = a->bs2,rmax = 0,ierr;
8753f1db9ecSBarry Smith   MatScalar  *aa = a->a,*ap;
876584200bdSSatish Balay 
8773a40ed3dSBarry Smith   PetscFunctionBegin;
8783a40ed3dSBarry Smith   if (mode == MAT_FLUSH_ASSEMBLY) PetscFunctionReturn(0);
879584200bdSSatish Balay 
88043ee02c3SBarry Smith   if (m) rmax = ailen[0];
881584200bdSSatish Balay   for (i=1; i<mbs; i++) {
882584200bdSSatish Balay     /* move each row back by the amount of empty slots (fshift) before it*/
883584200bdSSatish Balay     fshift += imax[i-1] - ailen[i-1];
884d402145bSBarry Smith     rmax   = PetscMax(rmax,ailen[i]);
885584200bdSSatish Balay     if (fshift) {
886a7c10996SSatish Balay       ip = aj + ai[i]; ap = aa + bs2*ai[i];
887584200bdSSatish Balay       N = ailen[i];
888584200bdSSatish Balay       for (j=0; j<N; j++) {
889584200bdSSatish Balay         ip[j-fshift] = ip[j];
890549d3d68SSatish Balay         ierr = PetscMemcpy(ap+(j-fshift)*bs2,ap+j*bs2,bs2*sizeof(MatScalar));CHKERRQ(ierr);
891584200bdSSatish Balay       }
892584200bdSSatish Balay     }
893584200bdSSatish Balay     ai[i] = ai[i-1] + ailen[i-1];
894584200bdSSatish Balay   }
895584200bdSSatish Balay   if (mbs) {
896584200bdSSatish Balay     fshift += imax[mbs-1] - ailen[mbs-1];
897584200bdSSatish Balay     ai[mbs] = ai[mbs-1] + ailen[mbs-1];
898584200bdSSatish Balay   }
899584200bdSSatish Balay   /* reset ilen and imax for each row */
900584200bdSSatish Balay   for (i=0; i<mbs; i++) {
901584200bdSSatish Balay     ailen[i] = imax[i] = ai[i+1] - ai[i];
902584200bdSSatish Balay   }
903a7c10996SSatish Balay   a->nz = ai[mbs];
904584200bdSSatish Balay 
905584200bdSSatish Balay   /* diagonals may have moved, so kill the diagonal pointers */
906584200bdSSatish Balay   if (fshift && a->diag) {
907606d414cSSatish Balay     ierr = PetscFree(a->diag);CHKERRQ(ierr);
908584200bdSSatish Balay     PLogObjectMemory(A,-(m+1)*sizeof(int));
909584200bdSSatish Balay     a->diag = 0;
910584200bdSSatish Balay   }
9113d2013a6SLois Curfman McInnes   PLogInfo(A,"MatAssemblyEnd_SeqBAIJ:Matrix size: %d X %d, block size %d; storage space: %d unneeded, %d used\n",
912219d9a1aSLois Curfman McInnes            m,a->n,a->bs,fshift*bs2,a->nz*bs2);
9133d2013a6SLois Curfman McInnes   PLogInfo(A,"MatAssemblyEnd_SeqBAIJ:Number of mallocs during MatSetValues is %d\n",
914584200bdSSatish Balay            a->reallocs);
915d402145bSBarry Smith   PLogInfo(A,"MatAssemblyEnd_SeqBAIJ:Most nonzeros blocks in any row is %d\n",rmax);
916e2f3b5e9SSatish Balay   a->reallocs          = 0;
9170e6d2581SBarry Smith   A->info.nz_unneeded  = (PetscReal)fshift*bs2;
9184e220ebcSLois Curfman McInnes 
9193a40ed3dSBarry Smith   PetscFunctionReturn(0);
920584200bdSSatish Balay }
921584200bdSSatish Balay 
9225a838052SSatish Balay 
923bea157c4SSatish Balay 
924bea157c4SSatish Balay /*
925bea157c4SSatish Balay    This function returns an array of flags which indicate the locations of contiguous
926bea157c4SSatish Balay    blocks that should be zeroed. for eg: if bs = 3  and is = [0,1,2,3,5,6,7,8,9]
927bea157c4SSatish Balay    then the resulting sizes = [3,1,1,3,1] correspondig to sets [(0,1,2),(3),(5),(6,7,8),(9)]
928bea157c4SSatish Balay    Assume: sizes should be long enough to hold all the values.
929bea157c4SSatish Balay */
9305615d1e5SSatish Balay #undef __FUNC__
931b2863d3aSBarry Smith #define __FUNC__ /*<a name=""></a>*/"MatZeroRows_SeqBAIJ_Check_Blocks"
932bea157c4SSatish Balay static int MatZeroRows_SeqBAIJ_Check_Blocks(int idx[],int n,int bs,int sizes[], int *bs_max)
933d9b7c43dSSatish Balay {
934bea157c4SSatish Balay   int        i,j,k,row;
935bea157c4SSatish Balay   PetscTruth flg;
9363a40ed3dSBarry Smith 
937433994e6SBarry Smith   PetscFunctionBegin;
938bea157c4SSatish Balay   for (i=0,j=0; i<n; j++) {
939bea157c4SSatish Balay     row = idx[i];
940bea157c4SSatish Balay     if (row%bs!=0) { /* Not the begining of a block */
941bea157c4SSatish Balay       sizes[j] = 1;
942bea157c4SSatish Balay       i++;
943e4fda26cSSatish Balay     } else if (i+bs > n) { /* complete block doesn't exist (at idx end) */
944bea157c4SSatish Balay       sizes[j] = 1;         /* Also makes sure atleast 'bs' values exist for next else */
945bea157c4SSatish Balay       i++;
946bea157c4SSatish Balay     } else { /* Begining of the block, so check if the complete block exists */
947bea157c4SSatish Balay       flg = PETSC_TRUE;
948bea157c4SSatish Balay       for (k=1; k<bs; k++) {
949bea157c4SSatish Balay         if (row+k != idx[i+k]) { /* break in the block */
950bea157c4SSatish Balay           flg = PETSC_FALSE;
951bea157c4SSatish Balay           break;
952d9b7c43dSSatish Balay         }
953bea157c4SSatish Balay       }
954bea157c4SSatish Balay       if (flg == PETSC_TRUE) { /* No break in the bs */
955bea157c4SSatish Balay         sizes[j] = bs;
956bea157c4SSatish Balay         i+= bs;
957bea157c4SSatish Balay       } else {
958bea157c4SSatish Balay         sizes[j] = 1;
959bea157c4SSatish Balay         i++;
960bea157c4SSatish Balay       }
961bea157c4SSatish Balay     }
962bea157c4SSatish Balay   }
963bea157c4SSatish Balay   *bs_max = j;
9643a40ed3dSBarry Smith   PetscFunctionReturn(0);
965d9b7c43dSSatish Balay }
966d9b7c43dSSatish Balay 
9675615d1e5SSatish Balay #undef __FUNC__
968b2863d3aSBarry Smith #define __FUNC__ /*<a name=""></a>*/"MatZeroRows_SeqBAIJ"
9698f6be9afSLois Curfman McInnes int MatZeroRows_SeqBAIJ(Mat A,IS is,Scalar *diag)
970d9b7c43dSSatish Balay {
971d9b7c43dSSatish Balay   Mat_SeqBAIJ *baij=(Mat_SeqBAIJ*)A->data;
972b6815fffSBarry Smith   int         ierr,i,j,k,count,is_n,*is_idx,*rows;
973bea157c4SSatish Balay   int         bs=baij->bs,bs2=baij->bs2,*sizes,row,bs_max;
9743f1db9ecSBarry Smith   Scalar      zero = 0.0;
9753f1db9ecSBarry Smith   MatScalar   *aa;
976d9b7c43dSSatish Balay 
9773a40ed3dSBarry Smith   PetscFunctionBegin;
978d9b7c43dSSatish Balay   /* Make a copy of the IS and  sort it */
979d9b7c43dSSatish Balay   ierr = ISGetSize(is,&is_n);CHKERRQ(ierr);
980d9b7c43dSSatish Balay   ierr = ISGetIndices(is,&is_idx);CHKERRQ(ierr);
981d9b7c43dSSatish Balay 
982bea157c4SSatish Balay   /* allocate memory for rows,sizes */
983bea157c4SSatish Balay   rows  = (int*)PetscMalloc((3*is_n+1)*sizeof(int));CHKPTRQ(rows);
984bea157c4SSatish Balay   sizes = rows + is_n;
985bea157c4SSatish Balay 
986563b5814SBarry Smith   /* copy IS values to rows, and sort them */
987bea157c4SSatish Balay   for (i=0; i<is_n; i++) { rows[i] = is_idx[i]; }
988bea157c4SSatish Balay   ierr = PetscSortInt(is_n,rows);CHKERRQ(ierr);
989dffd3267SBarry Smith   if (baij->keepzeroedrows) {
990dffd3267SBarry Smith     for (i=0; i<is_n; i++) { sizes[i] = 1; }
991dffd3267SBarry Smith     bs_max = is_n;
992dffd3267SBarry Smith   } else {
993bea157c4SSatish Balay     ierr = MatZeroRows_SeqBAIJ_Check_Blocks(rows,is_n,bs,sizes,&bs_max);CHKERRQ(ierr);
994dffd3267SBarry Smith   }
995b97a56abSSatish Balay   ierr = ISRestoreIndices(is,&is_idx);CHKERRQ(ierr);
996bea157c4SSatish Balay 
997bea157c4SSatish Balay   for (i=0,j=0; i<bs_max; j+=sizes[i],i++) {
998bea157c4SSatish Balay     row   = rows[j];
999b6815fffSBarry Smith     if (row < 0 || row > baij->m) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,0,"row %d out of range",row);
1000bea157c4SSatish Balay     count = (baij->i[row/bs +1] - baij->i[row/bs])*bs;
1001bea157c4SSatish Balay     aa    = baij->a + baij->i[row/bs]*bs2 + (row%bs);
1002dffd3267SBarry Smith     if (sizes[i] == bs && !baij->keepzeroedrows) {
1003bea157c4SSatish Balay       if (diag) {
1004bea157c4SSatish Balay         if (baij->ilen[row/bs] > 0) {
1005bea157c4SSatish Balay           baij->ilen[row/bs]       = 1;
1006bea157c4SSatish Balay           baij->j[baij->i[row/bs]] = row/bs;
1007bea157c4SSatish Balay           ierr = PetscMemzero(aa,count*bs*sizeof(MatScalar));CHKERRQ(ierr);
1008a07cd24cSSatish Balay         }
1009563b5814SBarry Smith         /* Now insert all the diagonal values for this bs */
1010bea157c4SSatish Balay         for (k=0; k<bs; k++) {
1011bea157c4SSatish Balay           ierr = (*A->ops->setvalues)(A,1,rows+j+k,1,rows+j+k,diag,INSERT_VALUES);CHKERRQ(ierr);
1012bea157c4SSatish Balay         }
1013bea157c4SSatish Balay       } else { /* (!diag) */
1014bea157c4SSatish Balay         baij->ilen[row/bs] = 0;
1015bea157c4SSatish Balay       } /* end (!diag) */
1016bea157c4SSatish Balay     } else { /* (sizes[i] != bs) */
1017aa482453SBarry Smith #if defined (PETSC_USE_DEBUG)
1018bea157c4SSatish Balay       if (sizes[i] != 1) SETERRQ(1,0,"Internal Error. Value should be 1");
1019bea157c4SSatish Balay #endif
1020bea157c4SSatish Balay       for (k=0; k<count; k++) {
1021d9b7c43dSSatish Balay         aa[0] =  zero;
1022d9b7c43dSSatish Balay         aa    += bs;
1023d9b7c43dSSatish Balay       }
1024d9b7c43dSSatish Balay       if (diag) {
1025f830108cSBarry Smith         ierr = (*A->ops->setvalues)(A,1,rows+j,1,rows+j,diag,INSERT_VALUES);CHKERRQ(ierr);
1026d9b7c43dSSatish Balay       }
1027d9b7c43dSSatish Balay     }
1028bea157c4SSatish Balay   }
1029bea157c4SSatish Balay 
1030606d414cSSatish Balay   ierr = PetscFree(rows);CHKERRQ(ierr);
10319a8dea36SBarry Smith   ierr = MatAssemblyEnd_SeqBAIJ(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
10323a40ed3dSBarry Smith   PetscFunctionReturn(0);
1033d9b7c43dSSatish Balay }
10341c351548SSatish Balay 
10355615d1e5SSatish Balay #undef __FUNC__
1036b2863d3aSBarry Smith #define __FUNC__ /*<a name=""></a>*/"MatSetValues_SeqBAIJ"
10372d61bbb3SSatish Balay int MatSetValues_SeqBAIJ(Mat A,int m,int *im,int n,int *in,Scalar *v,InsertMode is)
10382d61bbb3SSatish Balay {
10392d61bbb3SSatish Balay   Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)A->data;
10402d61bbb3SSatish Balay   int         *rp,k,low,high,t,ii,row,nrow,i,col,l,rmax,N,sorted=a->sorted;
10412d61bbb3SSatish Balay   int         *imax=a->imax,*ai=a->i,*ailen=a->ilen,roworiented=a->roworiented;
10422d61bbb3SSatish Balay   int         *aj=a->j,nonew=a->nonew,bs=a->bs,brow,bcol;
1043549d3d68SSatish Balay   int         ridx,cidx,bs2=a->bs2,ierr;
10443f1db9ecSBarry Smith   MatScalar   *ap,value,*aa=a->a,*bap;
10452d61bbb3SSatish Balay 
10462d61bbb3SSatish Balay   PetscFunctionBegin;
10472d61bbb3SSatish Balay   for (k=0; k<m; k++) { /* loop over added rows */
10482d61bbb3SSatish Balay     row  = im[k]; brow = row/bs;
10495ef9f2a5SBarry Smith     if (row < 0) continue;
1050aa482453SBarry Smith #if defined(PETSC_USE_BOPT_g)
105132e87ba3SBarry Smith     if (row >= a->m) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,0,"Row too large: row %d max %d",row,a->m);
10522d61bbb3SSatish Balay #endif
10532d61bbb3SSatish Balay     rp   = aj + ai[brow];
10542d61bbb3SSatish Balay     ap   = aa + bs2*ai[brow];
10552d61bbb3SSatish Balay     rmax = imax[brow];
10562d61bbb3SSatish Balay     nrow = ailen[brow];
10572d61bbb3SSatish Balay     low  = 0;
10582d61bbb3SSatish Balay     for (l=0; l<n; l++) { /* loop over added columns */
10595ef9f2a5SBarry Smith       if (in[l] < 0) continue;
1060aa482453SBarry Smith #if defined(PETSC_USE_BOPT_g)
106132e87ba3SBarry Smith       if (in[l] >= a->n) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,0,"Column too large: col %d max %d",in[l],a->n);
10622d61bbb3SSatish Balay #endif
10632d61bbb3SSatish Balay       col = in[l]; bcol = col/bs;
10642d61bbb3SSatish Balay       ridx = row % bs; cidx = col % bs;
10652d61bbb3SSatish Balay       if (roworiented) {
10665ef9f2a5SBarry Smith         value = v[l + k*n];
10672d61bbb3SSatish Balay       } else {
10682d61bbb3SSatish Balay         value = v[k + l*m];
10692d61bbb3SSatish Balay       }
10702d61bbb3SSatish Balay       if (!sorted) low = 0; high = nrow;
10712d61bbb3SSatish Balay       while (high-low > 7) {
10722d61bbb3SSatish Balay         t = (low+high)/2;
10732d61bbb3SSatish Balay         if (rp[t] > bcol) high = t;
10742d61bbb3SSatish Balay         else              low  = t;
10752d61bbb3SSatish Balay       }
10762d61bbb3SSatish Balay       for (i=low; i<high; i++) {
10772d61bbb3SSatish Balay         if (rp[i] > bcol) break;
10782d61bbb3SSatish Balay         if (rp[i] == bcol) {
10792d61bbb3SSatish Balay           bap  = ap +  bs2*i + bs*cidx + ridx;
10802d61bbb3SSatish Balay           if (is == ADD_VALUES) *bap += value;
10812d61bbb3SSatish Balay           else                  *bap  = value;
10822d61bbb3SSatish Balay           goto noinsert1;
10832d61bbb3SSatish Balay         }
10842d61bbb3SSatish Balay       }
10852d61bbb3SSatish Balay       if (nonew == 1) goto noinsert1;
10862d61bbb3SSatish Balay       else if (nonew == -1) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Inserting a new nonzero in the matrix");
10872d61bbb3SSatish Balay       if (nrow >= rmax) {
10882d61bbb3SSatish Balay         /* there is no extra room in row, therefore enlarge */
10892d61bbb3SSatish Balay         int       new_nz = ai[a->mbs] + CHUNKSIZE,len,*new_i,*new_j;
10903f1db9ecSBarry Smith         MatScalar *new_a;
10912d61bbb3SSatish Balay 
10922d61bbb3SSatish Balay         if (nonew == -2) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Inserting a new nonzero in the matrix");
10932d61bbb3SSatish Balay 
10942d61bbb3SSatish Balay         /* Malloc new storage space */
10953f1db9ecSBarry Smith         len     = new_nz*(sizeof(int)+bs2*sizeof(MatScalar))+(a->mbs+1)*sizeof(int);
10963f1db9ecSBarry Smith         new_a   = (MatScalar*)PetscMalloc(len);CHKPTRQ(new_a);
10972d61bbb3SSatish Balay         new_j   = (int*)(new_a + bs2*new_nz);
10982d61bbb3SSatish Balay         new_i   = new_j + new_nz;
10992d61bbb3SSatish Balay 
11002d61bbb3SSatish Balay         /* copy over old data into new slots */
11012d61bbb3SSatish Balay         for (ii=0; ii<brow+1; ii++) {new_i[ii] = ai[ii];}
11022d61bbb3SSatish Balay         for (ii=brow+1; ii<a->mbs+1; ii++) {new_i[ii] = ai[ii]+CHUNKSIZE;}
1103549d3d68SSatish Balay         ierr = PetscMemcpy(new_j,aj,(ai[brow]+nrow)*sizeof(int));CHKERRQ(ierr);
11042d61bbb3SSatish Balay         len  = (new_nz - CHUNKSIZE - ai[brow] - nrow);
1105549d3d68SSatish Balay         ierr = PetscMemcpy(new_j+ai[brow]+nrow+CHUNKSIZE,aj+ai[brow]+nrow,len*sizeof(int));CHKERRQ(ierr);
1106549d3d68SSatish Balay         ierr = PetscMemcpy(new_a,aa,(ai[brow]+nrow)*bs2*sizeof(MatScalar));CHKERRQ(ierr);
1107549d3d68SSatish Balay         ierr = PetscMemzero(new_a+bs2*(ai[brow]+nrow),bs2*CHUNKSIZE*sizeof(MatScalar));CHKERRQ(ierr);
1108549d3d68SSatish Balay         ierr = PetscMemcpy(new_a+bs2*(ai[brow]+nrow+CHUNKSIZE),aa+bs2*(ai[brow]+nrow),bs2*len*sizeof(MatScalar));CHKERRQ(ierr);
11092d61bbb3SSatish Balay         /* free up old matrix storage */
1110606d414cSSatish Balay         ierr = PetscFree(a->a);CHKERRQ(ierr);
1111606d414cSSatish Balay         if (!a->singlemalloc) {
1112606d414cSSatish Balay           ierr = PetscFree(a->i);CHKERRQ(ierr);
1113606d414cSSatish Balay           ierr = PetscFree(a->j);CHKERRQ(ierr);
1114606d414cSSatish Balay         }
11152d61bbb3SSatish Balay         aa = a->a = new_a; ai = a->i = new_i; aj = a->j = new_j;
1116c4992f7dSBarry Smith         a->singlemalloc = PETSC_TRUE;
11172d61bbb3SSatish Balay 
11182d61bbb3SSatish Balay         rp   = aj + ai[brow]; ap = aa + bs2*ai[brow];
11192d61bbb3SSatish Balay         rmax = imax[brow] = imax[brow] + CHUNKSIZE;
11203f1db9ecSBarry Smith         PLogObjectMemory(A,CHUNKSIZE*(sizeof(int) + bs2*sizeof(MatScalar)));
11212d61bbb3SSatish Balay         a->maxnz += bs2*CHUNKSIZE;
11222d61bbb3SSatish Balay         a->reallocs++;
11232d61bbb3SSatish Balay         a->nz++;
11242d61bbb3SSatish Balay       }
11252d61bbb3SSatish Balay       N = nrow++ - 1;
11262d61bbb3SSatish Balay       /* shift up all the later entries in this row */
11272d61bbb3SSatish Balay       for (ii=N; ii>=i; ii--) {
11282d61bbb3SSatish Balay         rp[ii+1] = rp[ii];
1129549d3d68SSatish Balay         ierr     = PetscMemcpy(ap+bs2*(ii+1),ap+bs2*(ii),bs2*sizeof(MatScalar));CHKERRQ(ierr);
11302d61bbb3SSatish Balay       }
1131549d3d68SSatish Balay       if (N>=i) {
1132549d3d68SSatish Balay         ierr = PetscMemzero(ap+bs2*i,bs2*sizeof(MatScalar));CHKERRQ(ierr);
1133549d3d68SSatish Balay       }
11342d61bbb3SSatish Balay       rp[i]                      = bcol;
11352d61bbb3SSatish Balay       ap[bs2*i + bs*cidx + ridx] = value;
11362d61bbb3SSatish Balay       noinsert1:;
11372d61bbb3SSatish Balay       low = i;
11382d61bbb3SSatish Balay     }
11392d61bbb3SSatish Balay     ailen[brow] = nrow;
11402d61bbb3SSatish Balay   }
11412d61bbb3SSatish Balay   PetscFunctionReturn(0);
11422d61bbb3SSatish Balay }
11432d61bbb3SSatish Balay 
11440e6d2581SBarry Smith extern int MatLUFactorSymbolic_SeqBAIJ(Mat,IS,IS,PetscReal,Mat*);
11450e6d2581SBarry Smith extern int MatLUFactor_SeqBAIJ(Mat,IS,IS,PetscReal);
11462d61bbb3SSatish Balay extern int MatIncreaseOverlap_SeqBAIJ(Mat,int,IS*,int);
11477b2a1423SBarry Smith extern int MatGetSubMatrix_SeqBAIJ(Mat,IS,IS,int,MatReuse,Mat*);
11487b2a1423SBarry Smith extern int MatGetSubMatrices_SeqBAIJ(Mat,int,IS*,IS*,MatReuse,Mat**);
11497c922b88SBarry Smith extern int MatMultTranspose_SeqBAIJ(Mat,Vec,Vec);
11507c922b88SBarry Smith extern int MatMultTransposeAdd_SeqBAIJ(Mat,Vec,Vec,Vec);
11512d61bbb3SSatish Balay extern int MatScale_SeqBAIJ(Scalar*,Mat);
11520e6d2581SBarry Smith extern int MatNorm_SeqBAIJ(Mat,NormType,PetscReal *);
11532d61bbb3SSatish Balay extern int MatEqual_SeqBAIJ(Mat,Mat,PetscTruth*);
11542d61bbb3SSatish Balay extern int MatGetDiagonal_SeqBAIJ(Mat,Vec);
11552d61bbb3SSatish Balay extern int MatDiagonalScale_SeqBAIJ(Mat,Vec,Vec);
11562d61bbb3SSatish Balay extern int MatGetInfo_SeqBAIJ(Mat,MatInfoType,MatInfo *);
11572d61bbb3SSatish Balay extern int MatZeroEntries_SeqBAIJ(Mat);
11582d61bbb3SSatish Balay 
11592d61bbb3SSatish Balay extern int MatSolve_SeqBAIJ_N(Mat,Vec,Vec);
11602d61bbb3SSatish Balay extern int MatSolve_SeqBAIJ_1(Mat,Vec,Vec);
11612d61bbb3SSatish Balay extern int MatSolve_SeqBAIJ_2(Mat,Vec,Vec);
11622d61bbb3SSatish Balay extern int MatSolve_SeqBAIJ_3(Mat,Vec,Vec);
11632d61bbb3SSatish Balay extern int MatSolve_SeqBAIJ_4(Mat,Vec,Vec);
11642d61bbb3SSatish Balay extern int MatSolve_SeqBAIJ_5(Mat,Vec,Vec);
116515091d37SBarry Smith extern int MatSolve_SeqBAIJ_6(Mat,Vec,Vec);
11662d61bbb3SSatish Balay extern int MatSolve_SeqBAIJ_7(Mat,Vec,Vec);
11677c922b88SBarry Smith extern int MatSolveTranspose_SeqBAIJ_7(Mat,Vec,Vec);
11687c922b88SBarry Smith extern int MatSolveTranspose_SeqBAIJ_6(Mat,Vec,Vec);
11697c922b88SBarry Smith extern int MatSolveTranspose_SeqBAIJ_5(Mat,Vec,Vec);
11707c922b88SBarry Smith extern int MatSolveTranspose_SeqBAIJ_4(Mat,Vec,Vec);
11717c922b88SBarry Smith extern int MatSolveTranspose_SeqBAIJ_3(Mat,Vec,Vec);
11727c922b88SBarry Smith extern int MatSolveTranspose_SeqBAIJ_2(Mat,Vec,Vec);
11737c922b88SBarry Smith extern int MatSolveTranspose_SeqBAIJ_1(Mat,Vec,Vec);
11742d61bbb3SSatish Balay 
11752d61bbb3SSatish Balay extern int MatLUFactorNumeric_SeqBAIJ_N(Mat,Mat*);
11762d61bbb3SSatish Balay extern int MatLUFactorNumeric_SeqBAIJ_1(Mat,Mat*);
11772d61bbb3SSatish Balay extern int MatLUFactorNumeric_SeqBAIJ_2(Mat,Mat*);
11782d61bbb3SSatish Balay extern int MatLUFactorNumeric_SeqBAIJ_3(Mat,Mat*);
11792d61bbb3SSatish Balay extern int MatLUFactorNumeric_SeqBAIJ_4(Mat,Mat*);
11802d61bbb3SSatish Balay extern int MatLUFactorNumeric_SeqBAIJ_5(Mat,Mat*);
118115091d37SBarry Smith extern int MatLUFactorNumeric_SeqBAIJ_6(Mat,Mat*);
11822d61bbb3SSatish Balay 
11832d61bbb3SSatish Balay extern int MatMult_SeqBAIJ_1(Mat,Vec,Vec);
11842d61bbb3SSatish Balay extern int MatMult_SeqBAIJ_2(Mat,Vec,Vec);
11852d61bbb3SSatish Balay extern int MatMult_SeqBAIJ_3(Mat,Vec,Vec);
11862d61bbb3SSatish Balay extern int MatMult_SeqBAIJ_4(Mat,Vec,Vec);
11872d61bbb3SSatish Balay extern int MatMult_SeqBAIJ_5(Mat,Vec,Vec);
118815091d37SBarry Smith extern int MatMult_SeqBAIJ_6(Mat,Vec,Vec);
11892d61bbb3SSatish Balay extern int MatMult_SeqBAIJ_7(Mat,Vec,Vec);
11902d61bbb3SSatish Balay extern int MatMult_SeqBAIJ_N(Mat,Vec,Vec);
11912d61bbb3SSatish Balay 
11922d61bbb3SSatish Balay extern int MatMultAdd_SeqBAIJ_1(Mat,Vec,Vec,Vec);
11932d61bbb3SSatish Balay extern int MatMultAdd_SeqBAIJ_2(Mat,Vec,Vec,Vec);
11942d61bbb3SSatish Balay extern int MatMultAdd_SeqBAIJ_3(Mat,Vec,Vec,Vec);
11952d61bbb3SSatish Balay extern int MatMultAdd_SeqBAIJ_4(Mat,Vec,Vec,Vec);
11962d61bbb3SSatish Balay extern int MatMultAdd_SeqBAIJ_5(Mat,Vec,Vec,Vec);
119715091d37SBarry Smith extern int MatMultAdd_SeqBAIJ_6(Mat,Vec,Vec,Vec);
11982d61bbb3SSatish Balay extern int MatMultAdd_SeqBAIJ_7(Mat,Vec,Vec,Vec);
11992d61bbb3SSatish Balay extern int MatMultAdd_SeqBAIJ_N(Mat,Vec,Vec,Vec);
12002d61bbb3SSatish Balay 
12012d61bbb3SSatish Balay #undef __FUNC__
1202b2863d3aSBarry Smith #define __FUNC__ /*<a name=""></a>*/"MatILUFactor_SeqBAIJ"
12035ef9f2a5SBarry Smith int MatILUFactor_SeqBAIJ(Mat inA,IS row,IS col,MatILUInfo *info)
12042d61bbb3SSatish Balay {
12052d61bbb3SSatish Balay   Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)inA->data;
12062d61bbb3SSatish Balay   Mat         outA;
12072d61bbb3SSatish Balay   int         ierr;
1208667159a5SBarry Smith   PetscTruth  row_identity,col_identity;
12092d61bbb3SSatish Balay 
12102d61bbb3SSatish Balay   PetscFunctionBegin;
1211b6d21a55SBarry Smith   if (info && info->levels != 0) SETERRQ(PETSC_ERR_SUP,0,"Only levels = 0 supported for in-place ILU");
1212667159a5SBarry Smith   ierr = ISIdentity(row,&row_identity);CHKERRQ(ierr);
1213667159a5SBarry Smith   ierr = ISIdentity(col,&col_identity);CHKERRQ(ierr);
1214667159a5SBarry Smith   if (!row_identity || !col_identity) {
1215b008c796SBarry Smith     SETERRQ(1,1,"Row and column permutations must be identity for in-place ILU");
1216667159a5SBarry Smith   }
12172d61bbb3SSatish Balay 
12182d61bbb3SSatish Balay   outA          = inA;
12192d61bbb3SSatish Balay   inA->factor   = FACTOR_LU;
12202d61bbb3SSatish Balay 
12212d61bbb3SSatish Balay   if (!a->diag) {
1222c4992f7dSBarry Smith     ierr = MatMarkDiagonal_SeqBAIJ(inA);CHKERRQ(ierr);
12232d61bbb3SSatish Balay   }
12242d61bbb3SSatish Balay   /*
122515091d37SBarry Smith       Blocksize 2, 3, 4, 5, 6 and 7 have a special faster factorization/solver
122615091d37SBarry Smith       for ILU(0) factorization with natural ordering
12272d61bbb3SSatish Balay   */
122815091d37SBarry Smith   switch (a->bs) {
1229f1af5d2fSBarry Smith   case 1:
12307c922b88SBarry Smith     inA->ops->solvetranspose   = MatSolveTranspose_SeqBAIJ_2_NaturalOrdering;
1231f1af5d2fSBarry Smith     PLogInfo(inA,"MatILUFactor_SeqBAIJ:Using special in-place natural ordering solvetrans BS=1\n");
123215091d37SBarry Smith   case 2:
123315091d37SBarry Smith     inA->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_2_NaturalOrdering;
123415091d37SBarry Smith     inA->ops->solve           = MatSolve_SeqBAIJ_2_NaturalOrdering;
12357c922b88SBarry Smith     inA->ops->solvetranspose  = MatSolveTranspose_SeqBAIJ_2_NaturalOrdering;
123615091d37SBarry Smith     PLogInfo(inA,"MatILUFactor_SeqBAIJ:Using special in-place natural ordering factor and solve BS=2\n");
123715091d37SBarry Smith     break;
123815091d37SBarry Smith   case 3:
123915091d37SBarry Smith     inA->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_3_NaturalOrdering;
124015091d37SBarry Smith     inA->ops->solve           = MatSolve_SeqBAIJ_3_NaturalOrdering;
12417c922b88SBarry Smith     inA->ops->solvetranspose  = MatSolveTranspose_SeqBAIJ_3_NaturalOrdering;
124215091d37SBarry Smith     PLogInfo(inA,"MatILUFactor_SeqBAIJ:Using special in-place natural ordering factor and solve BS=3\n");
124315091d37SBarry Smith     break;
124415091d37SBarry Smith   case 4:
1245667159a5SBarry Smith     inA->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_4_NaturalOrdering;
1246f830108cSBarry Smith     inA->ops->solve           = MatSolve_SeqBAIJ_4_NaturalOrdering;
12477c922b88SBarry Smith     inA->ops->solvetranspose  = MatSolveTranspose_SeqBAIJ_4_NaturalOrdering;
124815091d37SBarry Smith     PLogInfo(inA,"MatILUFactor_SeqBAIJ:Using special in-place natural ordering factor and solve BS=4\n");
124915091d37SBarry Smith     break;
125015091d37SBarry Smith   case 5:
1251667159a5SBarry Smith     inA->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_5_NaturalOrdering;
1252667159a5SBarry Smith     inA->ops->solve           = MatSolve_SeqBAIJ_5_NaturalOrdering;
12537c922b88SBarry Smith     inA->ops->solvetranspose  = MatSolveTranspose_SeqBAIJ_5_NaturalOrdering;
125415091d37SBarry Smith     PLogInfo(inA,"MatILUFactor_SeqBAIJ:Using special in-place natural ordering factor and solve BS=5\n");
125515091d37SBarry Smith     break;
125615091d37SBarry Smith   case 6:
125715091d37SBarry Smith     inA->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_6_NaturalOrdering;
125815091d37SBarry Smith     inA->ops->solve           = MatSolve_SeqBAIJ_6_NaturalOrdering;
12597c922b88SBarry Smith     inA->ops->solvetranspose  = MatSolveTranspose_SeqBAIJ_6_NaturalOrdering;
126015091d37SBarry Smith     PLogInfo(inA,"MatILUFactor_SeqBAIJ:Using special in-place natural ordering factor and solve BS=6\n");
126115091d37SBarry Smith     break;
126215091d37SBarry Smith   case 7:
126315091d37SBarry Smith     inA->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_7_NaturalOrdering;
12647c922b88SBarry Smith     inA->ops->solvetranspose  = MatSolveTranspose_SeqBAIJ_7_NaturalOrdering;
126515091d37SBarry Smith     inA->ops->solve           = MatSolve_SeqBAIJ_7_NaturalOrdering;
126615091d37SBarry Smith     PLogInfo(inA,"MatILUFactor_SeqBAIJ:Using special in-place natural ordering factor and solve BS=7\n");
126715091d37SBarry Smith     break;
1268c38d4ed2SBarry Smith   default:
1269c38d4ed2SBarry Smith     a->row        = row;
1270c38d4ed2SBarry Smith     a->col        = col;
1271c38d4ed2SBarry Smith     ierr          = PetscObjectReference((PetscObject)row);CHKERRQ(ierr);
1272c38d4ed2SBarry Smith     ierr          = PetscObjectReference((PetscObject)col);CHKERRQ(ierr);
1273c38d4ed2SBarry Smith 
1274c38d4ed2SBarry Smith     /* Create the invert permutation so that it can be used in MatLUFactorNumeric() */
12754c49b128SBarry Smith     ierr = ISInvertPermutation(col,PETSC_DECIDE,&a->icol);CHKERRQ(ierr);
1276c38d4ed2SBarry Smith     PLogObjectParent(inA,a->icol);
1277c38d4ed2SBarry Smith 
1278c38d4ed2SBarry Smith     if (!a->solve_work) {
1279c38d4ed2SBarry Smith       a->solve_work = (Scalar*)PetscMalloc((a->m+a->bs)*sizeof(Scalar));CHKPTRQ(a->solve_work);
1280c38d4ed2SBarry Smith       PLogObjectMemory(inA,(a->m+a->bs)*sizeof(Scalar));
1281c38d4ed2SBarry Smith     }
12822d61bbb3SSatish Balay   }
12832d61bbb3SSatish Balay 
1284667159a5SBarry Smith   ierr = MatLUFactorNumeric(inA,&outA);CHKERRQ(ierr);
1285667159a5SBarry Smith 
12862d61bbb3SSatish Balay   PetscFunctionReturn(0);
12872d61bbb3SSatish Balay }
12882d61bbb3SSatish Balay #undef __FUNC__
1289b2863d3aSBarry Smith #define __FUNC__ /*<a name=""></a>*/"MatPrintHelp_SeqBAIJ"
1290ba4ca20aSSatish Balay int MatPrintHelp_SeqBAIJ(Mat A)
1291ba4ca20aSSatish Balay {
1292c38d4ed2SBarry Smith   static PetscTruth called = PETSC_FALSE;
1293ba4ca20aSSatish Balay   MPI_Comm          comm = A->comm;
1294d132466eSBarry Smith   int               ierr;
1295ba4ca20aSSatish Balay 
12963a40ed3dSBarry Smith   PetscFunctionBegin;
1297c38d4ed2SBarry Smith   if (called) {PetscFunctionReturn(0);} else called = PETSC_TRUE;
1298d132466eSBarry Smith   ierr = (*PetscHelpPrintf)(comm," Options for MATSEQBAIJ and MATMPIBAIJ matrix formats (the defaults):\n");CHKERRQ(ierr);
1299d132466eSBarry Smith   ierr = (*PetscHelpPrintf)(comm,"  -mat_block_size <block_size>\n");CHKERRQ(ierr);
13003a40ed3dSBarry Smith   PetscFunctionReturn(0);
1301ba4ca20aSSatish Balay }
1302d9b7c43dSSatish Balay 
1303fb2e594dSBarry Smith EXTERN_C_BEGIN
130427a8da17SBarry Smith #undef __FUNC__
1305b2863d3aSBarry Smith #define __FUNC__ /*<a name=""></a>*/"MatSeqBAIJSetColumnIndices_SeqBAIJ"
130627a8da17SBarry Smith int MatSeqBAIJSetColumnIndices_SeqBAIJ(Mat mat,int *indices)
130727a8da17SBarry Smith {
130827a8da17SBarry Smith   Mat_SeqBAIJ *baij = (Mat_SeqBAIJ *)mat->data;
130927a8da17SBarry Smith   int         i,nz,n;
131027a8da17SBarry Smith 
131127a8da17SBarry Smith   PetscFunctionBegin;
131227a8da17SBarry Smith   nz = baij->maxnz;
131327a8da17SBarry Smith   n  = baij->n;
131427a8da17SBarry Smith   for (i=0; i<nz; i++) {
131527a8da17SBarry Smith     baij->j[i] = indices[i];
131627a8da17SBarry Smith   }
131727a8da17SBarry Smith   baij->nz = nz;
131827a8da17SBarry Smith   for (i=0; i<n; i++) {
131927a8da17SBarry Smith     baij->ilen[i] = baij->imax[i];
132027a8da17SBarry Smith   }
132127a8da17SBarry Smith 
132227a8da17SBarry Smith   PetscFunctionReturn(0);
132327a8da17SBarry Smith }
1324fb2e594dSBarry Smith EXTERN_C_END
132527a8da17SBarry Smith 
132627a8da17SBarry Smith #undef __FUNC__
1327b2863d3aSBarry Smith #define __FUNC__ /*<a name=""></a>*/"MatSeqBAIJSetColumnIndices"
132827a8da17SBarry Smith /*@
132927a8da17SBarry Smith     MatSeqBAIJSetColumnIndices - Set the column indices for all the rows
133027a8da17SBarry Smith        in the matrix.
133127a8da17SBarry Smith 
133227a8da17SBarry Smith   Input Parameters:
133327a8da17SBarry Smith +  mat - the SeqBAIJ matrix
133427a8da17SBarry Smith -  indices - the column indices
133527a8da17SBarry Smith 
133615091d37SBarry Smith   Level: advanced
133715091d37SBarry Smith 
133827a8da17SBarry Smith   Notes:
133927a8da17SBarry Smith     This can be called if you have precomputed the nonzero structure of the
134027a8da17SBarry Smith   matrix and want to provide it to the matrix object to improve the performance
134127a8da17SBarry Smith   of the MatSetValues() operation.
134227a8da17SBarry Smith 
134327a8da17SBarry Smith     You MUST have set the correct numbers of nonzeros per row in the call to
134427a8da17SBarry Smith   MatCreateSeqBAIJ().
134527a8da17SBarry Smith 
134627a8da17SBarry Smith     MUST be called before any calls to MatSetValues();
134727a8da17SBarry Smith 
134827a8da17SBarry Smith @*/
134927a8da17SBarry Smith int MatSeqBAIJSetColumnIndices(Mat mat,int *indices)
135027a8da17SBarry Smith {
135127a8da17SBarry Smith   int ierr,(*f)(Mat,int *);
135227a8da17SBarry Smith 
135327a8da17SBarry Smith   PetscFunctionBegin;
135427a8da17SBarry Smith   PetscValidHeaderSpecific(mat,MAT_COOKIE);
1355549d3d68SSatish Balay   ierr = PetscObjectQueryFunction((PetscObject)mat,"MatSeqBAIJSetColumnIndices_C",(void **)&f);CHKERRQ(ierr);
135627a8da17SBarry Smith   if (f) {
135727a8da17SBarry Smith     ierr = (*f)(mat,indices);CHKERRQ(ierr);
135827a8da17SBarry Smith   } else {
135927a8da17SBarry Smith     SETERRQ(1,1,"Wrong type of matrix to set column indices");
136027a8da17SBarry Smith   }
136127a8da17SBarry Smith   PetscFunctionReturn(0);
136227a8da17SBarry Smith }
136327a8da17SBarry Smith 
13642593348eSBarry Smith /* -------------------------------------------------------------------*/
1365cc2dc46cSBarry Smith static struct _MatOps MatOps_Values = {MatSetValues_SeqBAIJ,
1366cc2dc46cSBarry Smith        MatGetRow_SeqBAIJ,
1367cc2dc46cSBarry Smith        MatRestoreRow_SeqBAIJ,
1368cc2dc46cSBarry Smith        MatMult_SeqBAIJ_N,
1369cc2dc46cSBarry Smith        MatMultAdd_SeqBAIJ_N,
13707c922b88SBarry Smith        MatMultTranspose_SeqBAIJ,
13717c922b88SBarry Smith        MatMultTransposeAdd_SeqBAIJ,
1372cc2dc46cSBarry Smith        MatSolve_SeqBAIJ_N,
1373cc2dc46cSBarry Smith        0,
1374cc2dc46cSBarry Smith        0,
1375cc2dc46cSBarry Smith        0,
1376cc2dc46cSBarry Smith        MatLUFactor_SeqBAIJ,
1377cc2dc46cSBarry Smith        0,
1378b6490206SBarry Smith        0,
1379f2501298SSatish Balay        MatTranspose_SeqBAIJ,
1380cc2dc46cSBarry Smith        MatGetInfo_SeqBAIJ,
1381cc2dc46cSBarry Smith        MatEqual_SeqBAIJ,
1382cc2dc46cSBarry Smith        MatGetDiagonal_SeqBAIJ,
1383cc2dc46cSBarry Smith        MatDiagonalScale_SeqBAIJ,
1384cc2dc46cSBarry Smith        MatNorm_SeqBAIJ,
1385b6490206SBarry Smith        0,
1386cc2dc46cSBarry Smith        MatAssemblyEnd_SeqBAIJ,
1387cc2dc46cSBarry Smith        0,
1388cc2dc46cSBarry Smith        MatSetOption_SeqBAIJ,
1389cc2dc46cSBarry Smith        MatZeroEntries_SeqBAIJ,
1390cc2dc46cSBarry Smith        MatZeroRows_SeqBAIJ,
1391cc2dc46cSBarry Smith        MatLUFactorSymbolic_SeqBAIJ,
1392cc2dc46cSBarry Smith        MatLUFactorNumeric_SeqBAIJ_N,
1393cc2dc46cSBarry Smith        0,
1394cc2dc46cSBarry Smith        0,
1395cc2dc46cSBarry Smith        MatGetSize_SeqBAIJ,
1396cc2dc46cSBarry Smith        MatGetSize_SeqBAIJ,
1397cc2dc46cSBarry Smith        MatGetOwnershipRange_SeqBAIJ,
1398cc2dc46cSBarry Smith        MatILUFactorSymbolic_SeqBAIJ,
1399cc2dc46cSBarry Smith        0,
1400cc2dc46cSBarry Smith        0,
1401cc2dc46cSBarry Smith        0,
14022e8a6d31SBarry Smith        MatDuplicate_SeqBAIJ,
1403cc2dc46cSBarry Smith        0,
1404cc2dc46cSBarry Smith        0,
1405cc2dc46cSBarry Smith        MatILUFactor_SeqBAIJ,
1406cc2dc46cSBarry Smith        0,
1407cc2dc46cSBarry Smith        0,
1408cc2dc46cSBarry Smith        MatGetSubMatrices_SeqBAIJ,
1409cc2dc46cSBarry Smith        MatIncreaseOverlap_SeqBAIJ,
1410cc2dc46cSBarry Smith        MatGetValues_SeqBAIJ,
1411cc2dc46cSBarry Smith        0,
1412cc2dc46cSBarry Smith        MatPrintHelp_SeqBAIJ,
1413cc2dc46cSBarry Smith        MatScale_SeqBAIJ,
1414cc2dc46cSBarry Smith        0,
1415cc2dc46cSBarry Smith        0,
1416cc2dc46cSBarry Smith        0,
1417cc2dc46cSBarry Smith        MatGetBlockSize_SeqBAIJ,
14183b2fbd54SBarry Smith        MatGetRowIJ_SeqBAIJ,
141992c4ed94SBarry Smith        MatRestoreRowIJ_SeqBAIJ,
1420cc2dc46cSBarry Smith        0,
1421cc2dc46cSBarry Smith        0,
1422cc2dc46cSBarry Smith        0,
1423cc2dc46cSBarry Smith        0,
1424cc2dc46cSBarry Smith        0,
1425cc2dc46cSBarry Smith        0,
1426d3825aa8SBarry Smith        MatSetValuesBlocked_SeqBAIJ,
1427cc2dc46cSBarry Smith        MatGetSubMatrix_SeqBAIJ,
1428cc2dc46cSBarry Smith        0,
1429cc2dc46cSBarry Smith        0,
1430cc2dc46cSBarry Smith        MatGetMaps_Petsc};
14312593348eSBarry Smith 
14323e90b805SBarry Smith EXTERN_C_BEGIN
14333e90b805SBarry Smith #undef __FUNC__
1434b2863d3aSBarry Smith #define __FUNC__ /*<a name=""></a>*/"MatStoreValues_SeqBAIJ"
14353e90b805SBarry Smith int MatStoreValues_SeqBAIJ(Mat mat)
14363e90b805SBarry Smith {
14373e90b805SBarry Smith   Mat_SeqBAIJ *aij = (Mat_SeqBAIJ *)mat->data;
14383e90b805SBarry Smith   int         nz = aij->i[aij->m]*aij->bs*aij->bs2;
1439d132466eSBarry Smith   int         ierr;
14403e90b805SBarry Smith 
14413e90b805SBarry Smith   PetscFunctionBegin;
14423e90b805SBarry Smith   if (aij->nonew != 1) {
14433e90b805SBarry Smith     SETERRQ(1,1,"Must call MatSetOption(A,MAT_NO_NEW_NONZERO_LOCATIONS);first");
14443e90b805SBarry Smith   }
14453e90b805SBarry Smith 
14463e90b805SBarry Smith   /* allocate space for values if not already there */
14473e90b805SBarry Smith   if (!aij->saved_values) {
14483e90b805SBarry Smith     aij->saved_values = (Scalar*)PetscMalloc(nz*sizeof(Scalar));CHKPTRQ(aij->saved_values);
14493e90b805SBarry Smith   }
14503e90b805SBarry Smith 
14513e90b805SBarry Smith   /* copy values over */
1452d132466eSBarry Smith   ierr = PetscMemcpy(aij->saved_values,aij->a,nz*sizeof(Scalar));CHKERRQ(ierr);
14533e90b805SBarry Smith   PetscFunctionReturn(0);
14543e90b805SBarry Smith }
14553e90b805SBarry Smith EXTERN_C_END
14563e90b805SBarry Smith 
14573e90b805SBarry Smith EXTERN_C_BEGIN
14583e90b805SBarry Smith #undef __FUNC__
1459b2863d3aSBarry Smith #define __FUNC__ /*<a name=""></a>*/"MatRetrieveValues_SeqBAIJ"
146032e87ba3SBarry Smith int MatRetrieveValues_SeqBAIJ(Mat mat)
14613e90b805SBarry Smith {
14623e90b805SBarry Smith   Mat_SeqBAIJ *aij = (Mat_SeqBAIJ *)mat->data;
1463549d3d68SSatish Balay   int         nz = aij->i[aij->m]*aij->bs*aij->bs2,ierr;
14643e90b805SBarry Smith 
14653e90b805SBarry Smith   PetscFunctionBegin;
14663e90b805SBarry Smith   if (aij->nonew != 1) {
14673e90b805SBarry Smith     SETERRQ(1,1,"Must call MatSetOption(A,MAT_NO_NEW_NONZERO_LOCATIONS);first");
14683e90b805SBarry Smith   }
14693e90b805SBarry Smith   if (!aij->saved_values) {
14703e90b805SBarry Smith     SETERRQ(1,1,"Must call MatStoreValues(A);first");
14713e90b805SBarry Smith   }
14723e90b805SBarry Smith 
14733e90b805SBarry Smith   /* copy values over */
1474549d3d68SSatish Balay   ierr = PetscMemcpy(aij->a,aij->saved_values,nz*sizeof(Scalar));CHKERRQ(ierr);
14753e90b805SBarry Smith   PetscFunctionReturn(0);
14763e90b805SBarry Smith }
14773e90b805SBarry Smith EXTERN_C_END
14783e90b805SBarry Smith 
14795615d1e5SSatish Balay #undef __FUNC__
1480b2863d3aSBarry Smith #define __FUNC__ /*<a name=""></a>*/"MatCreateSeqBAIJ"
14812593348eSBarry Smith /*@C
148244cd7ae7SLois Curfman McInnes    MatCreateSeqBAIJ - Creates a sparse matrix in block AIJ (block
148344cd7ae7SLois Curfman McInnes    compressed row) format.  For good matrix assembly performance the
148444cd7ae7SLois Curfman McInnes    user should preallocate the matrix storage by setting the parameter nz
14857fc3c18eSBarry Smith    (or the array nnz).  By setting these parameters accurately, performance
14862bd5e0b2SLois Curfman McInnes    during matrix assembly can be increased by more than a factor of 50.
14872593348eSBarry Smith 
1488db81eaa0SLois Curfman McInnes    Collective on MPI_Comm
1489db81eaa0SLois Curfman McInnes 
14902593348eSBarry Smith    Input Parameters:
1491db81eaa0SLois Curfman McInnes +  comm - MPI communicator, set to PETSC_COMM_SELF
1492b6490206SBarry Smith .  bs - size of block
14932593348eSBarry Smith .  m - number of rows
14942593348eSBarry Smith .  n - number of columns
1495b6490206SBarry Smith .  nz - number of block nonzeros per block row (same for all rows)
14967fc3c18eSBarry Smith -  nnz - array containing the number of block nonzeros in the various block rows
14972bd5e0b2SLois Curfman McInnes          (possibly different for each block row) or PETSC_NULL
14982593348eSBarry Smith 
14992593348eSBarry Smith    Output Parameter:
15002593348eSBarry Smith .  A - the matrix
15012593348eSBarry Smith 
15020513a670SBarry Smith    Options Database Keys:
1503db81eaa0SLois Curfman McInnes .   -mat_no_unroll - uses code that does not unroll the loops in the
1504db81eaa0SLois Curfman McInnes                      block calculations (much slower)
1505db81eaa0SLois Curfman McInnes .    -mat_block_size - size of the blocks to use
15060513a670SBarry Smith 
150715091d37SBarry Smith    Level: intermediate
150815091d37SBarry Smith 
15092593348eSBarry Smith    Notes:
151044cd7ae7SLois Curfman McInnes    The block AIJ format is fully compatible with standard Fortran 77
15112593348eSBarry Smith    storage.  That is, the stored row and column indices can begin at
151244cd7ae7SLois Curfman McInnes    either one (as in Fortran) or zero.  See the users' manual for details.
15132593348eSBarry Smith 
15142593348eSBarry Smith    Specify the preallocated storage with either nz or nnz (not both).
15152593348eSBarry Smith    Set nz=PETSC_DEFAULT and nnz=PETSC_NULL for PETSc to control dynamic memory
15162593348eSBarry Smith    allocation.  For additional details, see the users manual chapter on
15176da5968aSLois Curfman McInnes    matrices.
15182593348eSBarry Smith 
1519db81eaa0SLois Curfman McInnes .seealso: MatCreate(), MatCreateSeqAIJ(), MatSetValues(), MatCreateMPIBAIJ()
15202593348eSBarry Smith @*/
1521b6490206SBarry Smith int MatCreateSeqBAIJ(MPI_Comm comm,int bs,int m,int n,int nz,int *nnz,Mat *A)
15222593348eSBarry Smith {
15232593348eSBarry Smith   Mat         B;
1524b6490206SBarry Smith   Mat_SeqBAIJ *b;
15256827595bSBarry Smith   int         i,len,ierr,mbs,nbs,bs2,size,newbs = bs;
1526f1af5d2fSBarry Smith   PetscTruth  flg;
15273b2fbd54SBarry Smith 
15283a40ed3dSBarry Smith   PetscFunctionBegin;
1529d132466eSBarry Smith   ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr);
1530a8c6a408SBarry Smith   if (size > 1) SETERRQ(PETSC_ERR_ARG_WRONG,0,"Comm must be of size 1");
1531b6490206SBarry Smith 
15326827595bSBarry Smith   ierr = OptionsGetInt(PETSC_NULL,"-mat_block_size",&newbs,PETSC_NULL);CHKERRQ(ierr);
15336827595bSBarry Smith   if (nnz && newbs != bs) {
15346827595bSBarry Smith     SETERRQ(1,1,"Cannot change blocksize from command line if setting nnz");
15356827595bSBarry Smith   }
15366827595bSBarry Smith 
1537302e33e3SBarry Smith   mbs  = m/bs;
1538302e33e3SBarry Smith   nbs  = n/bs;
1539302e33e3SBarry Smith   bs2  = bs*bs;
15400513a670SBarry Smith 
15413a40ed3dSBarry Smith   if (mbs*bs!=m || nbs*bs!=n) {
1542a8c6a408SBarry Smith     SETERRQ(PETSC_ERR_ARG_SIZ,0,"Number rows, cols must be divisible by blocksize");
15433a40ed3dSBarry Smith   }
15442593348eSBarry Smith 
1545b73539f3SBarry Smith   if (nz < -2) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,0,"nz cannot be less than -2: value %d",nz);
1546b73539f3SBarry Smith   if (nnz) {
1547faf3f1fcSBarry Smith     for (i=0; i<mbs; i++) {
1548b73539f3SBarry Smith       if (nnz[i] < 0) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,0,"nnz cannot be less than 0: local row %d value %d",i,nnz[i]);
1549b73539f3SBarry Smith     }
1550b73539f3SBarry Smith   }
1551b73539f3SBarry Smith 
15522593348eSBarry Smith   *A = 0;
15533f1db9ecSBarry Smith   PetscHeaderCreate(B,_p_Mat,struct _MatOps,MAT_COOKIE,MATSEQBAIJ,"Mat",comm,MatDestroy,MatView);
15542593348eSBarry Smith   PLogObjectCreate(B);
1555b6490206SBarry Smith   B->data = (void*)(b = PetscNew(Mat_SeqBAIJ));CHKPTRQ(b);
1556549d3d68SSatish Balay   ierr    = PetscMemzero(b,sizeof(Mat_SeqBAIJ));CHKERRQ(ierr);
1557549d3d68SSatish Balay   ierr    = PetscMemcpy(B->ops,&MatOps_Values,sizeof(struct _MatOps));CHKERRQ(ierr);
15581a6a6d98SBarry Smith   ierr    = OptionsHasName(PETSC_NULL,"-mat_no_unroll",&flg);CHKERRQ(ierr);
15591a6a6d98SBarry Smith   if (!flg) {
15607fc0212eSBarry Smith     switch (bs) {
15617fc0212eSBarry Smith     case 1:
1562f830108cSBarry Smith       B->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_1;
1563f830108cSBarry Smith       B->ops->solve           = MatSolve_SeqBAIJ_1;
15647c922b88SBarry Smith       B->ops->solvetranspose  = MatSolveTranspose_SeqBAIJ_1;
1565f830108cSBarry Smith       B->ops->mult            = MatMult_SeqBAIJ_1;
1566f830108cSBarry Smith       B->ops->multadd         = MatMultAdd_SeqBAIJ_1;
15677fc0212eSBarry Smith       break;
15684eeb42bcSBarry Smith     case 2:
1569f830108cSBarry Smith       B->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_2;
1570f830108cSBarry Smith       B->ops->solve           = MatSolve_SeqBAIJ_2;
15717c922b88SBarry Smith       B->ops->solvetranspose  = MatSolveTranspose_SeqBAIJ_2;
1572f830108cSBarry Smith       B->ops->mult            = MatMult_SeqBAIJ_2;
1573f830108cSBarry Smith       B->ops->multadd         = MatMultAdd_SeqBAIJ_2;
15746d84be18SBarry Smith       break;
1575f327dd97SBarry Smith     case 3:
1576f830108cSBarry Smith       B->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_3;
1577f830108cSBarry Smith       B->ops->solve           = MatSolve_SeqBAIJ_3;
15787c922b88SBarry Smith       B->ops->solvetranspose  = MatSolveTranspose_SeqBAIJ_3;
1579f830108cSBarry Smith       B->ops->mult            = MatMult_SeqBAIJ_3;
1580f830108cSBarry Smith       B->ops->multadd         = MatMultAdd_SeqBAIJ_3;
15814eeb42bcSBarry Smith       break;
15826d84be18SBarry Smith     case 4:
1583f830108cSBarry Smith       B->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_4;
1584f830108cSBarry Smith       B->ops->solve           = MatSolve_SeqBAIJ_4;
15857c922b88SBarry Smith       B->ops->solvetranspose  = MatSolveTranspose_SeqBAIJ_4;
1586f830108cSBarry Smith       B->ops->mult            = MatMult_SeqBAIJ_4;
1587f830108cSBarry Smith       B->ops->multadd         = MatMultAdd_SeqBAIJ_4;
15886d84be18SBarry Smith       break;
15896d84be18SBarry Smith     case 5:
1590f830108cSBarry Smith       B->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_5;
1591f830108cSBarry Smith       B->ops->solve           = MatSolve_SeqBAIJ_5;
15927c922b88SBarry Smith       B->ops->solvetranspose  = MatSolveTranspose_SeqBAIJ_5;
1593f830108cSBarry Smith       B->ops->mult            = MatMult_SeqBAIJ_5;
1594f830108cSBarry Smith       B->ops->multadd         = MatMultAdd_SeqBAIJ_5;
15956d84be18SBarry Smith       break;
159615091d37SBarry Smith     case 6:
159715091d37SBarry Smith       B->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_6;
159815091d37SBarry Smith       B->ops->solve           = MatSolve_SeqBAIJ_6;
15997c922b88SBarry Smith       B->ops->solvetranspose  = MatSolveTranspose_SeqBAIJ_6;
160015091d37SBarry Smith       B->ops->mult            = MatMult_SeqBAIJ_6;
160115091d37SBarry Smith       B->ops->multadd         = MatMultAdd_SeqBAIJ_6;
160215091d37SBarry Smith       break;
160348e9ddb2SSatish Balay     case 7:
1604f830108cSBarry Smith       B->ops->mult            = MatMult_SeqBAIJ_7;
1605f830108cSBarry Smith       B->ops->solve           = MatSolve_SeqBAIJ_7;
16067c922b88SBarry Smith       B->ops->solvetranspose  = MatSolveTranspose_SeqBAIJ_7;
1607f830108cSBarry Smith       B->ops->multadd         = MatMultAdd_SeqBAIJ_7;
160848e9ddb2SSatish Balay       break;
16097fc0212eSBarry Smith     }
16101a6a6d98SBarry Smith   }
1611e1311b90SBarry Smith   B->ops->destroy     = MatDestroy_SeqBAIJ;
1612e1311b90SBarry Smith   B->ops->view        = MatView_SeqBAIJ;
16132593348eSBarry Smith   B->factor           = 0;
16142593348eSBarry Smith   B->lupivotthreshold = 1.0;
161590f02eecSBarry Smith   B->mapping          = 0;
16162593348eSBarry Smith   b->row              = 0;
16172593348eSBarry Smith   b->col              = 0;
1618e51c0b9cSSatish Balay   b->icol             = 0;
16192593348eSBarry Smith   b->reallocs         = 0;
16203e90b805SBarry Smith   b->saved_values     = 0;
1621563b5814SBarry Smith #if defined(PEYSC_USE_MAT_SINGLE)
1622563b5814SBarry Smith   b->setvalueslen     = 0;
1623563b5814SBarry Smith   b->setvaluescopy    = PETSC_NULL;
1624563b5814SBarry Smith #endif
16252593348eSBarry Smith 
162644cd7ae7SLois Curfman McInnes   b->m       = m; B->m = m; B->M = m;
162744cd7ae7SLois Curfman McInnes   b->n       = n; B->n = n; B->N = n;
1628a5ae1ecdSBarry Smith 
16297413bad6SBarry Smith   ierr = MapCreateMPI(comm,m,m,&B->rmap);CHKERRQ(ierr);
16307413bad6SBarry Smith   ierr = MapCreateMPI(comm,n,n,&B->cmap);CHKERRQ(ierr);
1631a5ae1ecdSBarry Smith 
1632b6490206SBarry Smith   b->mbs     = mbs;
1633f2501298SSatish Balay   b->nbs     = nbs;
1634b6490206SBarry Smith   b->imax    = (int*)PetscMalloc((mbs+1)*sizeof(int));CHKPTRQ(b->imax);
1635c4992f7dSBarry Smith   if (!nnz) {
1636119a934aSSatish Balay     if (nz == PETSC_DEFAULT) nz = 5;
16372593348eSBarry Smith     else if (nz <= 0)        nz = 1;
1638b6490206SBarry Smith     for (i=0; i<mbs; i++) b->imax[i] = nz;
1639b6490206SBarry Smith     nz = nz*mbs;
16403a40ed3dSBarry Smith   } else {
16412593348eSBarry Smith     nz = 0;
1642b6490206SBarry Smith     for (i=0; i<mbs; i++) {b->imax[i] = nnz[i]; nz += nnz[i];}
16432593348eSBarry Smith   }
16442593348eSBarry Smith 
16452593348eSBarry Smith   /* allocate the matrix space */
16463f1db9ecSBarry Smith   len   = nz*sizeof(int) + nz*bs2*sizeof(MatScalar) + (b->m+1)*sizeof(int);
16473f1db9ecSBarry Smith   b->a  = (MatScalar*)PetscMalloc(len);CHKPTRQ(b->a);
1648549d3d68SSatish Balay   ierr = PetscMemzero(b->a,nz*bs2*sizeof(MatScalar));CHKERRQ(ierr);
16497e67e3f9SSatish Balay   b->j  = (int*)(b->a + nz*bs2);
1650549d3d68SSatish Balay   ierr = PetscMemzero(b->j,nz*sizeof(int));CHKERRQ(ierr);
16512593348eSBarry Smith   b->i  = b->j + nz;
1652c4992f7dSBarry Smith   b->singlemalloc = PETSC_TRUE;
16532593348eSBarry Smith 
1654de6a44a3SBarry Smith   b->i[0] = 0;
1655b6490206SBarry Smith   for (i=1; i<mbs+1; i++) {
16562593348eSBarry Smith     b->i[i] = b->i[i-1] + b->imax[i-1];
16572593348eSBarry Smith   }
16582593348eSBarry Smith 
1659b6490206SBarry Smith   /* b->ilen will count nonzeros in each block row so far. */
1660b6490206SBarry Smith   b->ilen = (int*)PetscMalloc((mbs+1)*sizeof(int));
1661f09e8eb9SSatish Balay   PLogObjectMemory(B,len+2*(mbs+1)*sizeof(int)+sizeof(struct _p_Mat)+sizeof(Mat_SeqBAIJ));
1662b6490206SBarry Smith   for (i=0; i<mbs; i++) { b->ilen[i] = 0;}
16632593348eSBarry Smith 
1664b6490206SBarry Smith   b->bs               = bs;
16659df24120SSatish Balay   b->bs2              = bs2;
1666b6490206SBarry Smith   b->mbs              = mbs;
16672593348eSBarry Smith   b->nz               = 0;
166818e7b8e4SLois Curfman McInnes   b->maxnz            = nz*bs2;
1669c4992f7dSBarry Smith   b->sorted           = PETSC_FALSE;
1670c4992f7dSBarry Smith   b->roworiented      = PETSC_TRUE;
16712593348eSBarry Smith   b->nonew            = 0;
16722593348eSBarry Smith   b->diag             = 0;
16732593348eSBarry Smith   b->solve_work       = 0;
1674de6a44a3SBarry Smith   b->mult_work        = 0;
16752593348eSBarry Smith   b->spptr            = 0;
16760e6d2581SBarry Smith   B->info.nz_unneeded = (PetscReal)b->maxnz;
1677883fce79SBarry Smith   b->keepzeroedrows   = PETSC_FALSE;
16784e220ebcSLois Curfman McInnes 
16792593348eSBarry Smith   *A = B;
16802593348eSBarry Smith   ierr = OptionsHasName(PETSC_NULL,"-help",&flg);CHKERRQ(ierr);
16812593348eSBarry Smith   if (flg) {ierr = MatPrintHelp(B);CHKERRQ(ierr); }
168227a8da17SBarry Smith 
1683f1af5d2fSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatStoreValues_C",
16843e90b805SBarry Smith                                      "MatStoreValues_SeqBAIJ",
1685*bc4b532fSSatish Balay                                       MatStoreValues_SeqBAIJ);CHKERRQ(ierr);
1686f1af5d2fSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatRetrieveValues_C",
16873e90b805SBarry Smith                                      "MatRetrieveValues_SeqBAIJ",
1688*bc4b532fSSatish Balay                                       MatRetrieveValues_SeqBAIJ);CHKERRQ(ierr);
1689f1af5d2fSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatSeqBAIJSetColumnIndices_C",
169027a8da17SBarry Smith                                      "MatSeqBAIJSetColumnIndices_SeqBAIJ",
1691*bc4b532fSSatish Balay                                       MatSeqBAIJSetColumnIndices_SeqBAIJ);CHKERRQ(ierr);
16923a40ed3dSBarry Smith   PetscFunctionReturn(0);
16932593348eSBarry Smith }
16942593348eSBarry Smith 
16955615d1e5SSatish Balay #undef __FUNC__
1696b2863d3aSBarry Smith #define __FUNC__ /*<a name=""></a>*/"MatDuplicate_SeqBAIJ"
16972e8a6d31SBarry Smith int MatDuplicate_SeqBAIJ(Mat A,MatDuplicateOption cpvalues,Mat *B)
16982593348eSBarry Smith {
16992593348eSBarry Smith   Mat         C;
1700b6490206SBarry Smith   Mat_SeqBAIJ *c,*a = (Mat_SeqBAIJ*)A->data;
170127a8da17SBarry Smith   int         i,len,mbs = a->mbs,nz = a->nz,bs2 =a->bs2,ierr;
1702de6a44a3SBarry Smith 
17033a40ed3dSBarry Smith   PetscFunctionBegin;
1704a8c6a408SBarry Smith   if (a->i[mbs] != nz) SETERRQ(PETSC_ERR_PLIB,0,"Corrupt matrix");
17052593348eSBarry Smith 
17062593348eSBarry Smith   *B = 0;
17073f1db9ecSBarry Smith   PetscHeaderCreate(C,_p_Mat,struct _MatOps,MAT_COOKIE,MATSEQBAIJ,"Mat",A->comm,MatDestroy,MatView);
17082593348eSBarry Smith   PLogObjectCreate(C);
1709b6490206SBarry Smith   C->data           = (void*)(c = PetscNew(Mat_SeqBAIJ));CHKPTRQ(c);
1710549d3d68SSatish Balay   ierr              = PetscMemcpy(C->ops,A->ops,sizeof(struct _MatOps));CHKERRQ(ierr);
1711e1311b90SBarry Smith   C->ops->destroy   = MatDestroy_SeqBAIJ;
1712e1311b90SBarry Smith   C->ops->view      = MatView_SeqBAIJ;
17132593348eSBarry Smith   C->factor         = A->factor;
17142593348eSBarry Smith   c->row            = 0;
17152593348eSBarry Smith   c->col            = 0;
1716cac97260SSatish Balay   c->icol           = 0;
171732e87ba3SBarry Smith   c->saved_values   = 0;
1718f1e2ffcdSBarry Smith   c->keepzeroedrows = a->keepzeroedrows;
17192593348eSBarry Smith   C->assembled      = PETSC_TRUE;
17202593348eSBarry Smith 
172144cd7ae7SLois Curfman McInnes   c->m = C->m   = a->m;
172244cd7ae7SLois Curfman McInnes   c->n = C->n   = a->n;
172344cd7ae7SLois Curfman McInnes   C->M          = a->m;
172444cd7ae7SLois Curfman McInnes   C->N          = a->n;
172544cd7ae7SLois Curfman McInnes 
1726b6490206SBarry Smith   c->bs         = a->bs;
17279df24120SSatish Balay   c->bs2        = a->bs2;
1728b6490206SBarry Smith   c->mbs        = a->mbs;
1729b6490206SBarry Smith   c->nbs        = a->nbs;
17302593348eSBarry Smith 
1731b6490206SBarry Smith   c->imax       = (int*)PetscMalloc((mbs+1)*sizeof(int));CHKPTRQ(c->imax);
1732b6490206SBarry Smith   c->ilen       = (int*)PetscMalloc((mbs+1)*sizeof(int));CHKPTRQ(c->ilen);
1733b6490206SBarry Smith   for (i=0; i<mbs; i++) {
17342593348eSBarry Smith     c->imax[i] = a->imax[i];
17352593348eSBarry Smith     c->ilen[i] = a->ilen[i];
17362593348eSBarry Smith   }
17372593348eSBarry Smith 
17382593348eSBarry Smith   /* allocate the matrix space */
1739c4992f7dSBarry Smith   c->singlemalloc = PETSC_TRUE;
17403f1db9ecSBarry Smith   len  = (mbs+1)*sizeof(int) + nz*(bs2*sizeof(MatScalar) + sizeof(int));
17413f1db9ecSBarry Smith   c->a = (MatScalar*)PetscMalloc(len);CHKPTRQ(c->a);
17427e67e3f9SSatish Balay   c->j = (int*)(c->a + nz*bs2);
1743de6a44a3SBarry Smith   c->i = c->j + nz;
1744549d3d68SSatish Balay   ierr = PetscMemcpy(c->i,a->i,(mbs+1)*sizeof(int));CHKERRQ(ierr);
1745b6490206SBarry Smith   if (mbs > 0) {
1746549d3d68SSatish Balay     ierr = PetscMemcpy(c->j,a->j,nz*sizeof(int));CHKERRQ(ierr);
17472e8a6d31SBarry Smith     if (cpvalues == MAT_COPY_VALUES) {
1748549d3d68SSatish Balay       ierr = PetscMemcpy(c->a,a->a,bs2*nz*sizeof(MatScalar));CHKERRQ(ierr);
17492e8a6d31SBarry Smith     } else {
1750549d3d68SSatish Balay       ierr = PetscMemzero(c->a,bs2*nz*sizeof(MatScalar));CHKERRQ(ierr);
17512593348eSBarry Smith     }
17522593348eSBarry Smith   }
17532593348eSBarry Smith 
1754f09e8eb9SSatish Balay   PLogObjectMemory(C,len+2*(mbs+1)*sizeof(int)+sizeof(struct _p_Mat)+sizeof(Mat_SeqBAIJ));
17552593348eSBarry Smith   c->sorted      = a->sorted;
17562593348eSBarry Smith   c->roworiented = a->roworiented;
17572593348eSBarry Smith   c->nonew       = a->nonew;
17582593348eSBarry Smith 
17592593348eSBarry Smith   if (a->diag) {
1760b6490206SBarry Smith     c->diag = (int*)PetscMalloc((mbs+1)*sizeof(int));CHKPTRQ(c->diag);
1761b6490206SBarry Smith     PLogObjectMemory(C,(mbs+1)*sizeof(int));
1762b6490206SBarry Smith     for (i=0; i<mbs; i++) {
17632593348eSBarry Smith       c->diag[i] = a->diag[i];
17642593348eSBarry Smith     }
176598305bb5SBarry Smith   } else c->diag        = 0;
17662593348eSBarry Smith   c->nz                 = a->nz;
17672593348eSBarry Smith   c->maxnz              = a->maxnz;
17682593348eSBarry Smith   c->solve_work         = 0;
17692593348eSBarry Smith   c->spptr              = 0;      /* Dangerous -I'm throwing away a->spptr */
17707fc0212eSBarry Smith   c->mult_work          = 0;
17712593348eSBarry Smith   *B = C;
17727b2a1423SBarry Smith   ierr = FListDuplicate(A->qlist,&C->qlist);CHKERRQ(ierr);
17733a40ed3dSBarry Smith   PetscFunctionReturn(0);
17742593348eSBarry Smith }
17752593348eSBarry Smith 
17765615d1e5SSatish Balay #undef __FUNC__
1777b2863d3aSBarry Smith #define __FUNC__ /*<a name=""></a>*/"MatLoad_SeqBAIJ"
177819bcc07fSBarry Smith int MatLoad_SeqBAIJ(Viewer viewer,MatType type,Mat *A)
17792593348eSBarry Smith {
1780b6490206SBarry Smith   Mat_SeqBAIJ  *a;
17812593348eSBarry Smith   Mat          B;
1782f1af5d2fSBarry Smith   int          i,nz,ierr,fd,header[4],size,*rowlengths=0,M,N,bs=1;
1783b6490206SBarry Smith   int          *mask,mbs,*jj,j,rowcount,nzcount,k,*browlengths,maskcount;
178435aab85fSBarry Smith   int          kmax,jcount,block,idx,point,nzcountb,extra_rows;
1785a7c10996SSatish Balay   int          *masked,nmask,tmp,bs2,ishift;
1786b6490206SBarry Smith   Scalar       *aa;
178719bcc07fSBarry Smith   MPI_Comm     comm = ((PetscObject)viewer)->comm;
17882593348eSBarry Smith 
17893a40ed3dSBarry Smith   PetscFunctionBegin;
1790f1af5d2fSBarry Smith   ierr = OptionsGetInt(PETSC_NULL,"-matload_block_size",&bs,PETSC_NULL);CHKERRQ(ierr);
1791de6a44a3SBarry Smith   bs2  = bs*bs;
1792b6490206SBarry Smith 
1793d132466eSBarry Smith   ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr);
1794cc0fae11SBarry Smith   if (size > 1) SETERRQ(PETSC_ERR_ARG_WRONG,0,"view must have one processor");
179590ace30eSBarry Smith   ierr = ViewerBinaryGetDescriptor(viewer,&fd);CHKERRQ(ierr);
17960752156aSBarry Smith   ierr = PetscBinaryRead(fd,header,4,PETSC_INT);CHKERRQ(ierr);
1797a8c6a408SBarry Smith   if (header[0] != MAT_COOKIE) SETERRQ(PETSC_ERR_FILE_UNEXPECTED,0,"not Mat object");
17982593348eSBarry Smith   M = header[1]; N = header[2]; nz = header[3];
17992593348eSBarry Smith 
1800d64ed03dSBarry Smith   if (header[3] < 0) {
1801a8c6a408SBarry Smith     SETERRQ(PETSC_ERR_FILE_UNEXPECTED,1,"Matrix stored in special format, cannot load as SeqBAIJ");
1802d64ed03dSBarry Smith   }
1803d64ed03dSBarry Smith 
1804a8c6a408SBarry Smith   if (M != N) SETERRQ(PETSC_ERR_SUP,0,"Can only do square matrices");
180535aab85fSBarry Smith 
180635aab85fSBarry Smith   /*
180735aab85fSBarry Smith      This code adds extra rows to make sure the number of rows is
180835aab85fSBarry Smith     divisible by the blocksize
180935aab85fSBarry Smith   */
1810b6490206SBarry Smith   mbs        = M/bs;
181135aab85fSBarry Smith   extra_rows = bs - M + bs*(mbs);
181235aab85fSBarry Smith   if (extra_rows == bs) extra_rows = 0;
181335aab85fSBarry Smith   else                  mbs++;
181435aab85fSBarry Smith   if (extra_rows) {
1815537820f0SBarry Smith     PLogInfo(0,"MatLoad_SeqBAIJ:Padding loaded matrix to match blocksize\n");
181635aab85fSBarry Smith   }
1817b6490206SBarry Smith 
18182593348eSBarry Smith   /* read in row lengths */
181935aab85fSBarry Smith   rowlengths = (int*)PetscMalloc((M+extra_rows)*sizeof(int));CHKPTRQ(rowlengths);
18200752156aSBarry Smith   ierr = PetscBinaryRead(fd,rowlengths,M,PETSC_INT);CHKERRQ(ierr);
182135aab85fSBarry Smith   for (i=0; i<extra_rows; i++) rowlengths[M+i] = 1;
18222593348eSBarry Smith 
1823b6490206SBarry Smith   /* read in column indices */
182435aab85fSBarry Smith   jj = (int*)PetscMalloc((nz+extra_rows)*sizeof(int));CHKPTRQ(jj);
18250752156aSBarry Smith   ierr = PetscBinaryRead(fd,jj,nz,PETSC_INT);CHKERRQ(ierr);
182635aab85fSBarry Smith   for (i=0; i<extra_rows; i++) jj[nz+i] = M+i;
1827b6490206SBarry Smith 
1828b6490206SBarry Smith   /* loop over row lengths determining block row lengths */
1829b6490206SBarry Smith   browlengths = (int*)PetscMalloc(mbs*sizeof(int));CHKPTRQ(browlengths);
1830549d3d68SSatish Balay   ierr        = PetscMemzero(browlengths,mbs*sizeof(int));CHKERRQ(ierr);
183135aab85fSBarry Smith   mask        = (int*)PetscMalloc(2*mbs*sizeof(int));CHKPTRQ(mask);
1832549d3d68SSatish Balay   ierr        = PetscMemzero(mask,mbs*sizeof(int));CHKERRQ(ierr);
183335aab85fSBarry Smith   masked      = mask + mbs;
1834b6490206SBarry Smith   rowcount    = 0; nzcount = 0;
1835b6490206SBarry Smith   for (i=0; i<mbs; i++) {
183635aab85fSBarry Smith     nmask = 0;
1837b6490206SBarry Smith     for (j=0; j<bs; j++) {
1838b6490206SBarry Smith       kmax = rowlengths[rowcount];
1839b6490206SBarry Smith       for (k=0; k<kmax; k++) {
184035aab85fSBarry Smith         tmp = jj[nzcount++]/bs;
184135aab85fSBarry Smith         if (!mask[tmp]) {masked[nmask++] = tmp; mask[tmp] = 1;}
1842b6490206SBarry Smith       }
1843b6490206SBarry Smith       rowcount++;
1844b6490206SBarry Smith     }
184535aab85fSBarry Smith     browlengths[i] += nmask;
184635aab85fSBarry Smith     /* zero out the mask elements we set */
184735aab85fSBarry Smith     for (j=0; j<nmask; j++) mask[masked[j]] = 0;
1848b6490206SBarry Smith   }
1849b6490206SBarry Smith 
18502593348eSBarry Smith   /* create our matrix */
18513eee16b0SBarry Smith   ierr = MatCreateSeqBAIJ(comm,bs,M+extra_rows,N+extra_rows,0,browlengths,A);CHKERRQ(ierr);
18522593348eSBarry Smith   B = *A;
1853b6490206SBarry Smith   a = (Mat_SeqBAIJ*)B->data;
18542593348eSBarry Smith 
18552593348eSBarry Smith   /* set matrix "i" values */
1856de6a44a3SBarry Smith   a->i[0] = 0;
1857b6490206SBarry Smith   for (i=1; i<= mbs; i++) {
1858b6490206SBarry Smith     a->i[i]      = a->i[i-1] + browlengths[i-1];
1859b6490206SBarry Smith     a->ilen[i-1] = browlengths[i-1];
18602593348eSBarry Smith   }
1861b6490206SBarry Smith   a->nz         = 0;
1862b6490206SBarry Smith   for (i=0; i<mbs; i++) a->nz += browlengths[i];
18632593348eSBarry Smith 
1864b6490206SBarry Smith   /* read in nonzero values */
186535aab85fSBarry Smith   aa = (Scalar*)PetscMalloc((nz+extra_rows)*sizeof(Scalar));CHKPTRQ(aa);
18660752156aSBarry Smith   ierr = PetscBinaryRead(fd,aa,nz,PETSC_SCALAR);CHKERRQ(ierr);
186735aab85fSBarry Smith   for (i=0; i<extra_rows; i++) aa[nz+i] = 1.0;
1868b6490206SBarry Smith 
1869b6490206SBarry Smith   /* set "a" and "j" values into matrix */
1870b6490206SBarry Smith   nzcount = 0; jcount = 0;
1871b6490206SBarry Smith   for (i=0; i<mbs; i++) {
1872b6490206SBarry Smith     nzcountb = nzcount;
187335aab85fSBarry Smith     nmask    = 0;
1874b6490206SBarry Smith     for (j=0; j<bs; j++) {
1875b6490206SBarry Smith       kmax = rowlengths[i*bs+j];
1876b6490206SBarry Smith       for (k=0; k<kmax; k++) {
187735aab85fSBarry Smith         tmp = jj[nzcount++]/bs;
187835aab85fSBarry Smith 	if (!mask[tmp]) { masked[nmask++] = tmp; mask[tmp] = 1;}
1879b6490206SBarry Smith       }
1880b6490206SBarry Smith       rowcount++;
1881b6490206SBarry Smith     }
1882de6a44a3SBarry Smith     /* sort the masked values */
1883433994e6SBarry Smith     ierr = PetscSortInt(nmask,masked);CHKERRQ(ierr);
1884de6a44a3SBarry Smith 
1885b6490206SBarry Smith     /* set "j" values into matrix */
1886b6490206SBarry Smith     maskcount = 1;
188735aab85fSBarry Smith     for (j=0; j<nmask; j++) {
188835aab85fSBarry Smith       a->j[jcount++]  = masked[j];
1889de6a44a3SBarry Smith       mask[masked[j]] = maskcount++;
1890b6490206SBarry Smith     }
1891b6490206SBarry Smith     /* set "a" values into matrix */
1892de6a44a3SBarry Smith     ishift = bs2*a->i[i];
1893b6490206SBarry Smith     for (j=0; j<bs; j++) {
1894b6490206SBarry Smith       kmax = rowlengths[i*bs+j];
1895b6490206SBarry Smith       for (k=0; k<kmax; k++) {
1896de6a44a3SBarry Smith         tmp       = jj[nzcountb]/bs ;
1897de6a44a3SBarry Smith         block     = mask[tmp] - 1;
1898de6a44a3SBarry Smith         point     = jj[nzcountb] - bs*tmp;
1899de6a44a3SBarry Smith         idx       = ishift + bs2*block + j + bs*point;
1900375fe846SBarry Smith         a->a[idx] = (MatScalar)aa[nzcountb++];
1901b6490206SBarry Smith       }
1902b6490206SBarry Smith     }
190335aab85fSBarry Smith     /* zero out the mask elements we set */
190435aab85fSBarry Smith     for (j=0; j<nmask; j++) mask[masked[j]] = 0;
1905b6490206SBarry Smith   }
1906a8c6a408SBarry Smith   if (jcount != a->nz) SETERRQ(PETSC_ERR_FILE_UNEXPECTED,0,"Bad binary matrix");
1907b6490206SBarry Smith 
1908606d414cSSatish Balay   ierr = PetscFree(rowlengths);CHKERRQ(ierr);
1909606d414cSSatish Balay   ierr = PetscFree(browlengths);CHKERRQ(ierr);
1910606d414cSSatish Balay   ierr = PetscFree(aa);CHKERRQ(ierr);
1911606d414cSSatish Balay   ierr = PetscFree(jj);CHKERRQ(ierr);
1912606d414cSSatish Balay   ierr = PetscFree(mask);CHKERRQ(ierr);
1913b6490206SBarry Smith 
1914b6490206SBarry Smith   B->assembled = PETSC_TRUE;
1915de6a44a3SBarry Smith 
19169c01be13SBarry Smith   ierr = MatView_Private(B);CHKERRQ(ierr);
19173a40ed3dSBarry Smith   PetscFunctionReturn(0);
19182593348eSBarry Smith }
19192593348eSBarry Smith 
19202593348eSBarry Smith 
19212593348eSBarry Smith 
1922