xref: /petsc/src/mat/impls/baij/seq/baij.c (revision a5ae1ecdc7f32e56ab356dfc0ee0d859f7614a9d)
1a5eb4965SSatish Balay #ifdef PETSC_RCS_HEADER
2*a5ae1ecdSBarry Smith static char vcid[] = "$Id: baij.c,v 1.140 1998/07/14 02:38:13 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 
103369ce9aSBarry Smith #include "pinclude/pviewer.h"
113369ce9aSBarry Smith #include "sys.h"
1270f55243SBarry Smith #include "src/mat/impls/baij/seq/baij.h"
131a6a6d98SBarry Smith #include "src/vec/vecimpl.h"
141a6a6d98SBarry Smith #include "src/inline/spops.h"
152593348eSBarry Smith #include "petsc.h"
163b547af2SSatish Balay 
172d61bbb3SSatish Balay #define CHUNKSIZE  10
18de6a44a3SBarry Smith 
195615d1e5SSatish Balay #undef __FUNC__
205615d1e5SSatish Balay #define __FUNC__ "MatMarkDiag_SeqBAIJ"
21de6a44a3SBarry Smith int MatMarkDiag_SeqBAIJ(Mat A)
22de6a44a3SBarry Smith {
23de6a44a3SBarry Smith   Mat_SeqBAIJ *a = (Mat_SeqBAIJ *) A->data;
247fc0212eSBarry Smith   int         i,j, *diag, m = a->mbs;
25de6a44a3SBarry Smith 
263a40ed3dSBarry Smith   PetscFunctionBegin;
27de6a44a3SBarry Smith   diag = (int *) PetscMalloc( (m+1)*sizeof(int)); CHKPTRQ(diag);
28de6a44a3SBarry Smith   PLogObjectMemory(A,(m+1)*sizeof(int));
297fc0212eSBarry Smith   for ( i=0; i<m; i++ ) {
30de6a44a3SBarry Smith     for ( j=a->i[i]; j<a->i[i+1]; j++ ) {
31de6a44a3SBarry Smith       if (a->j[j] == i) {
32de6a44a3SBarry Smith         diag[i] = j;
33de6a44a3SBarry Smith         break;
34de6a44a3SBarry Smith       }
35de6a44a3SBarry Smith     }
36de6a44a3SBarry Smith   }
37de6a44a3SBarry Smith   a->diag = diag;
383a40ed3dSBarry Smith   PetscFunctionReturn(0);
39de6a44a3SBarry Smith }
402593348eSBarry Smith 
412593348eSBarry Smith 
423b2fbd54SBarry Smith extern int MatToSymmetricIJ_SeqAIJ(int,int*,int*,int,int,int**,int**);
433b2fbd54SBarry Smith 
445615d1e5SSatish Balay #undef __FUNC__
455615d1e5SSatish Balay #define __FUNC__ "MatGetRowIJ_SeqBAIJ"
463b2fbd54SBarry Smith static int MatGetRowIJ_SeqBAIJ(Mat A,int oshift,PetscTruth symmetric,int *nn,int **ia,int **ja,
473b2fbd54SBarry Smith                             PetscTruth *done)
483b2fbd54SBarry Smith {
493b2fbd54SBarry Smith   Mat_SeqBAIJ *a = (Mat_SeqBAIJ *) A->data;
503b2fbd54SBarry Smith   int         ierr, n = a->mbs,i;
513b2fbd54SBarry Smith 
523a40ed3dSBarry Smith   PetscFunctionBegin;
533b2fbd54SBarry Smith   *nn = n;
543a40ed3dSBarry Smith   if (!ia) PetscFunctionReturn(0);
553b2fbd54SBarry Smith   if (symmetric) {
563b2fbd54SBarry Smith     ierr = MatToSymmetricIJ_SeqAIJ(n,a->i,a->j,0,oshift,ia,ja);CHKERRQ(ierr);
573b2fbd54SBarry Smith   } else if (oshift == 1) {
583b2fbd54SBarry Smith     /* temporarily add 1 to i and j indices */
593b2fbd54SBarry Smith     int nz = a->i[n] + 1;
603b2fbd54SBarry Smith     for ( i=0; i<nz; i++ ) a->j[i]++;
613b2fbd54SBarry Smith     for ( i=0; i<n+1; i++ ) a->i[i]++;
623b2fbd54SBarry Smith     *ia = a->i; *ja = a->j;
633b2fbd54SBarry Smith   } else {
643b2fbd54SBarry Smith     *ia = a->i; *ja = a->j;
653b2fbd54SBarry Smith   }
663b2fbd54SBarry Smith 
673a40ed3dSBarry Smith   PetscFunctionReturn(0);
683b2fbd54SBarry Smith }
693b2fbd54SBarry Smith 
705615d1e5SSatish Balay #undef __FUNC__
71d4bb536fSBarry Smith #define __FUNC__ "MatRestoreRowIJ_SeqBAIJ"
723b2fbd54SBarry Smith static int MatRestoreRowIJ_SeqBAIJ(Mat A,int oshift,PetscTruth symmetric,int *nn,int **ia,int **ja,
733b2fbd54SBarry Smith                                 PetscTruth *done)
743b2fbd54SBarry Smith {
753b2fbd54SBarry Smith   Mat_SeqBAIJ *a = (Mat_SeqBAIJ *) A->data;
763b2fbd54SBarry Smith   int         i,n = a->mbs;
773b2fbd54SBarry Smith 
783a40ed3dSBarry Smith   PetscFunctionBegin;
793a40ed3dSBarry Smith   if (!ia) PetscFunctionReturn(0);
803b2fbd54SBarry Smith   if (symmetric) {
813b2fbd54SBarry Smith     PetscFree(*ia);
823b2fbd54SBarry Smith     PetscFree(*ja);
83af5da2bfSBarry Smith   } else if (oshift == 1) {
843b2fbd54SBarry Smith     int nz = a->i[n];
853b2fbd54SBarry Smith     for ( i=0; i<nz; i++ ) a->j[i]--;
863b2fbd54SBarry Smith     for ( i=0; i<n+1; i++ ) a->i[i]--;
873b2fbd54SBarry Smith   }
883a40ed3dSBarry Smith   PetscFunctionReturn(0);
893b2fbd54SBarry Smith }
903b2fbd54SBarry Smith 
912d61bbb3SSatish Balay #undef __FUNC__
922d61bbb3SSatish Balay #define __FUNC__ "MatGetBlockSize_SeqBAIJ"
932d61bbb3SSatish Balay int MatGetBlockSize_SeqBAIJ(Mat mat, int *bs)
942d61bbb3SSatish Balay {
952d61bbb3SSatish Balay   Mat_SeqBAIJ *baij = (Mat_SeqBAIJ *) mat->data;
962d61bbb3SSatish Balay 
972d61bbb3SSatish Balay   PetscFunctionBegin;
982d61bbb3SSatish Balay   *bs = baij->bs;
992d61bbb3SSatish Balay   PetscFunctionReturn(0);
1002d61bbb3SSatish Balay }
1012d61bbb3SSatish Balay 
1022d61bbb3SSatish Balay 
1032d61bbb3SSatish Balay #undef __FUNC__
1042d61bbb3SSatish Balay #define __FUNC__ "MatDestroy_SeqBAIJ"
105e1311b90SBarry Smith int MatDestroy_SeqBAIJ(Mat A)
1062d61bbb3SSatish Balay {
1072d61bbb3SSatish Balay   Mat_SeqBAIJ *a = (Mat_SeqBAIJ *) A->data;
108e51c0b9cSSatish Balay   int         ierr;
1092d61bbb3SSatish Balay 
11094d884c6SBarry Smith   if (--A->refct > 0) PetscFunctionReturn(0);
11194d884c6SBarry Smith 
11294d884c6SBarry Smith   if (A->mapping) {
11394d884c6SBarry Smith     ierr = ISLocalToGlobalMappingDestroy(A->mapping); CHKERRQ(ierr);
11494d884c6SBarry Smith   }
11594d884c6SBarry Smith   if (A->bmapping) {
11694d884c6SBarry Smith     ierr = ISLocalToGlobalMappingDestroy(A->bmapping); CHKERRQ(ierr);
11794d884c6SBarry Smith   }
11861b13de0SBarry Smith   if (A->rmap) {
11961b13de0SBarry Smith     ierr = MapDestroy(A->rmap);CHKERRQ(ierr);
12061b13de0SBarry Smith   }
12161b13de0SBarry Smith   if (A->cmap) {
12261b13de0SBarry Smith     ierr = MapDestroy(A->cmap);CHKERRQ(ierr);
12361b13de0SBarry Smith   }
1242d61bbb3SSatish Balay #if defined(USE_PETSC_LOG)
125e1311b90SBarry Smith   PLogObjectState((PetscObject) A,"Rows=%d, Cols=%d, NZ=%d",a->m,a->n,a->nz);
1262d61bbb3SSatish Balay #endif
1272d61bbb3SSatish Balay   PetscFree(a->a);
1282d61bbb3SSatish Balay   if (!a->singlemalloc) { PetscFree(a->i); PetscFree(a->j);}
1292d61bbb3SSatish Balay   if (a->diag) PetscFree(a->diag);
1302d61bbb3SSatish Balay   if (a->ilen) PetscFree(a->ilen);
1312d61bbb3SSatish Balay   if (a->imax) PetscFree(a->imax);
1322d61bbb3SSatish Balay   if (a->solve_work) PetscFree(a->solve_work);
1332d61bbb3SSatish Balay   if (a->mult_work) PetscFree(a->mult_work);
134e51c0b9cSSatish Balay   if (a->icol) {ierr = ISDestroy(a->icol);CHKERRQ(ierr);}
1352d61bbb3SSatish Balay   PetscFree(a);
1362d61bbb3SSatish Balay   PLogObjectDestroy(A);
1372d61bbb3SSatish Balay   PetscHeaderDestroy(A);
1382d61bbb3SSatish Balay   PetscFunctionReturn(0);
1392d61bbb3SSatish Balay }
1402d61bbb3SSatish Balay 
1412d61bbb3SSatish Balay #undef __FUNC__
1422d61bbb3SSatish Balay #define __FUNC__ "MatSetOption_SeqBAIJ"
1432d61bbb3SSatish Balay int MatSetOption_SeqBAIJ(Mat A,MatOption op)
1442d61bbb3SSatish Balay {
1452d61bbb3SSatish Balay   Mat_SeqBAIJ *a = (Mat_SeqBAIJ *) A->data;
1462d61bbb3SSatish Balay 
1472d61bbb3SSatish Balay   PetscFunctionBegin;
1482d61bbb3SSatish Balay   if      (op == MAT_ROW_ORIENTED)                 a->roworiented = 1;
1492d61bbb3SSatish Balay   else if (op == MAT_COLUMN_ORIENTED)              a->roworiented = 0;
1502d61bbb3SSatish Balay   else if (op == MAT_COLUMNS_SORTED)               a->sorted      = 1;
1512d61bbb3SSatish Balay   else if (op == MAT_COLUMNS_UNSORTED)             a->sorted      = 0;
1522d61bbb3SSatish Balay   else if (op == MAT_NO_NEW_NONZERO_LOCATIONS)     a->nonew       = 1;
1532d61bbb3SSatish Balay   else if (op == MAT_NEW_NONZERO_LOCATION_ERROR)   a->nonew       = -1;
1542d61bbb3SSatish Balay   else if (op == MAT_NEW_NONZERO_ALLOCATION_ERROR) a->nonew       = -2;
1552d61bbb3SSatish Balay   else if (op == MAT_YES_NEW_NONZERO_LOCATIONS)    a->nonew       = 0;
1562d61bbb3SSatish Balay   else if (op == MAT_ROWS_SORTED ||
1572d61bbb3SSatish Balay            op == MAT_ROWS_UNSORTED ||
1582d61bbb3SSatish Balay            op == MAT_SYMMETRIC ||
1592d61bbb3SSatish Balay            op == MAT_STRUCTURALLY_SYMMETRIC ||
1602d61bbb3SSatish Balay            op == MAT_YES_NEW_DIAGONALS ||
161b51ba29fSSatish Balay            op == MAT_IGNORE_OFF_PROC_ENTRIES ||
162b51ba29fSSatish Balay            op == MAT_USE_HASH_TABLE) {
163981c4779SBarry Smith     PLogInfo(A,"MatSetOption_SeqBAIJ:Option ignored\n");
1642d61bbb3SSatish Balay   } else if (op == MAT_NO_NEW_DIAGONALS) {
1652d61bbb3SSatish Balay     SETERRQ(PETSC_ERR_SUP,0,"MAT_NO_NEW_DIAGONALS");
1662d61bbb3SSatish Balay   } else {
1672d61bbb3SSatish Balay     SETERRQ(PETSC_ERR_SUP,0,"unknown option");
1682d61bbb3SSatish Balay   }
1692d61bbb3SSatish Balay   PetscFunctionReturn(0);
1702d61bbb3SSatish Balay }
1712d61bbb3SSatish Balay 
1722d61bbb3SSatish Balay 
1732d61bbb3SSatish Balay #undef __FUNC__
1742d61bbb3SSatish Balay #define __FUNC__ "MatGetSize_SeqBAIJ"
1752d61bbb3SSatish Balay int MatGetSize_SeqBAIJ(Mat A,int *m,int *n)
1762d61bbb3SSatish Balay {
1772d61bbb3SSatish Balay   Mat_SeqBAIJ *a = (Mat_SeqBAIJ *) A->data;
1782d61bbb3SSatish Balay 
1792d61bbb3SSatish Balay   PetscFunctionBegin;
1802d61bbb3SSatish Balay   if (m) *m = a->m;
1812d61bbb3SSatish Balay   if (n) *n = a->n;
1822d61bbb3SSatish Balay   PetscFunctionReturn(0);
1832d61bbb3SSatish Balay }
1842d61bbb3SSatish Balay 
1852d61bbb3SSatish Balay #undef __FUNC__
1862d61bbb3SSatish Balay #define __FUNC__ "MatGetOwnershipRange_SeqBAIJ"
1872d61bbb3SSatish Balay int MatGetOwnershipRange_SeqBAIJ(Mat A,int *m,int *n)
1882d61bbb3SSatish Balay {
1892d61bbb3SSatish Balay   Mat_SeqBAIJ *a = (Mat_SeqBAIJ *) A->data;
1902d61bbb3SSatish Balay 
1912d61bbb3SSatish Balay   PetscFunctionBegin;
1922d61bbb3SSatish Balay   *m = 0; *n = a->m;
1932d61bbb3SSatish Balay   PetscFunctionReturn(0);
1942d61bbb3SSatish Balay }
1952d61bbb3SSatish Balay 
1962d61bbb3SSatish Balay #undef __FUNC__
1972d61bbb3SSatish Balay #define __FUNC__ "MatGetRow_SeqBAIJ"
1982d61bbb3SSatish Balay int MatGetRow_SeqBAIJ(Mat A,int row,int *nz,int **idx,Scalar **v)
1992d61bbb3SSatish Balay {
2002d61bbb3SSatish Balay   Mat_SeqBAIJ *a = (Mat_SeqBAIJ *) A->data;
2012d61bbb3SSatish Balay   int          itmp,i,j,k,M,*ai,*aj,bs,bn,bp,*idx_i,bs2;
2022d61bbb3SSatish Balay   Scalar      *aa,*v_i,*aa_i;
2032d61bbb3SSatish Balay 
2042d61bbb3SSatish Balay   PetscFunctionBegin;
2052d61bbb3SSatish Balay   bs  = a->bs;
2062d61bbb3SSatish Balay   ai  = a->i;
2072d61bbb3SSatish Balay   aj  = a->j;
2082d61bbb3SSatish Balay   aa  = a->a;
2092d61bbb3SSatish Balay   bs2 = a->bs2;
2102d61bbb3SSatish Balay 
2112d61bbb3SSatish Balay   if (row < 0 || row >= a->m) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Row out of range");
2122d61bbb3SSatish Balay 
2132d61bbb3SSatish Balay   bn  = row/bs;   /* Block number */
2142d61bbb3SSatish Balay   bp  = row % bs; /* Block Position */
2152d61bbb3SSatish Balay   M   = ai[bn+1] - ai[bn];
2162d61bbb3SSatish Balay   *nz = bs*M;
2172d61bbb3SSatish Balay 
2182d61bbb3SSatish Balay   if (v) {
2192d61bbb3SSatish Balay     *v = 0;
2202d61bbb3SSatish Balay     if (*nz) {
2212d61bbb3SSatish Balay       *v = (Scalar *) PetscMalloc( (*nz)*sizeof(Scalar) ); CHKPTRQ(*v);
2222d61bbb3SSatish Balay       for ( i=0; i<M; i++ ) { /* for each block in the block row */
2232d61bbb3SSatish Balay         v_i  = *v + i*bs;
2242d61bbb3SSatish Balay         aa_i = aa + bs2*(ai[bn] + i);
2252d61bbb3SSatish Balay         for ( j=bp,k=0; j<bs2; j+=bs,k++ ) {v_i[k] = aa_i[j];}
2262d61bbb3SSatish Balay       }
2272d61bbb3SSatish Balay     }
2282d61bbb3SSatish Balay   }
2292d61bbb3SSatish Balay 
2302d61bbb3SSatish Balay   if (idx) {
2312d61bbb3SSatish Balay     *idx = 0;
2322d61bbb3SSatish Balay     if (*nz) {
2332d61bbb3SSatish Balay       *idx = (int *) PetscMalloc( (*nz)*sizeof(int) ); CHKPTRQ(*idx);
2342d61bbb3SSatish Balay       for ( i=0; i<M; i++ ) { /* for each block in the block row */
2352d61bbb3SSatish Balay         idx_i = *idx + i*bs;
2362d61bbb3SSatish Balay         itmp  = bs*aj[ai[bn] + i];
2372d61bbb3SSatish Balay         for ( j=0; j<bs; j++ ) {idx_i[j] = itmp++;}
2382d61bbb3SSatish Balay       }
2392d61bbb3SSatish Balay     }
2402d61bbb3SSatish Balay   }
2412d61bbb3SSatish Balay   PetscFunctionReturn(0);
2422d61bbb3SSatish Balay }
2432d61bbb3SSatish Balay 
2442d61bbb3SSatish Balay #undef __FUNC__
2452d61bbb3SSatish Balay #define __FUNC__ "MatRestoreRow_SeqBAIJ"
2462d61bbb3SSatish Balay int MatRestoreRow_SeqBAIJ(Mat A,int row,int *nz,int **idx,Scalar **v)
2472d61bbb3SSatish Balay {
2482d61bbb3SSatish Balay   PetscFunctionBegin;
2492d61bbb3SSatish Balay   if (idx) {if (*idx) PetscFree(*idx);}
2502d61bbb3SSatish Balay   if (v)   {if (*v)   PetscFree(*v);}
2512d61bbb3SSatish Balay   PetscFunctionReturn(0);
2522d61bbb3SSatish Balay }
2532d61bbb3SSatish Balay 
2542d61bbb3SSatish Balay #undef __FUNC__
2552d61bbb3SSatish Balay #define __FUNC__ "MatTranspose_SeqBAIJ"
2562d61bbb3SSatish Balay int MatTranspose_SeqBAIJ(Mat A,Mat *B)
2572d61bbb3SSatish Balay {
2582d61bbb3SSatish Balay   Mat_SeqBAIJ *a=(Mat_SeqBAIJ *)A->data;
2592d61bbb3SSatish Balay   Mat         C;
2602d61bbb3SSatish Balay   int         i,j,k,ierr,*aj=a->j,*ai=a->i,bs=a->bs,mbs=a->mbs,nbs=a->nbs,len,*col;
2612d61bbb3SSatish Balay   int         *rows,*cols,bs2=a->bs2;
2622d61bbb3SSatish Balay   Scalar      *array=a->a;
2632d61bbb3SSatish Balay 
2642d61bbb3SSatish Balay   PetscFunctionBegin;
2652d61bbb3SSatish Balay   if (B==PETSC_NULL && mbs!=nbs) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Square matrix only for in-place");
2662d61bbb3SSatish Balay   col = (int *) PetscMalloc((1+nbs)*sizeof(int)); CHKPTRQ(col);
2672d61bbb3SSatish Balay   PetscMemzero(col,(1+nbs)*sizeof(int));
2682d61bbb3SSatish Balay 
2692d61bbb3SSatish Balay   for ( i=0; i<ai[mbs]; i++ ) col[aj[i]] += 1;
2702d61bbb3SSatish Balay   ierr = MatCreateSeqBAIJ(A->comm,bs,a->n,a->m,PETSC_NULL,col,&C); CHKERRQ(ierr);
2712d61bbb3SSatish Balay   PetscFree(col);
2722d61bbb3SSatish Balay   rows = (int *) PetscMalloc(2*bs*sizeof(int)); CHKPTRQ(rows);
2732d61bbb3SSatish Balay   cols = rows + bs;
2742d61bbb3SSatish Balay   for ( i=0; i<mbs; i++ ) {
2752d61bbb3SSatish Balay     cols[0] = i*bs;
2762d61bbb3SSatish Balay     for (k=1; k<bs; k++ ) cols[k] = cols[k-1] + 1;
2772d61bbb3SSatish Balay     len = ai[i+1] - ai[i];
2782d61bbb3SSatish Balay     for ( j=0; j<len; j++ ) {
2792d61bbb3SSatish Balay       rows[0] = (*aj++)*bs;
2802d61bbb3SSatish Balay       for (k=1; k<bs; k++ ) rows[k] = rows[k-1] + 1;
2812d61bbb3SSatish Balay       ierr = MatSetValues(C,bs,rows,bs,cols,array,INSERT_VALUES); CHKERRQ(ierr);
2822d61bbb3SSatish Balay       array += bs2;
2832d61bbb3SSatish Balay     }
2842d61bbb3SSatish Balay   }
2852d61bbb3SSatish Balay   PetscFree(rows);
2862d61bbb3SSatish Balay 
2872d61bbb3SSatish Balay   ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY); CHKERRQ(ierr);
2882d61bbb3SSatish Balay   ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY); CHKERRQ(ierr);
2892d61bbb3SSatish Balay 
2902d61bbb3SSatish Balay   if (B != PETSC_NULL) {
2912d61bbb3SSatish Balay     *B = C;
2922d61bbb3SSatish Balay   } else {
293f830108cSBarry Smith     PetscOps *Abops;
294cc2dc46cSBarry Smith     MatOps   Aops;
295f830108cSBarry Smith 
2962d61bbb3SSatish Balay     /* This isn't really an in-place transpose */
2972d61bbb3SSatish Balay     PetscFree(a->a);
2982d61bbb3SSatish Balay     if (!a->singlemalloc) {PetscFree(a->i); PetscFree(a->j);}
2992d61bbb3SSatish Balay     if (a->diag) PetscFree(a->diag);
3002d61bbb3SSatish Balay     if (a->ilen) PetscFree(a->ilen);
3012d61bbb3SSatish Balay     if (a->imax) PetscFree(a->imax);
3022d61bbb3SSatish Balay     if (a->solve_work) PetscFree(a->solve_work);
3032d61bbb3SSatish Balay     PetscFree(a);
304f830108cSBarry Smith 
305f830108cSBarry Smith     /*
306f830108cSBarry Smith        This is horrible, horrible code. We need to keep the
307f830108cSBarry Smith       A pointers for the bops and ops but copy everything
308f830108cSBarry Smith       else from C.
309f830108cSBarry Smith     */
310f830108cSBarry Smith     Abops    = A->bops;
311f830108cSBarry Smith     Aops     = A->ops;
3122d61bbb3SSatish Balay     PetscMemcpy(A,C,sizeof(struct _p_Mat));
313f830108cSBarry Smith     A->bops  = Abops;
314f830108cSBarry Smith     A->ops   = Aops;
31527a8da17SBarry Smith     A->qlist = 0;
316f830108cSBarry Smith 
3172d61bbb3SSatish Balay     PetscHeaderDestroy(C);
3182d61bbb3SSatish Balay   }
3192d61bbb3SSatish Balay   PetscFunctionReturn(0);
3202d61bbb3SSatish Balay }
3212d61bbb3SSatish Balay 
3222d61bbb3SSatish Balay 
3232d61bbb3SSatish Balay 
3243b2fbd54SBarry Smith 
3255615d1e5SSatish Balay #undef __FUNC__
326d4bb536fSBarry Smith #define __FUNC__ "MatView_SeqBAIJ_Binary"
327b6490206SBarry Smith static int MatView_SeqBAIJ_Binary(Mat A,Viewer viewer)
3282593348eSBarry Smith {
329b6490206SBarry Smith   Mat_SeqBAIJ *a = (Mat_SeqBAIJ *) A->data;
3309df24120SSatish Balay   int         i, fd, *col_lens, ierr, bs = a->bs,count,*jj,j,k,l,bs2=a->bs2;
331b6490206SBarry Smith   Scalar      *aa;
3322593348eSBarry Smith 
3333a40ed3dSBarry Smith   PetscFunctionBegin;
33490ace30eSBarry Smith   ierr = ViewerBinaryGetDescriptor(viewer,&fd); CHKERRQ(ierr);
3352593348eSBarry Smith   col_lens = (int *) PetscMalloc((4+a->m)*sizeof(int));CHKPTRQ(col_lens);
3362593348eSBarry Smith   col_lens[0] = MAT_COOKIE;
3373b2fbd54SBarry Smith 
3382593348eSBarry Smith   col_lens[1] = a->m;
3392593348eSBarry Smith   col_lens[2] = a->n;
3407e67e3f9SSatish Balay   col_lens[3] = a->nz*bs2;
3412593348eSBarry Smith 
3422593348eSBarry Smith   /* store lengths of each row and write (including header) to file */
343b6490206SBarry Smith   count = 0;
344b6490206SBarry Smith   for ( i=0; i<a->mbs; i++ ) {
345b6490206SBarry Smith     for ( j=0; j<bs; j++ ) {
346b6490206SBarry Smith       col_lens[4+count++] = bs*(a->i[i+1] - a->i[i]);
347b6490206SBarry Smith     }
3482593348eSBarry Smith   }
3490752156aSBarry Smith   ierr = PetscBinaryWrite(fd,col_lens,4+a->m,PETSC_INT,1); CHKERRQ(ierr);
3502593348eSBarry Smith   PetscFree(col_lens);
3512593348eSBarry Smith 
3522593348eSBarry Smith   /* store column indices (zero start index) */
35366963ce1SSatish Balay   jj = (int *) PetscMalloc( (a->nz+1)*bs2*sizeof(int) ); CHKPTRQ(jj);
354b6490206SBarry Smith   count = 0;
355b6490206SBarry Smith   for ( i=0; i<a->mbs; i++ ) {
356b6490206SBarry Smith     for ( j=0; j<bs; j++ ) {
357b6490206SBarry Smith       for ( k=a->i[i]; k<a->i[i+1]; k++ ) {
358b6490206SBarry Smith         for ( l=0; l<bs; l++ ) {
359b6490206SBarry Smith           jj[count++] = bs*a->j[k] + l;
3602593348eSBarry Smith         }
3612593348eSBarry Smith       }
362b6490206SBarry Smith     }
363b6490206SBarry Smith   }
3640752156aSBarry Smith   ierr = PetscBinaryWrite(fd,jj,bs2*a->nz,PETSC_INT,0); CHKERRQ(ierr);
365b6490206SBarry Smith   PetscFree(jj);
3662593348eSBarry Smith 
3672593348eSBarry Smith   /* store nonzero values */
36866963ce1SSatish Balay   aa = (Scalar *) PetscMalloc((a->nz+1)*bs2*sizeof(Scalar)); CHKPTRQ(aa);
369b6490206SBarry Smith   count = 0;
370b6490206SBarry Smith   for ( i=0; i<a->mbs; i++ ) {
371b6490206SBarry Smith     for ( j=0; j<bs; j++ ) {
372b6490206SBarry Smith       for ( k=a->i[i]; k<a->i[i+1]; k++ ) {
373b6490206SBarry Smith         for ( l=0; l<bs; l++ ) {
3747e67e3f9SSatish Balay           aa[count++] = a->a[bs2*k + l*bs + j];
375b6490206SBarry Smith         }
376b6490206SBarry Smith       }
377b6490206SBarry Smith     }
378b6490206SBarry Smith   }
3790752156aSBarry Smith   ierr = PetscBinaryWrite(fd,aa,bs2*a->nz,PETSC_SCALAR,0); CHKERRQ(ierr);
380b6490206SBarry Smith   PetscFree(aa);
3813a40ed3dSBarry Smith   PetscFunctionReturn(0);
3822593348eSBarry Smith }
3832593348eSBarry Smith 
3845615d1e5SSatish Balay #undef __FUNC__
385d4bb536fSBarry Smith #define __FUNC__ "MatView_SeqBAIJ_ASCII"
386b6490206SBarry Smith static int MatView_SeqBAIJ_ASCII(Mat A,Viewer viewer)
3872593348eSBarry Smith {
388b6490206SBarry Smith   Mat_SeqBAIJ *a = (Mat_SeqBAIJ *) A->data;
3899df24120SSatish Balay   int         ierr, i,j,format,bs = a->bs,k,l,bs2=a->bs2;
3902593348eSBarry Smith   FILE        *fd;
3912593348eSBarry Smith   char        *outputname;
3922593348eSBarry Smith 
3933a40ed3dSBarry Smith   PetscFunctionBegin;
39490ace30eSBarry Smith   ierr = ViewerASCIIGetPointer(viewer,&fd); CHKERRQ(ierr);
3952593348eSBarry Smith   ierr = ViewerFileGetOutputname_Private(viewer,&outputname);CHKERRQ(ierr);
39690ace30eSBarry Smith   ierr = ViewerGetFormat(viewer,&format);
397639f9d9dSBarry Smith   if (format == VIEWER_FORMAT_ASCII_INFO || format == VIEWER_FORMAT_ASCII_INFO_LONG) {
3987ddc982cSLois Curfman McInnes     fprintf(fd,"  block size is %d\n",bs);
3992593348eSBarry Smith   }
400639f9d9dSBarry Smith   else if (format == VIEWER_FORMAT_ASCII_MATLAB) {
401a8c6a408SBarry Smith     SETERRQ(PETSC_ERR_SUP,0,"Matlab format not supported");
4022593348eSBarry Smith   }
403639f9d9dSBarry Smith   else if (format == VIEWER_FORMAT_ASCII_COMMON) {
40444cd7ae7SLois Curfman McInnes     for ( i=0; i<a->mbs; i++ ) {
40544cd7ae7SLois Curfman McInnes       for ( j=0; j<bs; j++ ) {
40644cd7ae7SLois Curfman McInnes         fprintf(fd,"row %d:",i*bs+j);
40744cd7ae7SLois Curfman McInnes         for ( k=a->i[i]; k<a->i[i+1]; k++ ) {
40844cd7ae7SLois Curfman McInnes           for ( l=0; l<bs; l++ ) {
4093a40ed3dSBarry Smith #if defined(USE_PETSC_COMPLEX)
410e20fef11SSatish Balay           if (PetscImaginary(a->a[bs2*k + l*bs + j]) > 0.0 && PetscReal(a->a[bs2*k + l*bs + j]) != 0.0)
41144cd7ae7SLois Curfman McInnes             fprintf(fd," %d %g + %g i",bs*a->j[k]+l,
412e20fef11SSatish Balay               PetscReal(a->a[bs2*k + l*bs + j]),PetscImaginary(a->a[bs2*k + l*bs + j]));
413e20fef11SSatish Balay           else if (PetscImaginary(a->a[bs2*k + l*bs + j]) < 0.0 && PetscReal(a->a[bs2*k + l*bs + j]) != 0.0)
414766eeae4SLois Curfman McInnes             fprintf(fd," %d %g - %g i",bs*a->j[k]+l,
415e20fef11SSatish Balay               PetscReal(a->a[bs2*k + l*bs + j]),-PetscImaginary(a->a[bs2*k + l*bs + j]));
416e20fef11SSatish Balay           else if (PetscReal(a->a[bs2*k + l*bs + j]) != 0.0)
417e20fef11SSatish Balay             fprintf(fd," %d %g ",bs*a->j[k]+l,PetscReal(a->a[bs2*k + l*bs + j]));
41844cd7ae7SLois Curfman McInnes #else
41944cd7ae7SLois Curfman McInnes           if (a->a[bs2*k + l*bs + j] != 0.0)
42044cd7ae7SLois Curfman McInnes             fprintf(fd," %d %g ",bs*a->j[k]+l,a->a[bs2*k + l*bs + j]);
42144cd7ae7SLois Curfman McInnes #endif
42244cd7ae7SLois Curfman McInnes           }
42344cd7ae7SLois Curfman McInnes         }
42444cd7ae7SLois Curfman McInnes         fprintf(fd,"\n");
42544cd7ae7SLois Curfman McInnes       }
42644cd7ae7SLois Curfman McInnes     }
42744cd7ae7SLois Curfman McInnes   }
4282593348eSBarry Smith   else {
429b6490206SBarry Smith     for ( i=0; i<a->mbs; i++ ) {
430b6490206SBarry Smith       for ( j=0; j<bs; j++ ) {
431b6490206SBarry Smith         fprintf(fd,"row %d:",i*bs+j);
432b6490206SBarry Smith         for ( k=a->i[i]; k<a->i[i+1]; k++ ) {
433b6490206SBarry Smith           for ( l=0; l<bs; l++ ) {
4343a40ed3dSBarry Smith #if defined(USE_PETSC_COMPLEX)
435e20fef11SSatish Balay           if (PetscImaginary(a->a[bs2*k + l*bs + j]) > 0.0) {
43688685aaeSLois Curfman McInnes             fprintf(fd," %d %g + %g i",bs*a->j[k]+l,
437e20fef11SSatish Balay               PetscReal(a->a[bs2*k + l*bs + j]),PetscImaginary(a->a[bs2*k + l*bs + j]));
43888685aaeSLois Curfman McInnes           }
439e20fef11SSatish Balay           else if (PetscImaginary(a->a[bs2*k + l*bs + j]) < 0.0) {
440766eeae4SLois Curfman McInnes             fprintf(fd," %d %g - %g i",bs*a->j[k]+l,
441e20fef11SSatish Balay               PetscReal(a->a[bs2*k + l*bs + j]),-PetscImaginary(a->a[bs2*k + l*bs + j]));
442766eeae4SLois Curfman McInnes           }
44388685aaeSLois Curfman McInnes           else {
444e20fef11SSatish Balay             fprintf(fd," %d %g ",bs*a->j[k]+l,PetscReal(a->a[bs2*k + l*bs + j]));
44588685aaeSLois Curfman McInnes           }
44688685aaeSLois Curfman McInnes #else
4477e67e3f9SSatish Balay             fprintf(fd," %d %g ",bs*a->j[k]+l,a->a[bs2*k + l*bs + j]);
44888685aaeSLois Curfman McInnes #endif
4492593348eSBarry Smith           }
4502593348eSBarry Smith         }
4512593348eSBarry Smith         fprintf(fd,"\n");
4522593348eSBarry Smith       }
4532593348eSBarry Smith     }
454b6490206SBarry Smith   }
4552593348eSBarry Smith   fflush(fd);
4563a40ed3dSBarry Smith   PetscFunctionReturn(0);
4572593348eSBarry Smith }
4582593348eSBarry Smith 
4595615d1e5SSatish Balay #undef __FUNC__
460d4bb536fSBarry Smith #define __FUNC__ "MatView_SeqBAIJ_Draw"
4613270192aSSatish Balay static int MatView_SeqBAIJ_Draw(Mat A,Viewer viewer)
4623270192aSSatish Balay {
4633270192aSSatish Balay   Mat_SeqBAIJ  *a=(Mat_SeqBAIJ *) A->data;
4643270192aSSatish Balay   int          row,ierr,i,j,k,l,mbs=a->mbs,pause,color,bs=a->bs,bs2=a->bs2;
4653270192aSSatish Balay   double       xl,yl,xr,yr,w,h,xc,yc,scale = 1.0,x_l,x_r,y_l,y_r;
4663270192aSSatish Balay   Scalar       *aa;
4673270192aSSatish Balay   Draw         draw;
4683270192aSSatish Balay   DrawButton   button;
4693270192aSSatish Balay   PetscTruth   isnull;
4703270192aSSatish Balay 
4713a40ed3dSBarry Smith   PetscFunctionBegin;
4723a40ed3dSBarry Smith   ierr = ViewerDrawGetDraw(viewer,&draw);CHKERRQ(ierr);
4733a40ed3dSBarry Smith   ierr = DrawIsNull(draw,&isnull); CHKERRQ(ierr); if (isnull) PetscFunctionReturn(0);
4743270192aSSatish Balay 
4753270192aSSatish Balay   xr  = a->n; yr = a->m; h = yr/10.0; w = xr/10.0;
4763270192aSSatish Balay   xr += w;    yr += h;  xl = -w;     yl = -h;
4773270192aSSatish Balay   ierr = DrawSetCoordinates(draw,xl,yl,xr,yr); CHKERRQ(ierr);
4783270192aSSatish Balay   /* loop over matrix elements drawing boxes */
4793270192aSSatish Balay   color = DRAW_BLUE;
4803270192aSSatish Balay   for ( i=0,row=0; i<mbs; i++,row+=bs ) {
4813270192aSSatish Balay     for ( j=a->i[i]; j<a->i[i+1]; j++ ) {
4823270192aSSatish Balay       y_l = a->m - row - 1.0; y_r = y_l + 1.0;
4833270192aSSatish Balay       x_l = a->j[j]*bs; x_r = x_l + 1.0;
4843270192aSSatish Balay       aa = a->a + j*bs2;
4853270192aSSatish Balay       for ( k=0; k<bs; k++ ) {
4863270192aSSatish Balay         for ( l=0; l<bs; l++ ) {
4873270192aSSatish Balay           if (PetscReal(*aa++) >=  0.) continue;
488b34f160eSSatish Balay           DrawRectangle(draw,x_l+k,y_l-l,x_r+k,y_r-l,color,color,color,color);
4893270192aSSatish Balay         }
4903270192aSSatish Balay       }
4913270192aSSatish Balay     }
4923270192aSSatish Balay   }
4933270192aSSatish Balay   color = DRAW_CYAN;
4943270192aSSatish Balay   for ( i=0,row=0; i<mbs; i++,row+=bs ) {
4953270192aSSatish Balay     for ( j=a->i[i]; j<a->i[i+1]; j++ ) {
4963270192aSSatish Balay       y_l = a->m - row - 1.0; y_r = y_l + 1.0;
4973270192aSSatish Balay       x_l = a->j[j]*bs; x_r = x_l + 1.0;
4983270192aSSatish Balay       aa = a->a + j*bs2;
4993270192aSSatish Balay       for ( k=0; k<bs; k++ ) {
5003270192aSSatish Balay         for ( l=0; l<bs; l++ ) {
5013270192aSSatish Balay           if (PetscReal(*aa++) != 0.) continue;
502b34f160eSSatish Balay           DrawRectangle(draw,x_l+k,y_l-l,x_r+k,y_r-l,color,color,color,color);
5033270192aSSatish Balay         }
5043270192aSSatish Balay       }
5053270192aSSatish Balay     }
5063270192aSSatish Balay   }
5073270192aSSatish Balay 
5083270192aSSatish Balay   color = DRAW_RED;
5093270192aSSatish Balay   for ( i=0,row=0; i<mbs; i++,row+=bs ) {
5103270192aSSatish Balay     for ( j=a->i[i]; j<a->i[i+1]; j++ ) {
5113270192aSSatish Balay       y_l = a->m - row - 1.0; y_r = y_l + 1.0;
5123270192aSSatish Balay       x_l = a->j[j]*bs; x_r = x_l + 1.0;
5133270192aSSatish Balay       aa = a->a + j*bs2;
5143270192aSSatish Balay       for ( k=0; k<bs; k++ ) {
5153270192aSSatish Balay         for ( l=0; l<bs; l++ ) {
5163270192aSSatish Balay           if (PetscReal(*aa++) <= 0.) continue;
517b34f160eSSatish Balay           DrawRectangle(draw,x_l+k,y_l-l,x_r+k,y_r-l,color,color,color,color);
5183270192aSSatish Balay         }
5193270192aSSatish Balay       }
5203270192aSSatish Balay     }
5213270192aSSatish Balay   }
5223270192aSSatish Balay 
52355843e3eSBarry Smith   DrawSynchronizedFlush(draw);
5243270192aSSatish Balay   DrawGetPause(draw,&pause);
5253a40ed3dSBarry Smith   if (pause >= 0) { PetscSleep(pause); PetscFunctionReturn(0);}
5263270192aSSatish Balay 
5273270192aSSatish Balay   /* allow the matrix to zoom or shrink */
52855843e3eSBarry Smith   ierr = DrawSynchronizedGetMouseButton(draw,&button,&xc,&yc,0,0);
5293270192aSSatish Balay   while (button != BUTTON_RIGHT) {
53055843e3eSBarry Smith     DrawSynchronizedClear(draw);
5313270192aSSatish Balay     if (button == BUTTON_LEFT) scale = .5;
5323270192aSSatish Balay     else if (button == BUTTON_CENTER) scale = 2.;
5333270192aSSatish Balay     xl = scale*(xl + w - xc) + xc - w*scale;
5343270192aSSatish Balay     xr = scale*(xr - w - xc) + xc + w*scale;
5353270192aSSatish Balay     yl = scale*(yl + h - yc) + yc - h*scale;
5363270192aSSatish Balay     yr = scale*(yr - h - yc) + yc + h*scale;
5373270192aSSatish Balay     w *= scale; h *= scale;
5383270192aSSatish Balay     ierr = DrawSetCoordinates(draw,xl,yl,xr,yr); CHKERRQ(ierr);
5393270192aSSatish Balay     color = DRAW_BLUE;
5403270192aSSatish Balay     for ( i=0,row=0; i<mbs; i++,row+=bs ) {
5413270192aSSatish Balay       for ( j=a->i[i]; j<a->i[i+1]; j++ ) {
5423270192aSSatish Balay         y_l = a->m - row - 1.0; y_r = y_l + 1.0;
5433270192aSSatish Balay         x_l = a->j[j]*bs; x_r = x_l + 1.0;
5443270192aSSatish Balay         aa = a->a + j*bs2;
5453270192aSSatish Balay         for ( k=0; k<bs; k++ ) {
5463270192aSSatish Balay           for ( l=0; l<bs; l++ ) {
5473270192aSSatish Balay             if (PetscReal(*aa++) >=  0.) continue;
548b34f160eSSatish Balay             DrawRectangle(draw,x_l+k,y_l-l,x_r+k,y_r-l,color,color,color,color);
5493270192aSSatish Balay           }
5503270192aSSatish Balay         }
5513270192aSSatish Balay       }
5523270192aSSatish Balay     }
5533270192aSSatish Balay     color = DRAW_CYAN;
5543270192aSSatish Balay     for ( i=0,row=0; i<mbs; i++,row+=bs ) {
5553270192aSSatish Balay       for ( j=a->i[i]; j<a->i[i+1]; j++ ) {
5563270192aSSatish Balay         y_l = a->m - row - 1.0; y_r = y_l + 1.0;
5573270192aSSatish Balay         x_l = a->j[j]*bs; x_r = x_l + 1.0;
5583270192aSSatish Balay         aa = a->a + j*bs2;
5593270192aSSatish Balay         for ( k=0; k<bs; k++ ) {
5603270192aSSatish Balay           for ( l=0; l<bs; l++ ) {
5613270192aSSatish Balay           if (PetscReal(*aa++) != 0.) continue;
562b34f160eSSatish Balay           DrawRectangle(draw,x_l+k,y_l-l,x_r+k,y_r-l,color,color,color,color);
5633270192aSSatish Balay           }
5643270192aSSatish Balay         }
5653270192aSSatish Balay       }
5663270192aSSatish Balay     }
5673270192aSSatish Balay 
5683270192aSSatish Balay     color = DRAW_RED;
5693270192aSSatish Balay     for ( i=0,row=0; i<mbs; i++,row+=bs ) {
5703270192aSSatish Balay       for ( j=a->i[i]; j<a->i[i+1]; j++ ) {
5713270192aSSatish Balay         y_l = a->m - row - 1.0; y_r = y_l + 1.0;
5723270192aSSatish Balay         x_l = a->j[j]*bs; x_r = x_l + 1.0;
5733270192aSSatish Balay         aa = a->a + j*bs2;
5743270192aSSatish Balay         for ( k=0; k<bs; k++ ) {
5753270192aSSatish Balay           for ( l=0; l<bs; l++ ) {
5763270192aSSatish Balay             if (PetscReal(*aa++) <= 0.) continue;
577b34f160eSSatish Balay             DrawRectangle(draw,x_l+k,y_l-l,x_r+k,y_r-l,color,color,color,color);
5783270192aSSatish Balay           }
5793270192aSSatish Balay         }
5803270192aSSatish Balay       }
5813270192aSSatish Balay     }
58255843e3eSBarry Smith     ierr = DrawSynchronizedGetMouseButton(draw,&button,&xc,&yc,0,0);
5833270192aSSatish Balay   }
5843a40ed3dSBarry Smith   PetscFunctionReturn(0);
5853270192aSSatish Balay }
5863270192aSSatish Balay 
5875615d1e5SSatish Balay #undef __FUNC__
588d4bb536fSBarry Smith #define __FUNC__ "MatView_SeqBAIJ"
589e1311b90SBarry Smith int MatView_SeqBAIJ(Mat A,Viewer viewer)
5902593348eSBarry Smith {
59119bcc07fSBarry Smith   ViewerType  vtype;
59219bcc07fSBarry Smith   int         ierr;
5932593348eSBarry Smith 
5943a40ed3dSBarry Smith   PetscFunctionBegin;
59519bcc07fSBarry Smith   ierr = ViewerGetType(viewer,&vtype); CHKERRQ(ierr);
59619bcc07fSBarry Smith   if (vtype == MATLAB_VIEWER) {
597a8c6a408SBarry Smith     SETERRQ(PETSC_ERR_SUP,0,"Matlab viewer not supported");
5983a40ed3dSBarry Smith   } else if (vtype == ASCII_FILE_VIEWER || vtype == ASCII_FILES_VIEWER){
5993a40ed3dSBarry Smith     ierr = MatView_SeqBAIJ_ASCII(A,viewer);CHKERRQ(ierr);
6003a40ed3dSBarry Smith   } else if (vtype == BINARY_FILE_VIEWER) {
6013a40ed3dSBarry Smith     ierr = MatView_SeqBAIJ_Binary(A,viewer);CHKERRQ(ierr);
6023a40ed3dSBarry Smith   } else if (vtype == DRAW_VIEWER) {
6033a40ed3dSBarry Smith     ierr = MatView_SeqBAIJ_Draw(A,viewer);CHKERRQ(ierr);
6045cd90555SBarry Smith   } else {
6055cd90555SBarry Smith     SETERRQ(1,1,"Viewer type not supported by PETSc object");
6062593348eSBarry Smith   }
6073a40ed3dSBarry Smith   PetscFunctionReturn(0);
6082593348eSBarry Smith }
609b6490206SBarry Smith 
610cd0e1443SSatish Balay 
6115615d1e5SSatish Balay #undef __FUNC__
6122d61bbb3SSatish Balay #define __FUNC__ "MatGetValues_SeqBAIJ"
6132d61bbb3SSatish Balay int MatGetValues_SeqBAIJ(Mat A,int m,int *im,int n,int *in,Scalar *v)
614cd0e1443SSatish Balay {
615cd0e1443SSatish Balay   Mat_SeqBAIJ *a = (Mat_SeqBAIJ *) A->data;
6162d61bbb3SSatish Balay   int        *rp, k, low, high, t, row, nrow, i, col, l, *aj = a->j;
6172d61bbb3SSatish Balay   int        *ai = a->i, *ailen = a->ilen;
6182d61bbb3SSatish Balay   int        brow,bcol,ridx,cidx,bs=a->bs,bs2=a->bs2;
6192d61bbb3SSatish Balay   Scalar     *ap, *aa = a->a, zero = 0.0;
620cd0e1443SSatish Balay 
6213a40ed3dSBarry Smith   PetscFunctionBegin;
6222d61bbb3SSatish Balay   for ( k=0; k<m; k++ ) { /* loop over rows */
623cd0e1443SSatish Balay     row  = im[k]; brow = row/bs;
624a8c6a408SBarry Smith     if (row < 0) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Negative row");
625a8c6a408SBarry Smith     if (row >= a->m) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Row too large");
6262d61bbb3SSatish Balay     rp   = aj + ai[brow] ; ap = aa + bs2*ai[brow] ;
6272c3acbe9SBarry Smith     nrow = ailen[brow];
6282d61bbb3SSatish Balay     for ( l=0; l<n; l++ ) { /* loop over columns */
629a8c6a408SBarry Smith       if (in[l] < 0) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Negative column");
630a8c6a408SBarry Smith       if (in[l] >= a->n) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Column too large");
6312d61bbb3SSatish Balay       col  = in[l] ;
6322d61bbb3SSatish Balay       bcol = col/bs;
6332d61bbb3SSatish Balay       cidx = col%bs;
6342d61bbb3SSatish Balay       ridx = row%bs;
6352d61bbb3SSatish Balay       high = nrow;
6362d61bbb3SSatish Balay       low  = 0; /* assume unsorted */
6372d61bbb3SSatish Balay       while (high-low > 5) {
638cd0e1443SSatish Balay         t = (low+high)/2;
639cd0e1443SSatish Balay         if (rp[t] > bcol) high = t;
640cd0e1443SSatish Balay         else             low  = t;
641cd0e1443SSatish Balay       }
642cd0e1443SSatish Balay       for ( i=low; i<high; i++ ) {
643cd0e1443SSatish Balay         if (rp[i] > bcol) break;
644cd0e1443SSatish Balay         if (rp[i] == bcol) {
6452d61bbb3SSatish Balay           *v++ = ap[bs2*i+bs*cidx+ridx];
6462d61bbb3SSatish Balay           goto finished;
647cd0e1443SSatish Balay         }
648cd0e1443SSatish Balay       }
6492d61bbb3SSatish Balay       *v++ = zero;
6502d61bbb3SSatish Balay       finished:;
651cd0e1443SSatish Balay     }
652cd0e1443SSatish Balay   }
6533a40ed3dSBarry Smith   PetscFunctionReturn(0);
654cd0e1443SSatish Balay }
655cd0e1443SSatish Balay 
6562d61bbb3SSatish Balay 
6575615d1e5SSatish Balay #undef __FUNC__
65805a5f48eSSatish Balay #define __FUNC__ "MatSetValuesBlocked_SeqBAIJ"
65992c4ed94SBarry Smith int MatSetValuesBlocked_SeqBAIJ(Mat A,int m,int *im,int n,int *in,Scalar *v,InsertMode is)
66092c4ed94SBarry Smith {
66192c4ed94SBarry Smith   Mat_SeqBAIJ *a = (Mat_SeqBAIJ *) A->data;
6628a84c255SSatish Balay   int         *rp,k,low,high,t,ii,jj,row,nrow,i,col,l,rmax,N,sorted=a->sorted;
663dd9472c6SBarry Smith   int         *imax=a->imax,*ai=a->i,*ailen=a->ilen, roworiented=a->roworiented;
664dd9472c6SBarry Smith   int         *aj=a->j,nonew=a->nonew,bs2=a->bs2,bs=a->bs,stepval;
6650e324ae4SSatish Balay   Scalar      *ap,*value=v,*aa=a->a,*bap;
66692c4ed94SBarry Smith 
6673a40ed3dSBarry Smith   PetscFunctionBegin;
6680e324ae4SSatish Balay   if (roworiented) {
6690e324ae4SSatish Balay     stepval = (n-1)*bs;
6700e324ae4SSatish Balay   } else {
6710e324ae4SSatish Balay     stepval = (m-1)*bs;
6720e324ae4SSatish Balay   }
67392c4ed94SBarry Smith   for ( k=0; k<m; k++ ) { /* loop over added rows */
67492c4ed94SBarry Smith     row  = im[k];
6753a40ed3dSBarry Smith #if defined(USE_PETSC_BOPT_g)
676a8c6a408SBarry Smith     if (row < 0) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Negative row");
677a8c6a408SBarry Smith     if (row >= a->mbs) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Row too large");
67892c4ed94SBarry Smith #endif
67992c4ed94SBarry Smith     rp   = aj + ai[row];
68092c4ed94SBarry Smith     ap   = aa + bs2*ai[row];
68192c4ed94SBarry Smith     rmax = imax[row];
68292c4ed94SBarry Smith     nrow = ailen[row];
68392c4ed94SBarry Smith     low  = 0;
68492c4ed94SBarry Smith     for ( l=0; l<n; l++ ) { /* loop over added columns */
6853a40ed3dSBarry Smith #if defined(USE_PETSC_BOPT_g)
686a8c6a408SBarry Smith       if (in[l] < 0) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Negative column");
687a8c6a408SBarry Smith       if (in[l] >= a->nbs) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Column too large");
68892c4ed94SBarry Smith #endif
68992c4ed94SBarry Smith       col = in[l];
69092c4ed94SBarry Smith       if (roworiented) {
6910e324ae4SSatish Balay         value = v + k*(stepval+bs)*bs + l*bs;
6920e324ae4SSatish Balay       } else {
6930e324ae4SSatish Balay         value = v + l*(stepval+bs)*bs + k*bs;
69492c4ed94SBarry Smith       }
69592c4ed94SBarry Smith       if (!sorted) low = 0; high = nrow;
69692c4ed94SBarry Smith       while (high-low > 7) {
69792c4ed94SBarry Smith         t = (low+high)/2;
69892c4ed94SBarry Smith         if (rp[t] > col) high = t;
69992c4ed94SBarry Smith         else             low  = t;
70092c4ed94SBarry Smith       }
70192c4ed94SBarry Smith       for ( i=low; i<high; i++ ) {
70292c4ed94SBarry Smith         if (rp[i] > col) break;
70392c4ed94SBarry Smith         if (rp[i] == col) {
7048a84c255SSatish Balay           bap  = ap +  bs2*i;
7050e324ae4SSatish Balay           if (roworiented) {
7068a84c255SSatish Balay             if (is == ADD_VALUES) {
707dd9472c6SBarry Smith               for ( ii=0; ii<bs; ii++,value+=stepval ) {
708dd9472c6SBarry Smith                 for (jj=ii; jj<bs2; jj+=bs ) {
7098a84c255SSatish Balay                   bap[jj] += *value++;
710dd9472c6SBarry Smith                 }
711dd9472c6SBarry Smith               }
7120e324ae4SSatish Balay             } else {
713dd9472c6SBarry Smith               for ( ii=0; ii<bs; ii++,value+=stepval ) {
714dd9472c6SBarry Smith                 for (jj=ii; jj<bs2; jj+=bs ) {
7150e324ae4SSatish Balay                   bap[jj] = *value++;
7168a84c255SSatish Balay                 }
717dd9472c6SBarry Smith               }
718dd9472c6SBarry Smith             }
7190e324ae4SSatish Balay           } else {
7200e324ae4SSatish Balay             if (is == ADD_VALUES) {
721dd9472c6SBarry Smith               for ( ii=0; ii<bs; ii++,value+=stepval ) {
722dd9472c6SBarry Smith                 for (jj=0; jj<bs; jj++ ) {
7230e324ae4SSatish Balay                   *bap++ += *value++;
724dd9472c6SBarry Smith                 }
725dd9472c6SBarry Smith               }
7260e324ae4SSatish Balay             } else {
727dd9472c6SBarry Smith               for ( ii=0; ii<bs; ii++,value+=stepval ) {
728dd9472c6SBarry Smith                 for (jj=0; jj<bs; jj++ ) {
7290e324ae4SSatish Balay                   *bap++  = *value++;
7300e324ae4SSatish Balay                 }
7318a84c255SSatish Balay               }
732dd9472c6SBarry Smith             }
733dd9472c6SBarry Smith           }
734f1241b54SBarry Smith           goto noinsert2;
73592c4ed94SBarry Smith         }
73692c4ed94SBarry Smith       }
73789280ab3SLois Curfman McInnes       if (nonew == 1) goto noinsert2;
738a8c6a408SBarry Smith       else if (nonew == -1) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Inserting a new nonzero in the matrix");
73992c4ed94SBarry Smith       if (nrow >= rmax) {
74092c4ed94SBarry Smith         /* there is no extra room in row, therefore enlarge */
74192c4ed94SBarry Smith         int    new_nz = ai[a->mbs] + CHUNKSIZE,len,*new_i,*new_j;
74292c4ed94SBarry Smith         Scalar *new_a;
74392c4ed94SBarry Smith 
744a8c6a408SBarry Smith         if (nonew == -2) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Inserting a new nonzero in the matrix");
74589280ab3SLois Curfman McInnes 
74692c4ed94SBarry Smith         /* malloc new storage space */
74792c4ed94SBarry Smith         len     = new_nz*(sizeof(int)+bs2*sizeof(Scalar))+(a->mbs+1)*sizeof(int);
74892c4ed94SBarry Smith         new_a   = (Scalar *) PetscMalloc( len ); CHKPTRQ(new_a);
74992c4ed94SBarry Smith         new_j   = (int *) (new_a + bs2*new_nz);
75092c4ed94SBarry Smith         new_i   = new_j + new_nz;
75192c4ed94SBarry Smith 
75292c4ed94SBarry Smith         /* copy over old data into new slots */
75392c4ed94SBarry Smith         for ( ii=0; ii<row+1; ii++ ) {new_i[ii] = ai[ii];}
75492c4ed94SBarry Smith         for ( ii=row+1; ii<a->mbs+1; ii++ ) {new_i[ii] = ai[ii]+CHUNKSIZE;}
75592c4ed94SBarry Smith         PetscMemcpy(new_j,aj,(ai[row]+nrow)*sizeof(int));
75692c4ed94SBarry Smith         len = (new_nz - CHUNKSIZE - ai[row] - nrow);
757dd9472c6SBarry Smith         PetscMemcpy(new_j+ai[row]+nrow+CHUNKSIZE,aj+ai[row]+nrow,len*sizeof(int));
75892c4ed94SBarry Smith         PetscMemcpy(new_a,aa,(ai[row]+nrow)*bs2*sizeof(Scalar));
75992c4ed94SBarry Smith         PetscMemzero(new_a+bs2*(ai[row]+nrow),bs2*CHUNKSIZE*sizeof(Scalar));
760dd9472c6SBarry Smith         PetscMemcpy(new_a+bs2*(ai[row]+nrow+CHUNKSIZE),aa+bs2*(ai[row]+nrow),bs2*len*sizeof(Scalar));
76192c4ed94SBarry Smith         /* free up old matrix storage */
76292c4ed94SBarry Smith         PetscFree(a->a);
76392c4ed94SBarry Smith         if (!a->singlemalloc) {PetscFree(a->i);PetscFree(a->j);}
76492c4ed94SBarry Smith         aa = a->a = new_a; ai = a->i = new_i; aj = a->j = new_j;
76592c4ed94SBarry Smith         a->singlemalloc = 1;
76692c4ed94SBarry Smith 
76792c4ed94SBarry Smith         rp   = aj + ai[row]; ap = aa + bs2*ai[row];
76892c4ed94SBarry Smith         rmax = imax[row] = imax[row] + CHUNKSIZE;
76992c4ed94SBarry Smith         PLogObjectMemory(A,CHUNKSIZE*(sizeof(int) + bs2*sizeof(Scalar)));
77092c4ed94SBarry Smith         a->maxnz += bs2*CHUNKSIZE;
77192c4ed94SBarry Smith         a->reallocs++;
77292c4ed94SBarry Smith         a->nz++;
77392c4ed94SBarry Smith       }
77492c4ed94SBarry Smith       N = nrow++ - 1;
77592c4ed94SBarry Smith       /* shift up all the later entries in this row */
77692c4ed94SBarry Smith       for ( ii=N; ii>=i; ii-- ) {
77792c4ed94SBarry Smith         rp[ii+1] = rp[ii];
77892c4ed94SBarry Smith         PetscMemcpy(ap+bs2*(ii+1),ap+bs2*(ii),bs2*sizeof(Scalar));
77992c4ed94SBarry Smith       }
78092c4ed94SBarry Smith       if (N >= i) PetscMemzero(ap+bs2*i,bs2*sizeof(Scalar));
78192c4ed94SBarry Smith       rp[i] = col;
7828a84c255SSatish Balay       bap   = ap +  bs2*i;
7830e324ae4SSatish Balay       if (roworiented) {
784dd9472c6SBarry Smith         for ( ii=0; ii<bs; ii++,value+=stepval) {
785dd9472c6SBarry Smith           for (jj=ii; jj<bs2; jj+=bs ) {
7860e324ae4SSatish Balay             bap[jj] = *value++;
787dd9472c6SBarry Smith           }
788dd9472c6SBarry Smith         }
7890e324ae4SSatish Balay       } else {
790dd9472c6SBarry Smith         for ( ii=0; ii<bs; ii++,value+=stepval ) {
791dd9472c6SBarry Smith           for (jj=0; jj<bs; jj++ ) {
7920e324ae4SSatish Balay             *bap++  = *value++;
7930e324ae4SSatish Balay           }
794dd9472c6SBarry Smith         }
795dd9472c6SBarry Smith       }
796f1241b54SBarry Smith       noinsert2:;
79792c4ed94SBarry Smith       low = i;
79892c4ed94SBarry Smith     }
79992c4ed94SBarry Smith     ailen[row] = nrow;
80092c4ed94SBarry Smith   }
8013a40ed3dSBarry Smith   PetscFunctionReturn(0);
80292c4ed94SBarry Smith }
80392c4ed94SBarry Smith 
804f2501298SSatish Balay 
8055615d1e5SSatish Balay #undef __FUNC__
8065615d1e5SSatish Balay #define __FUNC__ "MatAssemblyEnd_SeqBAIJ"
8078f6be9afSLois Curfman McInnes int MatAssemblyEnd_SeqBAIJ(Mat A,MatAssemblyType mode)
808584200bdSSatish Balay {
809584200bdSSatish Balay   Mat_SeqBAIJ *a = (Mat_SeqBAIJ *) A->data;
810584200bdSSatish Balay   int        fshift = 0,i,j,*ai = a->i, *aj = a->j, *imax = a->imax;
811a7c10996SSatish Balay   int        m = a->m,*ip, N, *ailen = a->ilen;
81243ee02c3SBarry Smith   int        mbs = a->mbs, bs2 = a->bs2,rmax = 0;
813584200bdSSatish Balay   Scalar     *aa = a->a, *ap;
814584200bdSSatish Balay 
8153a40ed3dSBarry Smith   PetscFunctionBegin;
8163a40ed3dSBarry Smith   if (mode == MAT_FLUSH_ASSEMBLY) PetscFunctionReturn(0);
817584200bdSSatish Balay 
81843ee02c3SBarry Smith   if (m) rmax = ailen[0];
819584200bdSSatish Balay   for ( i=1; i<mbs; i++ ) {
820584200bdSSatish Balay     /* move each row back by the amount of empty slots (fshift) before it*/
821584200bdSSatish Balay     fshift += imax[i-1] - ailen[i-1];
822d402145bSBarry Smith     rmax   = PetscMax(rmax,ailen[i]);
823584200bdSSatish Balay     if (fshift) {
824a7c10996SSatish Balay       ip = aj + ai[i]; ap = aa + bs2*ai[i];
825584200bdSSatish Balay       N = ailen[i];
826584200bdSSatish Balay       for ( j=0; j<N; j++ ) {
827584200bdSSatish Balay         ip[j-fshift] = ip[j];
8287e67e3f9SSatish Balay         PetscMemcpy(ap+(j-fshift)*bs2,ap+j*bs2,bs2*sizeof(Scalar));
829584200bdSSatish Balay       }
830584200bdSSatish Balay     }
831584200bdSSatish Balay     ai[i] = ai[i-1] + ailen[i-1];
832584200bdSSatish Balay   }
833584200bdSSatish Balay   if (mbs) {
834584200bdSSatish Balay     fshift += imax[mbs-1] - ailen[mbs-1];
835584200bdSSatish Balay     ai[mbs] = ai[mbs-1] + ailen[mbs-1];
836584200bdSSatish Balay   }
837584200bdSSatish Balay   /* reset ilen and imax for each row */
838584200bdSSatish Balay   for ( i=0; i<mbs; i++ ) {
839584200bdSSatish Balay     ailen[i] = imax[i] = ai[i+1] - ai[i];
840584200bdSSatish Balay   }
841a7c10996SSatish Balay   a->nz = ai[mbs];
842584200bdSSatish Balay 
843584200bdSSatish Balay   /* diagonals may have moved, so kill the diagonal pointers */
844584200bdSSatish Balay   if (fshift && a->diag) {
845584200bdSSatish Balay     PetscFree(a->diag);
846584200bdSSatish Balay     PLogObjectMemory(A,-(m+1)*sizeof(int));
847584200bdSSatish Balay     a->diag = 0;
848584200bdSSatish Balay   }
8493d2013a6SLois Curfman McInnes   PLogInfo(A,"MatAssemblyEnd_SeqBAIJ:Matrix size: %d X %d, block size %d; storage space: %d unneeded, %d used\n",
850219d9a1aSLois Curfman McInnes            m,a->n,a->bs,fshift*bs2,a->nz*bs2);
8513d2013a6SLois Curfman McInnes   PLogInfo(A,"MatAssemblyEnd_SeqBAIJ:Number of mallocs during MatSetValues is %d\n",
852584200bdSSatish Balay            a->reallocs);
853d402145bSBarry Smith   PLogInfo(A,"MatAssemblyEnd_SeqBAIJ:Most nonzeros blocks in any row is %d\n",rmax);
854e2f3b5e9SSatish Balay   a->reallocs          = 0;
8554e220ebcSLois Curfman McInnes   A->info.nz_unneeded  = (double)fshift*bs2;
8564e220ebcSLois Curfman McInnes 
8573a40ed3dSBarry Smith   PetscFunctionReturn(0);
858584200bdSSatish Balay }
859584200bdSSatish Balay 
8605a838052SSatish Balay 
861d9b7c43dSSatish Balay /* idx should be of length atlease bs */
8625615d1e5SSatish Balay #undef __FUNC__
8635615d1e5SSatish Balay #define __FUNC__ "MatZeroRows_SeqBAIJ_Check_Block"
864d9b7c43dSSatish Balay static int MatZeroRows_SeqBAIJ_Check_Block(int *idx, int bs, PetscTruth *flg)
865d9b7c43dSSatish Balay {
866d9b7c43dSSatish Balay   int i,row;
8673a40ed3dSBarry Smith 
8683a40ed3dSBarry Smith   PetscFunctionBegin;
869d9b7c43dSSatish Balay   row = idx[0];
8703a40ed3dSBarry Smith   if (row%bs!=0) { *flg = PETSC_FALSE; PetscFunctionReturn(0); }
871d9b7c43dSSatish Balay 
872d9b7c43dSSatish Balay   for ( i=1; i<bs; i++ ) {
8733a40ed3dSBarry Smith     if (row+i != idx[i]) { *flg = PETSC_FALSE; PetscFunctionReturn(0); }
874d9b7c43dSSatish Balay   }
875d9b7c43dSSatish Balay   *flg = PETSC_TRUE;
8763a40ed3dSBarry Smith   PetscFunctionReturn(0);
877d9b7c43dSSatish Balay }
878d9b7c43dSSatish Balay 
8795615d1e5SSatish Balay #undef __FUNC__
8805615d1e5SSatish Balay #define __FUNC__ "MatZeroRows_SeqBAIJ"
8818f6be9afSLois Curfman McInnes int MatZeroRows_SeqBAIJ(Mat A,IS is, Scalar *diag)
882d9b7c43dSSatish Balay {
883d9b7c43dSSatish Balay   Mat_SeqBAIJ *baij=(Mat_SeqBAIJ*)A->data;
884d9b7c43dSSatish Balay   IS          is_local;
885d9b7c43dSSatish Balay   int         ierr,i,j,count,m=baij->m,is_n,*is_idx,*rows,bs=baij->bs,bs2=baij->bs2;
886d9b7c43dSSatish Balay   PetscTruth  flg;
887d9b7c43dSSatish Balay   Scalar      zero = 0.0,*aa;
888d9b7c43dSSatish Balay 
8893a40ed3dSBarry Smith   PetscFunctionBegin;
890d9b7c43dSSatish Balay   /* Make a copy of the IS and  sort it */
891d9b7c43dSSatish Balay   ierr = ISGetSize(is,&is_n);CHKERRQ(ierr);
892d9b7c43dSSatish Balay   ierr = ISGetIndices(is,&is_idx);CHKERRQ(ierr);
893537820f0SBarry Smith   ierr = ISCreateGeneral(A->comm,is_n,is_idx,&is_local); CHKERRQ(ierr);
894d9b7c43dSSatish Balay   ierr = ISSort(is_local); CHKERRQ(ierr);
895d9b7c43dSSatish Balay   ierr = ISGetIndices(is_local,&rows); CHKERRQ(ierr);
896d9b7c43dSSatish Balay 
897d9b7c43dSSatish Balay   i = 0;
898d9b7c43dSSatish Balay   while (i < is_n) {
899a8c6a408SBarry Smith     if (rows[i]<0 || rows[i]>m) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"row out of range");
900d9b7c43dSSatish Balay     flg = PETSC_FALSE;
901d9b7c43dSSatish Balay     if (i+bs <= is_n) {ierr = MatZeroRows_SeqBAIJ_Check_Block(rows+i,bs,&flg); CHKERRQ(ierr); }
902d9b7c43dSSatish Balay     count = (baij->i[rows[i]/bs +1] - baij->i[rows[i]/bs])*bs;
903d9b7c43dSSatish Balay     aa    = baij->a + baij->i[rows[i]/bs]*bs2 + (rows[i]%bs);
9042d61bbb3SSatish Balay     if (flg) { /* There exists a block of rows to be Zerowed */
905a07cd24cSSatish Balay       if (baij->ilen[rows[i]/bs] > 0) {
9062d61bbb3SSatish Balay         PetscMemzero(aa,count*bs*sizeof(Scalar));
9072d61bbb3SSatish Balay         baij->ilen[rows[i]/bs] = 1;
9082d61bbb3SSatish Balay         baij->j[baij->i[rows[i]/bs]] = rows[i]/bs;
909a07cd24cSSatish Balay       }
9102d61bbb3SSatish Balay       i += bs;
9112d61bbb3SSatish Balay     } else { /* Zero out only the requested row */
912d9b7c43dSSatish Balay       for ( j=0; j<count; j++ ) {
913d9b7c43dSSatish Balay         aa[0] = zero;
914d9b7c43dSSatish Balay         aa+=bs;
915d9b7c43dSSatish Balay       }
916d9b7c43dSSatish Balay       i++;
917d9b7c43dSSatish Balay     }
918d9b7c43dSSatish Balay   }
919d9b7c43dSSatish Balay   if (diag) {
920d9b7c43dSSatish Balay     for ( j=0; j<is_n; j++ ) {
921f830108cSBarry Smith       ierr = (*A->ops->setvalues)(A,1,rows+j,1,rows+j,diag,INSERT_VALUES);CHKERRQ(ierr);
9222d61bbb3SSatish Balay       /* ierr = MatSetValues(A,1,rows+j,1,rows+j,diag,INSERT_VALUES);CHKERRQ(ierr); */
923d9b7c43dSSatish Balay     }
924d9b7c43dSSatish Balay   }
925d9b7c43dSSatish Balay   ierr = ISRestoreIndices(is,&is_idx); CHKERRQ(ierr);
926d9b7c43dSSatish Balay   ierr = ISRestoreIndices(is_local,&rows); CHKERRQ(ierr);
927d9b7c43dSSatish Balay   ierr = ISDestroy(is_local); CHKERRQ(ierr);
9289a8dea36SBarry Smith   ierr = MatAssemblyEnd_SeqBAIJ(A,MAT_FINAL_ASSEMBLY); CHKERRQ(ierr);
9293a40ed3dSBarry Smith   PetscFunctionReturn(0);
930d9b7c43dSSatish Balay }
9311c351548SSatish Balay 
9325615d1e5SSatish Balay #undef __FUNC__
9332d61bbb3SSatish Balay #define __FUNC__ "MatSetValues_SeqBAIJ"
9342d61bbb3SSatish Balay int MatSetValues_SeqBAIJ(Mat A,int m,int *im,int n,int *in,Scalar *v,InsertMode is)
9352d61bbb3SSatish Balay {
9362d61bbb3SSatish Balay   Mat_SeqBAIJ *a = (Mat_SeqBAIJ *) A->data;
9372d61bbb3SSatish Balay   int         *rp,k,low,high,t,ii,row,nrow,i,col,l,rmax,N,sorted=a->sorted;
9382d61bbb3SSatish Balay   int         *imax=a->imax,*ai=a->i,*ailen=a->ilen,roworiented=a->roworiented;
9392d61bbb3SSatish Balay   int         *aj=a->j,nonew=a->nonew,bs=a->bs,brow,bcol;
9402d61bbb3SSatish Balay   int          ridx,cidx,bs2=a->bs2;
9412d61bbb3SSatish Balay   Scalar      *ap,value,*aa=a->a,*bap;
9422d61bbb3SSatish Balay 
9432d61bbb3SSatish Balay   PetscFunctionBegin;
9442d61bbb3SSatish Balay   for ( k=0; k<m; k++ ) { /* loop over added rows */
9452d61bbb3SSatish Balay     row  = im[k]; brow = row/bs;
9462d61bbb3SSatish Balay #if defined(USE_PETSC_BOPT_g)
9472d61bbb3SSatish Balay     if (row < 0) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Negative row");
9482d61bbb3SSatish Balay     if (row >= a->m) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Row too large");
9492d61bbb3SSatish Balay #endif
9502d61bbb3SSatish Balay     rp   = aj + ai[brow];
9512d61bbb3SSatish Balay     ap   = aa + bs2*ai[brow];
9522d61bbb3SSatish Balay     rmax = imax[brow];
9532d61bbb3SSatish Balay     nrow = ailen[brow];
9542d61bbb3SSatish Balay     low  = 0;
9552d61bbb3SSatish Balay     for ( l=0; l<n; l++ ) { /* loop over added columns */
9562d61bbb3SSatish Balay #if defined(USE_PETSC_BOPT_g)
9572d61bbb3SSatish Balay       if (in[l] < 0) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Negative column");
9582d61bbb3SSatish Balay       if (in[l] >= a->n) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Column too large");
9592d61bbb3SSatish Balay #endif
9602d61bbb3SSatish Balay       col = in[l]; bcol = col/bs;
9612d61bbb3SSatish Balay       ridx = row % bs; cidx = col % bs;
9622d61bbb3SSatish Balay       if (roworiented) {
9632d61bbb3SSatish Balay         value = *v++;
9642d61bbb3SSatish Balay       } else {
9652d61bbb3SSatish Balay         value = v[k + l*m];
9662d61bbb3SSatish Balay       }
9672d61bbb3SSatish Balay       if (!sorted) low = 0; high = nrow;
9682d61bbb3SSatish Balay       while (high-low > 7) {
9692d61bbb3SSatish Balay         t = (low+high)/2;
9702d61bbb3SSatish Balay         if (rp[t] > bcol) high = t;
9712d61bbb3SSatish Balay         else              low  = t;
9722d61bbb3SSatish Balay       }
9732d61bbb3SSatish Balay       for ( i=low; i<high; i++ ) {
9742d61bbb3SSatish Balay         if (rp[i] > bcol) break;
9752d61bbb3SSatish Balay         if (rp[i] == bcol) {
9762d61bbb3SSatish Balay           bap  = ap +  bs2*i + bs*cidx + ridx;
9772d61bbb3SSatish Balay           if (is == ADD_VALUES) *bap += value;
9782d61bbb3SSatish Balay           else                  *bap  = value;
9792d61bbb3SSatish Balay           goto noinsert1;
9802d61bbb3SSatish Balay         }
9812d61bbb3SSatish Balay       }
9822d61bbb3SSatish Balay       if (nonew == 1) goto noinsert1;
9832d61bbb3SSatish Balay       else if (nonew == -1) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Inserting a new nonzero in the matrix");
9842d61bbb3SSatish Balay       if (nrow >= rmax) {
9852d61bbb3SSatish Balay         /* there is no extra room in row, therefore enlarge */
9862d61bbb3SSatish Balay         int    new_nz = ai[a->mbs] + CHUNKSIZE,len,*new_i,*new_j;
9872d61bbb3SSatish Balay         Scalar *new_a;
9882d61bbb3SSatish Balay 
9892d61bbb3SSatish Balay         if (nonew == -2) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Inserting a new nonzero in the matrix");
9902d61bbb3SSatish Balay 
9912d61bbb3SSatish Balay         /* Malloc new storage space */
9922d61bbb3SSatish Balay         len     = new_nz*(sizeof(int)+bs2*sizeof(Scalar))+(a->mbs+1)*sizeof(int);
9932d61bbb3SSatish Balay         new_a   = (Scalar *) PetscMalloc( len ); CHKPTRQ(new_a);
9942d61bbb3SSatish Balay         new_j   = (int *) (new_a + bs2*new_nz);
9952d61bbb3SSatish Balay         new_i   = new_j + new_nz;
9962d61bbb3SSatish Balay 
9972d61bbb3SSatish Balay         /* copy over old data into new slots */
9982d61bbb3SSatish Balay         for ( ii=0; ii<brow+1; ii++ ) {new_i[ii] = ai[ii];}
9992d61bbb3SSatish Balay         for ( ii=brow+1; ii<a->mbs+1; ii++ ) {new_i[ii] = ai[ii]+CHUNKSIZE;}
10002d61bbb3SSatish Balay         PetscMemcpy(new_j,aj,(ai[brow]+nrow)*sizeof(int));
10012d61bbb3SSatish Balay         len = (new_nz - CHUNKSIZE - ai[brow] - nrow);
10022d61bbb3SSatish Balay         PetscMemcpy(new_j+ai[brow]+nrow+CHUNKSIZE,aj+ai[brow]+nrow,
10032d61bbb3SSatish Balay                                                            len*sizeof(int));
10042d61bbb3SSatish Balay         PetscMemcpy(new_a,aa,(ai[brow]+nrow)*bs2*sizeof(Scalar));
10052d61bbb3SSatish Balay         PetscMemzero(new_a+bs2*(ai[brow]+nrow),bs2*CHUNKSIZE*sizeof(Scalar));
10062d61bbb3SSatish Balay         PetscMemcpy(new_a+bs2*(ai[brow]+nrow+CHUNKSIZE),
10072d61bbb3SSatish Balay                     aa+bs2*(ai[brow]+nrow),bs2*len*sizeof(Scalar));
10082d61bbb3SSatish Balay         /* free up old matrix storage */
10092d61bbb3SSatish Balay         PetscFree(a->a);
10102d61bbb3SSatish Balay         if (!a->singlemalloc) {PetscFree(a->i);PetscFree(a->j);}
10112d61bbb3SSatish Balay         aa = a->a = new_a; ai = a->i = new_i; aj = a->j = new_j;
10122d61bbb3SSatish Balay         a->singlemalloc = 1;
10132d61bbb3SSatish Balay 
10142d61bbb3SSatish Balay         rp   = aj + ai[brow]; ap = aa + bs2*ai[brow];
10152d61bbb3SSatish Balay         rmax = imax[brow] = imax[brow] + CHUNKSIZE;
10162d61bbb3SSatish Balay         PLogObjectMemory(A,CHUNKSIZE*(sizeof(int) + bs2*sizeof(Scalar)));
10172d61bbb3SSatish Balay         a->maxnz += bs2*CHUNKSIZE;
10182d61bbb3SSatish Balay         a->reallocs++;
10192d61bbb3SSatish Balay         a->nz++;
10202d61bbb3SSatish Balay       }
10212d61bbb3SSatish Balay       N = nrow++ - 1;
10222d61bbb3SSatish Balay       /* shift up all the later entries in this row */
10232d61bbb3SSatish Balay       for ( ii=N; ii>=i; ii-- ) {
10242d61bbb3SSatish Balay         rp[ii+1] = rp[ii];
10252d61bbb3SSatish Balay         PetscMemcpy(ap+bs2*(ii+1),ap+bs2*(ii),bs2*sizeof(Scalar));
10262d61bbb3SSatish Balay       }
10272d61bbb3SSatish Balay       if (N>=i) PetscMemzero(ap+bs2*i,bs2*sizeof(Scalar));
10282d61bbb3SSatish Balay       rp[i]                      = bcol;
10292d61bbb3SSatish Balay       ap[bs2*i + bs*cidx + ridx] = value;
10302d61bbb3SSatish Balay       noinsert1:;
10312d61bbb3SSatish Balay       low = i;
10322d61bbb3SSatish Balay     }
10332d61bbb3SSatish Balay     ailen[brow] = nrow;
10342d61bbb3SSatish Balay   }
10352d61bbb3SSatish Balay   PetscFunctionReturn(0);
10362d61bbb3SSatish Balay }
10372d61bbb3SSatish Balay 
10382d61bbb3SSatish Balay extern int MatLUFactorSymbolic_SeqBAIJ(Mat,IS,IS,double,Mat*);
10392d61bbb3SSatish Balay extern int MatLUFactor_SeqBAIJ(Mat,IS,IS,double);
10402d61bbb3SSatish Balay extern int MatIncreaseOverlap_SeqBAIJ(Mat,int,IS*,int);
1041d3825aa8SBarry Smith extern int MatGetSubMatrix_SeqBAIJ(Mat,IS,IS,int,MatGetSubMatrixCall,Mat*);
10422d61bbb3SSatish Balay extern int MatGetSubMatrices_SeqBAIJ(Mat,int,IS*,IS*,MatGetSubMatrixCall,Mat**);
10432d61bbb3SSatish Balay extern int MatMultTrans_SeqBAIJ(Mat,Vec,Vec);
10442d61bbb3SSatish Balay extern int MatMultTransAdd_SeqBAIJ(Mat,Vec,Vec,Vec);
10452d61bbb3SSatish Balay extern int MatScale_SeqBAIJ(Scalar*,Mat);
10462d61bbb3SSatish Balay extern int MatNorm_SeqBAIJ(Mat,NormType,double *);
10472d61bbb3SSatish Balay extern int MatEqual_SeqBAIJ(Mat,Mat, PetscTruth*);
10482d61bbb3SSatish Balay extern int MatGetDiagonal_SeqBAIJ(Mat,Vec);
10492d61bbb3SSatish Balay extern int MatDiagonalScale_SeqBAIJ(Mat,Vec,Vec);
10502d61bbb3SSatish Balay extern int MatGetInfo_SeqBAIJ(Mat,MatInfoType,MatInfo *);
10512d61bbb3SSatish Balay extern int MatZeroEntries_SeqBAIJ(Mat);
10522d61bbb3SSatish Balay 
10532d61bbb3SSatish Balay extern int MatSolve_SeqBAIJ_N(Mat,Vec,Vec);
10542d61bbb3SSatish Balay extern int MatSolve_SeqBAIJ_1(Mat,Vec,Vec);
10552d61bbb3SSatish Balay extern int MatSolve_SeqBAIJ_2(Mat,Vec,Vec);
10562d61bbb3SSatish Balay extern int MatSolve_SeqBAIJ_3(Mat,Vec,Vec);
10572d61bbb3SSatish Balay extern int MatSolve_SeqBAIJ_4(Mat,Vec,Vec);
10582d61bbb3SSatish Balay extern int MatSolve_SeqBAIJ_5(Mat,Vec,Vec);
10592d61bbb3SSatish Balay extern int MatSolve_SeqBAIJ_7(Mat,Vec,Vec);
10602d61bbb3SSatish Balay 
10612d61bbb3SSatish Balay extern int MatLUFactorNumeric_SeqBAIJ_N(Mat,Mat*);
10622d61bbb3SSatish Balay extern int MatLUFactorNumeric_SeqBAIJ_1(Mat,Mat*);
10632d61bbb3SSatish Balay extern int MatLUFactorNumeric_SeqBAIJ_2(Mat,Mat*);
10642d61bbb3SSatish Balay extern int MatLUFactorNumeric_SeqBAIJ_3(Mat,Mat*);
10652d61bbb3SSatish Balay extern int MatLUFactorNumeric_SeqBAIJ_4(Mat,Mat*);
10662d61bbb3SSatish Balay extern int MatLUFactorNumeric_SeqBAIJ_5(Mat,Mat*);
10672d61bbb3SSatish Balay extern int MatSolve_SeqBAIJ_4_NaturalOrdering(Mat,Vec,Vec);
10682d61bbb3SSatish Balay 
10692d61bbb3SSatish Balay extern int MatMult_SeqBAIJ_1(Mat,Vec,Vec);
10702d61bbb3SSatish Balay extern int MatMult_SeqBAIJ_2(Mat,Vec,Vec);
10712d61bbb3SSatish Balay extern int MatMult_SeqBAIJ_3(Mat,Vec,Vec);
10722d61bbb3SSatish Balay extern int MatMult_SeqBAIJ_4(Mat,Vec,Vec);
10732d61bbb3SSatish Balay extern int MatMult_SeqBAIJ_5(Mat,Vec,Vec);
10742d61bbb3SSatish Balay extern int MatMult_SeqBAIJ_7(Mat,Vec,Vec);
10752d61bbb3SSatish Balay extern int MatMult_SeqBAIJ_N(Mat,Vec,Vec);
10762d61bbb3SSatish Balay 
10772d61bbb3SSatish Balay extern int MatMultAdd_SeqBAIJ_1(Mat,Vec,Vec,Vec);
10782d61bbb3SSatish Balay extern int MatMultAdd_SeqBAIJ_2(Mat,Vec,Vec,Vec);
10792d61bbb3SSatish Balay extern int MatMultAdd_SeqBAIJ_3(Mat,Vec,Vec,Vec);
10802d61bbb3SSatish Balay extern int MatMultAdd_SeqBAIJ_4(Mat,Vec,Vec,Vec);
10812d61bbb3SSatish Balay extern int MatMultAdd_SeqBAIJ_5(Mat,Vec,Vec,Vec);
10822d61bbb3SSatish Balay extern int MatMultAdd_SeqBAIJ_7(Mat,Vec,Vec,Vec);
10832d61bbb3SSatish Balay extern int MatMultAdd_SeqBAIJ_N(Mat,Vec,Vec,Vec);
10842d61bbb3SSatish Balay 
10852d61bbb3SSatish Balay /*
10862d61bbb3SSatish Balay      note: This can only work for identity for row and col. It would
10872d61bbb3SSatish Balay    be good to check this and otherwise generate an error.
10882d61bbb3SSatish Balay */
10892d61bbb3SSatish Balay #undef __FUNC__
10902d61bbb3SSatish Balay #define __FUNC__ "MatILUFactor_SeqBAIJ"
10912d61bbb3SSatish Balay int MatILUFactor_SeqBAIJ(Mat inA,IS row,IS col,double efill,int fill)
10922d61bbb3SSatish Balay {
10932d61bbb3SSatish Balay   Mat_SeqBAIJ *a = (Mat_SeqBAIJ *) inA->data;
10942d61bbb3SSatish Balay   Mat         outA;
10952d61bbb3SSatish Balay   int         ierr;
10962d61bbb3SSatish Balay 
10972d61bbb3SSatish Balay   PetscFunctionBegin;
10982d61bbb3SSatish Balay   if (fill != 0) SETERRQ(PETSC_ERR_SUP,0,"Only fill=0 supported");
10992d61bbb3SSatish Balay 
11002d61bbb3SSatish Balay   outA          = inA;
11012d61bbb3SSatish Balay   inA->factor   = FACTOR_LU;
11022d61bbb3SSatish Balay   a->row        = row;
11032d61bbb3SSatish Balay   a->col        = col;
11042d61bbb3SSatish Balay 
1105e51c0b9cSSatish Balay   /* Create the invert permutation so that it can be used in MatLUFactorNumeric() */
1106e51c0b9cSSatish Balay   ierr = ISInvertPermutation(col,&(a->icol)); CHKERRQ(ierr);
11071e4dd532SSatish Balay   PLogObjectParent(inA,a->icol);
1108e51c0b9cSSatish Balay 
11092d61bbb3SSatish Balay   if (!a->solve_work) {
11102d61bbb3SSatish Balay     a->solve_work = (Scalar *) PetscMalloc((a->m+a->bs)*sizeof(Scalar));CHKPTRQ(a->solve_work);
11112d61bbb3SSatish Balay     PLogObjectMemory(inA,(a->m+a->bs)*sizeof(Scalar));
11122d61bbb3SSatish Balay   }
11132d61bbb3SSatish Balay 
11142d61bbb3SSatish Balay   if (!a->diag) {
11152d61bbb3SSatish Balay     ierr = MatMarkDiag_SeqBAIJ(inA); CHKERRQ(ierr);
11162d61bbb3SSatish Balay   }
11172d61bbb3SSatish Balay   ierr = MatLUFactorNumeric(inA,&outA); CHKERRQ(ierr);
11182d61bbb3SSatish Balay 
11192d61bbb3SSatish Balay   /*
11202d61bbb3SSatish Balay       Blocksize 4 has a special faster solver for ILU(0) factorization
11212d61bbb3SSatish Balay     with natural ordering
11222d61bbb3SSatish Balay   */
11232d61bbb3SSatish Balay   if (a->bs == 4) {
1124f830108cSBarry Smith     inA->ops->solve = MatSolve_SeqBAIJ_4_NaturalOrdering;
11252d61bbb3SSatish Balay   }
11262d61bbb3SSatish Balay 
11272d61bbb3SSatish Balay   PetscFunctionReturn(0);
11282d61bbb3SSatish Balay }
11292d61bbb3SSatish Balay #undef __FUNC__
1130d4bb536fSBarry Smith #define __FUNC__ "MatPrintHelp_SeqBAIJ"
1131ba4ca20aSSatish Balay int MatPrintHelp_SeqBAIJ(Mat A)
1132ba4ca20aSSatish Balay {
1133ba4ca20aSSatish Balay   static int called = 0;
1134ba4ca20aSSatish Balay   MPI_Comm   comm = A->comm;
1135ba4ca20aSSatish Balay 
11363a40ed3dSBarry Smith   PetscFunctionBegin;
11373a40ed3dSBarry Smith   if (called) {PetscFunctionReturn(0);} else called = 1;
113876be9ce4SBarry Smith   (*PetscHelpPrintf)(comm," Options for MATSEQBAIJ and MATMPIBAIJ matrix formats (the defaults):\n");
113976be9ce4SBarry Smith   (*PetscHelpPrintf)(comm,"  -mat_block_size <block_size>\n");
11403a40ed3dSBarry Smith   PetscFunctionReturn(0);
1141ba4ca20aSSatish Balay }
1142d9b7c43dSSatish Balay 
114327a8da17SBarry Smith #undef __FUNC__
114427a8da17SBarry Smith #define __FUNC__ "MatSeqBAIJSetColumnIndices_SeqBAIJ"
114527a8da17SBarry Smith int MatSeqBAIJSetColumnIndices_SeqBAIJ(Mat mat,int *indices)
114627a8da17SBarry Smith {
114727a8da17SBarry Smith   Mat_SeqBAIJ *baij = (Mat_SeqBAIJ *)mat->data;
114827a8da17SBarry Smith   int         i,nz,n;
114927a8da17SBarry Smith 
115027a8da17SBarry Smith   PetscFunctionBegin;
115127a8da17SBarry Smith   nz = baij->maxnz;
115227a8da17SBarry Smith   n  = baij->n;
115327a8da17SBarry Smith   for (i=0; i<nz; i++) {
115427a8da17SBarry Smith     baij->j[i] = indices[i];
115527a8da17SBarry Smith   }
115627a8da17SBarry Smith   baij->nz = nz;
115727a8da17SBarry Smith   for ( i=0; i<n; i++ ) {
115827a8da17SBarry Smith     baij->ilen[i] = baij->imax[i];
115927a8da17SBarry Smith   }
116027a8da17SBarry Smith 
116127a8da17SBarry Smith   PetscFunctionReturn(0);
116227a8da17SBarry Smith }
116327a8da17SBarry Smith 
116427a8da17SBarry Smith #undef __FUNC__
116527a8da17SBarry Smith #define __FUNC__ "MatSeqBAIJSetColumnIndices"
116627a8da17SBarry Smith /*@
116727a8da17SBarry Smith     MatSeqBAIJSetColumnIndices - Set the column indices for all the rows
116827a8da17SBarry Smith        in the matrix.
116927a8da17SBarry Smith 
117027a8da17SBarry Smith   Input Parameters:
117127a8da17SBarry Smith +  mat - the SeqBAIJ matrix
117227a8da17SBarry Smith -  indices - the column indices
117327a8da17SBarry Smith 
117427a8da17SBarry Smith   Notes:
117527a8da17SBarry Smith     This can be called if you have precomputed the nonzero structure of the
117627a8da17SBarry Smith   matrix and want to provide it to the matrix object to improve the performance
117727a8da17SBarry Smith   of the MatSetValues() operation.
117827a8da17SBarry Smith 
117927a8da17SBarry Smith     You MUST have set the correct numbers of nonzeros per row in the call to
118027a8da17SBarry Smith   MatCreateSeqBAIJ().
118127a8da17SBarry Smith 
118227a8da17SBarry Smith     MUST be called before any calls to MatSetValues();
118327a8da17SBarry Smith 
118427a8da17SBarry Smith @*/
118527a8da17SBarry Smith int MatSeqBAIJSetColumnIndices(Mat mat,int *indices)
118627a8da17SBarry Smith {
118727a8da17SBarry Smith   int ierr,(*f)(Mat,int *);
118827a8da17SBarry Smith 
118927a8da17SBarry Smith   PetscFunctionBegin;
119027a8da17SBarry Smith   PetscValidHeaderSpecific(mat,MAT_COOKIE);
119127a8da17SBarry Smith   ierr = PetscObjectQueryFunction((PetscObject)mat,"MatSeqBAIJSetColumnIndices_C",(void **)&f);
119227a8da17SBarry Smith          CHKERRQ(ierr);
119327a8da17SBarry Smith   if (f) {
119427a8da17SBarry Smith     ierr = (*f)(mat,indices);CHKERRQ(ierr);
119527a8da17SBarry Smith   } else {
119627a8da17SBarry Smith     SETERRQ(1,1,"Wrong type of matrix to set column indices");
119727a8da17SBarry Smith   }
119827a8da17SBarry Smith   PetscFunctionReturn(0);
119927a8da17SBarry Smith }
120027a8da17SBarry Smith 
12012593348eSBarry Smith /* -------------------------------------------------------------------*/
1202cc2dc46cSBarry Smith static struct _MatOps MatOps_Values = {MatSetValues_SeqBAIJ,
1203cc2dc46cSBarry Smith        MatGetRow_SeqBAIJ,
1204cc2dc46cSBarry Smith        MatRestoreRow_SeqBAIJ,
1205cc2dc46cSBarry Smith        MatMult_SeqBAIJ_N,
1206cc2dc46cSBarry Smith        MatMultAdd_SeqBAIJ_N,
1207cc2dc46cSBarry Smith        MatMultTrans_SeqBAIJ,
1208cc2dc46cSBarry Smith        MatMultTransAdd_SeqBAIJ,
1209cc2dc46cSBarry Smith        MatSolve_SeqBAIJ_N,
1210cc2dc46cSBarry Smith        0,
1211cc2dc46cSBarry Smith        0,
1212cc2dc46cSBarry Smith        0,
1213cc2dc46cSBarry Smith        MatLUFactor_SeqBAIJ,
1214cc2dc46cSBarry Smith        0,
1215b6490206SBarry Smith        0,
1216f2501298SSatish Balay        MatTranspose_SeqBAIJ,
1217cc2dc46cSBarry Smith        MatGetInfo_SeqBAIJ,
1218cc2dc46cSBarry Smith        MatEqual_SeqBAIJ,
1219cc2dc46cSBarry Smith        MatGetDiagonal_SeqBAIJ,
1220cc2dc46cSBarry Smith        MatDiagonalScale_SeqBAIJ,
1221cc2dc46cSBarry Smith        MatNorm_SeqBAIJ,
1222b6490206SBarry Smith        0,
1223cc2dc46cSBarry Smith        MatAssemblyEnd_SeqBAIJ,
1224cc2dc46cSBarry Smith        0,
1225cc2dc46cSBarry Smith        MatSetOption_SeqBAIJ,
1226cc2dc46cSBarry Smith        MatZeroEntries_SeqBAIJ,
1227cc2dc46cSBarry Smith        MatZeroRows_SeqBAIJ,
1228cc2dc46cSBarry Smith        MatLUFactorSymbolic_SeqBAIJ,
1229cc2dc46cSBarry Smith        MatLUFactorNumeric_SeqBAIJ_N,
1230cc2dc46cSBarry Smith        0,
1231cc2dc46cSBarry Smith        0,
1232cc2dc46cSBarry Smith        MatGetSize_SeqBAIJ,
1233cc2dc46cSBarry Smith        MatGetSize_SeqBAIJ,
1234cc2dc46cSBarry Smith        MatGetOwnershipRange_SeqBAIJ,
1235cc2dc46cSBarry Smith        MatILUFactorSymbolic_SeqBAIJ,
1236cc2dc46cSBarry Smith        0,
1237cc2dc46cSBarry Smith        0,
1238cc2dc46cSBarry Smith        0,
1239cc2dc46cSBarry Smith        MatConvertSameType_SeqBAIJ,
1240cc2dc46cSBarry Smith        0,
1241cc2dc46cSBarry Smith        0,
1242cc2dc46cSBarry Smith        MatILUFactor_SeqBAIJ,
1243cc2dc46cSBarry Smith        0,
1244cc2dc46cSBarry Smith        0,
1245cc2dc46cSBarry Smith        MatGetSubMatrices_SeqBAIJ,
1246cc2dc46cSBarry Smith        MatIncreaseOverlap_SeqBAIJ,
1247cc2dc46cSBarry Smith        MatGetValues_SeqBAIJ,
1248cc2dc46cSBarry Smith        0,
1249cc2dc46cSBarry Smith        MatPrintHelp_SeqBAIJ,
1250cc2dc46cSBarry Smith        MatScale_SeqBAIJ,
1251cc2dc46cSBarry Smith        0,
1252cc2dc46cSBarry Smith        0,
1253cc2dc46cSBarry Smith        0,
1254cc2dc46cSBarry Smith        MatGetBlockSize_SeqBAIJ,
12553b2fbd54SBarry Smith        MatGetRowIJ_SeqBAIJ,
125692c4ed94SBarry Smith        MatRestoreRowIJ_SeqBAIJ,
1257cc2dc46cSBarry Smith        0,
1258cc2dc46cSBarry Smith        0,
1259cc2dc46cSBarry Smith        0,
1260cc2dc46cSBarry Smith        0,
1261cc2dc46cSBarry Smith        0,
1262cc2dc46cSBarry Smith        0,
1263d3825aa8SBarry Smith        MatSetValuesBlocked_SeqBAIJ,
1264cc2dc46cSBarry Smith        MatGetSubMatrix_SeqBAIJ,
1265cc2dc46cSBarry Smith        0,
1266cc2dc46cSBarry Smith        0,
1267cc2dc46cSBarry Smith        MatGetMaps_Petsc};
12682593348eSBarry Smith 
12695615d1e5SSatish Balay #undef __FUNC__
12705615d1e5SSatish Balay #define __FUNC__ "MatCreateSeqBAIJ"
12712593348eSBarry Smith /*@C
127244cd7ae7SLois Curfman McInnes    MatCreateSeqBAIJ - Creates a sparse matrix in block AIJ (block
127344cd7ae7SLois Curfman McInnes    compressed row) format.  For good matrix assembly performance the
127444cd7ae7SLois Curfman McInnes    user should preallocate the matrix storage by setting the parameter nz
12752bd5e0b2SLois Curfman McInnes    (or the array nzz).  By setting these parameters accurately, performance
12762bd5e0b2SLois Curfman McInnes    during matrix assembly can be increased by more than a factor of 50.
12772593348eSBarry Smith 
1278db81eaa0SLois Curfman McInnes    Collective on MPI_Comm
1279db81eaa0SLois Curfman McInnes 
12802593348eSBarry Smith    Input Parameters:
1281db81eaa0SLois Curfman McInnes +  comm - MPI communicator, set to PETSC_COMM_SELF
1282b6490206SBarry Smith .  bs - size of block
12832593348eSBarry Smith .  m - number of rows
12842593348eSBarry Smith .  n - number of columns
1285b6490206SBarry Smith .  nz - number of block nonzeros per block row (same for all rows)
1286db81eaa0SLois Curfman McInnes -  nzz - array containing the number of block nonzeros in the various block rows
12872bd5e0b2SLois Curfman McInnes          (possibly different for each block row) or PETSC_NULL
12882593348eSBarry Smith 
12892593348eSBarry Smith    Output Parameter:
12902593348eSBarry Smith .  A - the matrix
12912593348eSBarry Smith 
12920513a670SBarry Smith    Options Database Keys:
1293db81eaa0SLois Curfman McInnes .   -mat_no_unroll - uses code that does not unroll the loops in the
1294db81eaa0SLois Curfman McInnes                      block calculations (much slower)
1295db81eaa0SLois Curfman McInnes .    -mat_block_size - size of the blocks to use
12960513a670SBarry Smith 
12972593348eSBarry Smith    Notes:
129844cd7ae7SLois Curfman McInnes    The block AIJ format is fully compatible with standard Fortran 77
12992593348eSBarry Smith    storage.  That is, the stored row and column indices can begin at
130044cd7ae7SLois Curfman McInnes    either one (as in Fortran) or zero.  See the users' manual for details.
13012593348eSBarry Smith 
13022593348eSBarry Smith    Specify the preallocated storage with either nz or nnz (not both).
13032593348eSBarry Smith    Set nz=PETSC_DEFAULT and nnz=PETSC_NULL for PETSc to control dynamic memory
13042593348eSBarry Smith    allocation.  For additional details, see the users manual chapter on
13056da5968aSLois Curfman McInnes    matrices.
13062593348eSBarry Smith 
1307db81eaa0SLois Curfman McInnes .seealso: MatCreate(), MatCreateSeqAIJ(), MatSetValues(), MatCreateMPIBAIJ()
13082593348eSBarry Smith @*/
1309b6490206SBarry Smith int MatCreateSeqBAIJ(MPI_Comm comm,int bs,int m,int n,int nz,int *nnz, Mat *A)
13102593348eSBarry Smith {
13112593348eSBarry Smith   Mat         B;
1312b6490206SBarry Smith   Mat_SeqBAIJ *b;
13133b2fbd54SBarry Smith   int         i,len,ierr,flg,mbs=m/bs,nbs=n/bs,bs2=bs*bs,size;
13143b2fbd54SBarry Smith 
13153a40ed3dSBarry Smith   PetscFunctionBegin;
13163b2fbd54SBarry Smith   MPI_Comm_size(comm,&size);
1317a8c6a408SBarry Smith   if (size > 1) SETERRQ(PETSC_ERR_ARG_WRONG,0,"Comm must be of size 1");
1318b6490206SBarry Smith 
13190513a670SBarry Smith   ierr = OptionsGetInt(PETSC_NULL,"-mat_block_size",&bs,&flg);CHKERRQ(ierr);
13200513a670SBarry Smith 
13213a40ed3dSBarry Smith   if (mbs*bs!=m || nbs*bs!=n) {
1322a8c6a408SBarry Smith     SETERRQ(PETSC_ERR_ARG_SIZ,0,"Number rows, cols must be divisible by blocksize");
13233a40ed3dSBarry Smith   }
13242593348eSBarry Smith 
13252593348eSBarry Smith   *A = 0;
1326f830108cSBarry Smith   PetscHeaderCreate(B,_p_Mat,struct _MatOps,MAT_COOKIE,MATSEQBAIJ,comm,MatDestroy,MatView);
13272593348eSBarry Smith   PLogObjectCreate(B);
1328b6490206SBarry Smith   B->data = (void *) (b = PetscNew(Mat_SeqBAIJ)); CHKPTRQ(b);
132944cd7ae7SLois Curfman McInnes   PetscMemzero(b,sizeof(Mat_SeqBAIJ));
1330cc2dc46cSBarry Smith   PetscMemcpy(B->ops,&MatOps_Values,sizeof(struct _MatOps));
13311a6a6d98SBarry Smith   ierr = OptionsHasName(PETSC_NULL,"-mat_no_unroll",&flg); CHKERRQ(ierr);
13321a6a6d98SBarry Smith   if (!flg) {
13337fc0212eSBarry Smith     switch (bs) {
13347fc0212eSBarry Smith     case 1:
1335f830108cSBarry Smith       B->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_1;
1336f830108cSBarry Smith       B->ops->solve           = MatSolve_SeqBAIJ_1;
1337f830108cSBarry Smith       B->ops->mult            = MatMult_SeqBAIJ_1;
1338f830108cSBarry Smith       B->ops->multadd         = MatMultAdd_SeqBAIJ_1;
13397fc0212eSBarry Smith       break;
13404eeb42bcSBarry Smith     case 2:
1341f830108cSBarry Smith       B->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_2;
1342f830108cSBarry Smith       B->ops->solve           = MatSolve_SeqBAIJ_2;
1343f830108cSBarry Smith       B->ops->mult            = MatMult_SeqBAIJ_2;
1344f830108cSBarry Smith       B->ops->multadd         = MatMultAdd_SeqBAIJ_2;
13456d84be18SBarry Smith       break;
1346f327dd97SBarry Smith     case 3:
1347f830108cSBarry Smith       B->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_3;
1348f830108cSBarry Smith       B->ops->solve           = MatSolve_SeqBAIJ_3;
1349f830108cSBarry Smith       B->ops->mult            = MatMult_SeqBAIJ_3;
1350f830108cSBarry Smith       B->ops->multadd         = MatMultAdd_SeqBAIJ_3;
13514eeb42bcSBarry Smith       break;
13526d84be18SBarry Smith     case 4:
1353f830108cSBarry Smith       B->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_4;
1354f830108cSBarry Smith       B->ops->solve           = MatSolve_SeqBAIJ_4;
1355f830108cSBarry Smith       B->ops->mult            = MatMult_SeqBAIJ_4;
1356f830108cSBarry Smith       B->ops->multadd         = MatMultAdd_SeqBAIJ_4;
13576d84be18SBarry Smith       break;
13586d84be18SBarry Smith     case 5:
1359f830108cSBarry Smith       B->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_5;
1360f830108cSBarry Smith       B->ops->solve           = MatSolve_SeqBAIJ_5;
1361f830108cSBarry Smith       B->ops->mult            = MatMult_SeqBAIJ_5;
1362f830108cSBarry Smith       B->ops->multadd         = MatMultAdd_SeqBAIJ_5;
13636d84be18SBarry Smith       break;
136448e9ddb2SSatish Balay     case 7:
1365f830108cSBarry Smith       B->ops->mult            = MatMult_SeqBAIJ_7;
1366f830108cSBarry Smith       B->ops->solve           = MatSolve_SeqBAIJ_7;
1367f830108cSBarry Smith       B->ops->multadd         = MatMultAdd_SeqBAIJ_7;
136848e9ddb2SSatish Balay       break;
13697fc0212eSBarry Smith     }
13701a6a6d98SBarry Smith   }
1371e1311b90SBarry Smith   B->ops->destroy          = MatDestroy_SeqBAIJ;
1372e1311b90SBarry Smith   B->ops->view             = MatView_SeqBAIJ;
13732593348eSBarry Smith   B->factor           = 0;
13742593348eSBarry Smith   B->lupivotthreshold = 1.0;
137590f02eecSBarry Smith   B->mapping          = 0;
13762593348eSBarry Smith   b->row              = 0;
13772593348eSBarry Smith   b->col              = 0;
1378e51c0b9cSSatish Balay   b->icol             = 0;
13792593348eSBarry Smith   b->reallocs         = 0;
13802593348eSBarry Smith 
138144cd7ae7SLois Curfman McInnes   b->m       = m; B->m = m; B->M = m;
138244cd7ae7SLois Curfman McInnes   b->n       = n; B->n = n; B->N = n;
1383*a5ae1ecdSBarry Smith 
1384*a5ae1ecdSBarry Smith   ierr = MapCreate(comm,m,m,B->rmap);CHKERRQ(ierr);
1385*a5ae1ecdSBarry Smith   ierr = MapCreate(comm,n,n,B->cmap);CHKERRQ(ierr);
1386*a5ae1ecdSBarry Smith 
1387b6490206SBarry Smith   b->mbs     = mbs;
1388f2501298SSatish Balay   b->nbs     = nbs;
1389b6490206SBarry Smith   b->imax    = (int *) PetscMalloc( (mbs+1)*sizeof(int) ); CHKPTRQ(b->imax);
13902593348eSBarry Smith   if (nnz == PETSC_NULL) {
1391119a934aSSatish Balay     if (nz == PETSC_DEFAULT) nz = 5;
13922593348eSBarry Smith     else if (nz <= 0)        nz = 1;
1393b6490206SBarry Smith     for ( i=0; i<mbs; i++ ) b->imax[i] = nz;
1394b6490206SBarry Smith     nz = nz*mbs;
13953a40ed3dSBarry Smith   } else {
13962593348eSBarry Smith     nz = 0;
1397b6490206SBarry Smith     for ( i=0; i<mbs; i++ ) {b->imax[i] = nnz[i]; nz += nnz[i];}
13982593348eSBarry Smith   }
13992593348eSBarry Smith 
14002593348eSBarry Smith   /* allocate the matrix space */
14017e67e3f9SSatish Balay   len   = nz*sizeof(int) + nz*bs2*sizeof(Scalar) + (b->m+1)*sizeof(int);
14022593348eSBarry Smith   b->a  = (Scalar *) PetscMalloc( len ); CHKPTRQ(b->a);
14037e67e3f9SSatish Balay   PetscMemzero(b->a,nz*bs2*sizeof(Scalar));
14047e67e3f9SSatish Balay   b->j  = (int *) (b->a + nz*bs2);
14052593348eSBarry Smith   PetscMemzero(b->j,nz*sizeof(int));
14062593348eSBarry Smith   b->i  = b->j + nz;
14072593348eSBarry Smith   b->singlemalloc = 1;
14082593348eSBarry Smith 
1409de6a44a3SBarry Smith   b->i[0] = 0;
1410b6490206SBarry Smith   for (i=1; i<mbs+1; i++) {
14112593348eSBarry Smith     b->i[i] = b->i[i-1] + b->imax[i-1];
14122593348eSBarry Smith   }
14132593348eSBarry Smith 
1414b6490206SBarry Smith   /* b->ilen will count nonzeros in each block row so far. */
1415b6490206SBarry Smith   b->ilen = (int *) PetscMalloc((mbs+1)*sizeof(int));
1416f09e8eb9SSatish Balay   PLogObjectMemory(B,len+2*(mbs+1)*sizeof(int)+sizeof(struct _p_Mat)+sizeof(Mat_SeqBAIJ));
1417b6490206SBarry Smith   for ( i=0; i<mbs; i++ ) { b->ilen[i] = 0;}
14182593348eSBarry Smith 
1419b6490206SBarry Smith   b->bs               = bs;
14209df24120SSatish Balay   b->bs2              = bs2;
1421b6490206SBarry Smith   b->mbs              = mbs;
14222593348eSBarry Smith   b->nz               = 0;
142318e7b8e4SLois Curfman McInnes   b->maxnz            = nz*bs2;
14242593348eSBarry Smith   b->sorted           = 0;
14252593348eSBarry Smith   b->roworiented      = 1;
14262593348eSBarry Smith   b->nonew            = 0;
14272593348eSBarry Smith   b->diag             = 0;
14282593348eSBarry Smith   b->solve_work       = 0;
1429de6a44a3SBarry Smith   b->mult_work        = 0;
14302593348eSBarry Smith   b->spptr            = 0;
14314e220ebcSLois Curfman McInnes   B->info.nz_unneeded = (double)b->maxnz;
14324e220ebcSLois Curfman McInnes 
14332593348eSBarry Smith   *A = B;
14342593348eSBarry Smith   ierr = OptionsHasName(PETSC_NULL,"-help", &flg); CHKERRQ(ierr);
14352593348eSBarry Smith   if (flg) {ierr = MatPrintHelp(B); CHKERRQ(ierr); }
143627a8da17SBarry Smith 
143727a8da17SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatSeqBAIJSetColumnIndices_C",
143827a8da17SBarry Smith                                      "MatSeqBAIJSetColumnIndices_SeqBAIJ",
143927a8da17SBarry Smith                                      (void*)MatSeqBAIJSetColumnIndices_SeqBAIJ);CHKERRQ(ierr);
144027a8da17SBarry Smith 
14413a40ed3dSBarry Smith   PetscFunctionReturn(0);
14422593348eSBarry Smith }
14432593348eSBarry Smith 
14445615d1e5SSatish Balay #undef __FUNC__
14455615d1e5SSatish Balay #define __FUNC__ "MatConvertSameType_SeqBAIJ"
1446b6490206SBarry Smith int MatConvertSameType_SeqBAIJ(Mat A,Mat *B,int cpvalues)
14472593348eSBarry Smith {
14482593348eSBarry Smith   Mat         C;
1449b6490206SBarry Smith   Mat_SeqBAIJ *c,*a = (Mat_SeqBAIJ *) A->data;
145027a8da17SBarry Smith   int         i,len, mbs = a->mbs,nz = a->nz,bs2 =a->bs2,ierr;
1451de6a44a3SBarry Smith 
14523a40ed3dSBarry Smith   PetscFunctionBegin;
1453a8c6a408SBarry Smith   if (a->i[mbs] != nz) SETERRQ(PETSC_ERR_PLIB,0,"Corrupt matrix");
14542593348eSBarry Smith 
14552593348eSBarry Smith   *B = 0;
1456f830108cSBarry Smith   PetscHeaderCreate(C,_p_Mat,struct _MatOps,MAT_COOKIE,MATSEQBAIJ,A->comm,MatDestroy,MatView);
14572593348eSBarry Smith   PLogObjectCreate(C);
1458b6490206SBarry Smith   C->data       = (void *) (c = PetscNew(Mat_SeqBAIJ)); CHKPTRQ(c);
1459c3c66ee5SSatish Balay   PetscMemcpy(C->ops,A->ops,sizeof(struct _MatOps));
1460e1311b90SBarry Smith   C->ops->destroy    = MatDestroy_SeqBAIJ;
1461e1311b90SBarry Smith   C->ops->view       = MatView_SeqBAIJ;
14622593348eSBarry Smith   C->factor     = A->factor;
14632593348eSBarry Smith   c->row        = 0;
14642593348eSBarry Smith   c->col        = 0;
14652593348eSBarry Smith   C->assembled  = PETSC_TRUE;
14662593348eSBarry Smith 
146744cd7ae7SLois Curfman McInnes   c->m = C->m   = a->m;
146844cd7ae7SLois Curfman McInnes   c->n = C->n   = a->n;
146944cd7ae7SLois Curfman McInnes   C->M          = a->m;
147044cd7ae7SLois Curfman McInnes   C->N          = a->n;
147144cd7ae7SLois Curfman McInnes 
1472b6490206SBarry Smith   c->bs         = a->bs;
14739df24120SSatish Balay   c->bs2        = a->bs2;
1474b6490206SBarry Smith   c->mbs        = a->mbs;
1475b6490206SBarry Smith   c->nbs        = a->nbs;
14762593348eSBarry Smith 
1477b6490206SBarry Smith   c->imax       = (int *) PetscMalloc((mbs+1)*sizeof(int)); CHKPTRQ(c->imax);
1478b6490206SBarry Smith   c->ilen       = (int *) PetscMalloc((mbs+1)*sizeof(int)); CHKPTRQ(c->ilen);
1479b6490206SBarry Smith   for ( i=0; i<mbs; i++ ) {
14802593348eSBarry Smith     c->imax[i] = a->imax[i];
14812593348eSBarry Smith     c->ilen[i] = a->ilen[i];
14822593348eSBarry Smith   }
14832593348eSBarry Smith 
14842593348eSBarry Smith   /* allocate the matrix space */
14852593348eSBarry Smith   c->singlemalloc = 1;
14867e67e3f9SSatish Balay   len   = (mbs+1)*sizeof(int) + nz*(bs2*sizeof(Scalar) + sizeof(int));
14872593348eSBarry Smith   c->a  = (Scalar *) PetscMalloc( len ); CHKPTRQ(c->a);
14887e67e3f9SSatish Balay   c->j  = (int *) (c->a + nz*bs2);
1489de6a44a3SBarry Smith   c->i  = c->j + nz;
1490b6490206SBarry Smith   PetscMemcpy(c->i,a->i,(mbs+1)*sizeof(int));
1491b6490206SBarry Smith   if (mbs > 0) {
1492de6a44a3SBarry Smith     PetscMemcpy(c->j,a->j,nz*sizeof(int));
14932593348eSBarry Smith     if (cpvalues == COPY_VALUES) {
14947e67e3f9SSatish Balay       PetscMemcpy(c->a,a->a,bs2*nz*sizeof(Scalar));
14952593348eSBarry Smith     }
14962593348eSBarry Smith   }
14972593348eSBarry Smith 
1498f09e8eb9SSatish Balay   PLogObjectMemory(C,len+2*(mbs+1)*sizeof(int)+sizeof(struct _p_Mat)+sizeof(Mat_SeqBAIJ));
14992593348eSBarry Smith   c->sorted      = a->sorted;
15002593348eSBarry Smith   c->roworiented = a->roworiented;
15012593348eSBarry Smith   c->nonew       = a->nonew;
15022593348eSBarry Smith 
15032593348eSBarry Smith   if (a->diag) {
1504b6490206SBarry Smith     c->diag = (int *) PetscMalloc( (mbs+1)*sizeof(int) ); CHKPTRQ(c->diag);
1505b6490206SBarry Smith     PLogObjectMemory(C,(mbs+1)*sizeof(int));
1506b6490206SBarry Smith     for ( i=0; i<mbs; i++ ) {
15072593348eSBarry Smith       c->diag[i] = a->diag[i];
15082593348eSBarry Smith     }
15092593348eSBarry Smith   }
15102593348eSBarry Smith   else c->diag          = 0;
15112593348eSBarry Smith   c->nz                 = a->nz;
15122593348eSBarry Smith   c->maxnz              = a->maxnz;
15132593348eSBarry Smith   c->solve_work         = 0;
15142593348eSBarry Smith   c->spptr              = 0;      /* Dangerous -I'm throwing away a->spptr */
15157fc0212eSBarry Smith   c->mult_work          = 0;
15162593348eSBarry Smith   *B = C;
151727a8da17SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)C,"MatSeqBAIJSetColumnIndices_C",
151827a8da17SBarry Smith                                      "MatSeqBAIJSetColumnIndices_SeqBAIJ",
151927a8da17SBarry Smith                                      (void*)MatSeqBAIJSetColumnIndices_SeqBAIJ);CHKERRQ(ierr);
15203a40ed3dSBarry Smith   PetscFunctionReturn(0);
15212593348eSBarry Smith }
15222593348eSBarry Smith 
15235615d1e5SSatish Balay #undef __FUNC__
15245615d1e5SSatish Balay #define __FUNC__ "MatLoad_SeqBAIJ"
152519bcc07fSBarry Smith int MatLoad_SeqBAIJ(Viewer viewer,MatType type,Mat *A)
15262593348eSBarry Smith {
1527b6490206SBarry Smith   Mat_SeqBAIJ  *a;
15282593348eSBarry Smith   Mat          B;
1529de6a44a3SBarry Smith   int          i,nz,ierr,fd,header[4],size,*rowlengths=0,M,N,bs=1,flg;
1530b6490206SBarry Smith   int          *mask,mbs,*jj,j,rowcount,nzcount,k,*browlengths,maskcount;
153135aab85fSBarry Smith   int          kmax,jcount,block,idx,point,nzcountb,extra_rows;
1532a7c10996SSatish Balay   int          *masked, nmask,tmp,bs2,ishift;
1533b6490206SBarry Smith   Scalar       *aa;
153419bcc07fSBarry Smith   MPI_Comm     comm = ((PetscObject) viewer)->comm;
15352593348eSBarry Smith 
15363a40ed3dSBarry Smith   PetscFunctionBegin;
15371a6a6d98SBarry Smith   ierr = OptionsGetInt(PETSC_NULL,"-matload_block_size",&bs,&flg);CHKERRQ(ierr);
1538de6a44a3SBarry Smith   bs2  = bs*bs;
1539b6490206SBarry Smith 
15402593348eSBarry Smith   MPI_Comm_size(comm,&size);
1541cc0fae11SBarry Smith   if (size > 1) SETERRQ(PETSC_ERR_ARG_WRONG,0,"view must have one processor");
154290ace30eSBarry Smith   ierr = ViewerBinaryGetDescriptor(viewer,&fd); CHKERRQ(ierr);
15430752156aSBarry Smith   ierr = PetscBinaryRead(fd,header,4,PETSC_INT); CHKERRQ(ierr);
1544a8c6a408SBarry Smith   if (header[0] != MAT_COOKIE) SETERRQ(PETSC_ERR_FILE_UNEXPECTED,0,"not Mat object");
15452593348eSBarry Smith   M = header[1]; N = header[2]; nz = header[3];
15462593348eSBarry Smith 
1547d64ed03dSBarry Smith   if (header[3] < 0) {
1548a8c6a408SBarry Smith     SETERRQ(PETSC_ERR_FILE_UNEXPECTED,1,"Matrix stored in special format, cannot load as SeqBAIJ");
1549d64ed03dSBarry Smith   }
1550d64ed03dSBarry Smith 
1551a8c6a408SBarry Smith   if (M != N) SETERRQ(PETSC_ERR_SUP,0,"Can only do square matrices");
155235aab85fSBarry Smith 
155335aab85fSBarry Smith   /*
155435aab85fSBarry Smith      This code adds extra rows to make sure the number of rows is
155535aab85fSBarry Smith     divisible by the blocksize
155635aab85fSBarry Smith   */
1557b6490206SBarry Smith   mbs        = M/bs;
155835aab85fSBarry Smith   extra_rows = bs - M + bs*(mbs);
155935aab85fSBarry Smith   if (extra_rows == bs) extra_rows = 0;
156035aab85fSBarry Smith   else                  mbs++;
156135aab85fSBarry Smith   if (extra_rows) {
1562537820f0SBarry Smith     PLogInfo(0,"MatLoad_SeqBAIJ:Padding loaded matrix to match blocksize\n");
156335aab85fSBarry Smith   }
1564b6490206SBarry Smith 
15652593348eSBarry Smith   /* read in row lengths */
156635aab85fSBarry Smith   rowlengths = (int*) PetscMalloc((M+extra_rows)*sizeof(int));CHKPTRQ(rowlengths);
15670752156aSBarry Smith   ierr = PetscBinaryRead(fd,rowlengths,M,PETSC_INT); CHKERRQ(ierr);
156835aab85fSBarry Smith   for ( i=0; i<extra_rows; i++ ) rowlengths[M+i] = 1;
15692593348eSBarry Smith 
1570b6490206SBarry Smith   /* read in column indices */
157135aab85fSBarry Smith   jj = (int*) PetscMalloc( (nz+extra_rows)*sizeof(int) ); CHKPTRQ(jj);
15720752156aSBarry Smith   ierr = PetscBinaryRead(fd,jj,nz,PETSC_INT); CHKERRQ(ierr);
157335aab85fSBarry Smith   for ( i=0; i<extra_rows; i++ ) jj[nz+i] = M+i;
1574b6490206SBarry Smith 
1575b6490206SBarry Smith   /* loop over row lengths determining block row lengths */
1576b6490206SBarry Smith   browlengths = (int *) PetscMalloc(mbs*sizeof(int));CHKPTRQ(browlengths);
1577b6490206SBarry Smith   PetscMemzero(browlengths,mbs*sizeof(int));
157835aab85fSBarry Smith   mask   = (int *) PetscMalloc( 2*mbs*sizeof(int) ); CHKPTRQ(mask);
157935aab85fSBarry Smith   PetscMemzero(mask,mbs*sizeof(int));
158035aab85fSBarry Smith   masked = mask + mbs;
1581b6490206SBarry Smith   rowcount = 0; nzcount = 0;
1582b6490206SBarry Smith   for ( i=0; i<mbs; i++ ) {
158335aab85fSBarry Smith     nmask = 0;
1584b6490206SBarry Smith     for ( j=0; j<bs; j++ ) {
1585b6490206SBarry Smith       kmax = rowlengths[rowcount];
1586b6490206SBarry Smith       for ( k=0; k<kmax; k++ ) {
158735aab85fSBarry Smith         tmp = jj[nzcount++]/bs;
158835aab85fSBarry Smith         if (!mask[tmp]) {masked[nmask++] = tmp; mask[tmp] = 1;}
1589b6490206SBarry Smith       }
1590b6490206SBarry Smith       rowcount++;
1591b6490206SBarry Smith     }
159235aab85fSBarry Smith     browlengths[i] += nmask;
159335aab85fSBarry Smith     /* zero out the mask elements we set */
159435aab85fSBarry Smith     for ( j=0; j<nmask; j++ ) mask[masked[j]] = 0;
1595b6490206SBarry Smith   }
1596b6490206SBarry Smith 
15972593348eSBarry Smith   /* create our matrix */
15983eee16b0SBarry Smith   ierr = MatCreateSeqBAIJ(comm,bs,M+extra_rows,N+extra_rows,0,browlengths,A);CHKERRQ(ierr);
15992593348eSBarry Smith   B = *A;
1600b6490206SBarry Smith   a = (Mat_SeqBAIJ *) B->data;
16012593348eSBarry Smith 
16022593348eSBarry Smith   /* set matrix "i" values */
1603de6a44a3SBarry Smith   a->i[0] = 0;
1604b6490206SBarry Smith   for ( i=1; i<= mbs; i++ ) {
1605b6490206SBarry Smith     a->i[i]      = a->i[i-1] + browlengths[i-1];
1606b6490206SBarry Smith     a->ilen[i-1] = browlengths[i-1];
16072593348eSBarry Smith   }
1608b6490206SBarry Smith   a->nz         = 0;
1609b6490206SBarry Smith   for ( i=0; i<mbs; i++ ) a->nz += browlengths[i];
16102593348eSBarry Smith 
1611b6490206SBarry Smith   /* read in nonzero values */
161235aab85fSBarry Smith   aa = (Scalar *) PetscMalloc((nz+extra_rows)*sizeof(Scalar));CHKPTRQ(aa);
16130752156aSBarry Smith   ierr = PetscBinaryRead(fd,aa,nz,PETSC_SCALAR); CHKERRQ(ierr);
161435aab85fSBarry Smith   for ( i=0; i<extra_rows; i++ ) aa[nz+i] = 1.0;
1615b6490206SBarry Smith 
1616b6490206SBarry Smith   /* set "a" and "j" values into matrix */
1617b6490206SBarry Smith   nzcount = 0; jcount = 0;
1618b6490206SBarry Smith   for ( i=0; i<mbs; i++ ) {
1619b6490206SBarry Smith     nzcountb = nzcount;
162035aab85fSBarry Smith     nmask    = 0;
1621b6490206SBarry Smith     for ( j=0; j<bs; j++ ) {
1622b6490206SBarry Smith       kmax = rowlengths[i*bs+j];
1623b6490206SBarry Smith       for ( k=0; k<kmax; k++ ) {
162435aab85fSBarry Smith         tmp = jj[nzcount++]/bs;
162535aab85fSBarry Smith 	if (!mask[tmp]) { masked[nmask++] = tmp; mask[tmp] = 1;}
1626b6490206SBarry Smith       }
1627b6490206SBarry Smith       rowcount++;
1628b6490206SBarry Smith     }
1629de6a44a3SBarry Smith     /* sort the masked values */
163077c4ece6SBarry Smith     PetscSortInt(nmask,masked);
1631de6a44a3SBarry Smith 
1632b6490206SBarry Smith     /* set "j" values into matrix */
1633b6490206SBarry Smith     maskcount = 1;
163435aab85fSBarry Smith     for ( j=0; j<nmask; j++ ) {
163535aab85fSBarry Smith       a->j[jcount++]  = masked[j];
1636de6a44a3SBarry Smith       mask[masked[j]] = maskcount++;
1637b6490206SBarry Smith     }
1638b6490206SBarry Smith     /* set "a" values into matrix */
1639de6a44a3SBarry Smith     ishift = bs2*a->i[i];
1640b6490206SBarry Smith     for ( j=0; j<bs; j++ ) {
1641b6490206SBarry Smith       kmax = rowlengths[i*bs+j];
1642b6490206SBarry Smith       for ( k=0; k<kmax; k++ ) {
1643de6a44a3SBarry Smith         tmp    = jj[nzcountb]/bs ;
1644de6a44a3SBarry Smith         block  = mask[tmp] - 1;
1645de6a44a3SBarry Smith         point  = jj[nzcountb] - bs*tmp;
1646de6a44a3SBarry Smith         idx    = ishift + bs2*block + j + bs*point;
1647b6490206SBarry Smith         a->a[idx] = aa[nzcountb++];
1648b6490206SBarry Smith       }
1649b6490206SBarry Smith     }
165035aab85fSBarry Smith     /* zero out the mask elements we set */
165135aab85fSBarry Smith     for ( j=0; j<nmask; j++ ) mask[masked[j]] = 0;
1652b6490206SBarry Smith   }
1653a8c6a408SBarry Smith   if (jcount != a->nz) SETERRQ(PETSC_ERR_FILE_UNEXPECTED,0,"Bad binary matrix");
1654b6490206SBarry Smith 
1655b6490206SBarry Smith   PetscFree(rowlengths);
1656b6490206SBarry Smith   PetscFree(browlengths);
1657b6490206SBarry Smith   PetscFree(aa);
1658b6490206SBarry Smith   PetscFree(jj);
1659b6490206SBarry Smith   PetscFree(mask);
1660b6490206SBarry Smith 
1661b6490206SBarry Smith   B->assembled = PETSC_TRUE;
1662de6a44a3SBarry Smith 
16639c01be13SBarry Smith   ierr = MatView_Private(B); CHKERRQ(ierr);
16643a40ed3dSBarry Smith   PetscFunctionReturn(0);
16652593348eSBarry Smith }
16662593348eSBarry Smith 
16672593348eSBarry Smith 
16682593348eSBarry Smith 
1669