xref: /petsc/src/mat/impls/baij/seq/baij.c (revision b2863d3a52358f7ee22ca3a1f84f250141973e94)
1*b2863d3aSBarry Smith /*$Id: baij.c,v 1.201 2000/04/09 03:09:54 bsmith Exp bsmith $*/
22593348eSBarry Smith 
32593348eSBarry Smith /*
4b6490206SBarry Smith     Defines the basic matrix operations for the BAIJ (compressed row)
52593348eSBarry Smith   matrix storage format.
62593348eSBarry Smith */
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 
122d61bbb3SSatish Balay #define CHUNKSIZE  10
13de6a44a3SBarry Smith 
14be5855fcSBarry Smith /*
15be5855fcSBarry Smith      Checks for missing diagonals
16be5855fcSBarry Smith */
17be5855fcSBarry Smith #undef __FUNC__
18*b2863d3aSBarry Smith #define  __FUNC__ /*<a name=""></a>*/"MatMissingDiagonal_SeqBAIJ"
19c4992f7dSBarry Smith int MatMissingDiagonal_SeqBAIJ(Mat A)
20be5855fcSBarry Smith {
21be5855fcSBarry Smith   Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)A->data;
22883fce79SBarry Smith   int         *diag,*jj = a->j,i,ierr;
23be5855fcSBarry Smith 
24be5855fcSBarry Smith   PetscFunctionBegin;
25c4992f7dSBarry Smith   ierr = MatMarkDiagonal_SeqBAIJ(A);CHKERRQ(ierr);
26883fce79SBarry Smith   diag = a->diag;
270e8e8aceSBarry Smith   for (i=0; i<a->mbs; i++) {
28be5855fcSBarry Smith     if (jj[diag[i]] != i) {
29be5855fcSBarry Smith       SETERRQ1(1,1,"Matrix is missing diagonal number %d",i);
30be5855fcSBarry Smith     }
31be5855fcSBarry Smith   }
32be5855fcSBarry Smith   PetscFunctionReturn(0);
33be5855fcSBarry Smith }
34be5855fcSBarry Smith 
355615d1e5SSatish Balay #undef __FUNC__
36*b2863d3aSBarry Smith #define  __FUNC__ /*<a name=""></a>*/"MatMarkDiagonal_SeqBAIJ"
37c4992f7dSBarry Smith int MatMarkDiagonal_SeqBAIJ(Mat A)
38de6a44a3SBarry Smith {
39de6a44a3SBarry Smith   Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)A->data;
407fc0212eSBarry Smith   int         i,j,*diag,m = a->mbs;
41de6a44a3SBarry Smith 
423a40ed3dSBarry Smith   PetscFunctionBegin;
43883fce79SBarry Smith   if (a->diag) PetscFunctionReturn(0);
44883fce79SBarry Smith 
45de6a44a3SBarry Smith   diag = (int*)PetscMalloc((m+1)*sizeof(int));CHKPTRQ(diag);
46de6a44a3SBarry Smith   PLogObjectMemory(A,(m+1)*sizeof(int));
477fc0212eSBarry Smith   for (i=0; i<m; i++) {
48ecc615b2SBarry Smith     diag[i] = a->i[i+1];
49de6a44a3SBarry Smith     for (j=a->i[i]; j<a->i[i+1]; j++) {
50de6a44a3SBarry Smith       if (a->j[j] == i) {
51de6a44a3SBarry Smith         diag[i] = j;
52de6a44a3SBarry Smith         break;
53de6a44a3SBarry Smith       }
54de6a44a3SBarry Smith     }
55de6a44a3SBarry Smith   }
56de6a44a3SBarry Smith   a->diag = diag;
573a40ed3dSBarry Smith   PetscFunctionReturn(0);
58de6a44a3SBarry Smith }
592593348eSBarry Smith 
602593348eSBarry Smith 
613b2fbd54SBarry Smith extern int MatToSymmetricIJ_SeqAIJ(int,int*,int*,int,int,int**,int**);
623b2fbd54SBarry Smith 
635615d1e5SSatish Balay #undef __FUNC__
64*b2863d3aSBarry Smith #define  __FUNC__ /*<a name=""></a>*/"MatGetRowIJ_SeqBAIJ"
650e6d2581SBarry Smith static int MatGetRowIJ_SeqBAIJ(Mat A,int oshift,PetscTruth symmetric,int *nn,int **ia,int **ja,PetscTruth *done)
663b2fbd54SBarry Smith {
673b2fbd54SBarry Smith   Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)A->data;
683b2fbd54SBarry Smith   int         ierr,n = a->mbs,i;
693b2fbd54SBarry Smith 
703a40ed3dSBarry Smith   PetscFunctionBegin;
713b2fbd54SBarry Smith   *nn = n;
723a40ed3dSBarry Smith   if (!ia) PetscFunctionReturn(0);
733b2fbd54SBarry Smith   if (symmetric) {
743b2fbd54SBarry Smith     ierr = MatToSymmetricIJ_SeqAIJ(n,a->i,a->j,0,oshift,ia,ja);CHKERRQ(ierr);
753b2fbd54SBarry Smith   } else if (oshift == 1) {
763b2fbd54SBarry Smith     /* temporarily add 1 to i and j indices */
773b2fbd54SBarry Smith     int nz = a->i[n] + 1;
783b2fbd54SBarry Smith     for (i=0; i<nz; i++) a->j[i]++;
793b2fbd54SBarry Smith     for (i=0; i<n+1; i++) a->i[i]++;
803b2fbd54SBarry Smith     *ia = a->i; *ja = a->j;
813b2fbd54SBarry Smith   } else {
823b2fbd54SBarry Smith     *ia = a->i; *ja = a->j;
833b2fbd54SBarry Smith   }
843b2fbd54SBarry Smith 
853a40ed3dSBarry Smith   PetscFunctionReturn(0);
863b2fbd54SBarry Smith }
873b2fbd54SBarry Smith 
885615d1e5SSatish Balay #undef __FUNC__
89*b2863d3aSBarry Smith #define  __FUNC__ /*<a name=""></a>*/"MatRestoreRowIJ_SeqBAIJ"
903b2fbd54SBarry Smith static int MatRestoreRowIJ_SeqBAIJ(Mat A,int oshift,PetscTruth symmetric,int *nn,int **ia,int **ja,
913b2fbd54SBarry Smith                                 PetscTruth *done)
923b2fbd54SBarry Smith {
933b2fbd54SBarry Smith   Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)A->data;
94606d414cSSatish Balay   int         i,n = a->mbs,ierr;
953b2fbd54SBarry Smith 
963a40ed3dSBarry Smith   PetscFunctionBegin;
973a40ed3dSBarry Smith   if (!ia) PetscFunctionReturn(0);
983b2fbd54SBarry Smith   if (symmetric) {
99606d414cSSatish Balay     ierr = PetscFree(*ia);CHKERRQ(ierr);
100606d414cSSatish Balay     ierr = PetscFree(*ja);CHKERRQ(ierr);
101af5da2bfSBarry Smith   } else if (oshift == 1) {
1023b2fbd54SBarry Smith     int nz = a->i[n];
1033b2fbd54SBarry Smith     for (i=0; i<nz; i++) a->j[i]--;
1043b2fbd54SBarry Smith     for (i=0; i<n+1; i++) a->i[i]--;
1053b2fbd54SBarry Smith   }
1063a40ed3dSBarry Smith   PetscFunctionReturn(0);
1073b2fbd54SBarry Smith }
1083b2fbd54SBarry Smith 
1092d61bbb3SSatish Balay #undef __FUNC__
110*b2863d3aSBarry Smith #define  __FUNC__ /*<a name=""></a>*/"MatGetBlockSize_SeqBAIJ"
1112d61bbb3SSatish Balay int MatGetBlockSize_SeqBAIJ(Mat mat,int *bs)
1122d61bbb3SSatish Balay {
1132d61bbb3SSatish Balay   Mat_SeqBAIJ *baij = (Mat_SeqBAIJ*)mat->data;
1142d61bbb3SSatish Balay 
1152d61bbb3SSatish Balay   PetscFunctionBegin;
1162d61bbb3SSatish Balay   *bs = baij->bs;
1172d61bbb3SSatish Balay   PetscFunctionReturn(0);
1182d61bbb3SSatish Balay }
1192d61bbb3SSatish Balay 
1202d61bbb3SSatish Balay 
1212d61bbb3SSatish Balay #undef __FUNC__
122*b2863d3aSBarry Smith #define  __FUNC__ /*<a name=""></a>*/"MatDestroy_SeqBAIJ"
123e1311b90SBarry Smith int MatDestroy_SeqBAIJ(Mat A)
1242d61bbb3SSatish Balay {
1252d61bbb3SSatish Balay   Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)A->data;
126e51c0b9cSSatish Balay   int         ierr;
1272d61bbb3SSatish Balay 
128433994e6SBarry Smith   PetscFunctionBegin;
12994d884c6SBarry Smith   if (A->mapping) {
13094d884c6SBarry Smith     ierr = ISLocalToGlobalMappingDestroy(A->mapping);CHKERRQ(ierr);
13194d884c6SBarry Smith   }
13294d884c6SBarry Smith   if (A->bmapping) {
13394d884c6SBarry Smith     ierr = ISLocalToGlobalMappingDestroy(A->bmapping);CHKERRQ(ierr);
13494d884c6SBarry Smith   }
13561b13de0SBarry Smith   if (A->rmap) {
13661b13de0SBarry Smith     ierr = MapDestroy(A->rmap);CHKERRQ(ierr);
13761b13de0SBarry Smith   }
13861b13de0SBarry Smith   if (A->cmap) {
13961b13de0SBarry Smith     ierr = MapDestroy(A->cmap);CHKERRQ(ierr);
14061b13de0SBarry Smith   }
141aa482453SBarry Smith #if defined(PETSC_USE_LOG)
142e1311b90SBarry Smith   PLogObjectState((PetscObject)A,"Rows=%d, Cols=%d, NZ=%d",a->m,a->n,a->nz);
1432d61bbb3SSatish Balay #endif
144606d414cSSatish Balay   ierr = PetscFree(a->a);CHKERRQ(ierr);
145606d414cSSatish Balay   if (!a->singlemalloc) {
146606d414cSSatish Balay     ierr = PetscFree(a->i);CHKERRQ(ierr);
147606d414cSSatish Balay     ierr = PetscFree(a->j);CHKERRQ(ierr);
148606d414cSSatish Balay   }
149c38d4ed2SBarry Smith   if (a->row) {
150c38d4ed2SBarry Smith     ierr = ISDestroy(a->row);CHKERRQ(ierr);
151c38d4ed2SBarry Smith   }
152c38d4ed2SBarry Smith   if (a->col) {
153c38d4ed2SBarry Smith     ierr = ISDestroy(a->col);CHKERRQ(ierr);
154c38d4ed2SBarry Smith   }
155606d414cSSatish Balay   if (a->diag) {ierr = PetscFree(a->diag);CHKERRQ(ierr);}
156606d414cSSatish Balay   if (a->ilen) {ierr = PetscFree(a->ilen);CHKERRQ(ierr);}
157606d414cSSatish Balay   if (a->imax) {ierr = PetscFree(a->imax);CHKERRQ(ierr);}
158606d414cSSatish Balay   if (a->solve_work) {ierr = PetscFree(a->solve_work);CHKERRQ(ierr);}
159606d414cSSatish Balay   if (a->mult_work) {ierr = PetscFree(a->mult_work);CHKERRQ(ierr);}
160e51c0b9cSSatish Balay   if (a->icol) {ierr = ISDestroy(a->icol);CHKERRQ(ierr);}
161606d414cSSatish Balay   if (a->saved_values) {ierr = PetscFree(a->saved_values);CHKERRQ(ierr);}
162606d414cSSatish Balay   ierr = PetscFree(a);CHKERRQ(ierr);
1632d61bbb3SSatish Balay   PLogObjectDestroy(A);
1642d61bbb3SSatish Balay   PetscHeaderDestroy(A);
1652d61bbb3SSatish Balay   PetscFunctionReturn(0);
1662d61bbb3SSatish Balay }
1672d61bbb3SSatish Balay 
1682d61bbb3SSatish Balay #undef __FUNC__
169*b2863d3aSBarry Smith #define  __FUNC__ /*<a name=""></a>*/"MatSetOption_SeqBAIJ"
1702d61bbb3SSatish Balay int MatSetOption_SeqBAIJ(Mat A,MatOption op)
1712d61bbb3SSatish Balay {
1722d61bbb3SSatish Balay   Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)A->data;
1732d61bbb3SSatish Balay 
1742d61bbb3SSatish Balay   PetscFunctionBegin;
175c4992f7dSBarry Smith   if      (op == MAT_ROW_ORIENTED)                 a->roworiented    = PETSC_TRUE;
176c4992f7dSBarry Smith   else if (op == MAT_COLUMN_ORIENTED)              a->roworiented    = PETSC_FALSE;
177c4992f7dSBarry Smith   else if (op == MAT_COLUMNS_SORTED)               a->sorted         = PETSC_TRUE;
178c4992f7dSBarry Smith   else if (op == MAT_COLUMNS_UNSORTED)             a->sorted         = PETSC_FALSE;
179c4992f7dSBarry Smith   else if (op == MAT_KEEP_ZEROED_ROWS)             a->keepzeroedrows = PETSC_TRUE;
1802d61bbb3SSatish Balay   else if (op == MAT_NO_NEW_NONZERO_LOCATIONS)     a->nonew          = 1;
1814787f768SSatish Balay   else if (op == MAT_NEW_NONZERO_LOCATION_ERR)     a->nonew          = -1;
1824787f768SSatish Balay   else if (op == MAT_NEW_NONZERO_ALLOCATION_ERR)   a->nonew          = -2;
1832d61bbb3SSatish Balay   else if (op == MAT_YES_NEW_NONZERO_LOCATIONS)    a->nonew          = 0;
1842d61bbb3SSatish Balay   else if (op == MAT_ROWS_SORTED ||
1852d61bbb3SSatish Balay            op == MAT_ROWS_UNSORTED ||
1862d61bbb3SSatish Balay            op == MAT_SYMMETRIC ||
1872d61bbb3SSatish Balay            op == MAT_STRUCTURALLY_SYMMETRIC ||
1882d61bbb3SSatish Balay            op == MAT_YES_NEW_DIAGONALS ||
189b51ba29fSSatish Balay            op == MAT_IGNORE_OFF_PROC_ENTRIES ||
190b51ba29fSSatish Balay            op == MAT_USE_HASH_TABLE) {
191981c4779SBarry Smith     PLogInfo(A,"MatSetOption_SeqBAIJ:Option ignored\n");
1922d61bbb3SSatish Balay   } else if (op == MAT_NO_NEW_DIAGONALS) {
1932d61bbb3SSatish Balay     SETERRQ(PETSC_ERR_SUP,0,"MAT_NO_NEW_DIAGONALS");
1942d61bbb3SSatish Balay   } else {
1952d61bbb3SSatish Balay     SETERRQ(PETSC_ERR_SUP,0,"unknown option");
1962d61bbb3SSatish Balay   }
1972d61bbb3SSatish Balay   PetscFunctionReturn(0);
1982d61bbb3SSatish Balay }
1992d61bbb3SSatish Balay 
2002d61bbb3SSatish Balay 
2012d61bbb3SSatish Balay #undef __FUNC__
202*b2863d3aSBarry Smith #define  __FUNC__ /*<a name=""></a>*/"MatGetSize_SeqBAIJ"
2032d61bbb3SSatish Balay int MatGetSize_SeqBAIJ(Mat A,int *m,int *n)
2042d61bbb3SSatish Balay {
2052d61bbb3SSatish Balay   Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)A->data;
2062d61bbb3SSatish Balay 
2072d61bbb3SSatish Balay   PetscFunctionBegin;
2082d61bbb3SSatish Balay   if (m) *m = a->m;
2092d61bbb3SSatish Balay   if (n) *n = a->n;
2102d61bbb3SSatish Balay   PetscFunctionReturn(0);
2112d61bbb3SSatish Balay }
2122d61bbb3SSatish Balay 
2132d61bbb3SSatish Balay #undef __FUNC__
214*b2863d3aSBarry Smith #define  __FUNC__ /*<a name=""></a>*/"MatGetOwnershipRange_SeqBAIJ"
2152d61bbb3SSatish Balay int MatGetOwnershipRange_SeqBAIJ(Mat A,int *m,int *n)
2162d61bbb3SSatish Balay {
2172d61bbb3SSatish Balay   Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)A->data;
2182d61bbb3SSatish Balay 
2192d61bbb3SSatish Balay   PetscFunctionBegin;
2204c49b128SBarry Smith   if (m) *m = 0;
2214c49b128SBarry Smith   if (n) *n = a->m;
2222d61bbb3SSatish Balay   PetscFunctionReturn(0);
2232d61bbb3SSatish Balay }
2242d61bbb3SSatish Balay 
2252d61bbb3SSatish Balay #undef __FUNC__
226*b2863d3aSBarry Smith #define  __FUNC__ /*<a name=""></a>*/"MatGetRow_SeqBAIJ"
2272d61bbb3SSatish Balay int MatGetRow_SeqBAIJ(Mat A,int row,int *nz,int **idx,Scalar **v)
2282d61bbb3SSatish Balay {
2292d61bbb3SSatish Balay   Mat_SeqBAIJ  *a = (Mat_SeqBAIJ*)A->data;
2302d61bbb3SSatish Balay   int          itmp,i,j,k,M,*ai,*aj,bs,bn,bp,*idx_i,bs2;
2313f1db9ecSBarry Smith   MatScalar    *aa,*aa_i;
2323f1db9ecSBarry Smith   Scalar       *v_i;
2332d61bbb3SSatish Balay 
2342d61bbb3SSatish Balay   PetscFunctionBegin;
2352d61bbb3SSatish Balay   bs  = a->bs;
2362d61bbb3SSatish Balay   ai  = a->i;
2372d61bbb3SSatish Balay   aj  = a->j;
2382d61bbb3SSatish Balay   aa  = a->a;
2392d61bbb3SSatish Balay   bs2 = a->bs2;
2402d61bbb3SSatish Balay 
2412d61bbb3SSatish Balay   if (row < 0 || row >= a->m) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Row out of range");
2422d61bbb3SSatish Balay 
2432d61bbb3SSatish Balay   bn  = row/bs;   /* Block number */
2442d61bbb3SSatish Balay   bp  = row % bs; /* Block Position */
2452d61bbb3SSatish Balay   M   = ai[bn+1] - ai[bn];
2462d61bbb3SSatish Balay   *nz = bs*M;
2472d61bbb3SSatish Balay 
2482d61bbb3SSatish Balay   if (v) {
2492d61bbb3SSatish Balay     *v = 0;
2502d61bbb3SSatish Balay     if (*nz) {
2512d61bbb3SSatish Balay       *v = (Scalar*)PetscMalloc((*nz)*sizeof(Scalar));CHKPTRQ(*v);
2522d61bbb3SSatish Balay       for (i=0; i<M; i++) { /* for each block in the block row */
2532d61bbb3SSatish Balay         v_i  = *v + i*bs;
2542d61bbb3SSatish Balay         aa_i = aa + bs2*(ai[bn] + i);
2552d61bbb3SSatish Balay         for (j=bp,k=0; j<bs2; j+=bs,k++) {v_i[k] = aa_i[j];}
2562d61bbb3SSatish Balay       }
2572d61bbb3SSatish Balay     }
2582d61bbb3SSatish Balay   }
2592d61bbb3SSatish Balay 
2602d61bbb3SSatish Balay   if (idx) {
2612d61bbb3SSatish Balay     *idx = 0;
2622d61bbb3SSatish Balay     if (*nz) {
2632d61bbb3SSatish Balay       *idx = (int*)PetscMalloc((*nz)*sizeof(int));CHKPTRQ(*idx);
2642d61bbb3SSatish Balay       for (i=0; i<M; i++) { /* for each block in the block row */
2652d61bbb3SSatish Balay         idx_i = *idx + i*bs;
2662d61bbb3SSatish Balay         itmp  = bs*aj[ai[bn] + i];
2672d61bbb3SSatish Balay         for (j=0; j<bs; j++) {idx_i[j] = itmp++;}
2682d61bbb3SSatish Balay       }
2692d61bbb3SSatish Balay     }
2702d61bbb3SSatish Balay   }
2712d61bbb3SSatish Balay   PetscFunctionReturn(0);
2722d61bbb3SSatish Balay }
2732d61bbb3SSatish Balay 
2742d61bbb3SSatish Balay #undef __FUNC__
275*b2863d3aSBarry Smith #define  __FUNC__ /*<a name=""></a>*/"MatRestoreRow_SeqBAIJ"
2762d61bbb3SSatish Balay int MatRestoreRow_SeqBAIJ(Mat A,int row,int *nz,int **idx,Scalar **v)
2772d61bbb3SSatish Balay {
278606d414cSSatish Balay   int ierr;
279606d414cSSatish Balay 
2802d61bbb3SSatish Balay   PetscFunctionBegin;
281606d414cSSatish Balay   if (idx) {if (*idx) {ierr = PetscFree(*idx);CHKERRQ(ierr);}}
282606d414cSSatish Balay   if (v)   {if (*v)   {ierr = PetscFree(*v);CHKERRQ(ierr);}}
2832d61bbb3SSatish Balay   PetscFunctionReturn(0);
2842d61bbb3SSatish Balay }
2852d61bbb3SSatish Balay 
2862d61bbb3SSatish Balay #undef __FUNC__
287*b2863d3aSBarry Smith #define  __FUNC__ /*<a name=""></a>*/"MatTranspose_SeqBAIJ"
2882d61bbb3SSatish Balay int MatTranspose_SeqBAIJ(Mat A,Mat *B)
2892d61bbb3SSatish Balay {
2902d61bbb3SSatish Balay   Mat_SeqBAIJ *a=(Mat_SeqBAIJ *)A->data;
2912d61bbb3SSatish Balay   Mat         C;
2922d61bbb3SSatish Balay   int         i,j,k,ierr,*aj=a->j,*ai=a->i,bs=a->bs,mbs=a->mbs,nbs=a->nbs,len,*col;
2930e6d2581SBarry Smith   int         *rows,*cols,bs2=a->bs2,refct;
294375fe846SBarry Smith   Scalar      *array;
2952d61bbb3SSatish Balay 
2962d61bbb3SSatish Balay   PetscFunctionBegin;
2970e6d2581SBarry Smith   if (!B && mbs!=nbs) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Square matrix only for in-place");
2982d61bbb3SSatish Balay   col  = (int*)PetscMalloc((1+nbs)*sizeof(int));CHKPTRQ(col);
299549d3d68SSatish Balay   ierr = PetscMemzero(col,(1+nbs)*sizeof(int));CHKERRQ(ierr);
3002d61bbb3SSatish Balay 
301375fe846SBarry Smith #if defined(PETSC_USE_MAT_SINGLE)
302375fe846SBarry Smith   array = (Scalar *)PetscMalloc(a->bs2*a->nz*sizeof(Scalar));CHKPTRQ(array);
303375fe846SBarry Smith   for (i=0; i<a->bs2*a->nz; i++) array[i] = (Scalar)a->a[i];
304375fe846SBarry Smith #else
3053eda8832SBarry Smith   array = a->a;
306375fe846SBarry Smith #endif
307375fe846SBarry Smith 
3082d61bbb3SSatish Balay   for (i=0; i<ai[mbs]; i++) col[aj[i]] += 1;
3092d61bbb3SSatish Balay   ierr = MatCreateSeqBAIJ(A->comm,bs,a->n,a->m,PETSC_NULL,col,&C);CHKERRQ(ierr);
310606d414cSSatish Balay   ierr = PetscFree(col);CHKERRQ(ierr);
3112d61bbb3SSatish Balay   rows = (int*)PetscMalloc(2*bs*sizeof(int));CHKPTRQ(rows);
3122d61bbb3SSatish Balay   cols = rows + bs;
3132d61bbb3SSatish Balay   for (i=0; i<mbs; i++) {
3142d61bbb3SSatish Balay     cols[0] = i*bs;
3152d61bbb3SSatish Balay     for (k=1; k<bs; k++) cols[k] = cols[k-1] + 1;
3162d61bbb3SSatish Balay     len = ai[i+1] - ai[i];
3172d61bbb3SSatish Balay     for (j=0; j<len; j++) {
3182d61bbb3SSatish Balay       rows[0] = (*aj++)*bs;
3192d61bbb3SSatish Balay       for (k=1; k<bs; k++) rows[k] = rows[k-1] + 1;
3202d61bbb3SSatish Balay       ierr = MatSetValues(C,bs,rows,bs,cols,array,INSERT_VALUES);CHKERRQ(ierr);
3212d61bbb3SSatish Balay       array += bs2;
3222d61bbb3SSatish Balay     }
3232d61bbb3SSatish Balay   }
324606d414cSSatish Balay   ierr = PetscFree(rows);CHKERRQ(ierr);
325375fe846SBarry Smith #if defined(PETSC_USE_MAT_SINGLE)
326375fe846SBarry Smith   ierr = PetscFree(array);
327375fe846SBarry Smith #endif
3282d61bbb3SSatish Balay 
3292d61bbb3SSatish Balay   ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
3302d61bbb3SSatish Balay   ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
3312d61bbb3SSatish Balay 
332c4992f7dSBarry Smith   if (B) {
3332d61bbb3SSatish Balay     *B = C;
3342d61bbb3SSatish Balay   } else {
335f830108cSBarry Smith     PetscOps *Abops;
336cc2dc46cSBarry Smith     MatOps   Aops;
337f830108cSBarry Smith 
3382d61bbb3SSatish Balay     /* This isn't really an in-place transpose */
339606d414cSSatish Balay     ierr = PetscFree(a->a);CHKERRQ(ierr);
340606d414cSSatish Balay     if (!a->singlemalloc) {
341606d414cSSatish Balay       ierr = PetscFree(a->i);CHKERRQ(ierr);
342606d414cSSatish Balay       ierr = PetscFree(a->j);CHKERRQ(ierr);
343606d414cSSatish Balay     }
344606d414cSSatish Balay     if (a->diag) {ierr = PetscFree(a->diag);CHKERRQ(ierr);}
345606d414cSSatish Balay     if (a->ilen) {ierr = PetscFree(a->ilen);CHKERRQ(ierr);}
346606d414cSSatish Balay     if (a->imax) {ierr = PetscFree(a->imax);CHKERRQ(ierr);}
347606d414cSSatish Balay     if (a->solve_work) {ierr = PetscFree(a->solve_work);CHKERRQ(ierr);}
348606d414cSSatish Balay     ierr = PetscFree(a);CHKERRQ(ierr);
349f830108cSBarry Smith 
3507413bad6SBarry Smith 
3517413bad6SBarry Smith     ierr = MapDestroy(A->rmap);CHKERRQ(ierr);
3527413bad6SBarry Smith     ierr = MapDestroy(A->cmap);CHKERRQ(ierr);
3537413bad6SBarry Smith 
354f830108cSBarry Smith     /*
355f830108cSBarry Smith        This is horrible, horrible code. We need to keep the
356f830108cSBarry Smith       A pointers for the bops and ops but copy everything
357f830108cSBarry Smith       else from C.
358f830108cSBarry Smith     */
359f830108cSBarry Smith     Abops    = A->bops;
360f830108cSBarry Smith     Aops     = A->ops;
3610e6d2581SBarry Smith     refct    = A->refct;
362549d3d68SSatish Balay     ierr     = PetscMemcpy(A,C,sizeof(struct _p_Mat));CHKERRQ(ierr);
363f830108cSBarry Smith     A->bops  = Abops;
364f830108cSBarry Smith     A->ops   = Aops;
36527a8da17SBarry Smith     A->qlist = 0;
3660e6d2581SBarry Smith     A->refct = refct;
367f830108cSBarry Smith 
3682d61bbb3SSatish Balay     PetscHeaderDestroy(C);
3692d61bbb3SSatish Balay   }
3702d61bbb3SSatish Balay   PetscFunctionReturn(0);
3712d61bbb3SSatish Balay }
3722d61bbb3SSatish Balay 
3735615d1e5SSatish Balay #undef __FUNC__
374*b2863d3aSBarry Smith #define  __FUNC__ /*<a name=""></a>*/"MatView_SeqBAIJ_Binary"
375b6490206SBarry Smith static int MatView_SeqBAIJ_Binary(Mat A,Viewer viewer)
3762593348eSBarry Smith {
377b6490206SBarry Smith   Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)A->data;
3789df24120SSatish Balay   int         i,fd,*col_lens,ierr,bs = a->bs,count,*jj,j,k,l,bs2=a->bs2;
379b6490206SBarry Smith   Scalar      *aa;
380ce6f0cecSBarry Smith   FILE        *file;
3812593348eSBarry Smith 
3823a40ed3dSBarry Smith   PetscFunctionBegin;
38390ace30eSBarry Smith   ierr = ViewerBinaryGetDescriptor(viewer,&fd);CHKERRQ(ierr);
3842593348eSBarry Smith   col_lens = (int*)PetscMalloc((4+a->m)*sizeof(int));CHKPTRQ(col_lens);
3852593348eSBarry Smith   col_lens[0] = MAT_COOKIE;
3863b2fbd54SBarry Smith 
3872593348eSBarry Smith   col_lens[1] = a->m;
3882593348eSBarry Smith   col_lens[2] = a->n;
3897e67e3f9SSatish Balay   col_lens[3] = a->nz*bs2;
3902593348eSBarry Smith 
3912593348eSBarry Smith   /* store lengths of each row and write (including header) to file */
392b6490206SBarry Smith   count = 0;
393b6490206SBarry Smith   for (i=0; i<a->mbs; i++) {
394b6490206SBarry Smith     for (j=0; j<bs; j++) {
395b6490206SBarry Smith       col_lens[4+count++] = bs*(a->i[i+1] - a->i[i]);
396b6490206SBarry Smith     }
3972593348eSBarry Smith   }
3980752156aSBarry Smith   ierr = PetscBinaryWrite(fd,col_lens,4+a->m,PETSC_INT,1);CHKERRQ(ierr);
399606d414cSSatish Balay   ierr = PetscFree(col_lens);CHKERRQ(ierr);
4002593348eSBarry Smith 
4012593348eSBarry Smith   /* store column indices (zero start index) */
40266963ce1SSatish Balay   jj = (int*)PetscMalloc((a->nz+1)*bs2*sizeof(int));CHKPTRQ(jj);
403b6490206SBarry Smith   count = 0;
404b6490206SBarry Smith   for (i=0; i<a->mbs; i++) {
405b6490206SBarry Smith     for (j=0; j<bs; j++) {
406b6490206SBarry Smith       for (k=a->i[i]; k<a->i[i+1]; k++) {
407b6490206SBarry Smith         for (l=0; l<bs; l++) {
408b6490206SBarry Smith           jj[count++] = bs*a->j[k] + l;
4092593348eSBarry Smith         }
4102593348eSBarry Smith       }
411b6490206SBarry Smith     }
412b6490206SBarry Smith   }
4130752156aSBarry Smith   ierr = PetscBinaryWrite(fd,jj,bs2*a->nz,PETSC_INT,0);CHKERRQ(ierr);
414606d414cSSatish Balay   ierr = PetscFree(jj);CHKERRQ(ierr);
4152593348eSBarry Smith 
4162593348eSBarry Smith   /* store nonzero values */
41766963ce1SSatish Balay   aa = (Scalar*)PetscMalloc((a->nz+1)*bs2*sizeof(Scalar));CHKPTRQ(aa);
418b6490206SBarry Smith   count = 0;
419b6490206SBarry Smith   for (i=0; i<a->mbs; i++) {
420b6490206SBarry Smith     for (j=0; j<bs; j++) {
421b6490206SBarry Smith       for (k=a->i[i]; k<a->i[i+1]; k++) {
422b6490206SBarry Smith         for (l=0; l<bs; l++) {
4237e67e3f9SSatish Balay           aa[count++] = a->a[bs2*k + l*bs + j];
424b6490206SBarry Smith         }
425b6490206SBarry Smith       }
426b6490206SBarry Smith     }
427b6490206SBarry Smith   }
4280752156aSBarry Smith   ierr = PetscBinaryWrite(fd,aa,bs2*a->nz,PETSC_SCALAR,0);CHKERRQ(ierr);
429606d414cSSatish Balay   ierr = PetscFree(aa);CHKERRQ(ierr);
430ce6f0cecSBarry Smith 
431ce6f0cecSBarry Smith   ierr = ViewerBinaryGetInfoPointer(viewer,&file);CHKERRQ(ierr);
432ce6f0cecSBarry Smith   if (file) {
433ce6f0cecSBarry Smith     fprintf(file,"-matload_block_size %d\n",a->bs);
434ce6f0cecSBarry Smith   }
4353a40ed3dSBarry Smith   PetscFunctionReturn(0);
4362593348eSBarry Smith }
4372593348eSBarry Smith 
4385615d1e5SSatish Balay #undef __FUNC__
439*b2863d3aSBarry Smith #define  __FUNC__ /*<a name=""></a>*/"MatView_SeqBAIJ_ASCII"
440b6490206SBarry Smith static int MatView_SeqBAIJ_ASCII(Mat A,Viewer viewer)
4412593348eSBarry Smith {
442b6490206SBarry Smith   Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)A->data;
4439df24120SSatish Balay   int         ierr,i,j,format,bs = a->bs,k,l,bs2=a->bs2;
4442593348eSBarry Smith   char        *outputname;
4452593348eSBarry Smith 
4463a40ed3dSBarry Smith   PetscFunctionBegin;
44777ed5343SBarry Smith   ierr = ViewerGetOutputname(viewer,&outputname);CHKERRQ(ierr);
448888f2ed8SSatish Balay   ierr = ViewerGetFormat(viewer,&format);CHKERRQ(ierr);
449639f9d9dSBarry Smith   if (format == VIEWER_FORMAT_ASCII_INFO || format == VIEWER_FORMAT_ASCII_INFO_LONG) {
450d132466eSBarry Smith     ierr = ViewerASCIIPrintf(viewer,"  block size is %d\n",bs);CHKERRQ(ierr);
4510ef38995SBarry Smith   } else if (format == VIEWER_FORMAT_ASCII_MATLAB) {
4526831982aSBarry Smith     SETERRQ(PETSC_ERR_SUP,0,"Matlab format not supported");
4530ef38995SBarry Smith   } else if (format == VIEWER_FORMAT_ASCII_COMMON) {
4546831982aSBarry Smith     ierr = ViewerASCIIUseTabs(viewer,PETSC_NO);CHKERRQ(ierr);
45544cd7ae7SLois Curfman McInnes     for (i=0; i<a->mbs; i++) {
45644cd7ae7SLois Curfman McInnes       for (j=0; j<bs; j++) {
4576831982aSBarry Smith         ierr = ViewerASCIIPrintf(viewer,"row %d:",i*bs+j);CHKERRQ(ierr);
45844cd7ae7SLois Curfman McInnes         for (k=a->i[i]; k<a->i[i+1]; k++) {
45944cd7ae7SLois Curfman McInnes           for (l=0; l<bs; l++) {
460aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
4610e6d2581SBarry Smith             if (PetscImaginaryPart(a->a[bs2*k + l*bs + j]) > 0.0 && PetscRealPart(a->a[bs2*k + l*bs + j]) != 0.0) {
4626831982aSBarry Smith               ierr = ViewerASCIIPrintf(viewer," %d %g + %gi",bs*a->j[k]+l,
4630e6d2581SBarry Smith                       PetscRealPart(a->a[bs2*k + l*bs + j]),PetscImaginaryPart(a->a[bs2*k + l*bs + j]));CHKERRQ(ierr);
4640e6d2581SBarry Smith             } else if (PetscImaginaryPart(a->a[bs2*k + l*bs + j]) < 0.0 && PetscRealPart(a->a[bs2*k + l*bs + j]) != 0.0) {
4656831982aSBarry Smith               ierr = ViewerASCIIPrintf(viewer," %d %g - %gi",bs*a->j[k]+l,
4660e6d2581SBarry Smith                       PetscRealPart(a->a[bs2*k + l*bs + j]),-PetscImaginaryPart(a->a[bs2*k + l*bs + j]));CHKERRQ(ierr);
4670e6d2581SBarry Smith             } else if (PetscRealPart(a->a[bs2*k + l*bs + j]) != 0.0) {
4680e6d2581SBarry Smith               ierr = ViewerASCIIPrintf(viewer," %d %g ",bs*a->j[k]+l,PetscRealPart(a->a[bs2*k + l*bs + j]));CHKERRQ(ierr);
4690ef38995SBarry Smith             }
47044cd7ae7SLois Curfman McInnes #else
4710ef38995SBarry Smith             if (a->a[bs2*k + l*bs + j] != 0.0) {
4726831982aSBarry Smith               ierr = ViewerASCIIPrintf(viewer," %d %g ",bs*a->j[k]+l,a->a[bs2*k + l*bs + j]);CHKERRQ(ierr);
4730ef38995SBarry Smith             }
47444cd7ae7SLois Curfman McInnes #endif
47544cd7ae7SLois Curfman McInnes           }
47644cd7ae7SLois Curfman McInnes         }
4776831982aSBarry Smith         ierr = ViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
47844cd7ae7SLois Curfman McInnes       }
47944cd7ae7SLois Curfman McInnes     }
4806831982aSBarry Smith     ierr = ViewerASCIIUseTabs(viewer,PETSC_YES);CHKERRQ(ierr);
4810ef38995SBarry Smith   } else {
4826831982aSBarry Smith     ierr = ViewerASCIIUseTabs(viewer,PETSC_NO);CHKERRQ(ierr);
483b6490206SBarry Smith     for (i=0; i<a->mbs; i++) {
484b6490206SBarry Smith       for (j=0; j<bs; j++) {
4856831982aSBarry Smith         ierr = ViewerASCIIPrintf(viewer,"row %d:",i*bs+j);CHKERRQ(ierr);
486b6490206SBarry Smith         for (k=a->i[i]; k<a->i[i+1]; k++) {
487b6490206SBarry Smith           for (l=0; l<bs; l++) {
488aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
4890e6d2581SBarry Smith             if (PetscImaginaryPart(a->a[bs2*k + l*bs + j]) > 0.0) {
4906831982aSBarry Smith               ierr = ViewerASCIIPrintf(viewer," %d %g + %g i",bs*a->j[k]+l,
4910e6d2581SBarry Smith                 PetscRealPart(a->a[bs2*k + l*bs + j]),PetscImaginaryPart(a->a[bs2*k + l*bs + j]));CHKERRQ(ierr);
4920e6d2581SBarry Smith             } else if (PetscImaginaryPart(a->a[bs2*k + l*bs + j]) < 0.0) {
4936831982aSBarry Smith               ierr = ViewerASCIIPrintf(viewer," %d %g - %g i",bs*a->j[k]+l,
4940e6d2581SBarry Smith                 PetscRealPart(a->a[bs2*k + l*bs + j]),-PetscImaginaryPart(a->a[bs2*k + l*bs + j]));CHKERRQ(ierr);
4950ef38995SBarry Smith             } else {
4960e6d2581SBarry Smith               ierr = ViewerASCIIPrintf(viewer," %d %g ",bs*a->j[k]+l,PetscRealPart(a->a[bs2*k + l*bs + j]));CHKERRQ(ierr);
49788685aaeSLois Curfman McInnes             }
49888685aaeSLois Curfman McInnes #else
4996831982aSBarry Smith             ierr = ViewerASCIIPrintf(viewer," %d %g ",bs*a->j[k]+l,a->a[bs2*k + l*bs + j]);CHKERRQ(ierr);
50088685aaeSLois Curfman McInnes #endif
5012593348eSBarry Smith           }
5022593348eSBarry Smith         }
5036831982aSBarry Smith         ierr = ViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
5042593348eSBarry Smith       }
5052593348eSBarry Smith     }
5066831982aSBarry Smith     ierr = ViewerASCIIUseTabs(viewer,PETSC_YES);CHKERRQ(ierr);
507b6490206SBarry Smith   }
5086831982aSBarry Smith   ierr = ViewerFlush(viewer);CHKERRQ(ierr);
5093a40ed3dSBarry Smith   PetscFunctionReturn(0);
5102593348eSBarry Smith }
5112593348eSBarry Smith 
5125615d1e5SSatish Balay #undef __FUNC__
513*b2863d3aSBarry Smith #define  __FUNC__ /*<a name=""></a>*/"MatView_SeqBAIJ_Draw_Zoom"
51477ed5343SBarry Smith static int MatView_SeqBAIJ_Draw_Zoom(Draw draw,void *Aa)
5153270192aSSatish Balay {
51677ed5343SBarry Smith   Mat          A = (Mat) Aa;
5173270192aSSatish Balay   Mat_SeqBAIJ  *a=(Mat_SeqBAIJ*)A->data;
518b65db4caSBarry Smith   int          row,ierr,i,j,k,l,mbs=a->mbs,color,bs=a->bs,bs2=a->bs2;
5190e6d2581SBarry Smith   PetscReal    xl,yl,xr,yr,x_l,x_r,y_l,y_r;
5203f1db9ecSBarry Smith   MatScalar    *aa;
52177ed5343SBarry Smith   Viewer       viewer;
5223270192aSSatish Balay 
5233a40ed3dSBarry Smith   PetscFunctionBegin;
5243270192aSSatish Balay 
525b65db4caSBarry Smith   /* still need to add support for contour plot of nonzeros; see MatView_SeqAIJ_Draw_Zoom()*/
52677ed5343SBarry Smith   ierr = PetscObjectQuery((PetscObject)A,"Zoomviewer",(PetscObject*)&viewer);CHKERRQ(ierr);
52777ed5343SBarry Smith 
52877ed5343SBarry Smith   ierr = DrawGetCoordinates(draw,&xl,&yl,&xr,&yr);CHKERRQ(ierr);
52977ed5343SBarry Smith 
5303270192aSSatish Balay   /* loop over matrix elements drawing boxes */
5313270192aSSatish Balay   color = DRAW_BLUE;
5323270192aSSatish Balay   for (i=0,row=0; i<mbs; i++,row+=bs) {
5333270192aSSatish Balay     for (j=a->i[i]; j<a->i[i+1]; j++) {
5343270192aSSatish Balay       y_l = a->m - row - 1.0; y_r = y_l + 1.0;
5353270192aSSatish Balay       x_l = a->j[j]*bs; x_r = x_l + 1.0;
5363270192aSSatish Balay       aa = a->a + j*bs2;
5373270192aSSatish Balay       for (k=0; k<bs; k++) {
5383270192aSSatish Balay         for (l=0; l<bs; l++) {
5390e6d2581SBarry Smith           if (PetscRealPart(*aa++) >=  0.) continue;
540433994e6SBarry Smith           ierr = DrawRectangle(draw,x_l+k,y_l-l,x_r+k,y_r-l,color,color,color,color);CHKERRQ(ierr);
5413270192aSSatish Balay         }
5423270192aSSatish Balay       }
5433270192aSSatish Balay     }
5443270192aSSatish Balay   }
5453270192aSSatish Balay   color = DRAW_CYAN;
5463270192aSSatish Balay   for (i=0,row=0; i<mbs; i++,row+=bs) {
5473270192aSSatish Balay     for (j=a->i[i]; j<a->i[i+1]; j++) {
5483270192aSSatish Balay       y_l = a->m - row - 1.0; y_r = y_l + 1.0;
5493270192aSSatish Balay       x_l = a->j[j]*bs; x_r = x_l + 1.0;
5503270192aSSatish Balay       aa = a->a + j*bs2;
5513270192aSSatish Balay       for (k=0; k<bs; k++) {
5523270192aSSatish Balay         for (l=0; l<bs; l++) {
5530e6d2581SBarry Smith           if (PetscRealPart(*aa++) != 0.) continue;
554433994e6SBarry Smith           ierr = DrawRectangle(draw,x_l+k,y_l-l,x_r+k,y_r-l,color,color,color,color);CHKERRQ(ierr);
5553270192aSSatish Balay         }
5563270192aSSatish Balay       }
5573270192aSSatish Balay     }
5583270192aSSatish Balay   }
5593270192aSSatish Balay 
5603270192aSSatish Balay   color = DRAW_RED;
5613270192aSSatish Balay   for (i=0,row=0; i<mbs; i++,row+=bs) {
5623270192aSSatish Balay     for (j=a->i[i]; j<a->i[i+1]; j++) {
5633270192aSSatish Balay       y_l = a->m - row - 1.0; y_r = y_l + 1.0;
5643270192aSSatish Balay       x_l = a->j[j]*bs; x_r = x_l + 1.0;
5653270192aSSatish Balay       aa = a->a + j*bs2;
5663270192aSSatish Balay       for (k=0; k<bs; k++) {
5673270192aSSatish Balay         for (l=0; l<bs; l++) {
5680e6d2581SBarry Smith           if (PetscRealPart(*aa++) <= 0.) continue;
569433994e6SBarry Smith           ierr = DrawRectangle(draw,x_l+k,y_l-l,x_r+k,y_r-l,color,color,color,color);CHKERRQ(ierr);
5703270192aSSatish Balay         }
5713270192aSSatish Balay       }
5723270192aSSatish Balay     }
5733270192aSSatish Balay   }
57477ed5343SBarry Smith   PetscFunctionReturn(0);
57577ed5343SBarry Smith }
5763270192aSSatish Balay 
57777ed5343SBarry Smith #undef __FUNC__
578*b2863d3aSBarry Smith #define  __FUNC__ /*<a name=""></a>*/"MatView_SeqBAIJ_Draw"
57977ed5343SBarry Smith static int MatView_SeqBAIJ_Draw(Mat A,Viewer viewer)
58077ed5343SBarry Smith {
58177ed5343SBarry Smith   Mat_SeqBAIJ  *a=(Mat_SeqBAIJ*)A->data;
5827dce120fSSatish Balay   int          ierr;
5830e6d2581SBarry Smith   PetscReal    xl,yl,xr,yr,w,h;
58477ed5343SBarry Smith   Draw         draw;
58577ed5343SBarry Smith   PetscTruth   isnull;
5863270192aSSatish Balay 
58777ed5343SBarry Smith   PetscFunctionBegin;
58877ed5343SBarry Smith 
58977ed5343SBarry Smith   ierr = ViewerDrawGetDraw(viewer,0,&draw);CHKERRQ(ierr);
59077ed5343SBarry Smith   ierr = DrawIsNull(draw,&isnull);CHKERRQ(ierr); if (isnull) PetscFunctionReturn(0);
59177ed5343SBarry Smith 
59277ed5343SBarry Smith   ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",(PetscObject)viewer);CHKERRQ(ierr);
59377ed5343SBarry Smith   xr  = a->n; yr = a->m; h = yr/10.0; w = xr/10.0;
59477ed5343SBarry Smith   xr += w;    yr += h;  xl = -w;     yl = -h;
5953270192aSSatish Balay   ierr = DrawSetCoordinates(draw,xl,yl,xr,yr);CHKERRQ(ierr);
59677ed5343SBarry Smith   ierr = DrawZoom(draw,MatView_SeqBAIJ_Draw_Zoom,A);CHKERRQ(ierr);
59777ed5343SBarry Smith   ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",PETSC_NULL);CHKERRQ(ierr);
5983a40ed3dSBarry Smith   PetscFunctionReturn(0);
5993270192aSSatish Balay }
6003270192aSSatish Balay 
6015615d1e5SSatish Balay #undef __FUNC__
602*b2863d3aSBarry Smith #define  __FUNC__ /*<a name=""></a>*/"MatView_SeqBAIJ"
603e1311b90SBarry Smith int MatView_SeqBAIJ(Mat A,Viewer viewer)
6042593348eSBarry Smith {
60519bcc07fSBarry Smith   int        ierr;
6066831982aSBarry Smith   PetscTruth issocket,isascii,isbinary,isdraw;
6072593348eSBarry Smith 
6083a40ed3dSBarry Smith   PetscFunctionBegin;
6096831982aSBarry Smith   ierr = PetscTypeCompare((PetscObject)viewer,SOCKET_VIEWER,&issocket);CHKERRQ(ierr);
6106831982aSBarry Smith   ierr = PetscTypeCompare((PetscObject)viewer,ASCII_VIEWER,&isascii);CHKERRQ(ierr);
6116831982aSBarry Smith   ierr = PetscTypeCompare((PetscObject)viewer,BINARY_VIEWER,&isbinary);CHKERRQ(ierr);
6126831982aSBarry Smith   ierr = PetscTypeCompare((PetscObject)viewer,DRAW_VIEWER,&isdraw);CHKERRQ(ierr);
6130f5bd95cSBarry Smith   if (issocket) {
6147b2a1423SBarry Smith     SETERRQ(PETSC_ERR_SUP,0,"Socket viewer not supported");
6150f5bd95cSBarry Smith   } else if (isascii){
6163a40ed3dSBarry Smith     ierr = MatView_SeqBAIJ_ASCII(A,viewer);CHKERRQ(ierr);
6170f5bd95cSBarry Smith   } else if (isbinary) {
6183a40ed3dSBarry Smith     ierr = MatView_SeqBAIJ_Binary(A,viewer);CHKERRQ(ierr);
6190f5bd95cSBarry Smith   } else if (isdraw) {
6203a40ed3dSBarry Smith     ierr = MatView_SeqBAIJ_Draw(A,viewer);CHKERRQ(ierr);
6215cd90555SBarry Smith   } else {
6220f5bd95cSBarry Smith     SETERRQ1(1,1,"Viewer type %s not supported by SeqBAIJ matrices",((PetscObject)viewer)->type_name);
6232593348eSBarry Smith   }
6243a40ed3dSBarry Smith   PetscFunctionReturn(0);
6252593348eSBarry Smith }
626b6490206SBarry Smith 
627cd0e1443SSatish Balay 
6285615d1e5SSatish Balay #undef __FUNC__
629*b2863d3aSBarry Smith #define  __FUNC__ /*<a name=""></a>*/"MatGetValues_SeqBAIJ"
6302d61bbb3SSatish Balay int MatGetValues_SeqBAIJ(Mat A,int m,int *im,int n,int *in,Scalar *v)
631cd0e1443SSatish Balay {
632cd0e1443SSatish Balay   Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)A->data;
6332d61bbb3SSatish Balay   int        *rp,k,low,high,t,row,nrow,i,col,l,*aj = a->j;
6342d61bbb3SSatish Balay   int        *ai = a->i,*ailen = a->ilen;
6352d61bbb3SSatish Balay   int        brow,bcol,ridx,cidx,bs=a->bs,bs2=a->bs2;
6363f1db9ecSBarry Smith   MatScalar  *ap,*aa = a->a,zero = 0.0;
637cd0e1443SSatish Balay 
6383a40ed3dSBarry Smith   PetscFunctionBegin;
6392d61bbb3SSatish Balay   for (k=0; k<m; k++) { /* loop over rows */
640cd0e1443SSatish Balay     row  = im[k]; brow = row/bs;
641a8c6a408SBarry Smith     if (row < 0) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Negative row");
642a8c6a408SBarry Smith     if (row >= a->m) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Row too large");
6432d61bbb3SSatish Balay     rp   = aj + ai[brow] ; ap = aa + bs2*ai[brow] ;
6442c3acbe9SBarry Smith     nrow = ailen[brow];
6452d61bbb3SSatish Balay     for (l=0; l<n; l++) { /* loop over columns */
646a8c6a408SBarry Smith       if (in[l] < 0) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Negative column");
647a8c6a408SBarry Smith       if (in[l] >= a->n) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Column too large");
6482d61bbb3SSatish Balay       col  = in[l] ;
6492d61bbb3SSatish Balay       bcol = col/bs;
6502d61bbb3SSatish Balay       cidx = col%bs;
6512d61bbb3SSatish Balay       ridx = row%bs;
6522d61bbb3SSatish Balay       high = nrow;
6532d61bbb3SSatish Balay       low  = 0; /* assume unsorted */
6542d61bbb3SSatish Balay       while (high-low > 5) {
655cd0e1443SSatish Balay         t = (low+high)/2;
656cd0e1443SSatish Balay         if (rp[t] > bcol) high = t;
657cd0e1443SSatish Balay         else             low  = t;
658cd0e1443SSatish Balay       }
659cd0e1443SSatish Balay       for (i=low; i<high; i++) {
660cd0e1443SSatish Balay         if (rp[i] > bcol) break;
661cd0e1443SSatish Balay         if (rp[i] == bcol) {
6622d61bbb3SSatish Balay           *v++ = ap[bs2*i+bs*cidx+ridx];
6632d61bbb3SSatish Balay           goto finished;
664cd0e1443SSatish Balay         }
665cd0e1443SSatish Balay       }
6662d61bbb3SSatish Balay       *v++ = zero;
6672d61bbb3SSatish Balay       finished:;
668cd0e1443SSatish Balay     }
669cd0e1443SSatish Balay   }
6703a40ed3dSBarry Smith   PetscFunctionReturn(0);
671cd0e1443SSatish Balay }
672cd0e1443SSatish Balay 
6732d61bbb3SSatish Balay 
6745615d1e5SSatish Balay #undef __FUNC__
675*b2863d3aSBarry Smith #define  __FUNC__ /*<a name=""></a>*/"MatSetValuesBlocked_SeqBAIJ"
67692c4ed94SBarry Smith int MatSetValuesBlocked_SeqBAIJ(Mat A,int m,int *im,int n,int *in,Scalar *v,InsertMode is)
67792c4ed94SBarry Smith {
67892c4ed94SBarry Smith   Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)A->data;
6798a84c255SSatish Balay   int         *rp,k,low,high,t,ii,jj,row,nrow,i,col,l,rmax,N,sorted=a->sorted;
680dd9472c6SBarry Smith   int         *imax=a->imax,*ai=a->i,*ailen=a->ilen,roworiented=a->roworiented;
681549d3d68SSatish Balay   int         *aj=a->j,nonew=a->nonew,bs2=a->bs2,bs=a->bs,stepval,ierr;
6823f1db9ecSBarry Smith   Scalar      *value = v;
6833f1db9ecSBarry Smith   MatScalar   *ap,*aa=a->a,*bap;
68492c4ed94SBarry Smith 
6853a40ed3dSBarry Smith   PetscFunctionBegin;
6860e324ae4SSatish Balay   if (roworiented) {
6870e324ae4SSatish Balay     stepval = (n-1)*bs;
6880e324ae4SSatish Balay   } else {
6890e324ae4SSatish Balay     stepval = (m-1)*bs;
6900e324ae4SSatish Balay   }
69192c4ed94SBarry Smith   for (k=0; k<m; k++) { /* loop over added rows */
69292c4ed94SBarry Smith     row  = im[k];
6935ef9f2a5SBarry Smith     if (row < 0) continue;
694aa482453SBarry Smith #if defined(PETSC_USE_BOPT_g)
695a8c6a408SBarry Smith     if (row >= a->mbs) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Row too large");
69692c4ed94SBarry Smith #endif
69792c4ed94SBarry Smith     rp   = aj + ai[row];
69892c4ed94SBarry Smith     ap   = aa + bs2*ai[row];
69992c4ed94SBarry Smith     rmax = imax[row];
70092c4ed94SBarry Smith     nrow = ailen[row];
70192c4ed94SBarry Smith     low  = 0;
70292c4ed94SBarry Smith     for (l=0; l<n; l++) { /* loop over added columns */
7035ef9f2a5SBarry Smith       if (in[l] < 0) continue;
704aa482453SBarry Smith #if defined(PETSC_USE_BOPT_g)
705a8c6a408SBarry Smith       if (in[l] >= a->nbs) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Column too large");
70692c4ed94SBarry Smith #endif
70792c4ed94SBarry Smith       col = in[l];
70892c4ed94SBarry Smith       if (roworiented) {
7090e324ae4SSatish Balay         value = v + k*(stepval+bs)*bs + l*bs;
7100e324ae4SSatish Balay       } else {
7110e324ae4SSatish Balay         value = v + l*(stepval+bs)*bs + k*bs;
71292c4ed94SBarry Smith       }
71392c4ed94SBarry Smith       if (!sorted) low = 0; high = nrow;
71492c4ed94SBarry Smith       while (high-low > 7) {
71592c4ed94SBarry Smith         t = (low+high)/2;
71692c4ed94SBarry Smith         if (rp[t] > col) high = t;
71792c4ed94SBarry Smith         else             low  = t;
71892c4ed94SBarry Smith       }
71992c4ed94SBarry Smith       for (i=low; i<high; i++) {
72092c4ed94SBarry Smith         if (rp[i] > col) break;
72192c4ed94SBarry Smith         if (rp[i] == col) {
7228a84c255SSatish Balay           bap  = ap +  bs2*i;
7230e324ae4SSatish Balay           if (roworiented) {
7248a84c255SSatish Balay             if (is == ADD_VALUES) {
725dd9472c6SBarry Smith               for (ii=0; ii<bs; ii++,value+=stepval) {
726dd9472c6SBarry Smith                 for (jj=ii; jj<bs2; jj+=bs) {
7278a84c255SSatish Balay                   bap[jj] += *value++;
728dd9472c6SBarry Smith                 }
729dd9472c6SBarry Smith               }
7300e324ae4SSatish Balay             } else {
731dd9472c6SBarry Smith               for (ii=0; ii<bs; ii++,value+=stepval) {
732dd9472c6SBarry Smith                 for (jj=ii; jj<bs2; jj+=bs) {
7330e324ae4SSatish Balay                   bap[jj] = *value++;
7348a84c255SSatish Balay                 }
735dd9472c6SBarry Smith               }
736dd9472c6SBarry Smith             }
7370e324ae4SSatish Balay           } else {
7380e324ae4SSatish Balay             if (is == ADD_VALUES) {
739dd9472c6SBarry Smith               for (ii=0; ii<bs; ii++,value+=stepval) {
740dd9472c6SBarry Smith                 for (jj=0; jj<bs; jj++) {
7410e324ae4SSatish Balay                   *bap++ += *value++;
742dd9472c6SBarry Smith                 }
743dd9472c6SBarry Smith               }
7440e324ae4SSatish Balay             } else {
745dd9472c6SBarry Smith               for (ii=0; ii<bs; ii++,value+=stepval) {
746dd9472c6SBarry Smith                 for (jj=0; jj<bs; jj++) {
7470e324ae4SSatish Balay                   *bap++  = *value++;
7480e324ae4SSatish Balay                 }
7498a84c255SSatish Balay               }
750dd9472c6SBarry Smith             }
751dd9472c6SBarry Smith           }
752f1241b54SBarry Smith           goto noinsert2;
75392c4ed94SBarry Smith         }
75492c4ed94SBarry Smith       }
75589280ab3SLois Curfman McInnes       if (nonew == 1) goto noinsert2;
756a8c6a408SBarry Smith       else if (nonew == -1) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Inserting a new nonzero in the matrix");
75792c4ed94SBarry Smith       if (nrow >= rmax) {
75892c4ed94SBarry Smith         /* there is no extra room in row, therefore enlarge */
75992c4ed94SBarry Smith         int       new_nz = ai[a->mbs] + CHUNKSIZE,len,*new_i,*new_j;
7603f1db9ecSBarry Smith         MatScalar *new_a;
76192c4ed94SBarry Smith 
762a8c6a408SBarry Smith         if (nonew == -2) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Inserting a new nonzero in the matrix");
76389280ab3SLois Curfman McInnes 
76492c4ed94SBarry Smith         /* malloc new storage space */
7653f1db9ecSBarry Smith         len     = new_nz*(sizeof(int)+bs2*sizeof(MatScalar))+(a->mbs+1)*sizeof(int);
7663f1db9ecSBarry Smith         new_a   = (MatScalar*)PetscMalloc(len);CHKPTRQ(new_a);
76792c4ed94SBarry Smith         new_j   = (int*)(new_a + bs2*new_nz);
76892c4ed94SBarry Smith         new_i   = new_j + new_nz;
76992c4ed94SBarry Smith 
77092c4ed94SBarry Smith         /* copy over old data into new slots */
77192c4ed94SBarry Smith         for (ii=0; ii<row+1; ii++) {new_i[ii] = ai[ii];}
77292c4ed94SBarry Smith         for (ii=row+1; ii<a->mbs+1; ii++) {new_i[ii] = ai[ii]+CHUNKSIZE;}
773549d3d68SSatish Balay         ierr = PetscMemcpy(new_j,aj,(ai[row]+nrow)*sizeof(int));CHKERRQ(ierr);
77492c4ed94SBarry Smith         len  = (new_nz - CHUNKSIZE - ai[row] - nrow);
775549d3d68SSatish Balay         ierr = PetscMemcpy(new_j+ai[row]+nrow+CHUNKSIZE,aj+ai[row]+nrow,len*sizeof(int));CHKERRQ(ierr);
776549d3d68SSatish Balay         ierr = PetscMemcpy(new_a,aa,(ai[row]+nrow)*bs2*sizeof(MatScalar));CHKERRQ(ierr);
777549d3d68SSatish Balay         ierr = PetscMemzero(new_a+bs2*(ai[row]+nrow),bs2*CHUNKSIZE*sizeof(MatScalar));CHKERRQ(ierr);
778549d3d68SSatish Balay         ierr = PetscMemcpy(new_a+bs2*(ai[row]+nrow+CHUNKSIZE),aa+bs2*(ai[row]+nrow),bs2*len*sizeof(MatScalar));CHKERRQ(ierr);
77992c4ed94SBarry Smith         /* free up old matrix storage */
780606d414cSSatish Balay         ierr = PetscFree(a->a);CHKERRQ(ierr);
781606d414cSSatish Balay         if (!a->singlemalloc) {
782606d414cSSatish Balay           ierr = PetscFree(a->i);CHKERRQ(ierr);
783606d414cSSatish Balay           ierr = PetscFree(a->j);CHKERRQ(ierr);
784606d414cSSatish Balay         }
78592c4ed94SBarry Smith         aa = a->a = new_a; ai = a->i = new_i; aj = a->j = new_j;
786c4992f7dSBarry Smith         a->singlemalloc = PETSC_TRUE;
78792c4ed94SBarry Smith 
78892c4ed94SBarry Smith         rp   = aj + ai[row]; ap = aa + bs2*ai[row];
78992c4ed94SBarry Smith         rmax = imax[row] = imax[row] + CHUNKSIZE;
7903f1db9ecSBarry Smith         PLogObjectMemory(A,CHUNKSIZE*(sizeof(int) + bs2*sizeof(MatScalar)));
79192c4ed94SBarry Smith         a->maxnz += bs2*CHUNKSIZE;
79292c4ed94SBarry Smith         a->reallocs++;
79392c4ed94SBarry Smith         a->nz++;
79492c4ed94SBarry Smith       }
79592c4ed94SBarry Smith       N = nrow++ - 1;
79692c4ed94SBarry Smith       /* shift up all the later entries in this row */
79792c4ed94SBarry Smith       for (ii=N; ii>=i; ii--) {
79892c4ed94SBarry Smith         rp[ii+1] = rp[ii];
799549d3d68SSatish Balay         ierr = PetscMemcpy(ap+bs2*(ii+1),ap+bs2*(ii),bs2*sizeof(MatScalar));CHKERRQ(ierr);
80092c4ed94SBarry Smith       }
801549d3d68SSatish Balay       if (N >= i) {
802549d3d68SSatish Balay         ierr = PetscMemzero(ap+bs2*i,bs2*sizeof(MatScalar));CHKERRQ(ierr);
803549d3d68SSatish Balay       }
80492c4ed94SBarry Smith       rp[i] = col;
8058a84c255SSatish Balay       bap   = ap +  bs2*i;
8060e324ae4SSatish Balay       if (roworiented) {
807dd9472c6SBarry Smith         for (ii=0; ii<bs; ii++,value+=stepval) {
808dd9472c6SBarry Smith           for (jj=ii; jj<bs2; jj+=bs) {
8090e324ae4SSatish Balay             bap[jj] = *value++;
810dd9472c6SBarry Smith           }
811dd9472c6SBarry Smith         }
8120e324ae4SSatish Balay       } else {
813dd9472c6SBarry Smith         for (ii=0; ii<bs; ii++,value+=stepval) {
814dd9472c6SBarry Smith           for (jj=0; jj<bs; jj++) {
8150e324ae4SSatish Balay             *bap++  = *value++;
8160e324ae4SSatish Balay           }
817dd9472c6SBarry Smith         }
818dd9472c6SBarry Smith       }
819f1241b54SBarry Smith       noinsert2:;
82092c4ed94SBarry Smith       low = i;
82192c4ed94SBarry Smith     }
82292c4ed94SBarry Smith     ailen[row] = nrow;
82392c4ed94SBarry Smith   }
8243a40ed3dSBarry Smith   PetscFunctionReturn(0);
82592c4ed94SBarry Smith }
82692c4ed94SBarry Smith 
827f2501298SSatish Balay 
8285615d1e5SSatish Balay #undef __FUNC__
829*b2863d3aSBarry Smith #define  __FUNC__ /*<a name=""></a>*/"MatAssemblyEnd_SeqBAIJ"
8308f6be9afSLois Curfman McInnes int MatAssemblyEnd_SeqBAIJ(Mat A,MatAssemblyType mode)
831584200bdSSatish Balay {
832584200bdSSatish Balay   Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)A->data;
833584200bdSSatish Balay   int        fshift = 0,i,j,*ai = a->i,*aj = a->j,*imax = a->imax;
834a7c10996SSatish Balay   int        m = a->m,*ip,N,*ailen = a->ilen;
835549d3d68SSatish Balay   int        mbs = a->mbs,bs2 = a->bs2,rmax = 0,ierr;
8363f1db9ecSBarry Smith   MatScalar  *aa = a->a,*ap;
837584200bdSSatish Balay 
8383a40ed3dSBarry Smith   PetscFunctionBegin;
8393a40ed3dSBarry Smith   if (mode == MAT_FLUSH_ASSEMBLY) PetscFunctionReturn(0);
840584200bdSSatish Balay 
84143ee02c3SBarry Smith   if (m) rmax = ailen[0];
842584200bdSSatish Balay   for (i=1; i<mbs; i++) {
843584200bdSSatish Balay     /* move each row back by the amount of empty slots (fshift) before it*/
844584200bdSSatish Balay     fshift += imax[i-1] - ailen[i-1];
845d402145bSBarry Smith     rmax   = PetscMax(rmax,ailen[i]);
846584200bdSSatish Balay     if (fshift) {
847a7c10996SSatish Balay       ip = aj + ai[i]; ap = aa + bs2*ai[i];
848584200bdSSatish Balay       N = ailen[i];
849584200bdSSatish Balay       for (j=0; j<N; j++) {
850584200bdSSatish Balay         ip[j-fshift] = ip[j];
851549d3d68SSatish Balay         ierr = PetscMemcpy(ap+(j-fshift)*bs2,ap+j*bs2,bs2*sizeof(MatScalar));CHKERRQ(ierr);
852584200bdSSatish Balay       }
853584200bdSSatish Balay     }
854584200bdSSatish Balay     ai[i] = ai[i-1] + ailen[i-1];
855584200bdSSatish Balay   }
856584200bdSSatish Balay   if (mbs) {
857584200bdSSatish Balay     fshift += imax[mbs-1] - ailen[mbs-1];
858584200bdSSatish Balay     ai[mbs] = ai[mbs-1] + ailen[mbs-1];
859584200bdSSatish Balay   }
860584200bdSSatish Balay   /* reset ilen and imax for each row */
861584200bdSSatish Balay   for (i=0; i<mbs; i++) {
862584200bdSSatish Balay     ailen[i] = imax[i] = ai[i+1] - ai[i];
863584200bdSSatish Balay   }
864a7c10996SSatish Balay   a->nz = ai[mbs];
865584200bdSSatish Balay 
866584200bdSSatish Balay   /* diagonals may have moved, so kill the diagonal pointers */
867584200bdSSatish Balay   if (fshift && a->diag) {
868606d414cSSatish Balay     ierr = PetscFree(a->diag);CHKERRQ(ierr);
869584200bdSSatish Balay     PLogObjectMemory(A,-(m+1)*sizeof(int));
870584200bdSSatish Balay     a->diag = 0;
871584200bdSSatish Balay   }
8723d2013a6SLois Curfman McInnes   PLogInfo(A,"MatAssemblyEnd_SeqBAIJ:Matrix size: %d X %d, block size %d; storage space: %d unneeded, %d used\n",
873219d9a1aSLois Curfman McInnes            m,a->n,a->bs,fshift*bs2,a->nz*bs2);
8743d2013a6SLois Curfman McInnes   PLogInfo(A,"MatAssemblyEnd_SeqBAIJ:Number of mallocs during MatSetValues is %d\n",
875584200bdSSatish Balay            a->reallocs);
876d402145bSBarry Smith   PLogInfo(A,"MatAssemblyEnd_SeqBAIJ:Most nonzeros blocks in any row is %d\n",rmax);
877e2f3b5e9SSatish Balay   a->reallocs          = 0;
8780e6d2581SBarry Smith   A->info.nz_unneeded  = (PetscReal)fshift*bs2;
8794e220ebcSLois Curfman McInnes 
8803a40ed3dSBarry Smith   PetscFunctionReturn(0);
881584200bdSSatish Balay }
882584200bdSSatish Balay 
8835a838052SSatish Balay 
884bea157c4SSatish Balay 
885bea157c4SSatish Balay /*
886bea157c4SSatish Balay    This function returns an array of flags which indicate the locations of contiguous
887bea157c4SSatish Balay    blocks that should be zeroed. for eg: if bs = 3  and is = [0,1,2,3,5,6,7,8,9]
888bea157c4SSatish Balay    then the resulting sizes = [3,1,1,3,1] correspondig to sets [(0,1,2),(3),(5),(6,7,8),(9)]
889bea157c4SSatish Balay    Assume: sizes should be long enough to hold all the values.
890bea157c4SSatish Balay */
8915615d1e5SSatish Balay #undef __FUNC__
892*b2863d3aSBarry Smith #define  __FUNC__ /*<a name=""></a>*/"MatZeroRows_SeqBAIJ_Check_Blocks"
893bea157c4SSatish Balay static int MatZeroRows_SeqBAIJ_Check_Blocks(int idx[],int n,int bs,int sizes[], int *bs_max)
894d9b7c43dSSatish Balay {
895bea157c4SSatish Balay   int        i,j,k,row;
896bea157c4SSatish Balay   PetscTruth flg;
8973a40ed3dSBarry Smith 
898433994e6SBarry Smith   PetscFunctionBegin;
899bea157c4SSatish Balay   for (i=0,j=0; i<n; j++) {
900bea157c4SSatish Balay     row = idx[i];
901bea157c4SSatish Balay     if (row%bs!=0) { /* Not the begining of a block */
902bea157c4SSatish Balay       sizes[j] = 1;
903bea157c4SSatish Balay       i++;
904e4fda26cSSatish Balay     } else if (i+bs > n) { /* complete block doesn't exist (at idx end) */
905bea157c4SSatish Balay       sizes[j] = 1;         /* Also makes sure atleast 'bs' values exist for next else */
906bea157c4SSatish Balay       i++;
907bea157c4SSatish Balay     } else { /* Begining of the block, so check if the complete block exists */
908bea157c4SSatish Balay       flg = PETSC_TRUE;
909bea157c4SSatish Balay       for (k=1; k<bs; k++) {
910bea157c4SSatish Balay         if (row+k != idx[i+k]) { /* break in the block */
911bea157c4SSatish Balay           flg = PETSC_FALSE;
912bea157c4SSatish Balay           break;
913d9b7c43dSSatish Balay         }
914bea157c4SSatish Balay       }
915bea157c4SSatish Balay       if (flg == PETSC_TRUE) { /* No break in the bs */
916bea157c4SSatish Balay         sizes[j] = bs;
917bea157c4SSatish Balay         i+= bs;
918bea157c4SSatish Balay       } else {
919bea157c4SSatish Balay         sizes[j] = 1;
920bea157c4SSatish Balay         i++;
921bea157c4SSatish Balay       }
922bea157c4SSatish Balay     }
923bea157c4SSatish Balay   }
924bea157c4SSatish Balay   *bs_max = j;
9253a40ed3dSBarry Smith   PetscFunctionReturn(0);
926d9b7c43dSSatish Balay }
927d9b7c43dSSatish Balay 
9285615d1e5SSatish Balay #undef __FUNC__
929*b2863d3aSBarry Smith #define  __FUNC__ /*<a name=""></a>*/"MatZeroRows_SeqBAIJ"
9308f6be9afSLois Curfman McInnes int MatZeroRows_SeqBAIJ(Mat A,IS is,Scalar *diag)
931d9b7c43dSSatish Balay {
932d9b7c43dSSatish Balay   Mat_SeqBAIJ *baij=(Mat_SeqBAIJ*)A->data;
933b6815fffSBarry Smith   int         ierr,i,j,k,count,is_n,*is_idx,*rows;
934bea157c4SSatish Balay   int         bs=baij->bs,bs2=baij->bs2,*sizes,row,bs_max;
9353f1db9ecSBarry Smith   Scalar      zero = 0.0;
9363f1db9ecSBarry Smith   MatScalar   *aa;
937d9b7c43dSSatish Balay 
9383a40ed3dSBarry Smith   PetscFunctionBegin;
939d9b7c43dSSatish Balay   /* Make a copy of the IS and  sort it */
940d9b7c43dSSatish Balay   ierr = ISGetSize(is,&is_n);CHKERRQ(ierr);
941d9b7c43dSSatish Balay   ierr = ISGetIndices(is,&is_idx);CHKERRQ(ierr);
942d9b7c43dSSatish Balay 
943bea157c4SSatish Balay   /* allocate memory for rows,sizes */
944bea157c4SSatish Balay   rows  = (int*)PetscMalloc((3*is_n+1)*sizeof(int));CHKPTRQ(rows);
945bea157c4SSatish Balay   sizes = rows + is_n;
946bea157c4SSatish Balay 
947bea157c4SSatish Balay   /* initialize copy IS valurs to rows, and sort them */
948bea157c4SSatish Balay   for (i=0; i<is_n; i++) { rows[i] = is_idx[i]; }
949bea157c4SSatish Balay   ierr = PetscSortInt(is_n,rows);CHKERRQ(ierr);
950dffd3267SBarry Smith   if (baij->keepzeroedrows) {
951dffd3267SBarry Smith     for (i=0; i<is_n; i++) { sizes[i] = 1; }
952dffd3267SBarry Smith     bs_max = is_n;
953dffd3267SBarry Smith   } else {
954bea157c4SSatish Balay     ierr = MatZeroRows_SeqBAIJ_Check_Blocks(rows,is_n,bs,sizes,&bs_max);CHKERRQ(ierr);
955dffd3267SBarry Smith   }
956b97a56abSSatish Balay   ierr = ISRestoreIndices(is,&is_idx);CHKERRQ(ierr);
957bea157c4SSatish Balay 
958bea157c4SSatish Balay   for (i=0,j=0; i<bs_max; j+=sizes[i],i++) {
959bea157c4SSatish Balay     row   = rows[j];
960b6815fffSBarry Smith     if (row < 0 || row > baij->m) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,0,"row %d out of range",row);
961bea157c4SSatish Balay     count = (baij->i[row/bs +1] - baij->i[row/bs])*bs;
962bea157c4SSatish Balay     aa    = baij->a + baij->i[row/bs]*bs2 + (row%bs);
963dffd3267SBarry Smith     if (sizes[i] == bs && !baij->keepzeroedrows) {
964bea157c4SSatish Balay       if (diag) {
965bea157c4SSatish Balay         if (baij->ilen[row/bs] > 0) {
966bea157c4SSatish Balay           baij->ilen[row/bs] = 1;
967bea157c4SSatish Balay           baij->j[baij->i[row/bs]] = row/bs;
968bea157c4SSatish Balay           ierr = PetscMemzero(aa,count*bs*sizeof(MatScalar));CHKERRQ(ierr);
969a07cd24cSSatish Balay         }
970bea157c4SSatish Balay         /* Now insert all the diagoanl values for this bs */
971bea157c4SSatish Balay         for (k=0; k<bs; k++) {
972bea157c4SSatish Balay           ierr = (*A->ops->setvalues)(A,1,rows+j+k,1,rows+j+k,diag,INSERT_VALUES);CHKERRQ(ierr);
973bea157c4SSatish Balay         }
974bea157c4SSatish Balay       } else { /* (!diag) */
975bea157c4SSatish Balay         baij->ilen[row/bs] = 0;
976bea157c4SSatish Balay       } /* end (!diag) */
977bea157c4SSatish Balay     } else { /* (sizes[i] != bs) */
978aa482453SBarry Smith #if defined (PETSC_USE_DEBUG)
979bea157c4SSatish Balay       if (sizes[i] != 1) SETERRQ(1,0,"Internal Error. Value should be 1");
980bea157c4SSatish Balay #endif
981bea157c4SSatish Balay       for (k=0; k<count; k++) {
982d9b7c43dSSatish Balay         aa[0] = zero;
983d9b7c43dSSatish Balay         aa+=bs;
984d9b7c43dSSatish Balay       }
985d9b7c43dSSatish Balay       if (diag) {
986f830108cSBarry Smith         ierr = (*A->ops->setvalues)(A,1,rows+j,1,rows+j,diag,INSERT_VALUES);CHKERRQ(ierr);
987d9b7c43dSSatish Balay       }
988d9b7c43dSSatish Balay     }
989bea157c4SSatish Balay   }
990bea157c4SSatish Balay 
991606d414cSSatish Balay   ierr = PetscFree(rows);CHKERRQ(ierr);
9929a8dea36SBarry Smith   ierr = MatAssemblyEnd_SeqBAIJ(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
9933a40ed3dSBarry Smith   PetscFunctionReturn(0);
994d9b7c43dSSatish Balay }
9951c351548SSatish Balay 
9965615d1e5SSatish Balay #undef __FUNC__
997*b2863d3aSBarry Smith #define  __FUNC__ /*<a name=""></a>*/"MatSetValues_SeqBAIJ"
9982d61bbb3SSatish Balay int MatSetValues_SeqBAIJ(Mat A,int m,int *im,int n,int *in,Scalar *v,InsertMode is)
9992d61bbb3SSatish Balay {
10002d61bbb3SSatish Balay   Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)A->data;
10012d61bbb3SSatish Balay   int         *rp,k,low,high,t,ii,row,nrow,i,col,l,rmax,N,sorted=a->sorted;
10022d61bbb3SSatish Balay   int         *imax=a->imax,*ai=a->i,*ailen=a->ilen,roworiented=a->roworiented;
10032d61bbb3SSatish Balay   int         *aj=a->j,nonew=a->nonew,bs=a->bs,brow,bcol;
1004549d3d68SSatish Balay   int         ridx,cidx,bs2=a->bs2,ierr;
10053f1db9ecSBarry Smith   MatScalar   *ap,value,*aa=a->a,*bap;
10062d61bbb3SSatish Balay 
10072d61bbb3SSatish Balay   PetscFunctionBegin;
10082d61bbb3SSatish Balay   for (k=0; k<m; k++) { /* loop over added rows */
10092d61bbb3SSatish Balay     row  = im[k]; brow = row/bs;
10105ef9f2a5SBarry Smith     if (row < 0) continue;
1011aa482453SBarry Smith #if defined(PETSC_USE_BOPT_g)
101232e87ba3SBarry Smith     if (row >= a->m) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,0,"Row too large: row %d max %d",row,a->m);
10132d61bbb3SSatish Balay #endif
10142d61bbb3SSatish Balay     rp   = aj + ai[brow];
10152d61bbb3SSatish Balay     ap   = aa + bs2*ai[brow];
10162d61bbb3SSatish Balay     rmax = imax[brow];
10172d61bbb3SSatish Balay     nrow = ailen[brow];
10182d61bbb3SSatish Balay     low  = 0;
10192d61bbb3SSatish Balay     for (l=0; l<n; l++) { /* loop over added columns */
10205ef9f2a5SBarry Smith       if (in[l] < 0) continue;
1021aa482453SBarry Smith #if defined(PETSC_USE_BOPT_g)
102232e87ba3SBarry Smith       if (in[l] >= a->n) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,0,"Column too large: col %d max %d",in[l],a->n);
10232d61bbb3SSatish Balay #endif
10242d61bbb3SSatish Balay       col = in[l]; bcol = col/bs;
10252d61bbb3SSatish Balay       ridx = row % bs; cidx = col % bs;
10262d61bbb3SSatish Balay       if (roworiented) {
10275ef9f2a5SBarry Smith         value = v[l + k*n];
10282d61bbb3SSatish Balay       } else {
10292d61bbb3SSatish Balay         value = v[k + l*m];
10302d61bbb3SSatish Balay       }
10312d61bbb3SSatish Balay       if (!sorted) low = 0; high = nrow;
10322d61bbb3SSatish Balay       while (high-low > 7) {
10332d61bbb3SSatish Balay         t = (low+high)/2;
10342d61bbb3SSatish Balay         if (rp[t] > bcol) high = t;
10352d61bbb3SSatish Balay         else              low  = t;
10362d61bbb3SSatish Balay       }
10372d61bbb3SSatish Balay       for (i=low; i<high; i++) {
10382d61bbb3SSatish Balay         if (rp[i] > bcol) break;
10392d61bbb3SSatish Balay         if (rp[i] == bcol) {
10402d61bbb3SSatish Balay           bap  = ap +  bs2*i + bs*cidx + ridx;
10412d61bbb3SSatish Balay           if (is == ADD_VALUES) *bap += value;
10422d61bbb3SSatish Balay           else                  *bap  = value;
10432d61bbb3SSatish Balay           goto noinsert1;
10442d61bbb3SSatish Balay         }
10452d61bbb3SSatish Balay       }
10462d61bbb3SSatish Balay       if (nonew == 1) goto noinsert1;
10472d61bbb3SSatish Balay       else if (nonew == -1) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Inserting a new nonzero in the matrix");
10482d61bbb3SSatish Balay       if (nrow >= rmax) {
10492d61bbb3SSatish Balay         /* there is no extra room in row, therefore enlarge */
10502d61bbb3SSatish Balay         int       new_nz = ai[a->mbs] + CHUNKSIZE,len,*new_i,*new_j;
10513f1db9ecSBarry Smith         MatScalar *new_a;
10522d61bbb3SSatish Balay 
10532d61bbb3SSatish Balay         if (nonew == -2) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Inserting a new nonzero in the matrix");
10542d61bbb3SSatish Balay 
10552d61bbb3SSatish Balay         /* Malloc new storage space */
10563f1db9ecSBarry Smith         len     = new_nz*(sizeof(int)+bs2*sizeof(MatScalar))+(a->mbs+1)*sizeof(int);
10573f1db9ecSBarry Smith         new_a   = (MatScalar*)PetscMalloc(len);CHKPTRQ(new_a);
10582d61bbb3SSatish Balay         new_j   = (int*)(new_a + bs2*new_nz);
10592d61bbb3SSatish Balay         new_i   = new_j + new_nz;
10602d61bbb3SSatish Balay 
10612d61bbb3SSatish Balay         /* copy over old data into new slots */
10622d61bbb3SSatish Balay         for (ii=0; ii<brow+1; ii++) {new_i[ii] = ai[ii];}
10632d61bbb3SSatish Balay         for (ii=brow+1; ii<a->mbs+1; ii++) {new_i[ii] = ai[ii]+CHUNKSIZE;}
1064549d3d68SSatish Balay         ierr = PetscMemcpy(new_j,aj,(ai[brow]+nrow)*sizeof(int));CHKERRQ(ierr);
10652d61bbb3SSatish Balay         len  = (new_nz - CHUNKSIZE - ai[brow] - nrow);
1066549d3d68SSatish Balay         ierr = PetscMemcpy(new_j+ai[brow]+nrow+CHUNKSIZE,aj+ai[brow]+nrow,len*sizeof(int));CHKERRQ(ierr);
1067549d3d68SSatish Balay         ierr = PetscMemcpy(new_a,aa,(ai[brow]+nrow)*bs2*sizeof(MatScalar));CHKERRQ(ierr);
1068549d3d68SSatish Balay         ierr = PetscMemzero(new_a+bs2*(ai[brow]+nrow),bs2*CHUNKSIZE*sizeof(MatScalar));CHKERRQ(ierr);
1069549d3d68SSatish Balay         ierr = PetscMemcpy(new_a+bs2*(ai[brow]+nrow+CHUNKSIZE),aa+bs2*(ai[brow]+nrow),bs2*len*sizeof(MatScalar));CHKERRQ(ierr);
10702d61bbb3SSatish Balay         /* free up old matrix storage */
1071606d414cSSatish Balay         ierr = PetscFree(a->a);CHKERRQ(ierr);
1072606d414cSSatish Balay         if (!a->singlemalloc) {
1073606d414cSSatish Balay           ierr = PetscFree(a->i);CHKERRQ(ierr);
1074606d414cSSatish Balay           ierr = PetscFree(a->j);CHKERRQ(ierr);
1075606d414cSSatish Balay         }
10762d61bbb3SSatish Balay         aa = a->a = new_a; ai = a->i = new_i; aj = a->j = new_j;
1077c4992f7dSBarry Smith         a->singlemalloc = PETSC_TRUE;
10782d61bbb3SSatish Balay 
10792d61bbb3SSatish Balay         rp   = aj + ai[brow]; ap = aa + bs2*ai[brow];
10802d61bbb3SSatish Balay         rmax = imax[brow] = imax[brow] + CHUNKSIZE;
10813f1db9ecSBarry Smith         PLogObjectMemory(A,CHUNKSIZE*(sizeof(int) + bs2*sizeof(MatScalar)));
10822d61bbb3SSatish Balay         a->maxnz += bs2*CHUNKSIZE;
10832d61bbb3SSatish Balay         a->reallocs++;
10842d61bbb3SSatish Balay         a->nz++;
10852d61bbb3SSatish Balay       }
10862d61bbb3SSatish Balay       N = nrow++ - 1;
10872d61bbb3SSatish Balay       /* shift up all the later entries in this row */
10882d61bbb3SSatish Balay       for (ii=N; ii>=i; ii--) {
10892d61bbb3SSatish Balay         rp[ii+1] = rp[ii];
1090549d3d68SSatish Balay         ierr     = PetscMemcpy(ap+bs2*(ii+1),ap+bs2*(ii),bs2*sizeof(MatScalar));CHKERRQ(ierr);
10912d61bbb3SSatish Balay       }
1092549d3d68SSatish Balay       if (N>=i) {
1093549d3d68SSatish Balay         ierr = PetscMemzero(ap+bs2*i,bs2*sizeof(MatScalar));CHKERRQ(ierr);
1094549d3d68SSatish Balay       }
10952d61bbb3SSatish Balay       rp[i]                      = bcol;
10962d61bbb3SSatish Balay       ap[bs2*i + bs*cidx + ridx] = value;
10972d61bbb3SSatish Balay       noinsert1:;
10982d61bbb3SSatish Balay       low = i;
10992d61bbb3SSatish Balay     }
11002d61bbb3SSatish Balay     ailen[brow] = nrow;
11012d61bbb3SSatish Balay   }
11022d61bbb3SSatish Balay   PetscFunctionReturn(0);
11032d61bbb3SSatish Balay }
11042d61bbb3SSatish Balay 
11050e6d2581SBarry Smith extern int MatLUFactorSymbolic_SeqBAIJ(Mat,IS,IS,PetscReal,Mat*);
11060e6d2581SBarry Smith extern int MatLUFactor_SeqBAIJ(Mat,IS,IS,PetscReal);
11072d61bbb3SSatish Balay extern int MatIncreaseOverlap_SeqBAIJ(Mat,int,IS*,int);
11087b2a1423SBarry Smith extern int MatGetSubMatrix_SeqBAIJ(Mat,IS,IS,int,MatReuse,Mat*);
11097b2a1423SBarry Smith extern int MatGetSubMatrices_SeqBAIJ(Mat,int,IS*,IS*,MatReuse,Mat**);
11107c922b88SBarry Smith extern int MatMultTranspose_SeqBAIJ(Mat,Vec,Vec);
11117c922b88SBarry Smith extern int MatMultTransposeAdd_SeqBAIJ(Mat,Vec,Vec,Vec);
11122d61bbb3SSatish Balay extern int MatScale_SeqBAIJ(Scalar*,Mat);
11130e6d2581SBarry Smith extern int MatNorm_SeqBAIJ(Mat,NormType,PetscReal *);
11142d61bbb3SSatish Balay extern int MatEqual_SeqBAIJ(Mat,Mat,PetscTruth*);
11152d61bbb3SSatish Balay extern int MatGetDiagonal_SeqBAIJ(Mat,Vec);
11162d61bbb3SSatish Balay extern int MatDiagonalScale_SeqBAIJ(Mat,Vec,Vec);
11172d61bbb3SSatish Balay extern int MatGetInfo_SeqBAIJ(Mat,MatInfoType,MatInfo *);
11182d61bbb3SSatish Balay extern int MatZeroEntries_SeqBAIJ(Mat);
11192d61bbb3SSatish Balay 
11202d61bbb3SSatish Balay extern int MatSolve_SeqBAIJ_N(Mat,Vec,Vec);
11212d61bbb3SSatish Balay extern int MatSolve_SeqBAIJ_1(Mat,Vec,Vec);
11222d61bbb3SSatish Balay extern int MatSolve_SeqBAIJ_2(Mat,Vec,Vec);
11232d61bbb3SSatish Balay extern int MatSolve_SeqBAIJ_3(Mat,Vec,Vec);
11242d61bbb3SSatish Balay extern int MatSolve_SeqBAIJ_4(Mat,Vec,Vec);
11252d61bbb3SSatish Balay extern int MatSolve_SeqBAIJ_5(Mat,Vec,Vec);
112615091d37SBarry Smith extern int MatSolve_SeqBAIJ_6(Mat,Vec,Vec);
11272d61bbb3SSatish Balay extern int MatSolve_SeqBAIJ_7(Mat,Vec,Vec);
11287c922b88SBarry Smith extern int MatSolveTranspose_SeqBAIJ_7(Mat,Vec,Vec);
11297c922b88SBarry Smith extern int MatSolveTranspose_SeqBAIJ_6(Mat,Vec,Vec);
11307c922b88SBarry Smith extern int MatSolveTranspose_SeqBAIJ_5(Mat,Vec,Vec);
11317c922b88SBarry Smith extern int MatSolveTranspose_SeqBAIJ_4(Mat,Vec,Vec);
11327c922b88SBarry Smith extern int MatSolveTranspose_SeqBAIJ_3(Mat,Vec,Vec);
11337c922b88SBarry Smith extern int MatSolveTranspose_SeqBAIJ_2(Mat,Vec,Vec);
11347c922b88SBarry Smith extern int MatSolveTranspose_SeqBAIJ_1(Mat,Vec,Vec);
11352d61bbb3SSatish Balay 
11362d61bbb3SSatish Balay extern int MatLUFactorNumeric_SeqBAIJ_N(Mat,Mat*);
11372d61bbb3SSatish Balay extern int MatLUFactorNumeric_SeqBAIJ_1(Mat,Mat*);
11382d61bbb3SSatish Balay extern int MatLUFactorNumeric_SeqBAIJ_2(Mat,Mat*);
11392d61bbb3SSatish Balay extern int MatLUFactorNumeric_SeqBAIJ_3(Mat,Mat*);
11402d61bbb3SSatish Balay extern int MatLUFactorNumeric_SeqBAIJ_4(Mat,Mat*);
11412d61bbb3SSatish Balay extern int MatLUFactorNumeric_SeqBAIJ_5(Mat,Mat*);
114215091d37SBarry Smith extern int MatLUFactorNumeric_SeqBAIJ_6(Mat,Mat*);
11432d61bbb3SSatish Balay 
11442d61bbb3SSatish Balay extern int MatMult_SeqBAIJ_1(Mat,Vec,Vec);
11452d61bbb3SSatish Balay extern int MatMult_SeqBAIJ_2(Mat,Vec,Vec);
11462d61bbb3SSatish Balay extern int MatMult_SeqBAIJ_3(Mat,Vec,Vec);
11472d61bbb3SSatish Balay extern int MatMult_SeqBAIJ_4(Mat,Vec,Vec);
11482d61bbb3SSatish Balay extern int MatMult_SeqBAIJ_5(Mat,Vec,Vec);
114915091d37SBarry Smith extern int MatMult_SeqBAIJ_6(Mat,Vec,Vec);
11502d61bbb3SSatish Balay extern int MatMult_SeqBAIJ_7(Mat,Vec,Vec);
11512d61bbb3SSatish Balay extern int MatMult_SeqBAIJ_N(Mat,Vec,Vec);
11522d61bbb3SSatish Balay 
11532d61bbb3SSatish Balay extern int MatMultAdd_SeqBAIJ_1(Mat,Vec,Vec,Vec);
11542d61bbb3SSatish Balay extern int MatMultAdd_SeqBAIJ_2(Mat,Vec,Vec,Vec);
11552d61bbb3SSatish Balay extern int MatMultAdd_SeqBAIJ_3(Mat,Vec,Vec,Vec);
11562d61bbb3SSatish Balay extern int MatMultAdd_SeqBAIJ_4(Mat,Vec,Vec,Vec);
11572d61bbb3SSatish Balay extern int MatMultAdd_SeqBAIJ_5(Mat,Vec,Vec,Vec);
115815091d37SBarry Smith extern int MatMultAdd_SeqBAIJ_6(Mat,Vec,Vec,Vec);
11592d61bbb3SSatish Balay extern int MatMultAdd_SeqBAIJ_7(Mat,Vec,Vec,Vec);
11602d61bbb3SSatish Balay extern int MatMultAdd_SeqBAIJ_N(Mat,Vec,Vec,Vec);
11612d61bbb3SSatish Balay 
11622d61bbb3SSatish Balay #undef __FUNC__
1163*b2863d3aSBarry Smith #define  __FUNC__ /*<a name=""></a>*/"MatILUFactor_SeqBAIJ"
11645ef9f2a5SBarry Smith int MatILUFactor_SeqBAIJ(Mat inA,IS row,IS col,MatILUInfo *info)
11652d61bbb3SSatish Balay {
11662d61bbb3SSatish Balay   Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)inA->data;
11672d61bbb3SSatish Balay   Mat         outA;
11682d61bbb3SSatish Balay   int         ierr;
1169667159a5SBarry Smith   PetscTruth  row_identity,col_identity;
11702d61bbb3SSatish Balay 
11712d61bbb3SSatish Balay   PetscFunctionBegin;
1172b6d21a55SBarry Smith   if (info && info->levels != 0) SETERRQ(PETSC_ERR_SUP,0,"Only levels = 0 supported for in-place ILU");
1173667159a5SBarry Smith   ierr = ISIdentity(row,&row_identity);CHKERRQ(ierr);
1174667159a5SBarry Smith   ierr = ISIdentity(col,&col_identity);CHKERRQ(ierr);
1175667159a5SBarry Smith   if (!row_identity || !col_identity) {
1176b008c796SBarry Smith     SETERRQ(1,1,"Row and column permutations must be identity for in-place ILU");
1177667159a5SBarry Smith   }
11782d61bbb3SSatish Balay 
11792d61bbb3SSatish Balay   outA          = inA;
11802d61bbb3SSatish Balay   inA->factor   = FACTOR_LU;
11812d61bbb3SSatish Balay 
11822d61bbb3SSatish Balay   if (!a->diag) {
1183c4992f7dSBarry Smith     ierr = MatMarkDiagonal_SeqBAIJ(inA);CHKERRQ(ierr);
11842d61bbb3SSatish Balay   }
11852d61bbb3SSatish Balay   /*
118615091d37SBarry Smith       Blocksize 2, 3, 4, 5, 6 and 7 have a special faster factorization/solver
118715091d37SBarry Smith       for ILU(0) factorization with natural ordering
11882d61bbb3SSatish Balay   */
118915091d37SBarry Smith   switch (a->bs) {
1190f1af5d2fSBarry Smith   case 1:
11917c922b88SBarry Smith     inA->ops->solvetranspose   = MatSolveTranspose_SeqBAIJ_2_NaturalOrdering;
1192f1af5d2fSBarry Smith     PLogInfo(inA,"MatILUFactor_SeqBAIJ:Using special in-place natural ordering solvetrans BS=1\n");
119315091d37SBarry Smith   case 2:
119415091d37SBarry Smith     inA->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_2_NaturalOrdering;
119515091d37SBarry Smith     inA->ops->solve           = MatSolve_SeqBAIJ_2_NaturalOrdering;
11967c922b88SBarry Smith     inA->ops->solvetranspose  = MatSolveTranspose_SeqBAIJ_2_NaturalOrdering;
119715091d37SBarry Smith     PLogInfo(inA,"MatILUFactor_SeqBAIJ:Using special in-place natural ordering factor and solve BS=2\n");
119815091d37SBarry Smith     break;
119915091d37SBarry Smith   case 3:
120015091d37SBarry Smith     inA->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_3_NaturalOrdering;
120115091d37SBarry Smith     inA->ops->solve           = MatSolve_SeqBAIJ_3_NaturalOrdering;
12027c922b88SBarry Smith     inA->ops->solvetranspose  = MatSolveTranspose_SeqBAIJ_3_NaturalOrdering;
120315091d37SBarry Smith     PLogInfo(inA,"MatILUFactor_SeqBAIJ:Using special in-place natural ordering factor and solve BS=3\n");
120415091d37SBarry Smith     break;
120515091d37SBarry Smith   case 4:
1206667159a5SBarry Smith     inA->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_4_NaturalOrdering;
1207f830108cSBarry Smith     inA->ops->solve           = MatSolve_SeqBAIJ_4_NaturalOrdering;
12087c922b88SBarry Smith     inA->ops->solvetranspose  = MatSolveTranspose_SeqBAIJ_4_NaturalOrdering;
120915091d37SBarry Smith     PLogInfo(inA,"MatILUFactor_SeqBAIJ:Using special in-place natural ordering factor and solve BS=4\n");
121015091d37SBarry Smith     break;
121115091d37SBarry Smith   case 5:
1212667159a5SBarry Smith     inA->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_5_NaturalOrdering;
1213667159a5SBarry Smith     inA->ops->solve           = MatSolve_SeqBAIJ_5_NaturalOrdering;
12147c922b88SBarry Smith     inA->ops->solvetranspose  = MatSolveTranspose_SeqBAIJ_5_NaturalOrdering;
121515091d37SBarry Smith     PLogInfo(inA,"MatILUFactor_SeqBAIJ:Using special in-place natural ordering factor and solve BS=5\n");
121615091d37SBarry Smith     break;
121715091d37SBarry Smith   case 6:
121815091d37SBarry Smith     inA->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_6_NaturalOrdering;
121915091d37SBarry Smith     inA->ops->solve           = MatSolve_SeqBAIJ_6_NaturalOrdering;
12207c922b88SBarry Smith     inA->ops->solvetranspose  = MatSolveTranspose_SeqBAIJ_6_NaturalOrdering;
122115091d37SBarry Smith     PLogInfo(inA,"MatILUFactor_SeqBAIJ:Using special in-place natural ordering factor and solve BS=6\n");
122215091d37SBarry Smith     break;
122315091d37SBarry Smith   case 7:
122415091d37SBarry Smith     inA->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_7_NaturalOrdering;
12257c922b88SBarry Smith     inA->ops->solvetranspose  = MatSolveTranspose_SeqBAIJ_7_NaturalOrdering;
122615091d37SBarry Smith     inA->ops->solve           = MatSolve_SeqBAIJ_7_NaturalOrdering;
122715091d37SBarry Smith     PLogInfo(inA,"MatILUFactor_SeqBAIJ:Using special in-place natural ordering factor and solve BS=7\n");
122815091d37SBarry Smith     break;
1229c38d4ed2SBarry Smith   default:
1230c38d4ed2SBarry Smith     a->row        = row;
1231c38d4ed2SBarry Smith     a->col        = col;
1232c38d4ed2SBarry Smith     ierr          = PetscObjectReference((PetscObject)row);CHKERRQ(ierr);
1233c38d4ed2SBarry Smith     ierr          = PetscObjectReference((PetscObject)col);CHKERRQ(ierr);
1234c38d4ed2SBarry Smith 
1235c38d4ed2SBarry Smith     /* Create the invert permutation so that it can be used in MatLUFactorNumeric() */
12364c49b128SBarry Smith     ierr = ISInvertPermutation(col,PETSC_DECIDE,&a->icol);CHKERRQ(ierr);
1237c38d4ed2SBarry Smith     PLogObjectParent(inA,a->icol);
1238c38d4ed2SBarry Smith 
1239c38d4ed2SBarry Smith     if (!a->solve_work) {
1240c38d4ed2SBarry Smith       a->solve_work = (Scalar*)PetscMalloc((a->m+a->bs)*sizeof(Scalar));CHKPTRQ(a->solve_work);
1241c38d4ed2SBarry Smith       PLogObjectMemory(inA,(a->m+a->bs)*sizeof(Scalar));
1242c38d4ed2SBarry Smith     }
12432d61bbb3SSatish Balay   }
12442d61bbb3SSatish Balay 
1245667159a5SBarry Smith   ierr = MatLUFactorNumeric(inA,&outA);CHKERRQ(ierr);
1246667159a5SBarry Smith 
12472d61bbb3SSatish Balay   PetscFunctionReturn(0);
12482d61bbb3SSatish Balay }
12492d61bbb3SSatish Balay #undef __FUNC__
1250*b2863d3aSBarry Smith #define  __FUNC__ /*<a name=""></a>*/"MatPrintHelp_SeqBAIJ"
1251ba4ca20aSSatish Balay int MatPrintHelp_SeqBAIJ(Mat A)
1252ba4ca20aSSatish Balay {
1253c38d4ed2SBarry Smith   static PetscTruth called = PETSC_FALSE;
1254ba4ca20aSSatish Balay   MPI_Comm          comm = A->comm;
1255d132466eSBarry Smith   int               ierr;
1256ba4ca20aSSatish Balay 
12573a40ed3dSBarry Smith   PetscFunctionBegin;
1258c38d4ed2SBarry Smith   if (called) {PetscFunctionReturn(0);} else called = PETSC_TRUE;
1259d132466eSBarry Smith   ierr = (*PetscHelpPrintf)(comm," Options for MATSEQBAIJ and MATMPIBAIJ matrix formats (the defaults):\n");CHKERRQ(ierr);
1260d132466eSBarry Smith   ierr = (*PetscHelpPrintf)(comm,"  -mat_block_size <block_size>\n");CHKERRQ(ierr);
12613a40ed3dSBarry Smith   PetscFunctionReturn(0);
1262ba4ca20aSSatish Balay }
1263d9b7c43dSSatish Balay 
1264fb2e594dSBarry Smith EXTERN_C_BEGIN
126527a8da17SBarry Smith #undef __FUNC__
1266*b2863d3aSBarry Smith #define  __FUNC__ /*<a name=""></a>*/"MatSeqBAIJSetColumnIndices_SeqBAIJ"
126727a8da17SBarry Smith int MatSeqBAIJSetColumnIndices_SeqBAIJ(Mat mat,int *indices)
126827a8da17SBarry Smith {
126927a8da17SBarry Smith   Mat_SeqBAIJ *baij = (Mat_SeqBAIJ *)mat->data;
127027a8da17SBarry Smith   int         i,nz,n;
127127a8da17SBarry Smith 
127227a8da17SBarry Smith   PetscFunctionBegin;
127327a8da17SBarry Smith   nz = baij->maxnz;
127427a8da17SBarry Smith   n  = baij->n;
127527a8da17SBarry Smith   for (i=0; i<nz; i++) {
127627a8da17SBarry Smith     baij->j[i] = indices[i];
127727a8da17SBarry Smith   }
127827a8da17SBarry Smith   baij->nz = nz;
127927a8da17SBarry Smith   for (i=0; i<n; i++) {
128027a8da17SBarry Smith     baij->ilen[i] = baij->imax[i];
128127a8da17SBarry Smith   }
128227a8da17SBarry Smith 
128327a8da17SBarry Smith   PetscFunctionReturn(0);
128427a8da17SBarry Smith }
1285fb2e594dSBarry Smith EXTERN_C_END
128627a8da17SBarry Smith 
128727a8da17SBarry Smith #undef __FUNC__
1288*b2863d3aSBarry Smith #define  __FUNC__ /*<a name=""></a>*/"MatSeqBAIJSetColumnIndices"
128927a8da17SBarry Smith /*@
129027a8da17SBarry Smith     MatSeqBAIJSetColumnIndices - Set the column indices for all the rows
129127a8da17SBarry Smith        in the matrix.
129227a8da17SBarry Smith 
129327a8da17SBarry Smith   Input Parameters:
129427a8da17SBarry Smith +  mat - the SeqBAIJ matrix
129527a8da17SBarry Smith -  indices - the column indices
129627a8da17SBarry Smith 
129715091d37SBarry Smith   Level: advanced
129815091d37SBarry Smith 
129927a8da17SBarry Smith   Notes:
130027a8da17SBarry Smith     This can be called if you have precomputed the nonzero structure of the
130127a8da17SBarry Smith   matrix and want to provide it to the matrix object to improve the performance
130227a8da17SBarry Smith   of the MatSetValues() operation.
130327a8da17SBarry Smith 
130427a8da17SBarry Smith     You MUST have set the correct numbers of nonzeros per row in the call to
130527a8da17SBarry Smith   MatCreateSeqBAIJ().
130627a8da17SBarry Smith 
130727a8da17SBarry Smith     MUST be called before any calls to MatSetValues();
130827a8da17SBarry Smith 
130927a8da17SBarry Smith @*/
131027a8da17SBarry Smith int MatSeqBAIJSetColumnIndices(Mat mat,int *indices)
131127a8da17SBarry Smith {
131227a8da17SBarry Smith   int ierr,(*f)(Mat,int *);
131327a8da17SBarry Smith 
131427a8da17SBarry Smith   PetscFunctionBegin;
131527a8da17SBarry Smith   PetscValidHeaderSpecific(mat,MAT_COOKIE);
1316549d3d68SSatish Balay   ierr = PetscObjectQueryFunction((PetscObject)mat,"MatSeqBAIJSetColumnIndices_C",(void **)&f);CHKERRQ(ierr);
131727a8da17SBarry Smith   if (f) {
131827a8da17SBarry Smith     ierr = (*f)(mat,indices);CHKERRQ(ierr);
131927a8da17SBarry Smith   } else {
132027a8da17SBarry Smith     SETERRQ(1,1,"Wrong type of matrix to set column indices");
132127a8da17SBarry Smith   }
132227a8da17SBarry Smith   PetscFunctionReturn(0);
132327a8da17SBarry Smith }
132427a8da17SBarry Smith 
13252593348eSBarry Smith /* -------------------------------------------------------------------*/
1326cc2dc46cSBarry Smith static struct _MatOps MatOps_Values = {MatSetValues_SeqBAIJ,
1327cc2dc46cSBarry Smith        MatGetRow_SeqBAIJ,
1328cc2dc46cSBarry Smith        MatRestoreRow_SeqBAIJ,
1329cc2dc46cSBarry Smith        MatMult_SeqBAIJ_N,
1330cc2dc46cSBarry Smith        MatMultAdd_SeqBAIJ_N,
13317c922b88SBarry Smith        MatMultTranspose_SeqBAIJ,
13327c922b88SBarry Smith        MatMultTransposeAdd_SeqBAIJ,
1333cc2dc46cSBarry Smith        MatSolve_SeqBAIJ_N,
1334cc2dc46cSBarry Smith        0,
1335cc2dc46cSBarry Smith        0,
1336cc2dc46cSBarry Smith        0,
1337cc2dc46cSBarry Smith        MatLUFactor_SeqBAIJ,
1338cc2dc46cSBarry Smith        0,
1339b6490206SBarry Smith        0,
1340f2501298SSatish Balay        MatTranspose_SeqBAIJ,
1341cc2dc46cSBarry Smith        MatGetInfo_SeqBAIJ,
1342cc2dc46cSBarry Smith        MatEqual_SeqBAIJ,
1343cc2dc46cSBarry Smith        MatGetDiagonal_SeqBAIJ,
1344cc2dc46cSBarry Smith        MatDiagonalScale_SeqBAIJ,
1345cc2dc46cSBarry Smith        MatNorm_SeqBAIJ,
1346b6490206SBarry Smith        0,
1347cc2dc46cSBarry Smith        MatAssemblyEnd_SeqBAIJ,
1348cc2dc46cSBarry Smith        0,
1349cc2dc46cSBarry Smith        MatSetOption_SeqBAIJ,
1350cc2dc46cSBarry Smith        MatZeroEntries_SeqBAIJ,
1351cc2dc46cSBarry Smith        MatZeroRows_SeqBAIJ,
1352cc2dc46cSBarry Smith        MatLUFactorSymbolic_SeqBAIJ,
1353cc2dc46cSBarry Smith        MatLUFactorNumeric_SeqBAIJ_N,
1354cc2dc46cSBarry Smith        0,
1355cc2dc46cSBarry Smith        0,
1356cc2dc46cSBarry Smith        MatGetSize_SeqBAIJ,
1357cc2dc46cSBarry Smith        MatGetSize_SeqBAIJ,
1358cc2dc46cSBarry Smith        MatGetOwnershipRange_SeqBAIJ,
1359cc2dc46cSBarry Smith        MatILUFactorSymbolic_SeqBAIJ,
1360cc2dc46cSBarry Smith        0,
1361cc2dc46cSBarry Smith        0,
1362cc2dc46cSBarry Smith        0,
13632e8a6d31SBarry Smith        MatDuplicate_SeqBAIJ,
1364cc2dc46cSBarry Smith        0,
1365cc2dc46cSBarry Smith        0,
1366cc2dc46cSBarry Smith        MatILUFactor_SeqBAIJ,
1367cc2dc46cSBarry Smith        0,
1368cc2dc46cSBarry Smith        0,
1369cc2dc46cSBarry Smith        MatGetSubMatrices_SeqBAIJ,
1370cc2dc46cSBarry Smith        MatIncreaseOverlap_SeqBAIJ,
1371cc2dc46cSBarry Smith        MatGetValues_SeqBAIJ,
1372cc2dc46cSBarry Smith        0,
1373cc2dc46cSBarry Smith        MatPrintHelp_SeqBAIJ,
1374cc2dc46cSBarry Smith        MatScale_SeqBAIJ,
1375cc2dc46cSBarry Smith        0,
1376cc2dc46cSBarry Smith        0,
1377cc2dc46cSBarry Smith        0,
1378cc2dc46cSBarry Smith        MatGetBlockSize_SeqBAIJ,
13793b2fbd54SBarry Smith        MatGetRowIJ_SeqBAIJ,
138092c4ed94SBarry Smith        MatRestoreRowIJ_SeqBAIJ,
1381cc2dc46cSBarry Smith        0,
1382cc2dc46cSBarry Smith        0,
1383cc2dc46cSBarry Smith        0,
1384cc2dc46cSBarry Smith        0,
1385cc2dc46cSBarry Smith        0,
1386cc2dc46cSBarry Smith        0,
1387d3825aa8SBarry Smith        MatSetValuesBlocked_SeqBAIJ,
1388cc2dc46cSBarry Smith        MatGetSubMatrix_SeqBAIJ,
1389cc2dc46cSBarry Smith        0,
1390cc2dc46cSBarry Smith        0,
1391cc2dc46cSBarry Smith        MatGetMaps_Petsc};
13922593348eSBarry Smith 
13933e90b805SBarry Smith EXTERN_C_BEGIN
13943e90b805SBarry Smith #undef __FUNC__
1395*b2863d3aSBarry Smith #define  __FUNC__ /*<a name=""></a>*/"MatStoreValues_SeqBAIJ"
13963e90b805SBarry Smith int MatStoreValues_SeqBAIJ(Mat mat)
13973e90b805SBarry Smith {
13983e90b805SBarry Smith   Mat_SeqBAIJ *aij = (Mat_SeqBAIJ *)mat->data;
13993e90b805SBarry Smith   int         nz = aij->i[aij->m]*aij->bs*aij->bs2;
1400d132466eSBarry Smith   int         ierr;
14013e90b805SBarry Smith 
14023e90b805SBarry Smith   PetscFunctionBegin;
14033e90b805SBarry Smith   if (aij->nonew != 1) {
14043e90b805SBarry Smith     SETERRQ(1,1,"Must call MatSetOption(A,MAT_NO_NEW_NONZERO_LOCATIONS);first");
14053e90b805SBarry Smith   }
14063e90b805SBarry Smith 
14073e90b805SBarry Smith   /* allocate space for values if not already there */
14083e90b805SBarry Smith   if (!aij->saved_values) {
14093e90b805SBarry Smith     aij->saved_values = (Scalar*)PetscMalloc(nz*sizeof(Scalar));CHKPTRQ(aij->saved_values);
14103e90b805SBarry Smith   }
14113e90b805SBarry Smith 
14123e90b805SBarry Smith   /* copy values over */
1413d132466eSBarry Smith   ierr = PetscMemcpy(aij->saved_values,aij->a,nz*sizeof(Scalar));CHKERRQ(ierr);
14143e90b805SBarry Smith   PetscFunctionReturn(0);
14153e90b805SBarry Smith }
14163e90b805SBarry Smith EXTERN_C_END
14173e90b805SBarry Smith 
14183e90b805SBarry Smith EXTERN_C_BEGIN
14193e90b805SBarry Smith #undef __FUNC__
1420*b2863d3aSBarry Smith #define  __FUNC__ /*<a name=""></a>*/"MatRetrieveValues_SeqBAIJ"
142132e87ba3SBarry Smith int MatRetrieveValues_SeqBAIJ(Mat mat)
14223e90b805SBarry Smith {
14233e90b805SBarry Smith   Mat_SeqBAIJ *aij = (Mat_SeqBAIJ *)mat->data;
1424549d3d68SSatish Balay   int         nz = aij->i[aij->m]*aij->bs*aij->bs2,ierr;
14253e90b805SBarry Smith 
14263e90b805SBarry Smith   PetscFunctionBegin;
14273e90b805SBarry Smith   if (aij->nonew != 1) {
14283e90b805SBarry Smith     SETERRQ(1,1,"Must call MatSetOption(A,MAT_NO_NEW_NONZERO_LOCATIONS);first");
14293e90b805SBarry Smith   }
14303e90b805SBarry Smith   if (!aij->saved_values) {
14313e90b805SBarry Smith     SETERRQ(1,1,"Must call MatStoreValues(A);first");
14323e90b805SBarry Smith   }
14333e90b805SBarry Smith 
14343e90b805SBarry Smith   /* copy values over */
1435549d3d68SSatish Balay   ierr = PetscMemcpy(aij->a,aij->saved_values,nz*sizeof(Scalar));CHKERRQ(ierr);
14363e90b805SBarry Smith   PetscFunctionReturn(0);
14373e90b805SBarry Smith }
14383e90b805SBarry Smith EXTERN_C_END
14393e90b805SBarry Smith 
14405615d1e5SSatish Balay #undef __FUNC__
1441*b2863d3aSBarry Smith #define  __FUNC__ /*<a name=""></a>*/"MatCreateSeqBAIJ"
14422593348eSBarry Smith /*@C
144344cd7ae7SLois Curfman McInnes    MatCreateSeqBAIJ - Creates a sparse matrix in block AIJ (block
144444cd7ae7SLois Curfman McInnes    compressed row) format.  For good matrix assembly performance the
144544cd7ae7SLois Curfman McInnes    user should preallocate the matrix storage by setting the parameter nz
14467fc3c18eSBarry Smith    (or the array nnz).  By setting these parameters accurately, performance
14472bd5e0b2SLois Curfman McInnes    during matrix assembly can be increased by more than a factor of 50.
14482593348eSBarry Smith 
1449db81eaa0SLois Curfman McInnes    Collective on MPI_Comm
1450db81eaa0SLois Curfman McInnes 
14512593348eSBarry Smith    Input Parameters:
1452db81eaa0SLois Curfman McInnes +  comm - MPI communicator, set to PETSC_COMM_SELF
1453b6490206SBarry Smith .  bs - size of block
14542593348eSBarry Smith .  m - number of rows
14552593348eSBarry Smith .  n - number of columns
1456b6490206SBarry Smith .  nz - number of block nonzeros per block row (same for all rows)
14577fc3c18eSBarry Smith -  nnz - array containing the number of block nonzeros in the various block rows
14582bd5e0b2SLois Curfman McInnes          (possibly different for each block row) or PETSC_NULL
14592593348eSBarry Smith 
14602593348eSBarry Smith    Output Parameter:
14612593348eSBarry Smith .  A - the matrix
14622593348eSBarry Smith 
14630513a670SBarry Smith    Options Database Keys:
1464db81eaa0SLois Curfman McInnes .   -mat_no_unroll - uses code that does not unroll the loops in the
1465db81eaa0SLois Curfman McInnes                      block calculations (much slower)
1466db81eaa0SLois Curfman McInnes .    -mat_block_size - size of the blocks to use
14670513a670SBarry Smith 
146815091d37SBarry Smith    Level: intermediate
146915091d37SBarry Smith 
14702593348eSBarry Smith    Notes:
147144cd7ae7SLois Curfman McInnes    The block AIJ format is fully compatible with standard Fortran 77
14722593348eSBarry Smith    storage.  That is, the stored row and column indices can begin at
147344cd7ae7SLois Curfman McInnes    either one (as in Fortran) or zero.  See the users' manual for details.
14742593348eSBarry Smith 
14752593348eSBarry Smith    Specify the preallocated storage with either nz or nnz (not both).
14762593348eSBarry Smith    Set nz=PETSC_DEFAULT and nnz=PETSC_NULL for PETSc to control dynamic memory
14772593348eSBarry Smith    allocation.  For additional details, see the users manual chapter on
14786da5968aSLois Curfman McInnes    matrices.
14792593348eSBarry Smith 
1480db81eaa0SLois Curfman McInnes .seealso: MatCreate(), MatCreateSeqAIJ(), MatSetValues(), MatCreateMPIBAIJ()
14812593348eSBarry Smith @*/
1482b6490206SBarry Smith int MatCreateSeqBAIJ(MPI_Comm comm,int bs,int m,int n,int nz,int *nnz,Mat *A)
14832593348eSBarry Smith {
14842593348eSBarry Smith   Mat         B;
1485b6490206SBarry Smith   Mat_SeqBAIJ *b;
1486f1af5d2fSBarry Smith   int         i,len,ierr,mbs,nbs,bs2,size;
1487f1af5d2fSBarry Smith   PetscTruth  flg;
14883b2fbd54SBarry Smith 
14893a40ed3dSBarry Smith   PetscFunctionBegin;
1490d132466eSBarry Smith   ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr);
1491a8c6a408SBarry Smith   if (size > 1) SETERRQ(PETSC_ERR_ARG_WRONG,0,"Comm must be of size 1");
1492b6490206SBarry Smith 
1493962fb4a0SBarry Smith   ierr = OptionsGetInt(PETSC_NULL,"-mat_block_size",&bs,PETSC_NULL);CHKERRQ(ierr);
1494302e33e3SBarry Smith   mbs  = m/bs;
1495302e33e3SBarry Smith   nbs  = n/bs;
1496302e33e3SBarry Smith   bs2  = bs*bs;
14970513a670SBarry Smith 
14983a40ed3dSBarry Smith   if (mbs*bs!=m || nbs*bs!=n) {
1499a8c6a408SBarry Smith     SETERRQ(PETSC_ERR_ARG_SIZ,0,"Number rows, cols must be divisible by blocksize");
15003a40ed3dSBarry Smith   }
15012593348eSBarry Smith 
1502b73539f3SBarry Smith   if (nz < -2) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,0,"nz cannot be less than -2: value %d",nz);
1503b73539f3SBarry Smith   if (nnz) {
1504faf3f1fcSBarry Smith     for (i=0; i<mbs; i++) {
1505b73539f3SBarry 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]);
1506b73539f3SBarry Smith     }
1507b73539f3SBarry Smith   }
1508b73539f3SBarry Smith 
15092593348eSBarry Smith   *A = 0;
15103f1db9ecSBarry Smith   PetscHeaderCreate(B,_p_Mat,struct _MatOps,MAT_COOKIE,MATSEQBAIJ,"Mat",comm,MatDestroy,MatView);
15112593348eSBarry Smith   PLogObjectCreate(B);
1512b6490206SBarry Smith   B->data = (void*)(b = PetscNew(Mat_SeqBAIJ));CHKPTRQ(b);
1513549d3d68SSatish Balay   ierr    = PetscMemzero(b,sizeof(Mat_SeqBAIJ));CHKERRQ(ierr);
1514549d3d68SSatish Balay   ierr    = PetscMemcpy(B->ops,&MatOps_Values,sizeof(struct _MatOps));CHKERRQ(ierr);
15151a6a6d98SBarry Smith   ierr    = OptionsHasName(PETSC_NULL,"-mat_no_unroll",&flg);CHKERRQ(ierr);
15161a6a6d98SBarry Smith   if (!flg) {
15177fc0212eSBarry Smith     switch (bs) {
15187fc0212eSBarry Smith     case 1:
1519f830108cSBarry Smith       B->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_1;
1520f830108cSBarry Smith       B->ops->solve           = MatSolve_SeqBAIJ_1;
15217c922b88SBarry Smith       B->ops->solvetranspose  = MatSolveTranspose_SeqBAIJ_1;
1522f830108cSBarry Smith       B->ops->mult            = MatMult_SeqBAIJ_1;
1523f830108cSBarry Smith       B->ops->multadd         = MatMultAdd_SeqBAIJ_1;
15247fc0212eSBarry Smith       break;
15254eeb42bcSBarry Smith     case 2:
1526f830108cSBarry Smith       B->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_2;
1527f830108cSBarry Smith       B->ops->solve           = MatSolve_SeqBAIJ_2;
15287c922b88SBarry Smith       B->ops->solvetranspose  = MatSolveTranspose_SeqBAIJ_2;
1529f830108cSBarry Smith       B->ops->mult            = MatMult_SeqBAIJ_2;
1530f830108cSBarry Smith       B->ops->multadd         = MatMultAdd_SeqBAIJ_2;
15316d84be18SBarry Smith       break;
1532f327dd97SBarry Smith     case 3:
1533f830108cSBarry Smith       B->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_3;
1534f830108cSBarry Smith       B->ops->solve           = MatSolve_SeqBAIJ_3;
15357c922b88SBarry Smith       B->ops->solvetranspose  = MatSolveTranspose_SeqBAIJ_3;
1536f830108cSBarry Smith       B->ops->mult            = MatMult_SeqBAIJ_3;
1537f830108cSBarry Smith       B->ops->multadd         = MatMultAdd_SeqBAIJ_3;
15384eeb42bcSBarry Smith       break;
15396d84be18SBarry Smith     case 4:
1540f830108cSBarry Smith       B->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_4;
1541f830108cSBarry Smith       B->ops->solve           = MatSolve_SeqBAIJ_4;
15427c922b88SBarry Smith       B->ops->solvetranspose  = MatSolveTranspose_SeqBAIJ_4;
1543f830108cSBarry Smith       B->ops->mult            = MatMult_SeqBAIJ_4;
1544f830108cSBarry Smith       B->ops->multadd         = MatMultAdd_SeqBAIJ_4;
15456d84be18SBarry Smith       break;
15466d84be18SBarry Smith     case 5:
1547f830108cSBarry Smith       B->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_5;
1548f830108cSBarry Smith       B->ops->solve           = MatSolve_SeqBAIJ_5;
15497c922b88SBarry Smith       B->ops->solvetranspose  = MatSolveTranspose_SeqBAIJ_5;
1550f830108cSBarry Smith       B->ops->mult            = MatMult_SeqBAIJ_5;
1551f830108cSBarry Smith       B->ops->multadd         = MatMultAdd_SeqBAIJ_5;
15526d84be18SBarry Smith       break;
155315091d37SBarry Smith     case 6:
155415091d37SBarry Smith       B->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_6;
155515091d37SBarry Smith       B->ops->solve           = MatSolve_SeqBAIJ_6;
15567c922b88SBarry Smith       B->ops->solvetranspose  = MatSolveTranspose_SeqBAIJ_6;
155715091d37SBarry Smith       B->ops->mult            = MatMult_SeqBAIJ_6;
155815091d37SBarry Smith       B->ops->multadd         = MatMultAdd_SeqBAIJ_6;
155915091d37SBarry Smith       break;
156048e9ddb2SSatish Balay     case 7:
1561f830108cSBarry Smith       B->ops->mult            = MatMult_SeqBAIJ_7;
1562f830108cSBarry Smith       B->ops->solve           = MatSolve_SeqBAIJ_7;
15637c922b88SBarry Smith       B->ops->solvetranspose  = MatSolveTranspose_SeqBAIJ_7;
1564f830108cSBarry Smith       B->ops->multadd         = MatMultAdd_SeqBAIJ_7;
156548e9ddb2SSatish Balay       break;
15667fc0212eSBarry Smith     }
15671a6a6d98SBarry Smith   }
1568e1311b90SBarry Smith   B->ops->destroy     = MatDestroy_SeqBAIJ;
1569e1311b90SBarry Smith   B->ops->view        = MatView_SeqBAIJ;
15702593348eSBarry Smith   B->factor           = 0;
15712593348eSBarry Smith   B->lupivotthreshold = 1.0;
157290f02eecSBarry Smith   B->mapping          = 0;
15732593348eSBarry Smith   b->row              = 0;
15742593348eSBarry Smith   b->col              = 0;
1575e51c0b9cSSatish Balay   b->icol             = 0;
15762593348eSBarry Smith   b->reallocs         = 0;
15773e90b805SBarry Smith   b->saved_values     = 0;
15782593348eSBarry Smith 
157944cd7ae7SLois Curfman McInnes   b->m       = m; B->m = m; B->M = m;
158044cd7ae7SLois Curfman McInnes   b->n       = n; B->n = n; B->N = n;
1581a5ae1ecdSBarry Smith 
15827413bad6SBarry Smith   ierr = MapCreateMPI(comm,m,m,&B->rmap);CHKERRQ(ierr);
15837413bad6SBarry Smith   ierr = MapCreateMPI(comm,n,n,&B->cmap);CHKERRQ(ierr);
1584a5ae1ecdSBarry Smith 
1585b6490206SBarry Smith   b->mbs     = mbs;
1586f2501298SSatish Balay   b->nbs     = nbs;
1587b6490206SBarry Smith   b->imax    = (int*)PetscMalloc((mbs+1)*sizeof(int));CHKPTRQ(b->imax);
1588c4992f7dSBarry Smith   if (!nnz) {
1589119a934aSSatish Balay     if (nz == PETSC_DEFAULT) nz = 5;
15902593348eSBarry Smith     else if (nz <= 0)        nz = 1;
1591b6490206SBarry Smith     for (i=0; i<mbs; i++) b->imax[i] = nz;
1592b6490206SBarry Smith     nz = nz*mbs;
15933a40ed3dSBarry Smith   } else {
15942593348eSBarry Smith     nz = 0;
1595b6490206SBarry Smith     for (i=0; i<mbs; i++) {b->imax[i] = nnz[i]; nz += nnz[i];}
15962593348eSBarry Smith   }
15972593348eSBarry Smith 
15982593348eSBarry Smith   /* allocate the matrix space */
15993f1db9ecSBarry Smith   len   = nz*sizeof(int) + nz*bs2*sizeof(MatScalar) + (b->m+1)*sizeof(int);
16003f1db9ecSBarry Smith   b->a  = (MatScalar*)PetscMalloc(len);CHKPTRQ(b->a);
1601549d3d68SSatish Balay   ierr = PetscMemzero(b->a,nz*bs2*sizeof(MatScalar));CHKERRQ(ierr);
16027e67e3f9SSatish Balay   b->j  = (int*)(b->a + nz*bs2);
1603549d3d68SSatish Balay   ierr = PetscMemzero(b->j,nz*sizeof(int));CHKERRQ(ierr);
16042593348eSBarry Smith   b->i  = b->j + nz;
1605c4992f7dSBarry Smith   b->singlemalloc = PETSC_TRUE;
16062593348eSBarry Smith 
1607de6a44a3SBarry Smith   b->i[0] = 0;
1608b6490206SBarry Smith   for (i=1; i<mbs+1; i++) {
16092593348eSBarry Smith     b->i[i] = b->i[i-1] + b->imax[i-1];
16102593348eSBarry Smith   }
16112593348eSBarry Smith 
1612b6490206SBarry Smith   /* b->ilen will count nonzeros in each block row so far. */
1613b6490206SBarry Smith   b->ilen = (int*)PetscMalloc((mbs+1)*sizeof(int));
1614f09e8eb9SSatish Balay   PLogObjectMemory(B,len+2*(mbs+1)*sizeof(int)+sizeof(struct _p_Mat)+sizeof(Mat_SeqBAIJ));
1615b6490206SBarry Smith   for (i=0; i<mbs; i++) { b->ilen[i] = 0;}
16162593348eSBarry Smith 
1617b6490206SBarry Smith   b->bs               = bs;
16189df24120SSatish Balay   b->bs2              = bs2;
1619b6490206SBarry Smith   b->mbs              = mbs;
16202593348eSBarry Smith   b->nz               = 0;
162118e7b8e4SLois Curfman McInnes   b->maxnz            = nz*bs2;
1622c4992f7dSBarry Smith   b->sorted           = PETSC_FALSE;
1623c4992f7dSBarry Smith   b->roworiented      = PETSC_TRUE;
16242593348eSBarry Smith   b->nonew            = 0;
16252593348eSBarry Smith   b->diag             = 0;
16262593348eSBarry Smith   b->solve_work       = 0;
1627de6a44a3SBarry Smith   b->mult_work        = 0;
16282593348eSBarry Smith   b->spptr            = 0;
16290e6d2581SBarry Smith   B->info.nz_unneeded = (PetscReal)b->maxnz;
1630883fce79SBarry Smith   b->keepzeroedrows   = PETSC_FALSE;
16314e220ebcSLois Curfman McInnes 
16322593348eSBarry Smith   *A = B;
16332593348eSBarry Smith   ierr = OptionsHasName(PETSC_NULL,"-help",&flg);CHKERRQ(ierr);
16342593348eSBarry Smith   if (flg) {ierr = MatPrintHelp(B);CHKERRQ(ierr); }
163527a8da17SBarry Smith 
1636f1af5d2fSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatStoreValues_C",
16373e90b805SBarry Smith                                      "MatStoreValues_SeqBAIJ",
16383e90b805SBarry Smith                                      (void*)MatStoreValues_SeqBAIJ);CHKERRQ(ierr);
1639f1af5d2fSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatRetrieveValues_C",
16403e90b805SBarry Smith                                      "MatRetrieveValues_SeqBAIJ",
16413e90b805SBarry Smith                                      (void*)MatRetrieveValues_SeqBAIJ);CHKERRQ(ierr);
1642f1af5d2fSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatSeqBAIJSetColumnIndices_C",
164327a8da17SBarry Smith                                      "MatSeqBAIJSetColumnIndices_SeqBAIJ",
164427a8da17SBarry Smith                                      (void*)MatSeqBAIJSetColumnIndices_SeqBAIJ);CHKERRQ(ierr);
16453a40ed3dSBarry Smith   PetscFunctionReturn(0);
16462593348eSBarry Smith }
16472593348eSBarry Smith 
16485615d1e5SSatish Balay #undef __FUNC__
1649*b2863d3aSBarry Smith #define  __FUNC__ /*<a name=""></a>*/"MatDuplicate_SeqBAIJ"
16502e8a6d31SBarry Smith int MatDuplicate_SeqBAIJ(Mat A,MatDuplicateOption cpvalues,Mat *B)
16512593348eSBarry Smith {
16522593348eSBarry Smith   Mat         C;
1653b6490206SBarry Smith   Mat_SeqBAIJ *c,*a = (Mat_SeqBAIJ*)A->data;
165427a8da17SBarry Smith   int         i,len,mbs = a->mbs,nz = a->nz,bs2 =a->bs2,ierr;
1655de6a44a3SBarry Smith 
16563a40ed3dSBarry Smith   PetscFunctionBegin;
1657a8c6a408SBarry Smith   if (a->i[mbs] != nz) SETERRQ(PETSC_ERR_PLIB,0,"Corrupt matrix");
16582593348eSBarry Smith 
16592593348eSBarry Smith   *B = 0;
16603f1db9ecSBarry Smith   PetscHeaderCreate(C,_p_Mat,struct _MatOps,MAT_COOKIE,MATSEQBAIJ,"Mat",A->comm,MatDestroy,MatView);
16612593348eSBarry Smith   PLogObjectCreate(C);
1662b6490206SBarry Smith   C->data           = (void*)(c = PetscNew(Mat_SeqBAIJ));CHKPTRQ(c);
1663549d3d68SSatish Balay   ierr              = PetscMemcpy(C->ops,A->ops,sizeof(struct _MatOps));CHKERRQ(ierr);
1664e1311b90SBarry Smith   C->ops->destroy   = MatDestroy_SeqBAIJ;
1665e1311b90SBarry Smith   C->ops->view      = MatView_SeqBAIJ;
16662593348eSBarry Smith   C->factor         = A->factor;
16672593348eSBarry Smith   c->row            = 0;
16682593348eSBarry Smith   c->col            = 0;
1669cac97260SSatish Balay   c->icol           = 0;
167032e87ba3SBarry Smith   c->saved_values   = 0;
1671f1e2ffcdSBarry Smith   c->keepzeroedrows = a->keepzeroedrows;
16722593348eSBarry Smith   C->assembled      = PETSC_TRUE;
16732593348eSBarry Smith 
167444cd7ae7SLois Curfman McInnes   c->m = C->m   = a->m;
167544cd7ae7SLois Curfman McInnes   c->n = C->n   = a->n;
167644cd7ae7SLois Curfman McInnes   C->M          = a->m;
167744cd7ae7SLois Curfman McInnes   C->N          = a->n;
167844cd7ae7SLois Curfman McInnes 
1679b6490206SBarry Smith   c->bs         = a->bs;
16809df24120SSatish Balay   c->bs2        = a->bs2;
1681b6490206SBarry Smith   c->mbs        = a->mbs;
1682b6490206SBarry Smith   c->nbs        = a->nbs;
16832593348eSBarry Smith 
1684b6490206SBarry Smith   c->imax       = (int*)PetscMalloc((mbs+1)*sizeof(int));CHKPTRQ(c->imax);
1685b6490206SBarry Smith   c->ilen       = (int*)PetscMalloc((mbs+1)*sizeof(int));CHKPTRQ(c->ilen);
1686b6490206SBarry Smith   for (i=0; i<mbs; i++) {
16872593348eSBarry Smith     c->imax[i] = a->imax[i];
16882593348eSBarry Smith     c->ilen[i] = a->ilen[i];
16892593348eSBarry Smith   }
16902593348eSBarry Smith 
16912593348eSBarry Smith   /* allocate the matrix space */
1692c4992f7dSBarry Smith   c->singlemalloc = PETSC_TRUE;
16933f1db9ecSBarry Smith   len  = (mbs+1)*sizeof(int) + nz*(bs2*sizeof(MatScalar) + sizeof(int));
16943f1db9ecSBarry Smith   c->a = (MatScalar*)PetscMalloc(len);CHKPTRQ(c->a);
16957e67e3f9SSatish Balay   c->j = (int*)(c->a + nz*bs2);
1696de6a44a3SBarry Smith   c->i = c->j + nz;
1697549d3d68SSatish Balay   ierr = PetscMemcpy(c->i,a->i,(mbs+1)*sizeof(int));CHKERRQ(ierr);
1698b6490206SBarry Smith   if (mbs > 0) {
1699549d3d68SSatish Balay     ierr = PetscMemcpy(c->j,a->j,nz*sizeof(int));CHKERRQ(ierr);
17002e8a6d31SBarry Smith     if (cpvalues == MAT_COPY_VALUES) {
1701549d3d68SSatish Balay       ierr = PetscMemcpy(c->a,a->a,bs2*nz*sizeof(MatScalar));CHKERRQ(ierr);
17022e8a6d31SBarry Smith     } else {
1703549d3d68SSatish Balay       ierr = PetscMemzero(c->a,bs2*nz*sizeof(MatScalar));CHKERRQ(ierr);
17042593348eSBarry Smith     }
17052593348eSBarry Smith   }
17062593348eSBarry Smith 
1707f09e8eb9SSatish Balay   PLogObjectMemory(C,len+2*(mbs+1)*sizeof(int)+sizeof(struct _p_Mat)+sizeof(Mat_SeqBAIJ));
17082593348eSBarry Smith   c->sorted      = a->sorted;
17092593348eSBarry Smith   c->roworiented = a->roworiented;
17102593348eSBarry Smith   c->nonew       = a->nonew;
17112593348eSBarry Smith 
17122593348eSBarry Smith   if (a->diag) {
1713b6490206SBarry Smith     c->diag = (int*)PetscMalloc((mbs+1)*sizeof(int));CHKPTRQ(c->diag);
1714b6490206SBarry Smith     PLogObjectMemory(C,(mbs+1)*sizeof(int));
1715b6490206SBarry Smith     for (i=0; i<mbs; i++) {
17162593348eSBarry Smith       c->diag[i] = a->diag[i];
17172593348eSBarry Smith     }
171898305bb5SBarry Smith   } else c->diag        = 0;
17192593348eSBarry Smith   c->nz                 = a->nz;
17202593348eSBarry Smith   c->maxnz              = a->maxnz;
17212593348eSBarry Smith   c->solve_work         = 0;
17222593348eSBarry Smith   c->spptr              = 0;      /* Dangerous -I'm throwing away a->spptr */
17237fc0212eSBarry Smith   c->mult_work          = 0;
17242593348eSBarry Smith   *B = C;
17257b2a1423SBarry Smith   ierr = FListDuplicate(A->qlist,&C->qlist);CHKERRQ(ierr);
17263a40ed3dSBarry Smith   PetscFunctionReturn(0);
17272593348eSBarry Smith }
17282593348eSBarry Smith 
17295615d1e5SSatish Balay #undef __FUNC__
1730*b2863d3aSBarry Smith #define  __FUNC__ /*<a name=""></a>*/"MatLoad_SeqBAIJ"
173119bcc07fSBarry Smith int MatLoad_SeqBAIJ(Viewer viewer,MatType type,Mat *A)
17322593348eSBarry Smith {
1733b6490206SBarry Smith   Mat_SeqBAIJ  *a;
17342593348eSBarry Smith   Mat          B;
1735f1af5d2fSBarry Smith   int          i,nz,ierr,fd,header[4],size,*rowlengths=0,M,N,bs=1;
1736b6490206SBarry Smith   int          *mask,mbs,*jj,j,rowcount,nzcount,k,*browlengths,maskcount;
173735aab85fSBarry Smith   int          kmax,jcount,block,idx,point,nzcountb,extra_rows;
1738a7c10996SSatish Balay   int          *masked,nmask,tmp,bs2,ishift;
1739b6490206SBarry Smith   Scalar       *aa;
174019bcc07fSBarry Smith   MPI_Comm     comm = ((PetscObject)viewer)->comm;
17412593348eSBarry Smith 
17423a40ed3dSBarry Smith   PetscFunctionBegin;
1743f1af5d2fSBarry Smith   ierr = OptionsGetInt(PETSC_NULL,"-matload_block_size",&bs,PETSC_NULL);CHKERRQ(ierr);
1744de6a44a3SBarry Smith   bs2  = bs*bs;
1745b6490206SBarry Smith 
1746d132466eSBarry Smith   ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr);
1747cc0fae11SBarry Smith   if (size > 1) SETERRQ(PETSC_ERR_ARG_WRONG,0,"view must have one processor");
174890ace30eSBarry Smith   ierr = ViewerBinaryGetDescriptor(viewer,&fd);CHKERRQ(ierr);
17490752156aSBarry Smith   ierr = PetscBinaryRead(fd,header,4,PETSC_INT);CHKERRQ(ierr);
1750a8c6a408SBarry Smith   if (header[0] != MAT_COOKIE) SETERRQ(PETSC_ERR_FILE_UNEXPECTED,0,"not Mat object");
17512593348eSBarry Smith   M = header[1]; N = header[2]; nz = header[3];
17522593348eSBarry Smith 
1753d64ed03dSBarry Smith   if (header[3] < 0) {
1754a8c6a408SBarry Smith     SETERRQ(PETSC_ERR_FILE_UNEXPECTED,1,"Matrix stored in special format, cannot load as SeqBAIJ");
1755d64ed03dSBarry Smith   }
1756d64ed03dSBarry Smith 
1757a8c6a408SBarry Smith   if (M != N) SETERRQ(PETSC_ERR_SUP,0,"Can only do square matrices");
175835aab85fSBarry Smith 
175935aab85fSBarry Smith   /*
176035aab85fSBarry Smith      This code adds extra rows to make sure the number of rows is
176135aab85fSBarry Smith     divisible by the blocksize
176235aab85fSBarry Smith   */
1763b6490206SBarry Smith   mbs        = M/bs;
176435aab85fSBarry Smith   extra_rows = bs - M + bs*(mbs);
176535aab85fSBarry Smith   if (extra_rows == bs) extra_rows = 0;
176635aab85fSBarry Smith   else                  mbs++;
176735aab85fSBarry Smith   if (extra_rows) {
1768537820f0SBarry Smith     PLogInfo(0,"MatLoad_SeqBAIJ:Padding loaded matrix to match blocksize\n");
176935aab85fSBarry Smith   }
1770b6490206SBarry Smith 
17712593348eSBarry Smith   /* read in row lengths */
177235aab85fSBarry Smith   rowlengths = (int*)PetscMalloc((M+extra_rows)*sizeof(int));CHKPTRQ(rowlengths);
17730752156aSBarry Smith   ierr = PetscBinaryRead(fd,rowlengths,M,PETSC_INT);CHKERRQ(ierr);
177435aab85fSBarry Smith   for (i=0; i<extra_rows; i++) rowlengths[M+i] = 1;
17752593348eSBarry Smith 
1776b6490206SBarry Smith   /* read in column indices */
177735aab85fSBarry Smith   jj = (int*)PetscMalloc((nz+extra_rows)*sizeof(int));CHKPTRQ(jj);
17780752156aSBarry Smith   ierr = PetscBinaryRead(fd,jj,nz,PETSC_INT);CHKERRQ(ierr);
177935aab85fSBarry Smith   for (i=0; i<extra_rows; i++) jj[nz+i] = M+i;
1780b6490206SBarry Smith 
1781b6490206SBarry Smith   /* loop over row lengths determining block row lengths */
1782b6490206SBarry Smith   browlengths = (int*)PetscMalloc(mbs*sizeof(int));CHKPTRQ(browlengths);
1783549d3d68SSatish Balay   ierr        = PetscMemzero(browlengths,mbs*sizeof(int));CHKERRQ(ierr);
178435aab85fSBarry Smith   mask        = (int*)PetscMalloc(2*mbs*sizeof(int));CHKPTRQ(mask);
1785549d3d68SSatish Balay   ierr        = PetscMemzero(mask,mbs*sizeof(int));CHKERRQ(ierr);
178635aab85fSBarry Smith   masked      = mask + mbs;
1787b6490206SBarry Smith   rowcount    = 0; nzcount = 0;
1788b6490206SBarry Smith   for (i=0; i<mbs; i++) {
178935aab85fSBarry Smith     nmask = 0;
1790b6490206SBarry Smith     for (j=0; j<bs; j++) {
1791b6490206SBarry Smith       kmax = rowlengths[rowcount];
1792b6490206SBarry Smith       for (k=0; k<kmax; k++) {
179335aab85fSBarry Smith         tmp = jj[nzcount++]/bs;
179435aab85fSBarry Smith         if (!mask[tmp]) {masked[nmask++] = tmp; mask[tmp] = 1;}
1795b6490206SBarry Smith       }
1796b6490206SBarry Smith       rowcount++;
1797b6490206SBarry Smith     }
179835aab85fSBarry Smith     browlengths[i] += nmask;
179935aab85fSBarry Smith     /* zero out the mask elements we set */
180035aab85fSBarry Smith     for (j=0; j<nmask; j++) mask[masked[j]] = 0;
1801b6490206SBarry Smith   }
1802b6490206SBarry Smith 
18032593348eSBarry Smith   /* create our matrix */
18043eee16b0SBarry Smith   ierr = MatCreateSeqBAIJ(comm,bs,M+extra_rows,N+extra_rows,0,browlengths,A);CHKERRQ(ierr);
18052593348eSBarry Smith   B = *A;
1806b6490206SBarry Smith   a = (Mat_SeqBAIJ*)B->data;
18072593348eSBarry Smith 
18082593348eSBarry Smith   /* set matrix "i" values */
1809de6a44a3SBarry Smith   a->i[0] = 0;
1810b6490206SBarry Smith   for (i=1; i<= mbs; i++) {
1811b6490206SBarry Smith     a->i[i]      = a->i[i-1] + browlengths[i-1];
1812b6490206SBarry Smith     a->ilen[i-1] = browlengths[i-1];
18132593348eSBarry Smith   }
1814b6490206SBarry Smith   a->nz         = 0;
1815b6490206SBarry Smith   for (i=0; i<mbs; i++) a->nz += browlengths[i];
18162593348eSBarry Smith 
1817b6490206SBarry Smith   /* read in nonzero values */
181835aab85fSBarry Smith   aa = (Scalar*)PetscMalloc((nz+extra_rows)*sizeof(Scalar));CHKPTRQ(aa);
18190752156aSBarry Smith   ierr = PetscBinaryRead(fd,aa,nz,PETSC_SCALAR);CHKERRQ(ierr);
182035aab85fSBarry Smith   for (i=0; i<extra_rows; i++) aa[nz+i] = 1.0;
1821b6490206SBarry Smith 
1822b6490206SBarry Smith   /* set "a" and "j" values into matrix */
1823b6490206SBarry Smith   nzcount = 0; jcount = 0;
1824b6490206SBarry Smith   for (i=0; i<mbs; i++) {
1825b6490206SBarry Smith     nzcountb = nzcount;
182635aab85fSBarry Smith     nmask    = 0;
1827b6490206SBarry Smith     for (j=0; j<bs; j++) {
1828b6490206SBarry Smith       kmax = rowlengths[i*bs+j];
1829b6490206SBarry Smith       for (k=0; k<kmax; k++) {
183035aab85fSBarry Smith         tmp = jj[nzcount++]/bs;
183135aab85fSBarry Smith 	if (!mask[tmp]) { masked[nmask++] = tmp; mask[tmp] = 1;}
1832b6490206SBarry Smith       }
1833b6490206SBarry Smith       rowcount++;
1834b6490206SBarry Smith     }
1835de6a44a3SBarry Smith     /* sort the masked values */
1836433994e6SBarry Smith     ierr = PetscSortInt(nmask,masked);CHKERRQ(ierr);
1837de6a44a3SBarry Smith 
1838b6490206SBarry Smith     /* set "j" values into matrix */
1839b6490206SBarry Smith     maskcount = 1;
184035aab85fSBarry Smith     for (j=0; j<nmask; j++) {
184135aab85fSBarry Smith       a->j[jcount++]  = masked[j];
1842de6a44a3SBarry Smith       mask[masked[j]] = maskcount++;
1843b6490206SBarry Smith     }
1844b6490206SBarry Smith     /* set "a" values into matrix */
1845de6a44a3SBarry Smith     ishift = bs2*a->i[i];
1846b6490206SBarry Smith     for (j=0; j<bs; j++) {
1847b6490206SBarry Smith       kmax = rowlengths[i*bs+j];
1848b6490206SBarry Smith       for (k=0; k<kmax; k++) {
1849de6a44a3SBarry Smith         tmp       = jj[nzcountb]/bs ;
1850de6a44a3SBarry Smith         block     = mask[tmp] - 1;
1851de6a44a3SBarry Smith         point     = jj[nzcountb] - bs*tmp;
1852de6a44a3SBarry Smith         idx       = ishift + bs2*block + j + bs*point;
1853375fe846SBarry Smith         a->a[idx] = (MatScalar)aa[nzcountb++];
1854b6490206SBarry Smith       }
1855b6490206SBarry Smith     }
185635aab85fSBarry Smith     /* zero out the mask elements we set */
185735aab85fSBarry Smith     for (j=0; j<nmask; j++) mask[masked[j]] = 0;
1858b6490206SBarry Smith   }
1859a8c6a408SBarry Smith   if (jcount != a->nz) SETERRQ(PETSC_ERR_FILE_UNEXPECTED,0,"Bad binary matrix");
1860b6490206SBarry Smith 
1861606d414cSSatish Balay   ierr = PetscFree(rowlengths);CHKERRQ(ierr);
1862606d414cSSatish Balay   ierr = PetscFree(browlengths);CHKERRQ(ierr);
1863606d414cSSatish Balay   ierr = PetscFree(aa);CHKERRQ(ierr);
1864606d414cSSatish Balay   ierr = PetscFree(jj);CHKERRQ(ierr);
1865606d414cSSatish Balay   ierr = PetscFree(mask);CHKERRQ(ierr);
1866b6490206SBarry Smith 
1867b6490206SBarry Smith   B->assembled = PETSC_TRUE;
1868de6a44a3SBarry Smith 
18699c01be13SBarry Smith   ierr = MatView_Private(B);CHKERRQ(ierr);
18703a40ed3dSBarry Smith   PetscFunctionReturn(0);
18712593348eSBarry Smith }
18722593348eSBarry Smith 
18732593348eSBarry Smith 
18742593348eSBarry Smith 
1875