xref: /petsc/src/mat/impls/baij/seq/baij.c (revision 4c49b1284a7fad5511c23c1bb39bf91d51e85708)
1*4c49b128SBarry Smith /*$Id: baij.c,v 1.198 2000/01/26 22:08:15 balay Exp bsmith $*/
22593348eSBarry Smith 
32593348eSBarry Smith /*
4b6490206SBarry Smith     Defines the basic matrix operations for the BAIJ (compressed row)
52593348eSBarry Smith   matrix storage format.
62593348eSBarry Smith */
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__
18c4992f7dSBarry Smith #define __FUNC__ "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__
36c4992f7dSBarry Smith #define __FUNC__ "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__
645615d1e5SSatish Balay #define __FUNC__ "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__
89d4bb536fSBarry Smith #define __FUNC__ "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__
1102d61bbb3SSatish Balay #define __FUNC__ "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__
1222d61bbb3SSatish Balay #define __FUNC__ "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__
1692d61bbb3SSatish Balay #define __FUNC__ "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__
2022d61bbb3SSatish Balay #define __FUNC__ "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__
2142d61bbb3SSatish Balay #define __FUNC__ "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;
220*4c49b128SBarry Smith   if (m) *m = 0;
221*4c49b128SBarry Smith   if (n) *n = a->m;
2222d61bbb3SSatish Balay   PetscFunctionReturn(0);
2232d61bbb3SSatish Balay }
2242d61bbb3SSatish Balay 
2252d61bbb3SSatish Balay #undef __FUNC__
2262d61bbb3SSatish Balay #define __FUNC__ "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__
2752d61bbb3SSatish Balay #define __FUNC__ "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__
2872d61bbb3SSatish Balay #define __FUNC__ "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;
2943f1db9ecSBarry Smith   MatScalar   *array = a->a;
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 
3012d61bbb3SSatish Balay   for (i=0; i<ai[mbs]; i++) col[aj[i]] += 1;
3022d61bbb3SSatish Balay   ierr = MatCreateSeqBAIJ(A->comm,bs,a->n,a->m,PETSC_NULL,col,&C);CHKERRQ(ierr);
303606d414cSSatish Balay   ierr = PetscFree(col);CHKERRQ(ierr);
3042d61bbb3SSatish Balay   rows = (int*)PetscMalloc(2*bs*sizeof(int));CHKPTRQ(rows);
3052d61bbb3SSatish Balay   cols = rows + bs;
3062d61bbb3SSatish Balay   for (i=0; i<mbs; i++) {
3072d61bbb3SSatish Balay     cols[0] = i*bs;
3082d61bbb3SSatish Balay     for (k=1; k<bs; k++) cols[k] = cols[k-1] + 1;
3092d61bbb3SSatish Balay     len = ai[i+1] - ai[i];
3102d61bbb3SSatish Balay     for (j=0; j<len; j++) {
3112d61bbb3SSatish Balay       rows[0] = (*aj++)*bs;
3122d61bbb3SSatish Balay       for (k=1; k<bs; k++) rows[k] = rows[k-1] + 1;
3132d61bbb3SSatish Balay       ierr = MatSetValues(C,bs,rows,bs,cols,array,INSERT_VALUES);CHKERRQ(ierr);
3142d61bbb3SSatish Balay       array += bs2;
3152d61bbb3SSatish Balay     }
3162d61bbb3SSatish Balay   }
317606d414cSSatish Balay   ierr = PetscFree(rows);CHKERRQ(ierr);
3182d61bbb3SSatish Balay 
3192d61bbb3SSatish Balay   ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
3202d61bbb3SSatish Balay   ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
3212d61bbb3SSatish Balay 
322c4992f7dSBarry Smith   if (B) {
3232d61bbb3SSatish Balay     *B = C;
3242d61bbb3SSatish Balay   } else {
325f830108cSBarry Smith     PetscOps *Abops;
326cc2dc46cSBarry Smith     MatOps   Aops;
327f830108cSBarry Smith 
3282d61bbb3SSatish Balay     /* This isn't really an in-place transpose */
329606d414cSSatish Balay     ierr = PetscFree(a->a);CHKERRQ(ierr);
330606d414cSSatish Balay     if (!a->singlemalloc) {
331606d414cSSatish Balay       ierr = PetscFree(a->i);CHKERRQ(ierr);
332606d414cSSatish Balay       ierr = PetscFree(a->j);CHKERRQ(ierr);
333606d414cSSatish Balay     }
334606d414cSSatish Balay     if (a->diag) {ierr = PetscFree(a->diag);CHKERRQ(ierr);}
335606d414cSSatish Balay     if (a->ilen) {ierr = PetscFree(a->ilen);CHKERRQ(ierr);}
336606d414cSSatish Balay     if (a->imax) {ierr = PetscFree(a->imax);CHKERRQ(ierr);}
337606d414cSSatish Balay     if (a->solve_work) {ierr = PetscFree(a->solve_work);CHKERRQ(ierr);}
338606d414cSSatish Balay     ierr = PetscFree(a);CHKERRQ(ierr);
339f830108cSBarry Smith 
3407413bad6SBarry Smith 
3417413bad6SBarry Smith     ierr = MapDestroy(A->rmap);CHKERRQ(ierr);
3427413bad6SBarry Smith     ierr = MapDestroy(A->cmap);CHKERRQ(ierr);
3437413bad6SBarry Smith 
344f830108cSBarry Smith     /*
345f830108cSBarry Smith        This is horrible, horrible code. We need to keep the
346f830108cSBarry Smith       A pointers for the bops and ops but copy everything
347f830108cSBarry Smith       else from C.
348f830108cSBarry Smith     */
349f830108cSBarry Smith     Abops    = A->bops;
350f830108cSBarry Smith     Aops     = A->ops;
3510e6d2581SBarry Smith     refct    = A->refct;
352549d3d68SSatish Balay     ierr     = PetscMemcpy(A,C,sizeof(struct _p_Mat));CHKERRQ(ierr);
353f830108cSBarry Smith     A->bops  = Abops;
354f830108cSBarry Smith     A->ops   = Aops;
35527a8da17SBarry Smith     A->qlist = 0;
3560e6d2581SBarry Smith     A->refct = refct;
357f830108cSBarry Smith 
3582d61bbb3SSatish Balay     PetscHeaderDestroy(C);
3592d61bbb3SSatish Balay   }
3602d61bbb3SSatish Balay   PetscFunctionReturn(0);
3612d61bbb3SSatish Balay }
3622d61bbb3SSatish Balay 
3635615d1e5SSatish Balay #undef __FUNC__
364d4bb536fSBarry Smith #define __FUNC__ "MatView_SeqBAIJ_Binary"
365b6490206SBarry Smith static int MatView_SeqBAIJ_Binary(Mat A,Viewer viewer)
3662593348eSBarry Smith {
367b6490206SBarry Smith   Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)A->data;
3689df24120SSatish Balay   int         i,fd,*col_lens,ierr,bs = a->bs,count,*jj,j,k,l,bs2=a->bs2;
369b6490206SBarry Smith   Scalar      *aa;
370ce6f0cecSBarry Smith   FILE        *file;
3712593348eSBarry Smith 
3723a40ed3dSBarry Smith   PetscFunctionBegin;
37390ace30eSBarry Smith   ierr = ViewerBinaryGetDescriptor(viewer,&fd);CHKERRQ(ierr);
3742593348eSBarry Smith   col_lens = (int*)PetscMalloc((4+a->m)*sizeof(int));CHKPTRQ(col_lens);
3752593348eSBarry Smith   col_lens[0] = MAT_COOKIE;
3763b2fbd54SBarry Smith 
3772593348eSBarry Smith   col_lens[1] = a->m;
3782593348eSBarry Smith   col_lens[2] = a->n;
3797e67e3f9SSatish Balay   col_lens[3] = a->nz*bs2;
3802593348eSBarry Smith 
3812593348eSBarry Smith   /* store lengths of each row and write (including header) to file */
382b6490206SBarry Smith   count = 0;
383b6490206SBarry Smith   for (i=0; i<a->mbs; i++) {
384b6490206SBarry Smith     for (j=0; j<bs; j++) {
385b6490206SBarry Smith       col_lens[4+count++] = bs*(a->i[i+1] - a->i[i]);
386b6490206SBarry Smith     }
3872593348eSBarry Smith   }
3880752156aSBarry Smith   ierr = PetscBinaryWrite(fd,col_lens,4+a->m,PETSC_INT,1);CHKERRQ(ierr);
389606d414cSSatish Balay   ierr = PetscFree(col_lens);CHKERRQ(ierr);
3902593348eSBarry Smith 
3912593348eSBarry Smith   /* store column indices (zero start index) */
39266963ce1SSatish Balay   jj = (int*)PetscMalloc((a->nz+1)*bs2*sizeof(int));CHKPTRQ(jj);
393b6490206SBarry Smith   count = 0;
394b6490206SBarry Smith   for (i=0; i<a->mbs; i++) {
395b6490206SBarry Smith     for (j=0; j<bs; j++) {
396b6490206SBarry Smith       for (k=a->i[i]; k<a->i[i+1]; k++) {
397b6490206SBarry Smith         for (l=0; l<bs; l++) {
398b6490206SBarry Smith           jj[count++] = bs*a->j[k] + l;
3992593348eSBarry Smith         }
4002593348eSBarry Smith       }
401b6490206SBarry Smith     }
402b6490206SBarry Smith   }
4030752156aSBarry Smith   ierr = PetscBinaryWrite(fd,jj,bs2*a->nz,PETSC_INT,0);CHKERRQ(ierr);
404606d414cSSatish Balay   ierr = PetscFree(jj);CHKERRQ(ierr);
4052593348eSBarry Smith 
4062593348eSBarry Smith   /* store nonzero values */
40766963ce1SSatish Balay   aa = (Scalar*)PetscMalloc((a->nz+1)*bs2*sizeof(Scalar));CHKPTRQ(aa);
408b6490206SBarry Smith   count = 0;
409b6490206SBarry Smith   for (i=0; i<a->mbs; i++) {
410b6490206SBarry Smith     for (j=0; j<bs; j++) {
411b6490206SBarry Smith       for (k=a->i[i]; k<a->i[i+1]; k++) {
412b6490206SBarry Smith         for (l=0; l<bs; l++) {
4137e67e3f9SSatish Balay           aa[count++] = a->a[bs2*k + l*bs + j];
414b6490206SBarry Smith         }
415b6490206SBarry Smith       }
416b6490206SBarry Smith     }
417b6490206SBarry Smith   }
4180752156aSBarry Smith   ierr = PetscBinaryWrite(fd,aa,bs2*a->nz,PETSC_SCALAR,0);CHKERRQ(ierr);
419606d414cSSatish Balay   ierr = PetscFree(aa);CHKERRQ(ierr);
420ce6f0cecSBarry Smith 
421ce6f0cecSBarry Smith   ierr = ViewerBinaryGetInfoPointer(viewer,&file);CHKERRQ(ierr);
422ce6f0cecSBarry Smith   if (file) {
423ce6f0cecSBarry Smith     fprintf(file,"-matload_block_size %d\n",a->bs);
424ce6f0cecSBarry Smith   }
4253a40ed3dSBarry Smith   PetscFunctionReturn(0);
4262593348eSBarry Smith }
4272593348eSBarry Smith 
4285615d1e5SSatish Balay #undef __FUNC__
429d4bb536fSBarry Smith #define __FUNC__ "MatView_SeqBAIJ_ASCII"
430b6490206SBarry Smith static int MatView_SeqBAIJ_ASCII(Mat A,Viewer viewer)
4312593348eSBarry Smith {
432b6490206SBarry Smith   Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)A->data;
4339df24120SSatish Balay   int         ierr,i,j,format,bs = a->bs,k,l,bs2=a->bs2;
4342593348eSBarry Smith   char        *outputname;
4352593348eSBarry Smith 
4363a40ed3dSBarry Smith   PetscFunctionBegin;
43777ed5343SBarry Smith   ierr = ViewerGetOutputname(viewer,&outputname);CHKERRQ(ierr);
438888f2ed8SSatish Balay   ierr = ViewerGetFormat(viewer,&format);CHKERRQ(ierr);
439639f9d9dSBarry Smith   if (format == VIEWER_FORMAT_ASCII_INFO || format == VIEWER_FORMAT_ASCII_INFO_LONG) {
440d132466eSBarry Smith     ierr = ViewerASCIIPrintf(viewer,"  block size is %d\n",bs);CHKERRQ(ierr);
4410ef38995SBarry Smith   } else if (format == VIEWER_FORMAT_ASCII_MATLAB) {
4426831982aSBarry Smith     SETERRQ(PETSC_ERR_SUP,0,"Matlab format not supported");
4430ef38995SBarry Smith   } else if (format == VIEWER_FORMAT_ASCII_COMMON) {
4446831982aSBarry Smith     ierr = ViewerASCIIUseTabs(viewer,PETSC_NO);CHKERRQ(ierr);
44544cd7ae7SLois Curfman McInnes     for (i=0; i<a->mbs; i++) {
44644cd7ae7SLois Curfman McInnes       for (j=0; j<bs; j++) {
4476831982aSBarry Smith         ierr = ViewerASCIIPrintf(viewer,"row %d:",i*bs+j);CHKERRQ(ierr);
44844cd7ae7SLois Curfman McInnes         for (k=a->i[i]; k<a->i[i+1]; k++) {
44944cd7ae7SLois Curfman McInnes           for (l=0; l<bs; l++) {
450aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
4510e6d2581SBarry Smith             if (PetscImaginaryPart(a->a[bs2*k + l*bs + j]) > 0.0 && PetscRealPart(a->a[bs2*k + l*bs + j]) != 0.0) {
4526831982aSBarry Smith               ierr = ViewerASCIIPrintf(viewer," %d %g + %gi",bs*a->j[k]+l,
4530e6d2581SBarry Smith                       PetscRealPart(a->a[bs2*k + l*bs + j]),PetscImaginaryPart(a->a[bs2*k + l*bs + j]));CHKERRQ(ierr);
4540e6d2581SBarry Smith             } else if (PetscImaginaryPart(a->a[bs2*k + l*bs + j]) < 0.0 && PetscRealPart(a->a[bs2*k + l*bs + j]) != 0.0) {
4556831982aSBarry Smith               ierr = ViewerASCIIPrintf(viewer," %d %g - %gi",bs*a->j[k]+l,
4560e6d2581SBarry Smith                       PetscRealPart(a->a[bs2*k + l*bs + j]),-PetscImaginaryPart(a->a[bs2*k + l*bs + j]));CHKERRQ(ierr);
4570e6d2581SBarry Smith             } else if (PetscRealPart(a->a[bs2*k + l*bs + j]) != 0.0) {
4580e6d2581SBarry Smith               ierr = ViewerASCIIPrintf(viewer," %d %g ",bs*a->j[k]+l,PetscRealPart(a->a[bs2*k + l*bs + j]));CHKERRQ(ierr);
4590ef38995SBarry Smith             }
46044cd7ae7SLois Curfman McInnes #else
4610ef38995SBarry Smith             if (a->a[bs2*k + l*bs + j] != 0.0) {
4626831982aSBarry Smith               ierr = ViewerASCIIPrintf(viewer," %d %g ",bs*a->j[k]+l,a->a[bs2*k + l*bs + j]);CHKERRQ(ierr);
4630ef38995SBarry Smith             }
46444cd7ae7SLois Curfman McInnes #endif
46544cd7ae7SLois Curfman McInnes           }
46644cd7ae7SLois Curfman McInnes         }
4676831982aSBarry Smith         ierr = ViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
46844cd7ae7SLois Curfman McInnes       }
46944cd7ae7SLois Curfman McInnes     }
4706831982aSBarry Smith     ierr = ViewerASCIIUseTabs(viewer,PETSC_YES);CHKERRQ(ierr);
4710ef38995SBarry Smith   } else {
4726831982aSBarry Smith     ierr = ViewerASCIIUseTabs(viewer,PETSC_NO);CHKERRQ(ierr);
473b6490206SBarry Smith     for (i=0; i<a->mbs; i++) {
474b6490206SBarry Smith       for (j=0; j<bs; j++) {
4756831982aSBarry Smith         ierr = ViewerASCIIPrintf(viewer,"row %d:",i*bs+j);CHKERRQ(ierr);
476b6490206SBarry Smith         for (k=a->i[i]; k<a->i[i+1]; k++) {
477b6490206SBarry Smith           for (l=0; l<bs; l++) {
478aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
4790e6d2581SBarry Smith             if (PetscImaginaryPart(a->a[bs2*k + l*bs + j]) > 0.0) {
4806831982aSBarry Smith               ierr = ViewerASCIIPrintf(viewer," %d %g + %g i",bs*a->j[k]+l,
4810e6d2581SBarry Smith                 PetscRealPart(a->a[bs2*k + l*bs + j]),PetscImaginaryPart(a->a[bs2*k + l*bs + j]));CHKERRQ(ierr);
4820e6d2581SBarry Smith             } else if (PetscImaginaryPart(a->a[bs2*k + l*bs + j]) < 0.0) {
4836831982aSBarry Smith               ierr = ViewerASCIIPrintf(viewer," %d %g - %g i",bs*a->j[k]+l,
4840e6d2581SBarry Smith                 PetscRealPart(a->a[bs2*k + l*bs + j]),-PetscImaginaryPart(a->a[bs2*k + l*bs + j]));CHKERRQ(ierr);
4850ef38995SBarry Smith             } else {
4860e6d2581SBarry Smith               ierr = ViewerASCIIPrintf(viewer," %d %g ",bs*a->j[k]+l,PetscRealPart(a->a[bs2*k + l*bs + j]));CHKERRQ(ierr);
48788685aaeSLois Curfman McInnes             }
48888685aaeSLois Curfman McInnes #else
4896831982aSBarry Smith             ierr = ViewerASCIIPrintf(viewer," %d %g ",bs*a->j[k]+l,a->a[bs2*k + l*bs + j]);CHKERRQ(ierr);
49088685aaeSLois Curfman McInnes #endif
4912593348eSBarry Smith           }
4922593348eSBarry Smith         }
4936831982aSBarry Smith         ierr = ViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
4942593348eSBarry Smith       }
4952593348eSBarry Smith     }
4966831982aSBarry Smith     ierr = ViewerASCIIUseTabs(viewer,PETSC_YES);CHKERRQ(ierr);
497b6490206SBarry Smith   }
4986831982aSBarry Smith   ierr = ViewerFlush(viewer);CHKERRQ(ierr);
4993a40ed3dSBarry Smith   PetscFunctionReturn(0);
5002593348eSBarry Smith }
5012593348eSBarry Smith 
5025615d1e5SSatish Balay #undef __FUNC__
50377ed5343SBarry Smith #define __FUNC__ "MatView_SeqBAIJ_Draw_Zoom"
50477ed5343SBarry Smith static int MatView_SeqBAIJ_Draw_Zoom(Draw draw,void *Aa)
5053270192aSSatish Balay {
50677ed5343SBarry Smith   Mat          A = (Mat) Aa;
5073270192aSSatish Balay   Mat_SeqBAIJ  *a=(Mat_SeqBAIJ*)A->data;
508b65db4caSBarry Smith   int          row,ierr,i,j,k,l,mbs=a->mbs,color,bs=a->bs,bs2=a->bs2;
5090e6d2581SBarry Smith   PetscReal    xl,yl,xr,yr,x_l,x_r,y_l,y_r;
5103f1db9ecSBarry Smith   MatScalar    *aa;
51177ed5343SBarry Smith   Viewer       viewer;
5123270192aSSatish Balay 
5133a40ed3dSBarry Smith   PetscFunctionBegin;
5143270192aSSatish Balay 
515b65db4caSBarry Smith   /* still need to add support for contour plot of nonzeros; see MatView_SeqAIJ_Draw_Zoom()*/
51677ed5343SBarry Smith   ierr = PetscObjectQuery((PetscObject)A,"Zoomviewer",(PetscObject*)&viewer);CHKERRQ(ierr);
51777ed5343SBarry Smith 
51877ed5343SBarry Smith   ierr = DrawGetCoordinates(draw,&xl,&yl,&xr,&yr);CHKERRQ(ierr);
51977ed5343SBarry Smith 
5203270192aSSatish Balay   /* loop over matrix elements drawing boxes */
5213270192aSSatish Balay   color = DRAW_BLUE;
5223270192aSSatish Balay   for (i=0,row=0; i<mbs; i++,row+=bs) {
5233270192aSSatish Balay     for (j=a->i[i]; j<a->i[i+1]; j++) {
5243270192aSSatish Balay       y_l = a->m - row - 1.0; y_r = y_l + 1.0;
5253270192aSSatish Balay       x_l = a->j[j]*bs; x_r = x_l + 1.0;
5263270192aSSatish Balay       aa = a->a + j*bs2;
5273270192aSSatish Balay       for (k=0; k<bs; k++) {
5283270192aSSatish Balay         for (l=0; l<bs; l++) {
5290e6d2581SBarry Smith           if (PetscRealPart(*aa++) >=  0.) continue;
530433994e6SBarry Smith           ierr = DrawRectangle(draw,x_l+k,y_l-l,x_r+k,y_r-l,color,color,color,color);CHKERRQ(ierr);
5313270192aSSatish Balay         }
5323270192aSSatish Balay       }
5333270192aSSatish Balay     }
5343270192aSSatish Balay   }
5353270192aSSatish Balay   color = DRAW_CYAN;
5363270192aSSatish Balay   for (i=0,row=0; i<mbs; i++,row+=bs) {
5373270192aSSatish Balay     for (j=a->i[i]; j<a->i[i+1]; j++) {
5383270192aSSatish Balay       y_l = a->m - row - 1.0; y_r = y_l + 1.0;
5393270192aSSatish Balay       x_l = a->j[j]*bs; x_r = x_l + 1.0;
5403270192aSSatish Balay       aa = a->a + j*bs2;
5413270192aSSatish Balay       for (k=0; k<bs; k++) {
5423270192aSSatish Balay         for (l=0; l<bs; l++) {
5430e6d2581SBarry Smith           if (PetscRealPart(*aa++) != 0.) continue;
544433994e6SBarry Smith           ierr = DrawRectangle(draw,x_l+k,y_l-l,x_r+k,y_r-l,color,color,color,color);CHKERRQ(ierr);
5453270192aSSatish Balay         }
5463270192aSSatish Balay       }
5473270192aSSatish Balay     }
5483270192aSSatish Balay   }
5493270192aSSatish Balay 
5503270192aSSatish Balay   color = DRAW_RED;
5513270192aSSatish Balay   for (i=0,row=0; i<mbs; i++,row+=bs) {
5523270192aSSatish Balay     for (j=a->i[i]; j<a->i[i+1]; j++) {
5533270192aSSatish Balay       y_l = a->m - row - 1.0; y_r = y_l + 1.0;
5543270192aSSatish Balay       x_l = a->j[j]*bs; x_r = x_l + 1.0;
5553270192aSSatish Balay       aa = a->a + j*bs2;
5563270192aSSatish Balay       for (k=0; k<bs; k++) {
5573270192aSSatish Balay         for (l=0; l<bs; l++) {
5580e6d2581SBarry Smith           if (PetscRealPart(*aa++) <= 0.) continue;
559433994e6SBarry Smith           ierr = DrawRectangle(draw,x_l+k,y_l-l,x_r+k,y_r-l,color,color,color,color);CHKERRQ(ierr);
5603270192aSSatish Balay         }
5613270192aSSatish Balay       }
5623270192aSSatish Balay     }
5633270192aSSatish Balay   }
56477ed5343SBarry Smith   PetscFunctionReturn(0);
56577ed5343SBarry Smith }
5663270192aSSatish Balay 
56777ed5343SBarry Smith #undef __FUNC__
56877ed5343SBarry Smith #define __FUNC__ "MatView_SeqBAIJ_Draw"
56977ed5343SBarry Smith static int MatView_SeqBAIJ_Draw(Mat A,Viewer viewer)
57077ed5343SBarry Smith {
57177ed5343SBarry Smith   Mat_SeqBAIJ  *a=(Mat_SeqBAIJ*)A->data;
5727dce120fSSatish Balay   int          ierr;
5730e6d2581SBarry Smith   PetscReal    xl,yl,xr,yr,w,h;
57477ed5343SBarry Smith   Draw         draw;
57577ed5343SBarry Smith   PetscTruth   isnull;
5763270192aSSatish Balay 
57777ed5343SBarry Smith   PetscFunctionBegin;
57877ed5343SBarry Smith 
57977ed5343SBarry Smith   ierr = ViewerDrawGetDraw(viewer,0,&draw);CHKERRQ(ierr);
58077ed5343SBarry Smith   ierr = DrawIsNull(draw,&isnull);CHKERRQ(ierr); if (isnull) PetscFunctionReturn(0);
58177ed5343SBarry Smith 
58277ed5343SBarry Smith   ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",(PetscObject)viewer);CHKERRQ(ierr);
58377ed5343SBarry Smith   xr  = a->n; yr = a->m; h = yr/10.0; w = xr/10.0;
58477ed5343SBarry Smith   xr += w;    yr += h;  xl = -w;     yl = -h;
5853270192aSSatish Balay   ierr = DrawSetCoordinates(draw,xl,yl,xr,yr);CHKERRQ(ierr);
58677ed5343SBarry Smith   ierr = DrawZoom(draw,MatView_SeqBAIJ_Draw_Zoom,A);CHKERRQ(ierr);
58777ed5343SBarry Smith   ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",PETSC_NULL);CHKERRQ(ierr);
5883a40ed3dSBarry Smith   PetscFunctionReturn(0);
5893270192aSSatish Balay }
5903270192aSSatish Balay 
5915615d1e5SSatish Balay #undef __FUNC__
592d4bb536fSBarry Smith #define __FUNC__ "MatView_SeqBAIJ"
593e1311b90SBarry Smith int MatView_SeqBAIJ(Mat A,Viewer viewer)
5942593348eSBarry Smith {
59519bcc07fSBarry Smith   int        ierr;
5966831982aSBarry Smith   PetscTruth issocket,isascii,isbinary,isdraw;
5972593348eSBarry Smith 
5983a40ed3dSBarry Smith   PetscFunctionBegin;
5996831982aSBarry Smith   ierr = PetscTypeCompare((PetscObject)viewer,SOCKET_VIEWER,&issocket);CHKERRQ(ierr);
6006831982aSBarry Smith   ierr = PetscTypeCompare((PetscObject)viewer,ASCII_VIEWER,&isascii);CHKERRQ(ierr);
6016831982aSBarry Smith   ierr = PetscTypeCompare((PetscObject)viewer,BINARY_VIEWER,&isbinary);CHKERRQ(ierr);
6026831982aSBarry Smith   ierr = PetscTypeCompare((PetscObject)viewer,DRAW_VIEWER,&isdraw);CHKERRQ(ierr);
6030f5bd95cSBarry Smith   if (issocket) {
6047b2a1423SBarry Smith     SETERRQ(PETSC_ERR_SUP,0,"Socket viewer not supported");
6050f5bd95cSBarry Smith   } else if (isascii){
6063a40ed3dSBarry Smith     ierr = MatView_SeqBAIJ_ASCII(A,viewer);CHKERRQ(ierr);
6070f5bd95cSBarry Smith   } else if (isbinary) {
6083a40ed3dSBarry Smith     ierr = MatView_SeqBAIJ_Binary(A,viewer);CHKERRQ(ierr);
6090f5bd95cSBarry Smith   } else if (isdraw) {
6103a40ed3dSBarry Smith     ierr = MatView_SeqBAIJ_Draw(A,viewer);CHKERRQ(ierr);
6115cd90555SBarry Smith   } else {
6120f5bd95cSBarry Smith     SETERRQ1(1,1,"Viewer type %s not supported by SeqBAIJ matrices",((PetscObject)viewer)->type_name);
6132593348eSBarry Smith   }
6143a40ed3dSBarry Smith   PetscFunctionReturn(0);
6152593348eSBarry Smith }
616b6490206SBarry Smith 
617cd0e1443SSatish Balay 
6185615d1e5SSatish Balay #undef __FUNC__
6192d61bbb3SSatish Balay #define __FUNC__ "MatGetValues_SeqBAIJ"
6202d61bbb3SSatish Balay int MatGetValues_SeqBAIJ(Mat A,int m,int *im,int n,int *in,Scalar *v)
621cd0e1443SSatish Balay {
622cd0e1443SSatish Balay   Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)A->data;
6232d61bbb3SSatish Balay   int        *rp,k,low,high,t,row,nrow,i,col,l,*aj = a->j;
6242d61bbb3SSatish Balay   int        *ai = a->i,*ailen = a->ilen;
6252d61bbb3SSatish Balay   int        brow,bcol,ridx,cidx,bs=a->bs,bs2=a->bs2;
6263f1db9ecSBarry Smith   MatScalar  *ap,*aa = a->a,zero = 0.0;
627cd0e1443SSatish Balay 
6283a40ed3dSBarry Smith   PetscFunctionBegin;
6292d61bbb3SSatish Balay   for (k=0; k<m; k++) { /* loop over rows */
630cd0e1443SSatish Balay     row  = im[k]; brow = row/bs;
631a8c6a408SBarry Smith     if (row < 0) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Negative row");
632a8c6a408SBarry Smith     if (row >= a->m) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Row too large");
6332d61bbb3SSatish Balay     rp   = aj + ai[brow] ; ap = aa + bs2*ai[brow] ;
6342c3acbe9SBarry Smith     nrow = ailen[brow];
6352d61bbb3SSatish Balay     for (l=0; l<n; l++) { /* loop over columns */
636a8c6a408SBarry Smith       if (in[l] < 0) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Negative column");
637a8c6a408SBarry Smith       if (in[l] >= a->n) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Column too large");
6382d61bbb3SSatish Balay       col  = in[l] ;
6392d61bbb3SSatish Balay       bcol = col/bs;
6402d61bbb3SSatish Balay       cidx = col%bs;
6412d61bbb3SSatish Balay       ridx = row%bs;
6422d61bbb3SSatish Balay       high = nrow;
6432d61bbb3SSatish Balay       low  = 0; /* assume unsorted */
6442d61bbb3SSatish Balay       while (high-low > 5) {
645cd0e1443SSatish Balay         t = (low+high)/2;
646cd0e1443SSatish Balay         if (rp[t] > bcol) high = t;
647cd0e1443SSatish Balay         else             low  = t;
648cd0e1443SSatish Balay       }
649cd0e1443SSatish Balay       for (i=low; i<high; i++) {
650cd0e1443SSatish Balay         if (rp[i] > bcol) break;
651cd0e1443SSatish Balay         if (rp[i] == bcol) {
6522d61bbb3SSatish Balay           *v++ = ap[bs2*i+bs*cidx+ridx];
6532d61bbb3SSatish Balay           goto finished;
654cd0e1443SSatish Balay         }
655cd0e1443SSatish Balay       }
6562d61bbb3SSatish Balay       *v++ = zero;
6572d61bbb3SSatish Balay       finished:;
658cd0e1443SSatish Balay     }
659cd0e1443SSatish Balay   }
6603a40ed3dSBarry Smith   PetscFunctionReturn(0);
661cd0e1443SSatish Balay }
662cd0e1443SSatish Balay 
6632d61bbb3SSatish Balay 
6645615d1e5SSatish Balay #undef __FUNC__
66505a5f48eSSatish Balay #define __FUNC__ "MatSetValuesBlocked_SeqBAIJ"
66692c4ed94SBarry Smith int MatSetValuesBlocked_SeqBAIJ(Mat A,int m,int *im,int n,int *in,Scalar *v,InsertMode is)
66792c4ed94SBarry Smith {
66892c4ed94SBarry Smith   Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)A->data;
6698a84c255SSatish Balay   int         *rp,k,low,high,t,ii,jj,row,nrow,i,col,l,rmax,N,sorted=a->sorted;
670dd9472c6SBarry Smith   int         *imax=a->imax,*ai=a->i,*ailen=a->ilen,roworiented=a->roworiented;
671549d3d68SSatish Balay   int         *aj=a->j,nonew=a->nonew,bs2=a->bs2,bs=a->bs,stepval,ierr;
6723f1db9ecSBarry Smith   Scalar      *value = v;
6733f1db9ecSBarry Smith   MatScalar   *ap,*aa=a->a,*bap;
67492c4ed94SBarry Smith 
6753a40ed3dSBarry Smith   PetscFunctionBegin;
6760e324ae4SSatish Balay   if (roworiented) {
6770e324ae4SSatish Balay     stepval = (n-1)*bs;
6780e324ae4SSatish Balay   } else {
6790e324ae4SSatish Balay     stepval = (m-1)*bs;
6800e324ae4SSatish Balay   }
68192c4ed94SBarry Smith   for (k=0; k<m; k++) { /* loop over added rows */
68292c4ed94SBarry Smith     row  = im[k];
6835ef9f2a5SBarry Smith     if (row < 0) continue;
684aa482453SBarry Smith #if defined(PETSC_USE_BOPT_g)
685a8c6a408SBarry Smith     if (row >= a->mbs) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Row too large");
68692c4ed94SBarry Smith #endif
68792c4ed94SBarry Smith     rp   = aj + ai[row];
68892c4ed94SBarry Smith     ap   = aa + bs2*ai[row];
68992c4ed94SBarry Smith     rmax = imax[row];
69092c4ed94SBarry Smith     nrow = ailen[row];
69192c4ed94SBarry Smith     low  = 0;
69292c4ed94SBarry Smith     for (l=0; l<n; l++) { /* loop over added columns */
6935ef9f2a5SBarry Smith       if (in[l] < 0) continue;
694aa482453SBarry Smith #if defined(PETSC_USE_BOPT_g)
695a8c6a408SBarry Smith       if (in[l] >= a->nbs) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Column too large");
69692c4ed94SBarry Smith #endif
69792c4ed94SBarry Smith       col = in[l];
69892c4ed94SBarry Smith       if (roworiented) {
6990e324ae4SSatish Balay         value = v + k*(stepval+bs)*bs + l*bs;
7000e324ae4SSatish Balay       } else {
7010e324ae4SSatish Balay         value = v + l*(stepval+bs)*bs + k*bs;
70292c4ed94SBarry Smith       }
70392c4ed94SBarry Smith       if (!sorted) low = 0; high = nrow;
70492c4ed94SBarry Smith       while (high-low > 7) {
70592c4ed94SBarry Smith         t = (low+high)/2;
70692c4ed94SBarry Smith         if (rp[t] > col) high = t;
70792c4ed94SBarry Smith         else             low  = t;
70892c4ed94SBarry Smith       }
70992c4ed94SBarry Smith       for (i=low; i<high; i++) {
71092c4ed94SBarry Smith         if (rp[i] > col) break;
71192c4ed94SBarry Smith         if (rp[i] == col) {
7128a84c255SSatish Balay           bap  = ap +  bs2*i;
7130e324ae4SSatish Balay           if (roworiented) {
7148a84c255SSatish Balay             if (is == ADD_VALUES) {
715dd9472c6SBarry Smith               for (ii=0; ii<bs; ii++,value+=stepval) {
716dd9472c6SBarry Smith                 for (jj=ii; jj<bs2; jj+=bs) {
7178a84c255SSatish Balay                   bap[jj] += *value++;
718dd9472c6SBarry Smith                 }
719dd9472c6SBarry Smith               }
7200e324ae4SSatish Balay             } else {
721dd9472c6SBarry Smith               for (ii=0; ii<bs; ii++,value+=stepval) {
722dd9472c6SBarry Smith                 for (jj=ii; jj<bs2; jj+=bs) {
7230e324ae4SSatish Balay                   bap[jj] = *value++;
7248a84c255SSatish Balay                 }
725dd9472c6SBarry Smith               }
726dd9472c6SBarry Smith             }
7270e324ae4SSatish Balay           } else {
7280e324ae4SSatish Balay             if (is == ADD_VALUES) {
729dd9472c6SBarry Smith               for (ii=0; ii<bs; ii++,value+=stepval) {
730dd9472c6SBarry Smith                 for (jj=0; jj<bs; jj++) {
7310e324ae4SSatish Balay                   *bap++ += *value++;
732dd9472c6SBarry Smith                 }
733dd9472c6SBarry Smith               }
7340e324ae4SSatish Balay             } else {
735dd9472c6SBarry Smith               for (ii=0; ii<bs; ii++,value+=stepval) {
736dd9472c6SBarry Smith                 for (jj=0; jj<bs; jj++) {
7370e324ae4SSatish Balay                   *bap++  = *value++;
7380e324ae4SSatish Balay                 }
7398a84c255SSatish Balay               }
740dd9472c6SBarry Smith             }
741dd9472c6SBarry Smith           }
742f1241b54SBarry Smith           goto noinsert2;
74392c4ed94SBarry Smith         }
74492c4ed94SBarry Smith       }
74589280ab3SLois Curfman McInnes       if (nonew == 1) goto noinsert2;
746a8c6a408SBarry Smith       else if (nonew == -1) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Inserting a new nonzero in the matrix");
74792c4ed94SBarry Smith       if (nrow >= rmax) {
74892c4ed94SBarry Smith         /* there is no extra room in row, therefore enlarge */
74992c4ed94SBarry Smith         int       new_nz = ai[a->mbs] + CHUNKSIZE,len,*new_i,*new_j;
7503f1db9ecSBarry Smith         MatScalar *new_a;
75192c4ed94SBarry Smith 
752a8c6a408SBarry Smith         if (nonew == -2) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Inserting a new nonzero in the matrix");
75389280ab3SLois Curfman McInnes 
75492c4ed94SBarry Smith         /* malloc new storage space */
7553f1db9ecSBarry Smith         len     = new_nz*(sizeof(int)+bs2*sizeof(MatScalar))+(a->mbs+1)*sizeof(int);
7563f1db9ecSBarry Smith         new_a   = (MatScalar*)PetscMalloc(len);CHKPTRQ(new_a);
75792c4ed94SBarry Smith         new_j   = (int*)(new_a + bs2*new_nz);
75892c4ed94SBarry Smith         new_i   = new_j + new_nz;
75992c4ed94SBarry Smith 
76092c4ed94SBarry Smith         /* copy over old data into new slots */
76192c4ed94SBarry Smith         for (ii=0; ii<row+1; ii++) {new_i[ii] = ai[ii];}
76292c4ed94SBarry Smith         for (ii=row+1; ii<a->mbs+1; ii++) {new_i[ii] = ai[ii]+CHUNKSIZE;}
763549d3d68SSatish Balay         ierr = PetscMemcpy(new_j,aj,(ai[row]+nrow)*sizeof(int));CHKERRQ(ierr);
76492c4ed94SBarry Smith         len  = (new_nz - CHUNKSIZE - ai[row] - nrow);
765549d3d68SSatish Balay         ierr = PetscMemcpy(new_j+ai[row]+nrow+CHUNKSIZE,aj+ai[row]+nrow,len*sizeof(int));CHKERRQ(ierr);
766549d3d68SSatish Balay         ierr = PetscMemcpy(new_a,aa,(ai[row]+nrow)*bs2*sizeof(MatScalar));CHKERRQ(ierr);
767549d3d68SSatish Balay         ierr = PetscMemzero(new_a+bs2*(ai[row]+nrow),bs2*CHUNKSIZE*sizeof(MatScalar));CHKERRQ(ierr);
768549d3d68SSatish Balay         ierr = PetscMemcpy(new_a+bs2*(ai[row]+nrow+CHUNKSIZE),aa+bs2*(ai[row]+nrow),bs2*len*sizeof(MatScalar));CHKERRQ(ierr);
76992c4ed94SBarry Smith         /* free up old matrix storage */
770606d414cSSatish Balay         ierr = PetscFree(a->a);CHKERRQ(ierr);
771606d414cSSatish Balay         if (!a->singlemalloc) {
772606d414cSSatish Balay           ierr = PetscFree(a->i);CHKERRQ(ierr);
773606d414cSSatish Balay           ierr = PetscFree(a->j);CHKERRQ(ierr);
774606d414cSSatish Balay         }
77592c4ed94SBarry Smith         aa = a->a = new_a; ai = a->i = new_i; aj = a->j = new_j;
776c4992f7dSBarry Smith         a->singlemalloc = PETSC_TRUE;
77792c4ed94SBarry Smith 
77892c4ed94SBarry Smith         rp   = aj + ai[row]; ap = aa + bs2*ai[row];
77992c4ed94SBarry Smith         rmax = imax[row] = imax[row] + CHUNKSIZE;
7803f1db9ecSBarry Smith         PLogObjectMemory(A,CHUNKSIZE*(sizeof(int) + bs2*sizeof(MatScalar)));
78192c4ed94SBarry Smith         a->maxnz += bs2*CHUNKSIZE;
78292c4ed94SBarry Smith         a->reallocs++;
78392c4ed94SBarry Smith         a->nz++;
78492c4ed94SBarry Smith       }
78592c4ed94SBarry Smith       N = nrow++ - 1;
78692c4ed94SBarry Smith       /* shift up all the later entries in this row */
78792c4ed94SBarry Smith       for (ii=N; ii>=i; ii--) {
78892c4ed94SBarry Smith         rp[ii+1] = rp[ii];
789549d3d68SSatish Balay         ierr = PetscMemcpy(ap+bs2*(ii+1),ap+bs2*(ii),bs2*sizeof(MatScalar));CHKERRQ(ierr);
79092c4ed94SBarry Smith       }
791549d3d68SSatish Balay       if (N >= i) {
792549d3d68SSatish Balay         ierr = PetscMemzero(ap+bs2*i,bs2*sizeof(MatScalar));CHKERRQ(ierr);
793549d3d68SSatish Balay       }
79492c4ed94SBarry Smith       rp[i] = col;
7958a84c255SSatish Balay       bap   = ap +  bs2*i;
7960e324ae4SSatish Balay       if (roworiented) {
797dd9472c6SBarry Smith         for (ii=0; ii<bs; ii++,value+=stepval) {
798dd9472c6SBarry Smith           for (jj=ii; jj<bs2; jj+=bs) {
7990e324ae4SSatish Balay             bap[jj] = *value++;
800dd9472c6SBarry Smith           }
801dd9472c6SBarry Smith         }
8020e324ae4SSatish Balay       } else {
803dd9472c6SBarry Smith         for (ii=0; ii<bs; ii++,value+=stepval) {
804dd9472c6SBarry Smith           for (jj=0; jj<bs; jj++) {
8050e324ae4SSatish Balay             *bap++  = *value++;
8060e324ae4SSatish Balay           }
807dd9472c6SBarry Smith         }
808dd9472c6SBarry Smith       }
809f1241b54SBarry Smith       noinsert2:;
81092c4ed94SBarry Smith       low = i;
81192c4ed94SBarry Smith     }
81292c4ed94SBarry Smith     ailen[row] = nrow;
81392c4ed94SBarry Smith   }
8143a40ed3dSBarry Smith   PetscFunctionReturn(0);
81592c4ed94SBarry Smith }
81692c4ed94SBarry Smith 
817f2501298SSatish Balay 
8185615d1e5SSatish Balay #undef __FUNC__
8195615d1e5SSatish Balay #define __FUNC__ "MatAssemblyEnd_SeqBAIJ"
8208f6be9afSLois Curfman McInnes int MatAssemblyEnd_SeqBAIJ(Mat A,MatAssemblyType mode)
821584200bdSSatish Balay {
822584200bdSSatish Balay   Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)A->data;
823584200bdSSatish Balay   int        fshift = 0,i,j,*ai = a->i,*aj = a->j,*imax = a->imax;
824a7c10996SSatish Balay   int        m = a->m,*ip,N,*ailen = a->ilen;
825549d3d68SSatish Balay   int        mbs = a->mbs,bs2 = a->bs2,rmax = 0,ierr;
8263f1db9ecSBarry Smith   MatScalar  *aa = a->a,*ap;
827584200bdSSatish Balay 
8283a40ed3dSBarry Smith   PetscFunctionBegin;
8293a40ed3dSBarry Smith   if (mode == MAT_FLUSH_ASSEMBLY) PetscFunctionReturn(0);
830584200bdSSatish Balay 
83143ee02c3SBarry Smith   if (m) rmax = ailen[0];
832584200bdSSatish Balay   for (i=1; i<mbs; i++) {
833584200bdSSatish Balay     /* move each row back by the amount of empty slots (fshift) before it*/
834584200bdSSatish Balay     fshift += imax[i-1] - ailen[i-1];
835d402145bSBarry Smith     rmax   = PetscMax(rmax,ailen[i]);
836584200bdSSatish Balay     if (fshift) {
837a7c10996SSatish Balay       ip = aj + ai[i]; ap = aa + bs2*ai[i];
838584200bdSSatish Balay       N = ailen[i];
839584200bdSSatish Balay       for (j=0; j<N; j++) {
840584200bdSSatish Balay         ip[j-fshift] = ip[j];
841549d3d68SSatish Balay         ierr = PetscMemcpy(ap+(j-fshift)*bs2,ap+j*bs2,bs2*sizeof(MatScalar));CHKERRQ(ierr);
842584200bdSSatish Balay       }
843584200bdSSatish Balay     }
844584200bdSSatish Balay     ai[i] = ai[i-1] + ailen[i-1];
845584200bdSSatish Balay   }
846584200bdSSatish Balay   if (mbs) {
847584200bdSSatish Balay     fshift += imax[mbs-1] - ailen[mbs-1];
848584200bdSSatish Balay     ai[mbs] = ai[mbs-1] + ailen[mbs-1];
849584200bdSSatish Balay   }
850584200bdSSatish Balay   /* reset ilen and imax for each row */
851584200bdSSatish Balay   for (i=0; i<mbs; i++) {
852584200bdSSatish Balay     ailen[i] = imax[i] = ai[i+1] - ai[i];
853584200bdSSatish Balay   }
854a7c10996SSatish Balay   a->nz = ai[mbs];
855584200bdSSatish Balay 
856584200bdSSatish Balay   /* diagonals may have moved, so kill the diagonal pointers */
857584200bdSSatish Balay   if (fshift && a->diag) {
858606d414cSSatish Balay     ierr = PetscFree(a->diag);CHKERRQ(ierr);
859584200bdSSatish Balay     PLogObjectMemory(A,-(m+1)*sizeof(int));
860584200bdSSatish Balay     a->diag = 0;
861584200bdSSatish Balay   }
8623d2013a6SLois Curfman McInnes   PLogInfo(A,"MatAssemblyEnd_SeqBAIJ:Matrix size: %d X %d, block size %d; storage space: %d unneeded, %d used\n",
863219d9a1aSLois Curfman McInnes            m,a->n,a->bs,fshift*bs2,a->nz*bs2);
8643d2013a6SLois Curfman McInnes   PLogInfo(A,"MatAssemblyEnd_SeqBAIJ:Number of mallocs during MatSetValues is %d\n",
865584200bdSSatish Balay            a->reallocs);
866d402145bSBarry Smith   PLogInfo(A,"MatAssemblyEnd_SeqBAIJ:Most nonzeros blocks in any row is %d\n",rmax);
867e2f3b5e9SSatish Balay   a->reallocs          = 0;
8680e6d2581SBarry Smith   A->info.nz_unneeded  = (PetscReal)fshift*bs2;
8694e220ebcSLois Curfman McInnes 
8703a40ed3dSBarry Smith   PetscFunctionReturn(0);
871584200bdSSatish Balay }
872584200bdSSatish Balay 
8735a838052SSatish Balay 
874bea157c4SSatish Balay 
875bea157c4SSatish Balay /*
876bea157c4SSatish Balay    This function returns an array of flags which indicate the locations of contiguous
877bea157c4SSatish Balay    blocks that should be zeroed. for eg: if bs = 3  and is = [0,1,2,3,5,6,7,8,9]
878bea157c4SSatish Balay    then the resulting sizes = [3,1,1,3,1] correspondig to sets [(0,1,2),(3),(5),(6,7,8),(9)]
879bea157c4SSatish Balay    Assume: sizes should be long enough to hold all the values.
880bea157c4SSatish Balay */
8815615d1e5SSatish Balay #undef __FUNC__
882bea157c4SSatish Balay #define __FUNC__ "MatZeroRows_SeqBAIJ_Check_Blocks"
883bea157c4SSatish Balay static int MatZeroRows_SeqBAIJ_Check_Blocks(int idx[],int n,int bs,int sizes[], int *bs_max)
884d9b7c43dSSatish Balay {
885bea157c4SSatish Balay   int        i,j,k,row;
886bea157c4SSatish Balay   PetscTruth flg;
8873a40ed3dSBarry Smith 
888433994e6SBarry Smith   PetscFunctionBegin;
889bea157c4SSatish Balay   for (i=0,j=0; i<n; j++) {
890bea157c4SSatish Balay     row = idx[i];
891bea157c4SSatish Balay     if (row%bs!=0) { /* Not the begining of a block */
892bea157c4SSatish Balay       sizes[j] = 1;
893bea157c4SSatish Balay       i++;
894e4fda26cSSatish Balay     } else if (i+bs > n) { /* complete block doesn't exist (at idx end) */
895bea157c4SSatish Balay       sizes[j] = 1;         /* Also makes sure atleast 'bs' values exist for next else */
896bea157c4SSatish Balay       i++;
897bea157c4SSatish Balay     } else { /* Begining of the block, so check if the complete block exists */
898bea157c4SSatish Balay       flg = PETSC_TRUE;
899bea157c4SSatish Balay       for (k=1; k<bs; k++) {
900bea157c4SSatish Balay         if (row+k != idx[i+k]) { /* break in the block */
901bea157c4SSatish Balay           flg = PETSC_FALSE;
902bea157c4SSatish Balay           break;
903d9b7c43dSSatish Balay         }
904bea157c4SSatish Balay       }
905bea157c4SSatish Balay       if (flg == PETSC_TRUE) { /* No break in the bs */
906bea157c4SSatish Balay         sizes[j] = bs;
907bea157c4SSatish Balay         i+= bs;
908bea157c4SSatish Balay       } else {
909bea157c4SSatish Balay         sizes[j] = 1;
910bea157c4SSatish Balay         i++;
911bea157c4SSatish Balay       }
912bea157c4SSatish Balay     }
913bea157c4SSatish Balay   }
914bea157c4SSatish Balay   *bs_max = j;
9153a40ed3dSBarry Smith   PetscFunctionReturn(0);
916d9b7c43dSSatish Balay }
917d9b7c43dSSatish Balay 
9185615d1e5SSatish Balay #undef __FUNC__
9195615d1e5SSatish Balay #define __FUNC__ "MatZeroRows_SeqBAIJ"
9208f6be9afSLois Curfman McInnes int MatZeroRows_SeqBAIJ(Mat A,IS is,Scalar *diag)
921d9b7c43dSSatish Balay {
922d9b7c43dSSatish Balay   Mat_SeqBAIJ *baij=(Mat_SeqBAIJ*)A->data;
923b6815fffSBarry Smith   int         ierr,i,j,k,count,is_n,*is_idx,*rows;
924bea157c4SSatish Balay   int         bs=baij->bs,bs2=baij->bs2,*sizes,row,bs_max;
9253f1db9ecSBarry Smith   Scalar      zero = 0.0;
9263f1db9ecSBarry Smith   MatScalar   *aa;
927d9b7c43dSSatish Balay 
9283a40ed3dSBarry Smith   PetscFunctionBegin;
929d9b7c43dSSatish Balay   /* Make a copy of the IS and  sort it */
930d9b7c43dSSatish Balay   ierr = ISGetSize(is,&is_n);CHKERRQ(ierr);
931d9b7c43dSSatish Balay   ierr = ISGetIndices(is,&is_idx);CHKERRQ(ierr);
932d9b7c43dSSatish Balay 
933bea157c4SSatish Balay   /* allocate memory for rows,sizes */
934bea157c4SSatish Balay   rows  = (int*)PetscMalloc((3*is_n+1)*sizeof(int));CHKPTRQ(rows);
935bea157c4SSatish Balay   sizes = rows + is_n;
936bea157c4SSatish Balay 
937bea157c4SSatish Balay   /* initialize copy IS valurs to rows, and sort them */
938bea157c4SSatish Balay   for (i=0; i<is_n; i++) { rows[i] = is_idx[i]; }
939bea157c4SSatish Balay   ierr = PetscSortInt(is_n,rows);CHKERRQ(ierr);
940dffd3267SBarry Smith   if (baij->keepzeroedrows) {
941dffd3267SBarry Smith     for (i=0; i<is_n; i++) { sizes[i] = 1; }
942dffd3267SBarry Smith     bs_max = is_n;
943dffd3267SBarry Smith   } else {
944bea157c4SSatish Balay     ierr = MatZeroRows_SeqBAIJ_Check_Blocks(rows,is_n,bs,sizes,&bs_max);CHKERRQ(ierr);
945dffd3267SBarry Smith   }
946b97a56abSSatish Balay   ierr = ISRestoreIndices(is,&is_idx);CHKERRQ(ierr);
947bea157c4SSatish Balay 
948bea157c4SSatish Balay   for (i=0,j=0; i<bs_max; j+=sizes[i],i++) {
949bea157c4SSatish Balay     row   = rows[j];
950b6815fffSBarry Smith     if (row < 0 || row > baij->m) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,0,"row %d out of range",row);
951bea157c4SSatish Balay     count = (baij->i[row/bs +1] - baij->i[row/bs])*bs;
952bea157c4SSatish Balay     aa    = baij->a + baij->i[row/bs]*bs2 + (row%bs);
953dffd3267SBarry Smith     if (sizes[i] == bs && !baij->keepzeroedrows) {
954bea157c4SSatish Balay       if (diag) {
955bea157c4SSatish Balay         if (baij->ilen[row/bs] > 0) {
956bea157c4SSatish Balay           baij->ilen[row/bs] = 1;
957bea157c4SSatish Balay           baij->j[baij->i[row/bs]] = row/bs;
958bea157c4SSatish Balay           ierr = PetscMemzero(aa,count*bs*sizeof(MatScalar));CHKERRQ(ierr);
959a07cd24cSSatish Balay         }
960bea157c4SSatish Balay         /* Now insert all the diagoanl values for this bs */
961bea157c4SSatish Balay         for (k=0; k<bs; k++) {
962bea157c4SSatish Balay           ierr = (*A->ops->setvalues)(A,1,rows+j+k,1,rows+j+k,diag,INSERT_VALUES);CHKERRQ(ierr);
963bea157c4SSatish Balay         }
964bea157c4SSatish Balay       } else { /* (!diag) */
965bea157c4SSatish Balay         baij->ilen[row/bs] = 0;
966bea157c4SSatish Balay       } /* end (!diag) */
967bea157c4SSatish Balay     } else { /* (sizes[i] != bs) */
968aa482453SBarry Smith #if defined (PETSC_USE_DEBUG)
969bea157c4SSatish Balay       if (sizes[i] != 1) SETERRQ(1,0,"Internal Error. Value should be 1");
970bea157c4SSatish Balay #endif
971bea157c4SSatish Balay       for (k=0; k<count; k++) {
972d9b7c43dSSatish Balay         aa[0] = zero;
973d9b7c43dSSatish Balay         aa+=bs;
974d9b7c43dSSatish Balay       }
975d9b7c43dSSatish Balay       if (diag) {
976f830108cSBarry Smith         ierr = (*A->ops->setvalues)(A,1,rows+j,1,rows+j,diag,INSERT_VALUES);CHKERRQ(ierr);
977d9b7c43dSSatish Balay       }
978d9b7c43dSSatish Balay     }
979bea157c4SSatish Balay   }
980bea157c4SSatish Balay 
981606d414cSSatish Balay   ierr = PetscFree(rows);CHKERRQ(ierr);
9829a8dea36SBarry Smith   ierr = MatAssemblyEnd_SeqBAIJ(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
9833a40ed3dSBarry Smith   PetscFunctionReturn(0);
984d9b7c43dSSatish Balay }
9851c351548SSatish Balay 
9865615d1e5SSatish Balay #undef __FUNC__
9872d61bbb3SSatish Balay #define __FUNC__ "MatSetValues_SeqBAIJ"
9882d61bbb3SSatish Balay int MatSetValues_SeqBAIJ(Mat A,int m,int *im,int n,int *in,Scalar *v,InsertMode is)
9892d61bbb3SSatish Balay {
9902d61bbb3SSatish Balay   Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)A->data;
9912d61bbb3SSatish Balay   int         *rp,k,low,high,t,ii,row,nrow,i,col,l,rmax,N,sorted=a->sorted;
9922d61bbb3SSatish Balay   int         *imax=a->imax,*ai=a->i,*ailen=a->ilen,roworiented=a->roworiented;
9932d61bbb3SSatish Balay   int         *aj=a->j,nonew=a->nonew,bs=a->bs,brow,bcol;
994549d3d68SSatish Balay   int         ridx,cidx,bs2=a->bs2,ierr;
9953f1db9ecSBarry Smith   MatScalar   *ap,value,*aa=a->a,*bap;
9962d61bbb3SSatish Balay 
9972d61bbb3SSatish Balay   PetscFunctionBegin;
9982d61bbb3SSatish Balay   for (k=0; k<m; k++) { /* loop over added rows */
9992d61bbb3SSatish Balay     row  = im[k]; brow = row/bs;
10005ef9f2a5SBarry Smith     if (row < 0) continue;
1001aa482453SBarry Smith #if defined(PETSC_USE_BOPT_g)
100232e87ba3SBarry Smith     if (row >= a->m) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,0,"Row too large: row %d max %d",row,a->m);
10032d61bbb3SSatish Balay #endif
10042d61bbb3SSatish Balay     rp   = aj + ai[brow];
10052d61bbb3SSatish Balay     ap   = aa + bs2*ai[brow];
10062d61bbb3SSatish Balay     rmax = imax[brow];
10072d61bbb3SSatish Balay     nrow = ailen[brow];
10082d61bbb3SSatish Balay     low  = 0;
10092d61bbb3SSatish Balay     for (l=0; l<n; l++) { /* loop over added columns */
10105ef9f2a5SBarry Smith       if (in[l] < 0) continue;
1011aa482453SBarry Smith #if defined(PETSC_USE_BOPT_g)
101232e87ba3SBarry Smith       if (in[l] >= a->n) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,0,"Column too large: col %d max %d",in[l],a->n);
10132d61bbb3SSatish Balay #endif
10142d61bbb3SSatish Balay       col = in[l]; bcol = col/bs;
10152d61bbb3SSatish Balay       ridx = row % bs; cidx = col % bs;
10162d61bbb3SSatish Balay       if (roworiented) {
10175ef9f2a5SBarry Smith         value = v[l + k*n];
10182d61bbb3SSatish Balay       } else {
10192d61bbb3SSatish Balay         value = v[k + l*m];
10202d61bbb3SSatish Balay       }
10212d61bbb3SSatish Balay       if (!sorted) low = 0; high = nrow;
10222d61bbb3SSatish Balay       while (high-low > 7) {
10232d61bbb3SSatish Balay         t = (low+high)/2;
10242d61bbb3SSatish Balay         if (rp[t] > bcol) high = t;
10252d61bbb3SSatish Balay         else              low  = t;
10262d61bbb3SSatish Balay       }
10272d61bbb3SSatish Balay       for (i=low; i<high; i++) {
10282d61bbb3SSatish Balay         if (rp[i] > bcol) break;
10292d61bbb3SSatish Balay         if (rp[i] == bcol) {
10302d61bbb3SSatish Balay           bap  = ap +  bs2*i + bs*cidx + ridx;
10312d61bbb3SSatish Balay           if (is == ADD_VALUES) *bap += value;
10322d61bbb3SSatish Balay           else                  *bap  = value;
10332d61bbb3SSatish Balay           goto noinsert1;
10342d61bbb3SSatish Balay         }
10352d61bbb3SSatish Balay       }
10362d61bbb3SSatish Balay       if (nonew == 1) goto noinsert1;
10372d61bbb3SSatish Balay       else if (nonew == -1) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Inserting a new nonzero in the matrix");
10382d61bbb3SSatish Balay       if (nrow >= rmax) {
10392d61bbb3SSatish Balay         /* there is no extra room in row, therefore enlarge */
10402d61bbb3SSatish Balay         int       new_nz = ai[a->mbs] + CHUNKSIZE,len,*new_i,*new_j;
10413f1db9ecSBarry Smith         MatScalar *new_a;
10422d61bbb3SSatish Balay 
10432d61bbb3SSatish Balay         if (nonew == -2) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Inserting a new nonzero in the matrix");
10442d61bbb3SSatish Balay 
10452d61bbb3SSatish Balay         /* Malloc new storage space */
10463f1db9ecSBarry Smith         len     = new_nz*(sizeof(int)+bs2*sizeof(MatScalar))+(a->mbs+1)*sizeof(int);
10473f1db9ecSBarry Smith         new_a   = (MatScalar*)PetscMalloc(len);CHKPTRQ(new_a);
10482d61bbb3SSatish Balay         new_j   = (int*)(new_a + bs2*new_nz);
10492d61bbb3SSatish Balay         new_i   = new_j + new_nz;
10502d61bbb3SSatish Balay 
10512d61bbb3SSatish Balay         /* copy over old data into new slots */
10522d61bbb3SSatish Balay         for (ii=0; ii<brow+1; ii++) {new_i[ii] = ai[ii];}
10532d61bbb3SSatish Balay         for (ii=brow+1; ii<a->mbs+1; ii++) {new_i[ii] = ai[ii]+CHUNKSIZE;}
1054549d3d68SSatish Balay         ierr = PetscMemcpy(new_j,aj,(ai[brow]+nrow)*sizeof(int));CHKERRQ(ierr);
10552d61bbb3SSatish Balay         len  = (new_nz - CHUNKSIZE - ai[brow] - nrow);
1056549d3d68SSatish Balay         ierr = PetscMemcpy(new_j+ai[brow]+nrow+CHUNKSIZE,aj+ai[brow]+nrow,len*sizeof(int));CHKERRQ(ierr);
1057549d3d68SSatish Balay         ierr = PetscMemcpy(new_a,aa,(ai[brow]+nrow)*bs2*sizeof(MatScalar));CHKERRQ(ierr);
1058549d3d68SSatish Balay         ierr = PetscMemzero(new_a+bs2*(ai[brow]+nrow),bs2*CHUNKSIZE*sizeof(MatScalar));CHKERRQ(ierr);
1059549d3d68SSatish Balay         ierr = PetscMemcpy(new_a+bs2*(ai[brow]+nrow+CHUNKSIZE),aa+bs2*(ai[brow]+nrow),bs2*len*sizeof(MatScalar));CHKERRQ(ierr);
10602d61bbb3SSatish Balay         /* free up old matrix storage */
1061606d414cSSatish Balay         ierr = PetscFree(a->a);CHKERRQ(ierr);
1062606d414cSSatish Balay         if (!a->singlemalloc) {
1063606d414cSSatish Balay           ierr = PetscFree(a->i);CHKERRQ(ierr);
1064606d414cSSatish Balay           ierr = PetscFree(a->j);CHKERRQ(ierr);
1065606d414cSSatish Balay         }
10662d61bbb3SSatish Balay         aa = a->a = new_a; ai = a->i = new_i; aj = a->j = new_j;
1067c4992f7dSBarry Smith         a->singlemalloc = PETSC_TRUE;
10682d61bbb3SSatish Balay 
10692d61bbb3SSatish Balay         rp   = aj + ai[brow]; ap = aa + bs2*ai[brow];
10702d61bbb3SSatish Balay         rmax = imax[brow] = imax[brow] + CHUNKSIZE;
10713f1db9ecSBarry Smith         PLogObjectMemory(A,CHUNKSIZE*(sizeof(int) + bs2*sizeof(MatScalar)));
10722d61bbb3SSatish Balay         a->maxnz += bs2*CHUNKSIZE;
10732d61bbb3SSatish Balay         a->reallocs++;
10742d61bbb3SSatish Balay         a->nz++;
10752d61bbb3SSatish Balay       }
10762d61bbb3SSatish Balay       N = nrow++ - 1;
10772d61bbb3SSatish Balay       /* shift up all the later entries in this row */
10782d61bbb3SSatish Balay       for (ii=N; ii>=i; ii--) {
10792d61bbb3SSatish Balay         rp[ii+1] = rp[ii];
1080549d3d68SSatish Balay         ierr     = PetscMemcpy(ap+bs2*(ii+1),ap+bs2*(ii),bs2*sizeof(MatScalar));CHKERRQ(ierr);
10812d61bbb3SSatish Balay       }
1082549d3d68SSatish Balay       if (N>=i) {
1083549d3d68SSatish Balay         ierr = PetscMemzero(ap+bs2*i,bs2*sizeof(MatScalar));CHKERRQ(ierr);
1084549d3d68SSatish Balay       }
10852d61bbb3SSatish Balay       rp[i]                      = bcol;
10862d61bbb3SSatish Balay       ap[bs2*i + bs*cidx + ridx] = value;
10872d61bbb3SSatish Balay       noinsert1:;
10882d61bbb3SSatish Balay       low = i;
10892d61bbb3SSatish Balay     }
10902d61bbb3SSatish Balay     ailen[brow] = nrow;
10912d61bbb3SSatish Balay   }
10922d61bbb3SSatish Balay   PetscFunctionReturn(0);
10932d61bbb3SSatish Balay }
10942d61bbb3SSatish Balay 
10950e6d2581SBarry Smith extern int MatLUFactorSymbolic_SeqBAIJ(Mat,IS,IS,PetscReal,Mat*);
10960e6d2581SBarry Smith extern int MatLUFactor_SeqBAIJ(Mat,IS,IS,PetscReal);
10972d61bbb3SSatish Balay extern int MatIncreaseOverlap_SeqBAIJ(Mat,int,IS*,int);
10987b2a1423SBarry Smith extern int MatGetSubMatrix_SeqBAIJ(Mat,IS,IS,int,MatReuse,Mat*);
10997b2a1423SBarry Smith extern int MatGetSubMatrices_SeqBAIJ(Mat,int,IS*,IS*,MatReuse,Mat**);
11007c922b88SBarry Smith extern int MatMultTranspose_SeqBAIJ(Mat,Vec,Vec);
11017c922b88SBarry Smith extern int MatMultTransposeAdd_SeqBAIJ(Mat,Vec,Vec,Vec);
11022d61bbb3SSatish Balay extern int MatScale_SeqBAIJ(Scalar*,Mat);
11030e6d2581SBarry Smith extern int MatNorm_SeqBAIJ(Mat,NormType,PetscReal *);
11042d61bbb3SSatish Balay extern int MatEqual_SeqBAIJ(Mat,Mat,PetscTruth*);
11052d61bbb3SSatish Balay extern int MatGetDiagonal_SeqBAIJ(Mat,Vec);
11062d61bbb3SSatish Balay extern int MatDiagonalScale_SeqBAIJ(Mat,Vec,Vec);
11072d61bbb3SSatish Balay extern int MatGetInfo_SeqBAIJ(Mat,MatInfoType,MatInfo *);
11082d61bbb3SSatish Balay extern int MatZeroEntries_SeqBAIJ(Mat);
11092d61bbb3SSatish Balay 
11102d61bbb3SSatish Balay extern int MatSolve_SeqBAIJ_N(Mat,Vec,Vec);
11112d61bbb3SSatish Balay extern int MatSolve_SeqBAIJ_1(Mat,Vec,Vec);
11122d61bbb3SSatish Balay extern int MatSolve_SeqBAIJ_2(Mat,Vec,Vec);
11132d61bbb3SSatish Balay extern int MatSolve_SeqBAIJ_3(Mat,Vec,Vec);
11142d61bbb3SSatish Balay extern int MatSolve_SeqBAIJ_4(Mat,Vec,Vec);
11152d61bbb3SSatish Balay extern int MatSolve_SeqBAIJ_5(Mat,Vec,Vec);
111615091d37SBarry Smith extern int MatSolve_SeqBAIJ_6(Mat,Vec,Vec);
11172d61bbb3SSatish Balay extern int MatSolve_SeqBAIJ_7(Mat,Vec,Vec);
11187c922b88SBarry Smith extern int MatSolveTranspose_SeqBAIJ_7(Mat,Vec,Vec);
11197c922b88SBarry Smith extern int MatSolveTranspose_SeqBAIJ_6(Mat,Vec,Vec);
11207c922b88SBarry Smith extern int MatSolveTranspose_SeqBAIJ_5(Mat,Vec,Vec);
11217c922b88SBarry Smith extern int MatSolveTranspose_SeqBAIJ_4(Mat,Vec,Vec);
11227c922b88SBarry Smith extern int MatSolveTranspose_SeqBAIJ_3(Mat,Vec,Vec);
11237c922b88SBarry Smith extern int MatSolveTranspose_SeqBAIJ_2(Mat,Vec,Vec);
11247c922b88SBarry Smith extern int MatSolveTranspose_SeqBAIJ_1(Mat,Vec,Vec);
11252d61bbb3SSatish Balay 
11262d61bbb3SSatish Balay extern int MatLUFactorNumeric_SeqBAIJ_N(Mat,Mat*);
11272d61bbb3SSatish Balay extern int MatLUFactorNumeric_SeqBAIJ_1(Mat,Mat*);
11282d61bbb3SSatish Balay extern int MatLUFactorNumeric_SeqBAIJ_2(Mat,Mat*);
11292d61bbb3SSatish Balay extern int MatLUFactorNumeric_SeqBAIJ_3(Mat,Mat*);
11302d61bbb3SSatish Balay extern int MatLUFactorNumeric_SeqBAIJ_4(Mat,Mat*);
11312d61bbb3SSatish Balay extern int MatLUFactorNumeric_SeqBAIJ_5(Mat,Mat*);
113215091d37SBarry Smith extern int MatLUFactorNumeric_SeqBAIJ_6(Mat,Mat*);
11332d61bbb3SSatish Balay 
11342d61bbb3SSatish Balay extern int MatMult_SeqBAIJ_1(Mat,Vec,Vec);
11352d61bbb3SSatish Balay extern int MatMult_SeqBAIJ_2(Mat,Vec,Vec);
11362d61bbb3SSatish Balay extern int MatMult_SeqBAIJ_3(Mat,Vec,Vec);
11372d61bbb3SSatish Balay extern int MatMult_SeqBAIJ_4(Mat,Vec,Vec);
11382d61bbb3SSatish Balay extern int MatMult_SeqBAIJ_5(Mat,Vec,Vec);
113915091d37SBarry Smith extern int MatMult_SeqBAIJ_6(Mat,Vec,Vec);
11402d61bbb3SSatish Balay extern int MatMult_SeqBAIJ_7(Mat,Vec,Vec);
11412d61bbb3SSatish Balay extern int MatMult_SeqBAIJ_N(Mat,Vec,Vec);
11422d61bbb3SSatish Balay 
11432d61bbb3SSatish Balay extern int MatMultAdd_SeqBAIJ_1(Mat,Vec,Vec,Vec);
11442d61bbb3SSatish Balay extern int MatMultAdd_SeqBAIJ_2(Mat,Vec,Vec,Vec);
11452d61bbb3SSatish Balay extern int MatMultAdd_SeqBAIJ_3(Mat,Vec,Vec,Vec);
11462d61bbb3SSatish Balay extern int MatMultAdd_SeqBAIJ_4(Mat,Vec,Vec,Vec);
11472d61bbb3SSatish Balay extern int MatMultAdd_SeqBAIJ_5(Mat,Vec,Vec,Vec);
114815091d37SBarry Smith extern int MatMultAdd_SeqBAIJ_6(Mat,Vec,Vec,Vec);
11492d61bbb3SSatish Balay extern int MatMultAdd_SeqBAIJ_7(Mat,Vec,Vec,Vec);
11502d61bbb3SSatish Balay extern int MatMultAdd_SeqBAIJ_N(Mat,Vec,Vec,Vec);
11512d61bbb3SSatish Balay 
11522d61bbb3SSatish Balay #undef __FUNC__
11532d61bbb3SSatish Balay #define __FUNC__ "MatILUFactor_SeqBAIJ"
11545ef9f2a5SBarry Smith int MatILUFactor_SeqBAIJ(Mat inA,IS row,IS col,MatILUInfo *info)
11552d61bbb3SSatish Balay {
11562d61bbb3SSatish Balay   Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)inA->data;
11572d61bbb3SSatish Balay   Mat         outA;
11582d61bbb3SSatish Balay   int         ierr;
1159667159a5SBarry Smith   PetscTruth  row_identity,col_identity;
11602d61bbb3SSatish Balay 
11612d61bbb3SSatish Balay   PetscFunctionBegin;
1162b6d21a55SBarry Smith   if (info && info->levels != 0) SETERRQ(PETSC_ERR_SUP,0,"Only levels = 0 supported for in-place ILU");
1163667159a5SBarry Smith   ierr = ISIdentity(row,&row_identity);CHKERRQ(ierr);
1164667159a5SBarry Smith   ierr = ISIdentity(col,&col_identity);CHKERRQ(ierr);
1165667159a5SBarry Smith   if (!row_identity || !col_identity) {
1166b008c796SBarry Smith     SETERRQ(1,1,"Row and column permutations must be identity for in-place ILU");
1167667159a5SBarry Smith   }
11682d61bbb3SSatish Balay 
11692d61bbb3SSatish Balay   outA          = inA;
11702d61bbb3SSatish Balay   inA->factor   = FACTOR_LU;
11712d61bbb3SSatish Balay 
11722d61bbb3SSatish Balay   if (!a->diag) {
1173c4992f7dSBarry Smith     ierr = MatMarkDiagonal_SeqBAIJ(inA);CHKERRQ(ierr);
11742d61bbb3SSatish Balay   }
11752d61bbb3SSatish Balay   /*
117615091d37SBarry Smith       Blocksize 2, 3, 4, 5, 6 and 7 have a special faster factorization/solver
117715091d37SBarry Smith       for ILU(0) factorization with natural ordering
11782d61bbb3SSatish Balay   */
117915091d37SBarry Smith   switch (a->bs) {
1180f1af5d2fSBarry Smith   case 1:
11817c922b88SBarry Smith     inA->ops->solvetranspose   = MatSolveTranspose_SeqBAIJ_2_NaturalOrdering;
1182f1af5d2fSBarry Smith     PLogInfo(inA,"MatILUFactor_SeqBAIJ:Using special in-place natural ordering solvetrans BS=1\n");
118315091d37SBarry Smith   case 2:
118415091d37SBarry Smith     inA->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_2_NaturalOrdering;
118515091d37SBarry Smith     inA->ops->solve           = MatSolve_SeqBAIJ_2_NaturalOrdering;
11867c922b88SBarry Smith     inA->ops->solvetranspose  = MatSolveTranspose_SeqBAIJ_2_NaturalOrdering;
118715091d37SBarry Smith     PLogInfo(inA,"MatILUFactor_SeqBAIJ:Using special in-place natural ordering factor and solve BS=2\n");
118815091d37SBarry Smith     break;
118915091d37SBarry Smith   case 3:
119015091d37SBarry Smith     inA->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_3_NaturalOrdering;
119115091d37SBarry Smith     inA->ops->solve           = MatSolve_SeqBAIJ_3_NaturalOrdering;
11927c922b88SBarry Smith     inA->ops->solvetranspose  = MatSolveTranspose_SeqBAIJ_3_NaturalOrdering;
119315091d37SBarry Smith     PLogInfo(inA,"MatILUFactor_SeqBAIJ:Using special in-place natural ordering factor and solve BS=3\n");
119415091d37SBarry Smith     break;
119515091d37SBarry Smith   case 4:
1196667159a5SBarry Smith     inA->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_4_NaturalOrdering;
1197f830108cSBarry Smith     inA->ops->solve           = MatSolve_SeqBAIJ_4_NaturalOrdering;
11987c922b88SBarry Smith     inA->ops->solvetranspose  = MatSolveTranspose_SeqBAIJ_4_NaturalOrdering;
119915091d37SBarry Smith     PLogInfo(inA,"MatILUFactor_SeqBAIJ:Using special in-place natural ordering factor and solve BS=4\n");
120015091d37SBarry Smith     break;
120115091d37SBarry Smith   case 5:
1202667159a5SBarry Smith     inA->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_5_NaturalOrdering;
1203667159a5SBarry Smith     inA->ops->solve           = MatSolve_SeqBAIJ_5_NaturalOrdering;
12047c922b88SBarry Smith     inA->ops->solvetranspose  = MatSolveTranspose_SeqBAIJ_5_NaturalOrdering;
120515091d37SBarry Smith     PLogInfo(inA,"MatILUFactor_SeqBAIJ:Using special in-place natural ordering factor and solve BS=5\n");
120615091d37SBarry Smith     break;
120715091d37SBarry Smith   case 6:
120815091d37SBarry Smith     inA->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_6_NaturalOrdering;
120915091d37SBarry Smith     inA->ops->solve           = MatSolve_SeqBAIJ_6_NaturalOrdering;
12107c922b88SBarry Smith     inA->ops->solvetranspose  = MatSolveTranspose_SeqBAIJ_6_NaturalOrdering;
121115091d37SBarry Smith     PLogInfo(inA,"MatILUFactor_SeqBAIJ:Using special in-place natural ordering factor and solve BS=6\n");
121215091d37SBarry Smith     break;
121315091d37SBarry Smith   case 7:
121415091d37SBarry Smith     inA->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_7_NaturalOrdering;
12157c922b88SBarry Smith     inA->ops->solvetranspose  = MatSolveTranspose_SeqBAIJ_7_NaturalOrdering;
121615091d37SBarry Smith     inA->ops->solve           = MatSolve_SeqBAIJ_7_NaturalOrdering;
121715091d37SBarry Smith     PLogInfo(inA,"MatILUFactor_SeqBAIJ:Using special in-place natural ordering factor and solve BS=7\n");
121815091d37SBarry Smith     break;
1219c38d4ed2SBarry Smith   default:
1220c38d4ed2SBarry Smith     a->row        = row;
1221c38d4ed2SBarry Smith     a->col        = col;
1222c38d4ed2SBarry Smith     ierr          = PetscObjectReference((PetscObject)row);CHKERRQ(ierr);
1223c38d4ed2SBarry Smith     ierr          = PetscObjectReference((PetscObject)col);CHKERRQ(ierr);
1224c38d4ed2SBarry Smith 
1225c38d4ed2SBarry Smith     /* Create the invert permutation so that it can be used in MatLUFactorNumeric() */
1226*4c49b128SBarry Smith     ierr = ISInvertPermutation(col,PETSC_DECIDE,&a->icol);CHKERRQ(ierr);
1227c38d4ed2SBarry Smith     PLogObjectParent(inA,a->icol);
1228c38d4ed2SBarry Smith 
1229c38d4ed2SBarry Smith     if (!a->solve_work) {
1230c38d4ed2SBarry Smith       a->solve_work = (Scalar*)PetscMalloc((a->m+a->bs)*sizeof(Scalar));CHKPTRQ(a->solve_work);
1231c38d4ed2SBarry Smith       PLogObjectMemory(inA,(a->m+a->bs)*sizeof(Scalar));
1232c38d4ed2SBarry Smith     }
12332d61bbb3SSatish Balay   }
12342d61bbb3SSatish Balay 
1235667159a5SBarry Smith   ierr = MatLUFactorNumeric(inA,&outA);CHKERRQ(ierr);
1236667159a5SBarry Smith 
12372d61bbb3SSatish Balay   PetscFunctionReturn(0);
12382d61bbb3SSatish Balay }
12392d61bbb3SSatish Balay #undef __FUNC__
1240d4bb536fSBarry Smith #define __FUNC__ "MatPrintHelp_SeqBAIJ"
1241ba4ca20aSSatish Balay int MatPrintHelp_SeqBAIJ(Mat A)
1242ba4ca20aSSatish Balay {
1243c38d4ed2SBarry Smith   static PetscTruth called = PETSC_FALSE;
1244ba4ca20aSSatish Balay   MPI_Comm          comm = A->comm;
1245d132466eSBarry Smith   int               ierr;
1246ba4ca20aSSatish Balay 
12473a40ed3dSBarry Smith   PetscFunctionBegin;
1248c38d4ed2SBarry Smith   if (called) {PetscFunctionReturn(0);} else called = PETSC_TRUE;
1249d132466eSBarry Smith   ierr = (*PetscHelpPrintf)(comm," Options for MATSEQBAIJ and MATMPIBAIJ matrix formats (the defaults):\n");CHKERRQ(ierr);
1250d132466eSBarry Smith   ierr = (*PetscHelpPrintf)(comm,"  -mat_block_size <block_size>\n");CHKERRQ(ierr);
12513a40ed3dSBarry Smith   PetscFunctionReturn(0);
1252ba4ca20aSSatish Balay }
1253d9b7c43dSSatish Balay 
1254fb2e594dSBarry Smith EXTERN_C_BEGIN
125527a8da17SBarry Smith #undef __FUNC__
125627a8da17SBarry Smith #define __FUNC__ "MatSeqBAIJSetColumnIndices_SeqBAIJ"
125727a8da17SBarry Smith int MatSeqBAIJSetColumnIndices_SeqBAIJ(Mat mat,int *indices)
125827a8da17SBarry Smith {
125927a8da17SBarry Smith   Mat_SeqBAIJ *baij = (Mat_SeqBAIJ *)mat->data;
126027a8da17SBarry Smith   int         i,nz,n;
126127a8da17SBarry Smith 
126227a8da17SBarry Smith   PetscFunctionBegin;
126327a8da17SBarry Smith   nz = baij->maxnz;
126427a8da17SBarry Smith   n  = baij->n;
126527a8da17SBarry Smith   for (i=0; i<nz; i++) {
126627a8da17SBarry Smith     baij->j[i] = indices[i];
126727a8da17SBarry Smith   }
126827a8da17SBarry Smith   baij->nz = nz;
126927a8da17SBarry Smith   for (i=0; i<n; i++) {
127027a8da17SBarry Smith     baij->ilen[i] = baij->imax[i];
127127a8da17SBarry Smith   }
127227a8da17SBarry Smith 
127327a8da17SBarry Smith   PetscFunctionReturn(0);
127427a8da17SBarry Smith }
1275fb2e594dSBarry Smith EXTERN_C_END
127627a8da17SBarry Smith 
127727a8da17SBarry Smith #undef __FUNC__
127827a8da17SBarry Smith #define __FUNC__ "MatSeqBAIJSetColumnIndices"
127927a8da17SBarry Smith /*@
128027a8da17SBarry Smith     MatSeqBAIJSetColumnIndices - Set the column indices for all the rows
128127a8da17SBarry Smith        in the matrix.
128227a8da17SBarry Smith 
128327a8da17SBarry Smith   Input Parameters:
128427a8da17SBarry Smith +  mat - the SeqBAIJ matrix
128527a8da17SBarry Smith -  indices - the column indices
128627a8da17SBarry Smith 
128715091d37SBarry Smith   Level: advanced
128815091d37SBarry Smith 
128927a8da17SBarry Smith   Notes:
129027a8da17SBarry Smith     This can be called if you have precomputed the nonzero structure of the
129127a8da17SBarry Smith   matrix and want to provide it to the matrix object to improve the performance
129227a8da17SBarry Smith   of the MatSetValues() operation.
129327a8da17SBarry Smith 
129427a8da17SBarry Smith     You MUST have set the correct numbers of nonzeros per row in the call to
129527a8da17SBarry Smith   MatCreateSeqBAIJ().
129627a8da17SBarry Smith 
129727a8da17SBarry Smith     MUST be called before any calls to MatSetValues();
129827a8da17SBarry Smith 
129927a8da17SBarry Smith @*/
130027a8da17SBarry Smith int MatSeqBAIJSetColumnIndices(Mat mat,int *indices)
130127a8da17SBarry Smith {
130227a8da17SBarry Smith   int ierr,(*f)(Mat,int *);
130327a8da17SBarry Smith 
130427a8da17SBarry Smith   PetscFunctionBegin;
130527a8da17SBarry Smith   PetscValidHeaderSpecific(mat,MAT_COOKIE);
1306549d3d68SSatish Balay   ierr = PetscObjectQueryFunction((PetscObject)mat,"MatSeqBAIJSetColumnIndices_C",(void **)&f);CHKERRQ(ierr);
130727a8da17SBarry Smith   if (f) {
130827a8da17SBarry Smith     ierr = (*f)(mat,indices);CHKERRQ(ierr);
130927a8da17SBarry Smith   } else {
131027a8da17SBarry Smith     SETERRQ(1,1,"Wrong type of matrix to set column indices");
131127a8da17SBarry Smith   }
131227a8da17SBarry Smith   PetscFunctionReturn(0);
131327a8da17SBarry Smith }
131427a8da17SBarry Smith 
13152593348eSBarry Smith /* -------------------------------------------------------------------*/
1316cc2dc46cSBarry Smith static struct _MatOps MatOps_Values = {MatSetValues_SeqBAIJ,
1317cc2dc46cSBarry Smith        MatGetRow_SeqBAIJ,
1318cc2dc46cSBarry Smith        MatRestoreRow_SeqBAIJ,
1319cc2dc46cSBarry Smith        MatMult_SeqBAIJ_N,
1320cc2dc46cSBarry Smith        MatMultAdd_SeqBAIJ_N,
13217c922b88SBarry Smith        MatMultTranspose_SeqBAIJ,
13227c922b88SBarry Smith        MatMultTransposeAdd_SeqBAIJ,
1323cc2dc46cSBarry Smith        MatSolve_SeqBAIJ_N,
1324cc2dc46cSBarry Smith        0,
1325cc2dc46cSBarry Smith        0,
1326cc2dc46cSBarry Smith        0,
1327cc2dc46cSBarry Smith        MatLUFactor_SeqBAIJ,
1328cc2dc46cSBarry Smith        0,
1329b6490206SBarry Smith        0,
1330f2501298SSatish Balay        MatTranspose_SeqBAIJ,
1331cc2dc46cSBarry Smith        MatGetInfo_SeqBAIJ,
1332cc2dc46cSBarry Smith        MatEqual_SeqBAIJ,
1333cc2dc46cSBarry Smith        MatGetDiagonal_SeqBAIJ,
1334cc2dc46cSBarry Smith        MatDiagonalScale_SeqBAIJ,
1335cc2dc46cSBarry Smith        MatNorm_SeqBAIJ,
1336b6490206SBarry Smith        0,
1337cc2dc46cSBarry Smith        MatAssemblyEnd_SeqBAIJ,
1338cc2dc46cSBarry Smith        0,
1339cc2dc46cSBarry Smith        MatSetOption_SeqBAIJ,
1340cc2dc46cSBarry Smith        MatZeroEntries_SeqBAIJ,
1341cc2dc46cSBarry Smith        MatZeroRows_SeqBAIJ,
1342cc2dc46cSBarry Smith        MatLUFactorSymbolic_SeqBAIJ,
1343cc2dc46cSBarry Smith        MatLUFactorNumeric_SeqBAIJ_N,
1344cc2dc46cSBarry Smith        0,
1345cc2dc46cSBarry Smith        0,
1346cc2dc46cSBarry Smith        MatGetSize_SeqBAIJ,
1347cc2dc46cSBarry Smith        MatGetSize_SeqBAIJ,
1348cc2dc46cSBarry Smith        MatGetOwnershipRange_SeqBAIJ,
1349cc2dc46cSBarry Smith        MatILUFactorSymbolic_SeqBAIJ,
1350cc2dc46cSBarry Smith        0,
1351cc2dc46cSBarry Smith        0,
1352cc2dc46cSBarry Smith        0,
13532e8a6d31SBarry Smith        MatDuplicate_SeqBAIJ,
1354cc2dc46cSBarry Smith        0,
1355cc2dc46cSBarry Smith        0,
1356cc2dc46cSBarry Smith        MatILUFactor_SeqBAIJ,
1357cc2dc46cSBarry Smith        0,
1358cc2dc46cSBarry Smith        0,
1359cc2dc46cSBarry Smith        MatGetSubMatrices_SeqBAIJ,
1360cc2dc46cSBarry Smith        MatIncreaseOverlap_SeqBAIJ,
1361cc2dc46cSBarry Smith        MatGetValues_SeqBAIJ,
1362cc2dc46cSBarry Smith        0,
1363cc2dc46cSBarry Smith        MatPrintHelp_SeqBAIJ,
1364cc2dc46cSBarry Smith        MatScale_SeqBAIJ,
1365cc2dc46cSBarry Smith        0,
1366cc2dc46cSBarry Smith        0,
1367cc2dc46cSBarry Smith        0,
1368cc2dc46cSBarry Smith        MatGetBlockSize_SeqBAIJ,
13693b2fbd54SBarry Smith        MatGetRowIJ_SeqBAIJ,
137092c4ed94SBarry Smith        MatRestoreRowIJ_SeqBAIJ,
1371cc2dc46cSBarry Smith        0,
1372cc2dc46cSBarry Smith        0,
1373cc2dc46cSBarry Smith        0,
1374cc2dc46cSBarry Smith        0,
1375cc2dc46cSBarry Smith        0,
1376cc2dc46cSBarry Smith        0,
1377d3825aa8SBarry Smith        MatSetValuesBlocked_SeqBAIJ,
1378cc2dc46cSBarry Smith        MatGetSubMatrix_SeqBAIJ,
1379cc2dc46cSBarry Smith        0,
1380cc2dc46cSBarry Smith        0,
1381cc2dc46cSBarry Smith        MatGetMaps_Petsc};
13822593348eSBarry Smith 
13833e90b805SBarry Smith EXTERN_C_BEGIN
13843e90b805SBarry Smith #undef __FUNC__
13853e90b805SBarry Smith #define __FUNC__ "MatStoreValues_SeqBAIJ"
13863e90b805SBarry Smith int MatStoreValues_SeqBAIJ(Mat mat)
13873e90b805SBarry Smith {
13883e90b805SBarry Smith   Mat_SeqBAIJ *aij = (Mat_SeqBAIJ *)mat->data;
13893e90b805SBarry Smith   int         nz = aij->i[aij->m]*aij->bs*aij->bs2;
1390d132466eSBarry Smith   int         ierr;
13913e90b805SBarry Smith 
13923e90b805SBarry Smith   PetscFunctionBegin;
13933e90b805SBarry Smith   if (aij->nonew != 1) {
13943e90b805SBarry Smith     SETERRQ(1,1,"Must call MatSetOption(A,MAT_NO_NEW_NONZERO_LOCATIONS);first");
13953e90b805SBarry Smith   }
13963e90b805SBarry Smith 
13973e90b805SBarry Smith   /* allocate space for values if not already there */
13983e90b805SBarry Smith   if (!aij->saved_values) {
13993e90b805SBarry Smith     aij->saved_values = (Scalar*)PetscMalloc(nz*sizeof(Scalar));CHKPTRQ(aij->saved_values);
14003e90b805SBarry Smith   }
14013e90b805SBarry Smith 
14023e90b805SBarry Smith   /* copy values over */
1403d132466eSBarry Smith   ierr = PetscMemcpy(aij->saved_values,aij->a,nz*sizeof(Scalar));CHKERRQ(ierr);
14043e90b805SBarry Smith   PetscFunctionReturn(0);
14053e90b805SBarry Smith }
14063e90b805SBarry Smith EXTERN_C_END
14073e90b805SBarry Smith 
14083e90b805SBarry Smith EXTERN_C_BEGIN
14093e90b805SBarry Smith #undef __FUNC__
141032e87ba3SBarry Smith #define __FUNC__ "MatRetrieveValues_SeqBAIJ"
141132e87ba3SBarry Smith int MatRetrieveValues_SeqBAIJ(Mat mat)
14123e90b805SBarry Smith {
14133e90b805SBarry Smith   Mat_SeqBAIJ *aij = (Mat_SeqBAIJ *)mat->data;
1414549d3d68SSatish Balay   int         nz = aij->i[aij->m]*aij->bs*aij->bs2,ierr;
14153e90b805SBarry Smith 
14163e90b805SBarry Smith   PetscFunctionBegin;
14173e90b805SBarry Smith   if (aij->nonew != 1) {
14183e90b805SBarry Smith     SETERRQ(1,1,"Must call MatSetOption(A,MAT_NO_NEW_NONZERO_LOCATIONS);first");
14193e90b805SBarry Smith   }
14203e90b805SBarry Smith   if (!aij->saved_values) {
14213e90b805SBarry Smith     SETERRQ(1,1,"Must call MatStoreValues(A);first");
14223e90b805SBarry Smith   }
14233e90b805SBarry Smith 
14243e90b805SBarry Smith   /* copy values over */
1425549d3d68SSatish Balay   ierr = PetscMemcpy(aij->a,aij->saved_values,nz*sizeof(Scalar));CHKERRQ(ierr);
14263e90b805SBarry Smith   PetscFunctionReturn(0);
14273e90b805SBarry Smith }
14283e90b805SBarry Smith EXTERN_C_END
14293e90b805SBarry Smith 
14305615d1e5SSatish Balay #undef __FUNC__
14315615d1e5SSatish Balay #define __FUNC__ "MatCreateSeqBAIJ"
14322593348eSBarry Smith /*@C
143344cd7ae7SLois Curfman McInnes    MatCreateSeqBAIJ - Creates a sparse matrix in block AIJ (block
143444cd7ae7SLois Curfman McInnes    compressed row) format.  For good matrix assembly performance the
143544cd7ae7SLois Curfman McInnes    user should preallocate the matrix storage by setting the parameter nz
14367fc3c18eSBarry Smith    (or the array nnz).  By setting these parameters accurately, performance
14372bd5e0b2SLois Curfman McInnes    during matrix assembly can be increased by more than a factor of 50.
14382593348eSBarry Smith 
1439db81eaa0SLois Curfman McInnes    Collective on MPI_Comm
1440db81eaa0SLois Curfman McInnes 
14412593348eSBarry Smith    Input Parameters:
1442db81eaa0SLois Curfman McInnes +  comm - MPI communicator, set to PETSC_COMM_SELF
1443b6490206SBarry Smith .  bs - size of block
14442593348eSBarry Smith .  m - number of rows
14452593348eSBarry Smith .  n - number of columns
1446b6490206SBarry Smith .  nz - number of block nonzeros per block row (same for all rows)
14477fc3c18eSBarry Smith -  nnz - array containing the number of block nonzeros in the various block rows
14482bd5e0b2SLois Curfman McInnes          (possibly different for each block row) or PETSC_NULL
14492593348eSBarry Smith 
14502593348eSBarry Smith    Output Parameter:
14512593348eSBarry Smith .  A - the matrix
14522593348eSBarry Smith 
14530513a670SBarry Smith    Options Database Keys:
1454db81eaa0SLois Curfman McInnes .   -mat_no_unroll - uses code that does not unroll the loops in the
1455db81eaa0SLois Curfman McInnes                      block calculations (much slower)
1456db81eaa0SLois Curfman McInnes .    -mat_block_size - size of the blocks to use
14570513a670SBarry Smith 
145815091d37SBarry Smith    Level: intermediate
145915091d37SBarry Smith 
14602593348eSBarry Smith    Notes:
146144cd7ae7SLois Curfman McInnes    The block AIJ format is fully compatible with standard Fortran 77
14622593348eSBarry Smith    storage.  That is, the stored row and column indices can begin at
146344cd7ae7SLois Curfman McInnes    either one (as in Fortran) or zero.  See the users' manual for details.
14642593348eSBarry Smith 
14652593348eSBarry Smith    Specify the preallocated storage with either nz or nnz (not both).
14662593348eSBarry Smith    Set nz=PETSC_DEFAULT and nnz=PETSC_NULL for PETSc to control dynamic memory
14672593348eSBarry Smith    allocation.  For additional details, see the users manual chapter on
14686da5968aSLois Curfman McInnes    matrices.
14692593348eSBarry Smith 
1470db81eaa0SLois Curfman McInnes .seealso: MatCreate(), MatCreateSeqAIJ(), MatSetValues(), MatCreateMPIBAIJ()
14712593348eSBarry Smith @*/
1472b6490206SBarry Smith int MatCreateSeqBAIJ(MPI_Comm comm,int bs,int m,int n,int nz,int *nnz,Mat *A)
14732593348eSBarry Smith {
14742593348eSBarry Smith   Mat         B;
1475b6490206SBarry Smith   Mat_SeqBAIJ *b;
1476f1af5d2fSBarry Smith   int         i,len,ierr,mbs,nbs,bs2,size;
1477f1af5d2fSBarry Smith   PetscTruth  flg;
14783b2fbd54SBarry Smith 
14793a40ed3dSBarry Smith   PetscFunctionBegin;
1480d132466eSBarry Smith   ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr);
1481a8c6a408SBarry Smith   if (size > 1) SETERRQ(PETSC_ERR_ARG_WRONG,0,"Comm must be of size 1");
1482b6490206SBarry Smith 
1483962fb4a0SBarry Smith   ierr = OptionsGetInt(PETSC_NULL,"-mat_block_size",&bs,PETSC_NULL);CHKERRQ(ierr);
1484302e33e3SBarry Smith   mbs  = m/bs;
1485302e33e3SBarry Smith   nbs  = n/bs;
1486302e33e3SBarry Smith   bs2  = bs*bs;
14870513a670SBarry Smith 
14883a40ed3dSBarry Smith   if (mbs*bs!=m || nbs*bs!=n) {
1489a8c6a408SBarry Smith     SETERRQ(PETSC_ERR_ARG_SIZ,0,"Number rows, cols must be divisible by blocksize");
14903a40ed3dSBarry Smith   }
14912593348eSBarry Smith 
1492b73539f3SBarry Smith   if (nz < -2) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,0,"nz cannot be less than -2: value %d",nz);
1493b73539f3SBarry Smith   if (nnz) {
1494faf3f1fcSBarry Smith     for (i=0; i<mbs; i++) {
1495b73539f3SBarry 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]);
1496b73539f3SBarry Smith     }
1497b73539f3SBarry Smith   }
1498b73539f3SBarry Smith 
14992593348eSBarry Smith   *A = 0;
15003f1db9ecSBarry Smith   PetscHeaderCreate(B,_p_Mat,struct _MatOps,MAT_COOKIE,MATSEQBAIJ,"Mat",comm,MatDestroy,MatView);
15012593348eSBarry Smith   PLogObjectCreate(B);
1502b6490206SBarry Smith   B->data = (void*)(b = PetscNew(Mat_SeqBAIJ));CHKPTRQ(b);
1503549d3d68SSatish Balay   ierr    = PetscMemzero(b,sizeof(Mat_SeqBAIJ));CHKERRQ(ierr);
1504549d3d68SSatish Balay   ierr    = PetscMemcpy(B->ops,&MatOps_Values,sizeof(struct _MatOps));CHKERRQ(ierr);
15051a6a6d98SBarry Smith   ierr    = OptionsHasName(PETSC_NULL,"-mat_no_unroll",&flg);CHKERRQ(ierr);
15061a6a6d98SBarry Smith   if (!flg) {
15077fc0212eSBarry Smith     switch (bs) {
15087fc0212eSBarry Smith     case 1:
1509f830108cSBarry Smith       B->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_1;
1510f830108cSBarry Smith       B->ops->solve           = MatSolve_SeqBAIJ_1;
15117c922b88SBarry Smith       B->ops->solvetranspose  = MatSolveTranspose_SeqBAIJ_1;
1512f830108cSBarry Smith       B->ops->mult            = MatMult_SeqBAIJ_1;
1513f830108cSBarry Smith       B->ops->multadd         = MatMultAdd_SeqBAIJ_1;
15147fc0212eSBarry Smith       break;
15154eeb42bcSBarry Smith     case 2:
1516f830108cSBarry Smith       B->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_2;
1517f830108cSBarry Smith       B->ops->solve           = MatSolve_SeqBAIJ_2;
15187c922b88SBarry Smith       B->ops->solvetranspose  = MatSolveTranspose_SeqBAIJ_2;
1519f830108cSBarry Smith       B->ops->mult            = MatMult_SeqBAIJ_2;
1520f830108cSBarry Smith       B->ops->multadd         = MatMultAdd_SeqBAIJ_2;
15216d84be18SBarry Smith       break;
1522f327dd97SBarry Smith     case 3:
1523f830108cSBarry Smith       B->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_3;
1524f830108cSBarry Smith       B->ops->solve           = MatSolve_SeqBAIJ_3;
15257c922b88SBarry Smith       B->ops->solvetranspose  = MatSolveTranspose_SeqBAIJ_3;
1526f830108cSBarry Smith       B->ops->mult            = MatMult_SeqBAIJ_3;
1527f830108cSBarry Smith       B->ops->multadd         = MatMultAdd_SeqBAIJ_3;
15284eeb42bcSBarry Smith       break;
15296d84be18SBarry Smith     case 4:
1530f830108cSBarry Smith       B->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_4;
1531f830108cSBarry Smith       B->ops->solve           = MatSolve_SeqBAIJ_4;
15327c922b88SBarry Smith       B->ops->solvetranspose  = MatSolveTranspose_SeqBAIJ_4;
1533f830108cSBarry Smith       B->ops->mult            = MatMult_SeqBAIJ_4;
1534f830108cSBarry Smith       B->ops->multadd         = MatMultAdd_SeqBAIJ_4;
15356d84be18SBarry Smith       break;
15366d84be18SBarry Smith     case 5:
1537f830108cSBarry Smith       B->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_5;
1538f830108cSBarry Smith       B->ops->solve           = MatSolve_SeqBAIJ_5;
15397c922b88SBarry Smith       B->ops->solvetranspose  = MatSolveTranspose_SeqBAIJ_5;
1540f830108cSBarry Smith       B->ops->mult            = MatMult_SeqBAIJ_5;
1541f830108cSBarry Smith       B->ops->multadd         = MatMultAdd_SeqBAIJ_5;
15426d84be18SBarry Smith       break;
154315091d37SBarry Smith     case 6:
154415091d37SBarry Smith       B->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_6;
154515091d37SBarry Smith       B->ops->solve           = MatSolve_SeqBAIJ_6;
15467c922b88SBarry Smith       B->ops->solvetranspose  = MatSolveTranspose_SeqBAIJ_6;
154715091d37SBarry Smith       B->ops->mult            = MatMult_SeqBAIJ_6;
154815091d37SBarry Smith       B->ops->multadd         = MatMultAdd_SeqBAIJ_6;
154915091d37SBarry Smith       break;
155048e9ddb2SSatish Balay     case 7:
1551f830108cSBarry Smith       B->ops->mult            = MatMult_SeqBAIJ_7;
1552f830108cSBarry Smith       B->ops->solve           = MatSolve_SeqBAIJ_7;
15537c922b88SBarry Smith       B->ops->solvetranspose  = MatSolveTranspose_SeqBAIJ_7;
1554f830108cSBarry Smith       B->ops->multadd         = MatMultAdd_SeqBAIJ_7;
155548e9ddb2SSatish Balay       break;
15567fc0212eSBarry Smith     }
15571a6a6d98SBarry Smith   }
1558e1311b90SBarry Smith   B->ops->destroy     = MatDestroy_SeqBAIJ;
1559e1311b90SBarry Smith   B->ops->view        = MatView_SeqBAIJ;
15602593348eSBarry Smith   B->factor           = 0;
15612593348eSBarry Smith   B->lupivotthreshold = 1.0;
156290f02eecSBarry Smith   B->mapping          = 0;
15632593348eSBarry Smith   b->row              = 0;
15642593348eSBarry Smith   b->col              = 0;
1565e51c0b9cSSatish Balay   b->icol             = 0;
15662593348eSBarry Smith   b->reallocs         = 0;
15673e90b805SBarry Smith   b->saved_values     = 0;
15682593348eSBarry Smith 
156944cd7ae7SLois Curfman McInnes   b->m       = m; B->m = m; B->M = m;
157044cd7ae7SLois Curfman McInnes   b->n       = n; B->n = n; B->N = n;
1571a5ae1ecdSBarry Smith 
15727413bad6SBarry Smith   ierr = MapCreateMPI(comm,m,m,&B->rmap);CHKERRQ(ierr);
15737413bad6SBarry Smith   ierr = MapCreateMPI(comm,n,n,&B->cmap);CHKERRQ(ierr);
1574a5ae1ecdSBarry Smith 
1575b6490206SBarry Smith   b->mbs     = mbs;
1576f2501298SSatish Balay   b->nbs     = nbs;
1577b6490206SBarry Smith   b->imax    = (int*)PetscMalloc((mbs+1)*sizeof(int));CHKPTRQ(b->imax);
1578c4992f7dSBarry Smith   if (!nnz) {
1579119a934aSSatish Balay     if (nz == PETSC_DEFAULT) nz = 5;
15802593348eSBarry Smith     else if (nz <= 0)        nz = 1;
1581b6490206SBarry Smith     for (i=0; i<mbs; i++) b->imax[i] = nz;
1582b6490206SBarry Smith     nz = nz*mbs;
15833a40ed3dSBarry Smith   } else {
15842593348eSBarry Smith     nz = 0;
1585b6490206SBarry Smith     for (i=0; i<mbs; i++) {b->imax[i] = nnz[i]; nz += nnz[i];}
15862593348eSBarry Smith   }
15872593348eSBarry Smith 
15882593348eSBarry Smith   /* allocate the matrix space */
15893f1db9ecSBarry Smith   len   = nz*sizeof(int) + nz*bs2*sizeof(MatScalar) + (b->m+1)*sizeof(int);
15903f1db9ecSBarry Smith   b->a  = (MatScalar*)PetscMalloc(len);CHKPTRQ(b->a);
1591549d3d68SSatish Balay   ierr = PetscMemzero(b->a,nz*bs2*sizeof(MatScalar));CHKERRQ(ierr);
15927e67e3f9SSatish Balay   b->j  = (int*)(b->a + nz*bs2);
1593549d3d68SSatish Balay   ierr = PetscMemzero(b->j,nz*sizeof(int));CHKERRQ(ierr);
15942593348eSBarry Smith   b->i  = b->j + nz;
1595c4992f7dSBarry Smith   b->singlemalloc = PETSC_TRUE;
15962593348eSBarry Smith 
1597de6a44a3SBarry Smith   b->i[0] = 0;
1598b6490206SBarry Smith   for (i=1; i<mbs+1; i++) {
15992593348eSBarry Smith     b->i[i] = b->i[i-1] + b->imax[i-1];
16002593348eSBarry Smith   }
16012593348eSBarry Smith 
1602b6490206SBarry Smith   /* b->ilen will count nonzeros in each block row so far. */
1603b6490206SBarry Smith   b->ilen = (int*)PetscMalloc((mbs+1)*sizeof(int));
1604f09e8eb9SSatish Balay   PLogObjectMemory(B,len+2*(mbs+1)*sizeof(int)+sizeof(struct _p_Mat)+sizeof(Mat_SeqBAIJ));
1605b6490206SBarry Smith   for (i=0; i<mbs; i++) { b->ilen[i] = 0;}
16062593348eSBarry Smith 
1607b6490206SBarry Smith   b->bs               = bs;
16089df24120SSatish Balay   b->bs2              = bs2;
1609b6490206SBarry Smith   b->mbs              = mbs;
16102593348eSBarry Smith   b->nz               = 0;
161118e7b8e4SLois Curfman McInnes   b->maxnz            = nz*bs2;
1612c4992f7dSBarry Smith   b->sorted           = PETSC_FALSE;
1613c4992f7dSBarry Smith   b->roworiented      = PETSC_TRUE;
16142593348eSBarry Smith   b->nonew            = 0;
16152593348eSBarry Smith   b->diag             = 0;
16162593348eSBarry Smith   b->solve_work       = 0;
1617de6a44a3SBarry Smith   b->mult_work        = 0;
16182593348eSBarry Smith   b->spptr            = 0;
16190e6d2581SBarry Smith   B->info.nz_unneeded = (PetscReal)b->maxnz;
1620883fce79SBarry Smith   b->keepzeroedrows   = PETSC_FALSE;
16214e220ebcSLois Curfman McInnes 
16222593348eSBarry Smith   *A = B;
16232593348eSBarry Smith   ierr = OptionsHasName(PETSC_NULL,"-help",&flg);CHKERRQ(ierr);
16242593348eSBarry Smith   if (flg) {ierr = MatPrintHelp(B);CHKERRQ(ierr); }
162527a8da17SBarry Smith 
1626f1af5d2fSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatStoreValues_C",
16273e90b805SBarry Smith                                      "MatStoreValues_SeqBAIJ",
16283e90b805SBarry Smith                                      (void*)MatStoreValues_SeqBAIJ);CHKERRQ(ierr);
1629f1af5d2fSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatRetrieveValues_C",
16303e90b805SBarry Smith                                      "MatRetrieveValues_SeqBAIJ",
16313e90b805SBarry Smith                                      (void*)MatRetrieveValues_SeqBAIJ);CHKERRQ(ierr);
1632f1af5d2fSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatSeqBAIJSetColumnIndices_C",
163327a8da17SBarry Smith                                      "MatSeqBAIJSetColumnIndices_SeqBAIJ",
163427a8da17SBarry Smith                                      (void*)MatSeqBAIJSetColumnIndices_SeqBAIJ);CHKERRQ(ierr);
16353a40ed3dSBarry Smith   PetscFunctionReturn(0);
16362593348eSBarry Smith }
16372593348eSBarry Smith 
16385615d1e5SSatish Balay #undef __FUNC__
16392e8a6d31SBarry Smith #define __FUNC__ "MatDuplicate_SeqBAIJ"
16402e8a6d31SBarry Smith int MatDuplicate_SeqBAIJ(Mat A,MatDuplicateOption cpvalues,Mat *B)
16412593348eSBarry Smith {
16422593348eSBarry Smith   Mat         C;
1643b6490206SBarry Smith   Mat_SeqBAIJ *c,*a = (Mat_SeqBAIJ*)A->data;
164427a8da17SBarry Smith   int         i,len,mbs = a->mbs,nz = a->nz,bs2 =a->bs2,ierr;
1645de6a44a3SBarry Smith 
16463a40ed3dSBarry Smith   PetscFunctionBegin;
1647a8c6a408SBarry Smith   if (a->i[mbs] != nz) SETERRQ(PETSC_ERR_PLIB,0,"Corrupt matrix");
16482593348eSBarry Smith 
16492593348eSBarry Smith   *B = 0;
16503f1db9ecSBarry Smith   PetscHeaderCreate(C,_p_Mat,struct _MatOps,MAT_COOKIE,MATSEQBAIJ,"Mat",A->comm,MatDestroy,MatView);
16512593348eSBarry Smith   PLogObjectCreate(C);
1652b6490206SBarry Smith   C->data           = (void*)(c = PetscNew(Mat_SeqBAIJ));CHKPTRQ(c);
1653549d3d68SSatish Balay   ierr              = PetscMemcpy(C->ops,A->ops,sizeof(struct _MatOps));CHKERRQ(ierr);
1654e1311b90SBarry Smith   C->ops->destroy   = MatDestroy_SeqBAIJ;
1655e1311b90SBarry Smith   C->ops->view      = MatView_SeqBAIJ;
16562593348eSBarry Smith   C->factor         = A->factor;
16572593348eSBarry Smith   c->row            = 0;
16582593348eSBarry Smith   c->col            = 0;
1659cac97260SSatish Balay   c->icol           = 0;
166032e87ba3SBarry Smith   c->saved_values   = 0;
1661f1e2ffcdSBarry Smith   c->keepzeroedrows = a->keepzeroedrows;
16622593348eSBarry Smith   C->assembled      = PETSC_TRUE;
16632593348eSBarry Smith 
166444cd7ae7SLois Curfman McInnes   c->m = C->m   = a->m;
166544cd7ae7SLois Curfman McInnes   c->n = C->n   = a->n;
166644cd7ae7SLois Curfman McInnes   C->M          = a->m;
166744cd7ae7SLois Curfman McInnes   C->N          = a->n;
166844cd7ae7SLois Curfman McInnes 
1669b6490206SBarry Smith   c->bs         = a->bs;
16709df24120SSatish Balay   c->bs2        = a->bs2;
1671b6490206SBarry Smith   c->mbs        = a->mbs;
1672b6490206SBarry Smith   c->nbs        = a->nbs;
16732593348eSBarry Smith 
1674b6490206SBarry Smith   c->imax       = (int*)PetscMalloc((mbs+1)*sizeof(int));CHKPTRQ(c->imax);
1675b6490206SBarry Smith   c->ilen       = (int*)PetscMalloc((mbs+1)*sizeof(int));CHKPTRQ(c->ilen);
1676b6490206SBarry Smith   for (i=0; i<mbs; i++) {
16772593348eSBarry Smith     c->imax[i] = a->imax[i];
16782593348eSBarry Smith     c->ilen[i] = a->ilen[i];
16792593348eSBarry Smith   }
16802593348eSBarry Smith 
16812593348eSBarry Smith   /* allocate the matrix space */
1682c4992f7dSBarry Smith   c->singlemalloc = PETSC_TRUE;
16833f1db9ecSBarry Smith   len  = (mbs+1)*sizeof(int) + nz*(bs2*sizeof(MatScalar) + sizeof(int));
16843f1db9ecSBarry Smith   c->a = (MatScalar*)PetscMalloc(len);CHKPTRQ(c->a);
16857e67e3f9SSatish Balay   c->j = (int*)(c->a + nz*bs2);
1686de6a44a3SBarry Smith   c->i = c->j + nz;
1687549d3d68SSatish Balay   ierr = PetscMemcpy(c->i,a->i,(mbs+1)*sizeof(int));CHKERRQ(ierr);
1688b6490206SBarry Smith   if (mbs > 0) {
1689549d3d68SSatish Balay     ierr = PetscMemcpy(c->j,a->j,nz*sizeof(int));CHKERRQ(ierr);
16902e8a6d31SBarry Smith     if (cpvalues == MAT_COPY_VALUES) {
1691549d3d68SSatish Balay       ierr = PetscMemcpy(c->a,a->a,bs2*nz*sizeof(MatScalar));CHKERRQ(ierr);
16922e8a6d31SBarry Smith     } else {
1693549d3d68SSatish Balay       ierr = PetscMemzero(c->a,bs2*nz*sizeof(MatScalar));CHKERRQ(ierr);
16942593348eSBarry Smith     }
16952593348eSBarry Smith   }
16962593348eSBarry Smith 
1697f09e8eb9SSatish Balay   PLogObjectMemory(C,len+2*(mbs+1)*sizeof(int)+sizeof(struct _p_Mat)+sizeof(Mat_SeqBAIJ));
16982593348eSBarry Smith   c->sorted      = a->sorted;
16992593348eSBarry Smith   c->roworiented = a->roworiented;
17002593348eSBarry Smith   c->nonew       = a->nonew;
17012593348eSBarry Smith 
17022593348eSBarry Smith   if (a->diag) {
1703b6490206SBarry Smith     c->diag = (int*)PetscMalloc((mbs+1)*sizeof(int));CHKPTRQ(c->diag);
1704b6490206SBarry Smith     PLogObjectMemory(C,(mbs+1)*sizeof(int));
1705b6490206SBarry Smith     for (i=0; i<mbs; i++) {
17062593348eSBarry Smith       c->diag[i] = a->diag[i];
17072593348eSBarry Smith     }
170898305bb5SBarry Smith   } else c->diag        = 0;
17092593348eSBarry Smith   c->nz                 = a->nz;
17102593348eSBarry Smith   c->maxnz              = a->maxnz;
17112593348eSBarry Smith   c->solve_work         = 0;
17122593348eSBarry Smith   c->spptr              = 0;      /* Dangerous -I'm throwing away a->spptr */
17137fc0212eSBarry Smith   c->mult_work          = 0;
17142593348eSBarry Smith   *B = C;
17157b2a1423SBarry Smith   ierr = FListDuplicate(A->qlist,&C->qlist);CHKERRQ(ierr);
17163a40ed3dSBarry Smith   PetscFunctionReturn(0);
17172593348eSBarry Smith }
17182593348eSBarry Smith 
17195615d1e5SSatish Balay #undef __FUNC__
17205615d1e5SSatish Balay #define __FUNC__ "MatLoad_SeqBAIJ"
172119bcc07fSBarry Smith int MatLoad_SeqBAIJ(Viewer viewer,MatType type,Mat *A)
17222593348eSBarry Smith {
1723b6490206SBarry Smith   Mat_SeqBAIJ  *a;
17242593348eSBarry Smith   Mat          B;
1725f1af5d2fSBarry Smith   int          i,nz,ierr,fd,header[4],size,*rowlengths=0,M,N,bs=1;
1726b6490206SBarry Smith   int          *mask,mbs,*jj,j,rowcount,nzcount,k,*browlengths,maskcount;
172735aab85fSBarry Smith   int          kmax,jcount,block,idx,point,nzcountb,extra_rows;
1728a7c10996SSatish Balay   int          *masked,nmask,tmp,bs2,ishift;
1729b6490206SBarry Smith   Scalar       *aa;
173019bcc07fSBarry Smith   MPI_Comm     comm = ((PetscObject)viewer)->comm;
17312593348eSBarry Smith 
17323a40ed3dSBarry Smith   PetscFunctionBegin;
1733f1af5d2fSBarry Smith   ierr = OptionsGetInt(PETSC_NULL,"-matload_block_size",&bs,PETSC_NULL);CHKERRQ(ierr);
1734de6a44a3SBarry Smith   bs2  = bs*bs;
1735b6490206SBarry Smith 
1736d132466eSBarry Smith   ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr);
1737cc0fae11SBarry Smith   if (size > 1) SETERRQ(PETSC_ERR_ARG_WRONG,0,"view must have one processor");
173890ace30eSBarry Smith   ierr = ViewerBinaryGetDescriptor(viewer,&fd);CHKERRQ(ierr);
17390752156aSBarry Smith   ierr = PetscBinaryRead(fd,header,4,PETSC_INT);CHKERRQ(ierr);
1740a8c6a408SBarry Smith   if (header[0] != MAT_COOKIE) SETERRQ(PETSC_ERR_FILE_UNEXPECTED,0,"not Mat object");
17412593348eSBarry Smith   M = header[1]; N = header[2]; nz = header[3];
17422593348eSBarry Smith 
1743d64ed03dSBarry Smith   if (header[3] < 0) {
1744a8c6a408SBarry Smith     SETERRQ(PETSC_ERR_FILE_UNEXPECTED,1,"Matrix stored in special format, cannot load as SeqBAIJ");
1745d64ed03dSBarry Smith   }
1746d64ed03dSBarry Smith 
1747a8c6a408SBarry Smith   if (M != N) SETERRQ(PETSC_ERR_SUP,0,"Can only do square matrices");
174835aab85fSBarry Smith 
174935aab85fSBarry Smith   /*
175035aab85fSBarry Smith      This code adds extra rows to make sure the number of rows is
175135aab85fSBarry Smith     divisible by the blocksize
175235aab85fSBarry Smith   */
1753b6490206SBarry Smith   mbs        = M/bs;
175435aab85fSBarry Smith   extra_rows = bs - M + bs*(mbs);
175535aab85fSBarry Smith   if (extra_rows == bs) extra_rows = 0;
175635aab85fSBarry Smith   else                  mbs++;
175735aab85fSBarry Smith   if (extra_rows) {
1758537820f0SBarry Smith     PLogInfo(0,"MatLoad_SeqBAIJ:Padding loaded matrix to match blocksize\n");
175935aab85fSBarry Smith   }
1760b6490206SBarry Smith 
17612593348eSBarry Smith   /* read in row lengths */
176235aab85fSBarry Smith   rowlengths = (int*)PetscMalloc((M+extra_rows)*sizeof(int));CHKPTRQ(rowlengths);
17630752156aSBarry Smith   ierr = PetscBinaryRead(fd,rowlengths,M,PETSC_INT);CHKERRQ(ierr);
176435aab85fSBarry Smith   for (i=0; i<extra_rows; i++) rowlengths[M+i] = 1;
17652593348eSBarry Smith 
1766b6490206SBarry Smith   /* read in column indices */
176735aab85fSBarry Smith   jj = (int*)PetscMalloc((nz+extra_rows)*sizeof(int));CHKPTRQ(jj);
17680752156aSBarry Smith   ierr = PetscBinaryRead(fd,jj,nz,PETSC_INT);CHKERRQ(ierr);
176935aab85fSBarry Smith   for (i=0; i<extra_rows; i++) jj[nz+i] = M+i;
1770b6490206SBarry Smith 
1771b6490206SBarry Smith   /* loop over row lengths determining block row lengths */
1772b6490206SBarry Smith   browlengths = (int*)PetscMalloc(mbs*sizeof(int));CHKPTRQ(browlengths);
1773549d3d68SSatish Balay   ierr        = PetscMemzero(browlengths,mbs*sizeof(int));CHKERRQ(ierr);
177435aab85fSBarry Smith   mask        = (int*)PetscMalloc(2*mbs*sizeof(int));CHKPTRQ(mask);
1775549d3d68SSatish Balay   ierr        = PetscMemzero(mask,mbs*sizeof(int));CHKERRQ(ierr);
177635aab85fSBarry Smith   masked      = mask + mbs;
1777b6490206SBarry Smith   rowcount    = 0; nzcount = 0;
1778b6490206SBarry Smith   for (i=0; i<mbs; i++) {
177935aab85fSBarry Smith     nmask = 0;
1780b6490206SBarry Smith     for (j=0; j<bs; j++) {
1781b6490206SBarry Smith       kmax = rowlengths[rowcount];
1782b6490206SBarry Smith       for (k=0; k<kmax; k++) {
178335aab85fSBarry Smith         tmp = jj[nzcount++]/bs;
178435aab85fSBarry Smith         if (!mask[tmp]) {masked[nmask++] = tmp; mask[tmp] = 1;}
1785b6490206SBarry Smith       }
1786b6490206SBarry Smith       rowcount++;
1787b6490206SBarry Smith     }
178835aab85fSBarry Smith     browlengths[i] += nmask;
178935aab85fSBarry Smith     /* zero out the mask elements we set */
179035aab85fSBarry Smith     for (j=0; j<nmask; j++) mask[masked[j]] = 0;
1791b6490206SBarry Smith   }
1792b6490206SBarry Smith 
17932593348eSBarry Smith   /* create our matrix */
17943eee16b0SBarry Smith   ierr = MatCreateSeqBAIJ(comm,bs,M+extra_rows,N+extra_rows,0,browlengths,A);CHKERRQ(ierr);
17952593348eSBarry Smith   B = *A;
1796b6490206SBarry Smith   a = (Mat_SeqBAIJ*)B->data;
17972593348eSBarry Smith 
17982593348eSBarry Smith   /* set matrix "i" values */
1799de6a44a3SBarry Smith   a->i[0] = 0;
1800b6490206SBarry Smith   for (i=1; i<= mbs; i++) {
1801b6490206SBarry Smith     a->i[i]      = a->i[i-1] + browlengths[i-1];
1802b6490206SBarry Smith     a->ilen[i-1] = browlengths[i-1];
18032593348eSBarry Smith   }
1804b6490206SBarry Smith   a->nz         = 0;
1805b6490206SBarry Smith   for (i=0; i<mbs; i++) a->nz += browlengths[i];
18062593348eSBarry Smith 
1807b6490206SBarry Smith   /* read in nonzero values */
180835aab85fSBarry Smith   aa = (Scalar*)PetscMalloc((nz+extra_rows)*sizeof(Scalar));CHKPTRQ(aa);
18090752156aSBarry Smith   ierr = PetscBinaryRead(fd,aa,nz,PETSC_SCALAR);CHKERRQ(ierr);
181035aab85fSBarry Smith   for (i=0; i<extra_rows; i++) aa[nz+i] = 1.0;
1811b6490206SBarry Smith 
1812b6490206SBarry Smith   /* set "a" and "j" values into matrix */
1813b6490206SBarry Smith   nzcount = 0; jcount = 0;
1814b6490206SBarry Smith   for (i=0; i<mbs; i++) {
1815b6490206SBarry Smith     nzcountb = nzcount;
181635aab85fSBarry Smith     nmask    = 0;
1817b6490206SBarry Smith     for (j=0; j<bs; j++) {
1818b6490206SBarry Smith       kmax = rowlengths[i*bs+j];
1819b6490206SBarry Smith       for (k=0; k<kmax; k++) {
182035aab85fSBarry Smith         tmp = jj[nzcount++]/bs;
182135aab85fSBarry Smith 	if (!mask[tmp]) { masked[nmask++] = tmp; mask[tmp] = 1;}
1822b6490206SBarry Smith       }
1823b6490206SBarry Smith       rowcount++;
1824b6490206SBarry Smith     }
1825de6a44a3SBarry Smith     /* sort the masked values */
1826433994e6SBarry Smith     ierr = PetscSortInt(nmask,masked);CHKERRQ(ierr);
1827de6a44a3SBarry Smith 
1828b6490206SBarry Smith     /* set "j" values into matrix */
1829b6490206SBarry Smith     maskcount = 1;
183035aab85fSBarry Smith     for (j=0; j<nmask; j++) {
183135aab85fSBarry Smith       a->j[jcount++]  = masked[j];
1832de6a44a3SBarry Smith       mask[masked[j]] = maskcount++;
1833b6490206SBarry Smith     }
1834b6490206SBarry Smith     /* set "a" values into matrix */
1835de6a44a3SBarry Smith     ishift = bs2*a->i[i];
1836b6490206SBarry Smith     for (j=0; j<bs; j++) {
1837b6490206SBarry Smith       kmax = rowlengths[i*bs+j];
1838b6490206SBarry Smith       for (k=0; k<kmax; k++) {
1839de6a44a3SBarry Smith         tmp       = jj[nzcountb]/bs ;
1840de6a44a3SBarry Smith         block     = mask[tmp] - 1;
1841de6a44a3SBarry Smith         point     = jj[nzcountb] - bs*tmp;
1842de6a44a3SBarry Smith         idx       = ishift + bs2*block + j + bs*point;
1843b6490206SBarry Smith         a->a[idx] = aa[nzcountb++];
1844b6490206SBarry Smith       }
1845b6490206SBarry Smith     }
184635aab85fSBarry Smith     /* zero out the mask elements we set */
184735aab85fSBarry Smith     for (j=0; j<nmask; j++) mask[masked[j]] = 0;
1848b6490206SBarry Smith   }
1849a8c6a408SBarry Smith   if (jcount != a->nz) SETERRQ(PETSC_ERR_FILE_UNEXPECTED,0,"Bad binary matrix");
1850b6490206SBarry Smith 
1851606d414cSSatish Balay   ierr = PetscFree(rowlengths);CHKERRQ(ierr);
1852606d414cSSatish Balay   ierr = PetscFree(browlengths);CHKERRQ(ierr);
1853606d414cSSatish Balay   ierr = PetscFree(aa);CHKERRQ(ierr);
1854606d414cSSatish Balay   ierr = PetscFree(jj);CHKERRQ(ierr);
1855606d414cSSatish Balay   ierr = PetscFree(mask);CHKERRQ(ierr);
1856b6490206SBarry Smith 
1857b6490206SBarry Smith   B->assembled = PETSC_TRUE;
1858de6a44a3SBarry Smith 
18599c01be13SBarry Smith   ierr = MatView_Private(B);CHKERRQ(ierr);
18603a40ed3dSBarry Smith   PetscFunctionReturn(0);
18612593348eSBarry Smith }
18622593348eSBarry Smith 
18632593348eSBarry Smith 
18642593348eSBarry Smith 
1865