xref: /petsc/src/mat/impls/baij/seq/baij.c (revision 77ed534321f0a860738694ee6d0aa216f0623125)
1a5eb4965SSatish Balay #ifdef PETSC_RCS_HEADER
2*77ed5343SBarry Smith static char vcid[] = "$Id: baij.c,v 1.147 1998/10/28 16:05:51 bsmith Exp bsmith $";
32593348eSBarry Smith #endif
42593348eSBarry Smith 
52593348eSBarry Smith /*
6b6490206SBarry Smith     Defines the basic matrix operations for the BAIJ (compressed row)
72593348eSBarry Smith   matrix storage format.
82593348eSBarry Smith */
93369ce9aSBarry Smith #include "sys.h"
1070f55243SBarry Smith #include "src/mat/impls/baij/seq/baij.h"
111a6a6d98SBarry Smith #include "src/vec/vecimpl.h"
121a6a6d98SBarry Smith #include "src/inline/spops.h"
133b547af2SSatish Balay 
142d61bbb3SSatish Balay #define CHUNKSIZE  10
15de6a44a3SBarry Smith 
165615d1e5SSatish Balay #undef __FUNC__
175615d1e5SSatish Balay #define __FUNC__ "MatMarkDiag_SeqBAIJ"
18de6a44a3SBarry Smith int MatMarkDiag_SeqBAIJ(Mat A)
19de6a44a3SBarry Smith {
20de6a44a3SBarry Smith   Mat_SeqBAIJ *a = (Mat_SeqBAIJ *) A->data;
217fc0212eSBarry Smith   int         i,j, *diag, m = a->mbs;
22de6a44a3SBarry Smith 
233a40ed3dSBarry Smith   PetscFunctionBegin;
24de6a44a3SBarry Smith   diag = (int *) PetscMalloc( (m+1)*sizeof(int)); CHKPTRQ(diag);
25de6a44a3SBarry Smith   PLogObjectMemory(A,(m+1)*sizeof(int));
267fc0212eSBarry Smith   for ( i=0; i<m; i++ ) {
27ecc615b2SBarry Smith     diag[i] = a->i[i+1];
28de6a44a3SBarry Smith     for ( j=a->i[i]; j<a->i[i+1]; j++ ) {
29de6a44a3SBarry Smith       if (a->j[j] == i) {
30de6a44a3SBarry Smith         diag[i] = j;
31de6a44a3SBarry Smith         break;
32de6a44a3SBarry Smith       }
33de6a44a3SBarry Smith     }
34de6a44a3SBarry Smith   }
35de6a44a3SBarry Smith   a->diag = diag;
363a40ed3dSBarry Smith   PetscFunctionReturn(0);
37de6a44a3SBarry Smith }
382593348eSBarry Smith 
392593348eSBarry Smith 
403b2fbd54SBarry Smith extern int MatToSymmetricIJ_SeqAIJ(int,int*,int*,int,int,int**,int**);
413b2fbd54SBarry Smith 
425615d1e5SSatish Balay #undef __FUNC__
435615d1e5SSatish Balay #define __FUNC__ "MatGetRowIJ_SeqBAIJ"
443b2fbd54SBarry Smith static int MatGetRowIJ_SeqBAIJ(Mat A,int oshift,PetscTruth symmetric,int *nn,int **ia,int **ja,
453b2fbd54SBarry Smith                             PetscTruth *done)
463b2fbd54SBarry Smith {
473b2fbd54SBarry Smith   Mat_SeqBAIJ *a = (Mat_SeqBAIJ *) A->data;
483b2fbd54SBarry Smith   int         ierr, n = a->mbs,i;
493b2fbd54SBarry Smith 
503a40ed3dSBarry Smith   PetscFunctionBegin;
513b2fbd54SBarry Smith   *nn = n;
523a40ed3dSBarry Smith   if (!ia) PetscFunctionReturn(0);
533b2fbd54SBarry Smith   if (symmetric) {
543b2fbd54SBarry Smith     ierr = MatToSymmetricIJ_SeqAIJ(n,a->i,a->j,0,oshift,ia,ja);CHKERRQ(ierr);
553b2fbd54SBarry Smith   } else if (oshift == 1) {
563b2fbd54SBarry Smith     /* temporarily add 1 to i and j indices */
573b2fbd54SBarry Smith     int nz = a->i[n] + 1;
583b2fbd54SBarry Smith     for ( i=0; i<nz; i++ ) a->j[i]++;
593b2fbd54SBarry Smith     for ( i=0; i<n+1; i++ ) a->i[i]++;
603b2fbd54SBarry Smith     *ia = a->i; *ja = a->j;
613b2fbd54SBarry Smith   } else {
623b2fbd54SBarry Smith     *ia = a->i; *ja = a->j;
633b2fbd54SBarry Smith   }
643b2fbd54SBarry Smith 
653a40ed3dSBarry Smith   PetscFunctionReturn(0);
663b2fbd54SBarry Smith }
673b2fbd54SBarry Smith 
685615d1e5SSatish Balay #undef __FUNC__
69d4bb536fSBarry Smith #define __FUNC__ "MatRestoreRowIJ_SeqBAIJ"
703b2fbd54SBarry Smith static int MatRestoreRowIJ_SeqBAIJ(Mat A,int oshift,PetscTruth symmetric,int *nn,int **ia,int **ja,
713b2fbd54SBarry Smith                                 PetscTruth *done)
723b2fbd54SBarry Smith {
733b2fbd54SBarry Smith   Mat_SeqBAIJ *a = (Mat_SeqBAIJ *) A->data;
743b2fbd54SBarry Smith   int         i,n = a->mbs;
753b2fbd54SBarry Smith 
763a40ed3dSBarry Smith   PetscFunctionBegin;
773a40ed3dSBarry Smith   if (!ia) PetscFunctionReturn(0);
783b2fbd54SBarry Smith   if (symmetric) {
793b2fbd54SBarry Smith     PetscFree(*ia);
803b2fbd54SBarry Smith     PetscFree(*ja);
81af5da2bfSBarry Smith   } else if (oshift == 1) {
823b2fbd54SBarry Smith     int nz = a->i[n];
833b2fbd54SBarry Smith     for ( i=0; i<nz; i++ ) a->j[i]--;
843b2fbd54SBarry Smith     for ( i=0; i<n+1; i++ ) a->i[i]--;
853b2fbd54SBarry Smith   }
863a40ed3dSBarry Smith   PetscFunctionReturn(0);
873b2fbd54SBarry Smith }
883b2fbd54SBarry Smith 
892d61bbb3SSatish Balay #undef __FUNC__
902d61bbb3SSatish Balay #define __FUNC__ "MatGetBlockSize_SeqBAIJ"
912d61bbb3SSatish Balay int MatGetBlockSize_SeqBAIJ(Mat mat, int *bs)
922d61bbb3SSatish Balay {
932d61bbb3SSatish Balay   Mat_SeqBAIJ *baij = (Mat_SeqBAIJ *) mat->data;
942d61bbb3SSatish Balay 
952d61bbb3SSatish Balay   PetscFunctionBegin;
962d61bbb3SSatish Balay   *bs = baij->bs;
972d61bbb3SSatish Balay   PetscFunctionReturn(0);
982d61bbb3SSatish Balay }
992d61bbb3SSatish Balay 
1002d61bbb3SSatish Balay 
1012d61bbb3SSatish Balay #undef __FUNC__
1022d61bbb3SSatish Balay #define __FUNC__ "MatDestroy_SeqBAIJ"
103e1311b90SBarry Smith int MatDestroy_SeqBAIJ(Mat A)
1042d61bbb3SSatish Balay {
1052d61bbb3SSatish Balay   Mat_SeqBAIJ *a = (Mat_SeqBAIJ *) A->data;
106e51c0b9cSSatish Balay   int         ierr;
1072d61bbb3SSatish Balay 
10894d884c6SBarry Smith   if (--A->refct > 0) PetscFunctionReturn(0);
10994d884c6SBarry Smith 
11094d884c6SBarry Smith   if (A->mapping) {
11194d884c6SBarry Smith     ierr = ISLocalToGlobalMappingDestroy(A->mapping); CHKERRQ(ierr);
11294d884c6SBarry Smith   }
11394d884c6SBarry Smith   if (A->bmapping) {
11494d884c6SBarry Smith     ierr = ISLocalToGlobalMappingDestroy(A->bmapping); CHKERRQ(ierr);
11594d884c6SBarry Smith   }
11661b13de0SBarry Smith   if (A->rmap) {
11761b13de0SBarry Smith     ierr = MapDestroy(A->rmap);CHKERRQ(ierr);
11861b13de0SBarry Smith   }
11961b13de0SBarry Smith   if (A->cmap) {
12061b13de0SBarry Smith     ierr = MapDestroy(A->cmap);CHKERRQ(ierr);
12161b13de0SBarry Smith   }
1222d61bbb3SSatish Balay #if defined(USE_PETSC_LOG)
123e1311b90SBarry Smith   PLogObjectState((PetscObject) A,"Rows=%d, Cols=%d, NZ=%d",a->m,a->n,a->nz);
1242d61bbb3SSatish Balay #endif
1252d61bbb3SSatish Balay   PetscFree(a->a);
1262d61bbb3SSatish Balay   if (!a->singlemalloc) { PetscFree(a->i); PetscFree(a->j);}
1272d61bbb3SSatish Balay   if (a->diag) PetscFree(a->diag);
1282d61bbb3SSatish Balay   if (a->ilen) PetscFree(a->ilen);
1292d61bbb3SSatish Balay   if (a->imax) PetscFree(a->imax);
1302d61bbb3SSatish Balay   if (a->solve_work) PetscFree(a->solve_work);
1312d61bbb3SSatish Balay   if (a->mult_work) PetscFree(a->mult_work);
132e51c0b9cSSatish Balay   if (a->icol) {ierr = ISDestroy(a->icol);CHKERRQ(ierr);}
1332d61bbb3SSatish Balay   PetscFree(a);
1342d61bbb3SSatish Balay   PLogObjectDestroy(A);
1352d61bbb3SSatish Balay   PetscHeaderDestroy(A);
1362d61bbb3SSatish Balay   PetscFunctionReturn(0);
1372d61bbb3SSatish Balay }
1382d61bbb3SSatish Balay 
1392d61bbb3SSatish Balay #undef __FUNC__
1402d61bbb3SSatish Balay #define __FUNC__ "MatSetOption_SeqBAIJ"
1412d61bbb3SSatish Balay int MatSetOption_SeqBAIJ(Mat A,MatOption op)
1422d61bbb3SSatish Balay {
1432d61bbb3SSatish Balay   Mat_SeqBAIJ *a = (Mat_SeqBAIJ *) A->data;
1442d61bbb3SSatish Balay 
1452d61bbb3SSatish Balay   PetscFunctionBegin;
1462d61bbb3SSatish Balay   if      (op == MAT_ROW_ORIENTED)                 a->roworiented = 1;
1472d61bbb3SSatish Balay   else if (op == MAT_COLUMN_ORIENTED)              a->roworiented = 0;
1482d61bbb3SSatish Balay   else if (op == MAT_COLUMNS_SORTED)               a->sorted      = 1;
1492d61bbb3SSatish Balay   else if (op == MAT_COLUMNS_UNSORTED)             a->sorted      = 0;
1502d61bbb3SSatish Balay   else if (op == MAT_NO_NEW_NONZERO_LOCATIONS)     a->nonew       = 1;
1512d61bbb3SSatish Balay   else if (op == MAT_NEW_NONZERO_LOCATION_ERROR)   a->nonew       = -1;
1522d61bbb3SSatish Balay   else if (op == MAT_NEW_NONZERO_ALLOCATION_ERROR) a->nonew       = -2;
1532d61bbb3SSatish Balay   else if (op == MAT_YES_NEW_NONZERO_LOCATIONS)    a->nonew       = 0;
1542d61bbb3SSatish Balay   else if (op == MAT_ROWS_SORTED ||
1552d61bbb3SSatish Balay            op == MAT_ROWS_UNSORTED ||
1562d61bbb3SSatish Balay            op == MAT_SYMMETRIC ||
1572d61bbb3SSatish Balay            op == MAT_STRUCTURALLY_SYMMETRIC ||
1582d61bbb3SSatish Balay            op == MAT_YES_NEW_DIAGONALS ||
159b51ba29fSSatish Balay            op == MAT_IGNORE_OFF_PROC_ENTRIES ||
160b51ba29fSSatish Balay            op == MAT_USE_HASH_TABLE) {
161981c4779SBarry Smith     PLogInfo(A,"MatSetOption_SeqBAIJ:Option ignored\n");
1622d61bbb3SSatish Balay   } else if (op == MAT_NO_NEW_DIAGONALS) {
1632d61bbb3SSatish Balay     SETERRQ(PETSC_ERR_SUP,0,"MAT_NO_NEW_DIAGONALS");
1642d61bbb3SSatish Balay   } else {
1652d61bbb3SSatish Balay     SETERRQ(PETSC_ERR_SUP,0,"unknown option");
1662d61bbb3SSatish Balay   }
1672d61bbb3SSatish Balay   PetscFunctionReturn(0);
1682d61bbb3SSatish Balay }
1692d61bbb3SSatish Balay 
1702d61bbb3SSatish Balay 
1712d61bbb3SSatish Balay #undef __FUNC__
1722d61bbb3SSatish Balay #define __FUNC__ "MatGetSize_SeqBAIJ"
1732d61bbb3SSatish Balay int MatGetSize_SeqBAIJ(Mat A,int *m,int *n)
1742d61bbb3SSatish Balay {
1752d61bbb3SSatish Balay   Mat_SeqBAIJ *a = (Mat_SeqBAIJ *) A->data;
1762d61bbb3SSatish Balay 
1772d61bbb3SSatish Balay   PetscFunctionBegin;
1782d61bbb3SSatish Balay   if (m) *m = a->m;
1792d61bbb3SSatish Balay   if (n) *n = a->n;
1802d61bbb3SSatish Balay   PetscFunctionReturn(0);
1812d61bbb3SSatish Balay }
1822d61bbb3SSatish Balay 
1832d61bbb3SSatish Balay #undef __FUNC__
1842d61bbb3SSatish Balay #define __FUNC__ "MatGetOwnershipRange_SeqBAIJ"
1852d61bbb3SSatish Balay int MatGetOwnershipRange_SeqBAIJ(Mat A,int *m,int *n)
1862d61bbb3SSatish Balay {
1872d61bbb3SSatish Balay   Mat_SeqBAIJ *a = (Mat_SeqBAIJ *) A->data;
1882d61bbb3SSatish Balay 
1892d61bbb3SSatish Balay   PetscFunctionBegin;
1902d61bbb3SSatish Balay   *m = 0; *n = a->m;
1912d61bbb3SSatish Balay   PetscFunctionReturn(0);
1922d61bbb3SSatish Balay }
1932d61bbb3SSatish Balay 
1942d61bbb3SSatish Balay #undef __FUNC__
1952d61bbb3SSatish Balay #define __FUNC__ "MatGetRow_SeqBAIJ"
1962d61bbb3SSatish Balay int MatGetRow_SeqBAIJ(Mat A,int row,int *nz,int **idx,Scalar **v)
1972d61bbb3SSatish Balay {
1982d61bbb3SSatish Balay   Mat_SeqBAIJ *a = (Mat_SeqBAIJ *) A->data;
1992d61bbb3SSatish Balay   int          itmp,i,j,k,M,*ai,*aj,bs,bn,bp,*idx_i,bs2;
2002d61bbb3SSatish Balay   Scalar      *aa,*v_i,*aa_i;
2012d61bbb3SSatish Balay 
2022d61bbb3SSatish Balay   PetscFunctionBegin;
2032d61bbb3SSatish Balay   bs  = a->bs;
2042d61bbb3SSatish Balay   ai  = a->i;
2052d61bbb3SSatish Balay   aj  = a->j;
2062d61bbb3SSatish Balay   aa  = a->a;
2072d61bbb3SSatish Balay   bs2 = a->bs2;
2082d61bbb3SSatish Balay 
2092d61bbb3SSatish Balay   if (row < 0 || row >= a->m) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Row out of range");
2102d61bbb3SSatish Balay 
2112d61bbb3SSatish Balay   bn  = row/bs;   /* Block number */
2122d61bbb3SSatish Balay   bp  = row % bs; /* Block Position */
2132d61bbb3SSatish Balay   M   = ai[bn+1] - ai[bn];
2142d61bbb3SSatish Balay   *nz = bs*M;
2152d61bbb3SSatish Balay 
2162d61bbb3SSatish Balay   if (v) {
2172d61bbb3SSatish Balay     *v = 0;
2182d61bbb3SSatish Balay     if (*nz) {
2192d61bbb3SSatish Balay       *v = (Scalar *) PetscMalloc( (*nz)*sizeof(Scalar) ); CHKPTRQ(*v);
2202d61bbb3SSatish Balay       for ( i=0; i<M; i++ ) { /* for each block in the block row */
2212d61bbb3SSatish Balay         v_i  = *v + i*bs;
2222d61bbb3SSatish Balay         aa_i = aa + bs2*(ai[bn] + i);
2232d61bbb3SSatish Balay         for ( j=bp,k=0; j<bs2; j+=bs,k++ ) {v_i[k] = aa_i[j];}
2242d61bbb3SSatish Balay       }
2252d61bbb3SSatish Balay     }
2262d61bbb3SSatish Balay   }
2272d61bbb3SSatish Balay 
2282d61bbb3SSatish Balay   if (idx) {
2292d61bbb3SSatish Balay     *idx = 0;
2302d61bbb3SSatish Balay     if (*nz) {
2312d61bbb3SSatish Balay       *idx = (int *) PetscMalloc( (*nz)*sizeof(int) ); CHKPTRQ(*idx);
2322d61bbb3SSatish Balay       for ( i=0; i<M; i++ ) { /* for each block in the block row */
2332d61bbb3SSatish Balay         idx_i = *idx + i*bs;
2342d61bbb3SSatish Balay         itmp  = bs*aj[ai[bn] + i];
2352d61bbb3SSatish Balay         for ( j=0; j<bs; j++ ) {idx_i[j] = itmp++;}
2362d61bbb3SSatish Balay       }
2372d61bbb3SSatish Balay     }
2382d61bbb3SSatish Balay   }
2392d61bbb3SSatish Balay   PetscFunctionReturn(0);
2402d61bbb3SSatish Balay }
2412d61bbb3SSatish Balay 
2422d61bbb3SSatish Balay #undef __FUNC__
2432d61bbb3SSatish Balay #define __FUNC__ "MatRestoreRow_SeqBAIJ"
2442d61bbb3SSatish Balay int MatRestoreRow_SeqBAIJ(Mat A,int row,int *nz,int **idx,Scalar **v)
2452d61bbb3SSatish Balay {
2462d61bbb3SSatish Balay   PetscFunctionBegin;
2472d61bbb3SSatish Balay   if (idx) {if (*idx) PetscFree(*idx);}
2482d61bbb3SSatish Balay   if (v)   {if (*v)   PetscFree(*v);}
2492d61bbb3SSatish Balay   PetscFunctionReturn(0);
2502d61bbb3SSatish Balay }
2512d61bbb3SSatish Balay 
2522d61bbb3SSatish Balay #undef __FUNC__
2532d61bbb3SSatish Balay #define __FUNC__ "MatTranspose_SeqBAIJ"
2542d61bbb3SSatish Balay int MatTranspose_SeqBAIJ(Mat A,Mat *B)
2552d61bbb3SSatish Balay {
2562d61bbb3SSatish Balay   Mat_SeqBAIJ *a=(Mat_SeqBAIJ *)A->data;
2572d61bbb3SSatish Balay   Mat         C;
2582d61bbb3SSatish Balay   int         i,j,k,ierr,*aj=a->j,*ai=a->i,bs=a->bs,mbs=a->mbs,nbs=a->nbs,len,*col;
2592d61bbb3SSatish Balay   int         *rows,*cols,bs2=a->bs2;
2602d61bbb3SSatish Balay   Scalar      *array=a->a;
2612d61bbb3SSatish Balay 
2622d61bbb3SSatish Balay   PetscFunctionBegin;
2632d61bbb3SSatish Balay   if (B==PETSC_NULL && mbs!=nbs) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Square matrix only for in-place");
2642d61bbb3SSatish Balay   col = (int *) PetscMalloc((1+nbs)*sizeof(int)); CHKPTRQ(col);
2652d61bbb3SSatish Balay   PetscMemzero(col,(1+nbs)*sizeof(int));
2662d61bbb3SSatish Balay 
2672d61bbb3SSatish Balay   for ( i=0; i<ai[mbs]; i++ ) col[aj[i]] += 1;
2682d61bbb3SSatish Balay   ierr = MatCreateSeqBAIJ(A->comm,bs,a->n,a->m,PETSC_NULL,col,&C); CHKERRQ(ierr);
2692d61bbb3SSatish Balay   PetscFree(col);
2702d61bbb3SSatish Balay   rows = (int *) PetscMalloc(2*bs*sizeof(int)); CHKPTRQ(rows);
2712d61bbb3SSatish Balay   cols = rows + bs;
2722d61bbb3SSatish Balay   for ( i=0; i<mbs; i++ ) {
2732d61bbb3SSatish Balay     cols[0] = i*bs;
2742d61bbb3SSatish Balay     for (k=1; k<bs; k++ ) cols[k] = cols[k-1] + 1;
2752d61bbb3SSatish Balay     len = ai[i+1] - ai[i];
2762d61bbb3SSatish Balay     for ( j=0; j<len; j++ ) {
2772d61bbb3SSatish Balay       rows[0] = (*aj++)*bs;
2782d61bbb3SSatish Balay       for (k=1; k<bs; k++ ) rows[k] = rows[k-1] + 1;
2792d61bbb3SSatish Balay       ierr = MatSetValues(C,bs,rows,bs,cols,array,INSERT_VALUES); CHKERRQ(ierr);
2802d61bbb3SSatish Balay       array += bs2;
2812d61bbb3SSatish Balay     }
2822d61bbb3SSatish Balay   }
2832d61bbb3SSatish Balay   PetscFree(rows);
2842d61bbb3SSatish Balay 
2852d61bbb3SSatish Balay   ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY); CHKERRQ(ierr);
2862d61bbb3SSatish Balay   ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY); CHKERRQ(ierr);
2872d61bbb3SSatish Balay 
2882d61bbb3SSatish Balay   if (B != PETSC_NULL) {
2892d61bbb3SSatish Balay     *B = C;
2902d61bbb3SSatish Balay   } else {
291f830108cSBarry Smith     PetscOps *Abops;
292cc2dc46cSBarry Smith     MatOps   Aops;
293f830108cSBarry Smith 
2942d61bbb3SSatish Balay     /* This isn't really an in-place transpose */
2952d61bbb3SSatish Balay     PetscFree(a->a);
2962d61bbb3SSatish Balay     if (!a->singlemalloc) {PetscFree(a->i); PetscFree(a->j);}
2972d61bbb3SSatish Balay     if (a->diag) PetscFree(a->diag);
2982d61bbb3SSatish Balay     if (a->ilen) PetscFree(a->ilen);
2992d61bbb3SSatish Balay     if (a->imax) PetscFree(a->imax);
3002d61bbb3SSatish Balay     if (a->solve_work) PetscFree(a->solve_work);
3012d61bbb3SSatish Balay     PetscFree(a);
302f830108cSBarry Smith 
3037413bad6SBarry Smith 
3047413bad6SBarry Smith     ierr = MapDestroy(A->rmap);CHKERRQ(ierr);
3057413bad6SBarry Smith     ierr = MapDestroy(A->cmap);CHKERRQ(ierr);
3067413bad6SBarry Smith 
307f830108cSBarry Smith     /*
308f830108cSBarry Smith        This is horrible, horrible code. We need to keep the
309f830108cSBarry Smith       A pointers for the bops and ops but copy everything
310f830108cSBarry Smith       else from C.
311f830108cSBarry Smith     */
312f830108cSBarry Smith     Abops    = A->bops;
313f830108cSBarry Smith     Aops     = A->ops;
3142d61bbb3SSatish Balay     PetscMemcpy(A,C,sizeof(struct _p_Mat));
315f830108cSBarry Smith     A->bops  = Abops;
316f830108cSBarry Smith     A->ops   = Aops;
31727a8da17SBarry Smith     A->qlist = 0;
318f830108cSBarry Smith 
3192d61bbb3SSatish Balay     PetscHeaderDestroy(C);
3202d61bbb3SSatish Balay   }
3212d61bbb3SSatish Balay   PetscFunctionReturn(0);
3222d61bbb3SSatish Balay }
3232d61bbb3SSatish Balay 
3242d61bbb3SSatish Balay 
3252d61bbb3SSatish Balay 
3263b2fbd54SBarry Smith 
3275615d1e5SSatish Balay #undef __FUNC__
328d4bb536fSBarry Smith #define __FUNC__ "MatView_SeqBAIJ_Binary"
329b6490206SBarry Smith static int MatView_SeqBAIJ_Binary(Mat A,Viewer viewer)
3302593348eSBarry Smith {
331b6490206SBarry Smith   Mat_SeqBAIJ *a = (Mat_SeqBAIJ *) A->data;
3329df24120SSatish Balay   int         i, fd, *col_lens, ierr, bs = a->bs,count,*jj,j,k,l,bs2=a->bs2;
333b6490206SBarry Smith   Scalar      *aa;
3342593348eSBarry Smith 
3353a40ed3dSBarry Smith   PetscFunctionBegin;
33690ace30eSBarry Smith   ierr = ViewerBinaryGetDescriptor(viewer,&fd); CHKERRQ(ierr);
3372593348eSBarry Smith   col_lens = (int *) PetscMalloc((4+a->m)*sizeof(int));CHKPTRQ(col_lens);
3382593348eSBarry Smith   col_lens[0] = MAT_COOKIE;
3393b2fbd54SBarry Smith 
3402593348eSBarry Smith   col_lens[1] = a->m;
3412593348eSBarry Smith   col_lens[2] = a->n;
3427e67e3f9SSatish Balay   col_lens[3] = a->nz*bs2;
3432593348eSBarry Smith 
3442593348eSBarry Smith   /* store lengths of each row and write (including header) to file */
345b6490206SBarry Smith   count = 0;
346b6490206SBarry Smith   for ( i=0; i<a->mbs; i++ ) {
347b6490206SBarry Smith     for ( j=0; j<bs; j++ ) {
348b6490206SBarry Smith       col_lens[4+count++] = bs*(a->i[i+1] - a->i[i]);
349b6490206SBarry Smith     }
3502593348eSBarry Smith   }
3510752156aSBarry Smith   ierr = PetscBinaryWrite(fd,col_lens,4+a->m,PETSC_INT,1); CHKERRQ(ierr);
3522593348eSBarry Smith   PetscFree(col_lens);
3532593348eSBarry Smith 
3542593348eSBarry Smith   /* store column indices (zero start index) */
35566963ce1SSatish Balay   jj = (int *) PetscMalloc( (a->nz+1)*bs2*sizeof(int) ); CHKPTRQ(jj);
356b6490206SBarry Smith   count = 0;
357b6490206SBarry Smith   for ( i=0; i<a->mbs; i++ ) {
358b6490206SBarry Smith     for ( j=0; j<bs; j++ ) {
359b6490206SBarry Smith       for ( k=a->i[i]; k<a->i[i+1]; k++ ) {
360b6490206SBarry Smith         for ( l=0; l<bs; l++ ) {
361b6490206SBarry Smith           jj[count++] = bs*a->j[k] + l;
3622593348eSBarry Smith         }
3632593348eSBarry Smith       }
364b6490206SBarry Smith     }
365b6490206SBarry Smith   }
3660752156aSBarry Smith   ierr = PetscBinaryWrite(fd,jj,bs2*a->nz,PETSC_INT,0); CHKERRQ(ierr);
367b6490206SBarry Smith   PetscFree(jj);
3682593348eSBarry Smith 
3692593348eSBarry Smith   /* store nonzero values */
37066963ce1SSatish Balay   aa = (Scalar *) PetscMalloc((a->nz+1)*bs2*sizeof(Scalar)); CHKPTRQ(aa);
371b6490206SBarry Smith   count = 0;
372b6490206SBarry Smith   for ( i=0; i<a->mbs; i++ ) {
373b6490206SBarry Smith     for ( j=0; j<bs; j++ ) {
374b6490206SBarry Smith       for ( k=a->i[i]; k<a->i[i+1]; k++ ) {
375b6490206SBarry Smith         for ( l=0; l<bs; l++ ) {
3767e67e3f9SSatish Balay           aa[count++] = a->a[bs2*k + l*bs + j];
377b6490206SBarry Smith         }
378b6490206SBarry Smith       }
379b6490206SBarry Smith     }
380b6490206SBarry Smith   }
3810752156aSBarry Smith   ierr = PetscBinaryWrite(fd,aa,bs2*a->nz,PETSC_SCALAR,0); CHKERRQ(ierr);
382b6490206SBarry Smith   PetscFree(aa);
3833a40ed3dSBarry Smith   PetscFunctionReturn(0);
3842593348eSBarry Smith }
3852593348eSBarry Smith 
3865615d1e5SSatish Balay #undef __FUNC__
387d4bb536fSBarry Smith #define __FUNC__ "MatView_SeqBAIJ_ASCII"
388b6490206SBarry Smith static int MatView_SeqBAIJ_ASCII(Mat A,Viewer viewer)
3892593348eSBarry Smith {
390b6490206SBarry Smith   Mat_SeqBAIJ *a = (Mat_SeqBAIJ *) A->data;
3919df24120SSatish Balay   int         ierr, i,j,format,bs = a->bs,k,l,bs2=a->bs2;
3922593348eSBarry Smith   FILE        *fd;
3932593348eSBarry Smith   char        *outputname;
3942593348eSBarry Smith 
3953a40ed3dSBarry Smith   PetscFunctionBegin;
39690ace30eSBarry Smith   ierr = ViewerASCIIGetPointer(viewer,&fd); CHKERRQ(ierr);
397*77ed5343SBarry Smith   ierr = ViewerGetOutputname(viewer,&outputname);CHKERRQ(ierr);
39890ace30eSBarry Smith   ierr = ViewerGetFormat(viewer,&format);
399639f9d9dSBarry Smith   if (format == VIEWER_FORMAT_ASCII_INFO || format == VIEWER_FORMAT_ASCII_INFO_LONG) {
4007ddc982cSLois Curfman McInnes     fprintf(fd,"  block size is %d\n",bs);
4012593348eSBarry Smith   }
402639f9d9dSBarry Smith   else if (format == VIEWER_FORMAT_ASCII_MATLAB) {
403a8c6a408SBarry Smith     SETERRQ(PETSC_ERR_SUP,0,"Matlab format not supported");
4042593348eSBarry Smith   }
405639f9d9dSBarry Smith   else if (format == VIEWER_FORMAT_ASCII_COMMON) {
40644cd7ae7SLois Curfman McInnes     for ( i=0; i<a->mbs; i++ ) {
40744cd7ae7SLois Curfman McInnes       for ( j=0; j<bs; j++ ) {
40844cd7ae7SLois Curfman McInnes         fprintf(fd,"row %d:",i*bs+j);
40944cd7ae7SLois Curfman McInnes         for ( k=a->i[i]; k<a->i[i+1]; k++ ) {
41044cd7ae7SLois Curfman McInnes           for ( l=0; l<bs; l++ ) {
4113a40ed3dSBarry Smith #if defined(USE_PETSC_COMPLEX)
412e20fef11SSatish Balay           if (PetscImaginary(a->a[bs2*k + l*bs + j]) > 0.0 && PetscReal(a->a[bs2*k + l*bs + j]) != 0.0)
41344cd7ae7SLois Curfman McInnes             fprintf(fd," %d %g + %g i",bs*a->j[k]+l,
414e20fef11SSatish Balay               PetscReal(a->a[bs2*k + l*bs + j]),PetscImaginary(a->a[bs2*k + l*bs + j]));
415e20fef11SSatish Balay           else if (PetscImaginary(a->a[bs2*k + l*bs + j]) < 0.0 && PetscReal(a->a[bs2*k + l*bs + j]) != 0.0)
416766eeae4SLois Curfman McInnes             fprintf(fd," %d %g - %g i",bs*a->j[k]+l,
417e20fef11SSatish Balay               PetscReal(a->a[bs2*k + l*bs + j]),-PetscImaginary(a->a[bs2*k + l*bs + j]));
418e20fef11SSatish Balay           else if (PetscReal(a->a[bs2*k + l*bs + j]) != 0.0)
419e20fef11SSatish Balay             fprintf(fd," %d %g ",bs*a->j[k]+l,PetscReal(a->a[bs2*k + l*bs + j]));
42044cd7ae7SLois Curfman McInnes #else
42144cd7ae7SLois Curfman McInnes           if (a->a[bs2*k + l*bs + j] != 0.0)
42244cd7ae7SLois Curfman McInnes             fprintf(fd," %d %g ",bs*a->j[k]+l,a->a[bs2*k + l*bs + j]);
42344cd7ae7SLois Curfman McInnes #endif
42444cd7ae7SLois Curfman McInnes           }
42544cd7ae7SLois Curfman McInnes         }
42644cd7ae7SLois Curfman McInnes         fprintf(fd,"\n");
42744cd7ae7SLois Curfman McInnes       }
42844cd7ae7SLois Curfman McInnes     }
42944cd7ae7SLois Curfman McInnes   }
4302593348eSBarry Smith   else {
431b6490206SBarry Smith     for ( i=0; i<a->mbs; i++ ) {
432b6490206SBarry Smith       for ( j=0; j<bs; j++ ) {
433b6490206SBarry Smith         fprintf(fd,"row %d:",i*bs+j);
434b6490206SBarry Smith         for ( k=a->i[i]; k<a->i[i+1]; k++ ) {
435b6490206SBarry Smith           for ( l=0; l<bs; l++ ) {
4363a40ed3dSBarry Smith #if defined(USE_PETSC_COMPLEX)
437e20fef11SSatish Balay           if (PetscImaginary(a->a[bs2*k + l*bs + j]) > 0.0) {
43888685aaeSLois Curfman McInnes             fprintf(fd," %d %g + %g i",bs*a->j[k]+l,
439e20fef11SSatish Balay               PetscReal(a->a[bs2*k + l*bs + j]),PetscImaginary(a->a[bs2*k + l*bs + j]));
44088685aaeSLois Curfman McInnes           }
441e20fef11SSatish Balay           else if (PetscImaginary(a->a[bs2*k + l*bs + j]) < 0.0) {
442766eeae4SLois Curfman McInnes             fprintf(fd," %d %g - %g i",bs*a->j[k]+l,
443e20fef11SSatish Balay               PetscReal(a->a[bs2*k + l*bs + j]),-PetscImaginary(a->a[bs2*k + l*bs + j]));
444766eeae4SLois Curfman McInnes           }
44588685aaeSLois Curfman McInnes           else {
446e20fef11SSatish Balay             fprintf(fd," %d %g ",bs*a->j[k]+l,PetscReal(a->a[bs2*k + l*bs + j]));
44788685aaeSLois Curfman McInnes           }
44888685aaeSLois Curfman McInnes #else
4497e67e3f9SSatish Balay             fprintf(fd," %d %g ",bs*a->j[k]+l,a->a[bs2*k + l*bs + j]);
45088685aaeSLois Curfman McInnes #endif
4512593348eSBarry Smith           }
4522593348eSBarry Smith         }
4532593348eSBarry Smith         fprintf(fd,"\n");
4542593348eSBarry Smith       }
4552593348eSBarry Smith     }
456b6490206SBarry Smith   }
4572593348eSBarry Smith   fflush(fd);
4583a40ed3dSBarry Smith   PetscFunctionReturn(0);
4592593348eSBarry Smith }
4602593348eSBarry Smith 
4615615d1e5SSatish Balay #undef __FUNC__
462*77ed5343SBarry Smith #define __FUNC__ "MatView_SeqBAIJ_Draw_Zoom"
463*77ed5343SBarry Smith static int MatView_SeqBAIJ_Draw_Zoom(Draw draw,void *Aa)
4643270192aSSatish Balay {
465*77ed5343SBarry Smith   Mat          A = (Mat) Aa;
4663270192aSSatish Balay   Mat_SeqBAIJ  *a=(Mat_SeqBAIJ *) A->data;
467*77ed5343SBarry Smith   int          row,ierr,i,j,k,l,mbs=a->mbs,pause,color,bs=a->bs,bs2=a->bs2,rank;
4683270192aSSatish Balay   double       xl,yl,xr,yr,w,h,xc,yc,scale = 1.0,x_l,x_r,y_l,y_r;
4693270192aSSatish Balay   Scalar       *aa;
4703270192aSSatish Balay   DrawButton   button;
4713270192aSSatish Balay   PetscTruth   isnull;
472*77ed5343SBarry Smith   MPI_Comm     comm;
473*77ed5343SBarry Smith   Viewer       viewer;
4743270192aSSatish Balay 
4753a40ed3dSBarry Smith   PetscFunctionBegin;
476*77ed5343SBarry Smith   /*
477*77ed5343SBarry Smith       This is nasty. If this is called from an originally parallel matrix
478*77ed5343SBarry Smith    then all processes call this, but only the first has the matrix so the
479*77ed5343SBarry Smith    rest should return immediately.
480*77ed5343SBarry Smith   */
481*77ed5343SBarry Smith   ierr = PetscObjectGetComm((PetscObject)draw,&comm);CHKERRQ(ierr);
482*77ed5343SBarry Smith   MPI_Comm_rank(comm,&rank);
483*77ed5343SBarry Smith   if (rank) PetscFunctionReturn(0);
4843270192aSSatish Balay 
485*77ed5343SBarry Smith   ierr = PetscObjectQuery((PetscObject)A,"Zoomviewer",(PetscObject*) &viewer);CHKERRQ(ierr);
486*77ed5343SBarry Smith 
487*77ed5343SBarry Smith   ierr = DrawGetCoordinates(draw,&xl,&yl,&xr,&yr); CHKERRQ(ierr);
488*77ed5343SBarry Smith 
4893270192aSSatish Balay   /* loop over matrix elements drawing boxes */
4903270192aSSatish Balay   color = DRAW_BLUE;
4913270192aSSatish Balay   for ( i=0,row=0; i<mbs; i++,row+=bs ) {
4923270192aSSatish Balay     for ( j=a->i[i]; j<a->i[i+1]; j++ ) {
4933270192aSSatish Balay       y_l = a->m - row - 1.0; y_r = y_l + 1.0;
4943270192aSSatish Balay       x_l = a->j[j]*bs; x_r = x_l + 1.0;
4953270192aSSatish Balay       aa = a->a + j*bs2;
4963270192aSSatish Balay       for ( k=0; k<bs; k++ ) {
4973270192aSSatish Balay         for ( l=0; l<bs; l++ ) {
4983270192aSSatish Balay           if (PetscReal(*aa++) >=  0.) continue;
499b34f160eSSatish Balay           DrawRectangle(draw,x_l+k,y_l-l,x_r+k,y_r-l,color,color,color,color);
5003270192aSSatish Balay         }
5013270192aSSatish Balay       }
5023270192aSSatish Balay     }
5033270192aSSatish Balay   }
5043270192aSSatish Balay   color = DRAW_CYAN;
5053270192aSSatish Balay   for ( i=0,row=0; i<mbs; i++,row+=bs ) {
5063270192aSSatish Balay     for ( j=a->i[i]; j<a->i[i+1]; j++ ) {
5073270192aSSatish Balay       y_l = a->m - row - 1.0; y_r = y_l + 1.0;
5083270192aSSatish Balay       x_l = a->j[j]*bs; x_r = x_l + 1.0;
5093270192aSSatish Balay       aa = a->a + j*bs2;
5103270192aSSatish Balay       for ( k=0; k<bs; k++ ) {
5113270192aSSatish Balay         for ( l=0; l<bs; l++ ) {
5123270192aSSatish Balay           if (PetscReal(*aa++) != 0.) continue;
513b34f160eSSatish Balay           DrawRectangle(draw,x_l+k,y_l-l,x_r+k,y_r-l,color,color,color,color);
5143270192aSSatish Balay         }
5153270192aSSatish Balay       }
5163270192aSSatish Balay     }
5173270192aSSatish Balay   }
5183270192aSSatish Balay 
5193270192aSSatish Balay   color = DRAW_RED;
5203270192aSSatish Balay   for ( i=0,row=0; i<mbs; i++,row+=bs ) {
5213270192aSSatish Balay     for ( j=a->i[i]; j<a->i[i+1]; j++ ) {
5223270192aSSatish Balay       y_l = a->m - row - 1.0; y_r = y_l + 1.0;
5233270192aSSatish Balay       x_l = a->j[j]*bs; x_r = x_l + 1.0;
5243270192aSSatish Balay       aa = a->a + j*bs2;
5253270192aSSatish Balay       for ( k=0; k<bs; k++ ) {
5263270192aSSatish Balay         for ( l=0; l<bs; l++ ) {
5273270192aSSatish Balay           if (PetscReal(*aa++) <= 0.) continue;
528b34f160eSSatish Balay           DrawRectangle(draw,x_l+k,y_l-l,x_r+k,y_r-l,color,color,color,color);
5293270192aSSatish Balay         }
5303270192aSSatish Balay       }
5313270192aSSatish Balay     }
5323270192aSSatish Balay   }
533*77ed5343SBarry Smith   PetscFunctionReturn(0);
534*77ed5343SBarry Smith }
5353270192aSSatish Balay 
536*77ed5343SBarry Smith #undef __FUNC__
537*77ed5343SBarry Smith #define __FUNC__ "MatView_SeqBAIJ_Draw"
538*77ed5343SBarry Smith static int MatView_SeqBAIJ_Draw(Mat A,Viewer viewer)
539*77ed5343SBarry Smith {
540*77ed5343SBarry Smith   Mat_SeqBAIJ  *a=(Mat_SeqBAIJ *) A->data;
541*77ed5343SBarry Smith   int          row,ierr,i,j,k,l,mbs=a->mbs,pause,color,bs=a->bs,bs2=a->bs2,rank;
542*77ed5343SBarry Smith   double       xl,yl,xr,yr,w,h,xc,yc,scale = 1.0,x_l,x_r,y_l,y_r;
543*77ed5343SBarry Smith   Scalar       *aa;
544*77ed5343SBarry Smith   Draw         draw;
545*77ed5343SBarry Smith   DrawButton   button;
546*77ed5343SBarry Smith   PetscTruth   isnull;
5473270192aSSatish Balay 
548*77ed5343SBarry Smith   PetscFunctionBegin;
549*77ed5343SBarry Smith 
550*77ed5343SBarry Smith   ierr = ViewerDrawGetDraw(viewer,0,&draw);CHKERRQ(ierr);
551*77ed5343SBarry Smith   ierr = DrawIsNull(draw,&isnull); CHKERRQ(ierr); if (isnull) PetscFunctionReturn(0);
552*77ed5343SBarry Smith 
553*77ed5343SBarry Smith   ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",(PetscObject)viewer);CHKERRQ(ierr);
554*77ed5343SBarry Smith   xr  = a->n; yr = a->m; h = yr/10.0; w = xr/10.0;
555*77ed5343SBarry Smith   xr += w;    yr += h;  xl = -w;     yl = -h;
5563270192aSSatish Balay   ierr = DrawSetCoordinates(draw,xl,yl,xr,yr); CHKERRQ(ierr);
557*77ed5343SBarry Smith   ierr = DrawZoom(draw,MatView_SeqBAIJ_Draw_Zoom,A); CHKERRQ(ierr);
558*77ed5343SBarry Smith   ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",PETSC_NULL);CHKERRQ(ierr);
5593a40ed3dSBarry Smith   PetscFunctionReturn(0);
5603270192aSSatish Balay }
5613270192aSSatish Balay 
5625615d1e5SSatish Balay #undef __FUNC__
563d4bb536fSBarry Smith #define __FUNC__ "MatView_SeqBAIJ"
564e1311b90SBarry Smith int MatView_SeqBAIJ(Mat A,Viewer viewer)
5652593348eSBarry Smith {
56619bcc07fSBarry Smith   ViewerType  vtype;
56719bcc07fSBarry Smith   int         ierr;
5682593348eSBarry Smith 
5693a40ed3dSBarry Smith   PetscFunctionBegin;
57019bcc07fSBarry Smith   ierr = ViewerGetType(viewer,&vtype); CHKERRQ(ierr);
571*77ed5343SBarry Smith   if (!PetscStrcmp(vtype,MATLAB_VIEWER)) {
572a8c6a408SBarry Smith     SETERRQ(PETSC_ERR_SUP,0,"Matlab viewer not supported");
573*77ed5343SBarry Smith   } else if (!PetscStrcmp(vtype,ASCII_VIEWER)){
5743a40ed3dSBarry Smith     ierr = MatView_SeqBAIJ_ASCII(A,viewer);CHKERRQ(ierr);
575*77ed5343SBarry Smith   } else if (!PetscStrcmp(vtype,BINARY_VIEWER)) {
5763a40ed3dSBarry Smith     ierr = MatView_SeqBAIJ_Binary(A,viewer);CHKERRQ(ierr);
577*77ed5343SBarry Smith   } else if (!PetscStrcmp(vtype,DRAW_VIEWER)) {
5783a40ed3dSBarry Smith     ierr = MatView_SeqBAIJ_Draw(A,viewer);CHKERRQ(ierr);
5795cd90555SBarry Smith   } else {
5805cd90555SBarry Smith     SETERRQ(1,1,"Viewer type not supported by PETSc object");
5812593348eSBarry Smith   }
5823a40ed3dSBarry Smith   PetscFunctionReturn(0);
5832593348eSBarry Smith }
584b6490206SBarry Smith 
585cd0e1443SSatish Balay 
5865615d1e5SSatish Balay #undef __FUNC__
5872d61bbb3SSatish Balay #define __FUNC__ "MatGetValues_SeqBAIJ"
5882d61bbb3SSatish Balay int MatGetValues_SeqBAIJ(Mat A,int m,int *im,int n,int *in,Scalar *v)
589cd0e1443SSatish Balay {
590cd0e1443SSatish Balay   Mat_SeqBAIJ *a = (Mat_SeqBAIJ *) A->data;
5912d61bbb3SSatish Balay   int        *rp, k, low, high, t, row, nrow, i, col, l, *aj = a->j;
5922d61bbb3SSatish Balay   int        *ai = a->i, *ailen = a->ilen;
5932d61bbb3SSatish Balay   int        brow,bcol,ridx,cidx,bs=a->bs,bs2=a->bs2;
5942d61bbb3SSatish Balay   Scalar     *ap, *aa = a->a, zero = 0.0;
595cd0e1443SSatish Balay 
5963a40ed3dSBarry Smith   PetscFunctionBegin;
5972d61bbb3SSatish Balay   for ( k=0; k<m; k++ ) { /* loop over rows */
598cd0e1443SSatish Balay     row  = im[k]; brow = row/bs;
599a8c6a408SBarry Smith     if (row < 0) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Negative row");
600a8c6a408SBarry Smith     if (row >= a->m) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Row too large");
6012d61bbb3SSatish Balay     rp   = aj + ai[brow] ; ap = aa + bs2*ai[brow] ;
6022c3acbe9SBarry Smith     nrow = ailen[brow];
6032d61bbb3SSatish Balay     for ( l=0; l<n; l++ ) { /* loop over columns */
604a8c6a408SBarry Smith       if (in[l] < 0) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Negative column");
605a8c6a408SBarry Smith       if (in[l] >= a->n) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Column too large");
6062d61bbb3SSatish Balay       col  = in[l] ;
6072d61bbb3SSatish Balay       bcol = col/bs;
6082d61bbb3SSatish Balay       cidx = col%bs;
6092d61bbb3SSatish Balay       ridx = row%bs;
6102d61bbb3SSatish Balay       high = nrow;
6112d61bbb3SSatish Balay       low  = 0; /* assume unsorted */
6122d61bbb3SSatish Balay       while (high-low > 5) {
613cd0e1443SSatish Balay         t = (low+high)/2;
614cd0e1443SSatish Balay         if (rp[t] > bcol) high = t;
615cd0e1443SSatish Balay         else             low  = t;
616cd0e1443SSatish Balay       }
617cd0e1443SSatish Balay       for ( i=low; i<high; i++ ) {
618cd0e1443SSatish Balay         if (rp[i] > bcol) break;
619cd0e1443SSatish Balay         if (rp[i] == bcol) {
6202d61bbb3SSatish Balay           *v++ = ap[bs2*i+bs*cidx+ridx];
6212d61bbb3SSatish Balay           goto finished;
622cd0e1443SSatish Balay         }
623cd0e1443SSatish Balay       }
6242d61bbb3SSatish Balay       *v++ = zero;
6252d61bbb3SSatish Balay       finished:;
626cd0e1443SSatish Balay     }
627cd0e1443SSatish Balay   }
6283a40ed3dSBarry Smith   PetscFunctionReturn(0);
629cd0e1443SSatish Balay }
630cd0e1443SSatish Balay 
6312d61bbb3SSatish Balay 
6325615d1e5SSatish Balay #undef __FUNC__
63305a5f48eSSatish Balay #define __FUNC__ "MatSetValuesBlocked_SeqBAIJ"
63492c4ed94SBarry Smith int MatSetValuesBlocked_SeqBAIJ(Mat A,int m,int *im,int n,int *in,Scalar *v,InsertMode is)
63592c4ed94SBarry Smith {
63692c4ed94SBarry Smith   Mat_SeqBAIJ *a = (Mat_SeqBAIJ *) A->data;
6378a84c255SSatish Balay   int         *rp,k,low,high,t,ii,jj,row,nrow,i,col,l,rmax,N,sorted=a->sorted;
638dd9472c6SBarry Smith   int         *imax=a->imax,*ai=a->i,*ailen=a->ilen, roworiented=a->roworiented;
639dd9472c6SBarry Smith   int         *aj=a->j,nonew=a->nonew,bs2=a->bs2,bs=a->bs,stepval;
6400e324ae4SSatish Balay   Scalar      *ap,*value=v,*aa=a->a,*bap;
64192c4ed94SBarry Smith 
6423a40ed3dSBarry Smith   PetscFunctionBegin;
6430e324ae4SSatish Balay   if (roworiented) {
6440e324ae4SSatish Balay     stepval = (n-1)*bs;
6450e324ae4SSatish Balay   } else {
6460e324ae4SSatish Balay     stepval = (m-1)*bs;
6470e324ae4SSatish Balay   }
64892c4ed94SBarry Smith   for ( k=0; k<m; k++ ) { /* loop over added rows */
64992c4ed94SBarry Smith     row  = im[k];
6503a40ed3dSBarry Smith #if defined(USE_PETSC_BOPT_g)
651a8c6a408SBarry Smith     if (row < 0) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Negative row");
652a8c6a408SBarry Smith     if (row >= a->mbs) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Row too large");
65392c4ed94SBarry Smith #endif
65492c4ed94SBarry Smith     rp   = aj + ai[row];
65592c4ed94SBarry Smith     ap   = aa + bs2*ai[row];
65692c4ed94SBarry Smith     rmax = imax[row];
65792c4ed94SBarry Smith     nrow = ailen[row];
65892c4ed94SBarry Smith     low  = 0;
65992c4ed94SBarry Smith     for ( l=0; l<n; l++ ) { /* loop over added columns */
6603a40ed3dSBarry Smith #if defined(USE_PETSC_BOPT_g)
661a8c6a408SBarry Smith       if (in[l] < 0) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Negative column");
662a8c6a408SBarry Smith       if (in[l] >= a->nbs) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Column too large");
66392c4ed94SBarry Smith #endif
66492c4ed94SBarry Smith       col = in[l];
66592c4ed94SBarry Smith       if (roworiented) {
6660e324ae4SSatish Balay         value = v + k*(stepval+bs)*bs + l*bs;
6670e324ae4SSatish Balay       } else {
6680e324ae4SSatish Balay         value = v + l*(stepval+bs)*bs + k*bs;
66992c4ed94SBarry Smith       }
67092c4ed94SBarry Smith       if (!sorted) low = 0; high = nrow;
67192c4ed94SBarry Smith       while (high-low > 7) {
67292c4ed94SBarry Smith         t = (low+high)/2;
67392c4ed94SBarry Smith         if (rp[t] > col) high = t;
67492c4ed94SBarry Smith         else             low  = t;
67592c4ed94SBarry Smith       }
67692c4ed94SBarry Smith       for ( i=low; i<high; i++ ) {
67792c4ed94SBarry Smith         if (rp[i] > col) break;
67892c4ed94SBarry Smith         if (rp[i] == col) {
6798a84c255SSatish Balay           bap  = ap +  bs2*i;
6800e324ae4SSatish Balay           if (roworiented) {
6818a84c255SSatish Balay             if (is == ADD_VALUES) {
682dd9472c6SBarry Smith               for ( ii=0; ii<bs; ii++,value+=stepval ) {
683dd9472c6SBarry Smith                 for (jj=ii; jj<bs2; jj+=bs ) {
6848a84c255SSatish Balay                   bap[jj] += *value++;
685dd9472c6SBarry Smith                 }
686dd9472c6SBarry Smith               }
6870e324ae4SSatish Balay             } else {
688dd9472c6SBarry Smith               for ( ii=0; ii<bs; ii++,value+=stepval ) {
689dd9472c6SBarry Smith                 for (jj=ii; jj<bs2; jj+=bs ) {
6900e324ae4SSatish Balay                   bap[jj] = *value++;
6918a84c255SSatish Balay                 }
692dd9472c6SBarry Smith               }
693dd9472c6SBarry Smith             }
6940e324ae4SSatish Balay           } else {
6950e324ae4SSatish Balay             if (is == ADD_VALUES) {
696dd9472c6SBarry Smith               for ( ii=0; ii<bs; ii++,value+=stepval ) {
697dd9472c6SBarry Smith                 for (jj=0; jj<bs; jj++ ) {
6980e324ae4SSatish Balay                   *bap++ += *value++;
699dd9472c6SBarry Smith                 }
700dd9472c6SBarry Smith               }
7010e324ae4SSatish Balay             } else {
702dd9472c6SBarry Smith               for ( ii=0; ii<bs; ii++,value+=stepval ) {
703dd9472c6SBarry Smith                 for (jj=0; jj<bs; jj++ ) {
7040e324ae4SSatish Balay                   *bap++  = *value++;
7050e324ae4SSatish Balay                 }
7068a84c255SSatish Balay               }
707dd9472c6SBarry Smith             }
708dd9472c6SBarry Smith           }
709f1241b54SBarry Smith           goto noinsert2;
71092c4ed94SBarry Smith         }
71192c4ed94SBarry Smith       }
71289280ab3SLois Curfman McInnes       if (nonew == 1) goto noinsert2;
713a8c6a408SBarry Smith       else if (nonew == -1) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Inserting a new nonzero in the matrix");
71492c4ed94SBarry Smith       if (nrow >= rmax) {
71592c4ed94SBarry Smith         /* there is no extra room in row, therefore enlarge */
71692c4ed94SBarry Smith         int    new_nz = ai[a->mbs] + CHUNKSIZE,len,*new_i,*new_j;
71792c4ed94SBarry Smith         Scalar *new_a;
71892c4ed94SBarry Smith 
719a8c6a408SBarry Smith         if (nonew == -2) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Inserting a new nonzero in the matrix");
72089280ab3SLois Curfman McInnes 
72192c4ed94SBarry Smith         /* malloc new storage space */
72292c4ed94SBarry Smith         len     = new_nz*(sizeof(int)+bs2*sizeof(Scalar))+(a->mbs+1)*sizeof(int);
72392c4ed94SBarry Smith         new_a   = (Scalar *) PetscMalloc( len ); CHKPTRQ(new_a);
72492c4ed94SBarry Smith         new_j   = (int *) (new_a + bs2*new_nz);
72592c4ed94SBarry Smith         new_i   = new_j + new_nz;
72692c4ed94SBarry Smith 
72792c4ed94SBarry Smith         /* copy over old data into new slots */
72892c4ed94SBarry Smith         for ( ii=0; ii<row+1; ii++ ) {new_i[ii] = ai[ii];}
72992c4ed94SBarry Smith         for ( ii=row+1; ii<a->mbs+1; ii++ ) {new_i[ii] = ai[ii]+CHUNKSIZE;}
73092c4ed94SBarry Smith         PetscMemcpy(new_j,aj,(ai[row]+nrow)*sizeof(int));
73192c4ed94SBarry Smith         len = (new_nz - CHUNKSIZE - ai[row] - nrow);
732dd9472c6SBarry Smith         PetscMemcpy(new_j+ai[row]+nrow+CHUNKSIZE,aj+ai[row]+nrow,len*sizeof(int));
73392c4ed94SBarry Smith         PetscMemcpy(new_a,aa,(ai[row]+nrow)*bs2*sizeof(Scalar));
73492c4ed94SBarry Smith         PetscMemzero(new_a+bs2*(ai[row]+nrow),bs2*CHUNKSIZE*sizeof(Scalar));
735dd9472c6SBarry Smith         PetscMemcpy(new_a+bs2*(ai[row]+nrow+CHUNKSIZE),aa+bs2*(ai[row]+nrow),bs2*len*sizeof(Scalar));
73692c4ed94SBarry Smith         /* free up old matrix storage */
73792c4ed94SBarry Smith         PetscFree(a->a);
73892c4ed94SBarry Smith         if (!a->singlemalloc) {PetscFree(a->i);PetscFree(a->j);}
73992c4ed94SBarry Smith         aa = a->a = new_a; ai = a->i = new_i; aj = a->j = new_j;
74092c4ed94SBarry Smith         a->singlemalloc = 1;
74192c4ed94SBarry Smith 
74292c4ed94SBarry Smith         rp   = aj + ai[row]; ap = aa + bs2*ai[row];
74392c4ed94SBarry Smith         rmax = imax[row] = imax[row] + CHUNKSIZE;
74492c4ed94SBarry Smith         PLogObjectMemory(A,CHUNKSIZE*(sizeof(int) + bs2*sizeof(Scalar)));
74592c4ed94SBarry Smith         a->maxnz += bs2*CHUNKSIZE;
74692c4ed94SBarry Smith         a->reallocs++;
74792c4ed94SBarry Smith         a->nz++;
74892c4ed94SBarry Smith       }
74992c4ed94SBarry Smith       N = nrow++ - 1;
75092c4ed94SBarry Smith       /* shift up all the later entries in this row */
75192c4ed94SBarry Smith       for ( ii=N; ii>=i; ii-- ) {
75292c4ed94SBarry Smith         rp[ii+1] = rp[ii];
75392c4ed94SBarry Smith         PetscMemcpy(ap+bs2*(ii+1),ap+bs2*(ii),bs2*sizeof(Scalar));
75492c4ed94SBarry Smith       }
75592c4ed94SBarry Smith       if (N >= i) PetscMemzero(ap+bs2*i,bs2*sizeof(Scalar));
75692c4ed94SBarry Smith       rp[i] = col;
7578a84c255SSatish Balay       bap   = ap +  bs2*i;
7580e324ae4SSatish Balay       if (roworiented) {
759dd9472c6SBarry Smith         for ( ii=0; ii<bs; ii++,value+=stepval) {
760dd9472c6SBarry Smith           for (jj=ii; jj<bs2; jj+=bs ) {
7610e324ae4SSatish Balay             bap[jj] = *value++;
762dd9472c6SBarry Smith           }
763dd9472c6SBarry Smith         }
7640e324ae4SSatish Balay       } else {
765dd9472c6SBarry Smith         for ( ii=0; ii<bs; ii++,value+=stepval ) {
766dd9472c6SBarry Smith           for (jj=0; jj<bs; jj++ ) {
7670e324ae4SSatish Balay             *bap++  = *value++;
7680e324ae4SSatish Balay           }
769dd9472c6SBarry Smith         }
770dd9472c6SBarry Smith       }
771f1241b54SBarry Smith       noinsert2:;
77292c4ed94SBarry Smith       low = i;
77392c4ed94SBarry Smith     }
77492c4ed94SBarry Smith     ailen[row] = nrow;
77592c4ed94SBarry Smith   }
7763a40ed3dSBarry Smith   PetscFunctionReturn(0);
77792c4ed94SBarry Smith }
77892c4ed94SBarry Smith 
779f2501298SSatish Balay 
7805615d1e5SSatish Balay #undef __FUNC__
7815615d1e5SSatish Balay #define __FUNC__ "MatAssemblyEnd_SeqBAIJ"
7828f6be9afSLois Curfman McInnes int MatAssemblyEnd_SeqBAIJ(Mat A,MatAssemblyType mode)
783584200bdSSatish Balay {
784584200bdSSatish Balay   Mat_SeqBAIJ *a = (Mat_SeqBAIJ *) A->data;
785584200bdSSatish Balay   int        fshift = 0,i,j,*ai = a->i, *aj = a->j, *imax = a->imax;
786a7c10996SSatish Balay   int        m = a->m,*ip, N, *ailen = a->ilen;
78743ee02c3SBarry Smith   int        mbs = a->mbs, bs2 = a->bs2,rmax = 0;
788584200bdSSatish Balay   Scalar     *aa = a->a, *ap;
789584200bdSSatish Balay 
7903a40ed3dSBarry Smith   PetscFunctionBegin;
7913a40ed3dSBarry Smith   if (mode == MAT_FLUSH_ASSEMBLY) PetscFunctionReturn(0);
792584200bdSSatish Balay 
79343ee02c3SBarry Smith   if (m) rmax = ailen[0];
794584200bdSSatish Balay   for ( i=1; i<mbs; i++ ) {
795584200bdSSatish Balay     /* move each row back by the amount of empty slots (fshift) before it*/
796584200bdSSatish Balay     fshift += imax[i-1] - ailen[i-1];
797d402145bSBarry Smith     rmax   = PetscMax(rmax,ailen[i]);
798584200bdSSatish Balay     if (fshift) {
799a7c10996SSatish Balay       ip = aj + ai[i]; ap = aa + bs2*ai[i];
800584200bdSSatish Balay       N = ailen[i];
801584200bdSSatish Balay       for ( j=0; j<N; j++ ) {
802584200bdSSatish Balay         ip[j-fshift] = ip[j];
8037e67e3f9SSatish Balay         PetscMemcpy(ap+(j-fshift)*bs2,ap+j*bs2,bs2*sizeof(Scalar));
804584200bdSSatish Balay       }
805584200bdSSatish Balay     }
806584200bdSSatish Balay     ai[i] = ai[i-1] + ailen[i-1];
807584200bdSSatish Balay   }
808584200bdSSatish Balay   if (mbs) {
809584200bdSSatish Balay     fshift += imax[mbs-1] - ailen[mbs-1];
810584200bdSSatish Balay     ai[mbs] = ai[mbs-1] + ailen[mbs-1];
811584200bdSSatish Balay   }
812584200bdSSatish Balay   /* reset ilen and imax for each row */
813584200bdSSatish Balay   for ( i=0; i<mbs; i++ ) {
814584200bdSSatish Balay     ailen[i] = imax[i] = ai[i+1] - ai[i];
815584200bdSSatish Balay   }
816a7c10996SSatish Balay   a->nz = ai[mbs];
817584200bdSSatish Balay 
818584200bdSSatish Balay   /* diagonals may have moved, so kill the diagonal pointers */
819584200bdSSatish Balay   if (fshift && a->diag) {
820584200bdSSatish Balay     PetscFree(a->diag);
821584200bdSSatish Balay     PLogObjectMemory(A,-(m+1)*sizeof(int));
822584200bdSSatish Balay     a->diag = 0;
823584200bdSSatish Balay   }
8243d2013a6SLois Curfman McInnes   PLogInfo(A,"MatAssemblyEnd_SeqBAIJ:Matrix size: %d X %d, block size %d; storage space: %d unneeded, %d used\n",
825219d9a1aSLois Curfman McInnes            m,a->n,a->bs,fshift*bs2,a->nz*bs2);
8263d2013a6SLois Curfman McInnes   PLogInfo(A,"MatAssemblyEnd_SeqBAIJ:Number of mallocs during MatSetValues is %d\n",
827584200bdSSatish Balay            a->reallocs);
828d402145bSBarry Smith   PLogInfo(A,"MatAssemblyEnd_SeqBAIJ:Most nonzeros blocks in any row is %d\n",rmax);
829e2f3b5e9SSatish Balay   a->reallocs          = 0;
8304e220ebcSLois Curfman McInnes   A->info.nz_unneeded  = (double)fshift*bs2;
8314e220ebcSLois Curfman McInnes 
8323a40ed3dSBarry Smith   PetscFunctionReturn(0);
833584200bdSSatish Balay }
834584200bdSSatish Balay 
8355a838052SSatish Balay 
836d9b7c43dSSatish Balay /* idx should be of length atlease bs */
8375615d1e5SSatish Balay #undef __FUNC__
8385615d1e5SSatish Balay #define __FUNC__ "MatZeroRows_SeqBAIJ_Check_Block"
839d9b7c43dSSatish Balay static int MatZeroRows_SeqBAIJ_Check_Block(int *idx, int bs, PetscTruth *flg)
840d9b7c43dSSatish Balay {
841d9b7c43dSSatish Balay   int i,row;
8423a40ed3dSBarry Smith 
8433a40ed3dSBarry Smith   PetscFunctionBegin;
844d9b7c43dSSatish Balay   row = idx[0];
8453a40ed3dSBarry Smith   if (row%bs!=0) { *flg = PETSC_FALSE; PetscFunctionReturn(0); }
846d9b7c43dSSatish Balay 
847d9b7c43dSSatish Balay   for ( i=1; i<bs; i++ ) {
8483a40ed3dSBarry Smith     if (row+i != idx[i]) { *flg = PETSC_FALSE; PetscFunctionReturn(0); }
849d9b7c43dSSatish Balay   }
850d9b7c43dSSatish Balay   *flg = PETSC_TRUE;
8513a40ed3dSBarry Smith   PetscFunctionReturn(0);
852d9b7c43dSSatish Balay }
853d9b7c43dSSatish Balay 
8545615d1e5SSatish Balay #undef __FUNC__
8555615d1e5SSatish Balay #define __FUNC__ "MatZeroRows_SeqBAIJ"
8568f6be9afSLois Curfman McInnes int MatZeroRows_SeqBAIJ(Mat A,IS is, Scalar *diag)
857d9b7c43dSSatish Balay {
858d9b7c43dSSatish Balay   Mat_SeqBAIJ *baij=(Mat_SeqBAIJ*)A->data;
859d9b7c43dSSatish Balay   IS          is_local;
860d9b7c43dSSatish Balay   int         ierr,i,j,count,m=baij->m,is_n,*is_idx,*rows,bs=baij->bs,bs2=baij->bs2;
861d9b7c43dSSatish Balay   PetscTruth  flg;
862d9b7c43dSSatish Balay   Scalar      zero = 0.0,*aa;
863d9b7c43dSSatish Balay 
8643a40ed3dSBarry Smith   PetscFunctionBegin;
865d9b7c43dSSatish Balay   /* Make a copy of the IS and  sort it */
866d9b7c43dSSatish Balay   ierr = ISGetSize(is,&is_n);CHKERRQ(ierr);
867d9b7c43dSSatish Balay   ierr = ISGetIndices(is,&is_idx);CHKERRQ(ierr);
868537820f0SBarry Smith   ierr = ISCreateGeneral(A->comm,is_n,is_idx,&is_local); CHKERRQ(ierr);
869d9b7c43dSSatish Balay   ierr = ISSort(is_local); CHKERRQ(ierr);
870d9b7c43dSSatish Balay   ierr = ISGetIndices(is_local,&rows); CHKERRQ(ierr);
871d9b7c43dSSatish Balay 
872d9b7c43dSSatish Balay   i = 0;
873d9b7c43dSSatish Balay   while (i < is_n) {
874a8c6a408SBarry Smith     if (rows[i]<0 || rows[i]>m) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"row out of range");
875d9b7c43dSSatish Balay     flg = PETSC_FALSE;
876d9b7c43dSSatish Balay     if (i+bs <= is_n) {ierr = MatZeroRows_SeqBAIJ_Check_Block(rows+i,bs,&flg); CHKERRQ(ierr); }
877d9b7c43dSSatish Balay     count = (baij->i[rows[i]/bs +1] - baij->i[rows[i]/bs])*bs;
878d9b7c43dSSatish Balay     aa    = baij->a + baij->i[rows[i]/bs]*bs2 + (rows[i]%bs);
8792d61bbb3SSatish Balay     if (flg) { /* There exists a block of rows to be Zerowed */
880a07cd24cSSatish Balay       if (baij->ilen[rows[i]/bs] > 0) {
8812d61bbb3SSatish Balay         PetscMemzero(aa,count*bs*sizeof(Scalar));
8822d61bbb3SSatish Balay         baij->ilen[rows[i]/bs] = 1;
8832d61bbb3SSatish Balay         baij->j[baij->i[rows[i]/bs]] = rows[i]/bs;
884a07cd24cSSatish Balay       }
8852d61bbb3SSatish Balay       i += bs;
8862d61bbb3SSatish Balay     } else { /* Zero out only the requested row */
887d9b7c43dSSatish Balay       for ( j=0; j<count; j++ ) {
888d9b7c43dSSatish Balay         aa[0] = zero;
889d9b7c43dSSatish Balay         aa+=bs;
890d9b7c43dSSatish Balay       }
891d9b7c43dSSatish Balay       i++;
892d9b7c43dSSatish Balay     }
893d9b7c43dSSatish Balay   }
894d9b7c43dSSatish Balay   if (diag) {
895d9b7c43dSSatish Balay     for ( j=0; j<is_n; j++ ) {
896f830108cSBarry Smith       ierr = (*A->ops->setvalues)(A,1,rows+j,1,rows+j,diag,INSERT_VALUES);CHKERRQ(ierr);
8972d61bbb3SSatish Balay       /* ierr = MatSetValues(A,1,rows+j,1,rows+j,diag,INSERT_VALUES);CHKERRQ(ierr); */
898d9b7c43dSSatish Balay     }
899d9b7c43dSSatish Balay   }
900d9b7c43dSSatish Balay   ierr = ISRestoreIndices(is,&is_idx); CHKERRQ(ierr);
901d9b7c43dSSatish Balay   ierr = ISRestoreIndices(is_local,&rows); CHKERRQ(ierr);
902d9b7c43dSSatish Balay   ierr = ISDestroy(is_local); CHKERRQ(ierr);
9039a8dea36SBarry Smith   ierr = MatAssemblyEnd_SeqBAIJ(A,MAT_FINAL_ASSEMBLY); CHKERRQ(ierr);
9043a40ed3dSBarry Smith   PetscFunctionReturn(0);
905d9b7c43dSSatish Balay }
9061c351548SSatish Balay 
9075615d1e5SSatish Balay #undef __FUNC__
9082d61bbb3SSatish Balay #define __FUNC__ "MatSetValues_SeqBAIJ"
9092d61bbb3SSatish Balay int MatSetValues_SeqBAIJ(Mat A,int m,int *im,int n,int *in,Scalar *v,InsertMode is)
9102d61bbb3SSatish Balay {
9112d61bbb3SSatish Balay   Mat_SeqBAIJ *a = (Mat_SeqBAIJ *) A->data;
9122d61bbb3SSatish Balay   int         *rp,k,low,high,t,ii,row,nrow,i,col,l,rmax,N,sorted=a->sorted;
9132d61bbb3SSatish Balay   int         *imax=a->imax,*ai=a->i,*ailen=a->ilen,roworiented=a->roworiented;
9142d61bbb3SSatish Balay   int         *aj=a->j,nonew=a->nonew,bs=a->bs,brow,bcol;
9152d61bbb3SSatish Balay   int          ridx,cidx,bs2=a->bs2;
9162d61bbb3SSatish Balay   Scalar      *ap,value,*aa=a->a,*bap;
9172d61bbb3SSatish Balay 
9182d61bbb3SSatish Balay   PetscFunctionBegin;
9192d61bbb3SSatish Balay   for ( k=0; k<m; k++ ) { /* loop over added rows */
9202d61bbb3SSatish Balay     row  = im[k]; brow = row/bs;
9212d61bbb3SSatish Balay #if defined(USE_PETSC_BOPT_g)
9222d61bbb3SSatish Balay     if (row < 0) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Negative row");
9232d61bbb3SSatish Balay     if (row >= a->m) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Row too large");
9242d61bbb3SSatish Balay #endif
9252d61bbb3SSatish Balay     rp   = aj + ai[brow];
9262d61bbb3SSatish Balay     ap   = aa + bs2*ai[brow];
9272d61bbb3SSatish Balay     rmax = imax[brow];
9282d61bbb3SSatish Balay     nrow = ailen[brow];
9292d61bbb3SSatish Balay     low  = 0;
9302d61bbb3SSatish Balay     for ( l=0; l<n; l++ ) { /* loop over added columns */
9312d61bbb3SSatish Balay #if defined(USE_PETSC_BOPT_g)
9322d61bbb3SSatish Balay       if (in[l] < 0) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Negative column");
9332d61bbb3SSatish Balay       if (in[l] >= a->n) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Column too large");
9342d61bbb3SSatish Balay #endif
9352d61bbb3SSatish Balay       col = in[l]; bcol = col/bs;
9362d61bbb3SSatish Balay       ridx = row % bs; cidx = col % bs;
9372d61bbb3SSatish Balay       if (roworiented) {
9382d61bbb3SSatish Balay         value = *v++;
9392d61bbb3SSatish Balay       } else {
9402d61bbb3SSatish Balay         value = v[k + l*m];
9412d61bbb3SSatish Balay       }
9422d61bbb3SSatish Balay       if (!sorted) low = 0; high = nrow;
9432d61bbb3SSatish Balay       while (high-low > 7) {
9442d61bbb3SSatish Balay         t = (low+high)/2;
9452d61bbb3SSatish Balay         if (rp[t] > bcol) high = t;
9462d61bbb3SSatish Balay         else              low  = t;
9472d61bbb3SSatish Balay       }
9482d61bbb3SSatish Balay       for ( i=low; i<high; i++ ) {
9492d61bbb3SSatish Balay         if (rp[i] > bcol) break;
9502d61bbb3SSatish Balay         if (rp[i] == bcol) {
9512d61bbb3SSatish Balay           bap  = ap +  bs2*i + bs*cidx + ridx;
9522d61bbb3SSatish Balay           if (is == ADD_VALUES) *bap += value;
9532d61bbb3SSatish Balay           else                  *bap  = value;
9542d61bbb3SSatish Balay           goto noinsert1;
9552d61bbb3SSatish Balay         }
9562d61bbb3SSatish Balay       }
9572d61bbb3SSatish Balay       if (nonew == 1) goto noinsert1;
9582d61bbb3SSatish Balay       else if (nonew == -1) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Inserting a new nonzero in the matrix");
9592d61bbb3SSatish Balay       if (nrow >= rmax) {
9602d61bbb3SSatish Balay         /* there is no extra room in row, therefore enlarge */
9612d61bbb3SSatish Balay         int    new_nz = ai[a->mbs] + CHUNKSIZE,len,*new_i,*new_j;
9622d61bbb3SSatish Balay         Scalar *new_a;
9632d61bbb3SSatish Balay 
9642d61bbb3SSatish Balay         if (nonew == -2) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Inserting a new nonzero in the matrix");
9652d61bbb3SSatish Balay 
9662d61bbb3SSatish Balay         /* Malloc new storage space */
9672d61bbb3SSatish Balay         len     = new_nz*(sizeof(int)+bs2*sizeof(Scalar))+(a->mbs+1)*sizeof(int);
9682d61bbb3SSatish Balay         new_a   = (Scalar *) PetscMalloc( len ); CHKPTRQ(new_a);
9692d61bbb3SSatish Balay         new_j   = (int *) (new_a + bs2*new_nz);
9702d61bbb3SSatish Balay         new_i   = new_j + new_nz;
9712d61bbb3SSatish Balay 
9722d61bbb3SSatish Balay         /* copy over old data into new slots */
9732d61bbb3SSatish Balay         for ( ii=0; ii<brow+1; ii++ ) {new_i[ii] = ai[ii];}
9742d61bbb3SSatish Balay         for ( ii=brow+1; ii<a->mbs+1; ii++ ) {new_i[ii] = ai[ii]+CHUNKSIZE;}
9752d61bbb3SSatish Balay         PetscMemcpy(new_j,aj,(ai[brow]+nrow)*sizeof(int));
9762d61bbb3SSatish Balay         len = (new_nz - CHUNKSIZE - ai[brow] - nrow);
9772d61bbb3SSatish Balay         PetscMemcpy(new_j+ai[brow]+nrow+CHUNKSIZE,aj+ai[brow]+nrow,
9782d61bbb3SSatish Balay                                                            len*sizeof(int));
9792d61bbb3SSatish Balay         PetscMemcpy(new_a,aa,(ai[brow]+nrow)*bs2*sizeof(Scalar));
9802d61bbb3SSatish Balay         PetscMemzero(new_a+bs2*(ai[brow]+nrow),bs2*CHUNKSIZE*sizeof(Scalar));
9812d61bbb3SSatish Balay         PetscMemcpy(new_a+bs2*(ai[brow]+nrow+CHUNKSIZE),
9822d61bbb3SSatish Balay                     aa+bs2*(ai[brow]+nrow),bs2*len*sizeof(Scalar));
9832d61bbb3SSatish Balay         /* free up old matrix storage */
9842d61bbb3SSatish Balay         PetscFree(a->a);
9852d61bbb3SSatish Balay         if (!a->singlemalloc) {PetscFree(a->i);PetscFree(a->j);}
9862d61bbb3SSatish Balay         aa = a->a = new_a; ai = a->i = new_i; aj = a->j = new_j;
9872d61bbb3SSatish Balay         a->singlemalloc = 1;
9882d61bbb3SSatish Balay 
9892d61bbb3SSatish Balay         rp   = aj + ai[brow]; ap = aa + bs2*ai[brow];
9902d61bbb3SSatish Balay         rmax = imax[brow] = imax[brow] + CHUNKSIZE;
9912d61bbb3SSatish Balay         PLogObjectMemory(A,CHUNKSIZE*(sizeof(int) + bs2*sizeof(Scalar)));
9922d61bbb3SSatish Balay         a->maxnz += bs2*CHUNKSIZE;
9932d61bbb3SSatish Balay         a->reallocs++;
9942d61bbb3SSatish Balay         a->nz++;
9952d61bbb3SSatish Balay       }
9962d61bbb3SSatish Balay       N = nrow++ - 1;
9972d61bbb3SSatish Balay       /* shift up all the later entries in this row */
9982d61bbb3SSatish Balay       for ( ii=N; ii>=i; ii-- ) {
9992d61bbb3SSatish Balay         rp[ii+1] = rp[ii];
10002d61bbb3SSatish Balay         PetscMemcpy(ap+bs2*(ii+1),ap+bs2*(ii),bs2*sizeof(Scalar));
10012d61bbb3SSatish Balay       }
10022d61bbb3SSatish Balay       if (N>=i) PetscMemzero(ap+bs2*i,bs2*sizeof(Scalar));
10032d61bbb3SSatish Balay       rp[i]                      = bcol;
10042d61bbb3SSatish Balay       ap[bs2*i + bs*cidx + ridx] = value;
10052d61bbb3SSatish Balay       noinsert1:;
10062d61bbb3SSatish Balay       low = i;
10072d61bbb3SSatish Balay     }
10082d61bbb3SSatish Balay     ailen[brow] = nrow;
10092d61bbb3SSatish Balay   }
10102d61bbb3SSatish Balay   PetscFunctionReturn(0);
10112d61bbb3SSatish Balay }
10122d61bbb3SSatish Balay 
10132d61bbb3SSatish Balay extern int MatLUFactorSymbolic_SeqBAIJ(Mat,IS,IS,double,Mat*);
10142d61bbb3SSatish Balay extern int MatLUFactor_SeqBAIJ(Mat,IS,IS,double);
10152d61bbb3SSatish Balay extern int MatIncreaseOverlap_SeqBAIJ(Mat,int,IS*,int);
1016d3825aa8SBarry Smith extern int MatGetSubMatrix_SeqBAIJ(Mat,IS,IS,int,MatGetSubMatrixCall,Mat*);
10172d61bbb3SSatish Balay extern int MatGetSubMatrices_SeqBAIJ(Mat,int,IS*,IS*,MatGetSubMatrixCall,Mat**);
10182d61bbb3SSatish Balay extern int MatMultTrans_SeqBAIJ(Mat,Vec,Vec);
10192d61bbb3SSatish Balay extern int MatMultTransAdd_SeqBAIJ(Mat,Vec,Vec,Vec);
10202d61bbb3SSatish Balay extern int MatScale_SeqBAIJ(Scalar*,Mat);
10212d61bbb3SSatish Balay extern int MatNorm_SeqBAIJ(Mat,NormType,double *);
10222d61bbb3SSatish Balay extern int MatEqual_SeqBAIJ(Mat,Mat, PetscTruth*);
10232d61bbb3SSatish Balay extern int MatGetDiagonal_SeqBAIJ(Mat,Vec);
10242d61bbb3SSatish Balay extern int MatDiagonalScale_SeqBAIJ(Mat,Vec,Vec);
10252d61bbb3SSatish Balay extern int MatGetInfo_SeqBAIJ(Mat,MatInfoType,MatInfo *);
10262d61bbb3SSatish Balay extern int MatZeroEntries_SeqBAIJ(Mat);
10272d61bbb3SSatish Balay 
10282d61bbb3SSatish Balay extern int MatSolve_SeqBAIJ_N(Mat,Vec,Vec);
10292d61bbb3SSatish Balay extern int MatSolve_SeqBAIJ_1(Mat,Vec,Vec);
10302d61bbb3SSatish Balay extern int MatSolve_SeqBAIJ_2(Mat,Vec,Vec);
10312d61bbb3SSatish Balay extern int MatSolve_SeqBAIJ_3(Mat,Vec,Vec);
10322d61bbb3SSatish Balay extern int MatSolve_SeqBAIJ_4(Mat,Vec,Vec);
10332d61bbb3SSatish Balay extern int MatSolve_SeqBAIJ_5(Mat,Vec,Vec);
10342d61bbb3SSatish Balay extern int MatSolve_SeqBAIJ_7(Mat,Vec,Vec);
10352d61bbb3SSatish Balay 
10362d61bbb3SSatish Balay extern int MatLUFactorNumeric_SeqBAIJ_N(Mat,Mat*);
10372d61bbb3SSatish Balay extern int MatLUFactorNumeric_SeqBAIJ_1(Mat,Mat*);
10382d61bbb3SSatish Balay extern int MatLUFactorNumeric_SeqBAIJ_2(Mat,Mat*);
10392d61bbb3SSatish Balay extern int MatLUFactorNumeric_SeqBAIJ_3(Mat,Mat*);
10402d61bbb3SSatish Balay extern int MatLUFactorNumeric_SeqBAIJ_4(Mat,Mat*);
10412d61bbb3SSatish Balay extern int MatLUFactorNumeric_SeqBAIJ_5(Mat,Mat*);
10422d61bbb3SSatish Balay 
10432d61bbb3SSatish Balay extern int MatMult_SeqBAIJ_1(Mat,Vec,Vec);
10442d61bbb3SSatish Balay extern int MatMult_SeqBAIJ_2(Mat,Vec,Vec);
10452d61bbb3SSatish Balay extern int MatMult_SeqBAIJ_3(Mat,Vec,Vec);
10462d61bbb3SSatish Balay extern int MatMult_SeqBAIJ_4(Mat,Vec,Vec);
10472d61bbb3SSatish Balay extern int MatMult_SeqBAIJ_5(Mat,Vec,Vec);
10482d61bbb3SSatish Balay extern int MatMult_SeqBAIJ_7(Mat,Vec,Vec);
10492d61bbb3SSatish Balay extern int MatMult_SeqBAIJ_N(Mat,Vec,Vec);
10502d61bbb3SSatish Balay 
10512d61bbb3SSatish Balay extern int MatMultAdd_SeqBAIJ_1(Mat,Vec,Vec,Vec);
10522d61bbb3SSatish Balay extern int MatMultAdd_SeqBAIJ_2(Mat,Vec,Vec,Vec);
10532d61bbb3SSatish Balay extern int MatMultAdd_SeqBAIJ_3(Mat,Vec,Vec,Vec);
10542d61bbb3SSatish Balay extern int MatMultAdd_SeqBAIJ_4(Mat,Vec,Vec,Vec);
10552d61bbb3SSatish Balay extern int MatMultAdd_SeqBAIJ_5(Mat,Vec,Vec,Vec);
10562d61bbb3SSatish Balay extern int MatMultAdd_SeqBAIJ_7(Mat,Vec,Vec,Vec);
10572d61bbb3SSatish Balay extern int MatMultAdd_SeqBAIJ_N(Mat,Vec,Vec,Vec);
10582d61bbb3SSatish Balay 
10592d61bbb3SSatish Balay #undef __FUNC__
10602d61bbb3SSatish Balay #define __FUNC__ "MatILUFactor_SeqBAIJ"
10612d61bbb3SSatish Balay int MatILUFactor_SeqBAIJ(Mat inA,IS row,IS col,double efill,int fill)
10622d61bbb3SSatish Balay {
10632d61bbb3SSatish Balay   Mat_SeqBAIJ *a = (Mat_SeqBAIJ *) inA->data;
10642d61bbb3SSatish Balay   Mat         outA;
10652d61bbb3SSatish Balay   int         ierr;
1066667159a5SBarry Smith   PetscTruth  row_identity, col_identity;
10672d61bbb3SSatish Balay 
10682d61bbb3SSatish Balay   PetscFunctionBegin;
10692d61bbb3SSatish Balay   if (fill != 0) SETERRQ(PETSC_ERR_SUP,0,"Only fill=0 supported");
1070667159a5SBarry Smith   ierr = ISIdentity(row,&row_identity); CHKERRQ(ierr);
1071667159a5SBarry Smith   ierr = ISIdentity(col,&col_identity); CHKERRQ(ierr);
1072667159a5SBarry Smith   if (!row_identity || !col_identity) {
1073667159a5SBarry Smith     SETERRQ(1,1,"Row and column permutations must be identity");
1074667159a5SBarry Smith   }
10752d61bbb3SSatish Balay 
10762d61bbb3SSatish Balay   outA          = inA;
10772d61bbb3SSatish Balay   inA->factor   = FACTOR_LU;
10782d61bbb3SSatish Balay   a->row        = row;
10792d61bbb3SSatish Balay   a->col        = col;
10802d61bbb3SSatish Balay 
1081e51c0b9cSSatish Balay   /* Create the invert permutation so that it can be used in MatLUFactorNumeric() */
1082e51c0b9cSSatish Balay   ierr = ISInvertPermutation(col,&(a->icol)); CHKERRQ(ierr);
10831e4dd532SSatish Balay   PLogObjectParent(inA,a->icol);
1084e51c0b9cSSatish Balay 
10852d61bbb3SSatish Balay   if (!a->solve_work) {
10862d61bbb3SSatish Balay     a->solve_work = (Scalar *) PetscMalloc((a->m+a->bs)*sizeof(Scalar));CHKPTRQ(a->solve_work);
10872d61bbb3SSatish Balay     PLogObjectMemory(inA,(a->m+a->bs)*sizeof(Scalar));
10882d61bbb3SSatish Balay   }
10892d61bbb3SSatish Balay 
10902d61bbb3SSatish Balay   if (!a->diag) {
10912d61bbb3SSatish Balay     ierr = MatMarkDiag_SeqBAIJ(inA); CHKERRQ(ierr);
10922d61bbb3SSatish Balay   }
10932d61bbb3SSatish Balay   /*
1094667159a5SBarry Smith       Blocksize 4 and 5 have a special faster factorization/solver for ILU(0) factorization
10952d61bbb3SSatish Balay     with natural ordering
10962d61bbb3SSatish Balay   */
10972d61bbb3SSatish Balay   if (a->bs == 4) {
1098667159a5SBarry Smith     inA->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_4_NaturalOrdering;
1099f830108cSBarry Smith     inA->ops->solve           = MatSolve_SeqBAIJ_4_NaturalOrdering;
1100667159a5SBarry Smith     PLogInfo(inA,"Using special in-place natural ordering factor and solve BS=4\n");
1101667159a5SBarry Smith   } else if (a->bs == 5) {
1102667159a5SBarry Smith     inA->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_5_NaturalOrdering;
1103667159a5SBarry Smith     inA->ops->solve           = MatSolve_SeqBAIJ_5_NaturalOrdering;
1104667159a5SBarry Smith     PLogInfo(inA,"Using special in-place natural ordering factor and solve BS=5\n");
11052d61bbb3SSatish Balay   }
11062d61bbb3SSatish Balay 
1107667159a5SBarry Smith   ierr = MatLUFactorNumeric(inA,&outA); CHKERRQ(ierr);
1108667159a5SBarry Smith 
1109667159a5SBarry Smith 
11102d61bbb3SSatish Balay   PetscFunctionReturn(0);
11112d61bbb3SSatish Balay }
11122d61bbb3SSatish Balay #undef __FUNC__
1113d4bb536fSBarry Smith #define __FUNC__ "MatPrintHelp_SeqBAIJ"
1114ba4ca20aSSatish Balay int MatPrintHelp_SeqBAIJ(Mat A)
1115ba4ca20aSSatish Balay {
1116ba4ca20aSSatish Balay   static int called = 0;
1117ba4ca20aSSatish Balay   MPI_Comm   comm = A->comm;
1118ba4ca20aSSatish Balay 
11193a40ed3dSBarry Smith   PetscFunctionBegin;
11203a40ed3dSBarry Smith   if (called) {PetscFunctionReturn(0);} else called = 1;
112176be9ce4SBarry Smith   (*PetscHelpPrintf)(comm," Options for MATSEQBAIJ and MATMPIBAIJ matrix formats (the defaults):\n");
112276be9ce4SBarry Smith   (*PetscHelpPrintf)(comm,"  -mat_block_size <block_size>\n");
11233a40ed3dSBarry Smith   PetscFunctionReturn(0);
1124ba4ca20aSSatish Balay }
1125d9b7c43dSSatish Balay 
1126fb2e594dSBarry Smith EXTERN_C_BEGIN
112727a8da17SBarry Smith #undef __FUNC__
112827a8da17SBarry Smith #define __FUNC__ "MatSeqBAIJSetColumnIndices_SeqBAIJ"
112927a8da17SBarry Smith int MatSeqBAIJSetColumnIndices_SeqBAIJ(Mat mat,int *indices)
113027a8da17SBarry Smith {
113127a8da17SBarry Smith   Mat_SeqBAIJ *baij = (Mat_SeqBAIJ *)mat->data;
113227a8da17SBarry Smith   int         i,nz,n;
113327a8da17SBarry Smith 
113427a8da17SBarry Smith   PetscFunctionBegin;
113527a8da17SBarry Smith   nz = baij->maxnz;
113627a8da17SBarry Smith   n  = baij->n;
113727a8da17SBarry Smith   for (i=0; i<nz; i++) {
113827a8da17SBarry Smith     baij->j[i] = indices[i];
113927a8da17SBarry Smith   }
114027a8da17SBarry Smith   baij->nz = nz;
114127a8da17SBarry Smith   for ( i=0; i<n; i++ ) {
114227a8da17SBarry Smith     baij->ilen[i] = baij->imax[i];
114327a8da17SBarry Smith   }
114427a8da17SBarry Smith 
114527a8da17SBarry Smith   PetscFunctionReturn(0);
114627a8da17SBarry Smith }
1147fb2e594dSBarry Smith EXTERN_C_END
114827a8da17SBarry Smith 
114927a8da17SBarry Smith #undef __FUNC__
115027a8da17SBarry Smith #define __FUNC__ "MatSeqBAIJSetColumnIndices"
115127a8da17SBarry Smith /*@
115227a8da17SBarry Smith     MatSeqBAIJSetColumnIndices - Set the column indices for all the rows
115327a8da17SBarry Smith        in the matrix.
115427a8da17SBarry Smith 
115527a8da17SBarry Smith   Input Parameters:
115627a8da17SBarry Smith +  mat - the SeqBAIJ matrix
115727a8da17SBarry Smith -  indices - the column indices
115827a8da17SBarry Smith 
115927a8da17SBarry Smith   Notes:
116027a8da17SBarry Smith     This can be called if you have precomputed the nonzero structure of the
116127a8da17SBarry Smith   matrix and want to provide it to the matrix object to improve the performance
116227a8da17SBarry Smith   of the MatSetValues() operation.
116327a8da17SBarry Smith 
116427a8da17SBarry Smith     You MUST have set the correct numbers of nonzeros per row in the call to
116527a8da17SBarry Smith   MatCreateSeqBAIJ().
116627a8da17SBarry Smith 
116727a8da17SBarry Smith     MUST be called before any calls to MatSetValues();
116827a8da17SBarry Smith 
116927a8da17SBarry Smith @*/
117027a8da17SBarry Smith int MatSeqBAIJSetColumnIndices(Mat mat,int *indices)
117127a8da17SBarry Smith {
117227a8da17SBarry Smith   int ierr,(*f)(Mat,int *);
117327a8da17SBarry Smith 
117427a8da17SBarry Smith   PetscFunctionBegin;
117527a8da17SBarry Smith   PetscValidHeaderSpecific(mat,MAT_COOKIE);
117627a8da17SBarry Smith   ierr = PetscObjectQueryFunction((PetscObject)mat,"MatSeqBAIJSetColumnIndices_C",(void **)&f);
117727a8da17SBarry Smith          CHKERRQ(ierr);
117827a8da17SBarry Smith   if (f) {
117927a8da17SBarry Smith     ierr = (*f)(mat,indices);CHKERRQ(ierr);
118027a8da17SBarry Smith   } else {
118127a8da17SBarry Smith     SETERRQ(1,1,"Wrong type of matrix to set column indices");
118227a8da17SBarry Smith   }
118327a8da17SBarry Smith   PetscFunctionReturn(0);
118427a8da17SBarry Smith }
118527a8da17SBarry Smith 
11862593348eSBarry Smith /* -------------------------------------------------------------------*/
1187cc2dc46cSBarry Smith static struct _MatOps MatOps_Values = {MatSetValues_SeqBAIJ,
1188cc2dc46cSBarry Smith        MatGetRow_SeqBAIJ,
1189cc2dc46cSBarry Smith        MatRestoreRow_SeqBAIJ,
1190cc2dc46cSBarry Smith        MatMult_SeqBAIJ_N,
1191cc2dc46cSBarry Smith        MatMultAdd_SeqBAIJ_N,
1192cc2dc46cSBarry Smith        MatMultTrans_SeqBAIJ,
1193cc2dc46cSBarry Smith        MatMultTransAdd_SeqBAIJ,
1194cc2dc46cSBarry Smith        MatSolve_SeqBAIJ_N,
1195cc2dc46cSBarry Smith        0,
1196cc2dc46cSBarry Smith        0,
1197cc2dc46cSBarry Smith        0,
1198cc2dc46cSBarry Smith        MatLUFactor_SeqBAIJ,
1199cc2dc46cSBarry Smith        0,
1200b6490206SBarry Smith        0,
1201f2501298SSatish Balay        MatTranspose_SeqBAIJ,
1202cc2dc46cSBarry Smith        MatGetInfo_SeqBAIJ,
1203cc2dc46cSBarry Smith        MatEqual_SeqBAIJ,
1204cc2dc46cSBarry Smith        MatGetDiagonal_SeqBAIJ,
1205cc2dc46cSBarry Smith        MatDiagonalScale_SeqBAIJ,
1206cc2dc46cSBarry Smith        MatNorm_SeqBAIJ,
1207b6490206SBarry Smith        0,
1208cc2dc46cSBarry Smith        MatAssemblyEnd_SeqBAIJ,
1209cc2dc46cSBarry Smith        0,
1210cc2dc46cSBarry Smith        MatSetOption_SeqBAIJ,
1211cc2dc46cSBarry Smith        MatZeroEntries_SeqBAIJ,
1212cc2dc46cSBarry Smith        MatZeroRows_SeqBAIJ,
1213cc2dc46cSBarry Smith        MatLUFactorSymbolic_SeqBAIJ,
1214cc2dc46cSBarry Smith        MatLUFactorNumeric_SeqBAIJ_N,
1215cc2dc46cSBarry Smith        0,
1216cc2dc46cSBarry Smith        0,
1217cc2dc46cSBarry Smith        MatGetSize_SeqBAIJ,
1218cc2dc46cSBarry Smith        MatGetSize_SeqBAIJ,
1219cc2dc46cSBarry Smith        MatGetOwnershipRange_SeqBAIJ,
1220cc2dc46cSBarry Smith        MatILUFactorSymbolic_SeqBAIJ,
1221cc2dc46cSBarry Smith        0,
1222cc2dc46cSBarry Smith        0,
1223cc2dc46cSBarry Smith        0,
12242e8a6d31SBarry Smith        MatDuplicate_SeqBAIJ,
1225cc2dc46cSBarry Smith        0,
1226cc2dc46cSBarry Smith        0,
1227cc2dc46cSBarry Smith        MatILUFactor_SeqBAIJ,
1228cc2dc46cSBarry Smith        0,
1229cc2dc46cSBarry Smith        0,
1230cc2dc46cSBarry Smith        MatGetSubMatrices_SeqBAIJ,
1231cc2dc46cSBarry Smith        MatIncreaseOverlap_SeqBAIJ,
1232cc2dc46cSBarry Smith        MatGetValues_SeqBAIJ,
1233cc2dc46cSBarry Smith        0,
1234cc2dc46cSBarry Smith        MatPrintHelp_SeqBAIJ,
1235cc2dc46cSBarry Smith        MatScale_SeqBAIJ,
1236cc2dc46cSBarry Smith        0,
1237cc2dc46cSBarry Smith        0,
1238cc2dc46cSBarry Smith        0,
1239cc2dc46cSBarry Smith        MatGetBlockSize_SeqBAIJ,
12403b2fbd54SBarry Smith        MatGetRowIJ_SeqBAIJ,
124192c4ed94SBarry Smith        MatRestoreRowIJ_SeqBAIJ,
1242cc2dc46cSBarry Smith        0,
1243cc2dc46cSBarry Smith        0,
1244cc2dc46cSBarry Smith        0,
1245cc2dc46cSBarry Smith        0,
1246cc2dc46cSBarry Smith        0,
1247cc2dc46cSBarry Smith        0,
1248d3825aa8SBarry Smith        MatSetValuesBlocked_SeqBAIJ,
1249cc2dc46cSBarry Smith        MatGetSubMatrix_SeqBAIJ,
1250cc2dc46cSBarry Smith        0,
1251cc2dc46cSBarry Smith        0,
1252cc2dc46cSBarry Smith        MatGetMaps_Petsc};
12532593348eSBarry Smith 
12545615d1e5SSatish Balay #undef __FUNC__
12555615d1e5SSatish Balay #define __FUNC__ "MatCreateSeqBAIJ"
12562593348eSBarry Smith /*@C
125744cd7ae7SLois Curfman McInnes    MatCreateSeqBAIJ - Creates a sparse matrix in block AIJ (block
125844cd7ae7SLois Curfman McInnes    compressed row) format.  For good matrix assembly performance the
125944cd7ae7SLois Curfman McInnes    user should preallocate the matrix storage by setting the parameter nz
12602bd5e0b2SLois Curfman McInnes    (or the array nzz).  By setting these parameters accurately, performance
12612bd5e0b2SLois Curfman McInnes    during matrix assembly can be increased by more than a factor of 50.
12622593348eSBarry Smith 
1263db81eaa0SLois Curfman McInnes    Collective on MPI_Comm
1264db81eaa0SLois Curfman McInnes 
12652593348eSBarry Smith    Input Parameters:
1266db81eaa0SLois Curfman McInnes +  comm - MPI communicator, set to PETSC_COMM_SELF
1267b6490206SBarry Smith .  bs - size of block
12682593348eSBarry Smith .  m - number of rows
12692593348eSBarry Smith .  n - number of columns
1270b6490206SBarry Smith .  nz - number of block nonzeros per block row (same for all rows)
1271db81eaa0SLois Curfman McInnes -  nzz - array containing the number of block nonzeros in the various block rows
12722bd5e0b2SLois Curfman McInnes          (possibly different for each block row) or PETSC_NULL
12732593348eSBarry Smith 
12742593348eSBarry Smith    Output Parameter:
12752593348eSBarry Smith .  A - the matrix
12762593348eSBarry Smith 
12770513a670SBarry Smith    Options Database Keys:
1278db81eaa0SLois Curfman McInnes .   -mat_no_unroll - uses code that does not unroll the loops in the
1279db81eaa0SLois Curfman McInnes                      block calculations (much slower)
1280db81eaa0SLois Curfman McInnes .    -mat_block_size - size of the blocks to use
12810513a670SBarry Smith 
12822593348eSBarry Smith    Notes:
128344cd7ae7SLois Curfman McInnes    The block AIJ format is fully compatible with standard Fortran 77
12842593348eSBarry Smith    storage.  That is, the stored row and column indices can begin at
128544cd7ae7SLois Curfman McInnes    either one (as in Fortran) or zero.  See the users' manual for details.
12862593348eSBarry Smith 
12872593348eSBarry Smith    Specify the preallocated storage with either nz or nnz (not both).
12882593348eSBarry Smith    Set nz=PETSC_DEFAULT and nnz=PETSC_NULL for PETSc to control dynamic memory
12892593348eSBarry Smith    allocation.  For additional details, see the users manual chapter on
12906da5968aSLois Curfman McInnes    matrices.
12912593348eSBarry Smith 
1292db81eaa0SLois Curfman McInnes .seealso: MatCreate(), MatCreateSeqAIJ(), MatSetValues(), MatCreateMPIBAIJ()
12932593348eSBarry Smith @*/
1294b6490206SBarry Smith int MatCreateSeqBAIJ(MPI_Comm comm,int bs,int m,int n,int nz,int *nnz, Mat *A)
12952593348eSBarry Smith {
12962593348eSBarry Smith   Mat         B;
1297b6490206SBarry Smith   Mat_SeqBAIJ *b;
12983b2fbd54SBarry Smith   int         i,len,ierr,flg,mbs=m/bs,nbs=n/bs,bs2=bs*bs,size;
12993b2fbd54SBarry Smith 
13003a40ed3dSBarry Smith   PetscFunctionBegin;
13013b2fbd54SBarry Smith   MPI_Comm_size(comm,&size);
1302a8c6a408SBarry Smith   if (size > 1) SETERRQ(PETSC_ERR_ARG_WRONG,0,"Comm must be of size 1");
1303b6490206SBarry Smith 
13040513a670SBarry Smith   ierr = OptionsGetInt(PETSC_NULL,"-mat_block_size",&bs,&flg);CHKERRQ(ierr);
13050513a670SBarry Smith 
13063a40ed3dSBarry Smith   if (mbs*bs!=m || nbs*bs!=n) {
1307a8c6a408SBarry Smith     SETERRQ(PETSC_ERR_ARG_SIZ,0,"Number rows, cols must be divisible by blocksize");
13083a40ed3dSBarry Smith   }
13092593348eSBarry Smith 
13102593348eSBarry Smith   *A = 0;
1311f830108cSBarry Smith   PetscHeaderCreate(B,_p_Mat,struct _MatOps,MAT_COOKIE,MATSEQBAIJ,comm,MatDestroy,MatView);
13122593348eSBarry Smith   PLogObjectCreate(B);
1313b6490206SBarry Smith   B->data = (void *) (b = PetscNew(Mat_SeqBAIJ)); CHKPTRQ(b);
131444cd7ae7SLois Curfman McInnes   PetscMemzero(b,sizeof(Mat_SeqBAIJ));
1315cc2dc46cSBarry Smith   PetscMemcpy(B->ops,&MatOps_Values,sizeof(struct _MatOps));
13161a6a6d98SBarry Smith   ierr = OptionsHasName(PETSC_NULL,"-mat_no_unroll",&flg); CHKERRQ(ierr);
13171a6a6d98SBarry Smith   if (!flg) {
13187fc0212eSBarry Smith     switch (bs) {
13197fc0212eSBarry Smith     case 1:
1320f830108cSBarry Smith       B->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_1;
1321f830108cSBarry Smith       B->ops->solve           = MatSolve_SeqBAIJ_1;
1322f830108cSBarry Smith       B->ops->mult            = MatMult_SeqBAIJ_1;
1323f830108cSBarry Smith       B->ops->multadd         = MatMultAdd_SeqBAIJ_1;
13247fc0212eSBarry Smith       break;
13254eeb42bcSBarry Smith     case 2:
1326f830108cSBarry Smith       B->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_2;
1327f830108cSBarry Smith       B->ops->solve           = MatSolve_SeqBAIJ_2;
1328f830108cSBarry Smith       B->ops->mult            = MatMult_SeqBAIJ_2;
1329f830108cSBarry Smith       B->ops->multadd         = MatMultAdd_SeqBAIJ_2;
13306d84be18SBarry Smith       break;
1331f327dd97SBarry Smith     case 3:
1332f830108cSBarry Smith       B->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_3;
1333f830108cSBarry Smith       B->ops->solve           = MatSolve_SeqBAIJ_3;
1334f830108cSBarry Smith       B->ops->mult            = MatMult_SeqBAIJ_3;
1335f830108cSBarry Smith       B->ops->multadd         = MatMultAdd_SeqBAIJ_3;
13364eeb42bcSBarry Smith       break;
13376d84be18SBarry Smith     case 4:
1338f830108cSBarry Smith       B->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_4;
1339f830108cSBarry Smith       B->ops->solve           = MatSolve_SeqBAIJ_4;
1340f830108cSBarry Smith       B->ops->mult            = MatMult_SeqBAIJ_4;
1341f830108cSBarry Smith       B->ops->multadd         = MatMultAdd_SeqBAIJ_4;
13426d84be18SBarry Smith       break;
13436d84be18SBarry Smith     case 5:
1344f830108cSBarry Smith       B->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_5;
1345f830108cSBarry Smith       B->ops->solve           = MatSolve_SeqBAIJ_5;
1346f830108cSBarry Smith       B->ops->mult            = MatMult_SeqBAIJ_5;
1347f830108cSBarry Smith       B->ops->multadd         = MatMultAdd_SeqBAIJ_5;
13486d84be18SBarry Smith       break;
134948e9ddb2SSatish Balay     case 7:
1350f830108cSBarry Smith       B->ops->mult            = MatMult_SeqBAIJ_7;
1351f830108cSBarry Smith       B->ops->solve           = MatSolve_SeqBAIJ_7;
1352f830108cSBarry Smith       B->ops->multadd         = MatMultAdd_SeqBAIJ_7;
135348e9ddb2SSatish Balay       break;
13547fc0212eSBarry Smith     }
13551a6a6d98SBarry Smith   }
1356e1311b90SBarry Smith   B->ops->destroy     = MatDestroy_SeqBAIJ;
1357e1311b90SBarry Smith   B->ops->view        = MatView_SeqBAIJ;
13582593348eSBarry Smith   B->factor           = 0;
13592593348eSBarry Smith   B->lupivotthreshold = 1.0;
136090f02eecSBarry Smith   B->mapping          = 0;
13612593348eSBarry Smith   b->row              = 0;
13622593348eSBarry Smith   b->col              = 0;
1363e51c0b9cSSatish Balay   b->icol             = 0;
13642593348eSBarry Smith   b->reallocs         = 0;
13652593348eSBarry Smith 
136644cd7ae7SLois Curfman McInnes   b->m       = m; B->m = m; B->M = m;
136744cd7ae7SLois Curfman McInnes   b->n       = n; B->n = n; B->N = n;
1368a5ae1ecdSBarry Smith 
13697413bad6SBarry Smith   ierr = MapCreateMPI(comm,m,m,&B->rmap);CHKERRQ(ierr);
13707413bad6SBarry Smith   ierr = MapCreateMPI(comm,n,n,&B->cmap);CHKERRQ(ierr);
1371a5ae1ecdSBarry Smith 
1372b6490206SBarry Smith   b->mbs     = mbs;
1373f2501298SSatish Balay   b->nbs     = nbs;
1374b6490206SBarry Smith   b->imax    = (int *) PetscMalloc( (mbs+1)*sizeof(int) ); CHKPTRQ(b->imax);
13752593348eSBarry Smith   if (nnz == PETSC_NULL) {
1376119a934aSSatish Balay     if (nz == PETSC_DEFAULT) nz = 5;
13772593348eSBarry Smith     else if (nz <= 0)        nz = 1;
1378b6490206SBarry Smith     for ( i=0; i<mbs; i++ ) b->imax[i] = nz;
1379b6490206SBarry Smith     nz = nz*mbs;
13803a40ed3dSBarry Smith   } else {
13812593348eSBarry Smith     nz = 0;
1382b6490206SBarry Smith     for ( i=0; i<mbs; i++ ) {b->imax[i] = nnz[i]; nz += nnz[i];}
13832593348eSBarry Smith   }
13842593348eSBarry Smith 
13852593348eSBarry Smith   /* allocate the matrix space */
13867e67e3f9SSatish Balay   len   = nz*sizeof(int) + nz*bs2*sizeof(Scalar) + (b->m+1)*sizeof(int);
13872593348eSBarry Smith   b->a  = (Scalar *) PetscMalloc( len ); CHKPTRQ(b->a);
13887e67e3f9SSatish Balay   PetscMemzero(b->a,nz*bs2*sizeof(Scalar));
13897e67e3f9SSatish Balay   b->j  = (int *) (b->a + nz*bs2);
13902593348eSBarry Smith   PetscMemzero(b->j,nz*sizeof(int));
13912593348eSBarry Smith   b->i  = b->j + nz;
13922593348eSBarry Smith   b->singlemalloc = 1;
13932593348eSBarry Smith 
1394de6a44a3SBarry Smith   b->i[0] = 0;
1395b6490206SBarry Smith   for (i=1; i<mbs+1; i++) {
13962593348eSBarry Smith     b->i[i] = b->i[i-1] + b->imax[i-1];
13972593348eSBarry Smith   }
13982593348eSBarry Smith 
1399b6490206SBarry Smith   /* b->ilen will count nonzeros in each block row so far. */
1400b6490206SBarry Smith   b->ilen = (int *) PetscMalloc((mbs+1)*sizeof(int));
1401f09e8eb9SSatish Balay   PLogObjectMemory(B,len+2*(mbs+1)*sizeof(int)+sizeof(struct _p_Mat)+sizeof(Mat_SeqBAIJ));
1402b6490206SBarry Smith   for ( i=0; i<mbs; i++ ) { b->ilen[i] = 0;}
14032593348eSBarry Smith 
1404b6490206SBarry Smith   b->bs               = bs;
14059df24120SSatish Balay   b->bs2              = bs2;
1406b6490206SBarry Smith   b->mbs              = mbs;
14072593348eSBarry Smith   b->nz               = 0;
140818e7b8e4SLois Curfman McInnes   b->maxnz            = nz*bs2;
14092593348eSBarry Smith   b->sorted           = 0;
14102593348eSBarry Smith   b->roworiented      = 1;
14112593348eSBarry Smith   b->nonew            = 0;
14122593348eSBarry Smith   b->diag             = 0;
14132593348eSBarry Smith   b->solve_work       = 0;
1414de6a44a3SBarry Smith   b->mult_work        = 0;
14152593348eSBarry Smith   b->spptr            = 0;
14164e220ebcSLois Curfman McInnes   B->info.nz_unneeded = (double)b->maxnz;
14174e220ebcSLois Curfman McInnes 
14182593348eSBarry Smith   *A = B;
14192593348eSBarry Smith   ierr = OptionsHasName(PETSC_NULL,"-help", &flg); CHKERRQ(ierr);
14202593348eSBarry Smith   if (flg) {ierr = MatPrintHelp(B); CHKERRQ(ierr); }
142127a8da17SBarry Smith 
142227a8da17SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatSeqBAIJSetColumnIndices_C",
142327a8da17SBarry Smith                                      "MatSeqBAIJSetColumnIndices_SeqBAIJ",
142427a8da17SBarry Smith                                      (void*)MatSeqBAIJSetColumnIndices_SeqBAIJ);CHKERRQ(ierr);
142527a8da17SBarry Smith 
14263a40ed3dSBarry Smith   PetscFunctionReturn(0);
14272593348eSBarry Smith }
14282593348eSBarry Smith 
14295615d1e5SSatish Balay #undef __FUNC__
14302e8a6d31SBarry Smith #define __FUNC__ "MatDuplicate_SeqBAIJ"
14312e8a6d31SBarry Smith int MatDuplicate_SeqBAIJ(Mat A,MatDuplicateOption cpvalues,Mat *B)
14322593348eSBarry Smith {
14332593348eSBarry Smith   Mat         C;
1434b6490206SBarry Smith   Mat_SeqBAIJ *c,*a = (Mat_SeqBAIJ *) A->data;
143527a8da17SBarry Smith   int         i,len, mbs = a->mbs,nz = a->nz,bs2 =a->bs2,ierr;
1436de6a44a3SBarry Smith 
14373a40ed3dSBarry Smith   PetscFunctionBegin;
1438a8c6a408SBarry Smith   if (a->i[mbs] != nz) SETERRQ(PETSC_ERR_PLIB,0,"Corrupt matrix");
14392593348eSBarry Smith 
14402593348eSBarry Smith   *B = 0;
1441f830108cSBarry Smith   PetscHeaderCreate(C,_p_Mat,struct _MatOps,MAT_COOKIE,MATSEQBAIJ,A->comm,MatDestroy,MatView);
14422593348eSBarry Smith   PLogObjectCreate(C);
1443b6490206SBarry Smith   C->data       = (void *) (c = PetscNew(Mat_SeqBAIJ)); CHKPTRQ(c);
1444c3c66ee5SSatish Balay   PetscMemcpy(C->ops,A->ops,sizeof(struct _MatOps));
1445e1311b90SBarry Smith   C->ops->destroy    = MatDestroy_SeqBAIJ;
1446e1311b90SBarry Smith   C->ops->view       = MatView_SeqBAIJ;
14472593348eSBarry Smith   C->factor          = A->factor;
14482593348eSBarry Smith   c->row             = 0;
14492593348eSBarry Smith   c->col             = 0;
14502593348eSBarry Smith   C->assembled       = PETSC_TRUE;
14512593348eSBarry Smith 
145244cd7ae7SLois Curfman McInnes   c->m = C->m   = a->m;
145344cd7ae7SLois Curfman McInnes   c->n = C->n   = a->n;
145444cd7ae7SLois Curfman McInnes   C->M          = a->m;
145544cd7ae7SLois Curfman McInnes   C->N          = a->n;
145644cd7ae7SLois Curfman McInnes 
1457b6490206SBarry Smith   c->bs         = a->bs;
14589df24120SSatish Balay   c->bs2        = a->bs2;
1459b6490206SBarry Smith   c->mbs        = a->mbs;
1460b6490206SBarry Smith   c->nbs        = a->nbs;
14612593348eSBarry Smith 
1462b6490206SBarry Smith   c->imax       = (int *) PetscMalloc((mbs+1)*sizeof(int)); CHKPTRQ(c->imax);
1463b6490206SBarry Smith   c->ilen       = (int *) PetscMalloc((mbs+1)*sizeof(int)); CHKPTRQ(c->ilen);
1464b6490206SBarry Smith   for ( i=0; i<mbs; i++ ) {
14652593348eSBarry Smith     c->imax[i] = a->imax[i];
14662593348eSBarry Smith     c->ilen[i] = a->ilen[i];
14672593348eSBarry Smith   }
14682593348eSBarry Smith 
14692593348eSBarry Smith   /* allocate the matrix space */
14702593348eSBarry Smith   c->singlemalloc = 1;
14717e67e3f9SSatish Balay   len   = (mbs+1)*sizeof(int) + nz*(bs2*sizeof(Scalar) + sizeof(int));
14722593348eSBarry Smith   c->a  = (Scalar *) PetscMalloc( len ); CHKPTRQ(c->a);
14737e67e3f9SSatish Balay   c->j  = (int *) (c->a + nz*bs2);
1474de6a44a3SBarry Smith   c->i  = c->j + nz;
1475b6490206SBarry Smith   PetscMemcpy(c->i,a->i,(mbs+1)*sizeof(int));
1476b6490206SBarry Smith   if (mbs > 0) {
1477de6a44a3SBarry Smith     PetscMemcpy(c->j,a->j,nz*sizeof(int));
14782e8a6d31SBarry Smith     if (cpvalues == MAT_COPY_VALUES) {
14797e67e3f9SSatish Balay       PetscMemcpy(c->a,a->a,bs2*nz*sizeof(Scalar));
14802e8a6d31SBarry Smith     } else {
14812e8a6d31SBarry Smith       PetscMemzero(c->a,bs2*nz*sizeof(Scalar));
14822593348eSBarry Smith     }
14832593348eSBarry Smith   }
14842593348eSBarry Smith 
1485f09e8eb9SSatish Balay   PLogObjectMemory(C,len+2*(mbs+1)*sizeof(int)+sizeof(struct _p_Mat)+sizeof(Mat_SeqBAIJ));
14862593348eSBarry Smith   c->sorted      = a->sorted;
14872593348eSBarry Smith   c->roworiented = a->roworiented;
14882593348eSBarry Smith   c->nonew       = a->nonew;
14892593348eSBarry Smith 
14902593348eSBarry Smith   if (a->diag) {
1491b6490206SBarry Smith     c->diag = (int *) PetscMalloc( (mbs+1)*sizeof(int) ); CHKPTRQ(c->diag);
1492b6490206SBarry Smith     PLogObjectMemory(C,(mbs+1)*sizeof(int));
1493b6490206SBarry Smith     for ( i=0; i<mbs; i++ ) {
14942593348eSBarry Smith       c->diag[i] = a->diag[i];
14952593348eSBarry Smith     }
14962593348eSBarry Smith   }
14972593348eSBarry Smith   else c->diag          = 0;
14982593348eSBarry Smith   c->nz                 = a->nz;
14992593348eSBarry Smith   c->maxnz              = a->maxnz;
15002593348eSBarry Smith   c->solve_work         = 0;
15012593348eSBarry Smith   c->spptr              = 0;      /* Dangerous -I'm throwing away a->spptr */
15027fc0212eSBarry Smith   c->mult_work          = 0;
15032593348eSBarry Smith   *B = C;
150427a8da17SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)C,"MatSeqBAIJSetColumnIndices_C",
150527a8da17SBarry Smith                                      "MatSeqBAIJSetColumnIndices_SeqBAIJ",
150627a8da17SBarry Smith                                      (void*)MatSeqBAIJSetColumnIndices_SeqBAIJ);CHKERRQ(ierr);
15073a40ed3dSBarry Smith   PetscFunctionReturn(0);
15082593348eSBarry Smith }
15092593348eSBarry Smith 
15105615d1e5SSatish Balay #undef __FUNC__
15115615d1e5SSatish Balay #define __FUNC__ "MatLoad_SeqBAIJ"
151219bcc07fSBarry Smith int MatLoad_SeqBAIJ(Viewer viewer,MatType type,Mat *A)
15132593348eSBarry Smith {
1514b6490206SBarry Smith   Mat_SeqBAIJ  *a;
15152593348eSBarry Smith   Mat          B;
1516de6a44a3SBarry Smith   int          i,nz,ierr,fd,header[4],size,*rowlengths=0,M,N,bs=1,flg;
1517b6490206SBarry Smith   int          *mask,mbs,*jj,j,rowcount,nzcount,k,*browlengths,maskcount;
151835aab85fSBarry Smith   int          kmax,jcount,block,idx,point,nzcountb,extra_rows;
1519a7c10996SSatish Balay   int          *masked, nmask,tmp,bs2,ishift;
1520b6490206SBarry Smith   Scalar       *aa;
152119bcc07fSBarry Smith   MPI_Comm     comm = ((PetscObject) viewer)->comm;
15222593348eSBarry Smith 
15233a40ed3dSBarry Smith   PetscFunctionBegin;
15241a6a6d98SBarry Smith   ierr = OptionsGetInt(PETSC_NULL,"-matload_block_size",&bs,&flg);CHKERRQ(ierr);
1525de6a44a3SBarry Smith   bs2  = bs*bs;
1526b6490206SBarry Smith 
15272593348eSBarry Smith   MPI_Comm_size(comm,&size);
1528cc0fae11SBarry Smith   if (size > 1) SETERRQ(PETSC_ERR_ARG_WRONG,0,"view must have one processor");
152990ace30eSBarry Smith   ierr = ViewerBinaryGetDescriptor(viewer,&fd); CHKERRQ(ierr);
15300752156aSBarry Smith   ierr = PetscBinaryRead(fd,header,4,PETSC_INT); CHKERRQ(ierr);
1531a8c6a408SBarry Smith   if (header[0] != MAT_COOKIE) SETERRQ(PETSC_ERR_FILE_UNEXPECTED,0,"not Mat object");
15322593348eSBarry Smith   M = header[1]; N = header[2]; nz = header[3];
15332593348eSBarry Smith 
1534d64ed03dSBarry Smith   if (header[3] < 0) {
1535a8c6a408SBarry Smith     SETERRQ(PETSC_ERR_FILE_UNEXPECTED,1,"Matrix stored in special format, cannot load as SeqBAIJ");
1536d64ed03dSBarry Smith   }
1537d64ed03dSBarry Smith 
1538a8c6a408SBarry Smith   if (M != N) SETERRQ(PETSC_ERR_SUP,0,"Can only do square matrices");
153935aab85fSBarry Smith 
154035aab85fSBarry Smith   /*
154135aab85fSBarry Smith      This code adds extra rows to make sure the number of rows is
154235aab85fSBarry Smith     divisible by the blocksize
154335aab85fSBarry Smith   */
1544b6490206SBarry Smith   mbs        = M/bs;
154535aab85fSBarry Smith   extra_rows = bs - M + bs*(mbs);
154635aab85fSBarry Smith   if (extra_rows == bs) extra_rows = 0;
154735aab85fSBarry Smith   else                  mbs++;
154835aab85fSBarry Smith   if (extra_rows) {
1549537820f0SBarry Smith     PLogInfo(0,"MatLoad_SeqBAIJ:Padding loaded matrix to match blocksize\n");
155035aab85fSBarry Smith   }
1551b6490206SBarry Smith 
15522593348eSBarry Smith   /* read in row lengths */
155335aab85fSBarry Smith   rowlengths = (int*) PetscMalloc((M+extra_rows)*sizeof(int));CHKPTRQ(rowlengths);
15540752156aSBarry Smith   ierr = PetscBinaryRead(fd,rowlengths,M,PETSC_INT); CHKERRQ(ierr);
155535aab85fSBarry Smith   for ( i=0; i<extra_rows; i++ ) rowlengths[M+i] = 1;
15562593348eSBarry Smith 
1557b6490206SBarry Smith   /* read in column indices */
155835aab85fSBarry Smith   jj = (int*) PetscMalloc( (nz+extra_rows)*sizeof(int) ); CHKPTRQ(jj);
15590752156aSBarry Smith   ierr = PetscBinaryRead(fd,jj,nz,PETSC_INT); CHKERRQ(ierr);
156035aab85fSBarry Smith   for ( i=0; i<extra_rows; i++ ) jj[nz+i] = M+i;
1561b6490206SBarry Smith 
1562b6490206SBarry Smith   /* loop over row lengths determining block row lengths */
1563b6490206SBarry Smith   browlengths = (int *) PetscMalloc(mbs*sizeof(int));CHKPTRQ(browlengths);
1564b6490206SBarry Smith   PetscMemzero(browlengths,mbs*sizeof(int));
156535aab85fSBarry Smith   mask   = (int *) PetscMalloc( 2*mbs*sizeof(int) ); CHKPTRQ(mask);
156635aab85fSBarry Smith   PetscMemzero(mask,mbs*sizeof(int));
156735aab85fSBarry Smith   masked = mask + mbs;
1568b6490206SBarry Smith   rowcount = 0; nzcount = 0;
1569b6490206SBarry Smith   for ( i=0; i<mbs; i++ ) {
157035aab85fSBarry Smith     nmask = 0;
1571b6490206SBarry Smith     for ( j=0; j<bs; j++ ) {
1572b6490206SBarry Smith       kmax = rowlengths[rowcount];
1573b6490206SBarry Smith       for ( k=0; k<kmax; k++ ) {
157435aab85fSBarry Smith         tmp = jj[nzcount++]/bs;
157535aab85fSBarry Smith         if (!mask[tmp]) {masked[nmask++] = tmp; mask[tmp] = 1;}
1576b6490206SBarry Smith       }
1577b6490206SBarry Smith       rowcount++;
1578b6490206SBarry Smith     }
157935aab85fSBarry Smith     browlengths[i] += nmask;
158035aab85fSBarry Smith     /* zero out the mask elements we set */
158135aab85fSBarry Smith     for ( j=0; j<nmask; j++ ) mask[masked[j]] = 0;
1582b6490206SBarry Smith   }
1583b6490206SBarry Smith 
15842593348eSBarry Smith   /* create our matrix */
15853eee16b0SBarry Smith   ierr = MatCreateSeqBAIJ(comm,bs,M+extra_rows,N+extra_rows,0,browlengths,A);CHKERRQ(ierr);
15862593348eSBarry Smith   B = *A;
1587b6490206SBarry Smith   a = (Mat_SeqBAIJ *) B->data;
15882593348eSBarry Smith 
15892593348eSBarry Smith   /* set matrix "i" values */
1590de6a44a3SBarry Smith   a->i[0] = 0;
1591b6490206SBarry Smith   for ( i=1; i<= mbs; i++ ) {
1592b6490206SBarry Smith     a->i[i]      = a->i[i-1] + browlengths[i-1];
1593b6490206SBarry Smith     a->ilen[i-1] = browlengths[i-1];
15942593348eSBarry Smith   }
1595b6490206SBarry Smith   a->nz         = 0;
1596b6490206SBarry Smith   for ( i=0; i<mbs; i++ ) a->nz += browlengths[i];
15972593348eSBarry Smith 
1598b6490206SBarry Smith   /* read in nonzero values */
159935aab85fSBarry Smith   aa = (Scalar *) PetscMalloc((nz+extra_rows)*sizeof(Scalar));CHKPTRQ(aa);
16000752156aSBarry Smith   ierr = PetscBinaryRead(fd,aa,nz,PETSC_SCALAR); CHKERRQ(ierr);
160135aab85fSBarry Smith   for ( i=0; i<extra_rows; i++ ) aa[nz+i] = 1.0;
1602b6490206SBarry Smith 
1603b6490206SBarry Smith   /* set "a" and "j" values into matrix */
1604b6490206SBarry Smith   nzcount = 0; jcount = 0;
1605b6490206SBarry Smith   for ( i=0; i<mbs; i++ ) {
1606b6490206SBarry Smith     nzcountb = nzcount;
160735aab85fSBarry Smith     nmask    = 0;
1608b6490206SBarry Smith     for ( j=0; j<bs; j++ ) {
1609b6490206SBarry Smith       kmax = rowlengths[i*bs+j];
1610b6490206SBarry Smith       for ( k=0; k<kmax; k++ ) {
161135aab85fSBarry Smith         tmp = jj[nzcount++]/bs;
161235aab85fSBarry Smith 	if (!mask[tmp]) { masked[nmask++] = tmp; mask[tmp] = 1;}
1613b6490206SBarry Smith       }
1614b6490206SBarry Smith       rowcount++;
1615b6490206SBarry Smith     }
1616de6a44a3SBarry Smith     /* sort the masked values */
161777c4ece6SBarry Smith     PetscSortInt(nmask,masked);
1618de6a44a3SBarry Smith 
1619b6490206SBarry Smith     /* set "j" values into matrix */
1620b6490206SBarry Smith     maskcount = 1;
162135aab85fSBarry Smith     for ( j=0; j<nmask; j++ ) {
162235aab85fSBarry Smith       a->j[jcount++]  = masked[j];
1623de6a44a3SBarry Smith       mask[masked[j]] = maskcount++;
1624b6490206SBarry Smith     }
1625b6490206SBarry Smith     /* set "a" values into matrix */
1626de6a44a3SBarry Smith     ishift = bs2*a->i[i];
1627b6490206SBarry Smith     for ( j=0; j<bs; j++ ) {
1628b6490206SBarry Smith       kmax = rowlengths[i*bs+j];
1629b6490206SBarry Smith       for ( k=0; k<kmax; k++ ) {
1630de6a44a3SBarry Smith         tmp    = jj[nzcountb]/bs ;
1631de6a44a3SBarry Smith         block  = mask[tmp] - 1;
1632de6a44a3SBarry Smith         point  = jj[nzcountb] - bs*tmp;
1633de6a44a3SBarry Smith         idx    = ishift + bs2*block + j + bs*point;
1634b6490206SBarry Smith         a->a[idx] = aa[nzcountb++];
1635b6490206SBarry Smith       }
1636b6490206SBarry Smith     }
163735aab85fSBarry Smith     /* zero out the mask elements we set */
163835aab85fSBarry Smith     for ( j=0; j<nmask; j++ ) mask[masked[j]] = 0;
1639b6490206SBarry Smith   }
1640a8c6a408SBarry Smith   if (jcount != a->nz) SETERRQ(PETSC_ERR_FILE_UNEXPECTED,0,"Bad binary matrix");
1641b6490206SBarry Smith 
1642b6490206SBarry Smith   PetscFree(rowlengths);
1643b6490206SBarry Smith   PetscFree(browlengths);
1644b6490206SBarry Smith   PetscFree(aa);
1645b6490206SBarry Smith   PetscFree(jj);
1646b6490206SBarry Smith   PetscFree(mask);
1647b6490206SBarry Smith 
1648b6490206SBarry Smith   B->assembled = PETSC_TRUE;
1649de6a44a3SBarry Smith 
16509c01be13SBarry Smith   ierr = MatView_Private(B); CHKERRQ(ierr);
16513a40ed3dSBarry Smith   PetscFunctionReturn(0);
16522593348eSBarry Smith }
16532593348eSBarry Smith 
16542593348eSBarry Smith 
16552593348eSBarry Smith 
1656