xref: /petsc/src/mat/impls/baij/seq/baij.c (revision b65db4ca3424960b3ee21ed30a2ef6b8bdcb9ab8)
1*b65db4caSBarry Smith /*$Id: baij.c,v 1.196 2000/01/19 22:00:37 bsmith Exp bsmith $*/
22593348eSBarry Smith 
32593348eSBarry Smith /*
4b6490206SBarry Smith     Defines the basic matrix operations for the BAIJ (compressed row)
52593348eSBarry Smith   matrix storage format.
62593348eSBarry Smith */
73369ce9aSBarry Smith #include "sys.h"
870f55243SBarry Smith #include "src/mat/impls/baij/seq/baij.h"
91a6a6d98SBarry Smith #include "src/vec/vecimpl.h"
101a6a6d98SBarry Smith #include "src/inline/spops.h"
113b547af2SSatish Balay 
122d61bbb3SSatish Balay #define CHUNKSIZE  10
13de6a44a3SBarry Smith 
14be5855fcSBarry Smith /*
15be5855fcSBarry Smith      Checks for missing diagonals
16be5855fcSBarry Smith */
17be5855fcSBarry Smith #undef __FUNC__
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;
2202d61bbb3SSatish Balay   *m = 0; *n = a->m;
2212d61bbb3SSatish Balay   PetscFunctionReturn(0);
2222d61bbb3SSatish Balay }
2232d61bbb3SSatish Balay 
2242d61bbb3SSatish Balay #undef __FUNC__
2252d61bbb3SSatish Balay #define __FUNC__ "MatGetRow_SeqBAIJ"
2262d61bbb3SSatish Balay int MatGetRow_SeqBAIJ(Mat A,int row,int *nz,int **idx,Scalar **v)
2272d61bbb3SSatish Balay {
2282d61bbb3SSatish Balay   Mat_SeqBAIJ  *a = (Mat_SeqBAIJ*)A->data;
2292d61bbb3SSatish Balay   int          itmp,i,j,k,M,*ai,*aj,bs,bn,bp,*idx_i,bs2;
2303f1db9ecSBarry Smith   MatScalar    *aa,*aa_i;
2313f1db9ecSBarry Smith   Scalar       *v_i;
2322d61bbb3SSatish Balay 
2332d61bbb3SSatish Balay   PetscFunctionBegin;
2342d61bbb3SSatish Balay   bs  = a->bs;
2352d61bbb3SSatish Balay   ai  = a->i;
2362d61bbb3SSatish Balay   aj  = a->j;
2372d61bbb3SSatish Balay   aa  = a->a;
2382d61bbb3SSatish Balay   bs2 = a->bs2;
2392d61bbb3SSatish Balay 
2402d61bbb3SSatish Balay   if (row < 0 || row >= a->m) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Row out of range");
2412d61bbb3SSatish Balay 
2422d61bbb3SSatish Balay   bn  = row/bs;   /* Block number */
2432d61bbb3SSatish Balay   bp  = row % bs; /* Block Position */
2442d61bbb3SSatish Balay   M   = ai[bn+1] - ai[bn];
2452d61bbb3SSatish Balay   *nz = bs*M;
2462d61bbb3SSatish Balay 
2472d61bbb3SSatish Balay   if (v) {
2482d61bbb3SSatish Balay     *v = 0;
2492d61bbb3SSatish Balay     if (*nz) {
2502d61bbb3SSatish Balay       *v = (Scalar*)PetscMalloc((*nz)*sizeof(Scalar));CHKPTRQ(*v);
2512d61bbb3SSatish Balay       for (i=0; i<M; i++) { /* for each block in the block row */
2522d61bbb3SSatish Balay         v_i  = *v + i*bs;
2532d61bbb3SSatish Balay         aa_i = aa + bs2*(ai[bn] + i);
2542d61bbb3SSatish Balay         for (j=bp,k=0; j<bs2; j+=bs,k++) {v_i[k] = aa_i[j];}
2552d61bbb3SSatish Balay       }
2562d61bbb3SSatish Balay     }
2572d61bbb3SSatish Balay   }
2582d61bbb3SSatish Balay 
2592d61bbb3SSatish Balay   if (idx) {
2602d61bbb3SSatish Balay     *idx = 0;
2612d61bbb3SSatish Balay     if (*nz) {
2622d61bbb3SSatish Balay       *idx = (int*)PetscMalloc((*nz)*sizeof(int));CHKPTRQ(*idx);
2632d61bbb3SSatish Balay       for (i=0; i<M; i++) { /* for each block in the block row */
2642d61bbb3SSatish Balay         idx_i = *idx + i*bs;
2652d61bbb3SSatish Balay         itmp  = bs*aj[ai[bn] + i];
2662d61bbb3SSatish Balay         for (j=0; j<bs; j++) {idx_i[j] = itmp++;}
2672d61bbb3SSatish Balay       }
2682d61bbb3SSatish Balay     }
2692d61bbb3SSatish Balay   }
2702d61bbb3SSatish Balay   PetscFunctionReturn(0);
2712d61bbb3SSatish Balay }
2722d61bbb3SSatish Balay 
2732d61bbb3SSatish Balay #undef __FUNC__
2742d61bbb3SSatish Balay #define __FUNC__ "MatRestoreRow_SeqBAIJ"
2752d61bbb3SSatish Balay int MatRestoreRow_SeqBAIJ(Mat A,int row,int *nz,int **idx,Scalar **v)
2762d61bbb3SSatish Balay {
277606d414cSSatish Balay   int ierr;
278606d414cSSatish Balay 
2792d61bbb3SSatish Balay   PetscFunctionBegin;
280606d414cSSatish Balay   if (idx) {if (*idx) {ierr = PetscFree(*idx);CHKERRQ(ierr);}}
281606d414cSSatish Balay   if (v)   {if (*v)   {ierr = PetscFree(*v);CHKERRQ(ierr);}}
2822d61bbb3SSatish Balay   PetscFunctionReturn(0);
2832d61bbb3SSatish Balay }
2842d61bbb3SSatish Balay 
2852d61bbb3SSatish Balay #undef __FUNC__
2862d61bbb3SSatish Balay #define __FUNC__ "MatTranspose_SeqBAIJ"
2872d61bbb3SSatish Balay int MatTranspose_SeqBAIJ(Mat A,Mat *B)
2882d61bbb3SSatish Balay {
2892d61bbb3SSatish Balay   Mat_SeqBAIJ *a=(Mat_SeqBAIJ *)A->data;
2902d61bbb3SSatish Balay   Mat         C;
2912d61bbb3SSatish Balay   int         i,j,k,ierr,*aj=a->j,*ai=a->i,bs=a->bs,mbs=a->mbs,nbs=a->nbs,len,*col;
2920e6d2581SBarry Smith   int         *rows,*cols,bs2=a->bs2,refct;
2933f1db9ecSBarry Smith   MatScalar   *array = a->a;
2942d61bbb3SSatish Balay 
2952d61bbb3SSatish Balay   PetscFunctionBegin;
2960e6d2581SBarry Smith   if (!B && mbs!=nbs) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Square matrix only for in-place");
2972d61bbb3SSatish Balay   col  = (int*)PetscMalloc((1+nbs)*sizeof(int));CHKPTRQ(col);
298549d3d68SSatish Balay   ierr = PetscMemzero(col,(1+nbs)*sizeof(int));CHKERRQ(ierr);
2992d61bbb3SSatish Balay 
3002d61bbb3SSatish Balay   for (i=0; i<ai[mbs]; i++) col[aj[i]] += 1;
3012d61bbb3SSatish Balay   ierr = MatCreateSeqBAIJ(A->comm,bs,a->n,a->m,PETSC_NULL,col,&C);CHKERRQ(ierr);
302606d414cSSatish Balay   ierr = PetscFree(col);CHKERRQ(ierr);
3032d61bbb3SSatish Balay   rows = (int*)PetscMalloc(2*bs*sizeof(int));CHKPTRQ(rows);
3042d61bbb3SSatish Balay   cols = rows + bs;
3052d61bbb3SSatish Balay   for (i=0; i<mbs; i++) {
3062d61bbb3SSatish Balay     cols[0] = i*bs;
3072d61bbb3SSatish Balay     for (k=1; k<bs; k++) cols[k] = cols[k-1] + 1;
3082d61bbb3SSatish Balay     len = ai[i+1] - ai[i];
3092d61bbb3SSatish Balay     for (j=0; j<len; j++) {
3102d61bbb3SSatish Balay       rows[0] = (*aj++)*bs;
3112d61bbb3SSatish Balay       for (k=1; k<bs; k++) rows[k] = rows[k-1] + 1;
3122d61bbb3SSatish Balay       ierr = MatSetValues(C,bs,rows,bs,cols,array,INSERT_VALUES);CHKERRQ(ierr);
3132d61bbb3SSatish Balay       array += bs2;
3142d61bbb3SSatish Balay     }
3152d61bbb3SSatish Balay   }
316606d414cSSatish Balay   ierr = PetscFree(rows);CHKERRQ(ierr);
3172d61bbb3SSatish Balay 
3182d61bbb3SSatish Balay   ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
3192d61bbb3SSatish Balay   ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
3202d61bbb3SSatish Balay 
321c4992f7dSBarry Smith   if (B) {
3222d61bbb3SSatish Balay     *B = C;
3232d61bbb3SSatish Balay   } else {
324f830108cSBarry Smith     PetscOps *Abops;
325cc2dc46cSBarry Smith     MatOps   Aops;
326f830108cSBarry Smith 
3272d61bbb3SSatish Balay     /* This isn't really an in-place transpose */
328606d414cSSatish Balay     ierr = PetscFree(a->a);CHKERRQ(ierr);
329606d414cSSatish Balay     if (!a->singlemalloc) {
330606d414cSSatish Balay       ierr = PetscFree(a->i);CHKERRQ(ierr);
331606d414cSSatish Balay       ierr = PetscFree(a->j);CHKERRQ(ierr);
332606d414cSSatish Balay     }
333606d414cSSatish Balay     if (a->diag) {ierr = PetscFree(a->diag);CHKERRQ(ierr);}
334606d414cSSatish Balay     if (a->ilen) {ierr = PetscFree(a->ilen);CHKERRQ(ierr);}
335606d414cSSatish Balay     if (a->imax) {ierr = PetscFree(a->imax);CHKERRQ(ierr);}
336606d414cSSatish Balay     if (a->solve_work) {ierr = PetscFree(a->solve_work);CHKERRQ(ierr);}
337606d414cSSatish Balay     ierr = PetscFree(a);CHKERRQ(ierr);
338f830108cSBarry Smith 
3397413bad6SBarry Smith 
3407413bad6SBarry Smith     ierr = MapDestroy(A->rmap);CHKERRQ(ierr);
3417413bad6SBarry Smith     ierr = MapDestroy(A->cmap);CHKERRQ(ierr);
3427413bad6SBarry Smith 
343f830108cSBarry Smith     /*
344f830108cSBarry Smith        This is horrible, horrible code. We need to keep the
345f830108cSBarry Smith       A pointers for the bops and ops but copy everything
346f830108cSBarry Smith       else from C.
347f830108cSBarry Smith     */
348f830108cSBarry Smith     Abops    = A->bops;
349f830108cSBarry Smith     Aops     = A->ops;
3500e6d2581SBarry Smith     refct    = A->refct;
351549d3d68SSatish Balay     ierr     = PetscMemcpy(A,C,sizeof(struct _p_Mat));CHKERRQ(ierr);
352f830108cSBarry Smith     A->bops  = Abops;
353f830108cSBarry Smith     A->ops   = Aops;
35427a8da17SBarry Smith     A->qlist = 0;
3550e6d2581SBarry Smith     A->refct = refct;
356f830108cSBarry Smith 
3572d61bbb3SSatish Balay     PetscHeaderDestroy(C);
3582d61bbb3SSatish Balay   }
3592d61bbb3SSatish Balay   PetscFunctionReturn(0);
3602d61bbb3SSatish Balay }
3612d61bbb3SSatish Balay 
3625615d1e5SSatish Balay #undef __FUNC__
363d4bb536fSBarry Smith #define __FUNC__ "MatView_SeqBAIJ_Binary"
364b6490206SBarry Smith static int MatView_SeqBAIJ_Binary(Mat A,Viewer viewer)
3652593348eSBarry Smith {
366b6490206SBarry Smith   Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)A->data;
3679df24120SSatish Balay   int         i,fd,*col_lens,ierr,bs = a->bs,count,*jj,j,k,l,bs2=a->bs2;
368b6490206SBarry Smith   Scalar      *aa;
369ce6f0cecSBarry Smith   FILE        *file;
3702593348eSBarry Smith 
3713a40ed3dSBarry Smith   PetscFunctionBegin;
37290ace30eSBarry Smith   ierr = ViewerBinaryGetDescriptor(viewer,&fd);CHKERRQ(ierr);
3732593348eSBarry Smith   col_lens = (int*)PetscMalloc((4+a->m)*sizeof(int));CHKPTRQ(col_lens);
3742593348eSBarry Smith   col_lens[0] = MAT_COOKIE;
3753b2fbd54SBarry Smith 
3762593348eSBarry Smith   col_lens[1] = a->m;
3772593348eSBarry Smith   col_lens[2] = a->n;
3787e67e3f9SSatish Balay   col_lens[3] = a->nz*bs2;
3792593348eSBarry Smith 
3802593348eSBarry Smith   /* store lengths of each row and write (including header) to file */
381b6490206SBarry Smith   count = 0;
382b6490206SBarry Smith   for (i=0; i<a->mbs; i++) {
383b6490206SBarry Smith     for (j=0; j<bs; j++) {
384b6490206SBarry Smith       col_lens[4+count++] = bs*(a->i[i+1] - a->i[i]);
385b6490206SBarry Smith     }
3862593348eSBarry Smith   }
3870752156aSBarry Smith   ierr = PetscBinaryWrite(fd,col_lens,4+a->m,PETSC_INT,1);CHKERRQ(ierr);
388606d414cSSatish Balay   ierr = PetscFree(col_lens);CHKERRQ(ierr);
3892593348eSBarry Smith 
3902593348eSBarry Smith   /* store column indices (zero start index) */
39166963ce1SSatish Balay   jj = (int*)PetscMalloc((a->nz+1)*bs2*sizeof(int));CHKPTRQ(jj);
392b6490206SBarry Smith   count = 0;
393b6490206SBarry Smith   for (i=0; i<a->mbs; i++) {
394b6490206SBarry Smith     for (j=0; j<bs; j++) {
395b6490206SBarry Smith       for (k=a->i[i]; k<a->i[i+1]; k++) {
396b6490206SBarry Smith         for (l=0; l<bs; l++) {
397b6490206SBarry Smith           jj[count++] = bs*a->j[k] + l;
3982593348eSBarry Smith         }
3992593348eSBarry Smith       }
400b6490206SBarry Smith     }
401b6490206SBarry Smith   }
4020752156aSBarry Smith   ierr = PetscBinaryWrite(fd,jj,bs2*a->nz,PETSC_INT,0);CHKERRQ(ierr);
403606d414cSSatish Balay   ierr = PetscFree(jj);CHKERRQ(ierr);
4042593348eSBarry Smith 
4052593348eSBarry Smith   /* store nonzero values */
40666963ce1SSatish Balay   aa = (Scalar*)PetscMalloc((a->nz+1)*bs2*sizeof(Scalar));CHKPTRQ(aa);
407b6490206SBarry Smith   count = 0;
408b6490206SBarry Smith   for (i=0; i<a->mbs; i++) {
409b6490206SBarry Smith     for (j=0; j<bs; j++) {
410b6490206SBarry Smith       for (k=a->i[i]; k<a->i[i+1]; k++) {
411b6490206SBarry Smith         for (l=0; l<bs; l++) {
4127e67e3f9SSatish Balay           aa[count++] = a->a[bs2*k + l*bs + j];
413b6490206SBarry Smith         }
414b6490206SBarry Smith       }
415b6490206SBarry Smith     }
416b6490206SBarry Smith   }
4170752156aSBarry Smith   ierr = PetscBinaryWrite(fd,aa,bs2*a->nz,PETSC_SCALAR,0);CHKERRQ(ierr);
418606d414cSSatish Balay   ierr = PetscFree(aa);CHKERRQ(ierr);
419ce6f0cecSBarry Smith 
420ce6f0cecSBarry Smith   ierr = ViewerBinaryGetInfoPointer(viewer,&file);CHKERRQ(ierr);
421ce6f0cecSBarry Smith   if (file) {
422ce6f0cecSBarry Smith     fprintf(file,"-matload_block_size %d\n",a->bs);
423ce6f0cecSBarry Smith   }
4243a40ed3dSBarry Smith   PetscFunctionReturn(0);
4252593348eSBarry Smith }
4262593348eSBarry Smith 
4275615d1e5SSatish Balay #undef __FUNC__
428d4bb536fSBarry Smith #define __FUNC__ "MatView_SeqBAIJ_ASCII"
429b6490206SBarry Smith static int MatView_SeqBAIJ_ASCII(Mat A,Viewer viewer)
4302593348eSBarry Smith {
431b6490206SBarry Smith   Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)A->data;
4329df24120SSatish Balay   int         ierr,i,j,format,bs = a->bs,k,l,bs2=a->bs2;
4332593348eSBarry Smith   char        *outputname;
4342593348eSBarry Smith 
4353a40ed3dSBarry Smith   PetscFunctionBegin;
43677ed5343SBarry Smith   ierr = ViewerGetOutputname(viewer,&outputname);CHKERRQ(ierr);
437888f2ed8SSatish Balay   ierr = ViewerGetFormat(viewer,&format);CHKERRQ(ierr);
438639f9d9dSBarry Smith   if (format == VIEWER_FORMAT_ASCII_INFO || format == VIEWER_FORMAT_ASCII_INFO_LONG) {
439d132466eSBarry Smith     ierr = ViewerASCIIPrintf(viewer,"  block size is %d\n",bs);CHKERRQ(ierr);
4400ef38995SBarry Smith   } else if (format == VIEWER_FORMAT_ASCII_MATLAB) {
4416831982aSBarry Smith     SETERRQ(PETSC_ERR_SUP,0,"Matlab format not supported");
4420ef38995SBarry Smith   } else if (format == VIEWER_FORMAT_ASCII_COMMON) {
4436831982aSBarry Smith     ierr = ViewerASCIIUseTabs(viewer,PETSC_NO);CHKERRQ(ierr);
44444cd7ae7SLois Curfman McInnes     for (i=0; i<a->mbs; i++) {
44544cd7ae7SLois Curfman McInnes       for (j=0; j<bs; j++) {
4466831982aSBarry Smith         ierr = ViewerASCIIPrintf(viewer,"row %d:",i*bs+j);CHKERRQ(ierr);
44744cd7ae7SLois Curfman McInnes         for (k=a->i[i]; k<a->i[i+1]; k++) {
44844cd7ae7SLois Curfman McInnes           for (l=0; l<bs; l++) {
449aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
4500e6d2581SBarry Smith             if (PetscImaginaryPart(a->a[bs2*k + l*bs + j]) > 0.0 && PetscRealPart(a->a[bs2*k + l*bs + j]) != 0.0) {
4516831982aSBarry Smith               ierr = ViewerASCIIPrintf(viewer," %d %g + %g i",bs*a->j[k]+l,
4520e6d2581SBarry Smith                       PetscRealPart(a->a[bs2*k + l*bs + j]),PetscImaginaryPart(a->a[bs2*k + l*bs + j]));CHKERRQ(ierr);
4530e6d2581SBarry Smith             } else if (PetscImaginaryPart(a->a[bs2*k + l*bs + j]) < 0.0 && PetscRealPart(a->a[bs2*k + l*bs + j]) != 0.0) {
4546831982aSBarry Smith               ierr = ViewerASCIIPrintf(viewer," %d %g - %g i",bs*a->j[k]+l,
4550e6d2581SBarry Smith                       PetscRealPart(a->a[bs2*k + l*bs + j]),-PetscImaginaryPart(a->a[bs2*k + l*bs + j]));CHKERRQ(ierr);
4560e6d2581SBarry Smith             } else if (PetscRealPart(a->a[bs2*k + l*bs + j]) != 0.0) {
4570e6d2581SBarry Smith               ierr = ViewerASCIIPrintf(viewer," %d %g ",bs*a->j[k]+l,PetscRealPart(a->a[bs2*k + l*bs + j]));CHKERRQ(ierr);
4580ef38995SBarry Smith             }
45944cd7ae7SLois Curfman McInnes #else
4600ef38995SBarry Smith             if (a->a[bs2*k + l*bs + j] != 0.0) {
4616831982aSBarry Smith               ierr = ViewerASCIIPrintf(viewer," %d %g ",bs*a->j[k]+l,a->a[bs2*k + l*bs + j]);CHKERRQ(ierr);
4620ef38995SBarry Smith             }
46344cd7ae7SLois Curfman McInnes #endif
46444cd7ae7SLois Curfman McInnes           }
46544cd7ae7SLois Curfman McInnes         }
4666831982aSBarry Smith         ierr = ViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
46744cd7ae7SLois Curfman McInnes       }
46844cd7ae7SLois Curfman McInnes     }
4696831982aSBarry Smith     ierr = ViewerASCIIUseTabs(viewer,PETSC_YES);CHKERRQ(ierr);
4700ef38995SBarry Smith   } else {
4716831982aSBarry Smith     ierr = ViewerASCIIUseTabs(viewer,PETSC_NO);CHKERRQ(ierr);
472b6490206SBarry Smith     for (i=0; i<a->mbs; i++) {
473b6490206SBarry Smith       for (j=0; j<bs; j++) {
4746831982aSBarry Smith         ierr = ViewerASCIIPrintf(viewer,"row %d:",i*bs+j);CHKERRQ(ierr);
475b6490206SBarry Smith         for (k=a->i[i]; k<a->i[i+1]; k++) {
476b6490206SBarry Smith           for (l=0; l<bs; l++) {
477aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
4780e6d2581SBarry Smith             if (PetscImaginaryPart(a->a[bs2*k + l*bs + j]) > 0.0) {
4796831982aSBarry Smith               ierr = ViewerASCIIPrintf(viewer," %d %g + %g i",bs*a->j[k]+l,
4800e6d2581SBarry Smith                 PetscRealPart(a->a[bs2*k + l*bs + j]),PetscImaginaryPart(a->a[bs2*k + l*bs + j]));CHKERRQ(ierr);
4810e6d2581SBarry Smith             } else if (PetscImaginaryPart(a->a[bs2*k + l*bs + j]) < 0.0) {
4826831982aSBarry Smith               ierr = ViewerASCIIPrintf(viewer," %d %g - %g i",bs*a->j[k]+l,
4830e6d2581SBarry Smith                 PetscRealPart(a->a[bs2*k + l*bs + j]),-PetscImaginaryPart(a->a[bs2*k + l*bs + j]));CHKERRQ(ierr);
4840ef38995SBarry Smith             } else {
4850e6d2581SBarry Smith               ierr = ViewerASCIIPrintf(viewer," %d %g ",bs*a->j[k]+l,PetscRealPart(a->a[bs2*k + l*bs + j]));CHKERRQ(ierr);
48688685aaeSLois Curfman McInnes             }
48788685aaeSLois Curfman McInnes #else
4886831982aSBarry Smith             ierr = ViewerASCIIPrintf(viewer," %d %g ",bs*a->j[k]+l,a->a[bs2*k + l*bs + j]);CHKERRQ(ierr);
48988685aaeSLois Curfman McInnes #endif
4902593348eSBarry Smith           }
4912593348eSBarry Smith         }
4926831982aSBarry Smith         ierr = ViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
4932593348eSBarry Smith       }
4942593348eSBarry Smith     }
4956831982aSBarry Smith     ierr = ViewerASCIIUseTabs(viewer,PETSC_YES);CHKERRQ(ierr);
496b6490206SBarry Smith   }
4976831982aSBarry Smith   ierr = ViewerFlush(viewer);CHKERRQ(ierr);
4983a40ed3dSBarry Smith   PetscFunctionReturn(0);
4992593348eSBarry Smith }
5002593348eSBarry Smith 
5015615d1e5SSatish Balay #undef __FUNC__
50277ed5343SBarry Smith #define __FUNC__ "MatView_SeqBAIJ_Draw_Zoom"
50377ed5343SBarry Smith static int MatView_SeqBAIJ_Draw_Zoom(Draw draw,void *Aa)
5043270192aSSatish Balay {
50577ed5343SBarry Smith   Mat          A = (Mat) Aa;
5063270192aSSatish Balay   Mat_SeqBAIJ  *a=(Mat_SeqBAIJ*)A->data;
507*b65db4caSBarry Smith   int          row,ierr,i,j,k,l,mbs=a->mbs,color,bs=a->bs,bs2=a->bs2;
5080e6d2581SBarry Smith   PetscReal    xl,yl,xr,yr,x_l,x_r,y_l,y_r;
5093f1db9ecSBarry Smith   MatScalar    *aa;
51077ed5343SBarry Smith   Viewer       viewer;
5113270192aSSatish Balay 
5123a40ed3dSBarry Smith   PetscFunctionBegin;
5133270192aSSatish Balay 
514*b65db4caSBarry Smith   /* still need to add support for contour plot of nonzeros; see MatView_SeqAIJ_Draw_Zoom()*/
51577ed5343SBarry Smith   ierr = PetscObjectQuery((PetscObject)A,"Zoomviewer",(PetscObject*)&viewer);CHKERRQ(ierr);
51677ed5343SBarry Smith 
51777ed5343SBarry Smith   ierr = DrawGetCoordinates(draw,&xl,&yl,&xr,&yr);CHKERRQ(ierr);
51877ed5343SBarry Smith 
5193270192aSSatish Balay   /* loop over matrix elements drawing boxes */
5203270192aSSatish Balay   color = DRAW_BLUE;
5213270192aSSatish Balay   for (i=0,row=0; i<mbs; i++,row+=bs) {
5223270192aSSatish Balay     for (j=a->i[i]; j<a->i[i+1]; j++) {
5233270192aSSatish Balay       y_l = a->m - row - 1.0; y_r = y_l + 1.0;
5243270192aSSatish Balay       x_l = a->j[j]*bs; x_r = x_l + 1.0;
5253270192aSSatish Balay       aa = a->a + j*bs2;
5263270192aSSatish Balay       for (k=0; k<bs; k++) {
5273270192aSSatish Balay         for (l=0; l<bs; l++) {
5280e6d2581SBarry Smith           if (PetscRealPart(*aa++) >=  0.) continue;
529433994e6SBarry Smith           ierr = DrawRectangle(draw,x_l+k,y_l-l,x_r+k,y_r-l,color,color,color,color);CHKERRQ(ierr);
5303270192aSSatish Balay         }
5313270192aSSatish Balay       }
5323270192aSSatish Balay     }
5333270192aSSatish Balay   }
5343270192aSSatish Balay   color = DRAW_CYAN;
5353270192aSSatish Balay   for (i=0,row=0; i<mbs; i++,row+=bs) {
5363270192aSSatish Balay     for (j=a->i[i]; j<a->i[i+1]; j++) {
5373270192aSSatish Balay       y_l = a->m - row - 1.0; y_r = y_l + 1.0;
5383270192aSSatish Balay       x_l = a->j[j]*bs; x_r = x_l + 1.0;
5393270192aSSatish Balay       aa = a->a + j*bs2;
5403270192aSSatish Balay       for (k=0; k<bs; k++) {
5413270192aSSatish Balay         for (l=0; l<bs; l++) {
5420e6d2581SBarry Smith           if (PetscRealPart(*aa++) != 0.) continue;
543433994e6SBarry Smith           ierr = DrawRectangle(draw,x_l+k,y_l-l,x_r+k,y_r-l,color,color,color,color);CHKERRQ(ierr);
5443270192aSSatish Balay         }
5453270192aSSatish Balay       }
5463270192aSSatish Balay     }
5473270192aSSatish Balay   }
5483270192aSSatish Balay 
5493270192aSSatish Balay   color = DRAW_RED;
5503270192aSSatish Balay   for (i=0,row=0; i<mbs; i++,row+=bs) {
5513270192aSSatish Balay     for (j=a->i[i]; j<a->i[i+1]; j++) {
5523270192aSSatish Balay       y_l = a->m - row - 1.0; y_r = y_l + 1.0;
5533270192aSSatish Balay       x_l = a->j[j]*bs; x_r = x_l + 1.0;
5543270192aSSatish Balay       aa = a->a + j*bs2;
5553270192aSSatish Balay       for (k=0; k<bs; k++) {
5563270192aSSatish Balay         for (l=0; l<bs; l++) {
5570e6d2581SBarry Smith           if (PetscRealPart(*aa++) <= 0.) continue;
558433994e6SBarry Smith           ierr = DrawRectangle(draw,x_l+k,y_l-l,x_r+k,y_r-l,color,color,color,color);CHKERRQ(ierr);
5593270192aSSatish Balay         }
5603270192aSSatish Balay       }
5613270192aSSatish Balay     }
5623270192aSSatish Balay   }
56377ed5343SBarry Smith   PetscFunctionReturn(0);
56477ed5343SBarry Smith }
5653270192aSSatish Balay 
56677ed5343SBarry Smith #undef __FUNC__
56777ed5343SBarry Smith #define __FUNC__ "MatView_SeqBAIJ_Draw"
56877ed5343SBarry Smith static int MatView_SeqBAIJ_Draw(Mat A,Viewer viewer)
56977ed5343SBarry Smith {
57077ed5343SBarry Smith   Mat_SeqBAIJ  *a=(Mat_SeqBAIJ*)A->data;
5717dce120fSSatish Balay   int          ierr;
5720e6d2581SBarry Smith   PetscReal    xl,yl,xr,yr,w,h;
57377ed5343SBarry Smith   Draw         draw;
57477ed5343SBarry Smith   PetscTruth   isnull;
5753270192aSSatish Balay 
57677ed5343SBarry Smith   PetscFunctionBegin;
57777ed5343SBarry Smith 
57877ed5343SBarry Smith   ierr = ViewerDrawGetDraw(viewer,0,&draw);CHKERRQ(ierr);
57977ed5343SBarry Smith   ierr = DrawIsNull(draw,&isnull);CHKERRQ(ierr); if (isnull) PetscFunctionReturn(0);
58077ed5343SBarry Smith 
58177ed5343SBarry Smith   ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",(PetscObject)viewer);CHKERRQ(ierr);
58277ed5343SBarry Smith   xr  = a->n; yr = a->m; h = yr/10.0; w = xr/10.0;
58377ed5343SBarry Smith   xr += w;    yr += h;  xl = -w;     yl = -h;
5843270192aSSatish Balay   ierr = DrawSetCoordinates(draw,xl,yl,xr,yr);CHKERRQ(ierr);
58577ed5343SBarry Smith   ierr = DrawZoom(draw,MatView_SeqBAIJ_Draw_Zoom,A);CHKERRQ(ierr);
58677ed5343SBarry Smith   ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",PETSC_NULL);CHKERRQ(ierr);
5873a40ed3dSBarry Smith   PetscFunctionReturn(0);
5883270192aSSatish Balay }
5893270192aSSatish Balay 
5905615d1e5SSatish Balay #undef __FUNC__
591d4bb536fSBarry Smith #define __FUNC__ "MatView_SeqBAIJ"
592e1311b90SBarry Smith int MatView_SeqBAIJ(Mat A,Viewer viewer)
5932593348eSBarry Smith {
59419bcc07fSBarry Smith   int        ierr;
5956831982aSBarry Smith   PetscTruth issocket,isascii,isbinary,isdraw;
5962593348eSBarry Smith 
5973a40ed3dSBarry Smith   PetscFunctionBegin;
5986831982aSBarry Smith   ierr = PetscTypeCompare((PetscObject)viewer,SOCKET_VIEWER,&issocket);CHKERRQ(ierr);
5996831982aSBarry Smith   ierr = PetscTypeCompare((PetscObject)viewer,ASCII_VIEWER,&isascii);CHKERRQ(ierr);
6006831982aSBarry Smith   ierr = PetscTypeCompare((PetscObject)viewer,BINARY_VIEWER,&isbinary);CHKERRQ(ierr);
6016831982aSBarry Smith   ierr = PetscTypeCompare((PetscObject)viewer,DRAW_VIEWER,&isdraw);CHKERRQ(ierr);
6020f5bd95cSBarry Smith   if (issocket) {
6037b2a1423SBarry Smith     SETERRQ(PETSC_ERR_SUP,0,"Socket viewer not supported");
6040f5bd95cSBarry Smith   } else if (isascii){
6053a40ed3dSBarry Smith     ierr = MatView_SeqBAIJ_ASCII(A,viewer);CHKERRQ(ierr);
6060f5bd95cSBarry Smith   } else if (isbinary) {
6073a40ed3dSBarry Smith     ierr = MatView_SeqBAIJ_Binary(A,viewer);CHKERRQ(ierr);
6080f5bd95cSBarry Smith   } else if (isdraw) {
6093a40ed3dSBarry Smith     ierr = MatView_SeqBAIJ_Draw(A,viewer);CHKERRQ(ierr);
6105cd90555SBarry Smith   } else {
6110f5bd95cSBarry Smith     SETERRQ1(1,1,"Viewer type %s not supported by SeqBAIJ matrices",((PetscObject)viewer)->type_name);
6122593348eSBarry Smith   }
6133a40ed3dSBarry Smith   PetscFunctionReturn(0);
6142593348eSBarry Smith }
615b6490206SBarry Smith 
616cd0e1443SSatish Balay 
6175615d1e5SSatish Balay #undef __FUNC__
6182d61bbb3SSatish Balay #define __FUNC__ "MatGetValues_SeqBAIJ"
6192d61bbb3SSatish Balay int MatGetValues_SeqBAIJ(Mat A,int m,int *im,int n,int *in,Scalar *v)
620cd0e1443SSatish Balay {
621cd0e1443SSatish Balay   Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)A->data;
6222d61bbb3SSatish Balay   int        *rp,k,low,high,t,row,nrow,i,col,l,*aj = a->j;
6232d61bbb3SSatish Balay   int        *ai = a->i,*ailen = a->ilen;
6242d61bbb3SSatish Balay   int        brow,bcol,ridx,cidx,bs=a->bs,bs2=a->bs2;
6253f1db9ecSBarry Smith   MatScalar  *ap,*aa = a->a,zero = 0.0;
626cd0e1443SSatish Balay 
6273a40ed3dSBarry Smith   PetscFunctionBegin;
6282d61bbb3SSatish Balay   for (k=0; k<m; k++) { /* loop over rows */
629cd0e1443SSatish Balay     row  = im[k]; brow = row/bs;
630a8c6a408SBarry Smith     if (row < 0) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Negative row");
631a8c6a408SBarry Smith     if (row >= a->m) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Row too large");
6322d61bbb3SSatish Balay     rp   = aj + ai[brow] ; ap = aa + bs2*ai[brow] ;
6332c3acbe9SBarry Smith     nrow = ailen[brow];
6342d61bbb3SSatish Balay     for (l=0; l<n; l++) { /* loop over columns */
635a8c6a408SBarry Smith       if (in[l] < 0) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Negative column");
636a8c6a408SBarry Smith       if (in[l] >= a->n) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Column too large");
6372d61bbb3SSatish Balay       col  = in[l] ;
6382d61bbb3SSatish Balay       bcol = col/bs;
6392d61bbb3SSatish Balay       cidx = col%bs;
6402d61bbb3SSatish Balay       ridx = row%bs;
6412d61bbb3SSatish Balay       high = nrow;
6422d61bbb3SSatish Balay       low  = 0; /* assume unsorted */
6432d61bbb3SSatish Balay       while (high-low > 5) {
644cd0e1443SSatish Balay         t = (low+high)/2;
645cd0e1443SSatish Balay         if (rp[t] > bcol) high = t;
646cd0e1443SSatish Balay         else             low  = t;
647cd0e1443SSatish Balay       }
648cd0e1443SSatish Balay       for (i=low; i<high; i++) {
649cd0e1443SSatish Balay         if (rp[i] > bcol) break;
650cd0e1443SSatish Balay         if (rp[i] == bcol) {
6512d61bbb3SSatish Balay           *v++ = ap[bs2*i+bs*cidx+ridx];
6522d61bbb3SSatish Balay           goto finished;
653cd0e1443SSatish Balay         }
654cd0e1443SSatish Balay       }
6552d61bbb3SSatish Balay       *v++ = zero;
6562d61bbb3SSatish Balay       finished:;
657cd0e1443SSatish Balay     }
658cd0e1443SSatish Balay   }
6593a40ed3dSBarry Smith   PetscFunctionReturn(0);
660cd0e1443SSatish Balay }
661cd0e1443SSatish Balay 
6622d61bbb3SSatish Balay 
6635615d1e5SSatish Balay #undef __FUNC__
66405a5f48eSSatish Balay #define __FUNC__ "MatSetValuesBlocked_SeqBAIJ"
66592c4ed94SBarry Smith int MatSetValuesBlocked_SeqBAIJ(Mat A,int m,int *im,int n,int *in,Scalar *v,InsertMode is)
66692c4ed94SBarry Smith {
66792c4ed94SBarry Smith   Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)A->data;
6688a84c255SSatish Balay   int         *rp,k,low,high,t,ii,jj,row,nrow,i,col,l,rmax,N,sorted=a->sorted;
669dd9472c6SBarry Smith   int         *imax=a->imax,*ai=a->i,*ailen=a->ilen,roworiented=a->roworiented;
670549d3d68SSatish Balay   int         *aj=a->j,nonew=a->nonew,bs2=a->bs2,bs=a->bs,stepval,ierr;
6713f1db9ecSBarry Smith   Scalar      *value = v;
6723f1db9ecSBarry Smith   MatScalar   *ap,*aa=a->a,*bap;
67392c4ed94SBarry Smith 
6743a40ed3dSBarry Smith   PetscFunctionBegin;
6750e324ae4SSatish Balay   if (roworiented) {
6760e324ae4SSatish Balay     stepval = (n-1)*bs;
6770e324ae4SSatish Balay   } else {
6780e324ae4SSatish Balay     stepval = (m-1)*bs;
6790e324ae4SSatish Balay   }
68092c4ed94SBarry Smith   for (k=0; k<m; k++) { /* loop over added rows */
68192c4ed94SBarry Smith     row  = im[k];
6825ef9f2a5SBarry Smith     if (row < 0) continue;
683aa482453SBarry Smith #if defined(PETSC_USE_BOPT_g)
684a8c6a408SBarry Smith     if (row >= a->mbs) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Row too large");
68592c4ed94SBarry Smith #endif
68692c4ed94SBarry Smith     rp   = aj + ai[row];
68792c4ed94SBarry Smith     ap   = aa + bs2*ai[row];
68892c4ed94SBarry Smith     rmax = imax[row];
68992c4ed94SBarry Smith     nrow = ailen[row];
69092c4ed94SBarry Smith     low  = 0;
69192c4ed94SBarry Smith     for (l=0; l<n; l++) { /* loop over added columns */
6925ef9f2a5SBarry Smith       if (in[l] < 0) continue;
693aa482453SBarry Smith #if defined(PETSC_USE_BOPT_g)
694a8c6a408SBarry Smith       if (in[l] >= a->nbs) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Column too large");
69592c4ed94SBarry Smith #endif
69692c4ed94SBarry Smith       col = in[l];
69792c4ed94SBarry Smith       if (roworiented) {
6980e324ae4SSatish Balay         value = v + k*(stepval+bs)*bs + l*bs;
6990e324ae4SSatish Balay       } else {
7000e324ae4SSatish Balay         value = v + l*(stepval+bs)*bs + k*bs;
70192c4ed94SBarry Smith       }
70292c4ed94SBarry Smith       if (!sorted) low = 0; high = nrow;
70392c4ed94SBarry Smith       while (high-low > 7) {
70492c4ed94SBarry Smith         t = (low+high)/2;
70592c4ed94SBarry Smith         if (rp[t] > col) high = t;
70692c4ed94SBarry Smith         else             low  = t;
70792c4ed94SBarry Smith       }
70892c4ed94SBarry Smith       for (i=low; i<high; i++) {
70992c4ed94SBarry Smith         if (rp[i] > col) break;
71092c4ed94SBarry Smith         if (rp[i] == col) {
7118a84c255SSatish Balay           bap  = ap +  bs2*i;
7120e324ae4SSatish Balay           if (roworiented) {
7138a84c255SSatish Balay             if (is == ADD_VALUES) {
714dd9472c6SBarry Smith               for (ii=0; ii<bs; ii++,value+=stepval) {
715dd9472c6SBarry Smith                 for (jj=ii; jj<bs2; jj+=bs) {
7168a84c255SSatish Balay                   bap[jj] += *value++;
717dd9472c6SBarry Smith                 }
718dd9472c6SBarry Smith               }
7190e324ae4SSatish Balay             } else {
720dd9472c6SBarry Smith               for (ii=0; ii<bs; ii++,value+=stepval) {
721dd9472c6SBarry Smith                 for (jj=ii; jj<bs2; jj+=bs) {
7220e324ae4SSatish Balay                   bap[jj] = *value++;
7238a84c255SSatish Balay                 }
724dd9472c6SBarry Smith               }
725dd9472c6SBarry Smith             }
7260e324ae4SSatish Balay           } else {
7270e324ae4SSatish Balay             if (is == ADD_VALUES) {
728dd9472c6SBarry Smith               for (ii=0; ii<bs; ii++,value+=stepval) {
729dd9472c6SBarry Smith                 for (jj=0; jj<bs; jj++) {
7300e324ae4SSatish Balay                   *bap++ += *value++;
731dd9472c6SBarry Smith                 }
732dd9472c6SBarry Smith               }
7330e324ae4SSatish Balay             } else {
734dd9472c6SBarry Smith               for (ii=0; ii<bs; ii++,value+=stepval) {
735dd9472c6SBarry Smith                 for (jj=0; jj<bs; jj++) {
7360e324ae4SSatish Balay                   *bap++  = *value++;
7370e324ae4SSatish Balay                 }
7388a84c255SSatish Balay               }
739dd9472c6SBarry Smith             }
740dd9472c6SBarry Smith           }
741f1241b54SBarry Smith           goto noinsert2;
74292c4ed94SBarry Smith         }
74392c4ed94SBarry Smith       }
74489280ab3SLois Curfman McInnes       if (nonew == 1) goto noinsert2;
745a8c6a408SBarry Smith       else if (nonew == -1) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Inserting a new nonzero in the matrix");
74692c4ed94SBarry Smith       if (nrow >= rmax) {
74792c4ed94SBarry Smith         /* there is no extra room in row, therefore enlarge */
74892c4ed94SBarry Smith         int       new_nz = ai[a->mbs] + CHUNKSIZE,len,*new_i,*new_j;
7493f1db9ecSBarry Smith         MatScalar *new_a;
75092c4ed94SBarry Smith 
751a8c6a408SBarry Smith         if (nonew == -2) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Inserting a new nonzero in the matrix");
75289280ab3SLois Curfman McInnes 
75392c4ed94SBarry Smith         /* malloc new storage space */
7543f1db9ecSBarry Smith         len     = new_nz*(sizeof(int)+bs2*sizeof(MatScalar))+(a->mbs+1)*sizeof(int);
7553f1db9ecSBarry Smith         new_a   = (MatScalar*)PetscMalloc(len);CHKPTRQ(new_a);
75692c4ed94SBarry Smith         new_j   = (int*)(new_a + bs2*new_nz);
75792c4ed94SBarry Smith         new_i   = new_j + new_nz;
75892c4ed94SBarry Smith 
75992c4ed94SBarry Smith         /* copy over old data into new slots */
76092c4ed94SBarry Smith         for (ii=0; ii<row+1; ii++) {new_i[ii] = ai[ii];}
76192c4ed94SBarry Smith         for (ii=row+1; ii<a->mbs+1; ii++) {new_i[ii] = ai[ii]+CHUNKSIZE;}
762549d3d68SSatish Balay         ierr = PetscMemcpy(new_j,aj,(ai[row]+nrow)*sizeof(int));CHKERRQ(ierr);
76392c4ed94SBarry Smith         len  = (new_nz - CHUNKSIZE - ai[row] - nrow);
764549d3d68SSatish Balay         ierr = PetscMemcpy(new_j+ai[row]+nrow+CHUNKSIZE,aj+ai[row]+nrow,len*sizeof(int));CHKERRQ(ierr);
765549d3d68SSatish Balay         ierr = PetscMemcpy(new_a,aa,(ai[row]+nrow)*bs2*sizeof(MatScalar));CHKERRQ(ierr);
766549d3d68SSatish Balay         ierr = PetscMemzero(new_a+bs2*(ai[row]+nrow),bs2*CHUNKSIZE*sizeof(MatScalar));CHKERRQ(ierr);
767549d3d68SSatish Balay         ierr = PetscMemcpy(new_a+bs2*(ai[row]+nrow+CHUNKSIZE),aa+bs2*(ai[row]+nrow),bs2*len*sizeof(MatScalar));CHKERRQ(ierr);
76892c4ed94SBarry Smith         /* free up old matrix storage */
769606d414cSSatish Balay         ierr = PetscFree(a->a);CHKERRQ(ierr);
770606d414cSSatish Balay         if (!a->singlemalloc) {
771606d414cSSatish Balay           ierr = PetscFree(a->i);CHKERRQ(ierr);
772606d414cSSatish Balay           ierr = PetscFree(a->j);CHKERRQ(ierr);
773606d414cSSatish Balay         }
77492c4ed94SBarry Smith         aa = a->a = new_a; ai = a->i = new_i; aj = a->j = new_j;
775c4992f7dSBarry Smith         a->singlemalloc = PETSC_TRUE;
77692c4ed94SBarry Smith 
77792c4ed94SBarry Smith         rp   = aj + ai[row]; ap = aa + bs2*ai[row];
77892c4ed94SBarry Smith         rmax = imax[row] = imax[row] + CHUNKSIZE;
7793f1db9ecSBarry Smith         PLogObjectMemory(A,CHUNKSIZE*(sizeof(int) + bs2*sizeof(MatScalar)));
78092c4ed94SBarry Smith         a->maxnz += bs2*CHUNKSIZE;
78192c4ed94SBarry Smith         a->reallocs++;
78292c4ed94SBarry Smith         a->nz++;
78392c4ed94SBarry Smith       }
78492c4ed94SBarry Smith       N = nrow++ - 1;
78592c4ed94SBarry Smith       /* shift up all the later entries in this row */
78692c4ed94SBarry Smith       for (ii=N; ii>=i; ii--) {
78792c4ed94SBarry Smith         rp[ii+1] = rp[ii];
788549d3d68SSatish Balay         ierr = PetscMemcpy(ap+bs2*(ii+1),ap+bs2*(ii),bs2*sizeof(MatScalar));CHKERRQ(ierr);
78992c4ed94SBarry Smith       }
790549d3d68SSatish Balay       if (N >= i) {
791549d3d68SSatish Balay         ierr = PetscMemzero(ap+bs2*i,bs2*sizeof(MatScalar));CHKERRQ(ierr);
792549d3d68SSatish Balay       }
79392c4ed94SBarry Smith       rp[i] = col;
7948a84c255SSatish Balay       bap   = ap +  bs2*i;
7950e324ae4SSatish Balay       if (roworiented) {
796dd9472c6SBarry Smith         for (ii=0; ii<bs; ii++,value+=stepval) {
797dd9472c6SBarry Smith           for (jj=ii; jj<bs2; jj+=bs) {
7980e324ae4SSatish Balay             bap[jj] = *value++;
799dd9472c6SBarry Smith           }
800dd9472c6SBarry Smith         }
8010e324ae4SSatish Balay       } else {
802dd9472c6SBarry Smith         for (ii=0; ii<bs; ii++,value+=stepval) {
803dd9472c6SBarry Smith           for (jj=0; jj<bs; jj++) {
8040e324ae4SSatish Balay             *bap++  = *value++;
8050e324ae4SSatish Balay           }
806dd9472c6SBarry Smith         }
807dd9472c6SBarry Smith       }
808f1241b54SBarry Smith       noinsert2:;
80992c4ed94SBarry Smith       low = i;
81092c4ed94SBarry Smith     }
81192c4ed94SBarry Smith     ailen[row] = nrow;
81292c4ed94SBarry Smith   }
8133a40ed3dSBarry Smith   PetscFunctionReturn(0);
81492c4ed94SBarry Smith }
81592c4ed94SBarry Smith 
816f2501298SSatish Balay 
8175615d1e5SSatish Balay #undef __FUNC__
8185615d1e5SSatish Balay #define __FUNC__ "MatAssemblyEnd_SeqBAIJ"
8198f6be9afSLois Curfman McInnes int MatAssemblyEnd_SeqBAIJ(Mat A,MatAssemblyType mode)
820584200bdSSatish Balay {
821584200bdSSatish Balay   Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)A->data;
822584200bdSSatish Balay   int        fshift = 0,i,j,*ai = a->i,*aj = a->j,*imax = a->imax;
823a7c10996SSatish Balay   int        m = a->m,*ip,N,*ailen = a->ilen;
824549d3d68SSatish Balay   int        mbs = a->mbs,bs2 = a->bs2,rmax = 0,ierr;
8253f1db9ecSBarry Smith   MatScalar  *aa = a->a,*ap;
826584200bdSSatish Balay 
8273a40ed3dSBarry Smith   PetscFunctionBegin;
8283a40ed3dSBarry Smith   if (mode == MAT_FLUSH_ASSEMBLY) PetscFunctionReturn(0);
829584200bdSSatish Balay 
83043ee02c3SBarry Smith   if (m) rmax = ailen[0];
831584200bdSSatish Balay   for (i=1; i<mbs; i++) {
832584200bdSSatish Balay     /* move each row back by the amount of empty slots (fshift) before it*/
833584200bdSSatish Balay     fshift += imax[i-1] - ailen[i-1];
834d402145bSBarry Smith     rmax   = PetscMax(rmax,ailen[i]);
835584200bdSSatish Balay     if (fshift) {
836a7c10996SSatish Balay       ip = aj + ai[i]; ap = aa + bs2*ai[i];
837584200bdSSatish Balay       N = ailen[i];
838584200bdSSatish Balay       for (j=0; j<N; j++) {
839584200bdSSatish Balay         ip[j-fshift] = ip[j];
840549d3d68SSatish Balay         ierr = PetscMemcpy(ap+(j-fshift)*bs2,ap+j*bs2,bs2*sizeof(MatScalar));CHKERRQ(ierr);
841584200bdSSatish Balay       }
842584200bdSSatish Balay     }
843584200bdSSatish Balay     ai[i] = ai[i-1] + ailen[i-1];
844584200bdSSatish Balay   }
845584200bdSSatish Balay   if (mbs) {
846584200bdSSatish Balay     fshift += imax[mbs-1] - ailen[mbs-1];
847584200bdSSatish Balay     ai[mbs] = ai[mbs-1] + ailen[mbs-1];
848584200bdSSatish Balay   }
849584200bdSSatish Balay   /* reset ilen and imax for each row */
850584200bdSSatish Balay   for (i=0; i<mbs; i++) {
851584200bdSSatish Balay     ailen[i] = imax[i] = ai[i+1] - ai[i];
852584200bdSSatish Balay   }
853a7c10996SSatish Balay   a->nz = ai[mbs];
854584200bdSSatish Balay 
855584200bdSSatish Balay   /* diagonals may have moved, so kill the diagonal pointers */
856584200bdSSatish Balay   if (fshift && a->diag) {
857606d414cSSatish Balay     ierr = PetscFree(a->diag);CHKERRQ(ierr);
858584200bdSSatish Balay     PLogObjectMemory(A,-(m+1)*sizeof(int));
859584200bdSSatish Balay     a->diag = 0;
860584200bdSSatish Balay   }
8613d2013a6SLois Curfman McInnes   PLogInfo(A,"MatAssemblyEnd_SeqBAIJ:Matrix size: %d X %d, block size %d; storage space: %d unneeded, %d used\n",
862219d9a1aSLois Curfman McInnes            m,a->n,a->bs,fshift*bs2,a->nz*bs2);
8633d2013a6SLois Curfman McInnes   PLogInfo(A,"MatAssemblyEnd_SeqBAIJ:Number of mallocs during MatSetValues is %d\n",
864584200bdSSatish Balay            a->reallocs);
865d402145bSBarry Smith   PLogInfo(A,"MatAssemblyEnd_SeqBAIJ:Most nonzeros blocks in any row is %d\n",rmax);
866e2f3b5e9SSatish Balay   a->reallocs          = 0;
8670e6d2581SBarry Smith   A->info.nz_unneeded  = (PetscReal)fshift*bs2;
8684e220ebcSLois Curfman McInnes 
8693a40ed3dSBarry Smith   PetscFunctionReturn(0);
870584200bdSSatish Balay }
871584200bdSSatish Balay 
8725a838052SSatish Balay 
873bea157c4SSatish Balay 
874bea157c4SSatish Balay /*
875bea157c4SSatish Balay    This function returns an array of flags which indicate the locations of contiguous
876bea157c4SSatish Balay    blocks that should be zeroed. for eg: if bs = 3  and is = [0,1,2,3,5,6,7,8,9]
877bea157c4SSatish Balay    then the resulting sizes = [3,1,1,3,1] correspondig to sets [(0,1,2),(3),(5),(6,7,8),(9)]
878bea157c4SSatish Balay    Assume: sizes should be long enough to hold all the values.
879bea157c4SSatish Balay */
8805615d1e5SSatish Balay #undef __FUNC__
881bea157c4SSatish Balay #define __FUNC__ "MatZeroRows_SeqBAIJ_Check_Blocks"
882bea157c4SSatish Balay static int MatZeroRows_SeqBAIJ_Check_Blocks(int idx[],int n,int bs,int sizes[], int *bs_max)
883d9b7c43dSSatish Balay {
884bea157c4SSatish Balay   int        i,j,k,row;
885bea157c4SSatish Balay   PetscTruth flg;
8863a40ed3dSBarry Smith 
887433994e6SBarry Smith   PetscFunctionBegin;
888bea157c4SSatish Balay   for (i=0,j=0; i<n; j++) {
889bea157c4SSatish Balay     row = idx[i];
890bea157c4SSatish Balay     if (row%bs!=0) { /* Not the begining of a block */
891bea157c4SSatish Balay       sizes[j] = 1;
892bea157c4SSatish Balay       i++;
893e4fda26cSSatish Balay     } else if (i+bs > n) { /* complete block doesn't exist (at idx end) */
894bea157c4SSatish Balay       sizes[j] = 1;         /* Also makes sure atleast 'bs' values exist for next else */
895bea157c4SSatish Balay       i++;
896bea157c4SSatish Balay     } else { /* Begining of the block, so check if the complete block exists */
897bea157c4SSatish Balay       flg = PETSC_TRUE;
898bea157c4SSatish Balay       for (k=1; k<bs; k++) {
899bea157c4SSatish Balay         if (row+k != idx[i+k]) { /* break in the block */
900bea157c4SSatish Balay           flg = PETSC_FALSE;
901bea157c4SSatish Balay           break;
902d9b7c43dSSatish Balay         }
903bea157c4SSatish Balay       }
904bea157c4SSatish Balay       if (flg == PETSC_TRUE) { /* No break in the bs */
905bea157c4SSatish Balay         sizes[j] = bs;
906bea157c4SSatish Balay         i+= bs;
907bea157c4SSatish Balay       } else {
908bea157c4SSatish Balay         sizes[j] = 1;
909bea157c4SSatish Balay         i++;
910bea157c4SSatish Balay       }
911bea157c4SSatish Balay     }
912bea157c4SSatish Balay   }
913bea157c4SSatish Balay   *bs_max = j;
9143a40ed3dSBarry Smith   PetscFunctionReturn(0);
915d9b7c43dSSatish Balay }
916d9b7c43dSSatish Balay 
9175615d1e5SSatish Balay #undef __FUNC__
9185615d1e5SSatish Balay #define __FUNC__ "MatZeroRows_SeqBAIJ"
9198f6be9afSLois Curfman McInnes int MatZeroRows_SeqBAIJ(Mat A,IS is,Scalar *diag)
920d9b7c43dSSatish Balay {
921d9b7c43dSSatish Balay   Mat_SeqBAIJ *baij=(Mat_SeqBAIJ*)A->data;
922b6815fffSBarry Smith   int         ierr,i,j,k,count,is_n,*is_idx,*rows;
923bea157c4SSatish Balay   int         bs=baij->bs,bs2=baij->bs2,*sizes,row,bs_max;
9243f1db9ecSBarry Smith   Scalar      zero = 0.0;
9253f1db9ecSBarry Smith   MatScalar   *aa;
926d9b7c43dSSatish Balay 
9273a40ed3dSBarry Smith   PetscFunctionBegin;
928d9b7c43dSSatish Balay   /* Make a copy of the IS and  sort it */
929d9b7c43dSSatish Balay   ierr = ISGetSize(is,&is_n);CHKERRQ(ierr);
930d9b7c43dSSatish Balay   ierr = ISGetIndices(is,&is_idx);CHKERRQ(ierr);
931d9b7c43dSSatish Balay 
932bea157c4SSatish Balay   /* allocate memory for rows,sizes */
933bea157c4SSatish Balay   rows  = (int*)PetscMalloc((3*is_n+1)*sizeof(int));CHKPTRQ(rows);
934bea157c4SSatish Balay   sizes = rows + is_n;
935bea157c4SSatish Balay 
936bea157c4SSatish Balay   /* initialize copy IS valurs to rows, and sort them */
937bea157c4SSatish Balay   for (i=0; i<is_n; i++) { rows[i] = is_idx[i]; }
938bea157c4SSatish Balay   ierr = PetscSortInt(is_n,rows);CHKERRQ(ierr);
939dffd3267SBarry Smith   if (baij->keepzeroedrows) {
940dffd3267SBarry Smith     for (i=0; i<is_n; i++) { sizes[i] = 1; }
941dffd3267SBarry Smith     bs_max = is_n;
942dffd3267SBarry Smith   } else {
943bea157c4SSatish Balay     ierr = MatZeroRows_SeqBAIJ_Check_Blocks(rows,is_n,bs,sizes,&bs_max);CHKERRQ(ierr);
944dffd3267SBarry Smith   }
945b97a56abSSatish Balay   ierr = ISRestoreIndices(is,&is_idx);CHKERRQ(ierr);
946bea157c4SSatish Balay 
947bea157c4SSatish Balay   for (i=0,j=0; i<bs_max; j+=sizes[i],i++) {
948bea157c4SSatish Balay     row   = rows[j];
949b6815fffSBarry Smith     if (row < 0 || row > baij->m) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,0,"row %d out of range",row);
950bea157c4SSatish Balay     count = (baij->i[row/bs +1] - baij->i[row/bs])*bs;
951bea157c4SSatish Balay     aa    = baij->a + baij->i[row/bs]*bs2 + (row%bs);
952dffd3267SBarry Smith     if (sizes[i] == bs && !baij->keepzeroedrows) {
953bea157c4SSatish Balay       if (diag) {
954bea157c4SSatish Balay         if (baij->ilen[row/bs] > 0) {
955bea157c4SSatish Balay           baij->ilen[row/bs] = 1;
956bea157c4SSatish Balay           baij->j[baij->i[row/bs]] = row/bs;
957bea157c4SSatish Balay           ierr = PetscMemzero(aa,count*bs*sizeof(MatScalar));CHKERRQ(ierr);
958a07cd24cSSatish Balay         }
959bea157c4SSatish Balay         /* Now insert all the diagoanl values for this bs */
960bea157c4SSatish Balay         for (k=0; k<bs; k++) {
961bea157c4SSatish Balay           ierr = (*A->ops->setvalues)(A,1,rows+j+k,1,rows+j+k,diag,INSERT_VALUES);CHKERRQ(ierr);
962bea157c4SSatish Balay         }
963bea157c4SSatish Balay       } else { /* (!diag) */
964bea157c4SSatish Balay         baij->ilen[row/bs] = 0;
965bea157c4SSatish Balay       } /* end (!diag) */
966bea157c4SSatish Balay     } else { /* (sizes[i] != bs) */
967aa482453SBarry Smith #if defined (PETSC_USE_DEBUG)
968bea157c4SSatish Balay       if (sizes[i] != 1) SETERRQ(1,0,"Internal Error. Value should be 1");
969bea157c4SSatish Balay #endif
970bea157c4SSatish Balay       for (k=0; k<count; k++) {
971d9b7c43dSSatish Balay         aa[0] = zero;
972d9b7c43dSSatish Balay         aa+=bs;
973d9b7c43dSSatish Balay       }
974d9b7c43dSSatish Balay       if (diag) {
975f830108cSBarry Smith         ierr = (*A->ops->setvalues)(A,1,rows+j,1,rows+j,diag,INSERT_VALUES);CHKERRQ(ierr);
976d9b7c43dSSatish Balay       }
977d9b7c43dSSatish Balay     }
978bea157c4SSatish Balay   }
979bea157c4SSatish Balay 
980606d414cSSatish Balay   ierr = PetscFree(rows);CHKERRQ(ierr);
9819a8dea36SBarry Smith   ierr = MatAssemblyEnd_SeqBAIJ(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
9823a40ed3dSBarry Smith   PetscFunctionReturn(0);
983d9b7c43dSSatish Balay }
9841c351548SSatish Balay 
9855615d1e5SSatish Balay #undef __FUNC__
9862d61bbb3SSatish Balay #define __FUNC__ "MatSetValues_SeqBAIJ"
9872d61bbb3SSatish Balay int MatSetValues_SeqBAIJ(Mat A,int m,int *im,int n,int *in,Scalar *v,InsertMode is)
9882d61bbb3SSatish Balay {
9892d61bbb3SSatish Balay   Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)A->data;
9902d61bbb3SSatish Balay   int         *rp,k,low,high,t,ii,row,nrow,i,col,l,rmax,N,sorted=a->sorted;
9912d61bbb3SSatish Balay   int         *imax=a->imax,*ai=a->i,*ailen=a->ilen,roworiented=a->roworiented;
9922d61bbb3SSatish Balay   int         *aj=a->j,nonew=a->nonew,bs=a->bs,brow,bcol;
993549d3d68SSatish Balay   int         ridx,cidx,bs2=a->bs2,ierr;
9943f1db9ecSBarry Smith   MatScalar   *ap,value,*aa=a->a,*bap;
9952d61bbb3SSatish Balay 
9962d61bbb3SSatish Balay   PetscFunctionBegin;
9972d61bbb3SSatish Balay   for (k=0; k<m; k++) { /* loop over added rows */
9982d61bbb3SSatish Balay     row  = im[k]; brow = row/bs;
9995ef9f2a5SBarry Smith     if (row < 0) continue;
1000aa482453SBarry Smith #if defined(PETSC_USE_BOPT_g)
100132e87ba3SBarry Smith     if (row >= a->m) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,0,"Row too large: row %d max %d",row,a->m);
10022d61bbb3SSatish Balay #endif
10032d61bbb3SSatish Balay     rp   = aj + ai[brow];
10042d61bbb3SSatish Balay     ap   = aa + bs2*ai[brow];
10052d61bbb3SSatish Balay     rmax = imax[brow];
10062d61bbb3SSatish Balay     nrow = ailen[brow];
10072d61bbb3SSatish Balay     low  = 0;
10082d61bbb3SSatish Balay     for (l=0; l<n; l++) { /* loop over added columns */
10095ef9f2a5SBarry Smith       if (in[l] < 0) continue;
1010aa482453SBarry Smith #if defined(PETSC_USE_BOPT_g)
101132e87ba3SBarry Smith       if (in[l] >= a->n) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,0,"Column too large: col %d max %d",in[l],a->n);
10122d61bbb3SSatish Balay #endif
10132d61bbb3SSatish Balay       col = in[l]; bcol = col/bs;
10142d61bbb3SSatish Balay       ridx = row % bs; cidx = col % bs;
10152d61bbb3SSatish Balay       if (roworiented) {
10165ef9f2a5SBarry Smith         value = v[l + k*n];
10172d61bbb3SSatish Balay       } else {
10182d61bbb3SSatish Balay         value = v[k + l*m];
10192d61bbb3SSatish Balay       }
10202d61bbb3SSatish Balay       if (!sorted) low = 0; high = nrow;
10212d61bbb3SSatish Balay       while (high-low > 7) {
10222d61bbb3SSatish Balay         t = (low+high)/2;
10232d61bbb3SSatish Balay         if (rp[t] > bcol) high = t;
10242d61bbb3SSatish Balay         else              low  = t;
10252d61bbb3SSatish Balay       }
10262d61bbb3SSatish Balay       for (i=low; i<high; i++) {
10272d61bbb3SSatish Balay         if (rp[i] > bcol) break;
10282d61bbb3SSatish Balay         if (rp[i] == bcol) {
10292d61bbb3SSatish Balay           bap  = ap +  bs2*i + bs*cidx + ridx;
10302d61bbb3SSatish Balay           if (is == ADD_VALUES) *bap += value;
10312d61bbb3SSatish Balay           else                  *bap  = value;
10322d61bbb3SSatish Balay           goto noinsert1;
10332d61bbb3SSatish Balay         }
10342d61bbb3SSatish Balay       }
10352d61bbb3SSatish Balay       if (nonew == 1) goto noinsert1;
10362d61bbb3SSatish Balay       else if (nonew == -1) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Inserting a new nonzero in the matrix");
10372d61bbb3SSatish Balay       if (nrow >= rmax) {
10382d61bbb3SSatish Balay         /* there is no extra room in row, therefore enlarge */
10392d61bbb3SSatish Balay         int       new_nz = ai[a->mbs] + CHUNKSIZE,len,*new_i,*new_j;
10403f1db9ecSBarry Smith         MatScalar *new_a;
10412d61bbb3SSatish Balay 
10422d61bbb3SSatish Balay         if (nonew == -2) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Inserting a new nonzero in the matrix");
10432d61bbb3SSatish Balay 
10442d61bbb3SSatish Balay         /* Malloc new storage space */
10453f1db9ecSBarry Smith         len     = new_nz*(sizeof(int)+bs2*sizeof(MatScalar))+(a->mbs+1)*sizeof(int);
10463f1db9ecSBarry Smith         new_a   = (MatScalar*)PetscMalloc(len);CHKPTRQ(new_a);
10472d61bbb3SSatish Balay         new_j   = (int*)(new_a + bs2*new_nz);
10482d61bbb3SSatish Balay         new_i   = new_j + new_nz;
10492d61bbb3SSatish Balay 
10502d61bbb3SSatish Balay         /* copy over old data into new slots */
10512d61bbb3SSatish Balay         for (ii=0; ii<brow+1; ii++) {new_i[ii] = ai[ii];}
10522d61bbb3SSatish Balay         for (ii=brow+1; ii<a->mbs+1; ii++) {new_i[ii] = ai[ii]+CHUNKSIZE;}
1053549d3d68SSatish Balay         ierr = PetscMemcpy(new_j,aj,(ai[brow]+nrow)*sizeof(int));CHKERRQ(ierr);
10542d61bbb3SSatish Balay         len  = (new_nz - CHUNKSIZE - ai[brow] - nrow);
1055549d3d68SSatish Balay         ierr = PetscMemcpy(new_j+ai[brow]+nrow+CHUNKSIZE,aj+ai[brow]+nrow,len*sizeof(int));CHKERRQ(ierr);
1056549d3d68SSatish Balay         ierr = PetscMemcpy(new_a,aa,(ai[brow]+nrow)*bs2*sizeof(MatScalar));CHKERRQ(ierr);
1057549d3d68SSatish Balay         ierr = PetscMemzero(new_a+bs2*(ai[brow]+nrow),bs2*CHUNKSIZE*sizeof(MatScalar));CHKERRQ(ierr);
1058549d3d68SSatish Balay         ierr = PetscMemcpy(new_a+bs2*(ai[brow]+nrow+CHUNKSIZE),aa+bs2*(ai[brow]+nrow),bs2*len*sizeof(MatScalar));CHKERRQ(ierr);
10592d61bbb3SSatish Balay         /* free up old matrix storage */
1060606d414cSSatish Balay         ierr = PetscFree(a->a);CHKERRQ(ierr);
1061606d414cSSatish Balay         if (!a->singlemalloc) {
1062606d414cSSatish Balay           ierr = PetscFree(a->i);CHKERRQ(ierr);
1063606d414cSSatish Balay           ierr = PetscFree(a->j);CHKERRQ(ierr);
1064606d414cSSatish Balay         }
10652d61bbb3SSatish Balay         aa = a->a = new_a; ai = a->i = new_i; aj = a->j = new_j;
1066c4992f7dSBarry Smith         a->singlemalloc = PETSC_TRUE;
10672d61bbb3SSatish Balay 
10682d61bbb3SSatish Balay         rp   = aj + ai[brow]; ap = aa + bs2*ai[brow];
10692d61bbb3SSatish Balay         rmax = imax[brow] = imax[brow] + CHUNKSIZE;
10703f1db9ecSBarry Smith         PLogObjectMemory(A,CHUNKSIZE*(sizeof(int) + bs2*sizeof(MatScalar)));
10712d61bbb3SSatish Balay         a->maxnz += bs2*CHUNKSIZE;
10722d61bbb3SSatish Balay         a->reallocs++;
10732d61bbb3SSatish Balay         a->nz++;
10742d61bbb3SSatish Balay       }
10752d61bbb3SSatish Balay       N = nrow++ - 1;
10762d61bbb3SSatish Balay       /* shift up all the later entries in this row */
10772d61bbb3SSatish Balay       for (ii=N; ii>=i; ii--) {
10782d61bbb3SSatish Balay         rp[ii+1] = rp[ii];
1079549d3d68SSatish Balay         ierr     = PetscMemcpy(ap+bs2*(ii+1),ap+bs2*(ii),bs2*sizeof(MatScalar));CHKERRQ(ierr);
10802d61bbb3SSatish Balay       }
1081549d3d68SSatish Balay       if (N>=i) {
1082549d3d68SSatish Balay         ierr = PetscMemzero(ap+bs2*i,bs2*sizeof(MatScalar));CHKERRQ(ierr);
1083549d3d68SSatish Balay       }
10842d61bbb3SSatish Balay       rp[i]                      = bcol;
10852d61bbb3SSatish Balay       ap[bs2*i + bs*cidx + ridx] = value;
10862d61bbb3SSatish Balay       noinsert1:;
10872d61bbb3SSatish Balay       low = i;
10882d61bbb3SSatish Balay     }
10892d61bbb3SSatish Balay     ailen[brow] = nrow;
10902d61bbb3SSatish Balay   }
10912d61bbb3SSatish Balay   PetscFunctionReturn(0);
10922d61bbb3SSatish Balay }
10932d61bbb3SSatish Balay 
10940e6d2581SBarry Smith extern int MatLUFactorSymbolic_SeqBAIJ(Mat,IS,IS,PetscReal,Mat*);
10950e6d2581SBarry Smith extern int MatLUFactor_SeqBAIJ(Mat,IS,IS,PetscReal);
10962d61bbb3SSatish Balay extern int MatIncreaseOverlap_SeqBAIJ(Mat,int,IS*,int);
10977b2a1423SBarry Smith extern int MatGetSubMatrix_SeqBAIJ(Mat,IS,IS,int,MatReuse,Mat*);
10987b2a1423SBarry Smith extern int MatGetSubMatrices_SeqBAIJ(Mat,int,IS*,IS*,MatReuse,Mat**);
10997c922b88SBarry Smith extern int MatMultTranspose_SeqBAIJ(Mat,Vec,Vec);
11007c922b88SBarry Smith extern int MatMultTransposeAdd_SeqBAIJ(Mat,Vec,Vec,Vec);
11012d61bbb3SSatish Balay extern int MatScale_SeqBAIJ(Scalar*,Mat);
11020e6d2581SBarry Smith extern int MatNorm_SeqBAIJ(Mat,NormType,PetscReal *);
11032d61bbb3SSatish Balay extern int MatEqual_SeqBAIJ(Mat,Mat,PetscTruth*);
11042d61bbb3SSatish Balay extern int MatGetDiagonal_SeqBAIJ(Mat,Vec);
11052d61bbb3SSatish Balay extern int MatDiagonalScale_SeqBAIJ(Mat,Vec,Vec);
11062d61bbb3SSatish Balay extern int MatGetInfo_SeqBAIJ(Mat,MatInfoType,MatInfo *);
11072d61bbb3SSatish Balay extern int MatZeroEntries_SeqBAIJ(Mat);
11082d61bbb3SSatish Balay 
11092d61bbb3SSatish Balay extern int MatSolve_SeqBAIJ_N(Mat,Vec,Vec);
11102d61bbb3SSatish Balay extern int MatSolve_SeqBAIJ_1(Mat,Vec,Vec);
11112d61bbb3SSatish Balay extern int MatSolve_SeqBAIJ_2(Mat,Vec,Vec);
11122d61bbb3SSatish Balay extern int MatSolve_SeqBAIJ_3(Mat,Vec,Vec);
11132d61bbb3SSatish Balay extern int MatSolve_SeqBAIJ_4(Mat,Vec,Vec);
11142d61bbb3SSatish Balay extern int MatSolve_SeqBAIJ_5(Mat,Vec,Vec);
111515091d37SBarry Smith extern int MatSolve_SeqBAIJ_6(Mat,Vec,Vec);
11162d61bbb3SSatish Balay extern int MatSolve_SeqBAIJ_7(Mat,Vec,Vec);
11177c922b88SBarry Smith extern int MatSolveTranspose_SeqBAIJ_7(Mat,Vec,Vec);
11187c922b88SBarry Smith extern int MatSolveTranspose_SeqBAIJ_6(Mat,Vec,Vec);
11197c922b88SBarry Smith extern int MatSolveTranspose_SeqBAIJ_5(Mat,Vec,Vec);
11207c922b88SBarry Smith extern int MatSolveTranspose_SeqBAIJ_4(Mat,Vec,Vec);
11217c922b88SBarry Smith extern int MatSolveTranspose_SeqBAIJ_3(Mat,Vec,Vec);
11227c922b88SBarry Smith extern int MatSolveTranspose_SeqBAIJ_2(Mat,Vec,Vec);
11237c922b88SBarry Smith extern int MatSolveTranspose_SeqBAIJ_1(Mat,Vec,Vec);
11242d61bbb3SSatish Balay 
11252d61bbb3SSatish Balay extern int MatLUFactorNumeric_SeqBAIJ_N(Mat,Mat*);
11262d61bbb3SSatish Balay extern int MatLUFactorNumeric_SeqBAIJ_1(Mat,Mat*);
11272d61bbb3SSatish Balay extern int MatLUFactorNumeric_SeqBAIJ_2(Mat,Mat*);
11282d61bbb3SSatish Balay extern int MatLUFactorNumeric_SeqBAIJ_3(Mat,Mat*);
11292d61bbb3SSatish Balay extern int MatLUFactorNumeric_SeqBAIJ_4(Mat,Mat*);
11302d61bbb3SSatish Balay extern int MatLUFactorNumeric_SeqBAIJ_5(Mat,Mat*);
113115091d37SBarry Smith extern int MatLUFactorNumeric_SeqBAIJ_6(Mat,Mat*);
11322d61bbb3SSatish Balay 
11332d61bbb3SSatish Balay extern int MatMult_SeqBAIJ_1(Mat,Vec,Vec);
11342d61bbb3SSatish Balay extern int MatMult_SeqBAIJ_2(Mat,Vec,Vec);
11352d61bbb3SSatish Balay extern int MatMult_SeqBAIJ_3(Mat,Vec,Vec);
11362d61bbb3SSatish Balay extern int MatMult_SeqBAIJ_4(Mat,Vec,Vec);
11372d61bbb3SSatish Balay extern int MatMult_SeqBAIJ_5(Mat,Vec,Vec);
113815091d37SBarry Smith extern int MatMult_SeqBAIJ_6(Mat,Vec,Vec);
11392d61bbb3SSatish Balay extern int MatMult_SeqBAIJ_7(Mat,Vec,Vec);
11402d61bbb3SSatish Balay extern int MatMult_SeqBAIJ_N(Mat,Vec,Vec);
11412d61bbb3SSatish Balay 
11422d61bbb3SSatish Balay extern int MatMultAdd_SeqBAIJ_1(Mat,Vec,Vec,Vec);
11432d61bbb3SSatish Balay extern int MatMultAdd_SeqBAIJ_2(Mat,Vec,Vec,Vec);
11442d61bbb3SSatish Balay extern int MatMultAdd_SeqBAIJ_3(Mat,Vec,Vec,Vec);
11452d61bbb3SSatish Balay extern int MatMultAdd_SeqBAIJ_4(Mat,Vec,Vec,Vec);
11462d61bbb3SSatish Balay extern int MatMultAdd_SeqBAIJ_5(Mat,Vec,Vec,Vec);
114715091d37SBarry Smith extern int MatMultAdd_SeqBAIJ_6(Mat,Vec,Vec,Vec);
11482d61bbb3SSatish Balay extern int MatMultAdd_SeqBAIJ_7(Mat,Vec,Vec,Vec);
11492d61bbb3SSatish Balay extern int MatMultAdd_SeqBAIJ_N(Mat,Vec,Vec,Vec);
11502d61bbb3SSatish Balay 
11512d61bbb3SSatish Balay #undef __FUNC__
11522d61bbb3SSatish Balay #define __FUNC__ "MatILUFactor_SeqBAIJ"
11535ef9f2a5SBarry Smith int MatILUFactor_SeqBAIJ(Mat inA,IS row,IS col,MatILUInfo *info)
11542d61bbb3SSatish Balay {
11552d61bbb3SSatish Balay   Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)inA->data;
11562d61bbb3SSatish Balay   Mat         outA;
11572d61bbb3SSatish Balay   int         ierr;
1158667159a5SBarry Smith   PetscTruth  row_identity,col_identity;
11592d61bbb3SSatish Balay 
11602d61bbb3SSatish Balay   PetscFunctionBegin;
1161b6d21a55SBarry Smith   if (info && info->levels != 0) SETERRQ(PETSC_ERR_SUP,0,"Only levels = 0 supported for in-place ILU");
1162667159a5SBarry Smith   ierr = ISIdentity(row,&row_identity);CHKERRQ(ierr);
1163667159a5SBarry Smith   ierr = ISIdentity(col,&col_identity);CHKERRQ(ierr);
1164667159a5SBarry Smith   if (!row_identity || !col_identity) {
1165b008c796SBarry Smith     SETERRQ(1,1,"Row and column permutations must be identity for in-place ILU");
1166667159a5SBarry Smith   }
11672d61bbb3SSatish Balay 
11682d61bbb3SSatish Balay   outA          = inA;
11692d61bbb3SSatish Balay   inA->factor   = FACTOR_LU;
11702d61bbb3SSatish Balay 
11712d61bbb3SSatish Balay   if (!a->diag) {
1172c4992f7dSBarry Smith     ierr = MatMarkDiagonal_SeqBAIJ(inA);CHKERRQ(ierr);
11732d61bbb3SSatish Balay   }
11742d61bbb3SSatish Balay   /*
117515091d37SBarry Smith       Blocksize 2, 3, 4, 5, 6 and 7 have a special faster factorization/solver
117615091d37SBarry Smith       for ILU(0) factorization with natural ordering
11772d61bbb3SSatish Balay   */
117815091d37SBarry Smith   switch (a->bs) {
1179f1af5d2fSBarry Smith   case 1:
11807c922b88SBarry Smith     inA->ops->solvetranspose   = MatSolveTranspose_SeqBAIJ_2_NaturalOrdering;
1181f1af5d2fSBarry Smith     PLogInfo(inA,"MatILUFactor_SeqBAIJ:Using special in-place natural ordering solvetrans BS=1\n");
118215091d37SBarry Smith   case 2:
118315091d37SBarry Smith     inA->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_2_NaturalOrdering;
118415091d37SBarry Smith     inA->ops->solve           = MatSolve_SeqBAIJ_2_NaturalOrdering;
11857c922b88SBarry Smith     inA->ops->solvetranspose  = MatSolveTranspose_SeqBAIJ_2_NaturalOrdering;
118615091d37SBarry Smith     PLogInfo(inA,"MatILUFactor_SeqBAIJ:Using special in-place natural ordering factor and solve BS=2\n");
118715091d37SBarry Smith     break;
118815091d37SBarry Smith   case 3:
118915091d37SBarry Smith     inA->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_3_NaturalOrdering;
119015091d37SBarry Smith     inA->ops->solve           = MatSolve_SeqBAIJ_3_NaturalOrdering;
11917c922b88SBarry Smith     inA->ops->solvetranspose  = MatSolveTranspose_SeqBAIJ_3_NaturalOrdering;
119215091d37SBarry Smith     PLogInfo(inA,"MatILUFactor_SeqBAIJ:Using special in-place natural ordering factor and solve BS=3\n");
119315091d37SBarry Smith     break;
119415091d37SBarry Smith   case 4:
1195667159a5SBarry Smith     inA->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_4_NaturalOrdering;
1196f830108cSBarry Smith     inA->ops->solve           = MatSolve_SeqBAIJ_4_NaturalOrdering;
11977c922b88SBarry Smith     inA->ops->solvetranspose  = MatSolveTranspose_SeqBAIJ_4_NaturalOrdering;
119815091d37SBarry Smith     PLogInfo(inA,"MatILUFactor_SeqBAIJ:Using special in-place natural ordering factor and solve BS=4\n");
119915091d37SBarry Smith     break;
120015091d37SBarry Smith   case 5:
1201667159a5SBarry Smith     inA->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_5_NaturalOrdering;
1202667159a5SBarry Smith     inA->ops->solve           = MatSolve_SeqBAIJ_5_NaturalOrdering;
12037c922b88SBarry Smith     inA->ops->solvetranspose  = MatSolveTranspose_SeqBAIJ_5_NaturalOrdering;
120415091d37SBarry Smith     PLogInfo(inA,"MatILUFactor_SeqBAIJ:Using special in-place natural ordering factor and solve BS=5\n");
120515091d37SBarry Smith     break;
120615091d37SBarry Smith   case 6:
120715091d37SBarry Smith     inA->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_6_NaturalOrdering;
120815091d37SBarry Smith     inA->ops->solve           = MatSolve_SeqBAIJ_6_NaturalOrdering;
12097c922b88SBarry Smith     inA->ops->solvetranspose  = MatSolveTranspose_SeqBAIJ_6_NaturalOrdering;
121015091d37SBarry Smith     PLogInfo(inA,"MatILUFactor_SeqBAIJ:Using special in-place natural ordering factor and solve BS=6\n");
121115091d37SBarry Smith     break;
121215091d37SBarry Smith   case 7:
121315091d37SBarry Smith     inA->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_7_NaturalOrdering;
12147c922b88SBarry Smith     inA->ops->solvetranspose  = MatSolveTranspose_SeqBAIJ_7_NaturalOrdering;
121515091d37SBarry Smith     inA->ops->solve           = MatSolve_SeqBAIJ_7_NaturalOrdering;
121615091d37SBarry Smith     PLogInfo(inA,"MatILUFactor_SeqBAIJ:Using special in-place natural ordering factor and solve BS=7\n");
121715091d37SBarry Smith     break;
1218c38d4ed2SBarry Smith   default:
1219c38d4ed2SBarry Smith     a->row        = row;
1220c38d4ed2SBarry Smith     a->col        = col;
1221c38d4ed2SBarry Smith     ierr          = PetscObjectReference((PetscObject)row);CHKERRQ(ierr);
1222c38d4ed2SBarry Smith     ierr          = PetscObjectReference((PetscObject)col);CHKERRQ(ierr);
1223c38d4ed2SBarry Smith 
1224c38d4ed2SBarry Smith     /* Create the invert permutation so that it can be used in MatLUFactorNumeric() */
1225c38d4ed2SBarry Smith     ierr = ISInvertPermutation(col,&(a->icol));CHKERRQ(ierr);
1226c38d4ed2SBarry Smith     PLogObjectParent(inA,a->icol);
1227c38d4ed2SBarry Smith 
1228c38d4ed2SBarry Smith     if (!a->solve_work) {
1229c38d4ed2SBarry Smith       a->solve_work = (Scalar*)PetscMalloc((a->m+a->bs)*sizeof(Scalar));CHKPTRQ(a->solve_work);
1230c38d4ed2SBarry Smith       PLogObjectMemory(inA,(a->m+a->bs)*sizeof(Scalar));
1231c38d4ed2SBarry Smith     }
12322d61bbb3SSatish Balay   }
12332d61bbb3SSatish Balay 
1234667159a5SBarry Smith   ierr = MatLUFactorNumeric(inA,&outA);CHKERRQ(ierr);
1235667159a5SBarry Smith 
12362d61bbb3SSatish Balay   PetscFunctionReturn(0);
12372d61bbb3SSatish Balay }
12382d61bbb3SSatish Balay #undef __FUNC__
1239d4bb536fSBarry Smith #define __FUNC__ "MatPrintHelp_SeqBAIJ"
1240ba4ca20aSSatish Balay int MatPrintHelp_SeqBAIJ(Mat A)
1241ba4ca20aSSatish Balay {
1242c38d4ed2SBarry Smith   static PetscTruth called = PETSC_FALSE;
1243ba4ca20aSSatish Balay   MPI_Comm          comm = A->comm;
1244d132466eSBarry Smith   int               ierr;
1245ba4ca20aSSatish Balay 
12463a40ed3dSBarry Smith   PetscFunctionBegin;
1247c38d4ed2SBarry Smith   if (called) {PetscFunctionReturn(0);} else called = PETSC_TRUE;
1248d132466eSBarry Smith   ierr = (*PetscHelpPrintf)(comm," Options for MATSEQBAIJ and MATMPIBAIJ matrix formats (the defaults):\n");CHKERRQ(ierr);
1249d132466eSBarry Smith   ierr = (*PetscHelpPrintf)(comm,"  -mat_block_size <block_size>\n");CHKERRQ(ierr);
12503a40ed3dSBarry Smith   PetscFunctionReturn(0);
1251ba4ca20aSSatish Balay }
1252d9b7c43dSSatish Balay 
1253fb2e594dSBarry Smith EXTERN_C_BEGIN
125427a8da17SBarry Smith #undef __FUNC__
125527a8da17SBarry Smith #define __FUNC__ "MatSeqBAIJSetColumnIndices_SeqBAIJ"
125627a8da17SBarry Smith int MatSeqBAIJSetColumnIndices_SeqBAIJ(Mat mat,int *indices)
125727a8da17SBarry Smith {
125827a8da17SBarry Smith   Mat_SeqBAIJ *baij = (Mat_SeqBAIJ *)mat->data;
125927a8da17SBarry Smith   int         i,nz,n;
126027a8da17SBarry Smith 
126127a8da17SBarry Smith   PetscFunctionBegin;
126227a8da17SBarry Smith   nz = baij->maxnz;
126327a8da17SBarry Smith   n  = baij->n;
126427a8da17SBarry Smith   for (i=0; i<nz; i++) {
126527a8da17SBarry Smith     baij->j[i] = indices[i];
126627a8da17SBarry Smith   }
126727a8da17SBarry Smith   baij->nz = nz;
126827a8da17SBarry Smith   for (i=0; i<n; i++) {
126927a8da17SBarry Smith     baij->ilen[i] = baij->imax[i];
127027a8da17SBarry Smith   }
127127a8da17SBarry Smith 
127227a8da17SBarry Smith   PetscFunctionReturn(0);
127327a8da17SBarry Smith }
1274fb2e594dSBarry Smith EXTERN_C_END
127527a8da17SBarry Smith 
127627a8da17SBarry Smith #undef __FUNC__
127727a8da17SBarry Smith #define __FUNC__ "MatSeqBAIJSetColumnIndices"
127827a8da17SBarry Smith /*@
127927a8da17SBarry Smith     MatSeqBAIJSetColumnIndices - Set the column indices for all the rows
128027a8da17SBarry Smith        in the matrix.
128127a8da17SBarry Smith 
128227a8da17SBarry Smith   Input Parameters:
128327a8da17SBarry Smith +  mat - the SeqBAIJ matrix
128427a8da17SBarry Smith -  indices - the column indices
128527a8da17SBarry Smith 
128615091d37SBarry Smith   Level: advanced
128715091d37SBarry Smith 
128827a8da17SBarry Smith   Notes:
128927a8da17SBarry Smith     This can be called if you have precomputed the nonzero structure of the
129027a8da17SBarry Smith   matrix and want to provide it to the matrix object to improve the performance
129127a8da17SBarry Smith   of the MatSetValues() operation.
129227a8da17SBarry Smith 
129327a8da17SBarry Smith     You MUST have set the correct numbers of nonzeros per row in the call to
129427a8da17SBarry Smith   MatCreateSeqBAIJ().
129527a8da17SBarry Smith 
129627a8da17SBarry Smith     MUST be called before any calls to MatSetValues();
129727a8da17SBarry Smith 
129827a8da17SBarry Smith @*/
129927a8da17SBarry Smith int MatSeqBAIJSetColumnIndices(Mat mat,int *indices)
130027a8da17SBarry Smith {
130127a8da17SBarry Smith   int ierr,(*f)(Mat,int *);
130227a8da17SBarry Smith 
130327a8da17SBarry Smith   PetscFunctionBegin;
130427a8da17SBarry Smith   PetscValidHeaderSpecific(mat,MAT_COOKIE);
1305549d3d68SSatish Balay   ierr = PetscObjectQueryFunction((PetscObject)mat,"MatSeqBAIJSetColumnIndices_C",(void **)&f);CHKERRQ(ierr);
130627a8da17SBarry Smith   if (f) {
130727a8da17SBarry Smith     ierr = (*f)(mat,indices);CHKERRQ(ierr);
130827a8da17SBarry Smith   } else {
130927a8da17SBarry Smith     SETERRQ(1,1,"Wrong type of matrix to set column indices");
131027a8da17SBarry Smith   }
131127a8da17SBarry Smith   PetscFunctionReturn(0);
131227a8da17SBarry Smith }
131327a8da17SBarry Smith 
13142593348eSBarry Smith /* -------------------------------------------------------------------*/
1315cc2dc46cSBarry Smith static struct _MatOps MatOps_Values = {MatSetValues_SeqBAIJ,
1316cc2dc46cSBarry Smith        MatGetRow_SeqBAIJ,
1317cc2dc46cSBarry Smith        MatRestoreRow_SeqBAIJ,
1318cc2dc46cSBarry Smith        MatMult_SeqBAIJ_N,
1319cc2dc46cSBarry Smith        MatMultAdd_SeqBAIJ_N,
13207c922b88SBarry Smith        MatMultTranspose_SeqBAIJ,
13217c922b88SBarry Smith        MatMultTransposeAdd_SeqBAIJ,
1322cc2dc46cSBarry Smith        MatSolve_SeqBAIJ_N,
1323cc2dc46cSBarry Smith        0,
1324cc2dc46cSBarry Smith        0,
1325cc2dc46cSBarry Smith        0,
1326cc2dc46cSBarry Smith        MatLUFactor_SeqBAIJ,
1327cc2dc46cSBarry Smith        0,
1328b6490206SBarry Smith        0,
1329f2501298SSatish Balay        MatTranspose_SeqBAIJ,
1330cc2dc46cSBarry Smith        MatGetInfo_SeqBAIJ,
1331cc2dc46cSBarry Smith        MatEqual_SeqBAIJ,
1332cc2dc46cSBarry Smith        MatGetDiagonal_SeqBAIJ,
1333cc2dc46cSBarry Smith        MatDiagonalScale_SeqBAIJ,
1334cc2dc46cSBarry Smith        MatNorm_SeqBAIJ,
1335b6490206SBarry Smith        0,
1336cc2dc46cSBarry Smith        MatAssemblyEnd_SeqBAIJ,
1337cc2dc46cSBarry Smith        0,
1338cc2dc46cSBarry Smith        MatSetOption_SeqBAIJ,
1339cc2dc46cSBarry Smith        MatZeroEntries_SeqBAIJ,
1340cc2dc46cSBarry Smith        MatZeroRows_SeqBAIJ,
1341cc2dc46cSBarry Smith        MatLUFactorSymbolic_SeqBAIJ,
1342cc2dc46cSBarry Smith        MatLUFactorNumeric_SeqBAIJ_N,
1343cc2dc46cSBarry Smith        0,
1344cc2dc46cSBarry Smith        0,
1345cc2dc46cSBarry Smith        MatGetSize_SeqBAIJ,
1346cc2dc46cSBarry Smith        MatGetSize_SeqBAIJ,
1347cc2dc46cSBarry Smith        MatGetOwnershipRange_SeqBAIJ,
1348cc2dc46cSBarry Smith        MatILUFactorSymbolic_SeqBAIJ,
1349cc2dc46cSBarry Smith        0,
1350cc2dc46cSBarry Smith        0,
1351cc2dc46cSBarry Smith        0,
13522e8a6d31SBarry Smith        MatDuplicate_SeqBAIJ,
1353cc2dc46cSBarry Smith        0,
1354cc2dc46cSBarry Smith        0,
1355cc2dc46cSBarry Smith        MatILUFactor_SeqBAIJ,
1356cc2dc46cSBarry Smith        0,
1357cc2dc46cSBarry Smith        0,
1358cc2dc46cSBarry Smith        MatGetSubMatrices_SeqBAIJ,
1359cc2dc46cSBarry Smith        MatIncreaseOverlap_SeqBAIJ,
1360cc2dc46cSBarry Smith        MatGetValues_SeqBAIJ,
1361cc2dc46cSBarry Smith        0,
1362cc2dc46cSBarry Smith        MatPrintHelp_SeqBAIJ,
1363cc2dc46cSBarry Smith        MatScale_SeqBAIJ,
1364cc2dc46cSBarry Smith        0,
1365cc2dc46cSBarry Smith        0,
1366cc2dc46cSBarry Smith        0,
1367cc2dc46cSBarry Smith        MatGetBlockSize_SeqBAIJ,
13683b2fbd54SBarry Smith        MatGetRowIJ_SeqBAIJ,
136992c4ed94SBarry Smith        MatRestoreRowIJ_SeqBAIJ,
1370cc2dc46cSBarry Smith        0,
1371cc2dc46cSBarry Smith        0,
1372cc2dc46cSBarry Smith        0,
1373cc2dc46cSBarry Smith        0,
1374cc2dc46cSBarry Smith        0,
1375cc2dc46cSBarry Smith        0,
1376d3825aa8SBarry Smith        MatSetValuesBlocked_SeqBAIJ,
1377cc2dc46cSBarry Smith        MatGetSubMatrix_SeqBAIJ,
1378cc2dc46cSBarry Smith        0,
1379cc2dc46cSBarry Smith        0,
1380cc2dc46cSBarry Smith        MatGetMaps_Petsc};
13812593348eSBarry Smith 
13823e90b805SBarry Smith EXTERN_C_BEGIN
13833e90b805SBarry Smith #undef __FUNC__
13843e90b805SBarry Smith #define __FUNC__ "MatStoreValues_SeqBAIJ"
13853e90b805SBarry Smith int MatStoreValues_SeqBAIJ(Mat mat)
13863e90b805SBarry Smith {
13873e90b805SBarry Smith   Mat_SeqBAIJ *aij = (Mat_SeqBAIJ *)mat->data;
13883e90b805SBarry Smith   int         nz = aij->i[aij->m]*aij->bs*aij->bs2;
1389d132466eSBarry Smith   int         ierr;
13903e90b805SBarry Smith 
13913e90b805SBarry Smith   PetscFunctionBegin;
13923e90b805SBarry Smith   if (aij->nonew != 1) {
13933e90b805SBarry Smith     SETERRQ(1,1,"Must call MatSetOption(A,MAT_NO_NEW_NONZERO_LOCATIONS);first");
13943e90b805SBarry Smith   }
13953e90b805SBarry Smith 
13963e90b805SBarry Smith   /* allocate space for values if not already there */
13973e90b805SBarry Smith   if (!aij->saved_values) {
13983e90b805SBarry Smith     aij->saved_values = (Scalar*)PetscMalloc(nz*sizeof(Scalar));CHKPTRQ(aij->saved_values);
13993e90b805SBarry Smith   }
14003e90b805SBarry Smith 
14013e90b805SBarry Smith   /* copy values over */
1402d132466eSBarry Smith   ierr = PetscMemcpy(aij->saved_values,aij->a,nz*sizeof(Scalar));CHKERRQ(ierr);
14033e90b805SBarry Smith   PetscFunctionReturn(0);
14043e90b805SBarry Smith }
14053e90b805SBarry Smith EXTERN_C_END
14063e90b805SBarry Smith 
14073e90b805SBarry Smith EXTERN_C_BEGIN
14083e90b805SBarry Smith #undef __FUNC__
140932e87ba3SBarry Smith #define __FUNC__ "MatRetrieveValues_SeqBAIJ"
141032e87ba3SBarry Smith int MatRetrieveValues_SeqBAIJ(Mat mat)
14113e90b805SBarry Smith {
14123e90b805SBarry Smith   Mat_SeqBAIJ *aij = (Mat_SeqBAIJ *)mat->data;
1413549d3d68SSatish Balay   int         nz = aij->i[aij->m]*aij->bs*aij->bs2,ierr;
14143e90b805SBarry Smith 
14153e90b805SBarry Smith   PetscFunctionBegin;
14163e90b805SBarry Smith   if (aij->nonew != 1) {
14173e90b805SBarry Smith     SETERRQ(1,1,"Must call MatSetOption(A,MAT_NO_NEW_NONZERO_LOCATIONS);first");
14183e90b805SBarry Smith   }
14193e90b805SBarry Smith   if (!aij->saved_values) {
14203e90b805SBarry Smith     SETERRQ(1,1,"Must call MatStoreValues(A);first");
14213e90b805SBarry Smith   }
14223e90b805SBarry Smith 
14233e90b805SBarry Smith   /* copy values over */
1424549d3d68SSatish Balay   ierr = PetscMemcpy(aij->a,aij->saved_values,nz*sizeof(Scalar));CHKERRQ(ierr);
14253e90b805SBarry Smith   PetscFunctionReturn(0);
14263e90b805SBarry Smith }
14273e90b805SBarry Smith EXTERN_C_END
14283e90b805SBarry Smith 
14295615d1e5SSatish Balay #undef __FUNC__
14305615d1e5SSatish Balay #define __FUNC__ "MatCreateSeqBAIJ"
14312593348eSBarry Smith /*@C
143244cd7ae7SLois Curfman McInnes    MatCreateSeqBAIJ - Creates a sparse matrix in block AIJ (block
143344cd7ae7SLois Curfman McInnes    compressed row) format.  For good matrix assembly performance the
143444cd7ae7SLois Curfman McInnes    user should preallocate the matrix storage by setting the parameter nz
14357fc3c18eSBarry Smith    (or the array nnz).  By setting these parameters accurately, performance
14362bd5e0b2SLois Curfman McInnes    during matrix assembly can be increased by more than a factor of 50.
14372593348eSBarry Smith 
1438db81eaa0SLois Curfman McInnes    Collective on MPI_Comm
1439db81eaa0SLois Curfman McInnes 
14402593348eSBarry Smith    Input Parameters:
1441db81eaa0SLois Curfman McInnes +  comm - MPI communicator, set to PETSC_COMM_SELF
1442b6490206SBarry Smith .  bs - size of block
14432593348eSBarry Smith .  m - number of rows
14442593348eSBarry Smith .  n - number of columns
1445b6490206SBarry Smith .  nz - number of block nonzeros per block row (same for all rows)
14467fc3c18eSBarry Smith -  nnz - array containing the number of block nonzeros in the various block rows
14472bd5e0b2SLois Curfman McInnes          (possibly different for each block row) or PETSC_NULL
14482593348eSBarry Smith 
14492593348eSBarry Smith    Output Parameter:
14502593348eSBarry Smith .  A - the matrix
14512593348eSBarry Smith 
14520513a670SBarry Smith    Options Database Keys:
1453db81eaa0SLois Curfman McInnes .   -mat_no_unroll - uses code that does not unroll the loops in the
1454db81eaa0SLois Curfman McInnes                      block calculations (much slower)
1455db81eaa0SLois Curfman McInnes .    -mat_block_size - size of the blocks to use
14560513a670SBarry Smith 
145715091d37SBarry Smith    Level: intermediate
145815091d37SBarry Smith 
14592593348eSBarry Smith    Notes:
146044cd7ae7SLois Curfman McInnes    The block AIJ format is fully compatible with standard Fortran 77
14612593348eSBarry Smith    storage.  That is, the stored row and column indices can begin at
146244cd7ae7SLois Curfman McInnes    either one (as in Fortran) or zero.  See the users' manual for details.
14632593348eSBarry Smith 
14642593348eSBarry Smith    Specify the preallocated storage with either nz or nnz (not both).
14652593348eSBarry Smith    Set nz=PETSC_DEFAULT and nnz=PETSC_NULL for PETSc to control dynamic memory
14662593348eSBarry Smith    allocation.  For additional details, see the users manual chapter on
14676da5968aSLois Curfman McInnes    matrices.
14682593348eSBarry Smith 
1469db81eaa0SLois Curfman McInnes .seealso: MatCreate(), MatCreateSeqAIJ(), MatSetValues(), MatCreateMPIBAIJ()
14702593348eSBarry Smith @*/
1471b6490206SBarry Smith int MatCreateSeqBAIJ(MPI_Comm comm,int bs,int m,int n,int nz,int *nnz,Mat *A)
14722593348eSBarry Smith {
14732593348eSBarry Smith   Mat         B;
1474b6490206SBarry Smith   Mat_SeqBAIJ *b;
1475f1af5d2fSBarry Smith   int         i,len,ierr,mbs,nbs,bs2,size;
1476f1af5d2fSBarry Smith   PetscTruth  flg;
14773b2fbd54SBarry Smith 
14783a40ed3dSBarry Smith   PetscFunctionBegin;
1479d132466eSBarry Smith   ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr);
1480a8c6a408SBarry Smith   if (size > 1) SETERRQ(PETSC_ERR_ARG_WRONG,0,"Comm must be of size 1");
1481b6490206SBarry Smith 
1482962fb4a0SBarry Smith   ierr = OptionsGetInt(PETSC_NULL,"-mat_block_size",&bs,PETSC_NULL);CHKERRQ(ierr);
1483302e33e3SBarry Smith   mbs  = m/bs;
1484302e33e3SBarry Smith   nbs  = n/bs;
1485302e33e3SBarry Smith   bs2  = bs*bs;
14860513a670SBarry Smith 
14873a40ed3dSBarry Smith   if (mbs*bs!=m || nbs*bs!=n) {
1488a8c6a408SBarry Smith     SETERRQ(PETSC_ERR_ARG_SIZ,0,"Number rows, cols must be divisible by blocksize");
14893a40ed3dSBarry Smith   }
14902593348eSBarry Smith 
1491b73539f3SBarry Smith   if (nz < -2) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,0,"nz cannot be less than -2: value %d",nz);
1492b73539f3SBarry Smith   if (nnz) {
1493faf3f1fcSBarry Smith     for (i=0; i<mbs; i++) {
1494b73539f3SBarry 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]);
1495b73539f3SBarry Smith     }
1496b73539f3SBarry Smith   }
1497b73539f3SBarry Smith 
14982593348eSBarry Smith   *A = 0;
14993f1db9ecSBarry Smith   PetscHeaderCreate(B,_p_Mat,struct _MatOps,MAT_COOKIE,MATSEQBAIJ,"Mat",comm,MatDestroy,MatView);
15002593348eSBarry Smith   PLogObjectCreate(B);
1501b6490206SBarry Smith   B->data = (void*)(b = PetscNew(Mat_SeqBAIJ));CHKPTRQ(b);
1502549d3d68SSatish Balay   ierr    = PetscMemzero(b,sizeof(Mat_SeqBAIJ));CHKERRQ(ierr);
1503549d3d68SSatish Balay   ierr    = PetscMemcpy(B->ops,&MatOps_Values,sizeof(struct _MatOps));CHKERRQ(ierr);
15041a6a6d98SBarry Smith   ierr    = OptionsHasName(PETSC_NULL,"-mat_no_unroll",&flg);CHKERRQ(ierr);
15051a6a6d98SBarry Smith   if (!flg) {
15067fc0212eSBarry Smith     switch (bs) {
15077fc0212eSBarry Smith     case 1:
1508f830108cSBarry Smith       B->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_1;
1509f830108cSBarry Smith       B->ops->solve           = MatSolve_SeqBAIJ_1;
15107c922b88SBarry Smith       B->ops->solvetranspose  = MatSolveTranspose_SeqBAIJ_1;
1511f830108cSBarry Smith       B->ops->mult            = MatMult_SeqBAIJ_1;
1512f830108cSBarry Smith       B->ops->multadd         = MatMultAdd_SeqBAIJ_1;
15137fc0212eSBarry Smith       break;
15144eeb42bcSBarry Smith     case 2:
1515f830108cSBarry Smith       B->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_2;
1516f830108cSBarry Smith       B->ops->solve           = MatSolve_SeqBAIJ_2;
15177c922b88SBarry Smith       B->ops->solvetranspose  = MatSolveTranspose_SeqBAIJ_2;
1518f830108cSBarry Smith       B->ops->mult            = MatMult_SeqBAIJ_2;
1519f830108cSBarry Smith       B->ops->multadd         = MatMultAdd_SeqBAIJ_2;
15206d84be18SBarry Smith       break;
1521f327dd97SBarry Smith     case 3:
1522f830108cSBarry Smith       B->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_3;
1523f830108cSBarry Smith       B->ops->solve           = MatSolve_SeqBAIJ_3;
15247c922b88SBarry Smith       B->ops->solvetranspose  = MatSolveTranspose_SeqBAIJ_3;
1525f830108cSBarry Smith       B->ops->mult            = MatMult_SeqBAIJ_3;
1526f830108cSBarry Smith       B->ops->multadd         = MatMultAdd_SeqBAIJ_3;
15274eeb42bcSBarry Smith       break;
15286d84be18SBarry Smith     case 4:
1529f830108cSBarry Smith       B->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_4;
1530f830108cSBarry Smith       B->ops->solve           = MatSolve_SeqBAIJ_4;
15317c922b88SBarry Smith       B->ops->solvetranspose  = MatSolveTranspose_SeqBAIJ_4;
1532f830108cSBarry Smith       B->ops->mult            = MatMult_SeqBAIJ_4;
1533f830108cSBarry Smith       B->ops->multadd         = MatMultAdd_SeqBAIJ_4;
15346d84be18SBarry Smith       break;
15356d84be18SBarry Smith     case 5:
1536f830108cSBarry Smith       B->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_5;
1537f830108cSBarry Smith       B->ops->solve           = MatSolve_SeqBAIJ_5;
15387c922b88SBarry Smith       B->ops->solvetranspose  = MatSolveTranspose_SeqBAIJ_5;
1539f830108cSBarry Smith       B->ops->mult            = MatMult_SeqBAIJ_5;
1540f830108cSBarry Smith       B->ops->multadd         = MatMultAdd_SeqBAIJ_5;
15416d84be18SBarry Smith       break;
154215091d37SBarry Smith     case 6:
154315091d37SBarry Smith       B->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_6;
154415091d37SBarry Smith       B->ops->solve           = MatSolve_SeqBAIJ_6;
15457c922b88SBarry Smith       B->ops->solvetranspose  = MatSolveTranspose_SeqBAIJ_6;
154615091d37SBarry Smith       B->ops->mult            = MatMult_SeqBAIJ_6;
154715091d37SBarry Smith       B->ops->multadd         = MatMultAdd_SeqBAIJ_6;
154815091d37SBarry Smith       break;
154948e9ddb2SSatish Balay     case 7:
1550f830108cSBarry Smith       B->ops->mult            = MatMult_SeqBAIJ_7;
1551f830108cSBarry Smith       B->ops->solve           = MatSolve_SeqBAIJ_7;
15527c922b88SBarry Smith       B->ops->solvetranspose  = MatSolveTranspose_SeqBAIJ_7;
1553f830108cSBarry Smith       B->ops->multadd         = MatMultAdd_SeqBAIJ_7;
155448e9ddb2SSatish Balay       break;
15557fc0212eSBarry Smith     }
15561a6a6d98SBarry Smith   }
1557e1311b90SBarry Smith   B->ops->destroy     = MatDestroy_SeqBAIJ;
1558e1311b90SBarry Smith   B->ops->view        = MatView_SeqBAIJ;
15592593348eSBarry Smith   B->factor           = 0;
15602593348eSBarry Smith   B->lupivotthreshold = 1.0;
156190f02eecSBarry Smith   B->mapping          = 0;
15622593348eSBarry Smith   b->row              = 0;
15632593348eSBarry Smith   b->col              = 0;
1564e51c0b9cSSatish Balay   b->icol             = 0;
15652593348eSBarry Smith   b->reallocs         = 0;
15663e90b805SBarry Smith   b->saved_values     = 0;
15672593348eSBarry Smith 
156844cd7ae7SLois Curfman McInnes   b->m       = m; B->m = m; B->M = m;
156944cd7ae7SLois Curfman McInnes   b->n       = n; B->n = n; B->N = n;
1570a5ae1ecdSBarry Smith 
15717413bad6SBarry Smith   ierr = MapCreateMPI(comm,m,m,&B->rmap);CHKERRQ(ierr);
15727413bad6SBarry Smith   ierr = MapCreateMPI(comm,n,n,&B->cmap);CHKERRQ(ierr);
1573a5ae1ecdSBarry Smith 
1574b6490206SBarry Smith   b->mbs     = mbs;
1575f2501298SSatish Balay   b->nbs     = nbs;
1576b6490206SBarry Smith   b->imax    = (int*)PetscMalloc((mbs+1)*sizeof(int));CHKPTRQ(b->imax);
1577c4992f7dSBarry Smith   if (!nnz) {
1578119a934aSSatish Balay     if (nz == PETSC_DEFAULT) nz = 5;
15792593348eSBarry Smith     else if (nz <= 0)        nz = 1;
1580b6490206SBarry Smith     for (i=0; i<mbs; i++) b->imax[i] = nz;
1581b6490206SBarry Smith     nz = nz*mbs;
15823a40ed3dSBarry Smith   } else {
15832593348eSBarry Smith     nz = 0;
1584b6490206SBarry Smith     for (i=0; i<mbs; i++) {b->imax[i] = nnz[i]; nz += nnz[i];}
15852593348eSBarry Smith   }
15862593348eSBarry Smith 
15872593348eSBarry Smith   /* allocate the matrix space */
15883f1db9ecSBarry Smith   len   = nz*sizeof(int) + nz*bs2*sizeof(MatScalar) + (b->m+1)*sizeof(int);
15893f1db9ecSBarry Smith   b->a  = (MatScalar*)PetscMalloc(len);CHKPTRQ(b->a);
1590549d3d68SSatish Balay   ierr = PetscMemzero(b->a,nz*bs2*sizeof(MatScalar));CHKERRQ(ierr);
15917e67e3f9SSatish Balay   b->j  = (int*)(b->a + nz*bs2);
1592549d3d68SSatish Balay   ierr = PetscMemzero(b->j,nz*sizeof(int));CHKERRQ(ierr);
15932593348eSBarry Smith   b->i  = b->j + nz;
1594c4992f7dSBarry Smith   b->singlemalloc = PETSC_TRUE;
15952593348eSBarry Smith 
1596de6a44a3SBarry Smith   b->i[0] = 0;
1597b6490206SBarry Smith   for (i=1; i<mbs+1; i++) {
15982593348eSBarry Smith     b->i[i] = b->i[i-1] + b->imax[i-1];
15992593348eSBarry Smith   }
16002593348eSBarry Smith 
1601b6490206SBarry Smith   /* b->ilen will count nonzeros in each block row so far. */
1602b6490206SBarry Smith   b->ilen = (int*)PetscMalloc((mbs+1)*sizeof(int));
1603f09e8eb9SSatish Balay   PLogObjectMemory(B,len+2*(mbs+1)*sizeof(int)+sizeof(struct _p_Mat)+sizeof(Mat_SeqBAIJ));
1604b6490206SBarry Smith   for (i=0; i<mbs; i++) { b->ilen[i] = 0;}
16052593348eSBarry Smith 
1606b6490206SBarry Smith   b->bs               = bs;
16079df24120SSatish Balay   b->bs2              = bs2;
1608b6490206SBarry Smith   b->mbs              = mbs;
16092593348eSBarry Smith   b->nz               = 0;
161018e7b8e4SLois Curfman McInnes   b->maxnz            = nz*bs2;
1611c4992f7dSBarry Smith   b->sorted           = PETSC_FALSE;
1612c4992f7dSBarry Smith   b->roworiented      = PETSC_TRUE;
16132593348eSBarry Smith   b->nonew            = 0;
16142593348eSBarry Smith   b->diag             = 0;
16152593348eSBarry Smith   b->solve_work       = 0;
1616de6a44a3SBarry Smith   b->mult_work        = 0;
16172593348eSBarry Smith   b->spptr            = 0;
16180e6d2581SBarry Smith   B->info.nz_unneeded = (PetscReal)b->maxnz;
1619883fce79SBarry Smith   b->keepzeroedrows   = PETSC_FALSE;
16204e220ebcSLois Curfman McInnes 
16212593348eSBarry Smith   *A = B;
16222593348eSBarry Smith   ierr = OptionsHasName(PETSC_NULL,"-help",&flg);CHKERRQ(ierr);
16232593348eSBarry Smith   if (flg) {ierr = MatPrintHelp(B);CHKERRQ(ierr); }
162427a8da17SBarry Smith 
1625f1af5d2fSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatStoreValues_C",
16263e90b805SBarry Smith                                      "MatStoreValues_SeqBAIJ",
16273e90b805SBarry Smith                                      (void*)MatStoreValues_SeqBAIJ);CHKERRQ(ierr);
1628f1af5d2fSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatRetrieveValues_C",
16293e90b805SBarry Smith                                      "MatRetrieveValues_SeqBAIJ",
16303e90b805SBarry Smith                                      (void*)MatRetrieveValues_SeqBAIJ);CHKERRQ(ierr);
1631f1af5d2fSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatSeqBAIJSetColumnIndices_C",
163227a8da17SBarry Smith                                      "MatSeqBAIJSetColumnIndices_SeqBAIJ",
163327a8da17SBarry Smith                                      (void*)MatSeqBAIJSetColumnIndices_SeqBAIJ);CHKERRQ(ierr);
16343a40ed3dSBarry Smith   PetscFunctionReturn(0);
16352593348eSBarry Smith }
16362593348eSBarry Smith 
16375615d1e5SSatish Balay #undef __FUNC__
16382e8a6d31SBarry Smith #define __FUNC__ "MatDuplicate_SeqBAIJ"
16392e8a6d31SBarry Smith int MatDuplicate_SeqBAIJ(Mat A,MatDuplicateOption cpvalues,Mat *B)
16402593348eSBarry Smith {
16412593348eSBarry Smith   Mat         C;
1642b6490206SBarry Smith   Mat_SeqBAIJ *c,*a = (Mat_SeqBAIJ*)A->data;
164327a8da17SBarry Smith   int         i,len,mbs = a->mbs,nz = a->nz,bs2 =a->bs2,ierr;
1644de6a44a3SBarry Smith 
16453a40ed3dSBarry Smith   PetscFunctionBegin;
1646a8c6a408SBarry Smith   if (a->i[mbs] != nz) SETERRQ(PETSC_ERR_PLIB,0,"Corrupt matrix");
16472593348eSBarry Smith 
16482593348eSBarry Smith   *B = 0;
16493f1db9ecSBarry Smith   PetscHeaderCreate(C,_p_Mat,struct _MatOps,MAT_COOKIE,MATSEQBAIJ,"Mat",A->comm,MatDestroy,MatView);
16502593348eSBarry Smith   PLogObjectCreate(C);
1651b6490206SBarry Smith   C->data           = (void*)(c = PetscNew(Mat_SeqBAIJ));CHKPTRQ(c);
1652549d3d68SSatish Balay   ierr              = PetscMemcpy(C->ops,A->ops,sizeof(struct _MatOps));CHKERRQ(ierr);
1653e1311b90SBarry Smith   C->ops->destroy   = MatDestroy_SeqBAIJ;
1654e1311b90SBarry Smith   C->ops->view      = MatView_SeqBAIJ;
16552593348eSBarry Smith   C->factor         = A->factor;
16562593348eSBarry Smith   c->row            = 0;
16572593348eSBarry Smith   c->col            = 0;
1658cac97260SSatish Balay   c->icol           = 0;
165932e87ba3SBarry Smith   c->saved_values   = 0;
1660f1e2ffcdSBarry Smith   c->keepzeroedrows = a->keepzeroedrows;
16612593348eSBarry Smith   C->assembled      = PETSC_TRUE;
16622593348eSBarry Smith 
166344cd7ae7SLois Curfman McInnes   c->m = C->m   = a->m;
166444cd7ae7SLois Curfman McInnes   c->n = C->n   = a->n;
166544cd7ae7SLois Curfman McInnes   C->M          = a->m;
166644cd7ae7SLois Curfman McInnes   C->N          = a->n;
166744cd7ae7SLois Curfman McInnes 
1668b6490206SBarry Smith   c->bs         = a->bs;
16699df24120SSatish Balay   c->bs2        = a->bs2;
1670b6490206SBarry Smith   c->mbs        = a->mbs;
1671b6490206SBarry Smith   c->nbs        = a->nbs;
16722593348eSBarry Smith 
1673b6490206SBarry Smith   c->imax       = (int*)PetscMalloc((mbs+1)*sizeof(int));CHKPTRQ(c->imax);
1674b6490206SBarry Smith   c->ilen       = (int*)PetscMalloc((mbs+1)*sizeof(int));CHKPTRQ(c->ilen);
1675b6490206SBarry Smith   for (i=0; i<mbs; i++) {
16762593348eSBarry Smith     c->imax[i] = a->imax[i];
16772593348eSBarry Smith     c->ilen[i] = a->ilen[i];
16782593348eSBarry Smith   }
16792593348eSBarry Smith 
16802593348eSBarry Smith   /* allocate the matrix space */
1681c4992f7dSBarry Smith   c->singlemalloc = PETSC_TRUE;
16823f1db9ecSBarry Smith   len  = (mbs+1)*sizeof(int) + nz*(bs2*sizeof(MatScalar) + sizeof(int));
16833f1db9ecSBarry Smith   c->a = (MatScalar*)PetscMalloc(len);CHKPTRQ(c->a);
16847e67e3f9SSatish Balay   c->j = (int*)(c->a + nz*bs2);
1685de6a44a3SBarry Smith   c->i = c->j + nz;
1686549d3d68SSatish Balay   ierr = PetscMemcpy(c->i,a->i,(mbs+1)*sizeof(int));CHKERRQ(ierr);
1687b6490206SBarry Smith   if (mbs > 0) {
1688549d3d68SSatish Balay     ierr = PetscMemcpy(c->j,a->j,nz*sizeof(int));CHKERRQ(ierr);
16892e8a6d31SBarry Smith     if (cpvalues == MAT_COPY_VALUES) {
1690549d3d68SSatish Balay       ierr = PetscMemcpy(c->a,a->a,bs2*nz*sizeof(MatScalar));CHKERRQ(ierr);
16912e8a6d31SBarry Smith     } else {
1692549d3d68SSatish Balay       ierr = PetscMemzero(c->a,bs2*nz*sizeof(MatScalar));CHKERRQ(ierr);
16932593348eSBarry Smith     }
16942593348eSBarry Smith   }
16952593348eSBarry Smith 
1696f09e8eb9SSatish Balay   PLogObjectMemory(C,len+2*(mbs+1)*sizeof(int)+sizeof(struct _p_Mat)+sizeof(Mat_SeqBAIJ));
16972593348eSBarry Smith   c->sorted      = a->sorted;
16982593348eSBarry Smith   c->roworiented = a->roworiented;
16992593348eSBarry Smith   c->nonew       = a->nonew;
17002593348eSBarry Smith 
17012593348eSBarry Smith   if (a->diag) {
1702b6490206SBarry Smith     c->diag = (int*)PetscMalloc((mbs+1)*sizeof(int));CHKPTRQ(c->diag);
1703b6490206SBarry Smith     PLogObjectMemory(C,(mbs+1)*sizeof(int));
1704b6490206SBarry Smith     for (i=0; i<mbs; i++) {
17052593348eSBarry Smith       c->diag[i] = a->diag[i];
17062593348eSBarry Smith     }
170798305bb5SBarry Smith   } else c->diag        = 0;
17082593348eSBarry Smith   c->nz                 = a->nz;
17092593348eSBarry Smith   c->maxnz              = a->maxnz;
17102593348eSBarry Smith   c->solve_work         = 0;
17112593348eSBarry Smith   c->spptr              = 0;      /* Dangerous -I'm throwing away a->spptr */
17127fc0212eSBarry Smith   c->mult_work          = 0;
17132593348eSBarry Smith   *B = C;
17147b2a1423SBarry Smith   ierr = FListDuplicate(A->qlist,&C->qlist);CHKERRQ(ierr);
17153a40ed3dSBarry Smith   PetscFunctionReturn(0);
17162593348eSBarry Smith }
17172593348eSBarry Smith 
17185615d1e5SSatish Balay #undef __FUNC__
17195615d1e5SSatish Balay #define __FUNC__ "MatLoad_SeqBAIJ"
172019bcc07fSBarry Smith int MatLoad_SeqBAIJ(Viewer viewer,MatType type,Mat *A)
17212593348eSBarry Smith {
1722b6490206SBarry Smith   Mat_SeqBAIJ  *a;
17232593348eSBarry Smith   Mat          B;
1724f1af5d2fSBarry Smith   int          i,nz,ierr,fd,header[4],size,*rowlengths=0,M,N,bs=1;
1725b6490206SBarry Smith   int          *mask,mbs,*jj,j,rowcount,nzcount,k,*browlengths,maskcount;
172635aab85fSBarry Smith   int          kmax,jcount,block,idx,point,nzcountb,extra_rows;
1727a7c10996SSatish Balay   int          *masked,nmask,tmp,bs2,ishift;
1728b6490206SBarry Smith   Scalar       *aa;
172919bcc07fSBarry Smith   MPI_Comm     comm = ((PetscObject)viewer)->comm;
17302593348eSBarry Smith 
17313a40ed3dSBarry Smith   PetscFunctionBegin;
1732f1af5d2fSBarry Smith   ierr = OptionsGetInt(PETSC_NULL,"-matload_block_size",&bs,PETSC_NULL);CHKERRQ(ierr);
1733de6a44a3SBarry Smith   bs2  = bs*bs;
1734b6490206SBarry Smith 
1735d132466eSBarry Smith   ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr);
1736cc0fae11SBarry Smith   if (size > 1) SETERRQ(PETSC_ERR_ARG_WRONG,0,"view must have one processor");
173790ace30eSBarry Smith   ierr = ViewerBinaryGetDescriptor(viewer,&fd);CHKERRQ(ierr);
17380752156aSBarry Smith   ierr = PetscBinaryRead(fd,header,4,PETSC_INT);CHKERRQ(ierr);
1739a8c6a408SBarry Smith   if (header[0] != MAT_COOKIE) SETERRQ(PETSC_ERR_FILE_UNEXPECTED,0,"not Mat object");
17402593348eSBarry Smith   M = header[1]; N = header[2]; nz = header[3];
17412593348eSBarry Smith 
1742d64ed03dSBarry Smith   if (header[3] < 0) {
1743a8c6a408SBarry Smith     SETERRQ(PETSC_ERR_FILE_UNEXPECTED,1,"Matrix stored in special format, cannot load as SeqBAIJ");
1744d64ed03dSBarry Smith   }
1745d64ed03dSBarry Smith 
1746a8c6a408SBarry Smith   if (M != N) SETERRQ(PETSC_ERR_SUP,0,"Can only do square matrices");
174735aab85fSBarry Smith 
174835aab85fSBarry Smith   /*
174935aab85fSBarry Smith      This code adds extra rows to make sure the number of rows is
175035aab85fSBarry Smith     divisible by the blocksize
175135aab85fSBarry Smith   */
1752b6490206SBarry Smith   mbs        = M/bs;
175335aab85fSBarry Smith   extra_rows = bs - M + bs*(mbs);
175435aab85fSBarry Smith   if (extra_rows == bs) extra_rows = 0;
175535aab85fSBarry Smith   else                  mbs++;
175635aab85fSBarry Smith   if (extra_rows) {
1757537820f0SBarry Smith     PLogInfo(0,"MatLoad_SeqBAIJ:Padding loaded matrix to match blocksize\n");
175835aab85fSBarry Smith   }
1759b6490206SBarry Smith 
17602593348eSBarry Smith   /* read in row lengths */
176135aab85fSBarry Smith   rowlengths = (int*)PetscMalloc((M+extra_rows)*sizeof(int));CHKPTRQ(rowlengths);
17620752156aSBarry Smith   ierr = PetscBinaryRead(fd,rowlengths,M,PETSC_INT);CHKERRQ(ierr);
176335aab85fSBarry Smith   for (i=0; i<extra_rows; i++) rowlengths[M+i] = 1;
17642593348eSBarry Smith 
1765b6490206SBarry Smith   /* read in column indices */
176635aab85fSBarry Smith   jj = (int*)PetscMalloc((nz+extra_rows)*sizeof(int));CHKPTRQ(jj);
17670752156aSBarry Smith   ierr = PetscBinaryRead(fd,jj,nz,PETSC_INT);CHKERRQ(ierr);
176835aab85fSBarry Smith   for (i=0; i<extra_rows; i++) jj[nz+i] = M+i;
1769b6490206SBarry Smith 
1770b6490206SBarry Smith   /* loop over row lengths determining block row lengths */
1771b6490206SBarry Smith   browlengths = (int*)PetscMalloc(mbs*sizeof(int));CHKPTRQ(browlengths);
1772549d3d68SSatish Balay   ierr        = PetscMemzero(browlengths,mbs*sizeof(int));CHKERRQ(ierr);
177335aab85fSBarry Smith   mask        = (int*)PetscMalloc(2*mbs*sizeof(int));CHKPTRQ(mask);
1774549d3d68SSatish Balay   ierr        = PetscMemzero(mask,mbs*sizeof(int));CHKERRQ(ierr);
177535aab85fSBarry Smith   masked      = mask + mbs;
1776b6490206SBarry Smith   rowcount    = 0; nzcount = 0;
1777b6490206SBarry Smith   for (i=0; i<mbs; i++) {
177835aab85fSBarry Smith     nmask = 0;
1779b6490206SBarry Smith     for (j=0; j<bs; j++) {
1780b6490206SBarry Smith       kmax = rowlengths[rowcount];
1781b6490206SBarry Smith       for (k=0; k<kmax; k++) {
178235aab85fSBarry Smith         tmp = jj[nzcount++]/bs;
178335aab85fSBarry Smith         if (!mask[tmp]) {masked[nmask++] = tmp; mask[tmp] = 1;}
1784b6490206SBarry Smith       }
1785b6490206SBarry Smith       rowcount++;
1786b6490206SBarry Smith     }
178735aab85fSBarry Smith     browlengths[i] += nmask;
178835aab85fSBarry Smith     /* zero out the mask elements we set */
178935aab85fSBarry Smith     for (j=0; j<nmask; j++) mask[masked[j]] = 0;
1790b6490206SBarry Smith   }
1791b6490206SBarry Smith 
17922593348eSBarry Smith   /* create our matrix */
17933eee16b0SBarry Smith   ierr = MatCreateSeqBAIJ(comm,bs,M+extra_rows,N+extra_rows,0,browlengths,A);CHKERRQ(ierr);
17942593348eSBarry Smith   B = *A;
1795b6490206SBarry Smith   a = (Mat_SeqBAIJ*)B->data;
17962593348eSBarry Smith 
17972593348eSBarry Smith   /* set matrix "i" values */
1798de6a44a3SBarry Smith   a->i[0] = 0;
1799b6490206SBarry Smith   for (i=1; i<= mbs; i++) {
1800b6490206SBarry Smith     a->i[i]      = a->i[i-1] + browlengths[i-1];
1801b6490206SBarry Smith     a->ilen[i-1] = browlengths[i-1];
18022593348eSBarry Smith   }
1803b6490206SBarry Smith   a->nz         = 0;
1804b6490206SBarry Smith   for (i=0; i<mbs; i++) a->nz += browlengths[i];
18052593348eSBarry Smith 
1806b6490206SBarry Smith   /* read in nonzero values */
180735aab85fSBarry Smith   aa = (Scalar*)PetscMalloc((nz+extra_rows)*sizeof(Scalar));CHKPTRQ(aa);
18080752156aSBarry Smith   ierr = PetscBinaryRead(fd,aa,nz,PETSC_SCALAR);CHKERRQ(ierr);
180935aab85fSBarry Smith   for (i=0; i<extra_rows; i++) aa[nz+i] = 1.0;
1810b6490206SBarry Smith 
1811b6490206SBarry Smith   /* set "a" and "j" values into matrix */
1812b6490206SBarry Smith   nzcount = 0; jcount = 0;
1813b6490206SBarry Smith   for (i=0; i<mbs; i++) {
1814b6490206SBarry Smith     nzcountb = nzcount;
181535aab85fSBarry Smith     nmask    = 0;
1816b6490206SBarry Smith     for (j=0; j<bs; j++) {
1817b6490206SBarry Smith       kmax = rowlengths[i*bs+j];
1818b6490206SBarry Smith       for (k=0; k<kmax; k++) {
181935aab85fSBarry Smith         tmp = jj[nzcount++]/bs;
182035aab85fSBarry Smith 	if (!mask[tmp]) { masked[nmask++] = tmp; mask[tmp] = 1;}
1821b6490206SBarry Smith       }
1822b6490206SBarry Smith       rowcount++;
1823b6490206SBarry Smith     }
1824de6a44a3SBarry Smith     /* sort the masked values */
1825433994e6SBarry Smith     ierr = PetscSortInt(nmask,masked);CHKERRQ(ierr);
1826de6a44a3SBarry Smith 
1827b6490206SBarry Smith     /* set "j" values into matrix */
1828b6490206SBarry Smith     maskcount = 1;
182935aab85fSBarry Smith     for (j=0; j<nmask; j++) {
183035aab85fSBarry Smith       a->j[jcount++]  = masked[j];
1831de6a44a3SBarry Smith       mask[masked[j]] = maskcount++;
1832b6490206SBarry Smith     }
1833b6490206SBarry Smith     /* set "a" values into matrix */
1834de6a44a3SBarry Smith     ishift = bs2*a->i[i];
1835b6490206SBarry Smith     for (j=0; j<bs; j++) {
1836b6490206SBarry Smith       kmax = rowlengths[i*bs+j];
1837b6490206SBarry Smith       for (k=0; k<kmax; k++) {
1838de6a44a3SBarry Smith         tmp       = jj[nzcountb]/bs ;
1839de6a44a3SBarry Smith         block     = mask[tmp] - 1;
1840de6a44a3SBarry Smith         point     = jj[nzcountb] - bs*tmp;
1841de6a44a3SBarry Smith         idx       = ishift + bs2*block + j + bs*point;
1842b6490206SBarry Smith         a->a[idx] = aa[nzcountb++];
1843b6490206SBarry Smith       }
1844b6490206SBarry Smith     }
184535aab85fSBarry Smith     /* zero out the mask elements we set */
184635aab85fSBarry Smith     for (j=0; j<nmask; j++) mask[masked[j]] = 0;
1847b6490206SBarry Smith   }
1848a8c6a408SBarry Smith   if (jcount != a->nz) SETERRQ(PETSC_ERR_FILE_UNEXPECTED,0,"Bad binary matrix");
1849b6490206SBarry Smith 
1850606d414cSSatish Balay   ierr = PetscFree(rowlengths);CHKERRQ(ierr);
1851606d414cSSatish Balay   ierr = PetscFree(browlengths);CHKERRQ(ierr);
1852606d414cSSatish Balay   ierr = PetscFree(aa);CHKERRQ(ierr);
1853606d414cSSatish Balay   ierr = PetscFree(jj);CHKERRQ(ierr);
1854606d414cSSatish Balay   ierr = PetscFree(mask);CHKERRQ(ierr);
1855b6490206SBarry Smith 
1856b6490206SBarry Smith   B->assembled = PETSC_TRUE;
1857de6a44a3SBarry Smith 
18589c01be13SBarry Smith   ierr = MatView_Private(B);CHKERRQ(ierr);
18593a40ed3dSBarry Smith   PetscFunctionReturn(0);
18602593348eSBarry Smith }
18612593348eSBarry Smith 
18622593348eSBarry Smith 
18632593348eSBarry Smith 
1864