xref: /petsc/src/mat/impls/baij/seq/baij.c (revision 29bbc08cd5461c366aba6645924e8ff42acd1de0)
1*29bbc08cSBarry Smith /*$Id: baij.c,v 1.211 2000/09/06 18:34:20 bsmith Exp bsmith $*/
22593348eSBarry Smith 
32593348eSBarry Smith /*
4b6490206SBarry Smith     Defines the basic matrix operations for the BAIJ (compressed row)
52593348eSBarry Smith   matrix storage format.
62593348eSBarry Smith */
7e090d566SSatish Balay #include "petscsys.h"
870f55243SBarry Smith #include "src/mat/impls/baij/seq/baij.h"
91a6a6d98SBarry Smith #include "src/vec/vecimpl.h"
101a6a6d98SBarry Smith #include "src/inline/spops.h"
113b547af2SSatish Balay 
1295d5f7c2SBarry Smith /*  UGLY, ugly, ugly
1395d5f7c2SBarry Smith    When MatScalar == Scalar the function MatSetValuesBlocked_SeqBAIJ_MatScalar() does
1495d5f7c2SBarry Smith    not exist. Otherwise ..._MatScalar() takes matrix elements in single precision and
1595d5f7c2SBarry Smith    inserts them into the single precision data structure. The function MatSetValuesBlocked_SeqBAIJ()
1695d5f7c2SBarry Smith    converts the entries into single precision and then calls ..._MatScalar() to put them
1795d5f7c2SBarry Smith    into the single precision data structures.
1895d5f7c2SBarry Smith */
1995d5f7c2SBarry Smith #if defined(PETSC_USE_MAT_SINGLE)
20ca44d042SBarry Smith EXTERN int MatSetValuesBlocked_SeqBAIJ_MatScalar(Mat,int,int*,int,int*,MatScalar*,InsertMode);
2195d5f7c2SBarry Smith #else
2295d5f7c2SBarry Smith #define MatSetValuesBlocked_SeqBAIJ_MatScalar MatSetValuesBlocked_SeqBAIJ
2395d5f7c2SBarry Smith #endif
2495d5f7c2SBarry Smith 
252d61bbb3SSatish Balay #define CHUNKSIZE  10
26de6a44a3SBarry Smith 
27be5855fcSBarry Smith /*
28be5855fcSBarry Smith      Checks for missing diagonals
29be5855fcSBarry Smith */
30be5855fcSBarry Smith #undef __FUNC__
31b2863d3aSBarry Smith #define __FUNC__ /*<a name=""></a>*/"MatMissingDiagonal_SeqBAIJ"
32c4992f7dSBarry Smith int MatMissingDiagonal_SeqBAIJ(Mat A)
33be5855fcSBarry Smith {
34be5855fcSBarry Smith   Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)A->data;
35883fce79SBarry Smith   int         *diag,*jj = a->j,i,ierr;
36be5855fcSBarry Smith 
37be5855fcSBarry Smith   PetscFunctionBegin;
38c4992f7dSBarry Smith   ierr = MatMarkDiagonal_SeqBAIJ(A);CHKERRQ(ierr);
39883fce79SBarry Smith   diag = a->diag;
400e8e8aceSBarry Smith   for (i=0; i<a->mbs; i++) {
41be5855fcSBarry Smith     if (jj[diag[i]] != i) {
42*29bbc08cSBarry Smith       SETERRQ1(1,"Matrix is missing diagonal number %d",i);
43be5855fcSBarry Smith     }
44be5855fcSBarry Smith   }
45be5855fcSBarry Smith   PetscFunctionReturn(0);
46be5855fcSBarry Smith }
47be5855fcSBarry Smith 
485615d1e5SSatish Balay #undef __FUNC__
49b2863d3aSBarry Smith #define __FUNC__ /*<a name=""></a>*/"MatMarkDiagonal_SeqBAIJ"
50c4992f7dSBarry Smith int MatMarkDiagonal_SeqBAIJ(Mat A)
51de6a44a3SBarry Smith {
52de6a44a3SBarry Smith   Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)A->data;
537fc0212eSBarry Smith   int         i,j,*diag,m = a->mbs;
54de6a44a3SBarry Smith 
553a40ed3dSBarry Smith   PetscFunctionBegin;
56883fce79SBarry Smith   if (a->diag) PetscFunctionReturn(0);
57883fce79SBarry Smith 
58de6a44a3SBarry Smith   diag = (int*)PetscMalloc((m+1)*sizeof(int));CHKPTRQ(diag);
59de6a44a3SBarry Smith   PLogObjectMemory(A,(m+1)*sizeof(int));
607fc0212eSBarry Smith   for (i=0; i<m; i++) {
61ecc615b2SBarry Smith     diag[i] = a->i[i+1];
62de6a44a3SBarry Smith     for (j=a->i[i]; j<a->i[i+1]; j++) {
63de6a44a3SBarry Smith       if (a->j[j] == i) {
64de6a44a3SBarry Smith         diag[i] = j;
65de6a44a3SBarry Smith         break;
66de6a44a3SBarry Smith       }
67de6a44a3SBarry Smith     }
68de6a44a3SBarry Smith   }
69de6a44a3SBarry Smith   a->diag = diag;
703a40ed3dSBarry Smith   PetscFunctionReturn(0);
71de6a44a3SBarry Smith }
722593348eSBarry Smith 
732593348eSBarry Smith 
74ca44d042SBarry Smith EXTERN int MatToSymmetricIJ_SeqAIJ(int,int*,int*,int,int,int**,int**);
753b2fbd54SBarry Smith 
765615d1e5SSatish Balay #undef __FUNC__
77b2863d3aSBarry Smith #define __FUNC__ /*<a name=""></a>*/"MatGetRowIJ_SeqBAIJ"
780e6d2581SBarry Smith static int MatGetRowIJ_SeqBAIJ(Mat A,int oshift,PetscTruth symmetric,int *nn,int **ia,int **ja,PetscTruth *done)
793b2fbd54SBarry Smith {
803b2fbd54SBarry Smith   Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)A->data;
813b2fbd54SBarry Smith   int         ierr,n = a->mbs,i;
823b2fbd54SBarry Smith 
833a40ed3dSBarry Smith   PetscFunctionBegin;
843b2fbd54SBarry Smith   *nn = n;
853a40ed3dSBarry Smith   if (!ia) PetscFunctionReturn(0);
863b2fbd54SBarry Smith   if (symmetric) {
873b2fbd54SBarry Smith     ierr = MatToSymmetricIJ_SeqAIJ(n,a->i,a->j,0,oshift,ia,ja);CHKERRQ(ierr);
883b2fbd54SBarry Smith   } else if (oshift == 1) {
893b2fbd54SBarry Smith     /* temporarily add 1 to i and j indices */
903b2fbd54SBarry Smith     int nz = a->i[n] + 1;
913b2fbd54SBarry Smith     for (i=0; i<nz; i++) a->j[i]++;
923b2fbd54SBarry Smith     for (i=0; i<n+1; i++) a->i[i]++;
933b2fbd54SBarry Smith     *ia = a->i; *ja = a->j;
943b2fbd54SBarry Smith   } else {
953b2fbd54SBarry Smith     *ia = a->i; *ja = a->j;
963b2fbd54SBarry Smith   }
973b2fbd54SBarry Smith 
983a40ed3dSBarry Smith   PetscFunctionReturn(0);
993b2fbd54SBarry Smith }
1003b2fbd54SBarry Smith 
1015615d1e5SSatish Balay #undef __FUNC__
102b2863d3aSBarry Smith #define __FUNC__ /*<a name=""></a>*/"MatRestoreRowIJ_SeqBAIJ"
1033b2fbd54SBarry Smith static int MatRestoreRowIJ_SeqBAIJ(Mat A,int oshift,PetscTruth symmetric,int *nn,int **ia,int **ja,
1043b2fbd54SBarry Smith                                 PetscTruth *done)
1053b2fbd54SBarry Smith {
1063b2fbd54SBarry Smith   Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)A->data;
107606d414cSSatish Balay   int         i,n = a->mbs,ierr;
1083b2fbd54SBarry Smith 
1093a40ed3dSBarry Smith   PetscFunctionBegin;
1103a40ed3dSBarry Smith   if (!ia) PetscFunctionReturn(0);
1113b2fbd54SBarry Smith   if (symmetric) {
112606d414cSSatish Balay     ierr = PetscFree(*ia);CHKERRQ(ierr);
113606d414cSSatish Balay     ierr = PetscFree(*ja);CHKERRQ(ierr);
114af5da2bfSBarry Smith   } else if (oshift == 1) {
1153b2fbd54SBarry Smith     int nz = a->i[n];
1163b2fbd54SBarry Smith     for (i=0; i<nz; i++) a->j[i]--;
1173b2fbd54SBarry Smith     for (i=0; i<n+1; i++) a->i[i]--;
1183b2fbd54SBarry Smith   }
1193a40ed3dSBarry Smith   PetscFunctionReturn(0);
1203b2fbd54SBarry Smith }
1213b2fbd54SBarry Smith 
1222d61bbb3SSatish Balay #undef __FUNC__
123b2863d3aSBarry Smith #define __FUNC__ /*<a name=""></a>*/"MatGetBlockSize_SeqBAIJ"
1242d61bbb3SSatish Balay int MatGetBlockSize_SeqBAIJ(Mat mat,int *bs)
1252d61bbb3SSatish Balay {
1262d61bbb3SSatish Balay   Mat_SeqBAIJ *baij = (Mat_SeqBAIJ*)mat->data;
1272d61bbb3SSatish Balay 
1282d61bbb3SSatish Balay   PetscFunctionBegin;
1292d61bbb3SSatish Balay   *bs = baij->bs;
1302d61bbb3SSatish Balay   PetscFunctionReturn(0);
1312d61bbb3SSatish Balay }
1322d61bbb3SSatish Balay 
1332d61bbb3SSatish Balay 
1342d61bbb3SSatish Balay #undef __FUNC__
135b2863d3aSBarry Smith #define __FUNC__ /*<a name=""></a>*/"MatDestroy_SeqBAIJ"
136e1311b90SBarry Smith int MatDestroy_SeqBAIJ(Mat A)
1372d61bbb3SSatish Balay {
1382d61bbb3SSatish Balay   Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)A->data;
139e51c0b9cSSatish Balay   int         ierr;
1402d61bbb3SSatish Balay 
141433994e6SBarry Smith   PetscFunctionBegin;
14294d884c6SBarry Smith   if (A->mapping) {
14394d884c6SBarry Smith     ierr = ISLocalToGlobalMappingDestroy(A->mapping);CHKERRQ(ierr);
14494d884c6SBarry Smith   }
14594d884c6SBarry Smith   if (A->bmapping) {
14694d884c6SBarry Smith     ierr = ISLocalToGlobalMappingDestroy(A->bmapping);CHKERRQ(ierr);
14794d884c6SBarry Smith   }
14861b13de0SBarry Smith   if (A->rmap) {
14961b13de0SBarry Smith     ierr = MapDestroy(A->rmap);CHKERRQ(ierr);
15061b13de0SBarry Smith   }
15161b13de0SBarry Smith   if (A->cmap) {
15261b13de0SBarry Smith     ierr = MapDestroy(A->cmap);CHKERRQ(ierr);
15361b13de0SBarry Smith   }
154aa482453SBarry Smith #if defined(PETSC_USE_LOG)
155e1311b90SBarry Smith   PLogObjectState((PetscObject)A,"Rows=%d, Cols=%d, NZ=%d",a->m,a->n,a->nz);
1562d61bbb3SSatish Balay #endif
157606d414cSSatish Balay   ierr = PetscFree(a->a);CHKERRQ(ierr);
158606d414cSSatish Balay   if (!a->singlemalloc) {
159606d414cSSatish Balay     ierr = PetscFree(a->i);CHKERRQ(ierr);
160606d414cSSatish Balay     ierr = PetscFree(a->j);CHKERRQ(ierr);
161606d414cSSatish Balay   }
162c38d4ed2SBarry Smith   if (a->row) {
163c38d4ed2SBarry Smith     ierr = ISDestroy(a->row);CHKERRQ(ierr);
164c38d4ed2SBarry Smith   }
165c38d4ed2SBarry Smith   if (a->col) {
166c38d4ed2SBarry Smith     ierr = ISDestroy(a->col);CHKERRQ(ierr);
167c38d4ed2SBarry Smith   }
168606d414cSSatish Balay   if (a->diag) {ierr = PetscFree(a->diag);CHKERRQ(ierr);}
169606d414cSSatish Balay   if (a->ilen) {ierr = PetscFree(a->ilen);CHKERRQ(ierr);}
170606d414cSSatish Balay   if (a->imax) {ierr = PetscFree(a->imax);CHKERRQ(ierr);}
171606d414cSSatish Balay   if (a->solve_work) {ierr = PetscFree(a->solve_work);CHKERRQ(ierr);}
172606d414cSSatish Balay   if (a->mult_work) {ierr = PetscFree(a->mult_work);CHKERRQ(ierr);}
173e51c0b9cSSatish Balay   if (a->icol) {ierr = ISDestroy(a->icol);CHKERRQ(ierr);}
174606d414cSSatish Balay   if (a->saved_values) {ierr = PetscFree(a->saved_values);CHKERRQ(ierr);}
175563b5814SBarry Smith #if defined(PETSC_USE_MAT_SINGLE)
176563b5814SBarry Smith   if (a->setvaluescopy) {ierr = PetscFree(a->setvaluescopy);CHKERRQ(ierr);}
177563b5814SBarry Smith #endif
178606d414cSSatish Balay   ierr = PetscFree(a);CHKERRQ(ierr);
1792d61bbb3SSatish Balay   PLogObjectDestroy(A);
1802d61bbb3SSatish Balay   PetscHeaderDestroy(A);
1812d61bbb3SSatish Balay   PetscFunctionReturn(0);
1822d61bbb3SSatish Balay }
1832d61bbb3SSatish Balay 
1842d61bbb3SSatish Balay #undef __FUNC__
185b2863d3aSBarry Smith #define __FUNC__ /*<a name=""></a>*/"MatSetOption_SeqBAIJ"
1862d61bbb3SSatish Balay int MatSetOption_SeqBAIJ(Mat A,MatOption op)
1872d61bbb3SSatish Balay {
1882d61bbb3SSatish Balay   Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)A->data;
1892d61bbb3SSatish Balay 
1902d61bbb3SSatish Balay   PetscFunctionBegin;
191c4992f7dSBarry Smith   if      (op == MAT_ROW_ORIENTED)                 a->roworiented    = PETSC_TRUE;
192c4992f7dSBarry Smith   else if (op == MAT_COLUMN_ORIENTED)              a->roworiented    = PETSC_FALSE;
193c4992f7dSBarry Smith   else if (op == MAT_COLUMNS_SORTED)               a->sorted         = PETSC_TRUE;
194c4992f7dSBarry Smith   else if (op == MAT_COLUMNS_UNSORTED)             a->sorted         = PETSC_FALSE;
195c4992f7dSBarry Smith   else if (op == MAT_KEEP_ZEROED_ROWS)             a->keepzeroedrows = PETSC_TRUE;
1962d61bbb3SSatish Balay   else if (op == MAT_NO_NEW_NONZERO_LOCATIONS)     a->nonew          = 1;
1974787f768SSatish Balay   else if (op == MAT_NEW_NONZERO_LOCATION_ERR)     a->nonew          = -1;
1984787f768SSatish Balay   else if (op == MAT_NEW_NONZERO_ALLOCATION_ERR)   a->nonew          = -2;
1992d61bbb3SSatish Balay   else if (op == MAT_YES_NEW_NONZERO_LOCATIONS)    a->nonew          = 0;
2002d61bbb3SSatish Balay   else if (op == MAT_ROWS_SORTED ||
2012d61bbb3SSatish Balay            op == MAT_ROWS_UNSORTED ||
2022d61bbb3SSatish Balay            op == MAT_SYMMETRIC ||
2032d61bbb3SSatish Balay            op == MAT_STRUCTURALLY_SYMMETRIC ||
2042d61bbb3SSatish Balay            op == MAT_YES_NEW_DIAGONALS ||
205b51ba29fSSatish Balay            op == MAT_IGNORE_OFF_PROC_ENTRIES ||
206b51ba29fSSatish Balay            op == MAT_USE_HASH_TABLE) {
207981c4779SBarry Smith     PLogInfo(A,"MatSetOption_SeqBAIJ:Option ignored\n");
2082d61bbb3SSatish Balay   } else if (op == MAT_NO_NEW_DIAGONALS) {
209*29bbc08cSBarry Smith     SETERRQ(PETSC_ERR_SUP,"MAT_NO_NEW_DIAGONALS");
2102d61bbb3SSatish Balay   } else {
211*29bbc08cSBarry Smith     SETERRQ(PETSC_ERR_SUP,"unknown option");
2122d61bbb3SSatish Balay   }
2132d61bbb3SSatish Balay   PetscFunctionReturn(0);
2142d61bbb3SSatish Balay }
2152d61bbb3SSatish Balay 
2162d61bbb3SSatish Balay 
2172d61bbb3SSatish Balay #undef __FUNC__
218b2863d3aSBarry Smith #define __FUNC__ /*<a name=""></a>*/"MatGetSize_SeqBAIJ"
2192d61bbb3SSatish Balay int MatGetSize_SeqBAIJ(Mat A,int *m,int *n)
2202d61bbb3SSatish Balay {
2212d61bbb3SSatish Balay   Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)A->data;
2222d61bbb3SSatish Balay 
2232d61bbb3SSatish Balay   PetscFunctionBegin;
2242d61bbb3SSatish Balay   if (m) *m = a->m;
2252d61bbb3SSatish Balay   if (n) *n = a->n;
2262d61bbb3SSatish Balay   PetscFunctionReturn(0);
2272d61bbb3SSatish Balay }
2282d61bbb3SSatish Balay 
2292d61bbb3SSatish Balay #undef __FUNC__
230b2863d3aSBarry Smith #define __FUNC__ /*<a name=""></a>*/"MatGetOwnershipRange_SeqBAIJ"
2312d61bbb3SSatish Balay int MatGetOwnershipRange_SeqBAIJ(Mat A,int *m,int *n)
2322d61bbb3SSatish Balay {
2332d61bbb3SSatish Balay   Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)A->data;
2342d61bbb3SSatish Balay 
2352d61bbb3SSatish Balay   PetscFunctionBegin;
2364c49b128SBarry Smith   if (m) *m = 0;
2374c49b128SBarry Smith   if (n) *n = a->m;
2382d61bbb3SSatish Balay   PetscFunctionReturn(0);
2392d61bbb3SSatish Balay }
2402d61bbb3SSatish Balay 
2412d61bbb3SSatish Balay #undef __FUNC__
242b2863d3aSBarry Smith #define __FUNC__ /*<a name=""></a>*/"MatGetRow_SeqBAIJ"
2432d61bbb3SSatish Balay int MatGetRow_SeqBAIJ(Mat A,int row,int *nz,int **idx,Scalar **v)
2442d61bbb3SSatish Balay {
2452d61bbb3SSatish Balay   Mat_SeqBAIJ  *a = (Mat_SeqBAIJ*)A->data;
2462d61bbb3SSatish Balay   int          itmp,i,j,k,M,*ai,*aj,bs,bn,bp,*idx_i,bs2;
2473f1db9ecSBarry Smith   MatScalar    *aa,*aa_i;
2483f1db9ecSBarry Smith   Scalar       *v_i;
2492d61bbb3SSatish Balay 
2502d61bbb3SSatish Balay   PetscFunctionBegin;
2512d61bbb3SSatish Balay   bs  = a->bs;
2522d61bbb3SSatish Balay   ai  = a->i;
2532d61bbb3SSatish Balay   aj  = a->j;
2542d61bbb3SSatish Balay   aa  = a->a;
2552d61bbb3SSatish Balay   bs2 = a->bs2;
2562d61bbb3SSatish Balay 
257*29bbc08cSBarry Smith   if (row < 0 || row >= a->m) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Row out of range");
2582d61bbb3SSatish Balay 
2592d61bbb3SSatish Balay   bn  = row/bs;   /* Block number */
2602d61bbb3SSatish Balay   bp  = row % bs; /* Block Position */
2612d61bbb3SSatish Balay   M   = ai[bn+1] - ai[bn];
2622d61bbb3SSatish Balay   *nz = bs*M;
2632d61bbb3SSatish Balay 
2642d61bbb3SSatish Balay   if (v) {
2652d61bbb3SSatish Balay     *v = 0;
2662d61bbb3SSatish Balay     if (*nz) {
2672d61bbb3SSatish Balay       *v = (Scalar*)PetscMalloc((*nz)*sizeof(Scalar));CHKPTRQ(*v);
2682d61bbb3SSatish Balay       for (i=0; i<M; i++) { /* for each block in the block row */
2692d61bbb3SSatish Balay         v_i  = *v + i*bs;
2702d61bbb3SSatish Balay         aa_i = aa + bs2*(ai[bn] + i);
2712d61bbb3SSatish Balay         for (j=bp,k=0; j<bs2; j+=bs,k++) {v_i[k] = aa_i[j];}
2722d61bbb3SSatish Balay       }
2732d61bbb3SSatish Balay     }
2742d61bbb3SSatish Balay   }
2752d61bbb3SSatish Balay 
2762d61bbb3SSatish Balay   if (idx) {
2772d61bbb3SSatish Balay     *idx = 0;
2782d61bbb3SSatish Balay     if (*nz) {
2792d61bbb3SSatish Balay       *idx = (int*)PetscMalloc((*nz)*sizeof(int));CHKPTRQ(*idx);
2802d61bbb3SSatish Balay       for (i=0; i<M; i++) { /* for each block in the block row */
2812d61bbb3SSatish Balay         idx_i = *idx + i*bs;
2822d61bbb3SSatish Balay         itmp  = bs*aj[ai[bn] + i];
2832d61bbb3SSatish Balay         for (j=0; j<bs; j++) {idx_i[j] = itmp++;}
2842d61bbb3SSatish Balay       }
2852d61bbb3SSatish Balay     }
2862d61bbb3SSatish Balay   }
2872d61bbb3SSatish Balay   PetscFunctionReturn(0);
2882d61bbb3SSatish Balay }
2892d61bbb3SSatish Balay 
2902d61bbb3SSatish Balay #undef __FUNC__
291b2863d3aSBarry Smith #define __FUNC__ /*<a name=""></a>*/"MatRestoreRow_SeqBAIJ"
2922d61bbb3SSatish Balay int MatRestoreRow_SeqBAIJ(Mat A,int row,int *nz,int **idx,Scalar **v)
2932d61bbb3SSatish Balay {
294606d414cSSatish Balay   int ierr;
295606d414cSSatish Balay 
2962d61bbb3SSatish Balay   PetscFunctionBegin;
297606d414cSSatish Balay   if (idx) {if (*idx) {ierr = PetscFree(*idx);CHKERRQ(ierr);}}
298606d414cSSatish Balay   if (v)   {if (*v)   {ierr = PetscFree(*v);CHKERRQ(ierr);}}
2992d61bbb3SSatish Balay   PetscFunctionReturn(0);
3002d61bbb3SSatish Balay }
3012d61bbb3SSatish Balay 
3022d61bbb3SSatish Balay #undef __FUNC__
303b2863d3aSBarry Smith #define __FUNC__ /*<a name=""></a>*/"MatTranspose_SeqBAIJ"
3042d61bbb3SSatish Balay int MatTranspose_SeqBAIJ(Mat A,Mat *B)
3052d61bbb3SSatish Balay {
3062d61bbb3SSatish Balay   Mat_SeqBAIJ *a=(Mat_SeqBAIJ *)A->data;
3072d61bbb3SSatish Balay   Mat         C;
3082d61bbb3SSatish Balay   int         i,j,k,ierr,*aj=a->j,*ai=a->i,bs=a->bs,mbs=a->mbs,nbs=a->nbs,len,*col;
3090e6d2581SBarry Smith   int         *rows,*cols,bs2=a->bs2,refct;
310375fe846SBarry Smith   Scalar      *array;
3112d61bbb3SSatish Balay 
3122d61bbb3SSatish Balay   PetscFunctionBegin;
313*29bbc08cSBarry Smith   if (!B && mbs!=nbs) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Square matrix only for in-place");
3142d61bbb3SSatish Balay   col  = (int*)PetscMalloc((1+nbs)*sizeof(int));CHKPTRQ(col);
315549d3d68SSatish Balay   ierr = PetscMemzero(col,(1+nbs)*sizeof(int));CHKERRQ(ierr);
3162d61bbb3SSatish Balay 
317375fe846SBarry Smith #if defined(PETSC_USE_MAT_SINGLE)
318375fe846SBarry Smith   array = (Scalar *)PetscMalloc(a->bs2*a->nz*sizeof(Scalar));CHKPTRQ(array);
319375fe846SBarry Smith   for (i=0; i<a->bs2*a->nz; i++) array[i] = (Scalar)a->a[i];
320375fe846SBarry Smith #else
3213eda8832SBarry Smith   array = a->a;
322375fe846SBarry Smith #endif
323375fe846SBarry Smith 
3242d61bbb3SSatish Balay   for (i=0; i<ai[mbs]; i++) col[aj[i]] += 1;
3252d61bbb3SSatish Balay   ierr = MatCreateSeqBAIJ(A->comm,bs,a->n,a->m,PETSC_NULL,col,&C);CHKERRQ(ierr);
326606d414cSSatish Balay   ierr = PetscFree(col);CHKERRQ(ierr);
3272d61bbb3SSatish Balay   rows = (int*)PetscMalloc(2*bs*sizeof(int));CHKPTRQ(rows);
3282d61bbb3SSatish Balay   cols = rows + bs;
3292d61bbb3SSatish Balay   for (i=0; i<mbs; i++) {
3302d61bbb3SSatish Balay     cols[0] = i*bs;
3312d61bbb3SSatish Balay     for (k=1; k<bs; k++) cols[k] = cols[k-1] + 1;
3322d61bbb3SSatish Balay     len = ai[i+1] - ai[i];
3332d61bbb3SSatish Balay     for (j=0; j<len; j++) {
3342d61bbb3SSatish Balay       rows[0] = (*aj++)*bs;
3352d61bbb3SSatish Balay       for (k=1; k<bs; k++) rows[k] = rows[k-1] + 1;
3362d61bbb3SSatish Balay       ierr = MatSetValues(C,bs,rows,bs,cols,array,INSERT_VALUES);CHKERRQ(ierr);
3372d61bbb3SSatish Balay       array += bs2;
3382d61bbb3SSatish Balay     }
3392d61bbb3SSatish Balay   }
340606d414cSSatish Balay   ierr = PetscFree(rows);CHKERRQ(ierr);
341375fe846SBarry Smith #if defined(PETSC_USE_MAT_SINGLE)
342375fe846SBarry Smith   ierr = PetscFree(array);
343375fe846SBarry Smith #endif
3442d61bbb3SSatish Balay 
3452d61bbb3SSatish Balay   ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
3462d61bbb3SSatish Balay   ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
3472d61bbb3SSatish Balay 
348c4992f7dSBarry Smith   if (B) {
3492d61bbb3SSatish Balay     *B = C;
3502d61bbb3SSatish Balay   } else {
351f830108cSBarry Smith     PetscOps *Abops;
352cc2dc46cSBarry Smith     MatOps   Aops;
353f830108cSBarry Smith 
3542d61bbb3SSatish Balay     /* This isn't really an in-place transpose */
355606d414cSSatish Balay     ierr = PetscFree(a->a);CHKERRQ(ierr);
356606d414cSSatish Balay     if (!a->singlemalloc) {
357606d414cSSatish Balay       ierr = PetscFree(a->i);CHKERRQ(ierr);
358606d414cSSatish Balay       ierr = PetscFree(a->j);CHKERRQ(ierr);
359606d414cSSatish Balay     }
360606d414cSSatish Balay     if (a->diag) {ierr = PetscFree(a->diag);CHKERRQ(ierr);}
361606d414cSSatish Balay     if (a->ilen) {ierr = PetscFree(a->ilen);CHKERRQ(ierr);}
362606d414cSSatish Balay     if (a->imax) {ierr = PetscFree(a->imax);CHKERRQ(ierr);}
363606d414cSSatish Balay     if (a->solve_work) {ierr = PetscFree(a->solve_work);CHKERRQ(ierr);}
364606d414cSSatish Balay     ierr = PetscFree(a);CHKERRQ(ierr);
365f830108cSBarry Smith 
3667413bad6SBarry Smith 
3677413bad6SBarry Smith     ierr = MapDestroy(A->rmap);CHKERRQ(ierr);
3687413bad6SBarry Smith     ierr = MapDestroy(A->cmap);CHKERRQ(ierr);
3697413bad6SBarry Smith 
370f830108cSBarry Smith     /*
371f830108cSBarry Smith        This is horrible, horrible code. We need to keep the
372f830108cSBarry Smith       A pointers for the bops and ops but copy everything
373f830108cSBarry Smith       else from C.
374f830108cSBarry Smith     */
375f830108cSBarry Smith     Abops    = A->bops;
376f830108cSBarry Smith     Aops     = A->ops;
3770e6d2581SBarry Smith     refct    = A->refct;
378549d3d68SSatish Balay     ierr     = PetscMemcpy(A,C,sizeof(struct _p_Mat));CHKERRQ(ierr);
379f830108cSBarry Smith     A->bops  = Abops;
380f830108cSBarry Smith     A->ops   = Aops;
38127a8da17SBarry Smith     A->qlist = 0;
3820e6d2581SBarry Smith     A->refct = refct;
383f830108cSBarry Smith 
3842d61bbb3SSatish Balay     PetscHeaderDestroy(C);
3852d61bbb3SSatish Balay   }
3862d61bbb3SSatish Balay   PetscFunctionReturn(0);
3872d61bbb3SSatish Balay }
3882d61bbb3SSatish Balay 
3895615d1e5SSatish Balay #undef __FUNC__
390b2863d3aSBarry Smith #define __FUNC__ /*<a name=""></a>*/"MatView_SeqBAIJ_Binary"
391b6490206SBarry Smith static int MatView_SeqBAIJ_Binary(Mat A,Viewer viewer)
3922593348eSBarry Smith {
393b6490206SBarry Smith   Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)A->data;
3949df24120SSatish Balay   int         i,fd,*col_lens,ierr,bs = a->bs,count,*jj,j,k,l,bs2=a->bs2;
395b6490206SBarry Smith   Scalar      *aa;
396ce6f0cecSBarry Smith   FILE        *file;
3972593348eSBarry Smith 
3983a40ed3dSBarry Smith   PetscFunctionBegin;
39990ace30eSBarry Smith   ierr = ViewerBinaryGetDescriptor(viewer,&fd);CHKERRQ(ierr);
4002593348eSBarry Smith   col_lens = (int*)PetscMalloc((4+a->m)*sizeof(int));CHKPTRQ(col_lens);
4012593348eSBarry Smith   col_lens[0] = MAT_COOKIE;
4023b2fbd54SBarry Smith 
4032593348eSBarry Smith   col_lens[1] = a->m;
4042593348eSBarry Smith   col_lens[2] = a->n;
4057e67e3f9SSatish Balay   col_lens[3] = a->nz*bs2;
4062593348eSBarry Smith 
4072593348eSBarry Smith   /* store lengths of each row and write (including header) to file */
408b6490206SBarry Smith   count = 0;
409b6490206SBarry Smith   for (i=0; i<a->mbs; i++) {
410b6490206SBarry Smith     for (j=0; j<bs; j++) {
411b6490206SBarry Smith       col_lens[4+count++] = bs*(a->i[i+1] - a->i[i]);
412b6490206SBarry Smith     }
4132593348eSBarry Smith   }
4140752156aSBarry Smith   ierr = PetscBinaryWrite(fd,col_lens,4+a->m,PETSC_INT,1);CHKERRQ(ierr);
415606d414cSSatish Balay   ierr = PetscFree(col_lens);CHKERRQ(ierr);
4162593348eSBarry Smith 
4172593348eSBarry Smith   /* store column indices (zero start index) */
41866963ce1SSatish Balay   jj = (int*)PetscMalloc((a->nz+1)*bs2*sizeof(int));CHKPTRQ(jj);
419b6490206SBarry Smith   count = 0;
420b6490206SBarry Smith   for (i=0; i<a->mbs; i++) {
421b6490206SBarry Smith     for (j=0; j<bs; j++) {
422b6490206SBarry Smith       for (k=a->i[i]; k<a->i[i+1]; k++) {
423b6490206SBarry Smith         for (l=0; l<bs; l++) {
424b6490206SBarry Smith           jj[count++] = bs*a->j[k] + l;
4252593348eSBarry Smith         }
4262593348eSBarry Smith       }
427b6490206SBarry Smith     }
428b6490206SBarry Smith   }
4290752156aSBarry Smith   ierr = PetscBinaryWrite(fd,jj,bs2*a->nz,PETSC_INT,0);CHKERRQ(ierr);
430606d414cSSatish Balay   ierr = PetscFree(jj);CHKERRQ(ierr);
4312593348eSBarry Smith 
4322593348eSBarry Smith   /* store nonzero values */
43366963ce1SSatish Balay   aa = (Scalar*)PetscMalloc((a->nz+1)*bs2*sizeof(Scalar));CHKPTRQ(aa);
434b6490206SBarry Smith   count = 0;
435b6490206SBarry Smith   for (i=0; i<a->mbs; i++) {
436b6490206SBarry Smith     for (j=0; j<bs; j++) {
437b6490206SBarry Smith       for (k=a->i[i]; k<a->i[i+1]; k++) {
438b6490206SBarry Smith         for (l=0; l<bs; l++) {
4397e67e3f9SSatish Balay           aa[count++] = a->a[bs2*k + l*bs + j];
440b6490206SBarry Smith         }
441b6490206SBarry Smith       }
442b6490206SBarry Smith     }
443b6490206SBarry Smith   }
4440752156aSBarry Smith   ierr = PetscBinaryWrite(fd,aa,bs2*a->nz,PETSC_SCALAR,0);CHKERRQ(ierr);
445606d414cSSatish Balay   ierr = PetscFree(aa);CHKERRQ(ierr);
446ce6f0cecSBarry Smith 
447ce6f0cecSBarry Smith   ierr = ViewerBinaryGetInfoPointer(viewer,&file);CHKERRQ(ierr);
448ce6f0cecSBarry Smith   if (file) {
449ce6f0cecSBarry Smith     fprintf(file,"-matload_block_size %d\n",a->bs);
450ce6f0cecSBarry Smith   }
4513a40ed3dSBarry Smith   PetscFunctionReturn(0);
4522593348eSBarry Smith }
4532593348eSBarry Smith 
4545615d1e5SSatish Balay #undef __FUNC__
455b2863d3aSBarry Smith #define __FUNC__ /*<a name=""></a>*/"MatView_SeqBAIJ_ASCII"
456b6490206SBarry Smith static int MatView_SeqBAIJ_ASCII(Mat A,Viewer viewer)
4572593348eSBarry Smith {
458b6490206SBarry Smith   Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)A->data;
4599df24120SSatish Balay   int         ierr,i,j,format,bs = a->bs,k,l,bs2=a->bs2;
4602593348eSBarry Smith   char        *outputname;
4612593348eSBarry Smith 
4623a40ed3dSBarry Smith   PetscFunctionBegin;
46377ed5343SBarry Smith   ierr = ViewerGetOutputname(viewer,&outputname);CHKERRQ(ierr);
464888f2ed8SSatish Balay   ierr = ViewerGetFormat(viewer,&format);CHKERRQ(ierr);
465639f9d9dSBarry Smith   if (format == VIEWER_FORMAT_ASCII_INFO || format == VIEWER_FORMAT_ASCII_INFO_LONG) {
466d132466eSBarry Smith     ierr = ViewerASCIIPrintf(viewer,"  block size is %d\n",bs);CHKERRQ(ierr);
4670ef38995SBarry Smith   } else if (format == VIEWER_FORMAT_ASCII_MATLAB) {
468*29bbc08cSBarry Smith     SETERRQ(PETSC_ERR_SUP,"Matlab format not supported");
4690ef38995SBarry Smith   } else if (format == VIEWER_FORMAT_ASCII_COMMON) {
4706831982aSBarry Smith     ierr = ViewerASCIIUseTabs(viewer,PETSC_NO);CHKERRQ(ierr);
47144cd7ae7SLois Curfman McInnes     for (i=0; i<a->mbs; i++) {
47244cd7ae7SLois Curfman McInnes       for (j=0; j<bs; j++) {
4736831982aSBarry Smith         ierr = ViewerASCIIPrintf(viewer,"row %d:",i*bs+j);CHKERRQ(ierr);
47444cd7ae7SLois Curfman McInnes         for (k=a->i[i]; k<a->i[i+1]; k++) {
47544cd7ae7SLois Curfman McInnes           for (l=0; l<bs; l++) {
476aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
4770e6d2581SBarry Smith             if (PetscImaginaryPart(a->a[bs2*k + l*bs + j]) > 0.0 && PetscRealPart(a->a[bs2*k + l*bs + j]) != 0.0) {
4786831982aSBarry Smith               ierr = ViewerASCIIPrintf(viewer," %d %g + %gi",bs*a->j[k]+l,
4790e6d2581SBarry Smith                       PetscRealPart(a->a[bs2*k + l*bs + j]),PetscImaginaryPart(a->a[bs2*k + l*bs + j]));CHKERRQ(ierr);
4800e6d2581SBarry Smith             } else if (PetscImaginaryPart(a->a[bs2*k + l*bs + j]) < 0.0 && PetscRealPart(a->a[bs2*k + l*bs + j]) != 0.0) {
4816831982aSBarry Smith               ierr = ViewerASCIIPrintf(viewer," %d %g - %gi",bs*a->j[k]+l,
4820e6d2581SBarry Smith                       PetscRealPart(a->a[bs2*k + l*bs + j]),-PetscImaginaryPart(a->a[bs2*k + l*bs + j]));CHKERRQ(ierr);
4830e6d2581SBarry Smith             } else if (PetscRealPart(a->a[bs2*k + l*bs + j]) != 0.0) {
4840e6d2581SBarry Smith               ierr = ViewerASCIIPrintf(viewer," %d %g ",bs*a->j[k]+l,PetscRealPart(a->a[bs2*k + l*bs + j]));CHKERRQ(ierr);
4850ef38995SBarry Smith             }
48644cd7ae7SLois Curfman McInnes #else
4870ef38995SBarry Smith             if (a->a[bs2*k + l*bs + j] != 0.0) {
4886831982aSBarry Smith               ierr = ViewerASCIIPrintf(viewer," %d %g ",bs*a->j[k]+l,a->a[bs2*k + l*bs + j]);CHKERRQ(ierr);
4890ef38995SBarry Smith             }
49044cd7ae7SLois Curfman McInnes #endif
49144cd7ae7SLois Curfman McInnes           }
49244cd7ae7SLois Curfman McInnes         }
4936831982aSBarry Smith         ierr = ViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
49444cd7ae7SLois Curfman McInnes       }
49544cd7ae7SLois Curfman McInnes     }
4966831982aSBarry Smith     ierr = ViewerASCIIUseTabs(viewer,PETSC_YES);CHKERRQ(ierr);
4970ef38995SBarry Smith   } else {
4986831982aSBarry Smith     ierr = ViewerASCIIUseTabs(viewer,PETSC_NO);CHKERRQ(ierr);
499b6490206SBarry Smith     for (i=0; i<a->mbs; i++) {
500b6490206SBarry Smith       for (j=0; j<bs; j++) {
5016831982aSBarry Smith         ierr = ViewerASCIIPrintf(viewer,"row %d:",i*bs+j);CHKERRQ(ierr);
502b6490206SBarry Smith         for (k=a->i[i]; k<a->i[i+1]; k++) {
503b6490206SBarry Smith           for (l=0; l<bs; l++) {
504aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
5050e6d2581SBarry Smith             if (PetscImaginaryPart(a->a[bs2*k + l*bs + j]) > 0.0) {
5066831982aSBarry Smith               ierr = ViewerASCIIPrintf(viewer," %d %g + %g i",bs*a->j[k]+l,
5070e6d2581SBarry Smith                 PetscRealPart(a->a[bs2*k + l*bs + j]),PetscImaginaryPart(a->a[bs2*k + l*bs + j]));CHKERRQ(ierr);
5080e6d2581SBarry Smith             } else if (PetscImaginaryPart(a->a[bs2*k + l*bs + j]) < 0.0) {
5096831982aSBarry Smith               ierr = ViewerASCIIPrintf(viewer," %d %g - %g i",bs*a->j[k]+l,
5100e6d2581SBarry Smith                 PetscRealPart(a->a[bs2*k + l*bs + j]),-PetscImaginaryPart(a->a[bs2*k + l*bs + j]));CHKERRQ(ierr);
5110ef38995SBarry Smith             } else {
5120e6d2581SBarry Smith               ierr = ViewerASCIIPrintf(viewer," %d %g ",bs*a->j[k]+l,PetscRealPart(a->a[bs2*k + l*bs + j]));CHKERRQ(ierr);
51388685aaeSLois Curfman McInnes             }
51488685aaeSLois Curfman McInnes #else
5156831982aSBarry Smith             ierr = ViewerASCIIPrintf(viewer," %d %g ",bs*a->j[k]+l,a->a[bs2*k + l*bs + j]);CHKERRQ(ierr);
51688685aaeSLois Curfman McInnes #endif
5172593348eSBarry Smith           }
5182593348eSBarry Smith         }
5196831982aSBarry Smith         ierr = ViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
5202593348eSBarry Smith       }
5212593348eSBarry Smith     }
5226831982aSBarry Smith     ierr = ViewerASCIIUseTabs(viewer,PETSC_YES);CHKERRQ(ierr);
523b6490206SBarry Smith   }
5246831982aSBarry Smith   ierr = ViewerFlush(viewer);CHKERRQ(ierr);
5253a40ed3dSBarry Smith   PetscFunctionReturn(0);
5262593348eSBarry Smith }
5272593348eSBarry Smith 
5285615d1e5SSatish Balay #undef __FUNC__
529b2863d3aSBarry Smith #define __FUNC__ /*<a name=""></a>*/"MatView_SeqBAIJ_Draw_Zoom"
53077ed5343SBarry Smith static int MatView_SeqBAIJ_Draw_Zoom(Draw draw,void *Aa)
5313270192aSSatish Balay {
53277ed5343SBarry Smith   Mat          A = (Mat) Aa;
5333270192aSSatish Balay   Mat_SeqBAIJ  *a=(Mat_SeqBAIJ*)A->data;
534b65db4caSBarry Smith   int          row,ierr,i,j,k,l,mbs=a->mbs,color,bs=a->bs,bs2=a->bs2;
5350e6d2581SBarry Smith   PetscReal    xl,yl,xr,yr,x_l,x_r,y_l,y_r;
5363f1db9ecSBarry Smith   MatScalar    *aa;
53777ed5343SBarry Smith   Viewer       viewer;
5383270192aSSatish Balay 
5393a40ed3dSBarry Smith   PetscFunctionBegin;
5403270192aSSatish Balay 
541b65db4caSBarry Smith   /* still need to add support for contour plot of nonzeros; see MatView_SeqAIJ_Draw_Zoom()*/
54277ed5343SBarry Smith   ierr = PetscObjectQuery((PetscObject)A,"Zoomviewer",(PetscObject*)&viewer);CHKERRQ(ierr);
54377ed5343SBarry Smith 
54477ed5343SBarry Smith   ierr = DrawGetCoordinates(draw,&xl,&yl,&xr,&yr);CHKERRQ(ierr);
54577ed5343SBarry Smith 
5463270192aSSatish Balay   /* loop over matrix elements drawing boxes */
5473270192aSSatish Balay   color = DRAW_BLUE;
5483270192aSSatish Balay   for (i=0,row=0; i<mbs; i++,row+=bs) {
5493270192aSSatish Balay     for (j=a->i[i]; j<a->i[i+1]; j++) {
5503270192aSSatish Balay       y_l = a->m - row - 1.0; y_r = y_l + 1.0;
5513270192aSSatish Balay       x_l = a->j[j]*bs; x_r = x_l + 1.0;
5523270192aSSatish Balay       aa = a->a + j*bs2;
5533270192aSSatish Balay       for (k=0; k<bs; k++) {
5543270192aSSatish Balay         for (l=0; l<bs; l++) {
5550e6d2581SBarry Smith           if (PetscRealPart(*aa++) >=  0.) continue;
556433994e6SBarry Smith           ierr = DrawRectangle(draw,x_l+k,y_l-l,x_r+k,y_r-l,color,color,color,color);CHKERRQ(ierr);
5573270192aSSatish Balay         }
5583270192aSSatish Balay       }
5593270192aSSatish Balay     }
5603270192aSSatish Balay   }
5613270192aSSatish Balay   color = DRAW_CYAN;
5623270192aSSatish Balay   for (i=0,row=0; i<mbs; i++,row+=bs) {
5633270192aSSatish Balay     for (j=a->i[i]; j<a->i[i+1]; j++) {
5643270192aSSatish Balay       y_l = a->m - row - 1.0; y_r = y_l + 1.0;
5653270192aSSatish Balay       x_l = a->j[j]*bs; x_r = x_l + 1.0;
5663270192aSSatish Balay       aa = a->a + j*bs2;
5673270192aSSatish Balay       for (k=0; k<bs; k++) {
5683270192aSSatish Balay         for (l=0; l<bs; l++) {
5690e6d2581SBarry Smith           if (PetscRealPart(*aa++) != 0.) continue;
570433994e6SBarry Smith           ierr = DrawRectangle(draw,x_l+k,y_l-l,x_r+k,y_r-l,color,color,color,color);CHKERRQ(ierr);
5713270192aSSatish Balay         }
5723270192aSSatish Balay       }
5733270192aSSatish Balay     }
5743270192aSSatish Balay   }
5753270192aSSatish Balay 
5763270192aSSatish Balay   color = DRAW_RED;
5773270192aSSatish Balay   for (i=0,row=0; i<mbs; i++,row+=bs) {
5783270192aSSatish Balay     for (j=a->i[i]; j<a->i[i+1]; j++) {
5793270192aSSatish Balay       y_l = a->m - row - 1.0; y_r = y_l + 1.0;
5803270192aSSatish Balay       x_l = a->j[j]*bs; x_r = x_l + 1.0;
5813270192aSSatish Balay       aa = a->a + j*bs2;
5823270192aSSatish Balay       for (k=0; k<bs; k++) {
5833270192aSSatish Balay         for (l=0; l<bs; l++) {
5840e6d2581SBarry Smith           if (PetscRealPart(*aa++) <= 0.) continue;
585433994e6SBarry Smith           ierr = DrawRectangle(draw,x_l+k,y_l-l,x_r+k,y_r-l,color,color,color,color);CHKERRQ(ierr);
5863270192aSSatish Balay         }
5873270192aSSatish Balay       }
5883270192aSSatish Balay     }
5893270192aSSatish Balay   }
59077ed5343SBarry Smith   PetscFunctionReturn(0);
59177ed5343SBarry Smith }
5923270192aSSatish Balay 
59377ed5343SBarry Smith #undef __FUNC__
594b2863d3aSBarry Smith #define __FUNC__ /*<a name=""></a>*/"MatView_SeqBAIJ_Draw"
59577ed5343SBarry Smith static int MatView_SeqBAIJ_Draw(Mat A,Viewer viewer)
59677ed5343SBarry Smith {
59777ed5343SBarry Smith   Mat_SeqBAIJ  *a=(Mat_SeqBAIJ*)A->data;
5987dce120fSSatish Balay   int          ierr;
5990e6d2581SBarry Smith   PetscReal    xl,yl,xr,yr,w,h;
60077ed5343SBarry Smith   Draw         draw;
60177ed5343SBarry Smith   PetscTruth   isnull;
6023270192aSSatish Balay 
60377ed5343SBarry Smith   PetscFunctionBegin;
60477ed5343SBarry Smith 
60577ed5343SBarry Smith   ierr = ViewerDrawGetDraw(viewer,0,&draw);CHKERRQ(ierr);
60677ed5343SBarry Smith   ierr = DrawIsNull(draw,&isnull);CHKERRQ(ierr); if (isnull) PetscFunctionReturn(0);
60777ed5343SBarry Smith 
60877ed5343SBarry Smith   ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",(PetscObject)viewer);CHKERRQ(ierr);
60977ed5343SBarry Smith   xr  = a->n; yr = a->m; h = yr/10.0; w = xr/10.0;
61077ed5343SBarry Smith   xr += w;    yr += h;  xl = -w;     yl = -h;
6113270192aSSatish Balay   ierr = DrawSetCoordinates(draw,xl,yl,xr,yr);CHKERRQ(ierr);
61277ed5343SBarry Smith   ierr = DrawZoom(draw,MatView_SeqBAIJ_Draw_Zoom,A);CHKERRQ(ierr);
61377ed5343SBarry Smith   ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",PETSC_NULL);CHKERRQ(ierr);
6143a40ed3dSBarry Smith   PetscFunctionReturn(0);
6153270192aSSatish Balay }
6163270192aSSatish Balay 
6175615d1e5SSatish Balay #undef __FUNC__
618b2863d3aSBarry Smith #define __FUNC__ /*<a name=""></a>*/"MatView_SeqBAIJ"
619e1311b90SBarry Smith int MatView_SeqBAIJ(Mat A,Viewer viewer)
6202593348eSBarry Smith {
62119bcc07fSBarry Smith   int        ierr;
6226831982aSBarry Smith   PetscTruth issocket,isascii,isbinary,isdraw;
6232593348eSBarry Smith 
6243a40ed3dSBarry Smith   PetscFunctionBegin;
6256831982aSBarry Smith   ierr = PetscTypeCompare((PetscObject)viewer,SOCKET_VIEWER,&issocket);CHKERRQ(ierr);
6266831982aSBarry Smith   ierr = PetscTypeCompare((PetscObject)viewer,ASCII_VIEWER,&isascii);CHKERRQ(ierr);
6276831982aSBarry Smith   ierr = PetscTypeCompare((PetscObject)viewer,BINARY_VIEWER,&isbinary);CHKERRQ(ierr);
6286831982aSBarry Smith   ierr = PetscTypeCompare((PetscObject)viewer,DRAW_VIEWER,&isdraw);CHKERRQ(ierr);
6290f5bd95cSBarry Smith   if (issocket) {
630*29bbc08cSBarry Smith     SETERRQ(PETSC_ERR_SUP,"Socket viewer not supported");
6310f5bd95cSBarry Smith   } else if (isascii){
6323a40ed3dSBarry Smith     ierr = MatView_SeqBAIJ_ASCII(A,viewer);CHKERRQ(ierr);
6330f5bd95cSBarry Smith   } else if (isbinary) {
6343a40ed3dSBarry Smith     ierr = MatView_SeqBAIJ_Binary(A,viewer);CHKERRQ(ierr);
6350f5bd95cSBarry Smith   } else if (isdraw) {
6363a40ed3dSBarry Smith     ierr = MatView_SeqBAIJ_Draw(A,viewer);CHKERRQ(ierr);
6375cd90555SBarry Smith   } else {
638*29bbc08cSBarry Smith     SETERRQ1(1,"Viewer type %s not supported by SeqBAIJ matrices",((PetscObject)viewer)->type_name);
6392593348eSBarry Smith   }
6403a40ed3dSBarry Smith   PetscFunctionReturn(0);
6412593348eSBarry Smith }
642b6490206SBarry Smith 
643cd0e1443SSatish Balay 
6445615d1e5SSatish Balay #undef __FUNC__
645b2863d3aSBarry Smith #define __FUNC__ /*<a name=""></a>*/"MatGetValues_SeqBAIJ"
6462d61bbb3SSatish Balay int MatGetValues_SeqBAIJ(Mat A,int m,int *im,int n,int *in,Scalar *v)
647cd0e1443SSatish Balay {
648cd0e1443SSatish Balay   Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)A->data;
6492d61bbb3SSatish Balay   int        *rp,k,low,high,t,row,nrow,i,col,l,*aj = a->j;
6502d61bbb3SSatish Balay   int        *ai = a->i,*ailen = a->ilen;
6512d61bbb3SSatish Balay   int        brow,bcol,ridx,cidx,bs=a->bs,bs2=a->bs2;
6523f1db9ecSBarry Smith   MatScalar  *ap,*aa = a->a,zero = 0.0;
653cd0e1443SSatish Balay 
6543a40ed3dSBarry Smith   PetscFunctionBegin;
6552d61bbb3SSatish Balay   for (k=0; k<m; k++) { /* loop over rows */
656cd0e1443SSatish Balay     row  = im[k]; brow = row/bs;
657*29bbc08cSBarry Smith     if (row < 0) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Negative row");
658*29bbc08cSBarry Smith     if (row >= a->m) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Row too large");
6592d61bbb3SSatish Balay     rp   = aj + ai[brow] ; ap = aa + bs2*ai[brow] ;
6602c3acbe9SBarry Smith     nrow = ailen[brow];
6612d61bbb3SSatish Balay     for (l=0; l<n; l++) { /* loop over columns */
662*29bbc08cSBarry Smith       if (in[l] < 0) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Negative column");
663*29bbc08cSBarry Smith       if (in[l] >= a->n) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Column too large");
6642d61bbb3SSatish Balay       col  = in[l] ;
6652d61bbb3SSatish Balay       bcol = col/bs;
6662d61bbb3SSatish Balay       cidx = col%bs;
6672d61bbb3SSatish Balay       ridx = row%bs;
6682d61bbb3SSatish Balay       high = nrow;
6692d61bbb3SSatish Balay       low  = 0; /* assume unsorted */
6702d61bbb3SSatish Balay       while (high-low > 5) {
671cd0e1443SSatish Balay         t = (low+high)/2;
672cd0e1443SSatish Balay         if (rp[t] > bcol) high = t;
673cd0e1443SSatish Balay         else             low  = t;
674cd0e1443SSatish Balay       }
675cd0e1443SSatish Balay       for (i=low; i<high; i++) {
676cd0e1443SSatish Balay         if (rp[i] > bcol) break;
677cd0e1443SSatish Balay         if (rp[i] == bcol) {
6782d61bbb3SSatish Balay           *v++ = ap[bs2*i+bs*cidx+ridx];
6792d61bbb3SSatish Balay           goto finished;
680cd0e1443SSatish Balay         }
681cd0e1443SSatish Balay       }
6822d61bbb3SSatish Balay       *v++ = zero;
6832d61bbb3SSatish Balay       finished:;
684cd0e1443SSatish Balay     }
685cd0e1443SSatish Balay   }
6863a40ed3dSBarry Smith   PetscFunctionReturn(0);
687cd0e1443SSatish Balay }
688cd0e1443SSatish Balay 
68995d5f7c2SBarry Smith #if defined(PETSC_USE_MAT_SINGLE)
69095d5f7c2SBarry Smith #undef __FUNC__
69195d5f7c2SBarry Smith #define __FUNC__ /*<a name=""></a>*/"MatSetValuesBlocked_SeqBAIJ"
69295d5f7c2SBarry Smith int MatSetValuesBlocked_SeqBAIJ(Mat mat,int m,int *im,int n,int *in,Scalar *v,InsertMode addv)
69395d5f7c2SBarry Smith {
694563b5814SBarry Smith   Mat_SeqBAIJ *b = (Mat_SeqBAIJ*)mat->data;
695563b5814SBarry Smith   int         ierr,i,N = m*n*b->bs2;
696563b5814SBarry Smith   MatScalar   *vsingle;
69795d5f7c2SBarry Smith 
69895d5f7c2SBarry Smith   PetscFunctionBegin;
699563b5814SBarry Smith   if (N > b->setvalueslen) {
700563b5814SBarry Smith     if (b->setvaluescopy) {ierr = PetscFree(b->setvaluescopy);CHKERRQ(ierr);}
701563b5814SBarry Smith     b->setvaluescopy = (MatScalar*)PetscMalloc(N*sizeof(MatScalar));CHKPTRQ(b->setvaluescopy);
702563b5814SBarry Smith     b->setvalueslen  = N;
703563b5814SBarry Smith   }
704563b5814SBarry Smith   vsingle = b->setvaluescopy;
70595d5f7c2SBarry Smith   for (i=0; i<N; i++) {
70695d5f7c2SBarry Smith     vsingle[i] = v[i];
70795d5f7c2SBarry Smith   }
70895d5f7c2SBarry Smith   ierr = MatSetValuesBlocked_SeqBAIJ_MatScalar(mat,m,im,n,in,vsingle,addv);CHKERRQ(ierr);
70995d5f7c2SBarry Smith   PetscFunctionReturn(0);
71095d5f7c2SBarry Smith }
71195d5f7c2SBarry Smith #endif
71295d5f7c2SBarry Smith 
7132d61bbb3SSatish Balay 
7145615d1e5SSatish Balay #undef __FUNC__
715b2863d3aSBarry Smith #define __FUNC__ /*<a name=""></a>*/"MatSetValuesBlocked_SeqBAIJ"
71695d5f7c2SBarry Smith int MatSetValuesBlocked_SeqBAIJ_MatScalar(Mat A,int m,int *im,int n,int *in,MatScalar *v,InsertMode is)
71792c4ed94SBarry Smith {
71892c4ed94SBarry Smith   Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)A->data;
7198a84c255SSatish Balay   int         *rp,k,low,high,t,ii,jj,row,nrow,i,col,l,rmax,N,sorted=a->sorted;
720dd9472c6SBarry Smith   int         *imax=a->imax,*ai=a->i,*ailen=a->ilen,roworiented=a->roworiented;
721549d3d68SSatish Balay   int         *aj=a->j,nonew=a->nonew,bs2=a->bs2,bs=a->bs,stepval,ierr;
72295d5f7c2SBarry Smith   MatScalar      *value = v,*ap,*aa = a->a,*bap;
72392c4ed94SBarry Smith 
7243a40ed3dSBarry Smith   PetscFunctionBegin;
7250e324ae4SSatish Balay   if (roworiented) {
7260e324ae4SSatish Balay     stepval = (n-1)*bs;
7270e324ae4SSatish Balay   } else {
7280e324ae4SSatish Balay     stepval = (m-1)*bs;
7290e324ae4SSatish Balay   }
73092c4ed94SBarry Smith   for (k=0; k<m; k++) { /* loop over added rows */
73192c4ed94SBarry Smith     row  = im[k];
7325ef9f2a5SBarry Smith     if (row < 0) continue;
733aa482453SBarry Smith #if defined(PETSC_USE_BOPT_g)
734*29bbc08cSBarry Smith     if (row >= a->mbs) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Row too large");
73592c4ed94SBarry Smith #endif
73692c4ed94SBarry Smith     rp   = aj + ai[row];
73792c4ed94SBarry Smith     ap   = aa + bs2*ai[row];
73892c4ed94SBarry Smith     rmax = imax[row];
73992c4ed94SBarry Smith     nrow = ailen[row];
74092c4ed94SBarry Smith     low  = 0;
74192c4ed94SBarry Smith     for (l=0; l<n; l++) { /* loop over added columns */
7425ef9f2a5SBarry Smith       if (in[l] < 0) continue;
743aa482453SBarry Smith #if defined(PETSC_USE_BOPT_g)
744*29bbc08cSBarry Smith       if (in[l] >= a->nbs) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Column too large");
74592c4ed94SBarry Smith #endif
74692c4ed94SBarry Smith       col = in[l];
74792c4ed94SBarry Smith       if (roworiented) {
7480e324ae4SSatish Balay         value = v + k*(stepval+bs)*bs + l*bs;
7490e324ae4SSatish Balay       } else {
7500e324ae4SSatish Balay         value = v + l*(stepval+bs)*bs + k*bs;
75192c4ed94SBarry Smith       }
75292c4ed94SBarry Smith       if (!sorted) low = 0; high = nrow;
75392c4ed94SBarry Smith       while (high-low > 7) {
75492c4ed94SBarry Smith         t = (low+high)/2;
75592c4ed94SBarry Smith         if (rp[t] > col) high = t;
75692c4ed94SBarry Smith         else             low  = t;
75792c4ed94SBarry Smith       }
75892c4ed94SBarry Smith       for (i=low; i<high; i++) {
75992c4ed94SBarry Smith         if (rp[i] > col) break;
76092c4ed94SBarry Smith         if (rp[i] == col) {
7618a84c255SSatish Balay           bap  = ap +  bs2*i;
7620e324ae4SSatish Balay           if (roworiented) {
7638a84c255SSatish Balay             if (is == ADD_VALUES) {
764dd9472c6SBarry Smith               for (ii=0; ii<bs; ii++,value+=stepval) {
765dd9472c6SBarry Smith                 for (jj=ii; jj<bs2; jj+=bs) {
7668a84c255SSatish Balay                   bap[jj] += *value++;
767dd9472c6SBarry Smith                 }
768dd9472c6SBarry Smith               }
7690e324ae4SSatish Balay             } else {
770dd9472c6SBarry Smith               for (ii=0; ii<bs; ii++,value+=stepval) {
771dd9472c6SBarry Smith                 for (jj=ii; jj<bs2; jj+=bs) {
7720e324ae4SSatish Balay                   bap[jj] = *value++;
7738a84c255SSatish Balay                 }
774dd9472c6SBarry Smith               }
775dd9472c6SBarry Smith             }
7760e324ae4SSatish Balay           } else {
7770e324ae4SSatish Balay             if (is == ADD_VALUES) {
778dd9472c6SBarry Smith               for (ii=0; ii<bs; ii++,value+=stepval) {
779dd9472c6SBarry Smith                 for (jj=0; jj<bs; jj++) {
7800e324ae4SSatish Balay                   *bap++ += *value++;
781dd9472c6SBarry Smith                 }
782dd9472c6SBarry Smith               }
7830e324ae4SSatish Balay             } else {
784dd9472c6SBarry Smith               for (ii=0; ii<bs; ii++,value+=stepval) {
785dd9472c6SBarry Smith                 for (jj=0; jj<bs; jj++) {
7860e324ae4SSatish Balay                   *bap++  = *value++;
7870e324ae4SSatish Balay                 }
7888a84c255SSatish Balay               }
789dd9472c6SBarry Smith             }
790dd9472c6SBarry Smith           }
791f1241b54SBarry Smith           goto noinsert2;
79292c4ed94SBarry Smith         }
79392c4ed94SBarry Smith       }
79489280ab3SLois Curfman McInnes       if (nonew == 1) goto noinsert2;
795*29bbc08cSBarry Smith       else if (nonew == -1) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Inserting a new nonzero in the matrix");
79692c4ed94SBarry Smith       if (nrow >= rmax) {
79792c4ed94SBarry Smith         /* there is no extra room in row, therefore enlarge */
79892c4ed94SBarry Smith         int       new_nz = ai[a->mbs] + CHUNKSIZE,len,*new_i,*new_j;
7993f1db9ecSBarry Smith         MatScalar *new_a;
80092c4ed94SBarry Smith 
801*29bbc08cSBarry Smith         if (nonew == -2) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Inserting a new nonzero in the matrix");
80289280ab3SLois Curfman McInnes 
80392c4ed94SBarry Smith         /* malloc new storage space */
8043f1db9ecSBarry Smith         len     = new_nz*(sizeof(int)+bs2*sizeof(MatScalar))+(a->mbs+1)*sizeof(int);
8053f1db9ecSBarry Smith         new_a   = (MatScalar*)PetscMalloc(len);CHKPTRQ(new_a);
80692c4ed94SBarry Smith         new_j   = (int*)(new_a + bs2*new_nz);
80792c4ed94SBarry Smith         new_i   = new_j + new_nz;
80892c4ed94SBarry Smith 
80992c4ed94SBarry Smith         /* copy over old data into new slots */
81092c4ed94SBarry Smith         for (ii=0; ii<row+1; ii++) {new_i[ii] = ai[ii];}
81192c4ed94SBarry Smith         for (ii=row+1; ii<a->mbs+1; ii++) {new_i[ii] = ai[ii]+CHUNKSIZE;}
812549d3d68SSatish Balay         ierr = PetscMemcpy(new_j,aj,(ai[row]+nrow)*sizeof(int));CHKERRQ(ierr);
81392c4ed94SBarry Smith         len  = (new_nz - CHUNKSIZE - ai[row] - nrow);
814549d3d68SSatish Balay         ierr = PetscMemcpy(new_j+ai[row]+nrow+CHUNKSIZE,aj+ai[row]+nrow,len*sizeof(int));CHKERRQ(ierr);
815549d3d68SSatish Balay         ierr = PetscMemcpy(new_a,aa,(ai[row]+nrow)*bs2*sizeof(MatScalar));CHKERRQ(ierr);
816549d3d68SSatish Balay         ierr = PetscMemzero(new_a+bs2*(ai[row]+nrow),bs2*CHUNKSIZE*sizeof(MatScalar));CHKERRQ(ierr);
817549d3d68SSatish Balay         ierr = PetscMemcpy(new_a+bs2*(ai[row]+nrow+CHUNKSIZE),aa+bs2*(ai[row]+nrow),bs2*len*sizeof(MatScalar));CHKERRQ(ierr);
81892c4ed94SBarry Smith         /* free up old matrix storage */
819606d414cSSatish Balay         ierr = PetscFree(a->a);CHKERRQ(ierr);
820606d414cSSatish Balay         if (!a->singlemalloc) {
821606d414cSSatish Balay           ierr = PetscFree(a->i);CHKERRQ(ierr);
822606d414cSSatish Balay           ierr = PetscFree(a->j);CHKERRQ(ierr);
823606d414cSSatish Balay         }
82492c4ed94SBarry Smith         aa = a->a = new_a; ai = a->i = new_i; aj = a->j = new_j;
825c4992f7dSBarry Smith         a->singlemalloc = PETSC_TRUE;
82692c4ed94SBarry Smith 
82792c4ed94SBarry Smith         rp   = aj + ai[row]; ap = aa + bs2*ai[row];
82892c4ed94SBarry Smith         rmax = imax[row] = imax[row] + CHUNKSIZE;
8293f1db9ecSBarry Smith         PLogObjectMemory(A,CHUNKSIZE*(sizeof(int) + bs2*sizeof(MatScalar)));
83092c4ed94SBarry Smith         a->maxnz += bs2*CHUNKSIZE;
83192c4ed94SBarry Smith         a->reallocs++;
83292c4ed94SBarry Smith         a->nz++;
83392c4ed94SBarry Smith       }
83492c4ed94SBarry Smith       N = nrow++ - 1;
83592c4ed94SBarry Smith       /* shift up all the later entries in this row */
83692c4ed94SBarry Smith       for (ii=N; ii>=i; ii--) {
83792c4ed94SBarry Smith         rp[ii+1] = rp[ii];
838549d3d68SSatish Balay         ierr = PetscMemcpy(ap+bs2*(ii+1),ap+bs2*(ii),bs2*sizeof(MatScalar));CHKERRQ(ierr);
83992c4ed94SBarry Smith       }
840549d3d68SSatish Balay       if (N >= i) {
841549d3d68SSatish Balay         ierr = PetscMemzero(ap+bs2*i,bs2*sizeof(MatScalar));CHKERRQ(ierr);
842549d3d68SSatish Balay       }
84392c4ed94SBarry Smith       rp[i] = col;
8448a84c255SSatish Balay       bap   = ap +  bs2*i;
8450e324ae4SSatish Balay       if (roworiented) {
846dd9472c6SBarry Smith         for (ii=0; ii<bs; ii++,value+=stepval) {
847dd9472c6SBarry Smith           for (jj=ii; jj<bs2; jj+=bs) {
8480e324ae4SSatish Balay             bap[jj] = *value++;
849dd9472c6SBarry Smith           }
850dd9472c6SBarry Smith         }
8510e324ae4SSatish Balay       } else {
852dd9472c6SBarry Smith         for (ii=0; ii<bs; ii++,value+=stepval) {
853dd9472c6SBarry Smith           for (jj=0; jj<bs; jj++) {
8540e324ae4SSatish Balay             *bap++  = *value++;
8550e324ae4SSatish Balay           }
856dd9472c6SBarry Smith         }
857dd9472c6SBarry Smith       }
858f1241b54SBarry Smith       noinsert2:;
85992c4ed94SBarry Smith       low = i;
86092c4ed94SBarry Smith     }
86192c4ed94SBarry Smith     ailen[row] = nrow;
86292c4ed94SBarry Smith   }
8633a40ed3dSBarry Smith   PetscFunctionReturn(0);
86492c4ed94SBarry Smith }
86592c4ed94SBarry Smith 
866f2501298SSatish Balay 
8675615d1e5SSatish Balay #undef __FUNC__
868b2863d3aSBarry Smith #define __FUNC__ /*<a name=""></a>*/"MatAssemblyEnd_SeqBAIJ"
8698f6be9afSLois Curfman McInnes int MatAssemblyEnd_SeqBAIJ(Mat A,MatAssemblyType mode)
870584200bdSSatish Balay {
871584200bdSSatish Balay   Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)A->data;
872584200bdSSatish Balay   int        fshift = 0,i,j,*ai = a->i,*aj = a->j,*imax = a->imax;
873a7c10996SSatish Balay   int        m = a->m,*ip,N,*ailen = a->ilen;
874549d3d68SSatish Balay   int        mbs = a->mbs,bs2 = a->bs2,rmax = 0,ierr;
8753f1db9ecSBarry Smith   MatScalar  *aa = a->a,*ap;
876584200bdSSatish Balay 
8773a40ed3dSBarry Smith   PetscFunctionBegin;
8783a40ed3dSBarry Smith   if (mode == MAT_FLUSH_ASSEMBLY) PetscFunctionReturn(0);
879584200bdSSatish Balay 
88043ee02c3SBarry Smith   if (m) rmax = ailen[0];
881584200bdSSatish Balay   for (i=1; i<mbs; i++) {
882584200bdSSatish Balay     /* move each row back by the amount of empty slots (fshift) before it*/
883584200bdSSatish Balay     fshift += imax[i-1] - ailen[i-1];
884d402145bSBarry Smith     rmax   = PetscMax(rmax,ailen[i]);
885584200bdSSatish Balay     if (fshift) {
886a7c10996SSatish Balay       ip = aj + ai[i]; ap = aa + bs2*ai[i];
887584200bdSSatish Balay       N = ailen[i];
888584200bdSSatish Balay       for (j=0; j<N; j++) {
889584200bdSSatish Balay         ip[j-fshift] = ip[j];
890549d3d68SSatish Balay         ierr = PetscMemcpy(ap+(j-fshift)*bs2,ap+j*bs2,bs2*sizeof(MatScalar));CHKERRQ(ierr);
891584200bdSSatish Balay       }
892584200bdSSatish Balay     }
893584200bdSSatish Balay     ai[i] = ai[i-1] + ailen[i-1];
894584200bdSSatish Balay   }
895584200bdSSatish Balay   if (mbs) {
896584200bdSSatish Balay     fshift += imax[mbs-1] - ailen[mbs-1];
897584200bdSSatish Balay     ai[mbs] = ai[mbs-1] + ailen[mbs-1];
898584200bdSSatish Balay   }
899584200bdSSatish Balay   /* reset ilen and imax for each row */
900584200bdSSatish Balay   for (i=0; i<mbs; i++) {
901584200bdSSatish Balay     ailen[i] = imax[i] = ai[i+1] - ai[i];
902584200bdSSatish Balay   }
903a7c10996SSatish Balay   a->nz = ai[mbs];
904584200bdSSatish Balay 
905584200bdSSatish Balay   /* diagonals may have moved, so kill the diagonal pointers */
906584200bdSSatish Balay   if (fshift && a->diag) {
907606d414cSSatish Balay     ierr = PetscFree(a->diag);CHKERRQ(ierr);
908584200bdSSatish Balay     PLogObjectMemory(A,-(m+1)*sizeof(int));
909584200bdSSatish Balay     a->diag = 0;
910584200bdSSatish Balay   }
9113d2013a6SLois Curfman McInnes   PLogInfo(A,"MatAssemblyEnd_SeqBAIJ:Matrix size: %d X %d, block size %d; storage space: %d unneeded, %d used\n",
912219d9a1aSLois Curfman McInnes            m,a->n,a->bs,fshift*bs2,a->nz*bs2);
9133d2013a6SLois Curfman McInnes   PLogInfo(A,"MatAssemblyEnd_SeqBAIJ:Number of mallocs during MatSetValues is %d\n",
914584200bdSSatish Balay            a->reallocs);
915d402145bSBarry Smith   PLogInfo(A,"MatAssemblyEnd_SeqBAIJ:Most nonzeros blocks in any row is %d\n",rmax);
916e2f3b5e9SSatish Balay   a->reallocs          = 0;
9170e6d2581SBarry Smith   A->info.nz_unneeded  = (PetscReal)fshift*bs2;
9184e220ebcSLois Curfman McInnes 
9193a40ed3dSBarry Smith   PetscFunctionReturn(0);
920584200bdSSatish Balay }
921584200bdSSatish Balay 
9225a838052SSatish Balay 
923bea157c4SSatish Balay 
924bea157c4SSatish Balay /*
925bea157c4SSatish Balay    This function returns an array of flags which indicate the locations of contiguous
926bea157c4SSatish Balay    blocks that should be zeroed. for eg: if bs = 3  and is = [0,1,2,3,5,6,7,8,9]
927bea157c4SSatish Balay    then the resulting sizes = [3,1,1,3,1] correspondig to sets [(0,1,2),(3),(5),(6,7,8),(9)]
928bea157c4SSatish Balay    Assume: sizes should be long enough to hold all the values.
929bea157c4SSatish Balay */
9305615d1e5SSatish Balay #undef __FUNC__
931b2863d3aSBarry Smith #define __FUNC__ /*<a name=""></a>*/"MatZeroRows_SeqBAIJ_Check_Blocks"
932bea157c4SSatish Balay static int MatZeroRows_SeqBAIJ_Check_Blocks(int idx[],int n,int bs,int sizes[], int *bs_max)
933d9b7c43dSSatish Balay {
934bea157c4SSatish Balay   int        i,j,k,row;
935bea157c4SSatish Balay   PetscTruth flg;
9363a40ed3dSBarry Smith 
937433994e6SBarry Smith   PetscFunctionBegin;
938bea157c4SSatish Balay   for (i=0,j=0; i<n; j++) {
939bea157c4SSatish Balay     row = idx[i];
940bea157c4SSatish Balay     if (row%bs!=0) { /* Not the begining of a block */
941bea157c4SSatish Balay       sizes[j] = 1;
942bea157c4SSatish Balay       i++;
943e4fda26cSSatish Balay     } else if (i+bs > n) { /* complete block doesn't exist (at idx end) */
944bea157c4SSatish Balay       sizes[j] = 1;         /* Also makes sure atleast 'bs' values exist for next else */
945bea157c4SSatish Balay       i++;
946bea157c4SSatish Balay     } else { /* Begining of the block, so check if the complete block exists */
947bea157c4SSatish Balay       flg = PETSC_TRUE;
948bea157c4SSatish Balay       for (k=1; k<bs; k++) {
949bea157c4SSatish Balay         if (row+k != idx[i+k]) { /* break in the block */
950bea157c4SSatish Balay           flg = PETSC_FALSE;
951bea157c4SSatish Balay           break;
952d9b7c43dSSatish Balay         }
953bea157c4SSatish Balay       }
954bea157c4SSatish Balay       if (flg == PETSC_TRUE) { /* No break in the bs */
955bea157c4SSatish Balay         sizes[j] = bs;
956bea157c4SSatish Balay         i+= bs;
957bea157c4SSatish Balay       } else {
958bea157c4SSatish Balay         sizes[j] = 1;
959bea157c4SSatish Balay         i++;
960bea157c4SSatish Balay       }
961bea157c4SSatish Balay     }
962bea157c4SSatish Balay   }
963bea157c4SSatish Balay   *bs_max = j;
9643a40ed3dSBarry Smith   PetscFunctionReturn(0);
965d9b7c43dSSatish Balay }
966d9b7c43dSSatish Balay 
9675615d1e5SSatish Balay #undef __FUNC__
968b2863d3aSBarry Smith #define __FUNC__ /*<a name=""></a>*/"MatZeroRows_SeqBAIJ"
9698f6be9afSLois Curfman McInnes int MatZeroRows_SeqBAIJ(Mat A,IS is,Scalar *diag)
970d9b7c43dSSatish Balay {
971d9b7c43dSSatish Balay   Mat_SeqBAIJ *baij=(Mat_SeqBAIJ*)A->data;
972b6815fffSBarry Smith   int         ierr,i,j,k,count,is_n,*is_idx,*rows;
973bea157c4SSatish Balay   int         bs=baij->bs,bs2=baij->bs2,*sizes,row,bs_max;
9743f1db9ecSBarry Smith   Scalar      zero = 0.0;
9753f1db9ecSBarry Smith   MatScalar   *aa;
976d9b7c43dSSatish Balay 
9773a40ed3dSBarry Smith   PetscFunctionBegin;
978d9b7c43dSSatish Balay   /* Make a copy of the IS and  sort it */
979b9b97703SBarry Smith   ierr = ISGetLocalSize(is,&is_n);CHKERRQ(ierr);
980d9b7c43dSSatish Balay   ierr = ISGetIndices(is,&is_idx);CHKERRQ(ierr);
981d9b7c43dSSatish Balay 
982bea157c4SSatish Balay   /* allocate memory for rows,sizes */
983bea157c4SSatish Balay   rows  = (int*)PetscMalloc((3*is_n+1)*sizeof(int));CHKPTRQ(rows);
984bea157c4SSatish Balay   sizes = rows + is_n;
985bea157c4SSatish Balay 
986563b5814SBarry Smith   /* copy IS values to rows, and sort them */
987bea157c4SSatish Balay   for (i=0; i<is_n; i++) { rows[i] = is_idx[i]; }
988bea157c4SSatish Balay   ierr = PetscSortInt(is_n,rows);CHKERRQ(ierr);
989dffd3267SBarry Smith   if (baij->keepzeroedrows) {
990dffd3267SBarry Smith     for (i=0; i<is_n; i++) { sizes[i] = 1; }
991dffd3267SBarry Smith     bs_max = is_n;
992dffd3267SBarry Smith   } else {
993bea157c4SSatish Balay     ierr = MatZeroRows_SeqBAIJ_Check_Blocks(rows,is_n,bs,sizes,&bs_max);CHKERRQ(ierr);
994dffd3267SBarry Smith   }
995b97a56abSSatish Balay   ierr = ISRestoreIndices(is,&is_idx);CHKERRQ(ierr);
996bea157c4SSatish Balay 
997bea157c4SSatish Balay   for (i=0,j=0; i<bs_max; j+=sizes[i],i++) {
998bea157c4SSatish Balay     row   = rows[j];
999*29bbc08cSBarry Smith     if (row < 0 || row > baij->m) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"row %d out of range",row);
1000bea157c4SSatish Balay     count = (baij->i[row/bs +1] - baij->i[row/bs])*bs;
1001bea157c4SSatish Balay     aa    = baij->a + baij->i[row/bs]*bs2 + (row%bs);
1002dffd3267SBarry Smith     if (sizes[i] == bs && !baij->keepzeroedrows) {
1003bea157c4SSatish Balay       if (diag) {
1004bea157c4SSatish Balay         if (baij->ilen[row/bs] > 0) {
1005bea157c4SSatish Balay           baij->ilen[row/bs]       = 1;
1006bea157c4SSatish Balay           baij->j[baij->i[row/bs]] = row/bs;
1007bea157c4SSatish Balay           ierr = PetscMemzero(aa,count*bs*sizeof(MatScalar));CHKERRQ(ierr);
1008a07cd24cSSatish Balay         }
1009563b5814SBarry Smith         /* Now insert all the diagonal values for this bs */
1010bea157c4SSatish Balay         for (k=0; k<bs; k++) {
1011bea157c4SSatish Balay           ierr = (*A->ops->setvalues)(A,1,rows+j+k,1,rows+j+k,diag,INSERT_VALUES);CHKERRQ(ierr);
1012bea157c4SSatish Balay         }
1013bea157c4SSatish Balay       } else { /* (!diag) */
1014bea157c4SSatish Balay         baij->ilen[row/bs] = 0;
1015bea157c4SSatish Balay       } /* end (!diag) */
1016bea157c4SSatish Balay     } else { /* (sizes[i] != bs) */
1017aa482453SBarry Smith #if defined (PETSC_USE_DEBUG)
1018*29bbc08cSBarry Smith       if (sizes[i] != 1) SETERRQ(1,"Internal Error. Value should be 1");
1019bea157c4SSatish Balay #endif
1020bea157c4SSatish Balay       for (k=0; k<count; k++) {
1021d9b7c43dSSatish Balay         aa[0] =  zero;
1022d9b7c43dSSatish Balay         aa    += bs;
1023d9b7c43dSSatish Balay       }
1024d9b7c43dSSatish Balay       if (diag) {
1025f830108cSBarry Smith         ierr = (*A->ops->setvalues)(A,1,rows+j,1,rows+j,diag,INSERT_VALUES);CHKERRQ(ierr);
1026d9b7c43dSSatish Balay       }
1027d9b7c43dSSatish Balay     }
1028bea157c4SSatish Balay   }
1029bea157c4SSatish Balay 
1030606d414cSSatish Balay   ierr = PetscFree(rows);CHKERRQ(ierr);
10319a8dea36SBarry Smith   ierr = MatAssemblyEnd_SeqBAIJ(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
10323a40ed3dSBarry Smith   PetscFunctionReturn(0);
1033d9b7c43dSSatish Balay }
10341c351548SSatish Balay 
10355615d1e5SSatish Balay #undef __FUNC__
1036b2863d3aSBarry Smith #define __FUNC__ /*<a name=""></a>*/"MatSetValues_SeqBAIJ"
10372d61bbb3SSatish Balay int MatSetValues_SeqBAIJ(Mat A,int m,int *im,int n,int *in,Scalar *v,InsertMode is)
10382d61bbb3SSatish Balay {
10392d61bbb3SSatish Balay   Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)A->data;
10402d61bbb3SSatish Balay   int         *rp,k,low,high,t,ii,row,nrow,i,col,l,rmax,N,sorted=a->sorted;
10412d61bbb3SSatish Balay   int         *imax=a->imax,*ai=a->i,*ailen=a->ilen,roworiented=a->roworiented;
10422d61bbb3SSatish Balay   int         *aj=a->j,nonew=a->nonew,bs=a->bs,brow,bcol;
1043549d3d68SSatish Balay   int         ridx,cidx,bs2=a->bs2,ierr;
10443f1db9ecSBarry Smith   MatScalar   *ap,value,*aa=a->a,*bap;
10452d61bbb3SSatish Balay 
10462d61bbb3SSatish Balay   PetscFunctionBegin;
10472d61bbb3SSatish Balay   for (k=0; k<m; k++) { /* loop over added rows */
10482d61bbb3SSatish Balay     row  = im[k]; brow = row/bs;
10495ef9f2a5SBarry Smith     if (row < 0) continue;
1050aa482453SBarry Smith #if defined(PETSC_USE_BOPT_g)
1051*29bbc08cSBarry Smith     if (row >= a->m) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"Row too large: row %d max %d",row,a->m);
10522d61bbb3SSatish Balay #endif
10532d61bbb3SSatish Balay     rp   = aj + ai[brow];
10542d61bbb3SSatish Balay     ap   = aa + bs2*ai[brow];
10552d61bbb3SSatish Balay     rmax = imax[brow];
10562d61bbb3SSatish Balay     nrow = ailen[brow];
10572d61bbb3SSatish Balay     low  = 0;
10582d61bbb3SSatish Balay     for (l=0; l<n; l++) { /* loop over added columns */
10595ef9f2a5SBarry Smith       if (in[l] < 0) continue;
1060aa482453SBarry Smith #if defined(PETSC_USE_BOPT_g)
1061*29bbc08cSBarry Smith       if (in[l] >= a->n) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"Column too large: col %d max %d",in[l],a->n);
10622d61bbb3SSatish Balay #endif
10632d61bbb3SSatish Balay       col = in[l]; bcol = col/bs;
10642d61bbb3SSatish Balay       ridx = row % bs; cidx = col % bs;
10652d61bbb3SSatish Balay       if (roworiented) {
10665ef9f2a5SBarry Smith         value = v[l + k*n];
10672d61bbb3SSatish Balay       } else {
10682d61bbb3SSatish Balay         value = v[k + l*m];
10692d61bbb3SSatish Balay       }
10702d61bbb3SSatish Balay       if (!sorted) low = 0; high = nrow;
10712d61bbb3SSatish Balay       while (high-low > 7) {
10722d61bbb3SSatish Balay         t = (low+high)/2;
10732d61bbb3SSatish Balay         if (rp[t] > bcol) high = t;
10742d61bbb3SSatish Balay         else              low  = t;
10752d61bbb3SSatish Balay       }
10762d61bbb3SSatish Balay       for (i=low; i<high; i++) {
10772d61bbb3SSatish Balay         if (rp[i] > bcol) break;
10782d61bbb3SSatish Balay         if (rp[i] == bcol) {
10792d61bbb3SSatish Balay           bap  = ap +  bs2*i + bs*cidx + ridx;
10802d61bbb3SSatish Balay           if (is == ADD_VALUES) *bap += value;
10812d61bbb3SSatish Balay           else                  *bap  = value;
10822d61bbb3SSatish Balay           goto noinsert1;
10832d61bbb3SSatish Balay         }
10842d61bbb3SSatish Balay       }
10852d61bbb3SSatish Balay       if (nonew == 1) goto noinsert1;
1086*29bbc08cSBarry Smith       else if (nonew == -1) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Inserting a new nonzero in the matrix");
10872d61bbb3SSatish Balay       if (nrow >= rmax) {
10882d61bbb3SSatish Balay         /* there is no extra room in row, therefore enlarge */
10892d61bbb3SSatish Balay         int       new_nz = ai[a->mbs] + CHUNKSIZE,len,*new_i,*new_j;
10903f1db9ecSBarry Smith         MatScalar *new_a;
10912d61bbb3SSatish Balay 
1092*29bbc08cSBarry Smith         if (nonew == -2) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Inserting a new nonzero in the matrix");
10932d61bbb3SSatish Balay 
10942d61bbb3SSatish Balay         /* Malloc new storage space */
10953f1db9ecSBarry Smith         len     = new_nz*(sizeof(int)+bs2*sizeof(MatScalar))+(a->mbs+1)*sizeof(int);
10963f1db9ecSBarry Smith         new_a   = (MatScalar*)PetscMalloc(len);CHKPTRQ(new_a);
10972d61bbb3SSatish Balay         new_j   = (int*)(new_a + bs2*new_nz);
10982d61bbb3SSatish Balay         new_i   = new_j + new_nz;
10992d61bbb3SSatish Balay 
11002d61bbb3SSatish Balay         /* copy over old data into new slots */
11012d61bbb3SSatish Balay         for (ii=0; ii<brow+1; ii++) {new_i[ii] = ai[ii];}
11022d61bbb3SSatish Balay         for (ii=brow+1; ii<a->mbs+1; ii++) {new_i[ii] = ai[ii]+CHUNKSIZE;}
1103549d3d68SSatish Balay         ierr = PetscMemcpy(new_j,aj,(ai[brow]+nrow)*sizeof(int));CHKERRQ(ierr);
11042d61bbb3SSatish Balay         len  = (new_nz - CHUNKSIZE - ai[brow] - nrow);
1105549d3d68SSatish Balay         ierr = PetscMemcpy(new_j+ai[brow]+nrow+CHUNKSIZE,aj+ai[brow]+nrow,len*sizeof(int));CHKERRQ(ierr);
1106549d3d68SSatish Balay         ierr = PetscMemcpy(new_a,aa,(ai[brow]+nrow)*bs2*sizeof(MatScalar));CHKERRQ(ierr);
1107549d3d68SSatish Balay         ierr = PetscMemzero(new_a+bs2*(ai[brow]+nrow),bs2*CHUNKSIZE*sizeof(MatScalar));CHKERRQ(ierr);
1108549d3d68SSatish Balay         ierr = PetscMemcpy(new_a+bs2*(ai[brow]+nrow+CHUNKSIZE),aa+bs2*(ai[brow]+nrow),bs2*len*sizeof(MatScalar));CHKERRQ(ierr);
11092d61bbb3SSatish Balay         /* free up old matrix storage */
1110606d414cSSatish Balay         ierr = PetscFree(a->a);CHKERRQ(ierr);
1111606d414cSSatish Balay         if (!a->singlemalloc) {
1112606d414cSSatish Balay           ierr = PetscFree(a->i);CHKERRQ(ierr);
1113606d414cSSatish Balay           ierr = PetscFree(a->j);CHKERRQ(ierr);
1114606d414cSSatish Balay         }
11152d61bbb3SSatish Balay         aa = a->a = new_a; ai = a->i = new_i; aj = a->j = new_j;
1116c4992f7dSBarry Smith         a->singlemalloc = PETSC_TRUE;
11172d61bbb3SSatish Balay 
11182d61bbb3SSatish Balay         rp   = aj + ai[brow]; ap = aa + bs2*ai[brow];
11192d61bbb3SSatish Balay         rmax = imax[brow] = imax[brow] + CHUNKSIZE;
11203f1db9ecSBarry Smith         PLogObjectMemory(A,CHUNKSIZE*(sizeof(int) + bs2*sizeof(MatScalar)));
11212d61bbb3SSatish Balay         a->maxnz += bs2*CHUNKSIZE;
11222d61bbb3SSatish Balay         a->reallocs++;
11232d61bbb3SSatish Balay         a->nz++;
11242d61bbb3SSatish Balay       }
11252d61bbb3SSatish Balay       N = nrow++ - 1;
11262d61bbb3SSatish Balay       /* shift up all the later entries in this row */
11272d61bbb3SSatish Balay       for (ii=N; ii>=i; ii--) {
11282d61bbb3SSatish Balay         rp[ii+1] = rp[ii];
1129549d3d68SSatish Balay         ierr     = PetscMemcpy(ap+bs2*(ii+1),ap+bs2*(ii),bs2*sizeof(MatScalar));CHKERRQ(ierr);
11302d61bbb3SSatish Balay       }
1131549d3d68SSatish Balay       if (N>=i) {
1132549d3d68SSatish Balay         ierr = PetscMemzero(ap+bs2*i,bs2*sizeof(MatScalar));CHKERRQ(ierr);
1133549d3d68SSatish Balay       }
11342d61bbb3SSatish Balay       rp[i]                      = bcol;
11352d61bbb3SSatish Balay       ap[bs2*i + bs*cidx + ridx] = value;
11362d61bbb3SSatish Balay       noinsert1:;
11372d61bbb3SSatish Balay       low = i;
11382d61bbb3SSatish Balay     }
11392d61bbb3SSatish Balay     ailen[brow] = nrow;
11402d61bbb3SSatish Balay   }
11412d61bbb3SSatish Balay   PetscFunctionReturn(0);
11422d61bbb3SSatish Balay }
11432d61bbb3SSatish Balay 
1144b9b97703SBarry Smith EXTERN int MatLUFactorSymbolic_SeqBAIJ(Mat,IS,IS,MatLUInfo*,Mat*);
1145b9b97703SBarry Smith EXTERN int MatLUFactor_SeqBAIJ(Mat,IS,IS,MatLUInfo*);
1146ca44d042SBarry Smith EXTERN int MatIncreaseOverlap_SeqBAIJ(Mat,int,IS*,int);
1147ca44d042SBarry Smith EXTERN int MatGetSubMatrix_SeqBAIJ(Mat,IS,IS,int,MatReuse,Mat*);
1148ca44d042SBarry Smith EXTERN int MatGetSubMatrices_SeqBAIJ(Mat,int,IS*,IS*,MatReuse,Mat**);
1149ca44d042SBarry Smith EXTERN int MatMultTranspose_SeqBAIJ(Mat,Vec,Vec);
1150ca44d042SBarry Smith EXTERN int MatMultTransposeAdd_SeqBAIJ(Mat,Vec,Vec,Vec);
1151ca44d042SBarry Smith EXTERN int MatScale_SeqBAIJ(Scalar*,Mat);
1152ca44d042SBarry Smith EXTERN int MatNorm_SeqBAIJ(Mat,NormType,PetscReal *);
1153ca44d042SBarry Smith EXTERN int MatEqual_SeqBAIJ(Mat,Mat,PetscTruth*);
1154ca44d042SBarry Smith EXTERN int MatGetDiagonal_SeqBAIJ(Mat,Vec);
1155ca44d042SBarry Smith EXTERN int MatDiagonalScale_SeqBAIJ(Mat,Vec,Vec);
1156ca44d042SBarry Smith EXTERN int MatGetInfo_SeqBAIJ(Mat,MatInfoType,MatInfo *);
1157ca44d042SBarry Smith EXTERN int MatZeroEntries_SeqBAIJ(Mat);
11582d61bbb3SSatish Balay 
1159ca44d042SBarry Smith EXTERN int MatSolve_SeqBAIJ_N(Mat,Vec,Vec);
1160ca44d042SBarry Smith EXTERN int MatSolve_SeqBAIJ_1(Mat,Vec,Vec);
1161ca44d042SBarry Smith EXTERN int MatSolve_SeqBAIJ_2(Mat,Vec,Vec);
1162ca44d042SBarry Smith EXTERN int MatSolve_SeqBAIJ_3(Mat,Vec,Vec);
1163ca44d042SBarry Smith EXTERN int MatSolve_SeqBAIJ_4(Mat,Vec,Vec);
1164ca44d042SBarry Smith EXTERN int MatSolve_SeqBAIJ_5(Mat,Vec,Vec);
1165ca44d042SBarry Smith EXTERN int MatSolve_SeqBAIJ_6(Mat,Vec,Vec);
1166ca44d042SBarry Smith EXTERN int MatSolve_SeqBAIJ_7(Mat,Vec,Vec);
1167ca44d042SBarry Smith EXTERN int MatSolveTranspose_SeqBAIJ_7(Mat,Vec,Vec);
1168ca44d042SBarry Smith EXTERN int MatSolveTranspose_SeqBAIJ_6(Mat,Vec,Vec);
1169ca44d042SBarry Smith EXTERN int MatSolveTranspose_SeqBAIJ_5(Mat,Vec,Vec);
1170ca44d042SBarry Smith EXTERN int MatSolveTranspose_SeqBAIJ_4(Mat,Vec,Vec);
1171ca44d042SBarry Smith EXTERN int MatSolveTranspose_SeqBAIJ_3(Mat,Vec,Vec);
1172ca44d042SBarry Smith EXTERN int MatSolveTranspose_SeqBAIJ_2(Mat,Vec,Vec);
1173ca44d042SBarry Smith EXTERN int MatSolveTranspose_SeqBAIJ_1(Mat,Vec,Vec);
11742d61bbb3SSatish Balay 
1175ca44d042SBarry Smith EXTERN int MatLUFactorNumeric_SeqBAIJ_N(Mat,Mat*);
1176ca44d042SBarry Smith EXTERN int MatLUFactorNumeric_SeqBAIJ_1(Mat,Mat*);
1177ca44d042SBarry Smith EXTERN int MatLUFactorNumeric_SeqBAIJ_2(Mat,Mat*);
1178ca44d042SBarry Smith EXTERN int MatLUFactorNumeric_SeqBAIJ_3(Mat,Mat*);
1179ca44d042SBarry Smith EXTERN int MatLUFactorNumeric_SeqBAIJ_4(Mat,Mat*);
1180ca44d042SBarry Smith EXTERN int MatLUFactorNumeric_SeqBAIJ_5(Mat,Mat*);
1181ca44d042SBarry Smith EXTERN int MatLUFactorNumeric_SeqBAIJ_6(Mat,Mat*);
11822d61bbb3SSatish Balay 
1183ca44d042SBarry Smith EXTERN int MatMult_SeqBAIJ_1(Mat,Vec,Vec);
1184ca44d042SBarry Smith EXTERN int MatMult_SeqBAIJ_2(Mat,Vec,Vec);
1185ca44d042SBarry Smith EXTERN int MatMult_SeqBAIJ_3(Mat,Vec,Vec);
1186ca44d042SBarry Smith EXTERN int MatMult_SeqBAIJ_4(Mat,Vec,Vec);
1187ca44d042SBarry Smith EXTERN int MatMult_SeqBAIJ_5(Mat,Vec,Vec);
1188ca44d042SBarry Smith EXTERN int MatMult_SeqBAIJ_6(Mat,Vec,Vec);
1189ca44d042SBarry Smith EXTERN int MatMult_SeqBAIJ_7(Mat,Vec,Vec);
1190ca44d042SBarry Smith EXTERN int MatMult_SeqBAIJ_N(Mat,Vec,Vec);
11912d61bbb3SSatish Balay 
1192ca44d042SBarry Smith EXTERN int MatMultAdd_SeqBAIJ_1(Mat,Vec,Vec,Vec);
1193ca44d042SBarry Smith EXTERN int MatMultAdd_SeqBAIJ_2(Mat,Vec,Vec,Vec);
1194ca44d042SBarry Smith EXTERN int MatMultAdd_SeqBAIJ_3(Mat,Vec,Vec,Vec);
1195ca44d042SBarry Smith EXTERN int MatMultAdd_SeqBAIJ_4(Mat,Vec,Vec,Vec);
1196ca44d042SBarry Smith EXTERN int MatMultAdd_SeqBAIJ_5(Mat,Vec,Vec,Vec);
1197ca44d042SBarry Smith EXTERN int MatMultAdd_SeqBAIJ_6(Mat,Vec,Vec,Vec);
1198ca44d042SBarry Smith EXTERN int MatMultAdd_SeqBAIJ_7(Mat,Vec,Vec,Vec);
1199ca44d042SBarry Smith EXTERN int MatMultAdd_SeqBAIJ_N(Mat,Vec,Vec,Vec);
12002d61bbb3SSatish Balay 
12012d61bbb3SSatish Balay #undef __FUNC__
1202b2863d3aSBarry Smith #define __FUNC__ /*<a name=""></a>*/"MatILUFactor_SeqBAIJ"
12035ef9f2a5SBarry Smith int MatILUFactor_SeqBAIJ(Mat inA,IS row,IS col,MatILUInfo *info)
12042d61bbb3SSatish Balay {
12052d61bbb3SSatish Balay   Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)inA->data;
12062d61bbb3SSatish Balay   Mat         outA;
12072d61bbb3SSatish Balay   int         ierr;
1208667159a5SBarry Smith   PetscTruth  row_identity,col_identity;
12092d61bbb3SSatish Balay 
12102d61bbb3SSatish Balay   PetscFunctionBegin;
1211*29bbc08cSBarry Smith   if (info && info->levels != 0) SETERRQ(PETSC_ERR_SUP,"Only levels = 0 supported for in-place ILU");
1212667159a5SBarry Smith   ierr = ISIdentity(row,&row_identity);CHKERRQ(ierr);
1213667159a5SBarry Smith   ierr = ISIdentity(col,&col_identity);CHKERRQ(ierr);
1214667159a5SBarry Smith   if (!row_identity || !col_identity) {
1215*29bbc08cSBarry Smith     SETERRQ(1,"Row and column permutations must be identity for in-place ILU");
1216667159a5SBarry Smith   }
12172d61bbb3SSatish Balay 
12182d61bbb3SSatish Balay   outA          = inA;
12192d61bbb3SSatish Balay   inA->factor   = FACTOR_LU;
12202d61bbb3SSatish Balay 
12212d61bbb3SSatish Balay   if (!a->diag) {
1222c4992f7dSBarry Smith     ierr = MatMarkDiagonal_SeqBAIJ(inA);CHKERRQ(ierr);
12232d61bbb3SSatish Balay   }
12242d61bbb3SSatish Balay   /*
122515091d37SBarry Smith       Blocksize 2, 3, 4, 5, 6 and 7 have a special faster factorization/solver
122615091d37SBarry Smith       for ILU(0) factorization with natural ordering
12272d61bbb3SSatish Balay   */
122815091d37SBarry Smith   switch (a->bs) {
1229f1af5d2fSBarry Smith   case 1:
1230e37c484bSBarry Smith     inA->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_1;
1231e37c484bSBarry Smith     inA->ops->solve           = MatSolve_SeqBAIJ_1_NaturalOrdering;
1232e37c484bSBarry Smith     inA->ops->solvetranspose  = MatSolveTranspose_SeqBAIJ_1_NaturalOrdering;
1233e37c484bSBarry Smith     PLogInfo(inA,"MatILUFactor_SeqBAIJ:Using special in-place natural ordering factor and solve BS=1\n");
123415091d37SBarry Smith   case 2:
123515091d37SBarry Smith     inA->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_2_NaturalOrdering;
123615091d37SBarry Smith     inA->ops->solve           = MatSolve_SeqBAIJ_2_NaturalOrdering;
12377c922b88SBarry Smith     inA->ops->solvetranspose  = MatSolveTranspose_SeqBAIJ_2_NaturalOrdering;
123815091d37SBarry Smith     PLogInfo(inA,"MatILUFactor_SeqBAIJ:Using special in-place natural ordering factor and solve BS=2\n");
123915091d37SBarry Smith     break;
124015091d37SBarry Smith   case 3:
124115091d37SBarry Smith     inA->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_3_NaturalOrdering;
124215091d37SBarry Smith     inA->ops->solve           = MatSolve_SeqBAIJ_3_NaturalOrdering;
12437c922b88SBarry Smith     inA->ops->solvetranspose  = MatSolveTranspose_SeqBAIJ_3_NaturalOrdering;
124415091d37SBarry Smith     PLogInfo(inA,"MatILUFactor_SeqBAIJ:Using special in-place natural ordering factor and solve BS=3\n");
124515091d37SBarry Smith     break;
124615091d37SBarry Smith   case 4:
1247667159a5SBarry Smith     inA->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_4_NaturalOrdering;
1248f830108cSBarry Smith     inA->ops->solve           = MatSolve_SeqBAIJ_4_NaturalOrdering;
12497c922b88SBarry Smith     inA->ops->solvetranspose  = MatSolveTranspose_SeqBAIJ_4_NaturalOrdering;
125015091d37SBarry Smith     PLogInfo(inA,"MatILUFactor_SeqBAIJ:Using special in-place natural ordering factor and solve BS=4\n");
125115091d37SBarry Smith     break;
125215091d37SBarry Smith   case 5:
1253667159a5SBarry Smith     inA->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_5_NaturalOrdering;
1254667159a5SBarry Smith     inA->ops->solve           = MatSolve_SeqBAIJ_5_NaturalOrdering;
12557c922b88SBarry Smith     inA->ops->solvetranspose  = MatSolveTranspose_SeqBAIJ_5_NaturalOrdering;
125615091d37SBarry Smith     PLogInfo(inA,"MatILUFactor_SeqBAIJ:Using special in-place natural ordering factor and solve BS=5\n");
125715091d37SBarry Smith     break;
125815091d37SBarry Smith   case 6:
125915091d37SBarry Smith     inA->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_6_NaturalOrdering;
126015091d37SBarry Smith     inA->ops->solve           = MatSolve_SeqBAIJ_6_NaturalOrdering;
12617c922b88SBarry Smith     inA->ops->solvetranspose  = MatSolveTranspose_SeqBAIJ_6_NaturalOrdering;
126215091d37SBarry Smith     PLogInfo(inA,"MatILUFactor_SeqBAIJ:Using special in-place natural ordering factor and solve BS=6\n");
126315091d37SBarry Smith     break;
126415091d37SBarry Smith   case 7:
126515091d37SBarry Smith     inA->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_7_NaturalOrdering;
12667c922b88SBarry Smith     inA->ops->solvetranspose  = MatSolveTranspose_SeqBAIJ_7_NaturalOrdering;
126715091d37SBarry Smith     inA->ops->solve           = MatSolve_SeqBAIJ_7_NaturalOrdering;
126815091d37SBarry Smith     PLogInfo(inA,"MatILUFactor_SeqBAIJ:Using special in-place natural ordering factor and solve BS=7\n");
126915091d37SBarry Smith     break;
1270c38d4ed2SBarry Smith   default:
1271c38d4ed2SBarry Smith     a->row        = row;
1272c38d4ed2SBarry Smith     a->col        = col;
1273c38d4ed2SBarry Smith     ierr          = PetscObjectReference((PetscObject)row);CHKERRQ(ierr);
1274c38d4ed2SBarry Smith     ierr          = PetscObjectReference((PetscObject)col);CHKERRQ(ierr);
1275c38d4ed2SBarry Smith 
1276c38d4ed2SBarry Smith     /* Create the invert permutation so that it can be used in MatLUFactorNumeric() */
12774c49b128SBarry Smith     ierr = ISInvertPermutation(col,PETSC_DECIDE,&a->icol);CHKERRQ(ierr);
1278c38d4ed2SBarry Smith     PLogObjectParent(inA,a->icol);
1279c38d4ed2SBarry Smith 
1280c38d4ed2SBarry Smith     if (!a->solve_work) {
1281c38d4ed2SBarry Smith       a->solve_work = (Scalar*)PetscMalloc((a->m+a->bs)*sizeof(Scalar));CHKPTRQ(a->solve_work);
1282c38d4ed2SBarry Smith       PLogObjectMemory(inA,(a->m+a->bs)*sizeof(Scalar));
1283c38d4ed2SBarry Smith     }
12842d61bbb3SSatish Balay   }
12852d61bbb3SSatish Balay 
1286667159a5SBarry Smith   ierr = MatLUFactorNumeric(inA,&outA);CHKERRQ(ierr);
1287667159a5SBarry Smith 
12882d61bbb3SSatish Balay   PetscFunctionReturn(0);
12892d61bbb3SSatish Balay }
12902d61bbb3SSatish Balay #undef __FUNC__
1291b2863d3aSBarry Smith #define __FUNC__ /*<a name=""></a>*/"MatPrintHelp_SeqBAIJ"
1292ba4ca20aSSatish Balay int MatPrintHelp_SeqBAIJ(Mat A)
1293ba4ca20aSSatish Balay {
1294c38d4ed2SBarry Smith   static PetscTruth called = PETSC_FALSE;
1295ba4ca20aSSatish Balay   MPI_Comm          comm = A->comm;
1296d132466eSBarry Smith   int               ierr;
1297ba4ca20aSSatish Balay 
12983a40ed3dSBarry Smith   PetscFunctionBegin;
1299c38d4ed2SBarry Smith   if (called) {PetscFunctionReturn(0);} else called = PETSC_TRUE;
1300d132466eSBarry Smith   ierr = (*PetscHelpPrintf)(comm," Options for MATSEQBAIJ and MATMPIBAIJ matrix formats (the defaults):\n");CHKERRQ(ierr);
1301d132466eSBarry Smith   ierr = (*PetscHelpPrintf)(comm,"  -mat_block_size <block_size>\n");CHKERRQ(ierr);
13023a40ed3dSBarry Smith   PetscFunctionReturn(0);
1303ba4ca20aSSatish Balay }
1304d9b7c43dSSatish Balay 
1305fb2e594dSBarry Smith EXTERN_C_BEGIN
130627a8da17SBarry Smith #undef __FUNC__
1307b2863d3aSBarry Smith #define __FUNC__ /*<a name=""></a>*/"MatSeqBAIJSetColumnIndices_SeqBAIJ"
130827a8da17SBarry Smith int MatSeqBAIJSetColumnIndices_SeqBAIJ(Mat mat,int *indices)
130927a8da17SBarry Smith {
131027a8da17SBarry Smith   Mat_SeqBAIJ *baij = (Mat_SeqBAIJ *)mat->data;
131127a8da17SBarry Smith   int         i,nz,n;
131227a8da17SBarry Smith 
131327a8da17SBarry Smith   PetscFunctionBegin;
131427a8da17SBarry Smith   nz = baij->maxnz;
131527a8da17SBarry Smith   n  = baij->n;
131627a8da17SBarry Smith   for (i=0; i<nz; i++) {
131727a8da17SBarry Smith     baij->j[i] = indices[i];
131827a8da17SBarry Smith   }
131927a8da17SBarry Smith   baij->nz = nz;
132027a8da17SBarry Smith   for (i=0; i<n; i++) {
132127a8da17SBarry Smith     baij->ilen[i] = baij->imax[i];
132227a8da17SBarry Smith   }
132327a8da17SBarry Smith 
132427a8da17SBarry Smith   PetscFunctionReturn(0);
132527a8da17SBarry Smith }
1326fb2e594dSBarry Smith EXTERN_C_END
132727a8da17SBarry Smith 
132827a8da17SBarry Smith #undef __FUNC__
1329b2863d3aSBarry Smith #define __FUNC__ /*<a name=""></a>*/"MatSeqBAIJSetColumnIndices"
133027a8da17SBarry Smith /*@
133127a8da17SBarry Smith     MatSeqBAIJSetColumnIndices - Set the column indices for all the rows
133227a8da17SBarry Smith        in the matrix.
133327a8da17SBarry Smith 
133427a8da17SBarry Smith   Input Parameters:
133527a8da17SBarry Smith +  mat - the SeqBAIJ matrix
133627a8da17SBarry Smith -  indices - the column indices
133727a8da17SBarry Smith 
133815091d37SBarry Smith   Level: advanced
133915091d37SBarry Smith 
134027a8da17SBarry Smith   Notes:
134127a8da17SBarry Smith     This can be called if you have precomputed the nonzero structure of the
134227a8da17SBarry Smith   matrix and want to provide it to the matrix object to improve the performance
134327a8da17SBarry Smith   of the MatSetValues() operation.
134427a8da17SBarry Smith 
134527a8da17SBarry Smith     You MUST have set the correct numbers of nonzeros per row in the call to
134627a8da17SBarry Smith   MatCreateSeqBAIJ().
134727a8da17SBarry Smith 
134827a8da17SBarry Smith     MUST be called before any calls to MatSetValues();
134927a8da17SBarry Smith 
135027a8da17SBarry Smith @*/
135127a8da17SBarry Smith int MatSeqBAIJSetColumnIndices(Mat mat,int *indices)
135227a8da17SBarry Smith {
135327a8da17SBarry Smith   int ierr,(*f)(Mat,int *);
135427a8da17SBarry Smith 
135527a8da17SBarry Smith   PetscFunctionBegin;
135627a8da17SBarry Smith   PetscValidHeaderSpecific(mat,MAT_COOKIE);
1357549d3d68SSatish Balay   ierr = PetscObjectQueryFunction((PetscObject)mat,"MatSeqBAIJSetColumnIndices_C",(void **)&f);CHKERRQ(ierr);
135827a8da17SBarry Smith   if (f) {
135927a8da17SBarry Smith     ierr = (*f)(mat,indices);CHKERRQ(ierr);
136027a8da17SBarry Smith   } else {
1361*29bbc08cSBarry Smith     SETERRQ(1,"Wrong type of matrix to set column indices");
136227a8da17SBarry Smith   }
136327a8da17SBarry Smith   PetscFunctionReturn(0);
136427a8da17SBarry Smith }
136527a8da17SBarry Smith 
13662593348eSBarry Smith /* -------------------------------------------------------------------*/
1367cc2dc46cSBarry Smith static struct _MatOps MatOps_Values = {MatSetValues_SeqBAIJ,
1368cc2dc46cSBarry Smith        MatGetRow_SeqBAIJ,
1369cc2dc46cSBarry Smith        MatRestoreRow_SeqBAIJ,
1370cc2dc46cSBarry Smith        MatMult_SeqBAIJ_N,
1371cc2dc46cSBarry Smith        MatMultAdd_SeqBAIJ_N,
13727c922b88SBarry Smith        MatMultTranspose_SeqBAIJ,
13737c922b88SBarry Smith        MatMultTransposeAdd_SeqBAIJ,
1374cc2dc46cSBarry Smith        MatSolve_SeqBAIJ_N,
1375cc2dc46cSBarry Smith        0,
1376cc2dc46cSBarry Smith        0,
1377cc2dc46cSBarry Smith        0,
1378cc2dc46cSBarry Smith        MatLUFactor_SeqBAIJ,
1379cc2dc46cSBarry Smith        0,
1380b6490206SBarry Smith        0,
1381f2501298SSatish Balay        MatTranspose_SeqBAIJ,
1382cc2dc46cSBarry Smith        MatGetInfo_SeqBAIJ,
1383cc2dc46cSBarry Smith        MatEqual_SeqBAIJ,
1384cc2dc46cSBarry Smith        MatGetDiagonal_SeqBAIJ,
1385cc2dc46cSBarry Smith        MatDiagonalScale_SeqBAIJ,
1386cc2dc46cSBarry Smith        MatNorm_SeqBAIJ,
1387b6490206SBarry Smith        0,
1388cc2dc46cSBarry Smith        MatAssemblyEnd_SeqBAIJ,
1389cc2dc46cSBarry Smith        0,
1390cc2dc46cSBarry Smith        MatSetOption_SeqBAIJ,
1391cc2dc46cSBarry Smith        MatZeroEntries_SeqBAIJ,
1392cc2dc46cSBarry Smith        MatZeroRows_SeqBAIJ,
1393cc2dc46cSBarry Smith        MatLUFactorSymbolic_SeqBAIJ,
1394cc2dc46cSBarry Smith        MatLUFactorNumeric_SeqBAIJ_N,
1395cc2dc46cSBarry Smith        0,
1396cc2dc46cSBarry Smith        0,
1397cc2dc46cSBarry Smith        MatGetSize_SeqBAIJ,
1398cc2dc46cSBarry Smith        MatGetSize_SeqBAIJ,
1399cc2dc46cSBarry Smith        MatGetOwnershipRange_SeqBAIJ,
1400cc2dc46cSBarry Smith        MatILUFactorSymbolic_SeqBAIJ,
1401cc2dc46cSBarry Smith        0,
1402cc2dc46cSBarry Smith        0,
1403cc2dc46cSBarry Smith        0,
14042e8a6d31SBarry Smith        MatDuplicate_SeqBAIJ,
1405cc2dc46cSBarry Smith        0,
1406cc2dc46cSBarry Smith        0,
1407cc2dc46cSBarry Smith        MatILUFactor_SeqBAIJ,
1408cc2dc46cSBarry Smith        0,
1409cc2dc46cSBarry Smith        0,
1410cc2dc46cSBarry Smith        MatGetSubMatrices_SeqBAIJ,
1411cc2dc46cSBarry Smith        MatIncreaseOverlap_SeqBAIJ,
1412cc2dc46cSBarry Smith        MatGetValues_SeqBAIJ,
1413cc2dc46cSBarry Smith        0,
1414cc2dc46cSBarry Smith        MatPrintHelp_SeqBAIJ,
1415cc2dc46cSBarry Smith        MatScale_SeqBAIJ,
1416cc2dc46cSBarry Smith        0,
1417cc2dc46cSBarry Smith        0,
1418cc2dc46cSBarry Smith        0,
1419cc2dc46cSBarry Smith        MatGetBlockSize_SeqBAIJ,
14203b2fbd54SBarry Smith        MatGetRowIJ_SeqBAIJ,
142192c4ed94SBarry Smith        MatRestoreRowIJ_SeqBAIJ,
1422cc2dc46cSBarry Smith        0,
1423cc2dc46cSBarry Smith        0,
1424cc2dc46cSBarry Smith        0,
1425cc2dc46cSBarry Smith        0,
1426cc2dc46cSBarry Smith        0,
1427cc2dc46cSBarry Smith        0,
1428d3825aa8SBarry Smith        MatSetValuesBlocked_SeqBAIJ,
1429cc2dc46cSBarry Smith        MatGetSubMatrix_SeqBAIJ,
1430b9b97703SBarry Smith        MatDestroy_SeqBAIJ,
1431b9b97703SBarry Smith        MatView_SeqBAIJ,
1432cc2dc46cSBarry Smith        MatGetMaps_Petsc};
14332593348eSBarry Smith 
14343e90b805SBarry Smith EXTERN_C_BEGIN
14353e90b805SBarry Smith #undef __FUNC__
1436b2863d3aSBarry Smith #define __FUNC__ /*<a name=""></a>*/"MatStoreValues_SeqBAIJ"
14373e90b805SBarry Smith int MatStoreValues_SeqBAIJ(Mat mat)
14383e90b805SBarry Smith {
14393e90b805SBarry Smith   Mat_SeqBAIJ *aij = (Mat_SeqBAIJ *)mat->data;
14403e90b805SBarry Smith   int         nz = aij->i[aij->m]*aij->bs*aij->bs2;
1441d132466eSBarry Smith   int         ierr;
14423e90b805SBarry Smith 
14433e90b805SBarry Smith   PetscFunctionBegin;
14443e90b805SBarry Smith   if (aij->nonew != 1) {
1445*29bbc08cSBarry Smith     SETERRQ(1,"Must call MatSetOption(A,MAT_NO_NEW_NONZERO_LOCATIONS);first");
14463e90b805SBarry Smith   }
14473e90b805SBarry Smith 
14483e90b805SBarry Smith   /* allocate space for values if not already there */
14493e90b805SBarry Smith   if (!aij->saved_values) {
14503e90b805SBarry Smith     aij->saved_values = (Scalar*)PetscMalloc(nz*sizeof(Scalar));CHKPTRQ(aij->saved_values);
14513e90b805SBarry Smith   }
14523e90b805SBarry Smith 
14533e90b805SBarry Smith   /* copy values over */
1454d132466eSBarry Smith   ierr = PetscMemcpy(aij->saved_values,aij->a,nz*sizeof(Scalar));CHKERRQ(ierr);
14553e90b805SBarry Smith   PetscFunctionReturn(0);
14563e90b805SBarry Smith }
14573e90b805SBarry Smith EXTERN_C_END
14583e90b805SBarry Smith 
14593e90b805SBarry Smith EXTERN_C_BEGIN
14603e90b805SBarry Smith #undef __FUNC__
1461b2863d3aSBarry Smith #define __FUNC__ /*<a name=""></a>*/"MatRetrieveValues_SeqBAIJ"
146232e87ba3SBarry Smith int MatRetrieveValues_SeqBAIJ(Mat mat)
14633e90b805SBarry Smith {
14643e90b805SBarry Smith   Mat_SeqBAIJ *aij = (Mat_SeqBAIJ *)mat->data;
1465549d3d68SSatish Balay   int         nz = aij->i[aij->m]*aij->bs*aij->bs2,ierr;
14663e90b805SBarry Smith 
14673e90b805SBarry Smith   PetscFunctionBegin;
14683e90b805SBarry Smith   if (aij->nonew != 1) {
1469*29bbc08cSBarry Smith     SETERRQ(1,"Must call MatSetOption(A,MAT_NO_NEW_NONZERO_LOCATIONS);first");
14703e90b805SBarry Smith   }
14713e90b805SBarry Smith   if (!aij->saved_values) {
1472*29bbc08cSBarry Smith     SETERRQ(1,"Must call MatStoreValues(A);first");
14733e90b805SBarry Smith   }
14743e90b805SBarry Smith 
14753e90b805SBarry Smith   /* copy values over */
1476549d3d68SSatish Balay   ierr = PetscMemcpy(aij->a,aij->saved_values,nz*sizeof(Scalar));CHKERRQ(ierr);
14773e90b805SBarry Smith   PetscFunctionReturn(0);
14783e90b805SBarry Smith }
14793e90b805SBarry Smith EXTERN_C_END
14803e90b805SBarry Smith 
14815615d1e5SSatish Balay #undef __FUNC__
1482b2863d3aSBarry Smith #define __FUNC__ /*<a name=""></a>*/"MatCreateSeqBAIJ"
14832593348eSBarry Smith /*@C
148444cd7ae7SLois Curfman McInnes    MatCreateSeqBAIJ - Creates a sparse matrix in block AIJ (block
148544cd7ae7SLois Curfman McInnes    compressed row) format.  For good matrix assembly performance the
148644cd7ae7SLois Curfman McInnes    user should preallocate the matrix storage by setting the parameter nz
14877fc3c18eSBarry Smith    (or the array nnz).  By setting these parameters accurately, performance
14882bd5e0b2SLois Curfman McInnes    during matrix assembly can be increased by more than a factor of 50.
14892593348eSBarry Smith 
1490db81eaa0SLois Curfman McInnes    Collective on MPI_Comm
1491db81eaa0SLois Curfman McInnes 
14922593348eSBarry Smith    Input Parameters:
1493db81eaa0SLois Curfman McInnes +  comm - MPI communicator, set to PETSC_COMM_SELF
1494b6490206SBarry Smith .  bs - size of block
14952593348eSBarry Smith .  m - number of rows
14962593348eSBarry Smith .  n - number of columns
1497b6490206SBarry Smith .  nz - number of block nonzeros per block row (same for all rows)
14987fc3c18eSBarry Smith -  nnz - array containing the number of block nonzeros in the various block rows
14992bd5e0b2SLois Curfman McInnes          (possibly different for each block row) or PETSC_NULL
15002593348eSBarry Smith 
15012593348eSBarry Smith    Output Parameter:
15022593348eSBarry Smith .  A - the matrix
15032593348eSBarry Smith 
15040513a670SBarry Smith    Options Database Keys:
1505db81eaa0SLois Curfman McInnes .   -mat_no_unroll - uses code that does not unroll the loops in the
1506db81eaa0SLois Curfman McInnes                      block calculations (much slower)
1507db81eaa0SLois Curfman McInnes .    -mat_block_size - size of the blocks to use
15080513a670SBarry Smith 
150915091d37SBarry Smith    Level: intermediate
151015091d37SBarry Smith 
15112593348eSBarry Smith    Notes:
151244cd7ae7SLois Curfman McInnes    The block AIJ format is fully compatible with standard Fortran 77
15132593348eSBarry Smith    storage.  That is, the stored row and column indices can begin at
151444cd7ae7SLois Curfman McInnes    either one (as in Fortran) or zero.  See the users' manual for details.
15152593348eSBarry Smith 
15162593348eSBarry Smith    Specify the preallocated storage with either nz or nnz (not both).
15172593348eSBarry Smith    Set nz=PETSC_DEFAULT and nnz=PETSC_NULL for PETSc to control dynamic memory
15182593348eSBarry Smith    allocation.  For additional details, see the users manual chapter on
15196da5968aSLois Curfman McInnes    matrices.
15202593348eSBarry Smith 
1521db81eaa0SLois Curfman McInnes .seealso: MatCreate(), MatCreateSeqAIJ(), MatSetValues(), MatCreateMPIBAIJ()
15222593348eSBarry Smith @*/
1523b6490206SBarry Smith int MatCreateSeqBAIJ(MPI_Comm comm,int bs,int m,int n,int nz,int *nnz,Mat *A)
15242593348eSBarry Smith {
15252593348eSBarry Smith   Mat         B;
1526b6490206SBarry Smith   Mat_SeqBAIJ *b;
15276827595bSBarry Smith   int         i,len,ierr,mbs,nbs,bs2,size,newbs = bs;
1528f1af5d2fSBarry Smith   PetscTruth  flg;
15293b2fbd54SBarry Smith 
15303a40ed3dSBarry Smith   PetscFunctionBegin;
1531d132466eSBarry Smith   ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr);
1532*29bbc08cSBarry Smith   if (size > 1) SETERRQ(PETSC_ERR_ARG_WRONG,"Comm must be of size 1");
1533b6490206SBarry Smith 
15346827595bSBarry Smith   ierr = OptionsGetInt(PETSC_NULL,"-mat_block_size",&newbs,PETSC_NULL);CHKERRQ(ierr);
15356827595bSBarry Smith   if (nnz && newbs != bs) {
1536*29bbc08cSBarry Smith     SETERRQ(1,"Cannot change blocksize from command line if setting nnz");
15376827595bSBarry Smith   }
15386827595bSBarry Smith 
1539302e33e3SBarry Smith   mbs  = m/bs;
1540302e33e3SBarry Smith   nbs  = n/bs;
1541302e33e3SBarry Smith   bs2  = bs*bs;
15420513a670SBarry Smith 
15433a40ed3dSBarry Smith   if (mbs*bs!=m || nbs*bs!=n) {
1544*29bbc08cSBarry Smith     SETERRQ(PETSC_ERR_ARG_SIZ,"Number rows, cols must be divisible by blocksize");
15453a40ed3dSBarry Smith   }
15462593348eSBarry Smith 
1547*29bbc08cSBarry Smith   if (nz < -2) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"nz cannot be less than -2: value %d",nz);
1548b73539f3SBarry Smith   if (nnz) {
1549faf3f1fcSBarry Smith     for (i=0; i<mbs; i++) {
1550*29bbc08cSBarry Smith       if (nnz[i] < 0) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"nnz cannot be less than 0: local row %d value %d",i,nnz[i]);
1551b73539f3SBarry Smith     }
1552b73539f3SBarry Smith   }
1553b73539f3SBarry Smith 
15542593348eSBarry Smith   *A = 0;
15553f1db9ecSBarry Smith   PetscHeaderCreate(B,_p_Mat,struct _MatOps,MAT_COOKIE,MATSEQBAIJ,"Mat",comm,MatDestroy,MatView);
15562593348eSBarry Smith   PLogObjectCreate(B);
1557b6490206SBarry Smith   B->data = (void*)(b = PetscNew(Mat_SeqBAIJ));CHKPTRQ(b);
1558549d3d68SSatish Balay   ierr    = PetscMemzero(b,sizeof(Mat_SeqBAIJ));CHKERRQ(ierr);
1559549d3d68SSatish Balay   ierr    = PetscMemcpy(B->ops,&MatOps_Values,sizeof(struct _MatOps));CHKERRQ(ierr);
15601a6a6d98SBarry Smith   ierr    = OptionsHasName(PETSC_NULL,"-mat_no_unroll",&flg);CHKERRQ(ierr);
15611a6a6d98SBarry Smith   if (!flg) {
15627fc0212eSBarry Smith     switch (bs) {
15637fc0212eSBarry Smith     case 1:
1564f830108cSBarry Smith       B->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_1;
1565f830108cSBarry Smith       B->ops->solve           = MatSolve_SeqBAIJ_1;
15667c922b88SBarry Smith       B->ops->solvetranspose  = MatSolveTranspose_SeqBAIJ_1;
1567f830108cSBarry Smith       B->ops->mult            = MatMult_SeqBAIJ_1;
1568f830108cSBarry Smith       B->ops->multadd         = MatMultAdd_SeqBAIJ_1;
15697fc0212eSBarry Smith       break;
15704eeb42bcSBarry Smith     case 2:
1571f830108cSBarry Smith       B->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_2;
1572f830108cSBarry Smith       B->ops->solve           = MatSolve_SeqBAIJ_2;
15737c922b88SBarry Smith       B->ops->solvetranspose  = MatSolveTranspose_SeqBAIJ_2;
1574f830108cSBarry Smith       B->ops->mult            = MatMult_SeqBAIJ_2;
1575f830108cSBarry Smith       B->ops->multadd         = MatMultAdd_SeqBAIJ_2;
15766d84be18SBarry Smith       break;
1577f327dd97SBarry Smith     case 3:
1578f830108cSBarry Smith       B->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_3;
1579f830108cSBarry Smith       B->ops->solve           = MatSolve_SeqBAIJ_3;
15807c922b88SBarry Smith       B->ops->solvetranspose  = MatSolveTranspose_SeqBAIJ_3;
1581f830108cSBarry Smith       B->ops->mult            = MatMult_SeqBAIJ_3;
1582f830108cSBarry Smith       B->ops->multadd         = MatMultAdd_SeqBAIJ_3;
15834eeb42bcSBarry Smith       break;
15846d84be18SBarry Smith     case 4:
1585f830108cSBarry Smith       B->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_4;
1586f830108cSBarry Smith       B->ops->solve           = MatSolve_SeqBAIJ_4;
15877c922b88SBarry Smith       B->ops->solvetranspose  = MatSolveTranspose_SeqBAIJ_4;
1588f830108cSBarry Smith       B->ops->mult            = MatMult_SeqBAIJ_4;
1589f830108cSBarry Smith       B->ops->multadd         = MatMultAdd_SeqBAIJ_4;
15906d84be18SBarry Smith       break;
15916d84be18SBarry Smith     case 5:
1592f830108cSBarry Smith       B->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_5;
1593f830108cSBarry Smith       B->ops->solve           = MatSolve_SeqBAIJ_5;
15947c922b88SBarry Smith       B->ops->solvetranspose  = MatSolveTranspose_SeqBAIJ_5;
1595f830108cSBarry Smith       B->ops->mult            = MatMult_SeqBAIJ_5;
1596f830108cSBarry Smith       B->ops->multadd         = MatMultAdd_SeqBAIJ_5;
15976d84be18SBarry Smith       break;
159815091d37SBarry Smith     case 6:
159915091d37SBarry Smith       B->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_6;
160015091d37SBarry Smith       B->ops->solve           = MatSolve_SeqBAIJ_6;
16017c922b88SBarry Smith       B->ops->solvetranspose  = MatSolveTranspose_SeqBAIJ_6;
160215091d37SBarry Smith       B->ops->mult            = MatMult_SeqBAIJ_6;
160315091d37SBarry Smith       B->ops->multadd         = MatMultAdd_SeqBAIJ_6;
160415091d37SBarry Smith       break;
160548e9ddb2SSatish Balay     case 7:
1606f830108cSBarry Smith       B->ops->mult            = MatMult_SeqBAIJ_7;
1607f830108cSBarry Smith       B->ops->solve           = MatSolve_SeqBAIJ_7;
16087c922b88SBarry Smith       B->ops->solvetranspose  = MatSolveTranspose_SeqBAIJ_7;
1609f830108cSBarry Smith       B->ops->multadd         = MatMultAdd_SeqBAIJ_7;
161048e9ddb2SSatish Balay       break;
16117fc0212eSBarry Smith     }
16121a6a6d98SBarry Smith   }
16132593348eSBarry Smith   B->factor           = 0;
16142593348eSBarry Smith   B->lupivotthreshold = 1.0;
161590f02eecSBarry Smith   B->mapping          = 0;
16162593348eSBarry Smith   b->row              = 0;
16172593348eSBarry Smith   b->col              = 0;
1618e51c0b9cSSatish Balay   b->icol             = 0;
16192593348eSBarry Smith   b->reallocs         = 0;
16203e90b805SBarry Smith   b->saved_values     = 0;
1621563b5814SBarry Smith #if defined(PEYSC_USE_MAT_SINGLE)
1622563b5814SBarry Smith   b->setvalueslen     = 0;
1623563b5814SBarry Smith   b->setvaluescopy    = PETSC_NULL;
1624563b5814SBarry Smith #endif
16252593348eSBarry Smith 
162644cd7ae7SLois Curfman McInnes   b->m       = m; B->m = m; B->M = m;
162744cd7ae7SLois Curfman McInnes   b->n       = n; B->n = n; B->N = n;
1628a5ae1ecdSBarry Smith 
16297413bad6SBarry Smith   ierr = MapCreateMPI(comm,m,m,&B->rmap);CHKERRQ(ierr);
16307413bad6SBarry Smith   ierr = MapCreateMPI(comm,n,n,&B->cmap);CHKERRQ(ierr);
1631a5ae1ecdSBarry Smith 
1632b6490206SBarry Smith   b->mbs     = mbs;
1633f2501298SSatish Balay   b->nbs     = nbs;
1634b6490206SBarry Smith   b->imax    = (int*)PetscMalloc((mbs+1)*sizeof(int));CHKPTRQ(b->imax);
1635c4992f7dSBarry Smith   if (!nnz) {
1636119a934aSSatish Balay     if (nz == PETSC_DEFAULT) nz = 5;
16372593348eSBarry Smith     else if (nz <= 0)        nz = 1;
1638b6490206SBarry Smith     for (i=0; i<mbs; i++) b->imax[i] = nz;
1639b6490206SBarry Smith     nz = nz*mbs;
16403a40ed3dSBarry Smith   } else {
16412593348eSBarry Smith     nz = 0;
1642b6490206SBarry Smith     for (i=0; i<mbs; i++) {b->imax[i] = nnz[i]; nz += nnz[i];}
16432593348eSBarry Smith   }
16442593348eSBarry Smith 
16452593348eSBarry Smith   /* allocate the matrix space */
16463f1db9ecSBarry Smith   len   = nz*sizeof(int) + nz*bs2*sizeof(MatScalar) + (b->m+1)*sizeof(int);
16473f1db9ecSBarry Smith   b->a  = (MatScalar*)PetscMalloc(len);CHKPTRQ(b->a);
1648549d3d68SSatish Balay   ierr = PetscMemzero(b->a,nz*bs2*sizeof(MatScalar));CHKERRQ(ierr);
16497e67e3f9SSatish Balay   b->j  = (int*)(b->a + nz*bs2);
1650549d3d68SSatish Balay   ierr = PetscMemzero(b->j,nz*sizeof(int));CHKERRQ(ierr);
16512593348eSBarry Smith   b->i  = b->j + nz;
1652c4992f7dSBarry Smith   b->singlemalloc = PETSC_TRUE;
16532593348eSBarry Smith 
1654de6a44a3SBarry Smith   b->i[0] = 0;
1655b6490206SBarry Smith   for (i=1; i<mbs+1; i++) {
16562593348eSBarry Smith     b->i[i] = b->i[i-1] + b->imax[i-1];
16572593348eSBarry Smith   }
16582593348eSBarry Smith 
1659b6490206SBarry Smith   /* b->ilen will count nonzeros in each block row so far. */
1660b6490206SBarry Smith   b->ilen = (int*)PetscMalloc((mbs+1)*sizeof(int));
1661f09e8eb9SSatish Balay   PLogObjectMemory(B,len+2*(mbs+1)*sizeof(int)+sizeof(struct _p_Mat)+sizeof(Mat_SeqBAIJ));
1662b6490206SBarry Smith   for (i=0; i<mbs; i++) { b->ilen[i] = 0;}
16632593348eSBarry Smith 
1664b6490206SBarry Smith   b->bs               = bs;
16659df24120SSatish Balay   b->bs2              = bs2;
1666b6490206SBarry Smith   b->mbs              = mbs;
16672593348eSBarry Smith   b->nz               = 0;
166818e7b8e4SLois Curfman McInnes   b->maxnz            = nz*bs2;
1669c4992f7dSBarry Smith   b->sorted           = PETSC_FALSE;
1670c4992f7dSBarry Smith   b->roworiented      = PETSC_TRUE;
16712593348eSBarry Smith   b->nonew            = 0;
16722593348eSBarry Smith   b->diag             = 0;
16732593348eSBarry Smith   b->solve_work       = 0;
1674de6a44a3SBarry Smith   b->mult_work        = 0;
16752593348eSBarry Smith   b->spptr            = 0;
16760e6d2581SBarry Smith   B->info.nz_unneeded = (PetscReal)b->maxnz;
1677883fce79SBarry Smith   b->keepzeroedrows   = PETSC_FALSE;
16784e220ebcSLois Curfman McInnes 
16792593348eSBarry Smith   *A = B;
16802593348eSBarry Smith   ierr = OptionsHasName(PETSC_NULL,"-help",&flg);CHKERRQ(ierr);
16812593348eSBarry Smith   if (flg) {ierr = MatPrintHelp(B);CHKERRQ(ierr); }
168227a8da17SBarry Smith 
1683f1af5d2fSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatStoreValues_C",
16843e90b805SBarry Smith                                      "MatStoreValues_SeqBAIJ",
1685bc4b532fSSatish Balay                                       MatStoreValues_SeqBAIJ);CHKERRQ(ierr);
1686f1af5d2fSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatRetrieveValues_C",
16873e90b805SBarry Smith                                      "MatRetrieveValues_SeqBAIJ",
1688bc4b532fSSatish Balay                                       MatRetrieveValues_SeqBAIJ);CHKERRQ(ierr);
1689f1af5d2fSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatSeqBAIJSetColumnIndices_C",
169027a8da17SBarry Smith                                      "MatSeqBAIJSetColumnIndices_SeqBAIJ",
1691bc4b532fSSatish Balay                                       MatSeqBAIJSetColumnIndices_SeqBAIJ);CHKERRQ(ierr);
16923a40ed3dSBarry Smith   PetscFunctionReturn(0);
16932593348eSBarry Smith }
16942593348eSBarry Smith 
16955615d1e5SSatish Balay #undef __FUNC__
1696b2863d3aSBarry Smith #define __FUNC__ /*<a name=""></a>*/"MatDuplicate_SeqBAIJ"
16972e8a6d31SBarry Smith int MatDuplicate_SeqBAIJ(Mat A,MatDuplicateOption cpvalues,Mat *B)
16982593348eSBarry Smith {
16992593348eSBarry Smith   Mat         C;
1700b6490206SBarry Smith   Mat_SeqBAIJ *c,*a = (Mat_SeqBAIJ*)A->data;
170127a8da17SBarry Smith   int         i,len,mbs = a->mbs,nz = a->nz,bs2 =a->bs2,ierr;
1702de6a44a3SBarry Smith 
17033a40ed3dSBarry Smith   PetscFunctionBegin;
1704*29bbc08cSBarry Smith   if (a->i[mbs] != nz) SETERRQ(PETSC_ERR_PLIB,"Corrupt matrix");
17052593348eSBarry Smith 
17062593348eSBarry Smith   *B = 0;
17073f1db9ecSBarry Smith   PetscHeaderCreate(C,_p_Mat,struct _MatOps,MAT_COOKIE,MATSEQBAIJ,"Mat",A->comm,MatDestroy,MatView);
17082593348eSBarry Smith   PLogObjectCreate(C);
1709b6490206SBarry Smith   C->data           = (void*)(c = PetscNew(Mat_SeqBAIJ));CHKPTRQ(c);
1710549d3d68SSatish Balay   ierr              = PetscMemcpy(C->ops,A->ops,sizeof(struct _MatOps));CHKERRQ(ierr);
17112593348eSBarry Smith   C->factor         = A->factor;
17122593348eSBarry Smith   c->row            = 0;
17132593348eSBarry Smith   c->col            = 0;
1714cac97260SSatish Balay   c->icol           = 0;
171532e87ba3SBarry Smith   c->saved_values   = 0;
1716f1e2ffcdSBarry Smith   c->keepzeroedrows = a->keepzeroedrows;
17172593348eSBarry Smith   C->assembled      = PETSC_TRUE;
17182593348eSBarry Smith 
171944cd7ae7SLois Curfman McInnes   c->m = C->m   = a->m;
172044cd7ae7SLois Curfman McInnes   c->n = C->n   = a->n;
172144cd7ae7SLois Curfman McInnes   C->M          = a->m;
172244cd7ae7SLois Curfman McInnes   C->N          = a->n;
172344cd7ae7SLois Curfman McInnes 
1724b6490206SBarry Smith   c->bs         = a->bs;
17259df24120SSatish Balay   c->bs2        = a->bs2;
1726b6490206SBarry Smith   c->mbs        = a->mbs;
1727b6490206SBarry Smith   c->nbs        = a->nbs;
17282593348eSBarry Smith 
1729b6490206SBarry Smith   c->imax       = (int*)PetscMalloc((mbs+1)*sizeof(int));CHKPTRQ(c->imax);
1730b6490206SBarry Smith   c->ilen       = (int*)PetscMalloc((mbs+1)*sizeof(int));CHKPTRQ(c->ilen);
1731b6490206SBarry Smith   for (i=0; i<mbs; i++) {
17322593348eSBarry Smith     c->imax[i] = a->imax[i];
17332593348eSBarry Smith     c->ilen[i] = a->ilen[i];
17342593348eSBarry Smith   }
17352593348eSBarry Smith 
17362593348eSBarry Smith   /* allocate the matrix space */
1737c4992f7dSBarry Smith   c->singlemalloc = PETSC_TRUE;
17383f1db9ecSBarry Smith   len  = (mbs+1)*sizeof(int) + nz*(bs2*sizeof(MatScalar) + sizeof(int));
17393f1db9ecSBarry Smith   c->a = (MatScalar*)PetscMalloc(len);CHKPTRQ(c->a);
17407e67e3f9SSatish Balay   c->j = (int*)(c->a + nz*bs2);
1741de6a44a3SBarry Smith   c->i = c->j + nz;
1742549d3d68SSatish Balay   ierr = PetscMemcpy(c->i,a->i,(mbs+1)*sizeof(int));CHKERRQ(ierr);
1743b6490206SBarry Smith   if (mbs > 0) {
1744549d3d68SSatish Balay     ierr = PetscMemcpy(c->j,a->j,nz*sizeof(int));CHKERRQ(ierr);
17452e8a6d31SBarry Smith     if (cpvalues == MAT_COPY_VALUES) {
1746549d3d68SSatish Balay       ierr = PetscMemcpy(c->a,a->a,bs2*nz*sizeof(MatScalar));CHKERRQ(ierr);
17472e8a6d31SBarry Smith     } else {
1748549d3d68SSatish Balay       ierr = PetscMemzero(c->a,bs2*nz*sizeof(MatScalar));CHKERRQ(ierr);
17492593348eSBarry Smith     }
17502593348eSBarry Smith   }
17512593348eSBarry Smith 
1752f09e8eb9SSatish Balay   PLogObjectMemory(C,len+2*(mbs+1)*sizeof(int)+sizeof(struct _p_Mat)+sizeof(Mat_SeqBAIJ));
17532593348eSBarry Smith   c->sorted      = a->sorted;
17542593348eSBarry Smith   c->roworiented = a->roworiented;
17552593348eSBarry Smith   c->nonew       = a->nonew;
17562593348eSBarry Smith 
17572593348eSBarry Smith   if (a->diag) {
1758b6490206SBarry Smith     c->diag = (int*)PetscMalloc((mbs+1)*sizeof(int));CHKPTRQ(c->diag);
1759b6490206SBarry Smith     PLogObjectMemory(C,(mbs+1)*sizeof(int));
1760b6490206SBarry Smith     for (i=0; i<mbs; i++) {
17612593348eSBarry Smith       c->diag[i] = a->diag[i];
17622593348eSBarry Smith     }
176398305bb5SBarry Smith   } else c->diag        = 0;
17642593348eSBarry Smith   c->nz                 = a->nz;
17652593348eSBarry Smith   c->maxnz              = a->maxnz;
17662593348eSBarry Smith   c->solve_work         = 0;
17672593348eSBarry Smith   c->spptr              = 0;      /* Dangerous -I'm throwing away a->spptr */
17687fc0212eSBarry Smith   c->mult_work          = 0;
17692593348eSBarry Smith   *B = C;
17707b2a1423SBarry Smith   ierr = FListDuplicate(A->qlist,&C->qlist);CHKERRQ(ierr);
17713a40ed3dSBarry Smith   PetscFunctionReturn(0);
17722593348eSBarry Smith }
17732593348eSBarry Smith 
17745615d1e5SSatish Balay #undef __FUNC__
1775b2863d3aSBarry Smith #define __FUNC__ /*<a name=""></a>*/"MatLoad_SeqBAIJ"
177619bcc07fSBarry Smith int MatLoad_SeqBAIJ(Viewer viewer,MatType type,Mat *A)
17772593348eSBarry Smith {
1778b6490206SBarry Smith   Mat_SeqBAIJ  *a;
17792593348eSBarry Smith   Mat          B;
1780f1af5d2fSBarry Smith   int          i,nz,ierr,fd,header[4],size,*rowlengths=0,M,N,bs=1;
1781b6490206SBarry Smith   int          *mask,mbs,*jj,j,rowcount,nzcount,k,*browlengths,maskcount;
178235aab85fSBarry Smith   int          kmax,jcount,block,idx,point,nzcountb,extra_rows;
1783a7c10996SSatish Balay   int          *masked,nmask,tmp,bs2,ishift;
1784b6490206SBarry Smith   Scalar       *aa;
178519bcc07fSBarry Smith   MPI_Comm     comm = ((PetscObject)viewer)->comm;
17862593348eSBarry Smith 
17873a40ed3dSBarry Smith   PetscFunctionBegin;
1788f1af5d2fSBarry Smith   ierr = OptionsGetInt(PETSC_NULL,"-matload_block_size",&bs,PETSC_NULL);CHKERRQ(ierr);
1789de6a44a3SBarry Smith   bs2  = bs*bs;
1790b6490206SBarry Smith 
1791d132466eSBarry Smith   ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr);
1792*29bbc08cSBarry Smith   if (size > 1) SETERRQ(PETSC_ERR_ARG_WRONG,"view must have one processor");
179390ace30eSBarry Smith   ierr = ViewerBinaryGetDescriptor(viewer,&fd);CHKERRQ(ierr);
17940752156aSBarry Smith   ierr = PetscBinaryRead(fd,header,4,PETSC_INT);CHKERRQ(ierr);
1795*29bbc08cSBarry Smith   if (header[0] != MAT_COOKIE) SETERRQ(PETSC_ERR_FILE_UNEXPECTED,"not Mat object");
17962593348eSBarry Smith   M = header[1]; N = header[2]; nz = header[3];
17972593348eSBarry Smith 
1798d64ed03dSBarry Smith   if (header[3] < 0) {
1799*29bbc08cSBarry Smith     SETERRQ(PETSC_ERR_FILE_UNEXPECTED,"Matrix stored in special format, cannot load as SeqBAIJ");
1800d64ed03dSBarry Smith   }
1801d64ed03dSBarry Smith 
1802*29bbc08cSBarry Smith   if (M != N) SETERRQ(PETSC_ERR_SUP,"Can only do square matrices");
180335aab85fSBarry Smith 
180435aab85fSBarry Smith   /*
180535aab85fSBarry Smith      This code adds extra rows to make sure the number of rows is
180635aab85fSBarry Smith     divisible by the blocksize
180735aab85fSBarry Smith   */
1808b6490206SBarry Smith   mbs        = M/bs;
180935aab85fSBarry Smith   extra_rows = bs - M + bs*(mbs);
181035aab85fSBarry Smith   if (extra_rows == bs) extra_rows = 0;
181135aab85fSBarry Smith   else                  mbs++;
181235aab85fSBarry Smith   if (extra_rows) {
1813537820f0SBarry Smith     PLogInfo(0,"MatLoad_SeqBAIJ:Padding loaded matrix to match blocksize\n");
181435aab85fSBarry Smith   }
1815b6490206SBarry Smith 
18162593348eSBarry Smith   /* read in row lengths */
181735aab85fSBarry Smith   rowlengths = (int*)PetscMalloc((M+extra_rows)*sizeof(int));CHKPTRQ(rowlengths);
18180752156aSBarry Smith   ierr = PetscBinaryRead(fd,rowlengths,M,PETSC_INT);CHKERRQ(ierr);
181935aab85fSBarry Smith   for (i=0; i<extra_rows; i++) rowlengths[M+i] = 1;
18202593348eSBarry Smith 
1821b6490206SBarry Smith   /* read in column indices */
182235aab85fSBarry Smith   jj = (int*)PetscMalloc((nz+extra_rows)*sizeof(int));CHKPTRQ(jj);
18230752156aSBarry Smith   ierr = PetscBinaryRead(fd,jj,nz,PETSC_INT);CHKERRQ(ierr);
182435aab85fSBarry Smith   for (i=0; i<extra_rows; i++) jj[nz+i] = M+i;
1825b6490206SBarry Smith 
1826b6490206SBarry Smith   /* loop over row lengths determining block row lengths */
1827b6490206SBarry Smith   browlengths = (int*)PetscMalloc(mbs*sizeof(int));CHKPTRQ(browlengths);
1828549d3d68SSatish Balay   ierr        = PetscMemzero(browlengths,mbs*sizeof(int));CHKERRQ(ierr);
182935aab85fSBarry Smith   mask        = (int*)PetscMalloc(2*mbs*sizeof(int));CHKPTRQ(mask);
1830549d3d68SSatish Balay   ierr        = PetscMemzero(mask,mbs*sizeof(int));CHKERRQ(ierr);
183135aab85fSBarry Smith   masked      = mask + mbs;
1832b6490206SBarry Smith   rowcount    = 0; nzcount = 0;
1833b6490206SBarry Smith   for (i=0; i<mbs; i++) {
183435aab85fSBarry Smith     nmask = 0;
1835b6490206SBarry Smith     for (j=0; j<bs; j++) {
1836b6490206SBarry Smith       kmax = rowlengths[rowcount];
1837b6490206SBarry Smith       for (k=0; k<kmax; k++) {
183835aab85fSBarry Smith         tmp = jj[nzcount++]/bs;
183935aab85fSBarry Smith         if (!mask[tmp]) {masked[nmask++] = tmp; mask[tmp] = 1;}
1840b6490206SBarry Smith       }
1841b6490206SBarry Smith       rowcount++;
1842b6490206SBarry Smith     }
184335aab85fSBarry Smith     browlengths[i] += nmask;
184435aab85fSBarry Smith     /* zero out the mask elements we set */
184535aab85fSBarry Smith     for (j=0; j<nmask; j++) mask[masked[j]] = 0;
1846b6490206SBarry Smith   }
1847b6490206SBarry Smith 
18482593348eSBarry Smith   /* create our matrix */
18493eee16b0SBarry Smith   ierr = MatCreateSeqBAIJ(comm,bs,M+extra_rows,N+extra_rows,0,browlengths,A);CHKERRQ(ierr);
18502593348eSBarry Smith   B = *A;
1851b6490206SBarry Smith   a = (Mat_SeqBAIJ*)B->data;
18522593348eSBarry Smith 
18532593348eSBarry Smith   /* set matrix "i" values */
1854de6a44a3SBarry Smith   a->i[0] = 0;
1855b6490206SBarry Smith   for (i=1; i<= mbs; i++) {
1856b6490206SBarry Smith     a->i[i]      = a->i[i-1] + browlengths[i-1];
1857b6490206SBarry Smith     a->ilen[i-1] = browlengths[i-1];
18582593348eSBarry Smith   }
1859b6490206SBarry Smith   a->nz         = 0;
1860b6490206SBarry Smith   for (i=0; i<mbs; i++) a->nz += browlengths[i];
18612593348eSBarry Smith 
1862b6490206SBarry Smith   /* read in nonzero values */
186335aab85fSBarry Smith   aa = (Scalar*)PetscMalloc((nz+extra_rows)*sizeof(Scalar));CHKPTRQ(aa);
18640752156aSBarry Smith   ierr = PetscBinaryRead(fd,aa,nz,PETSC_SCALAR);CHKERRQ(ierr);
186535aab85fSBarry Smith   for (i=0; i<extra_rows; i++) aa[nz+i] = 1.0;
1866b6490206SBarry Smith 
1867b6490206SBarry Smith   /* set "a" and "j" values into matrix */
1868b6490206SBarry Smith   nzcount = 0; jcount = 0;
1869b6490206SBarry Smith   for (i=0; i<mbs; i++) {
1870b6490206SBarry Smith     nzcountb = nzcount;
187135aab85fSBarry Smith     nmask    = 0;
1872b6490206SBarry Smith     for (j=0; j<bs; j++) {
1873b6490206SBarry Smith       kmax = rowlengths[i*bs+j];
1874b6490206SBarry Smith       for (k=0; k<kmax; k++) {
187535aab85fSBarry Smith         tmp = jj[nzcount++]/bs;
187635aab85fSBarry Smith 	if (!mask[tmp]) { masked[nmask++] = tmp; mask[tmp] = 1;}
1877b6490206SBarry Smith       }
1878b6490206SBarry Smith       rowcount++;
1879b6490206SBarry Smith     }
1880de6a44a3SBarry Smith     /* sort the masked values */
1881433994e6SBarry Smith     ierr = PetscSortInt(nmask,masked);CHKERRQ(ierr);
1882de6a44a3SBarry Smith 
1883b6490206SBarry Smith     /* set "j" values into matrix */
1884b6490206SBarry Smith     maskcount = 1;
188535aab85fSBarry Smith     for (j=0; j<nmask; j++) {
188635aab85fSBarry Smith       a->j[jcount++]  = masked[j];
1887de6a44a3SBarry Smith       mask[masked[j]] = maskcount++;
1888b6490206SBarry Smith     }
1889b6490206SBarry Smith     /* set "a" values into matrix */
1890de6a44a3SBarry Smith     ishift = bs2*a->i[i];
1891b6490206SBarry Smith     for (j=0; j<bs; j++) {
1892b6490206SBarry Smith       kmax = rowlengths[i*bs+j];
1893b6490206SBarry Smith       for (k=0; k<kmax; k++) {
1894de6a44a3SBarry Smith         tmp       = jj[nzcountb]/bs ;
1895de6a44a3SBarry Smith         block     = mask[tmp] - 1;
1896de6a44a3SBarry Smith         point     = jj[nzcountb] - bs*tmp;
1897de6a44a3SBarry Smith         idx       = ishift + bs2*block + j + bs*point;
1898375fe846SBarry Smith         a->a[idx] = (MatScalar)aa[nzcountb++];
1899b6490206SBarry Smith       }
1900b6490206SBarry Smith     }
190135aab85fSBarry Smith     /* zero out the mask elements we set */
190235aab85fSBarry Smith     for (j=0; j<nmask; j++) mask[masked[j]] = 0;
1903b6490206SBarry Smith   }
1904*29bbc08cSBarry Smith   if (jcount != a->nz) SETERRQ(PETSC_ERR_FILE_UNEXPECTED,"Bad binary matrix");
1905b6490206SBarry Smith 
1906606d414cSSatish Balay   ierr = PetscFree(rowlengths);CHKERRQ(ierr);
1907606d414cSSatish Balay   ierr = PetscFree(browlengths);CHKERRQ(ierr);
1908606d414cSSatish Balay   ierr = PetscFree(aa);CHKERRQ(ierr);
1909606d414cSSatish Balay   ierr = PetscFree(jj);CHKERRQ(ierr);
1910606d414cSSatish Balay   ierr = PetscFree(mask);CHKERRQ(ierr);
1911b6490206SBarry Smith 
1912b6490206SBarry Smith   B->assembled = PETSC_TRUE;
1913de6a44a3SBarry Smith 
19149c01be13SBarry Smith   ierr = MatView_Private(B);CHKERRQ(ierr);
19153a40ed3dSBarry Smith   PetscFunctionReturn(0);
19162593348eSBarry Smith }
19172593348eSBarry Smith 
19182593348eSBarry Smith 
19192593348eSBarry Smith 
1920