xref: /petsc/src/mat/impls/baij/seq/baij.c (revision f1af5d2ffeae1f5fc391a89939f4818e47770ae3)
1*f1af5d2fSBarry Smith /*$Id: baij.c,v 1.187 1999/10/24 14:02:28 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__
18be5855fcSBarry Smith #define __FUNC__ "MatMissingDiag_SeqBAIJ"
19be5855fcSBarry Smith int MatMissingDiag_SeqBAIJ(Mat A)
20be5855fcSBarry Smith {
21be5855fcSBarry Smith   Mat_SeqBAIJ *a = (Mat_SeqBAIJ *) A->data;
22be5855fcSBarry Smith   int         *diag = a->diag, *jj = a->j,i;
23be5855fcSBarry Smith 
24be5855fcSBarry Smith   PetscFunctionBegin;
250e8e8aceSBarry Smith   for ( i=0; i<a->mbs; i++ ) {
26be5855fcSBarry Smith     if (jj[diag[i]] != i) {
27be5855fcSBarry Smith       SETERRQ1(1,1,"Matrix is missing diagonal number %d",i);
28be5855fcSBarry Smith     }
29be5855fcSBarry Smith   }
30be5855fcSBarry Smith   PetscFunctionReturn(0);
31be5855fcSBarry Smith }
32be5855fcSBarry Smith 
335615d1e5SSatish Balay #undef __FUNC__
345615d1e5SSatish Balay #define __FUNC__ "MatMarkDiag_SeqBAIJ"
35de6a44a3SBarry Smith int MatMarkDiag_SeqBAIJ(Mat A)
36de6a44a3SBarry Smith {
37de6a44a3SBarry Smith   Mat_SeqBAIJ *a = (Mat_SeqBAIJ *) A->data;
387fc0212eSBarry Smith   int         i,j, *diag, m = a->mbs;
39de6a44a3SBarry Smith 
403a40ed3dSBarry Smith   PetscFunctionBegin;
41de6a44a3SBarry Smith   diag = (int *) PetscMalloc( (m+1)*sizeof(int));CHKPTRQ(diag);
42de6a44a3SBarry Smith   PLogObjectMemory(A,(m+1)*sizeof(int));
437fc0212eSBarry Smith   for ( i=0; i<m; i++ ) {
44ecc615b2SBarry Smith     diag[i] = a->i[i+1];
45de6a44a3SBarry Smith     for ( j=a->i[i]; j<a->i[i+1]; j++ ) {
46de6a44a3SBarry Smith       if (a->j[j] == i) {
47de6a44a3SBarry Smith         diag[i] = j;
48de6a44a3SBarry Smith         break;
49de6a44a3SBarry Smith       }
50de6a44a3SBarry Smith     }
51de6a44a3SBarry Smith   }
52de6a44a3SBarry Smith   a->diag = diag;
533a40ed3dSBarry Smith   PetscFunctionReturn(0);
54de6a44a3SBarry Smith }
552593348eSBarry Smith 
562593348eSBarry Smith 
573b2fbd54SBarry Smith extern int MatToSymmetricIJ_SeqAIJ(int,int*,int*,int,int,int**,int**);
583b2fbd54SBarry Smith 
595615d1e5SSatish Balay #undef __FUNC__
605615d1e5SSatish Balay #define __FUNC__ "MatGetRowIJ_SeqBAIJ"
613b2fbd54SBarry Smith static int MatGetRowIJ_SeqBAIJ(Mat A,int oshift,PetscTruth symmetric,int *nn,int **ia,int **ja,
623b2fbd54SBarry Smith                             PetscTruth *done)
633b2fbd54SBarry Smith {
643b2fbd54SBarry Smith   Mat_SeqBAIJ *a = (Mat_SeqBAIJ *) A->data;
653b2fbd54SBarry Smith   int         ierr, n = a->mbs,i;
663b2fbd54SBarry Smith 
673a40ed3dSBarry Smith   PetscFunctionBegin;
683b2fbd54SBarry Smith   *nn = n;
693a40ed3dSBarry Smith   if (!ia) PetscFunctionReturn(0);
703b2fbd54SBarry Smith   if (symmetric) {
713b2fbd54SBarry Smith     ierr = MatToSymmetricIJ_SeqAIJ(n,a->i,a->j,0,oshift,ia,ja);CHKERRQ(ierr);
723b2fbd54SBarry Smith   } else if (oshift == 1) {
733b2fbd54SBarry Smith     /* temporarily add 1 to i and j indices */
743b2fbd54SBarry Smith     int nz = a->i[n] + 1;
753b2fbd54SBarry Smith     for ( i=0; i<nz; i++ ) a->j[i]++;
763b2fbd54SBarry Smith     for ( i=0; i<n+1; i++ ) a->i[i]++;
773b2fbd54SBarry Smith     *ia = a->i; *ja = a->j;
783b2fbd54SBarry Smith   } else {
793b2fbd54SBarry Smith     *ia = a->i; *ja = a->j;
803b2fbd54SBarry Smith   }
813b2fbd54SBarry Smith 
823a40ed3dSBarry Smith   PetscFunctionReturn(0);
833b2fbd54SBarry Smith }
843b2fbd54SBarry Smith 
855615d1e5SSatish Balay #undef __FUNC__
86d4bb536fSBarry Smith #define __FUNC__ "MatRestoreRowIJ_SeqBAIJ"
873b2fbd54SBarry Smith static int MatRestoreRowIJ_SeqBAIJ(Mat A,int oshift,PetscTruth symmetric,int *nn,int **ia,int **ja,
883b2fbd54SBarry Smith                                 PetscTruth *done)
893b2fbd54SBarry Smith {
903b2fbd54SBarry Smith   Mat_SeqBAIJ *a = (Mat_SeqBAIJ *) A->data;
91606d414cSSatish Balay   int         i,n = a->mbs,ierr;
923b2fbd54SBarry Smith 
933a40ed3dSBarry Smith   PetscFunctionBegin;
943a40ed3dSBarry Smith   if (!ia) PetscFunctionReturn(0);
953b2fbd54SBarry Smith   if (symmetric) {
96606d414cSSatish Balay     ierr = PetscFree(*ia);CHKERRQ(ierr);
97606d414cSSatish Balay     ierr = PetscFree(*ja);CHKERRQ(ierr);
98af5da2bfSBarry Smith   } else if (oshift == 1) {
993b2fbd54SBarry Smith     int nz = a->i[n];
1003b2fbd54SBarry Smith     for ( i=0; i<nz; i++ ) a->j[i]--;
1013b2fbd54SBarry Smith     for ( i=0; i<n+1; i++ ) a->i[i]--;
1023b2fbd54SBarry Smith   }
1033a40ed3dSBarry Smith   PetscFunctionReturn(0);
1043b2fbd54SBarry Smith }
1053b2fbd54SBarry Smith 
1062d61bbb3SSatish Balay #undef __FUNC__
1072d61bbb3SSatish Balay #define __FUNC__ "MatGetBlockSize_SeqBAIJ"
1082d61bbb3SSatish Balay int MatGetBlockSize_SeqBAIJ(Mat mat, int *bs)
1092d61bbb3SSatish Balay {
1102d61bbb3SSatish Balay   Mat_SeqBAIJ *baij = (Mat_SeqBAIJ *) mat->data;
1112d61bbb3SSatish Balay 
1122d61bbb3SSatish Balay   PetscFunctionBegin;
1132d61bbb3SSatish Balay   *bs = baij->bs;
1142d61bbb3SSatish Balay   PetscFunctionReturn(0);
1152d61bbb3SSatish Balay }
1162d61bbb3SSatish Balay 
1172d61bbb3SSatish Balay 
1182d61bbb3SSatish Balay #undef __FUNC__
1192d61bbb3SSatish Balay #define __FUNC__ "MatDestroy_SeqBAIJ"
120e1311b90SBarry Smith int MatDestroy_SeqBAIJ(Mat A)
1212d61bbb3SSatish Balay {
1222d61bbb3SSatish Balay   Mat_SeqBAIJ *a = (Mat_SeqBAIJ *) A->data;
123e51c0b9cSSatish Balay   int         ierr;
1242d61bbb3SSatish Balay 
125433994e6SBarry Smith   PetscFunctionBegin;
12694d884c6SBarry Smith   if (A->mapping) {
12794d884c6SBarry Smith     ierr = ISLocalToGlobalMappingDestroy(A->mapping);CHKERRQ(ierr);
12894d884c6SBarry Smith   }
12994d884c6SBarry Smith   if (A->bmapping) {
13094d884c6SBarry Smith     ierr = ISLocalToGlobalMappingDestroy(A->bmapping);CHKERRQ(ierr);
13194d884c6SBarry Smith   }
13261b13de0SBarry Smith   if (A->rmap) {
13361b13de0SBarry Smith     ierr = MapDestroy(A->rmap);CHKERRQ(ierr);
13461b13de0SBarry Smith   }
13561b13de0SBarry Smith   if (A->cmap) {
13661b13de0SBarry Smith     ierr = MapDestroy(A->cmap);CHKERRQ(ierr);
13761b13de0SBarry Smith   }
138aa482453SBarry Smith #if defined(PETSC_USE_LOG)
139e1311b90SBarry Smith   PLogObjectState((PetscObject) A,"Rows=%d, Cols=%d, NZ=%d",a->m,a->n,a->nz);
1402d61bbb3SSatish Balay #endif
141606d414cSSatish Balay   ierr = PetscFree(a->a);CHKERRQ(ierr);
142606d414cSSatish Balay   if (!a->singlemalloc) {
143606d414cSSatish Balay     ierr = PetscFree(a->i);CHKERRQ(ierr);
144606d414cSSatish Balay     ierr = PetscFree(a->j);CHKERRQ(ierr);
145606d414cSSatish Balay   }
146606d414cSSatish Balay   if (a->diag) {ierr = PetscFree(a->diag);CHKERRQ(ierr);}
147606d414cSSatish Balay   if (a->ilen) {ierr = PetscFree(a->ilen);CHKERRQ(ierr);}
148606d414cSSatish Balay   if (a->imax) {ierr = PetscFree(a->imax);CHKERRQ(ierr);}
149606d414cSSatish Balay   if (a->solve_work) {ierr = PetscFree(a->solve_work);CHKERRQ(ierr);}
150606d414cSSatish Balay   if (a->mult_work) {ierr = PetscFree(a->mult_work);CHKERRQ(ierr);}
151e51c0b9cSSatish Balay   if (a->icol) {ierr = ISDestroy(a->icol);CHKERRQ(ierr);}
152606d414cSSatish Balay   if (a->saved_values) {ierr = PetscFree(a->saved_values);CHKERRQ(ierr);}
153606d414cSSatish Balay   ierr = PetscFree(a);CHKERRQ(ierr);
1542d61bbb3SSatish Balay   PLogObjectDestroy(A);
1552d61bbb3SSatish Balay   PetscHeaderDestroy(A);
1562d61bbb3SSatish Balay   PetscFunctionReturn(0);
1572d61bbb3SSatish Balay }
1582d61bbb3SSatish Balay 
1592d61bbb3SSatish Balay #undef __FUNC__
1602d61bbb3SSatish Balay #define __FUNC__ "MatSetOption_SeqBAIJ"
1612d61bbb3SSatish Balay int MatSetOption_SeqBAIJ(Mat A,MatOption op)
1622d61bbb3SSatish Balay {
1632d61bbb3SSatish Balay   Mat_SeqBAIJ *a = (Mat_SeqBAIJ *) A->data;
1642d61bbb3SSatish Balay 
1652d61bbb3SSatish Balay   PetscFunctionBegin;
1662d61bbb3SSatish Balay   if      (op == MAT_ROW_ORIENTED)                 a->roworiented = 1;
1672d61bbb3SSatish Balay   else if (op == MAT_COLUMN_ORIENTED)              a->roworiented = 0;
1682d61bbb3SSatish Balay   else if (op == MAT_COLUMNS_SORTED)               a->sorted      = 1;
1692d61bbb3SSatish Balay   else if (op == MAT_COLUMNS_UNSORTED)             a->sorted      = 0;
1702d61bbb3SSatish Balay   else if (op == MAT_NO_NEW_NONZERO_LOCATIONS)     a->nonew       = 1;
1714787f768SSatish Balay   else if (op == MAT_NEW_NONZERO_LOCATION_ERR)     a->nonew       = -1;
1724787f768SSatish Balay   else if (op == MAT_NEW_NONZERO_ALLOCATION_ERR)   a->nonew       = -2;
1732d61bbb3SSatish Balay   else if (op == MAT_YES_NEW_NONZERO_LOCATIONS)    a->nonew       = 0;
1742d61bbb3SSatish Balay   else if (op == MAT_ROWS_SORTED ||
1752d61bbb3SSatish Balay            op == MAT_ROWS_UNSORTED ||
1762d61bbb3SSatish Balay            op == MAT_SYMMETRIC ||
1772d61bbb3SSatish Balay            op == MAT_STRUCTURALLY_SYMMETRIC ||
1782d61bbb3SSatish Balay            op == MAT_YES_NEW_DIAGONALS ||
179b51ba29fSSatish Balay            op == MAT_IGNORE_OFF_PROC_ENTRIES ||
180b51ba29fSSatish Balay            op == MAT_USE_HASH_TABLE) {
181981c4779SBarry Smith     PLogInfo(A,"MatSetOption_SeqBAIJ:Option ignored\n");
1822d61bbb3SSatish Balay   } else if (op == MAT_NO_NEW_DIAGONALS) {
1832d61bbb3SSatish Balay     SETERRQ(PETSC_ERR_SUP,0,"MAT_NO_NEW_DIAGONALS");
1842d61bbb3SSatish Balay   } else {
1852d61bbb3SSatish Balay     SETERRQ(PETSC_ERR_SUP,0,"unknown option");
1862d61bbb3SSatish Balay   }
1872d61bbb3SSatish Balay   PetscFunctionReturn(0);
1882d61bbb3SSatish Balay }
1892d61bbb3SSatish Balay 
1902d61bbb3SSatish Balay 
1912d61bbb3SSatish Balay #undef __FUNC__
1922d61bbb3SSatish Balay #define __FUNC__ "MatGetSize_SeqBAIJ"
1932d61bbb3SSatish Balay int MatGetSize_SeqBAIJ(Mat A,int *m,int *n)
1942d61bbb3SSatish Balay {
1952d61bbb3SSatish Balay   Mat_SeqBAIJ *a = (Mat_SeqBAIJ *) A->data;
1962d61bbb3SSatish Balay 
1972d61bbb3SSatish Balay   PetscFunctionBegin;
1982d61bbb3SSatish Balay   if (m) *m = a->m;
1992d61bbb3SSatish Balay   if (n) *n = a->n;
2002d61bbb3SSatish Balay   PetscFunctionReturn(0);
2012d61bbb3SSatish Balay }
2022d61bbb3SSatish Balay 
2032d61bbb3SSatish Balay #undef __FUNC__
2042d61bbb3SSatish Balay #define __FUNC__ "MatGetOwnershipRange_SeqBAIJ"
2052d61bbb3SSatish Balay int MatGetOwnershipRange_SeqBAIJ(Mat A,int *m,int *n)
2062d61bbb3SSatish Balay {
2072d61bbb3SSatish Balay   Mat_SeqBAIJ *a = (Mat_SeqBAIJ *) A->data;
2082d61bbb3SSatish Balay 
2092d61bbb3SSatish Balay   PetscFunctionBegin;
2102d61bbb3SSatish Balay   *m = 0; *n = a->m;
2112d61bbb3SSatish Balay   PetscFunctionReturn(0);
2122d61bbb3SSatish Balay }
2132d61bbb3SSatish Balay 
2142d61bbb3SSatish Balay #undef __FUNC__
2152d61bbb3SSatish Balay #define __FUNC__ "MatGetRow_SeqBAIJ"
2162d61bbb3SSatish Balay int MatGetRow_SeqBAIJ(Mat A,int row,int *nz,int **idx,Scalar **v)
2172d61bbb3SSatish Balay {
2182d61bbb3SSatish Balay   Mat_SeqBAIJ  *a = (Mat_SeqBAIJ *) A->data;
2192d61bbb3SSatish Balay   int          itmp,i,j,k,M,*ai,*aj,bs,bn,bp,*idx_i,bs2;
2203f1db9ecSBarry Smith   MatScalar    *aa,*aa_i;
2213f1db9ecSBarry Smith   Scalar       *v_i;
2222d61bbb3SSatish Balay 
2232d61bbb3SSatish Balay   PetscFunctionBegin;
2242d61bbb3SSatish Balay   bs  = a->bs;
2252d61bbb3SSatish Balay   ai  = a->i;
2262d61bbb3SSatish Balay   aj  = a->j;
2272d61bbb3SSatish Balay   aa  = a->a;
2282d61bbb3SSatish Balay   bs2 = a->bs2;
2292d61bbb3SSatish Balay 
2302d61bbb3SSatish Balay   if (row < 0 || row >= a->m) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Row out of range");
2312d61bbb3SSatish Balay 
2322d61bbb3SSatish Balay   bn  = row/bs;   /* Block number */
2332d61bbb3SSatish Balay   bp  = row % bs; /* Block Position */
2342d61bbb3SSatish Balay   M   = ai[bn+1] - ai[bn];
2352d61bbb3SSatish Balay   *nz = bs*M;
2362d61bbb3SSatish Balay 
2372d61bbb3SSatish Balay   if (v) {
2382d61bbb3SSatish Balay     *v = 0;
2392d61bbb3SSatish Balay     if (*nz) {
2402d61bbb3SSatish Balay       *v = (Scalar *) PetscMalloc( (*nz)*sizeof(Scalar) );CHKPTRQ(*v);
2412d61bbb3SSatish Balay       for ( i=0; i<M; i++ ) { /* for each block in the block row */
2422d61bbb3SSatish Balay         v_i  = *v + i*bs;
2432d61bbb3SSatish Balay         aa_i = aa + bs2*(ai[bn] + i);
2442d61bbb3SSatish Balay         for ( j=bp,k=0; j<bs2; j+=bs,k++ ) {v_i[k] = aa_i[j];}
2452d61bbb3SSatish Balay       }
2462d61bbb3SSatish Balay     }
2472d61bbb3SSatish Balay   }
2482d61bbb3SSatish Balay 
2492d61bbb3SSatish Balay   if (idx) {
2502d61bbb3SSatish Balay     *idx = 0;
2512d61bbb3SSatish Balay     if (*nz) {
2522d61bbb3SSatish Balay       *idx = (int *) PetscMalloc( (*nz)*sizeof(int) );CHKPTRQ(*idx);
2532d61bbb3SSatish Balay       for ( i=0; i<M; i++ ) { /* for each block in the block row */
2542d61bbb3SSatish Balay         idx_i = *idx + i*bs;
2552d61bbb3SSatish Balay         itmp  = bs*aj[ai[bn] + i];
2562d61bbb3SSatish Balay         for ( j=0; j<bs; j++ ) {idx_i[j] = itmp++;}
2572d61bbb3SSatish Balay       }
2582d61bbb3SSatish Balay     }
2592d61bbb3SSatish Balay   }
2602d61bbb3SSatish Balay   PetscFunctionReturn(0);
2612d61bbb3SSatish Balay }
2622d61bbb3SSatish Balay 
2632d61bbb3SSatish Balay #undef __FUNC__
2642d61bbb3SSatish Balay #define __FUNC__ "MatRestoreRow_SeqBAIJ"
2652d61bbb3SSatish Balay int MatRestoreRow_SeqBAIJ(Mat A,int row,int *nz,int **idx,Scalar **v)
2662d61bbb3SSatish Balay {
267606d414cSSatish Balay   int ierr;
268606d414cSSatish Balay 
2692d61bbb3SSatish Balay   PetscFunctionBegin;
270606d414cSSatish Balay   if (idx) {if (*idx) {ierr = PetscFree(*idx);CHKERRQ(ierr);}}
271606d414cSSatish Balay   if (v)   {if (*v)   {ierr = PetscFree(*v);CHKERRQ(ierr);}}
2722d61bbb3SSatish Balay   PetscFunctionReturn(0);
2732d61bbb3SSatish Balay }
2742d61bbb3SSatish Balay 
2752d61bbb3SSatish Balay #undef __FUNC__
2762d61bbb3SSatish Balay #define __FUNC__ "MatTranspose_SeqBAIJ"
2772d61bbb3SSatish Balay int MatTranspose_SeqBAIJ(Mat A,Mat *B)
2782d61bbb3SSatish Balay {
2792d61bbb3SSatish Balay   Mat_SeqBAIJ *a=(Mat_SeqBAIJ *)A->data;
2802d61bbb3SSatish Balay   Mat         C;
2812d61bbb3SSatish Balay   int         i,j,k,ierr,*aj=a->j,*ai=a->i,bs=a->bs,mbs=a->mbs,nbs=a->nbs,len,*col;
2822d61bbb3SSatish Balay   int         *rows,*cols,bs2=a->bs2;
2833f1db9ecSBarry Smith   MatScalar   *array = a->a;
2842d61bbb3SSatish Balay 
2852d61bbb3SSatish Balay   PetscFunctionBegin;
2862d61bbb3SSatish Balay   if (B==PETSC_NULL && mbs!=nbs) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Square matrix only for in-place");
2872d61bbb3SSatish Balay   col  = (int *) PetscMalloc((1+nbs)*sizeof(int));CHKPTRQ(col);
288549d3d68SSatish Balay   ierr = PetscMemzero(col,(1+nbs)*sizeof(int));CHKERRQ(ierr);
2892d61bbb3SSatish Balay 
2902d61bbb3SSatish Balay   for ( i=0; i<ai[mbs]; i++ ) col[aj[i]] += 1;
2912d61bbb3SSatish Balay   ierr = MatCreateSeqBAIJ(A->comm,bs,a->n,a->m,PETSC_NULL,col,&C);CHKERRQ(ierr);
292606d414cSSatish Balay   ierr = PetscFree(col);CHKERRQ(ierr);
2932d61bbb3SSatish Balay   rows = (int *) PetscMalloc(2*bs*sizeof(int));CHKPTRQ(rows);
2942d61bbb3SSatish Balay   cols = rows + bs;
2952d61bbb3SSatish Balay   for ( i=0; i<mbs; i++ ) {
2962d61bbb3SSatish Balay     cols[0] = i*bs;
2972d61bbb3SSatish Balay     for (k=1; k<bs; k++ ) cols[k] = cols[k-1] + 1;
2982d61bbb3SSatish Balay     len = ai[i+1] - ai[i];
2992d61bbb3SSatish Balay     for ( j=0; j<len; j++ ) {
3002d61bbb3SSatish Balay       rows[0] = (*aj++)*bs;
3012d61bbb3SSatish Balay       for (k=1; k<bs; k++ ) rows[k] = rows[k-1] + 1;
3022d61bbb3SSatish Balay       ierr = MatSetValues(C,bs,rows,bs,cols,array,INSERT_VALUES);CHKERRQ(ierr);
3032d61bbb3SSatish Balay       array += bs2;
3042d61bbb3SSatish Balay     }
3052d61bbb3SSatish Balay   }
306606d414cSSatish Balay   ierr = PetscFree(rows);CHKERRQ(ierr);
3072d61bbb3SSatish Balay 
3082d61bbb3SSatish Balay   ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
3092d61bbb3SSatish Balay   ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
3102d61bbb3SSatish Balay 
3112d61bbb3SSatish Balay   if (B != PETSC_NULL) {
3122d61bbb3SSatish Balay     *B = C;
3132d61bbb3SSatish Balay   } else {
314f830108cSBarry Smith     PetscOps *Abops;
315cc2dc46cSBarry Smith     MatOps   Aops;
316f830108cSBarry Smith 
3172d61bbb3SSatish Balay     /* This isn't really an in-place transpose */
318606d414cSSatish Balay     ierr = PetscFree(a->a);CHKERRQ(ierr);
319606d414cSSatish Balay     if (!a->singlemalloc) {
320606d414cSSatish Balay       ierr = PetscFree(a->i);CHKERRQ(ierr);
321606d414cSSatish Balay       ierr = PetscFree(a->j);CHKERRQ(ierr);
322606d414cSSatish Balay     }
323606d414cSSatish Balay     if (a->diag) {ierr = PetscFree(a->diag);CHKERRQ(ierr);}
324606d414cSSatish Balay     if (a->ilen) {ierr = PetscFree(a->ilen);CHKERRQ(ierr);}
325606d414cSSatish Balay     if (a->imax) {ierr = PetscFree(a->imax);CHKERRQ(ierr);}
326606d414cSSatish Balay     if (a->solve_work) {ierr = PetscFree(a->solve_work);CHKERRQ(ierr);}
327606d414cSSatish Balay     ierr = PetscFree(a);CHKERRQ(ierr);
328f830108cSBarry Smith 
3297413bad6SBarry Smith 
3307413bad6SBarry Smith     ierr = MapDestroy(A->rmap);CHKERRQ(ierr);
3317413bad6SBarry Smith     ierr = MapDestroy(A->cmap);CHKERRQ(ierr);
3327413bad6SBarry Smith 
333f830108cSBarry Smith     /*
334f830108cSBarry Smith        This is horrible, horrible code. We need to keep the
335f830108cSBarry Smith       A pointers for the bops and ops but copy everything
336f830108cSBarry Smith       else from C.
337f830108cSBarry Smith     */
338f830108cSBarry Smith     Abops    = A->bops;
339f830108cSBarry Smith     Aops     = A->ops;
340549d3d68SSatish Balay     ierr     = PetscMemcpy(A,C,sizeof(struct _p_Mat));CHKERRQ(ierr);
341f830108cSBarry Smith     A->bops  = Abops;
342f830108cSBarry Smith     A->ops   = Aops;
34327a8da17SBarry Smith     A->qlist = 0;
344f830108cSBarry Smith 
3452d61bbb3SSatish Balay     PetscHeaderDestroy(C);
3462d61bbb3SSatish Balay   }
3472d61bbb3SSatish Balay   PetscFunctionReturn(0);
3482d61bbb3SSatish Balay }
3492d61bbb3SSatish Balay 
3505615d1e5SSatish Balay #undef __FUNC__
351d4bb536fSBarry Smith #define __FUNC__ "MatView_SeqBAIJ_Binary"
352b6490206SBarry Smith static int MatView_SeqBAIJ_Binary(Mat A,Viewer viewer)
3532593348eSBarry Smith {
354b6490206SBarry Smith   Mat_SeqBAIJ *a = (Mat_SeqBAIJ *) A->data;
3559df24120SSatish Balay   int         i, fd, *col_lens, ierr, bs = a->bs,count,*jj,j,k,l,bs2=a->bs2;
356b6490206SBarry Smith   Scalar      *aa;
357ce6f0cecSBarry Smith   FILE        *file;
3582593348eSBarry Smith 
3593a40ed3dSBarry Smith   PetscFunctionBegin;
36090ace30eSBarry Smith   ierr = ViewerBinaryGetDescriptor(viewer,&fd);CHKERRQ(ierr);
3612593348eSBarry Smith   col_lens = (int *) PetscMalloc((4+a->m)*sizeof(int));CHKPTRQ(col_lens);
3622593348eSBarry Smith   col_lens[0] = MAT_COOKIE;
3633b2fbd54SBarry Smith 
3642593348eSBarry Smith   col_lens[1] = a->m;
3652593348eSBarry Smith   col_lens[2] = a->n;
3667e67e3f9SSatish Balay   col_lens[3] = a->nz*bs2;
3672593348eSBarry Smith 
3682593348eSBarry Smith   /* store lengths of each row and write (including header) to file */
369b6490206SBarry Smith   count = 0;
370b6490206SBarry Smith   for ( i=0; i<a->mbs; i++ ) {
371b6490206SBarry Smith     for ( j=0; j<bs; j++ ) {
372b6490206SBarry Smith       col_lens[4+count++] = bs*(a->i[i+1] - a->i[i]);
373b6490206SBarry Smith     }
3742593348eSBarry Smith   }
3750752156aSBarry Smith   ierr = PetscBinaryWrite(fd,col_lens,4+a->m,PETSC_INT,1);CHKERRQ(ierr);
376606d414cSSatish Balay   ierr = PetscFree(col_lens);CHKERRQ(ierr);
3772593348eSBarry Smith 
3782593348eSBarry Smith   /* store column indices (zero start index) */
37966963ce1SSatish Balay   jj = (int *) PetscMalloc( (a->nz+1)*bs2*sizeof(int) );CHKPTRQ(jj);
380b6490206SBarry Smith   count = 0;
381b6490206SBarry Smith   for ( i=0; i<a->mbs; i++ ) {
382b6490206SBarry Smith     for ( j=0; j<bs; j++ ) {
383b6490206SBarry Smith       for ( k=a->i[i]; k<a->i[i+1]; k++ ) {
384b6490206SBarry Smith         for ( l=0; l<bs; l++ ) {
385b6490206SBarry Smith           jj[count++] = bs*a->j[k] + l;
3862593348eSBarry Smith         }
3872593348eSBarry Smith       }
388b6490206SBarry Smith     }
389b6490206SBarry Smith   }
3900752156aSBarry Smith   ierr = PetscBinaryWrite(fd,jj,bs2*a->nz,PETSC_INT,0);CHKERRQ(ierr);
391606d414cSSatish Balay   ierr = PetscFree(jj);CHKERRQ(ierr);
3922593348eSBarry Smith 
3932593348eSBarry Smith   /* store nonzero values */
39466963ce1SSatish Balay   aa = (Scalar *) PetscMalloc((a->nz+1)*bs2*sizeof(Scalar));CHKPTRQ(aa);
395b6490206SBarry Smith   count = 0;
396b6490206SBarry Smith   for ( i=0; i<a->mbs; i++ ) {
397b6490206SBarry Smith     for ( j=0; j<bs; j++ ) {
398b6490206SBarry Smith       for ( k=a->i[i]; k<a->i[i+1]; k++ ) {
399b6490206SBarry Smith         for ( l=0; l<bs; l++ ) {
4007e67e3f9SSatish Balay           aa[count++] = a->a[bs2*k + l*bs + j];
401b6490206SBarry Smith         }
402b6490206SBarry Smith       }
403b6490206SBarry Smith     }
404b6490206SBarry Smith   }
4050752156aSBarry Smith   ierr = PetscBinaryWrite(fd,aa,bs2*a->nz,PETSC_SCALAR,0);CHKERRQ(ierr);
406606d414cSSatish Balay   ierr = PetscFree(aa);CHKERRQ(ierr);
407ce6f0cecSBarry Smith 
408ce6f0cecSBarry Smith   ierr = ViewerBinaryGetInfoPointer(viewer,&file);CHKERRQ(ierr);
409ce6f0cecSBarry Smith   if (file) {
410ce6f0cecSBarry Smith     fprintf(file,"-matload_block_size %d\n",a->bs);
411ce6f0cecSBarry Smith   }
4123a40ed3dSBarry Smith   PetscFunctionReturn(0);
4132593348eSBarry Smith }
4142593348eSBarry Smith 
4155615d1e5SSatish Balay #undef __FUNC__
416d4bb536fSBarry Smith #define __FUNC__ "MatView_SeqBAIJ_ASCII"
417b6490206SBarry Smith static int MatView_SeqBAIJ_ASCII(Mat A,Viewer viewer)
4182593348eSBarry Smith {
419b6490206SBarry Smith   Mat_SeqBAIJ *a = (Mat_SeqBAIJ *) A->data;
4209df24120SSatish Balay   int         ierr, i,j,format,bs = a->bs,k,l,bs2=a->bs2;
4212593348eSBarry Smith   char        *outputname;
4222593348eSBarry Smith 
4233a40ed3dSBarry Smith   PetscFunctionBegin;
42477ed5343SBarry Smith   ierr = ViewerGetOutputname(viewer,&outputname);CHKERRQ(ierr);
425888f2ed8SSatish Balay   ierr = ViewerGetFormat(viewer,&format);CHKERRQ(ierr);
426639f9d9dSBarry Smith   if (format == VIEWER_FORMAT_ASCII_INFO || format == VIEWER_FORMAT_ASCII_INFO_LONG) {
427d132466eSBarry Smith     ierr = ViewerASCIIPrintf(viewer,"  block size is %d\n",bs);CHKERRQ(ierr);
4280ef38995SBarry Smith   } else if (format == VIEWER_FORMAT_ASCII_MATLAB) {
4296831982aSBarry Smith     SETERRQ(PETSC_ERR_SUP,0,"Matlab format not supported");
4300ef38995SBarry Smith   } else if (format == VIEWER_FORMAT_ASCII_COMMON) {
4316831982aSBarry Smith     ierr = ViewerASCIIUseTabs(viewer,PETSC_NO);CHKERRQ(ierr);
43244cd7ae7SLois Curfman McInnes     for ( i=0; i<a->mbs; i++ ) {
43344cd7ae7SLois Curfman McInnes       for ( j=0; j<bs; j++ ) {
4346831982aSBarry Smith         ierr = ViewerASCIIPrintf(viewer,"row %d:",i*bs+j);CHKERRQ(ierr);
43544cd7ae7SLois Curfman McInnes         for ( k=a->i[i]; k<a->i[i+1]; k++ ) {
43644cd7ae7SLois Curfman McInnes           for ( l=0; l<bs; l++ ) {
437aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
4380ef38995SBarry Smith             if (PetscImaginary(a->a[bs2*k + l*bs + j]) > 0.0 && PetscReal(a->a[bs2*k + l*bs + j]) != 0.0) {
4396831982aSBarry Smith               ierr = ViewerASCIIPrintf(viewer," %d %g + %g i",bs*a->j[k]+l,
4406831982aSBarry Smith                       PetscReal(a->a[bs2*k + l*bs + j]),PetscImaginary(a->a[bs2*k + l*bs + j]));CHKERRQ(ierr);
4410ef38995SBarry Smith             } else if (PetscImaginary(a->a[bs2*k + l*bs + j]) < 0.0 && PetscReal(a->a[bs2*k + l*bs + j]) != 0.0) {
4426831982aSBarry Smith               ierr = ViewerASCIIPrintf(viewer," %d %g - %g i",bs*a->j[k]+l,
4436831982aSBarry Smith                       PetscReal(a->a[bs2*k + l*bs + j]),-PetscImaginary(a->a[bs2*k + l*bs + j]));CHKERRQ(ierr);
4440ef38995SBarry Smith             } else if (PetscReal(a->a[bs2*k + l*bs + j]) != 0.0) {
4456831982aSBarry Smith               ierr = ViewerASCIIPrintf(viewer," %d %g ",bs*a->j[k]+l,PetscReal(a->a[bs2*k + l*bs + j]));CHKERRQ(ierr);
4460ef38995SBarry Smith             }
44744cd7ae7SLois Curfman McInnes #else
4480ef38995SBarry Smith             if (a->a[bs2*k + l*bs + j] != 0.0) {
4496831982aSBarry Smith               ierr = ViewerASCIIPrintf(viewer," %d %g ",bs*a->j[k]+l,a->a[bs2*k + l*bs + j]);CHKERRQ(ierr);
4500ef38995SBarry Smith             }
45144cd7ae7SLois Curfman McInnes #endif
45244cd7ae7SLois Curfman McInnes           }
45344cd7ae7SLois Curfman McInnes         }
4546831982aSBarry Smith         ierr = ViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
45544cd7ae7SLois Curfman McInnes       }
45644cd7ae7SLois Curfman McInnes     }
4576831982aSBarry Smith     ierr = ViewerASCIIUseTabs(viewer,PETSC_YES);CHKERRQ(ierr);
4580ef38995SBarry Smith   } else {
4596831982aSBarry Smith     ierr = ViewerASCIIUseTabs(viewer,PETSC_NO);CHKERRQ(ierr);
460b6490206SBarry Smith     for ( i=0; i<a->mbs; i++ ) {
461b6490206SBarry Smith       for ( j=0; j<bs; j++ ) {
4626831982aSBarry Smith         ierr = ViewerASCIIPrintf(viewer,"row %d:",i*bs+j);CHKERRQ(ierr);
463b6490206SBarry Smith         for ( k=a->i[i]; k<a->i[i+1]; k++ ) {
464b6490206SBarry Smith           for ( l=0; l<bs; l++ ) {
465aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
466e20fef11SSatish Balay             if (PetscImaginary(a->a[bs2*k + l*bs + j]) > 0.0) {
4676831982aSBarry Smith               ierr = ViewerASCIIPrintf(viewer," %d %g + %g i",bs*a->j[k]+l,
4686831982aSBarry Smith                 PetscReal(a->a[bs2*k + l*bs + j]),PetscImaginary(a->a[bs2*k + l*bs + j]));CHKERRQ(ierr);
4690ef38995SBarry Smith             } else if (PetscImaginary(a->a[bs2*k + l*bs + j]) < 0.0) {
4706831982aSBarry Smith               ierr = ViewerASCIIPrintf(viewer," %d %g - %g i",bs*a->j[k]+l,
4716831982aSBarry Smith                 PetscReal(a->a[bs2*k + l*bs + j]),-PetscImaginary(a->a[bs2*k + l*bs + j]));CHKERRQ(ierr);
4720ef38995SBarry Smith             } else {
4736831982aSBarry Smith               ierr = ViewerASCIIPrintf(viewer," %d %g ",bs*a->j[k]+l,PetscReal(a->a[bs2*k + l*bs + j]));CHKERRQ(ierr);
47488685aaeSLois Curfman McInnes             }
47588685aaeSLois Curfman McInnes #else
4766831982aSBarry Smith             ierr = ViewerASCIIPrintf(viewer," %d %g ",bs*a->j[k]+l,a->a[bs2*k + l*bs + j]);CHKERRQ(ierr);
47788685aaeSLois Curfman McInnes #endif
4782593348eSBarry Smith           }
4792593348eSBarry Smith         }
4806831982aSBarry Smith         ierr = ViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
4812593348eSBarry Smith       }
4822593348eSBarry Smith     }
4836831982aSBarry Smith     ierr = ViewerASCIIUseTabs(viewer,PETSC_YES);CHKERRQ(ierr);
484b6490206SBarry Smith   }
4856831982aSBarry Smith   ierr = ViewerFlush(viewer);CHKERRQ(ierr);
4863a40ed3dSBarry Smith   PetscFunctionReturn(0);
4872593348eSBarry Smith }
4882593348eSBarry Smith 
4895615d1e5SSatish Balay #undef __FUNC__
49077ed5343SBarry Smith #define __FUNC__ "MatView_SeqBAIJ_Draw_Zoom"
49177ed5343SBarry Smith static int MatView_SeqBAIJ_Draw_Zoom(Draw draw,void *Aa)
4923270192aSSatish Balay {
49377ed5343SBarry Smith   Mat          A = (Mat) Aa;
4943270192aSSatish Balay   Mat_SeqBAIJ  *a=(Mat_SeqBAIJ *) A->data;
4957dce120fSSatish Balay   int          row,ierr,i,j,k,l,mbs=a->mbs,color,bs=a->bs,bs2=a->bs2,rank;
496fae8c767SSatish Balay   double       xl,yl,xr,yr,x_l,x_r,y_l,y_r;
4973f1db9ecSBarry Smith   MatScalar    *aa;
49877ed5343SBarry Smith   MPI_Comm     comm;
49977ed5343SBarry Smith   Viewer       viewer;
5003270192aSSatish Balay 
5013a40ed3dSBarry Smith   PetscFunctionBegin;
50277ed5343SBarry Smith   /*
50377ed5343SBarry Smith       This is nasty. If this is called from an originally parallel matrix
50477ed5343SBarry Smith    then all processes call this, but only the first has the matrix so the
50577ed5343SBarry Smith    rest should return immediately.
50677ed5343SBarry Smith   */
50777ed5343SBarry Smith   ierr = PetscObjectGetComm((PetscObject)draw,&comm);CHKERRQ(ierr);
508d132466eSBarry Smith   ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr);
50977ed5343SBarry Smith   if (rank) PetscFunctionReturn(0);
5103270192aSSatish Balay 
51177ed5343SBarry Smith   ierr = PetscObjectQuery((PetscObject)A,"Zoomviewer",(PetscObject*) &viewer);CHKERRQ(ierr);
51277ed5343SBarry Smith 
51377ed5343SBarry Smith   ierr = DrawGetCoordinates(draw,&xl,&yl,&xr,&yr);CHKERRQ(ierr);
51477ed5343SBarry Smith 
5153270192aSSatish Balay   /* loop over matrix elements drawing boxes */
5163270192aSSatish Balay   color = DRAW_BLUE;
5173270192aSSatish Balay   for ( i=0,row=0; i<mbs; i++,row+=bs ) {
5183270192aSSatish Balay     for ( j=a->i[i]; j<a->i[i+1]; j++ ) {
5193270192aSSatish Balay       y_l = a->m - row - 1.0; y_r = y_l + 1.0;
5203270192aSSatish Balay       x_l = a->j[j]*bs; x_r = x_l + 1.0;
5213270192aSSatish Balay       aa = a->a + j*bs2;
5223270192aSSatish Balay       for ( k=0; k<bs; k++ ) {
5233270192aSSatish Balay         for ( l=0; l<bs; l++ ) {
5243270192aSSatish Balay           if (PetscReal(*aa++) >=  0.) continue;
525433994e6SBarry Smith           ierr = DrawRectangle(draw,x_l+k,y_l-l,x_r+k,y_r-l,color,color,color,color);CHKERRQ(ierr);
5263270192aSSatish Balay         }
5273270192aSSatish Balay       }
5283270192aSSatish Balay     }
5293270192aSSatish Balay   }
5303270192aSSatish Balay   color = DRAW_CYAN;
5313270192aSSatish Balay   for ( i=0,row=0; i<mbs; i++,row+=bs ) {
5323270192aSSatish Balay     for ( j=a->i[i]; j<a->i[i+1]; j++ ) {
5333270192aSSatish Balay       y_l = a->m - row - 1.0; y_r = y_l + 1.0;
5343270192aSSatish Balay       x_l = a->j[j]*bs; x_r = x_l + 1.0;
5353270192aSSatish Balay       aa = a->a + j*bs2;
5363270192aSSatish Balay       for ( k=0; k<bs; k++ ) {
5373270192aSSatish Balay         for ( l=0; l<bs; l++ ) {
5383270192aSSatish Balay           if (PetscReal(*aa++) != 0.) continue;
539433994e6SBarry Smith           ierr = DrawRectangle(draw,x_l+k,y_l-l,x_r+k,y_r-l,color,color,color,color);CHKERRQ(ierr);
5403270192aSSatish Balay         }
5413270192aSSatish Balay       }
5423270192aSSatish Balay     }
5433270192aSSatish Balay   }
5443270192aSSatish Balay 
5453270192aSSatish Balay   color = DRAW_RED;
5463270192aSSatish Balay   for ( i=0,row=0; i<mbs; i++,row+=bs ) {
5473270192aSSatish Balay     for ( j=a->i[i]; j<a->i[i+1]; j++ ) {
5483270192aSSatish Balay       y_l = a->m - row - 1.0; y_r = y_l + 1.0;
5493270192aSSatish Balay       x_l = a->j[j]*bs; x_r = x_l + 1.0;
5503270192aSSatish Balay       aa = a->a + j*bs2;
5513270192aSSatish Balay       for ( k=0; k<bs; k++ ) {
5523270192aSSatish Balay         for ( l=0; l<bs; l++ ) {
5533270192aSSatish Balay           if (PetscReal(*aa++) <= 0.) continue;
554433994e6SBarry Smith           ierr = DrawRectangle(draw,x_l+k,y_l-l,x_r+k,y_r-l,color,color,color,color);CHKERRQ(ierr);
5553270192aSSatish Balay         }
5563270192aSSatish Balay       }
5573270192aSSatish Balay     }
5583270192aSSatish Balay   }
55977ed5343SBarry Smith   PetscFunctionReturn(0);
56077ed5343SBarry Smith }
5613270192aSSatish Balay 
56277ed5343SBarry Smith #undef __FUNC__
56377ed5343SBarry Smith #define __FUNC__ "MatView_SeqBAIJ_Draw"
56477ed5343SBarry Smith static int MatView_SeqBAIJ_Draw(Mat A,Viewer viewer)
56577ed5343SBarry Smith {
56677ed5343SBarry Smith   Mat_SeqBAIJ  *a=(Mat_SeqBAIJ *) A->data;
5677dce120fSSatish Balay   int          ierr;
5687dce120fSSatish Balay   double       xl,yl,xr,yr,w,h;
56977ed5343SBarry Smith   Draw         draw;
57077ed5343SBarry Smith   PetscTruth   isnull;
5713270192aSSatish Balay 
57277ed5343SBarry Smith   PetscFunctionBegin;
57377ed5343SBarry Smith 
57477ed5343SBarry Smith   ierr = ViewerDrawGetDraw(viewer,0,&draw);CHKERRQ(ierr);
57577ed5343SBarry Smith   ierr = DrawIsNull(draw,&isnull);CHKERRQ(ierr); if (isnull) PetscFunctionReturn(0);
57677ed5343SBarry Smith 
57777ed5343SBarry Smith   ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",(PetscObject)viewer);CHKERRQ(ierr);
57877ed5343SBarry Smith   xr  = a->n; yr = a->m; h = yr/10.0; w = xr/10.0;
57977ed5343SBarry Smith   xr += w;    yr += h;  xl = -w;     yl = -h;
5803270192aSSatish Balay   ierr = DrawSetCoordinates(draw,xl,yl,xr,yr);CHKERRQ(ierr);
58177ed5343SBarry Smith   ierr = DrawZoom(draw,MatView_SeqBAIJ_Draw_Zoom,A);CHKERRQ(ierr);
58277ed5343SBarry Smith   ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",PETSC_NULL);CHKERRQ(ierr);
5833a40ed3dSBarry Smith   PetscFunctionReturn(0);
5843270192aSSatish Balay }
5853270192aSSatish Balay 
5865615d1e5SSatish Balay #undef __FUNC__
587d4bb536fSBarry Smith #define __FUNC__ "MatView_SeqBAIJ"
588e1311b90SBarry Smith int MatView_SeqBAIJ(Mat A,Viewer viewer)
5892593348eSBarry Smith {
59019bcc07fSBarry Smith   int        ierr;
5916831982aSBarry Smith   PetscTruth issocket,isascii,isbinary,isdraw;
5922593348eSBarry Smith 
5933a40ed3dSBarry Smith   PetscFunctionBegin;
5946831982aSBarry Smith   ierr = PetscTypeCompare((PetscObject)viewer,SOCKET_VIEWER,&issocket);CHKERRQ(ierr);
5956831982aSBarry Smith   ierr = PetscTypeCompare((PetscObject)viewer,ASCII_VIEWER,&isascii);CHKERRQ(ierr);
5966831982aSBarry Smith   ierr = PetscTypeCompare((PetscObject)viewer,BINARY_VIEWER,&isbinary);CHKERRQ(ierr);
5976831982aSBarry Smith   ierr = PetscTypeCompare((PetscObject)viewer,DRAW_VIEWER,&isdraw);CHKERRQ(ierr);
5980f5bd95cSBarry Smith   if (issocket) {
5997b2a1423SBarry Smith     SETERRQ(PETSC_ERR_SUP,0,"Socket viewer not supported");
6000f5bd95cSBarry Smith   } else if (isascii){
6013a40ed3dSBarry Smith     ierr = MatView_SeqBAIJ_ASCII(A,viewer);CHKERRQ(ierr);
6020f5bd95cSBarry Smith   } else if (isbinary) {
6033a40ed3dSBarry Smith     ierr = MatView_SeqBAIJ_Binary(A,viewer);CHKERRQ(ierr);
6040f5bd95cSBarry Smith   } else if (isdraw) {
6053a40ed3dSBarry Smith     ierr = MatView_SeqBAIJ_Draw(A,viewer);CHKERRQ(ierr);
6065cd90555SBarry Smith   } else {
6070f5bd95cSBarry Smith     SETERRQ1(1,1,"Viewer type %s not supported by SeqBAIJ matrices",((PetscObject)viewer)->type_name);
6082593348eSBarry Smith   }
6093a40ed3dSBarry Smith   PetscFunctionReturn(0);
6102593348eSBarry Smith }
611b6490206SBarry Smith 
612cd0e1443SSatish Balay 
6135615d1e5SSatish Balay #undef __FUNC__
6142d61bbb3SSatish Balay #define __FUNC__ "MatGetValues_SeqBAIJ"
6152d61bbb3SSatish Balay int MatGetValues_SeqBAIJ(Mat A,int m,int *im,int n,int *in,Scalar *v)
616cd0e1443SSatish Balay {
617cd0e1443SSatish Balay   Mat_SeqBAIJ *a = (Mat_SeqBAIJ *) A->data;
6182d61bbb3SSatish Balay   int        *rp, k, low, high, t, row, nrow, i, col, l, *aj = a->j;
6192d61bbb3SSatish Balay   int        *ai = a->i, *ailen = a->ilen;
6202d61bbb3SSatish Balay   int        brow,bcol,ridx,cidx,bs=a->bs,bs2=a->bs2;
6213f1db9ecSBarry Smith   MatScalar  *ap, *aa = a->a, zero = 0.0;
622cd0e1443SSatish Balay 
6233a40ed3dSBarry Smith   PetscFunctionBegin;
6242d61bbb3SSatish Balay   for ( k=0; k<m; k++ ) { /* loop over rows */
625cd0e1443SSatish Balay     row  = im[k]; brow = row/bs;
626a8c6a408SBarry Smith     if (row < 0) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Negative row");
627a8c6a408SBarry Smith     if (row >= a->m) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Row too large");
6282d61bbb3SSatish Balay     rp   = aj + ai[brow] ; ap = aa + bs2*ai[brow] ;
6292c3acbe9SBarry Smith     nrow = ailen[brow];
6302d61bbb3SSatish Balay     for ( l=0; l<n; l++ ) { /* loop over columns */
631a8c6a408SBarry Smith       if (in[l] < 0) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Negative column");
632a8c6a408SBarry Smith       if (in[l] >= a->n) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Column too large");
6332d61bbb3SSatish Balay       col  = in[l] ;
6342d61bbb3SSatish Balay       bcol = col/bs;
6352d61bbb3SSatish Balay       cidx = col%bs;
6362d61bbb3SSatish Balay       ridx = row%bs;
6372d61bbb3SSatish Balay       high = nrow;
6382d61bbb3SSatish Balay       low  = 0; /* assume unsorted */
6392d61bbb3SSatish Balay       while (high-low > 5) {
640cd0e1443SSatish Balay         t = (low+high)/2;
641cd0e1443SSatish Balay         if (rp[t] > bcol) high = t;
642cd0e1443SSatish Balay         else             low  = t;
643cd0e1443SSatish Balay       }
644cd0e1443SSatish Balay       for ( i=low; i<high; i++ ) {
645cd0e1443SSatish Balay         if (rp[i] > bcol) break;
646cd0e1443SSatish Balay         if (rp[i] == bcol) {
6472d61bbb3SSatish Balay           *v++ = ap[bs2*i+bs*cidx+ridx];
6482d61bbb3SSatish Balay           goto finished;
649cd0e1443SSatish Balay         }
650cd0e1443SSatish Balay       }
6512d61bbb3SSatish Balay       *v++ = zero;
6522d61bbb3SSatish Balay       finished:;
653cd0e1443SSatish Balay     }
654cd0e1443SSatish Balay   }
6553a40ed3dSBarry Smith   PetscFunctionReturn(0);
656cd0e1443SSatish Balay }
657cd0e1443SSatish Balay 
6582d61bbb3SSatish Balay 
6595615d1e5SSatish Balay #undef __FUNC__
66005a5f48eSSatish Balay #define __FUNC__ "MatSetValuesBlocked_SeqBAIJ"
66192c4ed94SBarry Smith int MatSetValuesBlocked_SeqBAIJ(Mat A,int m,int *im,int n,int *in,Scalar *v,InsertMode is)
66292c4ed94SBarry Smith {
66392c4ed94SBarry Smith   Mat_SeqBAIJ *a = (Mat_SeqBAIJ *) A->data;
6648a84c255SSatish Balay   int         *rp,k,low,high,t,ii,jj,row,nrow,i,col,l,rmax,N,sorted=a->sorted;
665dd9472c6SBarry Smith   int         *imax=a->imax,*ai=a->i,*ailen=a->ilen, roworiented=a->roworiented;
666549d3d68SSatish Balay   int         *aj=a->j,nonew=a->nonew,bs2=a->bs2,bs=a->bs,stepval,ierr;
6673f1db9ecSBarry Smith   Scalar      *value = v;
6683f1db9ecSBarry Smith   MatScalar   *ap,*aa=a->a,*bap;
66992c4ed94SBarry Smith 
6703a40ed3dSBarry Smith   PetscFunctionBegin;
6710e324ae4SSatish Balay   if (roworiented) {
6720e324ae4SSatish Balay     stepval = (n-1)*bs;
6730e324ae4SSatish Balay   } else {
6740e324ae4SSatish Balay     stepval = (m-1)*bs;
6750e324ae4SSatish Balay   }
67692c4ed94SBarry Smith   for ( k=0; k<m; k++ ) { /* loop over added rows */
67792c4ed94SBarry Smith     row  = im[k];
6785ef9f2a5SBarry Smith     if (row < 0) continue;
679aa482453SBarry Smith #if defined(PETSC_USE_BOPT_g)
680a8c6a408SBarry Smith     if (row >= a->mbs) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Row too large");
68192c4ed94SBarry Smith #endif
68292c4ed94SBarry Smith     rp   = aj + ai[row];
68392c4ed94SBarry Smith     ap   = aa + bs2*ai[row];
68492c4ed94SBarry Smith     rmax = imax[row];
68592c4ed94SBarry Smith     nrow = ailen[row];
68692c4ed94SBarry Smith     low  = 0;
68792c4ed94SBarry Smith     for ( l=0; l<n; l++ ) { /* loop over added columns */
6885ef9f2a5SBarry Smith       if (in[l] < 0) continue;
689aa482453SBarry Smith #if defined(PETSC_USE_BOPT_g)
690a8c6a408SBarry Smith       if (in[l] >= a->nbs) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Column too large");
69192c4ed94SBarry Smith #endif
69292c4ed94SBarry Smith       col = in[l];
69392c4ed94SBarry Smith       if (roworiented) {
6940e324ae4SSatish Balay         value = v + k*(stepval+bs)*bs + l*bs;
6950e324ae4SSatish Balay       } else {
6960e324ae4SSatish Balay         value = v + l*(stepval+bs)*bs + k*bs;
69792c4ed94SBarry Smith       }
69892c4ed94SBarry Smith       if (!sorted) low = 0; high = nrow;
69992c4ed94SBarry Smith       while (high-low > 7) {
70092c4ed94SBarry Smith         t = (low+high)/2;
70192c4ed94SBarry Smith         if (rp[t] > col) high = t;
70292c4ed94SBarry Smith         else             low  = t;
70392c4ed94SBarry Smith       }
70492c4ed94SBarry Smith       for ( i=low; i<high; i++ ) {
70592c4ed94SBarry Smith         if (rp[i] > col) break;
70692c4ed94SBarry Smith         if (rp[i] == col) {
7078a84c255SSatish Balay           bap  = ap +  bs2*i;
7080e324ae4SSatish Balay           if (roworiented) {
7098a84c255SSatish Balay             if (is == ADD_VALUES) {
710dd9472c6SBarry Smith               for ( ii=0; ii<bs; ii++,value+=stepval ) {
711dd9472c6SBarry Smith                 for (jj=ii; jj<bs2; jj+=bs ) {
7128a84c255SSatish Balay                   bap[jj] += *value++;
713dd9472c6SBarry Smith                 }
714dd9472c6SBarry Smith               }
7150e324ae4SSatish Balay             } else {
716dd9472c6SBarry Smith               for ( ii=0; ii<bs; ii++,value+=stepval ) {
717dd9472c6SBarry Smith                 for (jj=ii; jj<bs2; jj+=bs ) {
7180e324ae4SSatish Balay                   bap[jj] = *value++;
7198a84c255SSatish Balay                 }
720dd9472c6SBarry Smith               }
721dd9472c6SBarry Smith             }
7220e324ae4SSatish Balay           } else {
7230e324ae4SSatish Balay             if (is == ADD_VALUES) {
724dd9472c6SBarry Smith               for ( ii=0; ii<bs; ii++,value+=stepval ) {
725dd9472c6SBarry Smith                 for (jj=0; jj<bs; jj++ ) {
7260e324ae4SSatish Balay                   *bap++ += *value++;
727dd9472c6SBarry Smith                 }
728dd9472c6SBarry Smith               }
7290e324ae4SSatish Balay             } else {
730dd9472c6SBarry Smith               for ( ii=0; ii<bs; ii++,value+=stepval ) {
731dd9472c6SBarry Smith                 for (jj=0; jj<bs; jj++ ) {
7320e324ae4SSatish Balay                   *bap++  = *value++;
7330e324ae4SSatish Balay                 }
7348a84c255SSatish Balay               }
735dd9472c6SBarry Smith             }
736dd9472c6SBarry Smith           }
737f1241b54SBarry Smith           goto noinsert2;
73892c4ed94SBarry Smith         }
73992c4ed94SBarry Smith       }
74089280ab3SLois Curfman McInnes       if (nonew == 1) goto noinsert2;
741a8c6a408SBarry Smith       else if (nonew == -1) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Inserting a new nonzero in the matrix");
74292c4ed94SBarry Smith       if (nrow >= rmax) {
74392c4ed94SBarry Smith         /* there is no extra room in row, therefore enlarge */
74492c4ed94SBarry Smith         int       new_nz = ai[a->mbs] + CHUNKSIZE,len,*new_i,*new_j;
7453f1db9ecSBarry Smith         MatScalar *new_a;
74692c4ed94SBarry Smith 
747a8c6a408SBarry Smith         if (nonew == -2) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Inserting a new nonzero in the matrix");
74889280ab3SLois Curfman McInnes 
74992c4ed94SBarry Smith         /* malloc new storage space */
7503f1db9ecSBarry Smith         len     = new_nz*(sizeof(int)+bs2*sizeof(MatScalar))+(a->mbs+1)*sizeof(int);
7513f1db9ecSBarry Smith         new_a   = (MatScalar *) PetscMalloc( len );CHKPTRQ(new_a);
75292c4ed94SBarry Smith         new_j   = (int *) (new_a + bs2*new_nz);
75392c4ed94SBarry Smith         new_i   = new_j + new_nz;
75492c4ed94SBarry Smith 
75592c4ed94SBarry Smith         /* copy over old data into new slots */
75692c4ed94SBarry Smith         for ( ii=0; ii<row+1; ii++ ) {new_i[ii] = ai[ii];}
75792c4ed94SBarry Smith         for ( ii=row+1; ii<a->mbs+1; ii++ ) {new_i[ii] = ai[ii]+CHUNKSIZE;}
758549d3d68SSatish Balay         ierr = PetscMemcpy(new_j,aj,(ai[row]+nrow)*sizeof(int));CHKERRQ(ierr);
75992c4ed94SBarry Smith         len  = (new_nz - CHUNKSIZE - ai[row] - nrow);
760549d3d68SSatish Balay         ierr = PetscMemcpy(new_j+ai[row]+nrow+CHUNKSIZE,aj+ai[row]+nrow,len*sizeof(int));CHKERRQ(ierr);
761549d3d68SSatish Balay         ierr = PetscMemcpy(new_a,aa,(ai[row]+nrow)*bs2*sizeof(MatScalar));CHKERRQ(ierr);
762549d3d68SSatish Balay         ierr = PetscMemzero(new_a+bs2*(ai[row]+nrow),bs2*CHUNKSIZE*sizeof(MatScalar));CHKERRQ(ierr);
763549d3d68SSatish Balay         ierr = PetscMemcpy(new_a+bs2*(ai[row]+nrow+CHUNKSIZE),aa+bs2*(ai[row]+nrow),bs2*len*sizeof(MatScalar));CHKERRQ(ierr);
76492c4ed94SBarry Smith         /* free up old matrix storage */
765606d414cSSatish Balay         ierr = PetscFree(a->a);CHKERRQ(ierr);
766606d414cSSatish Balay         if (!a->singlemalloc) {
767606d414cSSatish Balay           ierr = PetscFree(a->i);CHKERRQ(ierr);
768606d414cSSatish Balay           ierr = PetscFree(a->j);CHKERRQ(ierr);
769606d414cSSatish Balay         }
77092c4ed94SBarry Smith         aa = a->a = new_a; ai = a->i = new_i; aj = a->j = new_j;
77192c4ed94SBarry Smith         a->singlemalloc = 1;
77292c4ed94SBarry Smith 
77392c4ed94SBarry Smith         rp   = aj + ai[row]; ap = aa + bs2*ai[row];
77492c4ed94SBarry Smith         rmax = imax[row] = imax[row] + CHUNKSIZE;
7753f1db9ecSBarry Smith         PLogObjectMemory(A,CHUNKSIZE*(sizeof(int) + bs2*sizeof(MatScalar)));
77692c4ed94SBarry Smith         a->maxnz += bs2*CHUNKSIZE;
77792c4ed94SBarry Smith         a->reallocs++;
77892c4ed94SBarry Smith         a->nz++;
77992c4ed94SBarry Smith       }
78092c4ed94SBarry Smith       N = nrow++ - 1;
78192c4ed94SBarry Smith       /* shift up all the later entries in this row */
78292c4ed94SBarry Smith       for ( ii=N; ii>=i; ii-- ) {
78392c4ed94SBarry Smith         rp[ii+1] = rp[ii];
784549d3d68SSatish Balay         ierr = PetscMemcpy(ap+bs2*(ii+1),ap+bs2*(ii),bs2*sizeof(MatScalar));CHKERRQ(ierr);
78592c4ed94SBarry Smith       }
786549d3d68SSatish Balay       if (N >= i) {
787549d3d68SSatish Balay         ierr = PetscMemzero(ap+bs2*i,bs2*sizeof(MatScalar));CHKERRQ(ierr);
788549d3d68SSatish Balay       }
78992c4ed94SBarry Smith       rp[i] = col;
7908a84c255SSatish Balay       bap   = ap +  bs2*i;
7910e324ae4SSatish Balay       if (roworiented) {
792dd9472c6SBarry Smith         for ( ii=0; ii<bs; ii++,value+=stepval) {
793dd9472c6SBarry Smith           for (jj=ii; jj<bs2; jj+=bs ) {
7940e324ae4SSatish Balay             bap[jj] = *value++;
795dd9472c6SBarry Smith           }
796dd9472c6SBarry Smith         }
7970e324ae4SSatish Balay       } else {
798dd9472c6SBarry Smith         for ( ii=0; ii<bs; ii++,value+=stepval ) {
799dd9472c6SBarry Smith           for (jj=0; jj<bs; jj++ ) {
8000e324ae4SSatish Balay             *bap++  = *value++;
8010e324ae4SSatish Balay           }
802dd9472c6SBarry Smith         }
803dd9472c6SBarry Smith       }
804f1241b54SBarry Smith       noinsert2:;
80592c4ed94SBarry Smith       low = i;
80692c4ed94SBarry Smith     }
80792c4ed94SBarry Smith     ailen[row] = nrow;
80892c4ed94SBarry Smith   }
8093a40ed3dSBarry Smith   PetscFunctionReturn(0);
81092c4ed94SBarry Smith }
81192c4ed94SBarry Smith 
812f2501298SSatish Balay 
8135615d1e5SSatish Balay #undef __FUNC__
8145615d1e5SSatish Balay #define __FUNC__ "MatAssemblyEnd_SeqBAIJ"
8158f6be9afSLois Curfman McInnes int MatAssemblyEnd_SeqBAIJ(Mat A,MatAssemblyType mode)
816584200bdSSatish Balay {
817584200bdSSatish Balay   Mat_SeqBAIJ *a = (Mat_SeqBAIJ *) A->data;
818584200bdSSatish Balay   int        fshift = 0,i,j,*ai = a->i, *aj = a->j, *imax = a->imax;
819a7c10996SSatish Balay   int        m = a->m,*ip, N, *ailen = a->ilen;
820549d3d68SSatish Balay   int        mbs = a->mbs, bs2 = a->bs2,rmax = 0,ierr;
8213f1db9ecSBarry Smith   MatScalar  *aa = a->a, *ap;
822584200bdSSatish Balay 
8233a40ed3dSBarry Smith   PetscFunctionBegin;
8243a40ed3dSBarry Smith   if (mode == MAT_FLUSH_ASSEMBLY) PetscFunctionReturn(0);
825584200bdSSatish Balay 
82643ee02c3SBarry Smith   if (m) rmax = ailen[0];
827584200bdSSatish Balay   for ( i=1; i<mbs; i++ ) {
828584200bdSSatish Balay     /* move each row back by the amount of empty slots (fshift) before it*/
829584200bdSSatish Balay     fshift += imax[i-1] - ailen[i-1];
830d402145bSBarry Smith     rmax   = PetscMax(rmax,ailen[i]);
831584200bdSSatish Balay     if (fshift) {
832a7c10996SSatish Balay       ip = aj + ai[i]; ap = aa + bs2*ai[i];
833584200bdSSatish Balay       N = ailen[i];
834584200bdSSatish Balay       for ( j=0; j<N; j++ ) {
835584200bdSSatish Balay         ip[j-fshift] = ip[j];
836549d3d68SSatish Balay         ierr = PetscMemcpy(ap+(j-fshift)*bs2,ap+j*bs2,bs2*sizeof(MatScalar));CHKERRQ(ierr);
837584200bdSSatish Balay       }
838584200bdSSatish Balay     }
839584200bdSSatish Balay     ai[i] = ai[i-1] + ailen[i-1];
840584200bdSSatish Balay   }
841584200bdSSatish Balay   if (mbs) {
842584200bdSSatish Balay     fshift += imax[mbs-1] - ailen[mbs-1];
843584200bdSSatish Balay     ai[mbs] = ai[mbs-1] + ailen[mbs-1];
844584200bdSSatish Balay   }
845584200bdSSatish Balay   /* reset ilen and imax for each row */
846584200bdSSatish Balay   for ( i=0; i<mbs; i++ ) {
847584200bdSSatish Balay     ailen[i] = imax[i] = ai[i+1] - ai[i];
848584200bdSSatish Balay   }
849a7c10996SSatish Balay   a->nz = ai[mbs];
850584200bdSSatish Balay 
851584200bdSSatish Balay   /* diagonals may have moved, so kill the diagonal pointers */
852584200bdSSatish Balay   if (fshift && a->diag) {
853606d414cSSatish Balay     ierr = PetscFree(a->diag);CHKERRQ(ierr);
854584200bdSSatish Balay     PLogObjectMemory(A,-(m+1)*sizeof(int));
855584200bdSSatish Balay     a->diag = 0;
856584200bdSSatish Balay   }
8573d2013a6SLois Curfman McInnes   PLogInfo(A,"MatAssemblyEnd_SeqBAIJ:Matrix size: %d X %d, block size %d; storage space: %d unneeded, %d used\n",
858219d9a1aSLois Curfman McInnes            m,a->n,a->bs,fshift*bs2,a->nz*bs2);
8593d2013a6SLois Curfman McInnes   PLogInfo(A,"MatAssemblyEnd_SeqBAIJ:Number of mallocs during MatSetValues is %d\n",
860584200bdSSatish Balay            a->reallocs);
861d402145bSBarry Smith   PLogInfo(A,"MatAssemblyEnd_SeqBAIJ:Most nonzeros blocks in any row is %d\n",rmax);
862e2f3b5e9SSatish Balay   a->reallocs          = 0;
8634e220ebcSLois Curfman McInnes   A->info.nz_unneeded  = (double)fshift*bs2;
8644e220ebcSLois Curfman McInnes 
8653a40ed3dSBarry Smith   PetscFunctionReturn(0);
866584200bdSSatish Balay }
867584200bdSSatish Balay 
8685a838052SSatish Balay 
869bea157c4SSatish Balay 
870bea157c4SSatish Balay /*
871bea157c4SSatish Balay    This function returns an array of flags which indicate the locations of contiguous
872bea157c4SSatish Balay    blocks that should be zeroed. for eg: if bs = 3  and is = [0,1,2,3,5,6,7,8,9]
873bea157c4SSatish Balay    then the resulting sizes = [3,1,1,3,1] correspondig to sets [(0,1,2),(3),(5),(6,7,8),(9)]
874bea157c4SSatish Balay    Assume: sizes should be long enough to hold all the values.
875bea157c4SSatish Balay */
8765615d1e5SSatish Balay #undef __FUNC__
877bea157c4SSatish Balay #define __FUNC__ "MatZeroRows_SeqBAIJ_Check_Blocks"
878bea157c4SSatish Balay static int MatZeroRows_SeqBAIJ_Check_Blocks(int idx[],int n,int bs,int sizes[], int *bs_max)
879d9b7c43dSSatish Balay {
880bea157c4SSatish Balay   int        i,j,k,row;
881bea157c4SSatish Balay   PetscTruth flg;
8823a40ed3dSBarry Smith 
883433994e6SBarry Smith   PetscFunctionBegin;
884bea157c4SSatish Balay   for ( i=0,j=0; i<n; j++ ) {
885bea157c4SSatish Balay     row = idx[i];
886bea157c4SSatish Balay     if (row%bs!=0) { /* Not the begining of a block */
887bea157c4SSatish Balay       sizes[j] = 1;
888bea157c4SSatish Balay       i++;
889e4fda26cSSatish Balay     } else if (i+bs > n) { /* complete block doesn't exist (at idx end) */
890bea157c4SSatish Balay       sizes[j] = 1;         /* Also makes sure atleast 'bs' values exist for next else */
891bea157c4SSatish Balay       i++;
892bea157c4SSatish Balay     } else { /* Begining of the block, so check if the complete block exists */
893bea157c4SSatish Balay       flg = PETSC_TRUE;
894bea157c4SSatish Balay       for ( k=1; k<bs; k++ ) {
895bea157c4SSatish Balay         if (row+k != idx[i+k]) { /* break in the block */
896bea157c4SSatish Balay           flg = PETSC_FALSE;
897bea157c4SSatish Balay           break;
898d9b7c43dSSatish Balay         }
899bea157c4SSatish Balay       }
900bea157c4SSatish Balay       if (flg == PETSC_TRUE) { /* No break in the bs */
901bea157c4SSatish Balay         sizes[j] = bs;
902bea157c4SSatish Balay         i+= bs;
903bea157c4SSatish Balay       } else {
904bea157c4SSatish Balay         sizes[j] = 1;
905bea157c4SSatish Balay         i++;
906bea157c4SSatish Balay       }
907bea157c4SSatish Balay     }
908bea157c4SSatish Balay   }
909bea157c4SSatish Balay   *bs_max = j;
9103a40ed3dSBarry Smith   PetscFunctionReturn(0);
911d9b7c43dSSatish Balay }
912d9b7c43dSSatish Balay 
9135615d1e5SSatish Balay #undef __FUNC__
9145615d1e5SSatish Balay #define __FUNC__ "MatZeroRows_SeqBAIJ"
9158f6be9afSLois Curfman McInnes int MatZeroRows_SeqBAIJ(Mat A,IS is, Scalar *diag)
916d9b7c43dSSatish Balay {
917d9b7c43dSSatish Balay   Mat_SeqBAIJ *baij=(Mat_SeqBAIJ*)A->data;
918b6815fffSBarry Smith   int         ierr,i,j,k,count,is_n,*is_idx,*rows;
919bea157c4SSatish Balay   int         bs=baij->bs,bs2=baij->bs2,*sizes,row,bs_max;
9203f1db9ecSBarry Smith   Scalar      zero = 0.0;
9213f1db9ecSBarry Smith   MatScalar   *aa;
922d9b7c43dSSatish Balay 
9233a40ed3dSBarry Smith   PetscFunctionBegin;
924d9b7c43dSSatish Balay   /* Make a copy of the IS and  sort it */
925d9b7c43dSSatish Balay   ierr = ISGetSize(is,&is_n);CHKERRQ(ierr);
926d9b7c43dSSatish Balay   ierr = ISGetIndices(is,&is_idx);CHKERRQ(ierr);
927d9b7c43dSSatish Balay 
928bea157c4SSatish Balay   /* allocate memory for rows,sizes */
929bea157c4SSatish Balay   rows  = (int*)PetscMalloc((3*is_n+1)*sizeof(int));CHKPTRQ(rows);
930bea157c4SSatish Balay   sizes = rows + is_n;
931bea157c4SSatish Balay 
932bea157c4SSatish Balay   /* initialize copy IS valurs to rows, and sort them */
933bea157c4SSatish Balay   for (i=0; i<is_n; i++) { rows[i] = is_idx[i]; }
934bea157c4SSatish Balay   ierr = PetscSortInt(is_n,rows);CHKERRQ(ierr);
935bea157c4SSatish Balay   ierr = MatZeroRows_SeqBAIJ_Check_Blocks(rows,is_n,bs,sizes,&bs_max);CHKERRQ(ierr);
936b97a56abSSatish Balay   ierr = ISRestoreIndices(is,&is_idx);CHKERRQ(ierr);
937bea157c4SSatish Balay 
938bea157c4SSatish Balay   for ( i=0,j=0; i<bs_max; j+=sizes[i],i++ ) {
939bea157c4SSatish Balay     row   = rows[j];
940b6815fffSBarry Smith     if (row < 0 || row > baij->m) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,0,"row %d out of range",row);
941bea157c4SSatish Balay     count = (baij->i[row/bs +1] - baij->i[row/bs])*bs;
942bea157c4SSatish Balay     aa    = baij->a + baij->i[row/bs]*bs2 + (row%bs);
943bea157c4SSatish Balay     if (sizes[i] == bs) {
944bea157c4SSatish Balay       if (diag) {
945bea157c4SSatish Balay         if (baij->ilen[row/bs] > 0) {
946bea157c4SSatish Balay           baij->ilen[row/bs] = 1;
947bea157c4SSatish Balay           baij->j[baij->i[row/bs]] = row/bs;
948bea157c4SSatish Balay           ierr = PetscMemzero(aa,count*bs*sizeof(MatScalar));CHKERRQ(ierr);
949a07cd24cSSatish Balay         }
950bea157c4SSatish Balay         /* Now insert all the diagoanl values for this bs */
951bea157c4SSatish Balay         for ( k=0; k<bs; k++ ) {
952bea157c4SSatish Balay           ierr = (*A->ops->setvalues)(A,1,rows+j+k,1,rows+j+k,diag,INSERT_VALUES);CHKERRQ(ierr);
953bea157c4SSatish Balay         }
954bea157c4SSatish Balay       } else { /* (!diag) */
955bea157c4SSatish Balay         baij->ilen[row/bs] = 0;
956bea157c4SSatish Balay       } /* end (!diag) */
957bea157c4SSatish Balay     } else { /* (sizes[i] != bs) */
958aa482453SBarry Smith #if defined (PETSC_USE_DEBUG)
959bea157c4SSatish Balay       if (sizes[i] != 1) SETERRQ(1,0,"Internal Error. Value should be 1");
960bea157c4SSatish Balay #endif
961bea157c4SSatish Balay       for ( k=0; k<count; k++ ) {
962d9b7c43dSSatish Balay         aa[0] = zero;
963d9b7c43dSSatish Balay         aa+=bs;
964d9b7c43dSSatish Balay       }
965d9b7c43dSSatish Balay       if (diag) {
966f830108cSBarry Smith         ierr = (*A->ops->setvalues)(A,1,rows+j,1,rows+j,diag,INSERT_VALUES);CHKERRQ(ierr);
967d9b7c43dSSatish Balay       }
968d9b7c43dSSatish Balay     }
969bea157c4SSatish Balay   }
970bea157c4SSatish Balay 
971606d414cSSatish Balay   ierr = PetscFree(rows);CHKERRQ(ierr);
9729a8dea36SBarry Smith   ierr = MatAssemblyEnd_SeqBAIJ(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
9733a40ed3dSBarry Smith   PetscFunctionReturn(0);
974d9b7c43dSSatish Balay }
9751c351548SSatish Balay 
9765615d1e5SSatish Balay #undef __FUNC__
9772d61bbb3SSatish Balay #define __FUNC__ "MatSetValues_SeqBAIJ"
9782d61bbb3SSatish Balay int MatSetValues_SeqBAIJ(Mat A,int m,int *im,int n,int *in,Scalar *v,InsertMode is)
9792d61bbb3SSatish Balay {
9802d61bbb3SSatish Balay   Mat_SeqBAIJ *a = (Mat_SeqBAIJ *) A->data;
9812d61bbb3SSatish Balay   int         *rp,k,low,high,t,ii,row,nrow,i,col,l,rmax,N,sorted=a->sorted;
9822d61bbb3SSatish Balay   int         *imax=a->imax,*ai=a->i,*ailen=a->ilen,roworiented=a->roworiented;
9832d61bbb3SSatish Balay   int         *aj=a->j,nonew=a->nonew,bs=a->bs,brow,bcol;
984549d3d68SSatish Balay   int         ridx,cidx,bs2=a->bs2,ierr;
9853f1db9ecSBarry Smith   MatScalar   *ap,value,*aa=a->a,*bap;
9862d61bbb3SSatish Balay 
9872d61bbb3SSatish Balay   PetscFunctionBegin;
9882d61bbb3SSatish Balay   for ( k=0; k<m; k++ ) { /* loop over added rows */
9892d61bbb3SSatish Balay     row  = im[k]; brow = row/bs;
9905ef9f2a5SBarry Smith     if (row < 0) continue;
991aa482453SBarry Smith #if defined(PETSC_USE_BOPT_g)
99232e87ba3SBarry Smith     if (row >= a->m) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,0,"Row too large: row %d max %d",row,a->m);
9932d61bbb3SSatish Balay #endif
9942d61bbb3SSatish Balay     rp   = aj + ai[brow];
9952d61bbb3SSatish Balay     ap   = aa + bs2*ai[brow];
9962d61bbb3SSatish Balay     rmax = imax[brow];
9972d61bbb3SSatish Balay     nrow = ailen[brow];
9982d61bbb3SSatish Balay     low  = 0;
9992d61bbb3SSatish Balay     for ( l=0; l<n; l++ ) { /* loop over added columns */
10005ef9f2a5SBarry Smith       if (in[l] < 0) continue;
1001aa482453SBarry Smith #if defined(PETSC_USE_BOPT_g)
100232e87ba3SBarry Smith       if (in[l] >= a->n) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,0,"Column too large: col %d max %d",in[l],a->n);
10032d61bbb3SSatish Balay #endif
10042d61bbb3SSatish Balay       col = in[l]; bcol = col/bs;
10052d61bbb3SSatish Balay       ridx = row % bs; cidx = col % bs;
10062d61bbb3SSatish Balay       if (roworiented) {
10075ef9f2a5SBarry Smith         value = v[l + k*n];
10082d61bbb3SSatish Balay       } else {
10092d61bbb3SSatish Balay         value = v[k + l*m];
10102d61bbb3SSatish Balay       }
10112d61bbb3SSatish Balay       if (!sorted) low = 0; high = nrow;
10122d61bbb3SSatish Balay       while (high-low > 7) {
10132d61bbb3SSatish Balay         t = (low+high)/2;
10142d61bbb3SSatish Balay         if (rp[t] > bcol) high = t;
10152d61bbb3SSatish Balay         else              low  = t;
10162d61bbb3SSatish Balay       }
10172d61bbb3SSatish Balay       for ( i=low; i<high; i++ ) {
10182d61bbb3SSatish Balay         if (rp[i] > bcol) break;
10192d61bbb3SSatish Balay         if (rp[i] == bcol) {
10202d61bbb3SSatish Balay           bap  = ap +  bs2*i + bs*cidx + ridx;
10212d61bbb3SSatish Balay           if (is == ADD_VALUES) *bap += value;
10222d61bbb3SSatish Balay           else                  *bap  = value;
10232d61bbb3SSatish Balay           goto noinsert1;
10242d61bbb3SSatish Balay         }
10252d61bbb3SSatish Balay       }
10262d61bbb3SSatish Balay       if (nonew == 1) goto noinsert1;
10272d61bbb3SSatish Balay       else if (nonew == -1) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Inserting a new nonzero in the matrix");
10282d61bbb3SSatish Balay       if (nrow >= rmax) {
10292d61bbb3SSatish Balay         /* there is no extra room in row, therefore enlarge */
10302d61bbb3SSatish Balay         int       new_nz = ai[a->mbs] + CHUNKSIZE,len,*new_i,*new_j;
10313f1db9ecSBarry Smith         MatScalar *new_a;
10322d61bbb3SSatish Balay 
10332d61bbb3SSatish Balay         if (nonew == -2) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Inserting a new nonzero in the matrix");
10342d61bbb3SSatish Balay 
10352d61bbb3SSatish Balay         /* Malloc new storage space */
10363f1db9ecSBarry Smith         len     = new_nz*(sizeof(int)+bs2*sizeof(MatScalar))+(a->mbs+1)*sizeof(int);
10373f1db9ecSBarry Smith         new_a   = (MatScalar *) PetscMalloc( len );CHKPTRQ(new_a);
10382d61bbb3SSatish Balay         new_j   = (int *) (new_a + bs2*new_nz);
10392d61bbb3SSatish Balay         new_i   = new_j + new_nz;
10402d61bbb3SSatish Balay 
10412d61bbb3SSatish Balay         /* copy over old data into new slots */
10422d61bbb3SSatish Balay         for ( ii=0; ii<brow+1; ii++ ) {new_i[ii] = ai[ii];}
10432d61bbb3SSatish Balay         for ( ii=brow+1; ii<a->mbs+1; ii++ ) {new_i[ii] = ai[ii]+CHUNKSIZE;}
1044549d3d68SSatish Balay         ierr = PetscMemcpy(new_j,aj,(ai[brow]+nrow)*sizeof(int));CHKERRQ(ierr);
10452d61bbb3SSatish Balay         len  = (new_nz - CHUNKSIZE - ai[brow] - nrow);
1046549d3d68SSatish Balay         ierr = PetscMemcpy(new_j+ai[brow]+nrow+CHUNKSIZE,aj+ai[brow]+nrow,len*sizeof(int));CHKERRQ(ierr);
1047549d3d68SSatish Balay         ierr = PetscMemcpy(new_a,aa,(ai[brow]+nrow)*bs2*sizeof(MatScalar));CHKERRQ(ierr);
1048549d3d68SSatish Balay         ierr = PetscMemzero(new_a+bs2*(ai[brow]+nrow),bs2*CHUNKSIZE*sizeof(MatScalar));CHKERRQ(ierr);
1049549d3d68SSatish Balay         ierr = PetscMemcpy(new_a+bs2*(ai[brow]+nrow+CHUNKSIZE),aa+bs2*(ai[brow]+nrow),bs2*len*sizeof(MatScalar));CHKERRQ(ierr);
10502d61bbb3SSatish Balay         /* free up old matrix storage */
1051606d414cSSatish Balay         ierr = PetscFree(a->a);CHKERRQ(ierr);
1052606d414cSSatish Balay         if (!a->singlemalloc) {
1053606d414cSSatish Balay           ierr = PetscFree(a->i);CHKERRQ(ierr);
1054606d414cSSatish Balay           ierr = PetscFree(a->j);CHKERRQ(ierr);
1055606d414cSSatish Balay         }
10562d61bbb3SSatish Balay         aa = a->a = new_a; ai = a->i = new_i; aj = a->j = new_j;
10572d61bbb3SSatish Balay         a->singlemalloc = 1;
10582d61bbb3SSatish Balay 
10592d61bbb3SSatish Balay         rp   = aj + ai[brow]; ap = aa + bs2*ai[brow];
10602d61bbb3SSatish Balay         rmax = imax[brow] = imax[brow] + CHUNKSIZE;
10613f1db9ecSBarry Smith         PLogObjectMemory(A,CHUNKSIZE*(sizeof(int) + bs2*sizeof(MatScalar)));
10622d61bbb3SSatish Balay         a->maxnz += bs2*CHUNKSIZE;
10632d61bbb3SSatish Balay         a->reallocs++;
10642d61bbb3SSatish Balay         a->nz++;
10652d61bbb3SSatish Balay       }
10662d61bbb3SSatish Balay       N = nrow++ - 1;
10672d61bbb3SSatish Balay       /* shift up all the later entries in this row */
10682d61bbb3SSatish Balay       for ( ii=N; ii>=i; ii-- ) {
10692d61bbb3SSatish Balay         rp[ii+1] = rp[ii];
1070549d3d68SSatish Balay         ierr     = PetscMemcpy(ap+bs2*(ii+1),ap+bs2*(ii),bs2*sizeof(MatScalar));CHKERRQ(ierr);
10712d61bbb3SSatish Balay       }
1072549d3d68SSatish Balay       if (N>=i) {
1073549d3d68SSatish Balay         ierr = PetscMemzero(ap+bs2*i,bs2*sizeof(MatScalar));CHKERRQ(ierr);
1074549d3d68SSatish Balay       }
10752d61bbb3SSatish Balay       rp[i]                      = bcol;
10762d61bbb3SSatish Balay       ap[bs2*i + bs*cidx + ridx] = value;
10772d61bbb3SSatish Balay       noinsert1:;
10782d61bbb3SSatish Balay       low = i;
10792d61bbb3SSatish Balay     }
10802d61bbb3SSatish Balay     ailen[brow] = nrow;
10812d61bbb3SSatish Balay   }
10822d61bbb3SSatish Balay   PetscFunctionReturn(0);
10832d61bbb3SSatish Balay }
10842d61bbb3SSatish Balay 
10852d61bbb3SSatish Balay extern int MatLUFactorSymbolic_SeqBAIJ(Mat,IS,IS,double,Mat*);
10862d61bbb3SSatish Balay extern int MatLUFactor_SeqBAIJ(Mat,IS,IS,double);
10872d61bbb3SSatish Balay extern int MatIncreaseOverlap_SeqBAIJ(Mat,int,IS*,int);
10887b2a1423SBarry Smith extern int MatGetSubMatrix_SeqBAIJ(Mat,IS,IS,int,MatReuse,Mat*);
10897b2a1423SBarry Smith extern int MatGetSubMatrices_SeqBAIJ(Mat,int,IS*,IS*,MatReuse,Mat**);
10902d61bbb3SSatish Balay extern int MatMultTrans_SeqBAIJ(Mat,Vec,Vec);
10912d61bbb3SSatish Balay extern int MatMultTransAdd_SeqBAIJ(Mat,Vec,Vec,Vec);
10922d61bbb3SSatish Balay extern int MatScale_SeqBAIJ(Scalar*,Mat);
10932d61bbb3SSatish Balay extern int MatNorm_SeqBAIJ(Mat,NormType,double *);
10942d61bbb3SSatish Balay extern int MatEqual_SeqBAIJ(Mat,Mat, PetscTruth*);
10952d61bbb3SSatish Balay extern int MatGetDiagonal_SeqBAIJ(Mat,Vec);
10962d61bbb3SSatish Balay extern int MatDiagonalScale_SeqBAIJ(Mat,Vec,Vec);
10972d61bbb3SSatish Balay extern int MatGetInfo_SeqBAIJ(Mat,MatInfoType,MatInfo *);
10982d61bbb3SSatish Balay extern int MatZeroEntries_SeqBAIJ(Mat);
10992d61bbb3SSatish Balay 
11002d61bbb3SSatish Balay extern int MatSolve_SeqBAIJ_N(Mat,Vec,Vec);
11012d61bbb3SSatish Balay extern int MatSolve_SeqBAIJ_1(Mat,Vec,Vec);
11022d61bbb3SSatish Balay extern int MatSolve_SeqBAIJ_2(Mat,Vec,Vec);
11032d61bbb3SSatish Balay extern int MatSolve_SeqBAIJ_3(Mat,Vec,Vec);
11042d61bbb3SSatish Balay extern int MatSolve_SeqBAIJ_4(Mat,Vec,Vec);
11052d61bbb3SSatish Balay extern int MatSolve_SeqBAIJ_5(Mat,Vec,Vec);
110615091d37SBarry Smith extern int MatSolve_SeqBAIJ_6(Mat,Vec,Vec);
11072d61bbb3SSatish Balay extern int MatSolve_SeqBAIJ_7(Mat,Vec,Vec);
1108*f1af5d2fSBarry Smith extern int MatSolveTrans_SeqBAIJ_7(Mat,Vec,Vec);
1109*f1af5d2fSBarry Smith extern int MatSolveTrans_SeqBAIJ_6(Mat,Vec,Vec);
1110*f1af5d2fSBarry Smith extern int MatSolveTrans_SeqBAIJ_5(Mat,Vec,Vec);
1111*f1af5d2fSBarry Smith extern int MatSolveTrans_SeqBAIJ_4(Mat,Vec,Vec);
1112*f1af5d2fSBarry Smith extern int MatSolveTrans_SeqBAIJ_3(Mat,Vec,Vec);
1113*f1af5d2fSBarry Smith extern int MatSolveTrans_SeqBAIJ_2(Mat,Vec,Vec);
1114*f1af5d2fSBarry Smith extern int MatSolveTrans_SeqBAIJ_1(Mat,Vec,Vec);
11152d61bbb3SSatish Balay 
11162d61bbb3SSatish Balay extern int MatLUFactorNumeric_SeqBAIJ_N(Mat,Mat*);
11172d61bbb3SSatish Balay extern int MatLUFactorNumeric_SeqBAIJ_1(Mat,Mat*);
11182d61bbb3SSatish Balay extern int MatLUFactorNumeric_SeqBAIJ_2(Mat,Mat*);
11192d61bbb3SSatish Balay extern int MatLUFactorNumeric_SeqBAIJ_3(Mat,Mat*);
11202d61bbb3SSatish Balay extern int MatLUFactorNumeric_SeqBAIJ_4(Mat,Mat*);
11212d61bbb3SSatish Balay extern int MatLUFactorNumeric_SeqBAIJ_5(Mat,Mat*);
112215091d37SBarry Smith extern int MatLUFactorNumeric_SeqBAIJ_6(Mat,Mat*);
11232d61bbb3SSatish Balay 
11242d61bbb3SSatish Balay extern int MatMult_SeqBAIJ_1(Mat,Vec,Vec);
11252d61bbb3SSatish Balay extern int MatMult_SeqBAIJ_2(Mat,Vec,Vec);
11262d61bbb3SSatish Balay extern int MatMult_SeqBAIJ_3(Mat,Vec,Vec);
11272d61bbb3SSatish Balay extern int MatMult_SeqBAIJ_4(Mat,Vec,Vec);
11282d61bbb3SSatish Balay extern int MatMult_SeqBAIJ_5(Mat,Vec,Vec);
112915091d37SBarry Smith extern int MatMult_SeqBAIJ_6(Mat,Vec,Vec);
11302d61bbb3SSatish Balay extern int MatMult_SeqBAIJ_7(Mat,Vec,Vec);
11312d61bbb3SSatish Balay extern int MatMult_SeqBAIJ_N(Mat,Vec,Vec);
11322d61bbb3SSatish Balay 
11332d61bbb3SSatish Balay extern int MatMultAdd_SeqBAIJ_1(Mat,Vec,Vec,Vec);
11342d61bbb3SSatish Balay extern int MatMultAdd_SeqBAIJ_2(Mat,Vec,Vec,Vec);
11352d61bbb3SSatish Balay extern int MatMultAdd_SeqBAIJ_3(Mat,Vec,Vec,Vec);
11362d61bbb3SSatish Balay extern int MatMultAdd_SeqBAIJ_4(Mat,Vec,Vec,Vec);
11372d61bbb3SSatish Balay extern int MatMultAdd_SeqBAIJ_5(Mat,Vec,Vec,Vec);
113815091d37SBarry Smith extern int MatMultAdd_SeqBAIJ_6(Mat,Vec,Vec,Vec);
11392d61bbb3SSatish Balay extern int MatMultAdd_SeqBAIJ_7(Mat,Vec,Vec,Vec);
11402d61bbb3SSatish Balay extern int MatMultAdd_SeqBAIJ_N(Mat,Vec,Vec,Vec);
11412d61bbb3SSatish Balay 
11422d61bbb3SSatish Balay #undef __FUNC__
11432d61bbb3SSatish Balay #define __FUNC__ "MatILUFactor_SeqBAIJ"
11445ef9f2a5SBarry Smith int MatILUFactor_SeqBAIJ(Mat inA,IS row,IS col,MatILUInfo *info)
11452d61bbb3SSatish Balay {
11462d61bbb3SSatish Balay   Mat_SeqBAIJ *a = (Mat_SeqBAIJ *) inA->data;
11472d61bbb3SSatish Balay   Mat         outA;
11482d61bbb3SSatish Balay   int         ierr;
1149667159a5SBarry Smith   PetscTruth  row_identity, col_identity;
11502d61bbb3SSatish Balay 
11512d61bbb3SSatish Balay   PetscFunctionBegin;
1152b6d21a55SBarry Smith   if (info && info->levels != 0) SETERRQ(PETSC_ERR_SUP,0,"Only levels = 0 supported for in-place ILU");
1153667159a5SBarry Smith   ierr = ISIdentity(row,&row_identity);CHKERRQ(ierr);
1154667159a5SBarry Smith   ierr = ISIdentity(col,&col_identity);CHKERRQ(ierr);
1155667159a5SBarry Smith   if (!row_identity || !col_identity) {
1156b008c796SBarry Smith     SETERRQ(1,1,"Row and column permutations must be identity for in-place ILU");
1157667159a5SBarry Smith   }
11582d61bbb3SSatish Balay 
11592d61bbb3SSatish Balay   outA          = inA;
11602d61bbb3SSatish Balay   inA->factor   = FACTOR_LU;
11612d61bbb3SSatish Balay   a->row        = row;
11622d61bbb3SSatish Balay   a->col        = col;
11632d61bbb3SSatish Balay 
1164e51c0b9cSSatish Balay   /* Create the invert permutation so that it can be used in MatLUFactorNumeric() */
1165e51c0b9cSSatish Balay   ierr = ISInvertPermutation(col,&(a->icol));CHKERRQ(ierr);
11661e4dd532SSatish Balay   PLogObjectParent(inA,a->icol);
1167e51c0b9cSSatish Balay 
11682d61bbb3SSatish Balay   if (!a->solve_work) {
11692d61bbb3SSatish Balay     a->solve_work = (Scalar *) PetscMalloc((a->m+a->bs)*sizeof(Scalar));CHKPTRQ(a->solve_work);
11702d61bbb3SSatish Balay     PLogObjectMemory(inA,(a->m+a->bs)*sizeof(Scalar));
11712d61bbb3SSatish Balay   }
11722d61bbb3SSatish Balay 
11732d61bbb3SSatish Balay   if (!a->diag) {
11742d61bbb3SSatish Balay     ierr = MatMarkDiag_SeqBAIJ(inA);CHKERRQ(ierr);
11752d61bbb3SSatish Balay   }
11762d61bbb3SSatish Balay   /*
117715091d37SBarry Smith       Blocksize 2, 3, 4, 5, 6 and 7 have a special faster factorization/solver
117815091d37SBarry Smith       for ILU(0) factorization with natural ordering
11792d61bbb3SSatish Balay   */
118015091d37SBarry Smith   switch (a->bs) {
1181*f1af5d2fSBarry Smith   case 1:
1182*f1af5d2fSBarry Smith     inA->ops->solvetrans      = MatSolveTrans_SeqBAIJ_2_NaturalOrdering;
1183*f1af5d2fSBarry Smith     PLogInfo(inA,"MatILUFactor_SeqBAIJ:Using special in-place natural ordering solvetrans BS=1\n");
118415091d37SBarry Smith   case 2:
118515091d37SBarry Smith     inA->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_2_NaturalOrdering;
118615091d37SBarry Smith     inA->ops->solve           = MatSolve_SeqBAIJ_2_NaturalOrdering;
1187*f1af5d2fSBarry Smith     inA->ops->solvetrans      = MatSolveTrans_SeqBAIJ_2_NaturalOrdering;
118815091d37SBarry Smith     PLogInfo(inA,"MatILUFactor_SeqBAIJ:Using special in-place natural ordering factor and solve BS=2\n");
118915091d37SBarry Smith     break;
119015091d37SBarry Smith   case 3:
119115091d37SBarry Smith     inA->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_3_NaturalOrdering;
119215091d37SBarry Smith     inA->ops->solve           = MatSolve_SeqBAIJ_3_NaturalOrdering;
1193*f1af5d2fSBarry Smith     inA->ops->solvetrans      = MatSolveTrans_SeqBAIJ_3_NaturalOrdering;
119415091d37SBarry Smith     PLogInfo(inA,"MatILUFactor_SeqBAIJ:Using special in-place natural ordering factor and solve BS=3\n");
119515091d37SBarry Smith     break;
119615091d37SBarry Smith   case 4:
1197667159a5SBarry Smith     inA->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_4_NaturalOrdering;
1198f830108cSBarry Smith     inA->ops->solve           = MatSolve_SeqBAIJ_4_NaturalOrdering;
1199*f1af5d2fSBarry Smith     inA->ops->solvetrans      = MatSolveTrans_SeqBAIJ_4_NaturalOrdering;
120015091d37SBarry Smith     PLogInfo(inA,"MatILUFactor_SeqBAIJ:Using special in-place natural ordering factor and solve BS=4\n");
120115091d37SBarry Smith     break;
120215091d37SBarry Smith   case 5:
1203667159a5SBarry Smith     inA->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_5_NaturalOrdering;
1204667159a5SBarry Smith     inA->ops->solve           = MatSolve_SeqBAIJ_5_NaturalOrdering;
1205*f1af5d2fSBarry Smith     inA->ops->solvetrans      = MatSolveTrans_SeqBAIJ_5_NaturalOrdering;
120615091d37SBarry Smith     PLogInfo(inA,"MatILUFactor_SeqBAIJ:Using special in-place natural ordering factor and solve BS=5\n");
120715091d37SBarry Smith     break;
120815091d37SBarry Smith   case 6:
120915091d37SBarry Smith     inA->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_6_NaturalOrdering;
121015091d37SBarry Smith     inA->ops->solve           = MatSolve_SeqBAIJ_6_NaturalOrdering;
1211*f1af5d2fSBarry Smith     inA->ops->solvetrans      = MatSolveTrans_SeqBAIJ_6_NaturalOrdering;
121215091d37SBarry Smith     PLogInfo(inA,"MatILUFactor_SeqBAIJ:Using special in-place natural ordering factor and solve BS=6\n");
121315091d37SBarry Smith     break;
121415091d37SBarry Smith   case 7:
121515091d37SBarry Smith     inA->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_7_NaturalOrdering;
1216*f1af5d2fSBarry Smith     inA->ops->solvetrans      = MatSolveTrans_SeqBAIJ_7_NaturalOrdering;
121715091d37SBarry Smith     inA->ops->solve           = MatSolve_SeqBAIJ_7_NaturalOrdering;
121815091d37SBarry Smith     PLogInfo(inA,"MatILUFactor_SeqBAIJ:Using special in-place natural ordering factor and solve BS=7\n");
121915091d37SBarry Smith     break;
12202d61bbb3SSatish Balay   }
12212d61bbb3SSatish Balay 
1222667159a5SBarry Smith   ierr = MatLUFactorNumeric(inA,&outA);CHKERRQ(ierr);
1223667159a5SBarry Smith 
12242d61bbb3SSatish Balay   PetscFunctionReturn(0);
12252d61bbb3SSatish Balay }
12262d61bbb3SSatish Balay #undef __FUNC__
1227d4bb536fSBarry Smith #define __FUNC__ "MatPrintHelp_SeqBAIJ"
1228ba4ca20aSSatish Balay int MatPrintHelp_SeqBAIJ(Mat A)
1229ba4ca20aSSatish Balay {
1230ba4ca20aSSatish Balay   static int called = 0;
1231ba4ca20aSSatish Balay   MPI_Comm   comm = A->comm;
1232d132466eSBarry Smith   int        ierr;
1233ba4ca20aSSatish Balay 
12343a40ed3dSBarry Smith   PetscFunctionBegin;
12353a40ed3dSBarry Smith   if (called) {PetscFunctionReturn(0);} else called = 1;
1236d132466eSBarry Smith   ierr = (*PetscHelpPrintf)(comm," Options for MATSEQBAIJ and MATMPIBAIJ matrix formats (the defaults):\n");CHKERRQ(ierr);
1237d132466eSBarry Smith   ierr = (*PetscHelpPrintf)(comm,"  -mat_block_size <block_size>\n");CHKERRQ(ierr);
12383a40ed3dSBarry Smith   PetscFunctionReturn(0);
1239ba4ca20aSSatish Balay }
1240d9b7c43dSSatish Balay 
1241fb2e594dSBarry Smith EXTERN_C_BEGIN
124227a8da17SBarry Smith #undef __FUNC__
124327a8da17SBarry Smith #define __FUNC__ "MatSeqBAIJSetColumnIndices_SeqBAIJ"
124427a8da17SBarry Smith int MatSeqBAIJSetColumnIndices_SeqBAIJ(Mat mat,int *indices)
124527a8da17SBarry Smith {
124627a8da17SBarry Smith   Mat_SeqBAIJ *baij = (Mat_SeqBAIJ *)mat->data;
124727a8da17SBarry Smith   int         i,nz,n;
124827a8da17SBarry Smith 
124927a8da17SBarry Smith   PetscFunctionBegin;
125027a8da17SBarry Smith   nz = baij->maxnz;
125127a8da17SBarry Smith   n  = baij->n;
125227a8da17SBarry Smith   for (i=0; i<nz; i++) {
125327a8da17SBarry Smith     baij->j[i] = indices[i];
125427a8da17SBarry Smith   }
125527a8da17SBarry Smith   baij->nz = nz;
125627a8da17SBarry Smith   for ( i=0; i<n; i++ ) {
125727a8da17SBarry Smith     baij->ilen[i] = baij->imax[i];
125827a8da17SBarry Smith   }
125927a8da17SBarry Smith 
126027a8da17SBarry Smith   PetscFunctionReturn(0);
126127a8da17SBarry Smith }
1262fb2e594dSBarry Smith EXTERN_C_END
126327a8da17SBarry Smith 
126427a8da17SBarry Smith #undef __FUNC__
126527a8da17SBarry Smith #define __FUNC__ "MatSeqBAIJSetColumnIndices"
126627a8da17SBarry Smith /*@
126727a8da17SBarry Smith     MatSeqBAIJSetColumnIndices - Set the column indices for all the rows
126827a8da17SBarry Smith        in the matrix.
126927a8da17SBarry Smith 
127027a8da17SBarry Smith   Input Parameters:
127127a8da17SBarry Smith +  mat - the SeqBAIJ matrix
127227a8da17SBarry Smith -  indices - the column indices
127327a8da17SBarry Smith 
127415091d37SBarry Smith   Level: advanced
127515091d37SBarry Smith 
127627a8da17SBarry Smith   Notes:
127727a8da17SBarry Smith     This can be called if you have precomputed the nonzero structure of the
127827a8da17SBarry Smith   matrix and want to provide it to the matrix object to improve the performance
127927a8da17SBarry Smith   of the MatSetValues() operation.
128027a8da17SBarry Smith 
128127a8da17SBarry Smith     You MUST have set the correct numbers of nonzeros per row in the call to
128227a8da17SBarry Smith   MatCreateSeqBAIJ().
128327a8da17SBarry Smith 
128427a8da17SBarry Smith     MUST be called before any calls to MatSetValues();
128527a8da17SBarry Smith 
128627a8da17SBarry Smith @*/
128727a8da17SBarry Smith int MatSeqBAIJSetColumnIndices(Mat mat,int *indices)
128827a8da17SBarry Smith {
128927a8da17SBarry Smith   int ierr,(*f)(Mat,int *);
129027a8da17SBarry Smith 
129127a8da17SBarry Smith   PetscFunctionBegin;
129227a8da17SBarry Smith   PetscValidHeaderSpecific(mat,MAT_COOKIE);
1293549d3d68SSatish Balay   ierr = PetscObjectQueryFunction((PetscObject)mat,"MatSeqBAIJSetColumnIndices_C",(void **)&f);CHKERRQ(ierr);
129427a8da17SBarry Smith   if (f) {
129527a8da17SBarry Smith     ierr = (*f)(mat,indices);CHKERRQ(ierr);
129627a8da17SBarry Smith   } else {
129727a8da17SBarry Smith     SETERRQ(1,1,"Wrong type of matrix to set column indices");
129827a8da17SBarry Smith   }
129927a8da17SBarry Smith   PetscFunctionReturn(0);
130027a8da17SBarry Smith }
130127a8da17SBarry Smith 
13022593348eSBarry Smith /* -------------------------------------------------------------------*/
1303cc2dc46cSBarry Smith static struct _MatOps MatOps_Values = {MatSetValues_SeqBAIJ,
1304cc2dc46cSBarry Smith        MatGetRow_SeqBAIJ,
1305cc2dc46cSBarry Smith        MatRestoreRow_SeqBAIJ,
1306cc2dc46cSBarry Smith        MatMult_SeqBAIJ_N,
1307cc2dc46cSBarry Smith        MatMultAdd_SeqBAIJ_N,
1308cc2dc46cSBarry Smith        MatMultTrans_SeqBAIJ,
1309cc2dc46cSBarry Smith        MatMultTransAdd_SeqBAIJ,
1310cc2dc46cSBarry Smith        MatSolve_SeqBAIJ_N,
1311cc2dc46cSBarry Smith        0,
1312cc2dc46cSBarry Smith        0,
1313cc2dc46cSBarry Smith        0,
1314cc2dc46cSBarry Smith        MatLUFactor_SeqBAIJ,
1315cc2dc46cSBarry Smith        0,
1316b6490206SBarry Smith        0,
1317f2501298SSatish Balay        MatTranspose_SeqBAIJ,
1318cc2dc46cSBarry Smith        MatGetInfo_SeqBAIJ,
1319cc2dc46cSBarry Smith        MatEqual_SeqBAIJ,
1320cc2dc46cSBarry Smith        MatGetDiagonal_SeqBAIJ,
1321cc2dc46cSBarry Smith        MatDiagonalScale_SeqBAIJ,
1322cc2dc46cSBarry Smith        MatNorm_SeqBAIJ,
1323b6490206SBarry Smith        0,
1324cc2dc46cSBarry Smith        MatAssemblyEnd_SeqBAIJ,
1325cc2dc46cSBarry Smith        0,
1326cc2dc46cSBarry Smith        MatSetOption_SeqBAIJ,
1327cc2dc46cSBarry Smith        MatZeroEntries_SeqBAIJ,
1328cc2dc46cSBarry Smith        MatZeroRows_SeqBAIJ,
1329cc2dc46cSBarry Smith        MatLUFactorSymbolic_SeqBAIJ,
1330cc2dc46cSBarry Smith        MatLUFactorNumeric_SeqBAIJ_N,
1331cc2dc46cSBarry Smith        0,
1332cc2dc46cSBarry Smith        0,
1333cc2dc46cSBarry Smith        MatGetSize_SeqBAIJ,
1334cc2dc46cSBarry Smith        MatGetSize_SeqBAIJ,
1335cc2dc46cSBarry Smith        MatGetOwnershipRange_SeqBAIJ,
1336cc2dc46cSBarry Smith        MatILUFactorSymbolic_SeqBAIJ,
1337cc2dc46cSBarry Smith        0,
1338cc2dc46cSBarry Smith        0,
1339cc2dc46cSBarry Smith        0,
13402e8a6d31SBarry Smith        MatDuplicate_SeqBAIJ,
1341cc2dc46cSBarry Smith        0,
1342cc2dc46cSBarry Smith        0,
1343cc2dc46cSBarry Smith        MatILUFactor_SeqBAIJ,
1344cc2dc46cSBarry Smith        0,
1345cc2dc46cSBarry Smith        0,
1346cc2dc46cSBarry Smith        MatGetSubMatrices_SeqBAIJ,
1347cc2dc46cSBarry Smith        MatIncreaseOverlap_SeqBAIJ,
1348cc2dc46cSBarry Smith        MatGetValues_SeqBAIJ,
1349cc2dc46cSBarry Smith        0,
1350cc2dc46cSBarry Smith        MatPrintHelp_SeqBAIJ,
1351cc2dc46cSBarry Smith        MatScale_SeqBAIJ,
1352cc2dc46cSBarry Smith        0,
1353cc2dc46cSBarry Smith        0,
1354cc2dc46cSBarry Smith        0,
1355cc2dc46cSBarry Smith        MatGetBlockSize_SeqBAIJ,
13563b2fbd54SBarry Smith        MatGetRowIJ_SeqBAIJ,
135792c4ed94SBarry Smith        MatRestoreRowIJ_SeqBAIJ,
1358cc2dc46cSBarry Smith        0,
1359cc2dc46cSBarry Smith        0,
1360cc2dc46cSBarry Smith        0,
1361cc2dc46cSBarry Smith        0,
1362cc2dc46cSBarry Smith        0,
1363cc2dc46cSBarry Smith        0,
1364d3825aa8SBarry Smith        MatSetValuesBlocked_SeqBAIJ,
1365cc2dc46cSBarry Smith        MatGetSubMatrix_SeqBAIJ,
1366cc2dc46cSBarry Smith        0,
1367cc2dc46cSBarry Smith        0,
1368cc2dc46cSBarry Smith        MatGetMaps_Petsc};
13692593348eSBarry Smith 
13703e90b805SBarry Smith EXTERN_C_BEGIN
13713e90b805SBarry Smith #undef __FUNC__
13723e90b805SBarry Smith #define __FUNC__ "MatStoreValues_SeqBAIJ"
13733e90b805SBarry Smith int MatStoreValues_SeqBAIJ(Mat mat)
13743e90b805SBarry Smith {
13753e90b805SBarry Smith   Mat_SeqBAIJ *aij = (Mat_SeqBAIJ *)mat->data;
13763e90b805SBarry Smith   int         nz = aij->i[aij->m]*aij->bs*aij->bs2;
1377d132466eSBarry Smith   int         ierr;
13783e90b805SBarry Smith 
13793e90b805SBarry Smith   PetscFunctionBegin;
13803e90b805SBarry Smith   if (aij->nonew != 1) {
13813e90b805SBarry Smith     SETERRQ(1,1,"Must call MatSetOption(A,MAT_NO_NEW_NONZERO_LOCATIONS);first");
13823e90b805SBarry Smith   }
13833e90b805SBarry Smith 
13843e90b805SBarry Smith   /* allocate space for values if not already there */
13853e90b805SBarry Smith   if (!aij->saved_values) {
13863e90b805SBarry Smith     aij->saved_values = (Scalar *) PetscMalloc(nz*sizeof(Scalar));CHKPTRQ(aij->saved_values);
13873e90b805SBarry Smith   }
13883e90b805SBarry Smith 
13893e90b805SBarry Smith   /* copy values over */
1390d132466eSBarry Smith   ierr = PetscMemcpy(aij->saved_values,aij->a,nz*sizeof(Scalar));CHKERRQ(ierr);
13913e90b805SBarry Smith   PetscFunctionReturn(0);
13923e90b805SBarry Smith }
13933e90b805SBarry Smith EXTERN_C_END
13943e90b805SBarry Smith 
13953e90b805SBarry Smith EXTERN_C_BEGIN
13963e90b805SBarry Smith #undef __FUNC__
139732e87ba3SBarry Smith #define __FUNC__ "MatRetrieveValues_SeqBAIJ"
139832e87ba3SBarry Smith int MatRetrieveValues_SeqBAIJ(Mat mat)
13993e90b805SBarry Smith {
14003e90b805SBarry Smith   Mat_SeqBAIJ *aij = (Mat_SeqBAIJ *)mat->data;
1401549d3d68SSatish Balay   int         nz = aij->i[aij->m]*aij->bs*aij->bs2,ierr;
14023e90b805SBarry Smith 
14033e90b805SBarry Smith   PetscFunctionBegin;
14043e90b805SBarry Smith   if (aij->nonew != 1) {
14053e90b805SBarry Smith     SETERRQ(1,1,"Must call MatSetOption(A,MAT_NO_NEW_NONZERO_LOCATIONS);first");
14063e90b805SBarry Smith   }
14073e90b805SBarry Smith   if (!aij->saved_values) {
14083e90b805SBarry Smith     SETERRQ(1,1,"Must call MatStoreValues(A);first");
14093e90b805SBarry Smith   }
14103e90b805SBarry Smith 
14113e90b805SBarry Smith   /* copy values over */
1412549d3d68SSatish Balay   ierr = PetscMemcpy(aij->a, aij->saved_values,nz*sizeof(Scalar));CHKERRQ(ierr);
14133e90b805SBarry Smith   PetscFunctionReturn(0);
14143e90b805SBarry Smith }
14153e90b805SBarry Smith EXTERN_C_END
14163e90b805SBarry Smith 
14175615d1e5SSatish Balay #undef __FUNC__
14185615d1e5SSatish Balay #define __FUNC__ "MatCreateSeqBAIJ"
14192593348eSBarry Smith /*@C
142044cd7ae7SLois Curfman McInnes    MatCreateSeqBAIJ - Creates a sparse matrix in block AIJ (block
142144cd7ae7SLois Curfman McInnes    compressed row) format.  For good matrix assembly performance the
142244cd7ae7SLois Curfman McInnes    user should preallocate the matrix storage by setting the parameter nz
14237fc3c18eSBarry Smith    (or the array nnz).  By setting these parameters accurately, performance
14242bd5e0b2SLois Curfman McInnes    during matrix assembly can be increased by more than a factor of 50.
14252593348eSBarry Smith 
1426db81eaa0SLois Curfman McInnes    Collective on MPI_Comm
1427db81eaa0SLois Curfman McInnes 
14282593348eSBarry Smith    Input Parameters:
1429db81eaa0SLois Curfman McInnes +  comm - MPI communicator, set to PETSC_COMM_SELF
1430b6490206SBarry Smith .  bs - size of block
14312593348eSBarry Smith .  m - number of rows
14322593348eSBarry Smith .  n - number of columns
1433b6490206SBarry Smith .  nz - number of block nonzeros per block row (same for all rows)
14347fc3c18eSBarry Smith -  nnz - array containing the number of block nonzeros in the various block rows
14352bd5e0b2SLois Curfman McInnes          (possibly different for each block row) or PETSC_NULL
14362593348eSBarry Smith 
14372593348eSBarry Smith    Output Parameter:
14382593348eSBarry Smith .  A - the matrix
14392593348eSBarry Smith 
14400513a670SBarry Smith    Options Database Keys:
1441db81eaa0SLois Curfman McInnes .   -mat_no_unroll - uses code that does not unroll the loops in the
1442db81eaa0SLois Curfman McInnes                      block calculations (much slower)
1443db81eaa0SLois Curfman McInnes .    -mat_block_size - size of the blocks to use
14440513a670SBarry Smith 
144515091d37SBarry Smith    Level: intermediate
144615091d37SBarry Smith 
14472593348eSBarry Smith    Notes:
144844cd7ae7SLois Curfman McInnes    The block AIJ format is fully compatible with standard Fortran 77
14492593348eSBarry Smith    storage.  That is, the stored row and column indices can begin at
145044cd7ae7SLois Curfman McInnes    either one (as in Fortran) or zero.  See the users' manual for details.
14512593348eSBarry Smith 
14522593348eSBarry Smith    Specify the preallocated storage with either nz or nnz (not both).
14532593348eSBarry Smith    Set nz=PETSC_DEFAULT and nnz=PETSC_NULL for PETSc to control dynamic memory
14542593348eSBarry Smith    allocation.  For additional details, see the users manual chapter on
14556da5968aSLois Curfman McInnes    matrices.
14562593348eSBarry Smith 
1457db81eaa0SLois Curfman McInnes .seealso: MatCreate(), MatCreateSeqAIJ(), MatSetValues(), MatCreateMPIBAIJ()
14582593348eSBarry Smith @*/
1459b6490206SBarry Smith int MatCreateSeqBAIJ(MPI_Comm comm,int bs,int m,int n,int nz,int *nnz, Mat *A)
14602593348eSBarry Smith {
14612593348eSBarry Smith   Mat         B;
1462b6490206SBarry Smith   Mat_SeqBAIJ *b;
1463*f1af5d2fSBarry Smith   int         i,len,ierr,mbs,nbs,bs2,size;
1464*f1af5d2fSBarry Smith   PetscTruth  flg;
14653b2fbd54SBarry Smith 
14663a40ed3dSBarry Smith   PetscFunctionBegin;
1467d132466eSBarry Smith   ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr);
1468a8c6a408SBarry Smith   if (size > 1) SETERRQ(PETSC_ERR_ARG_WRONG,0,"Comm must be of size 1");
1469b6490206SBarry Smith 
1470962fb4a0SBarry Smith   ierr = OptionsGetInt(PETSC_NULL,"-mat_block_size",&bs,PETSC_NULL);CHKERRQ(ierr);
1471302e33e3SBarry Smith   mbs  = m/bs;
1472302e33e3SBarry Smith   nbs  = n/bs;
1473302e33e3SBarry Smith   bs2  = bs*bs;
14740513a670SBarry Smith 
14753a40ed3dSBarry Smith   if (mbs*bs!=m || nbs*bs!=n) {
1476a8c6a408SBarry Smith     SETERRQ(PETSC_ERR_ARG_SIZ,0,"Number rows, cols must be divisible by blocksize");
14773a40ed3dSBarry Smith   }
14782593348eSBarry Smith 
1479b73539f3SBarry Smith   if (nz < -2) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,0,"nz cannot be less than -2: value %d",nz);
1480b73539f3SBarry Smith   if (nnz) {
1481faf3f1fcSBarry Smith     for (i=0; i<mbs; i++) {
1482b73539f3SBarry 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]);
1483b73539f3SBarry Smith     }
1484b73539f3SBarry Smith   }
1485b73539f3SBarry Smith 
14862593348eSBarry Smith   *A = 0;
14873f1db9ecSBarry Smith   PetscHeaderCreate(B,_p_Mat,struct _MatOps,MAT_COOKIE,MATSEQBAIJ,"Mat",comm,MatDestroy,MatView);
14882593348eSBarry Smith   PLogObjectCreate(B);
1489b6490206SBarry Smith   B->data = (void *) (b = PetscNew(Mat_SeqBAIJ));CHKPTRQ(b);
1490549d3d68SSatish Balay   ierr    = PetscMemzero(b,sizeof(Mat_SeqBAIJ));CHKERRQ(ierr);
1491549d3d68SSatish Balay   ierr    = PetscMemcpy(B->ops,&MatOps_Values,sizeof(struct _MatOps));CHKERRQ(ierr);
14921a6a6d98SBarry Smith   ierr    = OptionsHasName(PETSC_NULL,"-mat_no_unroll",&flg);CHKERRQ(ierr);
14931a6a6d98SBarry Smith   if (!flg) {
14947fc0212eSBarry Smith     switch (bs) {
14957fc0212eSBarry Smith     case 1:
1496f830108cSBarry Smith       B->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_1;
1497f830108cSBarry Smith       B->ops->solve           = MatSolve_SeqBAIJ_1;
1498*f1af5d2fSBarry Smith       B->ops->solvetrans      = MatSolveTrans_SeqBAIJ_1;
1499f830108cSBarry Smith       B->ops->mult            = MatMult_SeqBAIJ_1;
1500f830108cSBarry Smith       B->ops->multadd         = MatMultAdd_SeqBAIJ_1;
15017fc0212eSBarry Smith       break;
15024eeb42bcSBarry Smith     case 2:
1503f830108cSBarry Smith       B->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_2;
1504f830108cSBarry Smith       B->ops->solve           = MatSolve_SeqBAIJ_2;
1505*f1af5d2fSBarry Smith       B->ops->solvetrans      = MatSolveTrans_SeqBAIJ_2;
1506f830108cSBarry Smith       B->ops->mult            = MatMult_SeqBAIJ_2;
1507f830108cSBarry Smith       B->ops->multadd         = MatMultAdd_SeqBAIJ_2;
15086d84be18SBarry Smith       break;
1509f327dd97SBarry Smith     case 3:
1510f830108cSBarry Smith       B->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_3;
1511f830108cSBarry Smith       B->ops->solve           = MatSolve_SeqBAIJ_3;
1512*f1af5d2fSBarry Smith       B->ops->solvetrans      = MatSolveTrans_SeqBAIJ_3;
1513f830108cSBarry Smith       B->ops->mult            = MatMult_SeqBAIJ_3;
1514f830108cSBarry Smith       B->ops->multadd         = MatMultAdd_SeqBAIJ_3;
15154eeb42bcSBarry Smith       break;
15166d84be18SBarry Smith     case 4:
1517f830108cSBarry Smith       B->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_4;
1518f830108cSBarry Smith       B->ops->solve           = MatSolve_SeqBAIJ_4;
1519*f1af5d2fSBarry Smith       B->ops->solvetrans      = MatSolveTrans_SeqBAIJ_4;
1520f830108cSBarry Smith       B->ops->mult            = MatMult_SeqBAIJ_4;
1521f830108cSBarry Smith       B->ops->multadd         = MatMultAdd_SeqBAIJ_4;
15226d84be18SBarry Smith       break;
15236d84be18SBarry Smith     case 5:
1524f830108cSBarry Smith       B->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_5;
1525f830108cSBarry Smith       B->ops->solve           = MatSolve_SeqBAIJ_5;
1526*f1af5d2fSBarry Smith       B->ops->solvetrans      = MatSolveTrans_SeqBAIJ_5;
1527f830108cSBarry Smith       B->ops->mult            = MatMult_SeqBAIJ_5;
1528f830108cSBarry Smith       B->ops->multadd         = MatMultAdd_SeqBAIJ_5;
15296d84be18SBarry Smith       break;
153015091d37SBarry Smith     case 6:
153115091d37SBarry Smith       B->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_6;
153215091d37SBarry Smith       B->ops->solve           = MatSolve_SeqBAIJ_6;
1533*f1af5d2fSBarry Smith       B->ops->solvetrans      = MatSolveTrans_SeqBAIJ_6;
153415091d37SBarry Smith       B->ops->mult            = MatMult_SeqBAIJ_6;
153515091d37SBarry Smith       B->ops->multadd         = MatMultAdd_SeqBAIJ_6;
153615091d37SBarry Smith       break;
153748e9ddb2SSatish Balay     case 7:
1538f830108cSBarry Smith       B->ops->mult            = MatMult_SeqBAIJ_7;
1539f830108cSBarry Smith       B->ops->solve           = MatSolve_SeqBAIJ_7;
1540*f1af5d2fSBarry Smith       B->ops->solvetrans      = MatSolveTrans_SeqBAIJ_7;
1541f830108cSBarry Smith       B->ops->multadd         = MatMultAdd_SeqBAIJ_7;
154248e9ddb2SSatish Balay       break;
15437fc0212eSBarry Smith     }
15441a6a6d98SBarry Smith   }
1545e1311b90SBarry Smith   B->ops->destroy     = MatDestroy_SeqBAIJ;
1546e1311b90SBarry Smith   B->ops->view        = MatView_SeqBAIJ;
15472593348eSBarry Smith   B->factor           = 0;
15482593348eSBarry Smith   B->lupivotthreshold = 1.0;
154990f02eecSBarry Smith   B->mapping          = 0;
15502593348eSBarry Smith   b->row              = 0;
15512593348eSBarry Smith   b->col              = 0;
1552e51c0b9cSSatish Balay   b->icol             = 0;
15532593348eSBarry Smith   b->reallocs         = 0;
15543e90b805SBarry Smith   b->saved_values     = 0;
15552593348eSBarry Smith 
155644cd7ae7SLois Curfman McInnes   b->m       = m; B->m = m; B->M = m;
155744cd7ae7SLois Curfman McInnes   b->n       = n; B->n = n; B->N = n;
1558a5ae1ecdSBarry Smith 
15597413bad6SBarry Smith   ierr = MapCreateMPI(comm,m,m,&B->rmap);CHKERRQ(ierr);
15607413bad6SBarry Smith   ierr = MapCreateMPI(comm,n,n,&B->cmap);CHKERRQ(ierr);
1561a5ae1ecdSBarry Smith 
1562b6490206SBarry Smith   b->mbs     = mbs;
1563f2501298SSatish Balay   b->nbs     = nbs;
1564b6490206SBarry Smith   b->imax    = (int *) PetscMalloc( (mbs+1)*sizeof(int) );CHKPTRQ(b->imax);
15652593348eSBarry Smith   if (nnz == PETSC_NULL) {
1566119a934aSSatish Balay     if (nz == PETSC_DEFAULT) nz = 5;
15672593348eSBarry Smith     else if (nz <= 0)        nz = 1;
1568b6490206SBarry Smith     for ( i=0; i<mbs; i++ ) b->imax[i] = nz;
1569b6490206SBarry Smith     nz = nz*mbs;
15703a40ed3dSBarry Smith   } else {
15712593348eSBarry Smith     nz = 0;
1572b6490206SBarry Smith     for ( i=0; i<mbs; i++ ) {b->imax[i] = nnz[i]; nz += nnz[i];}
15732593348eSBarry Smith   }
15742593348eSBarry Smith 
15752593348eSBarry Smith   /* allocate the matrix space */
15763f1db9ecSBarry Smith   len   = nz*sizeof(int) + nz*bs2*sizeof(MatScalar) + (b->m+1)*sizeof(int);
15773f1db9ecSBarry Smith   b->a  = (MatScalar *) PetscMalloc( len );CHKPTRQ(b->a);
1578549d3d68SSatish Balay   ierr = PetscMemzero(b->a,nz*bs2*sizeof(MatScalar));CHKERRQ(ierr);
15797e67e3f9SSatish Balay   b->j  = (int *) (b->a + nz*bs2);
1580549d3d68SSatish Balay   ierr = PetscMemzero(b->j,nz*sizeof(int));CHKERRQ(ierr);
15812593348eSBarry Smith   b->i  = b->j + nz;
15822593348eSBarry Smith   b->singlemalloc = 1;
15832593348eSBarry Smith 
1584de6a44a3SBarry Smith   b->i[0] = 0;
1585b6490206SBarry Smith   for (i=1; i<mbs+1; i++) {
15862593348eSBarry Smith     b->i[i] = b->i[i-1] + b->imax[i-1];
15872593348eSBarry Smith   }
15882593348eSBarry Smith 
1589b6490206SBarry Smith   /* b->ilen will count nonzeros in each block row so far. */
1590b6490206SBarry Smith   b->ilen = (int *) PetscMalloc((mbs+1)*sizeof(int));
1591f09e8eb9SSatish Balay   PLogObjectMemory(B,len+2*(mbs+1)*sizeof(int)+sizeof(struct _p_Mat)+sizeof(Mat_SeqBAIJ));
1592b6490206SBarry Smith   for ( i=0; i<mbs; i++ ) { b->ilen[i] = 0;}
15932593348eSBarry Smith 
1594b6490206SBarry Smith   b->bs               = bs;
15959df24120SSatish Balay   b->bs2              = bs2;
1596b6490206SBarry Smith   b->mbs              = mbs;
15972593348eSBarry Smith   b->nz               = 0;
159818e7b8e4SLois Curfman McInnes   b->maxnz            = nz*bs2;
15992593348eSBarry Smith   b->sorted           = 0;
16002593348eSBarry Smith   b->roworiented      = 1;
16012593348eSBarry Smith   b->nonew            = 0;
16022593348eSBarry Smith   b->diag             = 0;
16032593348eSBarry Smith   b->solve_work       = 0;
1604de6a44a3SBarry Smith   b->mult_work        = 0;
16052593348eSBarry Smith   b->spptr            = 0;
16064e220ebcSLois Curfman McInnes   B->info.nz_unneeded = (double)b->maxnz;
16074e220ebcSLois Curfman McInnes 
16082593348eSBarry Smith   *A = B;
16092593348eSBarry Smith   ierr = OptionsHasName(PETSC_NULL,"-help", &flg);CHKERRQ(ierr);
16102593348eSBarry Smith   if (flg) {ierr = MatPrintHelp(B);CHKERRQ(ierr); }
161127a8da17SBarry Smith 
1612*f1af5d2fSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatStoreValues_C",
16133e90b805SBarry Smith                                      "MatStoreValues_SeqBAIJ",
16143e90b805SBarry Smith                                      (void*)MatStoreValues_SeqBAIJ);CHKERRQ(ierr);
1615*f1af5d2fSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatRetrieveValues_C",
16163e90b805SBarry Smith                                      "MatRetrieveValues_SeqBAIJ",
16173e90b805SBarry Smith                                      (void*)MatRetrieveValues_SeqBAIJ);CHKERRQ(ierr);
1618*f1af5d2fSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatSeqBAIJSetColumnIndices_C",
161927a8da17SBarry Smith                                      "MatSeqBAIJSetColumnIndices_SeqBAIJ",
162027a8da17SBarry Smith                                      (void*)MatSeqBAIJSetColumnIndices_SeqBAIJ);CHKERRQ(ierr);
16213a40ed3dSBarry Smith   PetscFunctionReturn(0);
16222593348eSBarry Smith }
16232593348eSBarry Smith 
16245615d1e5SSatish Balay #undef __FUNC__
16252e8a6d31SBarry Smith #define __FUNC__ "MatDuplicate_SeqBAIJ"
16262e8a6d31SBarry Smith int MatDuplicate_SeqBAIJ(Mat A,MatDuplicateOption cpvalues,Mat *B)
16272593348eSBarry Smith {
16282593348eSBarry Smith   Mat         C;
1629b6490206SBarry Smith   Mat_SeqBAIJ *c,*a = (Mat_SeqBAIJ *) A->data;
163027a8da17SBarry Smith   int         i,len, mbs = a->mbs,nz = a->nz,bs2 =a->bs2,ierr;
1631de6a44a3SBarry Smith 
16323a40ed3dSBarry Smith   PetscFunctionBegin;
1633a8c6a408SBarry Smith   if (a->i[mbs] != nz) SETERRQ(PETSC_ERR_PLIB,0,"Corrupt matrix");
16342593348eSBarry Smith 
16352593348eSBarry Smith   *B = 0;
16363f1db9ecSBarry Smith   PetscHeaderCreate(C,_p_Mat,struct _MatOps,MAT_COOKIE,MATSEQBAIJ,"Mat",A->comm,MatDestroy,MatView);
16372593348eSBarry Smith   PLogObjectCreate(C);
1638b6490206SBarry Smith   C->data         = (void *) (c = PetscNew(Mat_SeqBAIJ));CHKPTRQ(c);
1639549d3d68SSatish Balay   ierr            = PetscMemcpy(C->ops,A->ops,sizeof(struct _MatOps));CHKERRQ(ierr);
1640e1311b90SBarry Smith   C->ops->destroy = MatDestroy_SeqBAIJ;
1641e1311b90SBarry Smith   C->ops->view    = MatView_SeqBAIJ;
16422593348eSBarry Smith   C->factor       = A->factor;
16432593348eSBarry Smith   c->row          = 0;
16442593348eSBarry Smith   c->col          = 0;
1645cac97260SSatish Balay   c->icol         = 0;
164632e87ba3SBarry Smith   c->saved_values = 0;
16472593348eSBarry Smith   C->assembled    = PETSC_TRUE;
16482593348eSBarry Smith 
164944cd7ae7SLois Curfman McInnes   c->m = C->m   = a->m;
165044cd7ae7SLois Curfman McInnes   c->n = C->n   = a->n;
165144cd7ae7SLois Curfman McInnes   C->M          = a->m;
165244cd7ae7SLois Curfman McInnes   C->N          = a->n;
165344cd7ae7SLois Curfman McInnes 
1654b6490206SBarry Smith   c->bs         = a->bs;
16559df24120SSatish Balay   c->bs2        = a->bs2;
1656b6490206SBarry Smith   c->mbs        = a->mbs;
1657b6490206SBarry Smith   c->nbs        = a->nbs;
16582593348eSBarry Smith 
1659b6490206SBarry Smith   c->imax       = (int *) PetscMalloc((mbs+1)*sizeof(int));CHKPTRQ(c->imax);
1660b6490206SBarry Smith   c->ilen       = (int *) PetscMalloc((mbs+1)*sizeof(int));CHKPTRQ(c->ilen);
1661b6490206SBarry Smith   for ( i=0; i<mbs; i++ ) {
16622593348eSBarry Smith     c->imax[i] = a->imax[i];
16632593348eSBarry Smith     c->ilen[i] = a->ilen[i];
16642593348eSBarry Smith   }
16652593348eSBarry Smith 
16662593348eSBarry Smith   /* allocate the matrix space */
16672593348eSBarry Smith   c->singlemalloc = 1;
16683f1db9ecSBarry Smith   len  = (mbs+1)*sizeof(int) + nz*(bs2*sizeof(MatScalar) + sizeof(int));
16693f1db9ecSBarry Smith   c->a = (MatScalar *) PetscMalloc( len );CHKPTRQ(c->a);
16707e67e3f9SSatish Balay   c->j = (int *) (c->a + nz*bs2);
1671de6a44a3SBarry Smith   c->i = c->j + nz;
1672549d3d68SSatish Balay   ierr = PetscMemcpy(c->i,a->i,(mbs+1)*sizeof(int));CHKERRQ(ierr);
1673b6490206SBarry Smith   if (mbs > 0) {
1674549d3d68SSatish Balay     ierr = PetscMemcpy(c->j,a->j,nz*sizeof(int));CHKERRQ(ierr);
16752e8a6d31SBarry Smith     if (cpvalues == MAT_COPY_VALUES) {
1676549d3d68SSatish Balay       ierr = PetscMemcpy(c->a,a->a,bs2*nz*sizeof(MatScalar));CHKERRQ(ierr);
16772e8a6d31SBarry Smith     } else {
1678549d3d68SSatish Balay       ierr = PetscMemzero(c->a,bs2*nz*sizeof(MatScalar));CHKERRQ(ierr);
16792593348eSBarry Smith     }
16802593348eSBarry Smith   }
16812593348eSBarry Smith 
1682f09e8eb9SSatish Balay   PLogObjectMemory(C,len+2*(mbs+1)*sizeof(int)+sizeof(struct _p_Mat)+sizeof(Mat_SeqBAIJ));
16832593348eSBarry Smith   c->sorted      = a->sorted;
16842593348eSBarry Smith   c->roworiented = a->roworiented;
16852593348eSBarry Smith   c->nonew       = a->nonew;
16862593348eSBarry Smith 
16872593348eSBarry Smith   if (a->diag) {
1688b6490206SBarry Smith     c->diag = (int *) PetscMalloc( (mbs+1)*sizeof(int) );CHKPTRQ(c->diag);
1689b6490206SBarry Smith     PLogObjectMemory(C,(mbs+1)*sizeof(int));
1690b6490206SBarry Smith     for ( i=0; i<mbs; i++ ) {
16912593348eSBarry Smith       c->diag[i] = a->diag[i];
16922593348eSBarry Smith     }
169398305bb5SBarry Smith   } else c->diag        = 0;
16942593348eSBarry Smith   c->nz                 = a->nz;
16952593348eSBarry Smith   c->maxnz              = a->maxnz;
16962593348eSBarry Smith   c->solve_work         = 0;
16972593348eSBarry Smith   c->spptr              = 0;      /* Dangerous -I'm throwing away a->spptr */
16987fc0212eSBarry Smith   c->mult_work          = 0;
16992593348eSBarry Smith   *B = C;
17007b2a1423SBarry Smith   ierr = FListDuplicate(A->qlist,&C->qlist);CHKERRQ(ierr);
17013a40ed3dSBarry Smith   PetscFunctionReturn(0);
17022593348eSBarry Smith }
17032593348eSBarry Smith 
17045615d1e5SSatish Balay #undef __FUNC__
17055615d1e5SSatish Balay #define __FUNC__ "MatLoad_SeqBAIJ"
170619bcc07fSBarry Smith int MatLoad_SeqBAIJ(Viewer viewer,MatType type,Mat *A)
17072593348eSBarry Smith {
1708b6490206SBarry Smith   Mat_SeqBAIJ  *a;
17092593348eSBarry Smith   Mat          B;
1710*f1af5d2fSBarry Smith   int          i,nz,ierr,fd,header[4],size,*rowlengths=0,M,N,bs=1;
1711b6490206SBarry Smith   int          *mask,mbs,*jj,j,rowcount,nzcount,k,*browlengths,maskcount;
171235aab85fSBarry Smith   int          kmax,jcount,block,idx,point,nzcountb,extra_rows;
1713a7c10996SSatish Balay   int          *masked, nmask,tmp,bs2,ishift;
1714b6490206SBarry Smith   Scalar       *aa;
171519bcc07fSBarry Smith   MPI_Comm     comm = ((PetscObject) viewer)->comm;
17162593348eSBarry Smith 
17173a40ed3dSBarry Smith   PetscFunctionBegin;
1718*f1af5d2fSBarry Smith   ierr = OptionsGetInt(PETSC_NULL,"-matload_block_size",&bs,PETSC_NULL);CHKERRQ(ierr);
1719de6a44a3SBarry Smith   bs2  = bs*bs;
1720b6490206SBarry Smith 
1721d132466eSBarry Smith   ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr);
1722cc0fae11SBarry Smith   if (size > 1) SETERRQ(PETSC_ERR_ARG_WRONG,0,"view must have one processor");
172390ace30eSBarry Smith   ierr = ViewerBinaryGetDescriptor(viewer,&fd);CHKERRQ(ierr);
17240752156aSBarry Smith   ierr = PetscBinaryRead(fd,header,4,PETSC_INT);CHKERRQ(ierr);
1725a8c6a408SBarry Smith   if (header[0] != MAT_COOKIE) SETERRQ(PETSC_ERR_FILE_UNEXPECTED,0,"not Mat object");
17262593348eSBarry Smith   M = header[1]; N = header[2]; nz = header[3];
17272593348eSBarry Smith 
1728d64ed03dSBarry Smith   if (header[3] < 0) {
1729a8c6a408SBarry Smith     SETERRQ(PETSC_ERR_FILE_UNEXPECTED,1,"Matrix stored in special format, cannot load as SeqBAIJ");
1730d64ed03dSBarry Smith   }
1731d64ed03dSBarry Smith 
1732a8c6a408SBarry Smith   if (M != N) SETERRQ(PETSC_ERR_SUP,0,"Can only do square matrices");
173335aab85fSBarry Smith 
173435aab85fSBarry Smith   /*
173535aab85fSBarry Smith      This code adds extra rows to make sure the number of rows is
173635aab85fSBarry Smith     divisible by the blocksize
173735aab85fSBarry Smith   */
1738b6490206SBarry Smith   mbs        = M/bs;
173935aab85fSBarry Smith   extra_rows = bs - M + bs*(mbs);
174035aab85fSBarry Smith   if (extra_rows == bs) extra_rows = 0;
174135aab85fSBarry Smith   else                  mbs++;
174235aab85fSBarry Smith   if (extra_rows) {
1743537820f0SBarry Smith     PLogInfo(0,"MatLoad_SeqBAIJ:Padding loaded matrix to match blocksize\n");
174435aab85fSBarry Smith   }
1745b6490206SBarry Smith 
17462593348eSBarry Smith   /* read in row lengths */
174735aab85fSBarry Smith   rowlengths = (int*) PetscMalloc((M+extra_rows)*sizeof(int));CHKPTRQ(rowlengths);
17480752156aSBarry Smith   ierr = PetscBinaryRead(fd,rowlengths,M,PETSC_INT);CHKERRQ(ierr);
174935aab85fSBarry Smith   for ( i=0; i<extra_rows; i++ ) rowlengths[M+i] = 1;
17502593348eSBarry Smith 
1751b6490206SBarry Smith   /* read in column indices */
175235aab85fSBarry Smith   jj = (int*) PetscMalloc( (nz+extra_rows)*sizeof(int) );CHKPTRQ(jj);
17530752156aSBarry Smith   ierr = PetscBinaryRead(fd,jj,nz,PETSC_INT);CHKERRQ(ierr);
175435aab85fSBarry Smith   for ( i=0; i<extra_rows; i++ ) jj[nz+i] = M+i;
1755b6490206SBarry Smith 
1756b6490206SBarry Smith   /* loop over row lengths determining block row lengths */
1757b6490206SBarry Smith   browlengths = (int *) PetscMalloc(mbs*sizeof(int));CHKPTRQ(browlengths);
1758549d3d68SSatish Balay   ierr        = PetscMemzero(browlengths,mbs*sizeof(int));CHKERRQ(ierr);
175935aab85fSBarry Smith   mask        = (int *) PetscMalloc( 2*mbs*sizeof(int) );CHKPTRQ(mask);
1760549d3d68SSatish Balay   ierr        = PetscMemzero(mask,mbs*sizeof(int));CHKERRQ(ierr);
176135aab85fSBarry Smith   masked      = mask + mbs;
1762b6490206SBarry Smith   rowcount    = 0; nzcount = 0;
1763b6490206SBarry Smith   for ( i=0; i<mbs; i++ ) {
176435aab85fSBarry Smith     nmask = 0;
1765b6490206SBarry Smith     for ( j=0; j<bs; j++ ) {
1766b6490206SBarry Smith       kmax = rowlengths[rowcount];
1767b6490206SBarry Smith       for ( k=0; k<kmax; k++ ) {
176835aab85fSBarry Smith         tmp = jj[nzcount++]/bs;
176935aab85fSBarry Smith         if (!mask[tmp]) {masked[nmask++] = tmp; mask[tmp] = 1;}
1770b6490206SBarry Smith       }
1771b6490206SBarry Smith       rowcount++;
1772b6490206SBarry Smith     }
177335aab85fSBarry Smith     browlengths[i] += nmask;
177435aab85fSBarry Smith     /* zero out the mask elements we set */
177535aab85fSBarry Smith     for ( j=0; j<nmask; j++ ) mask[masked[j]] = 0;
1776b6490206SBarry Smith   }
1777b6490206SBarry Smith 
17782593348eSBarry Smith   /* create our matrix */
17793eee16b0SBarry Smith   ierr = MatCreateSeqBAIJ(comm,bs,M+extra_rows,N+extra_rows,0,browlengths,A);CHKERRQ(ierr);
17802593348eSBarry Smith   B = *A;
1781b6490206SBarry Smith   a = (Mat_SeqBAIJ *) B->data;
17822593348eSBarry Smith 
17832593348eSBarry Smith   /* set matrix "i" values */
1784de6a44a3SBarry Smith   a->i[0] = 0;
1785b6490206SBarry Smith   for ( i=1; i<= mbs; i++ ) {
1786b6490206SBarry Smith     a->i[i]      = a->i[i-1] + browlengths[i-1];
1787b6490206SBarry Smith     a->ilen[i-1] = browlengths[i-1];
17882593348eSBarry Smith   }
1789b6490206SBarry Smith   a->nz         = 0;
1790b6490206SBarry Smith   for ( i=0; i<mbs; i++ ) a->nz += browlengths[i];
17912593348eSBarry Smith 
1792b6490206SBarry Smith   /* read in nonzero values */
179335aab85fSBarry Smith   aa = (Scalar *) PetscMalloc((nz+extra_rows)*sizeof(Scalar));CHKPTRQ(aa);
17940752156aSBarry Smith   ierr = PetscBinaryRead(fd,aa,nz,PETSC_SCALAR);CHKERRQ(ierr);
179535aab85fSBarry Smith   for ( i=0; i<extra_rows; i++ ) aa[nz+i] = 1.0;
1796b6490206SBarry Smith 
1797b6490206SBarry Smith   /* set "a" and "j" values into matrix */
1798b6490206SBarry Smith   nzcount = 0; jcount = 0;
1799b6490206SBarry Smith   for ( i=0; i<mbs; i++ ) {
1800b6490206SBarry Smith     nzcountb = nzcount;
180135aab85fSBarry Smith     nmask    = 0;
1802b6490206SBarry Smith     for ( j=0; j<bs; j++ ) {
1803b6490206SBarry Smith       kmax = rowlengths[i*bs+j];
1804b6490206SBarry Smith       for ( k=0; k<kmax; k++ ) {
180535aab85fSBarry Smith         tmp = jj[nzcount++]/bs;
180635aab85fSBarry Smith 	if (!mask[tmp]) { masked[nmask++] = tmp; mask[tmp] = 1;}
1807b6490206SBarry Smith       }
1808b6490206SBarry Smith       rowcount++;
1809b6490206SBarry Smith     }
1810de6a44a3SBarry Smith     /* sort the masked values */
1811433994e6SBarry Smith     ierr = PetscSortInt(nmask,masked);CHKERRQ(ierr);
1812de6a44a3SBarry Smith 
1813b6490206SBarry Smith     /* set "j" values into matrix */
1814b6490206SBarry Smith     maskcount = 1;
181535aab85fSBarry Smith     for ( j=0; j<nmask; j++ ) {
181635aab85fSBarry Smith       a->j[jcount++]  = masked[j];
1817de6a44a3SBarry Smith       mask[masked[j]] = maskcount++;
1818b6490206SBarry Smith     }
1819b6490206SBarry Smith     /* set "a" values into matrix */
1820de6a44a3SBarry Smith     ishift = bs2*a->i[i];
1821b6490206SBarry Smith     for ( j=0; j<bs; j++ ) {
1822b6490206SBarry Smith       kmax = rowlengths[i*bs+j];
1823b6490206SBarry Smith       for ( k=0; k<kmax; k++ ) {
1824de6a44a3SBarry Smith         tmp       = jj[nzcountb]/bs ;
1825de6a44a3SBarry Smith         block     = mask[tmp] - 1;
1826de6a44a3SBarry Smith         point     = jj[nzcountb] - bs*tmp;
1827de6a44a3SBarry Smith         idx       = ishift + bs2*block + j + bs*point;
1828b6490206SBarry Smith         a->a[idx] = aa[nzcountb++];
1829b6490206SBarry Smith       }
1830b6490206SBarry Smith     }
183135aab85fSBarry Smith     /* zero out the mask elements we set */
183235aab85fSBarry Smith     for ( j=0; j<nmask; j++ ) mask[masked[j]] = 0;
1833b6490206SBarry Smith   }
1834a8c6a408SBarry Smith   if (jcount != a->nz) SETERRQ(PETSC_ERR_FILE_UNEXPECTED,0,"Bad binary matrix");
1835b6490206SBarry Smith 
1836606d414cSSatish Balay   ierr = PetscFree(rowlengths);CHKERRQ(ierr);
1837606d414cSSatish Balay   ierr = PetscFree(browlengths);CHKERRQ(ierr);
1838606d414cSSatish Balay   ierr = PetscFree(aa);CHKERRQ(ierr);
1839606d414cSSatish Balay   ierr = PetscFree(jj);CHKERRQ(ierr);
1840606d414cSSatish Balay   ierr = PetscFree(mask);CHKERRQ(ierr);
1841b6490206SBarry Smith 
1842b6490206SBarry Smith   B->assembled = PETSC_TRUE;
1843de6a44a3SBarry Smith 
18449c01be13SBarry Smith   ierr = MatView_Private(B);CHKERRQ(ierr);
18453a40ed3dSBarry Smith   PetscFunctionReturn(0);
18462593348eSBarry Smith }
18472593348eSBarry Smith 
18482593348eSBarry Smith 
18492593348eSBarry Smith 
1850