xref: /petsc/src/mat/impls/baij/seq/baij.c (revision 435da068ed131cbb9cf235815d431601925f48e7)
1*435da068SBarry Smith /*$Id: baij.c,v 1.221 2001/03/09 21:49:34 balay 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__
31b0a32e0cSBarry Smith #define __FUNC__ "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) {
4229bbc08cSBarry 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__
49b0a32e0cSBarry Smith #define __FUNC__ "MatMarkDiagonal_SeqBAIJ"
50c4992f7dSBarry Smith int MatMarkDiagonal_SeqBAIJ(Mat A)
51de6a44a3SBarry Smith {
52de6a44a3SBarry Smith   Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)A->data;
5382502324SSatish Balay   int         i,j,*diag,m = a->mbs,ierr;
54de6a44a3SBarry Smith 
553a40ed3dSBarry Smith   PetscFunctionBegin;
56883fce79SBarry Smith   if (a->diag) PetscFunctionReturn(0);
57883fce79SBarry Smith 
58b0a32e0cSBarry Smith   ierr = PetscMalloc((m+1)*sizeof(int),&diag);CHKERRQ(ierr);
59b0a32e0cSBarry Smith   PetscLogObjectMemory(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__
77b0a32e0cSBarry Smith #define __FUNC__ "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 */
90*435da068SBarry Smith     int nz = a->i[n];
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__
102b0a32e0cSBarry Smith #define __FUNC__ "MatRestoreRowIJ_SeqBAIJ"
103*435da068SBarry Smith static int MatRestoreRowIJ_SeqBAIJ(Mat A,int oshift,PetscTruth symmetric,int *nn,int **ia,int **ja,PetscTruth *done)
1043b2fbd54SBarry Smith {
1053b2fbd54SBarry Smith   Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)A->data;
106606d414cSSatish Balay   int         i,n = a->mbs,ierr;
1073b2fbd54SBarry Smith 
1083a40ed3dSBarry Smith   PetscFunctionBegin;
1093a40ed3dSBarry Smith   if (!ia) PetscFunctionReturn(0);
1103b2fbd54SBarry Smith   if (symmetric) {
111606d414cSSatish Balay     ierr = PetscFree(*ia);CHKERRQ(ierr);
112606d414cSSatish Balay     ierr = PetscFree(*ja);CHKERRQ(ierr);
113af5da2bfSBarry Smith   } else if (oshift == 1) {
114*435da068SBarry Smith     int nz = a->i[n]-1;
1153b2fbd54SBarry Smith     for (i=0; i<nz; i++) a->j[i]--;
1163b2fbd54SBarry Smith     for (i=0; i<n+1; i++) a->i[i]--;
1173b2fbd54SBarry Smith   }
1183a40ed3dSBarry Smith   PetscFunctionReturn(0);
1193b2fbd54SBarry Smith }
1203b2fbd54SBarry Smith 
1212d61bbb3SSatish Balay #undef __FUNC__
122b0a32e0cSBarry Smith #define __FUNC__ "MatGetBlockSize_SeqBAIJ"
1232d61bbb3SSatish Balay int MatGetBlockSize_SeqBAIJ(Mat mat,int *bs)
1242d61bbb3SSatish Balay {
1252d61bbb3SSatish Balay   Mat_SeqBAIJ *baij = (Mat_SeqBAIJ*)mat->data;
1262d61bbb3SSatish Balay 
1272d61bbb3SSatish Balay   PetscFunctionBegin;
1282d61bbb3SSatish Balay   *bs = baij->bs;
1292d61bbb3SSatish Balay   PetscFunctionReturn(0);
1302d61bbb3SSatish Balay }
1312d61bbb3SSatish Balay 
1322d61bbb3SSatish Balay 
1332d61bbb3SSatish Balay #undef __FUNC__
134b0a32e0cSBarry Smith #define __FUNC__ "MatDestroy_SeqBAIJ"
135e1311b90SBarry Smith int MatDestroy_SeqBAIJ(Mat A)
1362d61bbb3SSatish Balay {
1372d61bbb3SSatish Balay   Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)A->data;
138e51c0b9cSSatish Balay   int         ierr;
1392d61bbb3SSatish Balay 
140433994e6SBarry Smith   PetscFunctionBegin;
141aa482453SBarry Smith #if defined(PETSC_USE_LOG)
142b0a32e0cSBarry Smith   PetscLogObjectState((PetscObject)A,"Rows=%d, Cols=%d, NZ=%d",A->m,A->n,a->nz);
1432d61bbb3SSatish Balay #endif
144606d414cSSatish Balay   ierr = PetscFree(a->a);CHKERRQ(ierr);
145606d414cSSatish Balay   if (!a->singlemalloc) {
146606d414cSSatish Balay     ierr = PetscFree(a->i);CHKERRQ(ierr);
147606d414cSSatish Balay     ierr = PetscFree(a->j);CHKERRQ(ierr);
148606d414cSSatish Balay   }
149c38d4ed2SBarry Smith   if (a->row) {
150c38d4ed2SBarry Smith     ierr = ISDestroy(a->row);CHKERRQ(ierr);
151c38d4ed2SBarry Smith   }
152c38d4ed2SBarry Smith   if (a->col) {
153c38d4ed2SBarry Smith     ierr = ISDestroy(a->col);CHKERRQ(ierr);
154c38d4ed2SBarry Smith   }
155606d414cSSatish Balay   if (a->diag) {ierr = PetscFree(a->diag);CHKERRQ(ierr);}
156606d414cSSatish Balay   if (a->ilen) {ierr = PetscFree(a->ilen);CHKERRQ(ierr);}
157606d414cSSatish Balay   if (a->imax) {ierr = PetscFree(a->imax);CHKERRQ(ierr);}
158606d414cSSatish Balay   if (a->solve_work) {ierr = PetscFree(a->solve_work);CHKERRQ(ierr);}
159606d414cSSatish Balay   if (a->mult_work) {ierr = PetscFree(a->mult_work);CHKERRQ(ierr);}
160e51c0b9cSSatish Balay   if (a->icol) {ierr = ISDestroy(a->icol);CHKERRQ(ierr);}
161606d414cSSatish Balay   if (a->saved_values) {ierr = PetscFree(a->saved_values);CHKERRQ(ierr);}
162563b5814SBarry Smith #if defined(PETSC_USE_MAT_SINGLE)
163563b5814SBarry Smith   if (a->setvaluescopy) {ierr = PetscFree(a->setvaluescopy);CHKERRQ(ierr);}
164563b5814SBarry Smith #endif
165606d414cSSatish Balay   ierr = PetscFree(a);CHKERRQ(ierr);
1662d61bbb3SSatish Balay   PetscFunctionReturn(0);
1672d61bbb3SSatish Balay }
1682d61bbb3SSatish Balay 
1692d61bbb3SSatish Balay #undef __FUNC__
170b0a32e0cSBarry Smith #define __FUNC__ "MatSetOption_SeqBAIJ"
1712d61bbb3SSatish Balay int MatSetOption_SeqBAIJ(Mat A,MatOption op)
1722d61bbb3SSatish Balay {
1732d61bbb3SSatish Balay   Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)A->data;
1742d61bbb3SSatish Balay 
1752d61bbb3SSatish Balay   PetscFunctionBegin;
176c4992f7dSBarry Smith   if      (op == MAT_ROW_ORIENTED)                 a->roworiented    = PETSC_TRUE;
177c4992f7dSBarry Smith   else if (op == MAT_COLUMN_ORIENTED)              a->roworiented    = PETSC_FALSE;
178c4992f7dSBarry Smith   else if (op == MAT_COLUMNS_SORTED)               a->sorted         = PETSC_TRUE;
179c4992f7dSBarry Smith   else if (op == MAT_COLUMNS_UNSORTED)             a->sorted         = PETSC_FALSE;
180c4992f7dSBarry Smith   else if (op == MAT_KEEP_ZEROED_ROWS)             a->keepzeroedrows = PETSC_TRUE;
1812d61bbb3SSatish Balay   else if (op == MAT_NO_NEW_NONZERO_LOCATIONS)     a->nonew          = 1;
1824787f768SSatish Balay   else if (op == MAT_NEW_NONZERO_LOCATION_ERR)     a->nonew          = -1;
1834787f768SSatish Balay   else if (op == MAT_NEW_NONZERO_ALLOCATION_ERR)   a->nonew          = -2;
1842d61bbb3SSatish Balay   else if (op == MAT_YES_NEW_NONZERO_LOCATIONS)    a->nonew          = 0;
1852d61bbb3SSatish Balay   else if (op == MAT_ROWS_SORTED ||
1862d61bbb3SSatish Balay            op == MAT_ROWS_UNSORTED ||
1872d61bbb3SSatish Balay            op == MAT_SYMMETRIC ||
1882d61bbb3SSatish Balay            op == MAT_STRUCTURALLY_SYMMETRIC ||
1892d61bbb3SSatish Balay            op == MAT_YES_NEW_DIAGONALS ||
190b51ba29fSSatish Balay            op == MAT_IGNORE_OFF_PROC_ENTRIES ||
191b51ba29fSSatish Balay            op == MAT_USE_HASH_TABLE) {
192b0a32e0cSBarry Smith     PetscLogInfo(A,"MatSetOption_SeqBAIJ:Option ignored\n");
1932d61bbb3SSatish Balay   } else if (op == MAT_NO_NEW_DIAGONALS) {
19429bbc08cSBarry Smith     SETERRQ(PETSC_ERR_SUP,"MAT_NO_NEW_DIAGONALS");
1952d61bbb3SSatish Balay   } else {
19629bbc08cSBarry Smith     SETERRQ(PETSC_ERR_SUP,"unknown option");
1972d61bbb3SSatish Balay   }
1982d61bbb3SSatish Balay   PetscFunctionReturn(0);
1992d61bbb3SSatish Balay }
2002d61bbb3SSatish Balay 
2012d61bbb3SSatish Balay #undef __FUNC__
202b0a32e0cSBarry Smith #define __FUNC__ "MatGetOwnershipRange_SeqBAIJ"
2032d61bbb3SSatish Balay int MatGetOwnershipRange_SeqBAIJ(Mat A,int *m,int *n)
2042d61bbb3SSatish Balay {
2052d61bbb3SSatish Balay   PetscFunctionBegin;
2064c49b128SBarry Smith   if (m) *m = 0;
207273d9f13SBarry Smith   if (n) *n = A->m;
2082d61bbb3SSatish Balay   PetscFunctionReturn(0);
2092d61bbb3SSatish Balay }
2102d61bbb3SSatish Balay 
2112d61bbb3SSatish Balay #undef __FUNC__
212b0a32e0cSBarry Smith #define __FUNC__ "MatGetRow_SeqBAIJ"
2132d61bbb3SSatish Balay int MatGetRow_SeqBAIJ(Mat A,int row,int *nz,int **idx,Scalar **v)
2142d61bbb3SSatish Balay {
2152d61bbb3SSatish Balay   Mat_SeqBAIJ  *a = (Mat_SeqBAIJ*)A->data;
21682502324SSatish Balay   int          itmp,i,j,k,M,*ai,*aj,bs,bn,bp,*idx_i,bs2,ierr;
2173f1db9ecSBarry Smith   MatScalar    *aa,*aa_i;
2183f1db9ecSBarry Smith   Scalar       *v_i;
2192d61bbb3SSatish Balay 
2202d61bbb3SSatish Balay   PetscFunctionBegin;
2212d61bbb3SSatish Balay   bs  = a->bs;
2222d61bbb3SSatish Balay   ai  = a->i;
2232d61bbb3SSatish Balay   aj  = a->j;
2242d61bbb3SSatish Balay   aa  = a->a;
2252d61bbb3SSatish Balay   bs2 = a->bs2;
2262d61bbb3SSatish Balay 
227273d9f13SBarry Smith   if (row < 0 || row >= A->m) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Row out of range");
2282d61bbb3SSatish Balay 
2292d61bbb3SSatish Balay   bn  = row/bs;   /* Block number */
2302d61bbb3SSatish Balay   bp  = row % bs; /* Block Position */
2312d61bbb3SSatish Balay   M   = ai[bn+1] - ai[bn];
2322d61bbb3SSatish Balay   *nz = bs*M;
2332d61bbb3SSatish Balay 
2342d61bbb3SSatish Balay   if (v) {
2352d61bbb3SSatish Balay     *v = 0;
2362d61bbb3SSatish Balay     if (*nz) {
237b0a32e0cSBarry Smith       ierr = PetscMalloc((*nz)*sizeof(Scalar),v);CHKERRQ(ierr);
2382d61bbb3SSatish Balay       for (i=0; i<M; i++) { /* for each block in the block row */
2392d61bbb3SSatish Balay         v_i  = *v + i*bs;
2402d61bbb3SSatish Balay         aa_i = aa + bs2*(ai[bn] + i);
2412d61bbb3SSatish Balay         for (j=bp,k=0; j<bs2; j+=bs,k++) {v_i[k] = aa_i[j];}
2422d61bbb3SSatish Balay       }
2432d61bbb3SSatish Balay     }
2442d61bbb3SSatish Balay   }
2452d61bbb3SSatish Balay 
2462d61bbb3SSatish Balay   if (idx) {
2472d61bbb3SSatish Balay     *idx = 0;
2482d61bbb3SSatish Balay     if (*nz) {
249b0a32e0cSBarry Smith       ierr = PetscMalloc((*nz)*sizeof(int),idx);CHKERRQ(ierr);
2502d61bbb3SSatish Balay       for (i=0; i<M; i++) { /* for each block in the block row */
2512d61bbb3SSatish Balay         idx_i = *idx + i*bs;
2522d61bbb3SSatish Balay         itmp  = bs*aj[ai[bn] + i];
2532d61bbb3SSatish Balay         for (j=0; j<bs; j++) {idx_i[j] = itmp++;}
2542d61bbb3SSatish Balay       }
2552d61bbb3SSatish Balay     }
2562d61bbb3SSatish Balay   }
2572d61bbb3SSatish Balay   PetscFunctionReturn(0);
2582d61bbb3SSatish Balay }
2592d61bbb3SSatish Balay 
2602d61bbb3SSatish Balay #undef __FUNC__
261b0a32e0cSBarry Smith #define __FUNC__ "MatRestoreRow_SeqBAIJ"
2622d61bbb3SSatish Balay int MatRestoreRow_SeqBAIJ(Mat A,int row,int *nz,int **idx,Scalar **v)
2632d61bbb3SSatish Balay {
264606d414cSSatish Balay   int ierr;
265606d414cSSatish Balay 
2662d61bbb3SSatish Balay   PetscFunctionBegin;
267606d414cSSatish Balay   if (idx) {if (*idx) {ierr = PetscFree(*idx);CHKERRQ(ierr);}}
268606d414cSSatish Balay   if (v)   {if (*v)   {ierr = PetscFree(*v);CHKERRQ(ierr);}}
2692d61bbb3SSatish Balay   PetscFunctionReturn(0);
2702d61bbb3SSatish Balay }
2712d61bbb3SSatish Balay 
2722d61bbb3SSatish Balay #undef __FUNC__
273b0a32e0cSBarry Smith #define __FUNC__ "MatTranspose_SeqBAIJ"
2742d61bbb3SSatish Balay int MatTranspose_SeqBAIJ(Mat A,Mat *B)
2752d61bbb3SSatish Balay {
2762d61bbb3SSatish Balay   Mat_SeqBAIJ *a=(Mat_SeqBAIJ *)A->data;
2772d61bbb3SSatish Balay   Mat         C;
2782d61bbb3SSatish Balay   int         i,j,k,ierr,*aj=a->j,*ai=a->i,bs=a->bs,mbs=a->mbs,nbs=a->nbs,len,*col;
279273d9f13SBarry Smith   int         *rows,*cols,bs2=a->bs2;
280375fe846SBarry Smith   Scalar      *array;
2812d61bbb3SSatish Balay 
2822d61bbb3SSatish Balay   PetscFunctionBegin;
28329bbc08cSBarry Smith   if (!B && mbs!=nbs) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Square matrix only for in-place");
284b0a32e0cSBarry Smith   ierr = PetscMalloc((1+nbs)*sizeof(int),&col);CHKERRQ(ierr);
285549d3d68SSatish Balay   ierr = PetscMemzero(col,(1+nbs)*sizeof(int));CHKERRQ(ierr);
2862d61bbb3SSatish Balay 
287375fe846SBarry Smith #if defined(PETSC_USE_MAT_SINGLE)
288b0a32e0cSBarry Smith   ierr = PetscMalloc(a->bs2*a->nz*sizeof(Scalar),&array);CHKERRQ(ierr);
289375fe846SBarry Smith   for (i=0; i<a->bs2*a->nz; i++) array[i] = (Scalar)a->a[i];
290375fe846SBarry Smith #else
2913eda8832SBarry Smith   array = a->a;
292375fe846SBarry Smith #endif
293375fe846SBarry Smith 
2942d61bbb3SSatish Balay   for (i=0; i<ai[mbs]; i++) col[aj[i]] += 1;
295273d9f13SBarry Smith   ierr = MatCreateSeqBAIJ(A->comm,bs,A->n,A->m,PETSC_NULL,col,&C);CHKERRQ(ierr);
296606d414cSSatish Balay   ierr = PetscFree(col);CHKERRQ(ierr);
297b0a32e0cSBarry Smith   ierr = PetscMalloc(2*bs*sizeof(int),&rows);CHKERRQ(ierr);
2982d61bbb3SSatish Balay   cols = rows + bs;
2992d61bbb3SSatish Balay   for (i=0; i<mbs; i++) {
3002d61bbb3SSatish Balay     cols[0] = i*bs;
3012d61bbb3SSatish Balay     for (k=1; k<bs; k++) cols[k] = cols[k-1] + 1;
3022d61bbb3SSatish Balay     len = ai[i+1] - ai[i];
3032d61bbb3SSatish Balay     for (j=0; j<len; j++) {
3042d61bbb3SSatish Balay       rows[0] = (*aj++)*bs;
3052d61bbb3SSatish Balay       for (k=1; k<bs; k++) rows[k] = rows[k-1] + 1;
3062d61bbb3SSatish Balay       ierr = MatSetValues(C,bs,rows,bs,cols,array,INSERT_VALUES);CHKERRQ(ierr);
3072d61bbb3SSatish Balay       array += bs2;
3082d61bbb3SSatish Balay     }
3092d61bbb3SSatish Balay   }
310606d414cSSatish Balay   ierr = PetscFree(rows);CHKERRQ(ierr);
311375fe846SBarry Smith #if defined(PETSC_USE_MAT_SINGLE)
312375fe846SBarry Smith   ierr = PetscFree(array);
313375fe846SBarry Smith #endif
3142d61bbb3SSatish Balay 
3152d61bbb3SSatish Balay   ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
3162d61bbb3SSatish Balay   ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
3172d61bbb3SSatish Balay 
318c4992f7dSBarry Smith   if (B) {
3192d61bbb3SSatish Balay     *B = C;
3202d61bbb3SSatish Balay   } else {
321273d9f13SBarry Smith     ierr = MatHeaderCopy(A,C);CHKERRQ(ierr);
3222d61bbb3SSatish Balay   }
3232d61bbb3SSatish Balay   PetscFunctionReturn(0);
3242d61bbb3SSatish Balay }
3252d61bbb3SSatish Balay 
3265615d1e5SSatish Balay #undef __FUNC__
327b0a32e0cSBarry Smith #define __FUNC__ "MatView_SeqBAIJ_Binary"
328b0a32e0cSBarry Smith static int MatView_SeqBAIJ_Binary(Mat A,PetscViewer viewer)
3292593348eSBarry Smith {
330b6490206SBarry Smith   Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)A->data;
3319df24120SSatish Balay   int         i,fd,*col_lens,ierr,bs = a->bs,count,*jj,j,k,l,bs2=a->bs2;
332b6490206SBarry Smith   Scalar      *aa;
333ce6f0cecSBarry Smith   FILE        *file;
3342593348eSBarry Smith 
3353a40ed3dSBarry Smith   PetscFunctionBegin;
336b0a32e0cSBarry Smith   ierr        = PetscViewerBinaryGetDescriptor(viewer,&fd);CHKERRQ(ierr);
337b0a32e0cSBarry Smith   ierr        = PetscMalloc((4+A->m)*sizeof(int),&col_lens);CHKERRQ(ierr);
3382593348eSBarry Smith   col_lens[0] = MAT_COOKIE;
3393b2fbd54SBarry Smith 
340273d9f13SBarry Smith   col_lens[1] = A->m;
341273d9f13SBarry Smith   col_lens[2] = A->n;
3427e67e3f9SSatish Balay   col_lens[3] = a->nz*bs2;
3432593348eSBarry Smith 
3442593348eSBarry Smith   /* store lengths of each row and write (including header) to file */
345b6490206SBarry Smith   count = 0;
346b6490206SBarry Smith   for (i=0; i<a->mbs; i++) {
347b6490206SBarry Smith     for (j=0; j<bs; j++) {
348b6490206SBarry Smith       col_lens[4+count++] = bs*(a->i[i+1] - a->i[i]);
349b6490206SBarry Smith     }
3502593348eSBarry Smith   }
351273d9f13SBarry Smith   ierr = PetscBinaryWrite(fd,col_lens,4+A->m,PETSC_INT,1);CHKERRQ(ierr);
352606d414cSSatish Balay   ierr = PetscFree(col_lens);CHKERRQ(ierr);
3532593348eSBarry Smith 
3542593348eSBarry Smith   /* store column indices (zero start index) */
355b0a32e0cSBarry Smith   ierr  = PetscMalloc((a->nz+1)*bs2*sizeof(int),&jj);CHKERRQ(ierr);
356b6490206SBarry Smith   count = 0;
357b6490206SBarry Smith   for (i=0; i<a->mbs; i++) {
358b6490206SBarry Smith     for (j=0; j<bs; j++) {
359b6490206SBarry Smith       for (k=a->i[i]; k<a->i[i+1]; k++) {
360b6490206SBarry Smith         for (l=0; l<bs; l++) {
361b6490206SBarry Smith           jj[count++] = bs*a->j[k] + l;
3622593348eSBarry Smith         }
3632593348eSBarry Smith       }
364b6490206SBarry Smith     }
365b6490206SBarry Smith   }
3660752156aSBarry Smith   ierr = PetscBinaryWrite(fd,jj,bs2*a->nz,PETSC_INT,0);CHKERRQ(ierr);
367606d414cSSatish Balay   ierr = PetscFree(jj);CHKERRQ(ierr);
3682593348eSBarry Smith 
3692593348eSBarry Smith   /* store nonzero values */
370b0a32e0cSBarry Smith   ierr  = PetscMalloc((a->nz+1)*bs2*sizeof(Scalar),&aa);CHKERRQ(ierr);
371b6490206SBarry Smith   count = 0;
372b6490206SBarry Smith   for (i=0; i<a->mbs; i++) {
373b6490206SBarry Smith     for (j=0; j<bs; j++) {
374b6490206SBarry Smith       for (k=a->i[i]; k<a->i[i+1]; k++) {
375b6490206SBarry Smith         for (l=0; l<bs; l++) {
3767e67e3f9SSatish Balay           aa[count++] = a->a[bs2*k + l*bs + j];
377b6490206SBarry Smith         }
378b6490206SBarry Smith       }
379b6490206SBarry Smith     }
380b6490206SBarry Smith   }
3810752156aSBarry Smith   ierr = PetscBinaryWrite(fd,aa,bs2*a->nz,PETSC_SCALAR,0);CHKERRQ(ierr);
382606d414cSSatish Balay   ierr = PetscFree(aa);CHKERRQ(ierr);
383ce6f0cecSBarry Smith 
384b0a32e0cSBarry Smith   ierr = PetscViewerBinaryGetInfoPointer(viewer,&file);CHKERRQ(ierr);
385ce6f0cecSBarry Smith   if (file) {
386ce6f0cecSBarry Smith     fprintf(file,"-matload_block_size %d\n",a->bs);
387ce6f0cecSBarry Smith   }
3883a40ed3dSBarry Smith   PetscFunctionReturn(0);
3892593348eSBarry Smith }
3902593348eSBarry Smith 
3915615d1e5SSatish Balay #undef __FUNC__
392b0a32e0cSBarry Smith #define __FUNC__ "MatView_SeqBAIJ_ASCII"
393b0a32e0cSBarry Smith static int MatView_SeqBAIJ_ASCII(Mat A,PetscViewer viewer)
3942593348eSBarry Smith {
395b6490206SBarry Smith   Mat_SeqBAIJ       *a = (Mat_SeqBAIJ*)A->data;
396fb9695e5SSatish Balay   int               ierr,i,j,bs = a->bs,k,l,bs2=a->bs2;
397f3ef73ceSBarry Smith   PetscViewerFormat format;
3982593348eSBarry Smith 
3993a40ed3dSBarry Smith   PetscFunctionBegin;
400b0a32e0cSBarry Smith   ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr);
401fb9695e5SSatish Balay   if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_LONG) {
402b0a32e0cSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  block size is %d\n",bs);CHKERRQ(ierr);
403fb9695e5SSatish Balay   } else if (format == PETSC_VIEWER_ASCII_MATLAB) {
40429bbc08cSBarry Smith     SETERRQ(PETSC_ERR_SUP,"Matlab format not supported");
405fb9695e5SSatish Balay   } else if (format == PETSC_VIEWER_ASCII_COMMON) {
406b0a32e0cSBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_NO);CHKERRQ(ierr);
40744cd7ae7SLois Curfman McInnes     for (i=0; i<a->mbs; i++) {
40844cd7ae7SLois Curfman McInnes       for (j=0; j<bs; j++) {
409b0a32e0cSBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"row %d:",i*bs+j);CHKERRQ(ierr);
41044cd7ae7SLois Curfman McInnes         for (k=a->i[i]; k<a->i[i+1]; k++) {
41144cd7ae7SLois Curfman McInnes           for (l=0; l<bs; l++) {
412aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
4130e6d2581SBarry Smith             if (PetscImaginaryPart(a->a[bs2*k + l*bs + j]) > 0.0 && PetscRealPart(a->a[bs2*k + l*bs + j]) != 0.0) {
414b0a32e0cSBarry Smith               ierr = PetscViewerASCIIPrintf(viewer," %d %g + %gi",bs*a->j[k]+l,
4150e6d2581SBarry Smith                       PetscRealPart(a->a[bs2*k + l*bs + j]),PetscImaginaryPart(a->a[bs2*k + l*bs + j]));CHKERRQ(ierr);
4160e6d2581SBarry Smith             } else if (PetscImaginaryPart(a->a[bs2*k + l*bs + j]) < 0.0 && PetscRealPart(a->a[bs2*k + l*bs + j]) != 0.0) {
417b0a32e0cSBarry Smith               ierr = PetscViewerASCIIPrintf(viewer," %d %g - %gi",bs*a->j[k]+l,
4180e6d2581SBarry Smith                       PetscRealPart(a->a[bs2*k + l*bs + j]),-PetscImaginaryPart(a->a[bs2*k + l*bs + j]));CHKERRQ(ierr);
4190e6d2581SBarry Smith             } else if (PetscRealPart(a->a[bs2*k + l*bs + j]) != 0.0) {
420b0a32e0cSBarry Smith               ierr = PetscViewerASCIIPrintf(viewer," %d %g ",bs*a->j[k]+l,PetscRealPart(a->a[bs2*k + l*bs + j]));CHKERRQ(ierr);
4210ef38995SBarry Smith             }
42244cd7ae7SLois Curfman McInnes #else
4230ef38995SBarry Smith             if (a->a[bs2*k + l*bs + j] != 0.0) {
424b0a32e0cSBarry Smith               ierr = PetscViewerASCIIPrintf(viewer," %d %g ",bs*a->j[k]+l,a->a[bs2*k + l*bs + j]);CHKERRQ(ierr);
4250ef38995SBarry Smith             }
42644cd7ae7SLois Curfman McInnes #endif
42744cd7ae7SLois Curfman McInnes           }
42844cd7ae7SLois Curfman McInnes         }
429b0a32e0cSBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
43044cd7ae7SLois Curfman McInnes       }
43144cd7ae7SLois Curfman McInnes     }
432b0a32e0cSBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_YES);CHKERRQ(ierr);
4330ef38995SBarry Smith   } else {
434b0a32e0cSBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_NO);CHKERRQ(ierr);
435b6490206SBarry Smith     for (i=0; i<a->mbs; i++) {
436b6490206SBarry Smith       for (j=0; j<bs; j++) {
437b0a32e0cSBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"row %d:",i*bs+j);CHKERRQ(ierr);
438b6490206SBarry Smith         for (k=a->i[i]; k<a->i[i+1]; k++) {
439b6490206SBarry Smith           for (l=0; l<bs; l++) {
440aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
4410e6d2581SBarry Smith             if (PetscImaginaryPart(a->a[bs2*k + l*bs + j]) > 0.0) {
442b0a32e0cSBarry Smith               ierr = PetscViewerASCIIPrintf(viewer," %d %g + %g i",bs*a->j[k]+l,
4430e6d2581SBarry Smith                 PetscRealPart(a->a[bs2*k + l*bs + j]),PetscImaginaryPart(a->a[bs2*k + l*bs + j]));CHKERRQ(ierr);
4440e6d2581SBarry Smith             } else if (PetscImaginaryPart(a->a[bs2*k + l*bs + j]) < 0.0) {
445b0a32e0cSBarry Smith               ierr = PetscViewerASCIIPrintf(viewer," %d %g - %g i",bs*a->j[k]+l,
4460e6d2581SBarry Smith                 PetscRealPart(a->a[bs2*k + l*bs + j]),-PetscImaginaryPart(a->a[bs2*k + l*bs + j]));CHKERRQ(ierr);
4470ef38995SBarry Smith             } else {
448b0a32e0cSBarry Smith               ierr = PetscViewerASCIIPrintf(viewer," %d %g ",bs*a->j[k]+l,PetscRealPart(a->a[bs2*k + l*bs + j]));CHKERRQ(ierr);
44988685aaeSLois Curfman McInnes             }
45088685aaeSLois Curfman McInnes #else
451b0a32e0cSBarry Smith             ierr = PetscViewerASCIIPrintf(viewer," %d %g ",bs*a->j[k]+l,a->a[bs2*k + l*bs + j]);CHKERRQ(ierr);
45288685aaeSLois Curfman McInnes #endif
4532593348eSBarry Smith           }
4542593348eSBarry Smith         }
455b0a32e0cSBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
4562593348eSBarry Smith       }
4572593348eSBarry Smith     }
458b0a32e0cSBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_YES);CHKERRQ(ierr);
459b6490206SBarry Smith   }
460b0a32e0cSBarry Smith   ierr = PetscViewerFlush(viewer);CHKERRQ(ierr);
4613a40ed3dSBarry Smith   PetscFunctionReturn(0);
4622593348eSBarry Smith }
4632593348eSBarry Smith 
4645615d1e5SSatish Balay #undef __FUNC__
465b0a32e0cSBarry Smith #define __FUNC__ "MatView_SeqBAIJ_Draw_Zoom"
466b0a32e0cSBarry Smith static int MatView_SeqBAIJ_Draw_Zoom(PetscDraw draw,void *Aa)
4673270192aSSatish Balay {
46877ed5343SBarry Smith   Mat          A = (Mat) Aa;
4693270192aSSatish Balay   Mat_SeqBAIJ  *a=(Mat_SeqBAIJ*)A->data;
470b65db4caSBarry Smith   int          row,ierr,i,j,k,l,mbs=a->mbs,color,bs=a->bs,bs2=a->bs2;
4710e6d2581SBarry Smith   PetscReal    xl,yl,xr,yr,x_l,x_r,y_l,y_r;
4723f1db9ecSBarry Smith   MatScalar    *aa;
473b0a32e0cSBarry Smith   PetscViewer       viewer;
4743270192aSSatish Balay 
4753a40ed3dSBarry Smith   PetscFunctionBegin;
4763270192aSSatish Balay 
477b65db4caSBarry Smith   /* still need to add support for contour plot of nonzeros; see MatView_SeqAIJ_Draw_Zoom()*/
47877ed5343SBarry Smith   ierr = PetscObjectQuery((PetscObject)A,"Zoomviewer",(PetscObject*)&viewer);CHKERRQ(ierr);
47977ed5343SBarry Smith 
480b0a32e0cSBarry Smith   ierr = PetscDrawGetCoordinates(draw,&xl,&yl,&xr,&yr);CHKERRQ(ierr);
48177ed5343SBarry Smith 
4823270192aSSatish Balay   /* loop over matrix elements drawing boxes */
483b0a32e0cSBarry Smith   color = PETSC_DRAW_BLUE;
4843270192aSSatish Balay   for (i=0,row=0; i<mbs; i++,row+=bs) {
4853270192aSSatish Balay     for (j=a->i[i]; j<a->i[i+1]; j++) {
486273d9f13SBarry Smith       y_l = A->m - row - 1.0; y_r = y_l + 1.0;
4873270192aSSatish Balay       x_l = a->j[j]*bs; x_r = x_l + 1.0;
4883270192aSSatish Balay       aa = a->a + j*bs2;
4893270192aSSatish Balay       for (k=0; k<bs; k++) {
4903270192aSSatish Balay         for (l=0; l<bs; l++) {
4910e6d2581SBarry Smith           if (PetscRealPart(*aa++) >=  0.) continue;
492b0a32e0cSBarry Smith           ierr = PetscDrawRectangle(draw,x_l+k,y_l-l,x_r+k,y_r-l,color,color,color,color);CHKERRQ(ierr);
4933270192aSSatish Balay         }
4943270192aSSatish Balay       }
4953270192aSSatish Balay     }
4963270192aSSatish Balay   }
497b0a32e0cSBarry Smith   color = PETSC_DRAW_CYAN;
4983270192aSSatish Balay   for (i=0,row=0; i<mbs; i++,row+=bs) {
4993270192aSSatish Balay     for (j=a->i[i]; j<a->i[i+1]; j++) {
500273d9f13SBarry Smith       y_l = A->m - row - 1.0; y_r = y_l + 1.0;
5013270192aSSatish Balay       x_l = a->j[j]*bs; x_r = x_l + 1.0;
5023270192aSSatish Balay       aa = a->a + j*bs2;
5033270192aSSatish Balay       for (k=0; k<bs; k++) {
5043270192aSSatish Balay         for (l=0; l<bs; l++) {
5050e6d2581SBarry Smith           if (PetscRealPart(*aa++) != 0.) continue;
506b0a32e0cSBarry Smith           ierr = PetscDrawRectangle(draw,x_l+k,y_l-l,x_r+k,y_r-l,color,color,color,color);CHKERRQ(ierr);
5073270192aSSatish Balay         }
5083270192aSSatish Balay       }
5093270192aSSatish Balay     }
5103270192aSSatish Balay   }
5113270192aSSatish Balay 
512b0a32e0cSBarry Smith   color = PETSC_DRAW_RED;
5133270192aSSatish Balay   for (i=0,row=0; i<mbs; i++,row+=bs) {
5143270192aSSatish Balay     for (j=a->i[i]; j<a->i[i+1]; j++) {
515273d9f13SBarry Smith       y_l = A->m - row - 1.0; y_r = y_l + 1.0;
5163270192aSSatish Balay       x_l = a->j[j]*bs; x_r = x_l + 1.0;
5173270192aSSatish Balay       aa = a->a + j*bs2;
5183270192aSSatish Balay       for (k=0; k<bs; k++) {
5193270192aSSatish Balay         for (l=0; l<bs; l++) {
5200e6d2581SBarry Smith           if (PetscRealPart(*aa++) <= 0.) continue;
521b0a32e0cSBarry Smith           ierr = PetscDrawRectangle(draw,x_l+k,y_l-l,x_r+k,y_r-l,color,color,color,color);CHKERRQ(ierr);
5223270192aSSatish Balay         }
5233270192aSSatish Balay       }
5243270192aSSatish Balay     }
5253270192aSSatish Balay   }
52677ed5343SBarry Smith   PetscFunctionReturn(0);
52777ed5343SBarry Smith }
5283270192aSSatish Balay 
52977ed5343SBarry Smith #undef __FUNC__
530b0a32e0cSBarry Smith #define __FUNC__ "MatView_SeqBAIJ_Draw"
531b0a32e0cSBarry Smith static int MatView_SeqBAIJ_Draw(Mat A,PetscViewer viewer)
53277ed5343SBarry Smith {
5337dce120fSSatish Balay   int          ierr;
5340e6d2581SBarry Smith   PetscReal    xl,yl,xr,yr,w,h;
535b0a32e0cSBarry Smith   PetscDraw         draw;
53677ed5343SBarry Smith   PetscTruth   isnull;
5373270192aSSatish Balay 
53877ed5343SBarry Smith   PetscFunctionBegin;
53977ed5343SBarry Smith 
540b0a32e0cSBarry Smith   ierr = PetscViewerDrawGetDraw(viewer,0,&draw);CHKERRQ(ierr);
541b0a32e0cSBarry Smith   ierr = PetscDrawIsNull(draw,&isnull);CHKERRQ(ierr); if (isnull) PetscFunctionReturn(0);
54277ed5343SBarry Smith 
54377ed5343SBarry Smith   ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",(PetscObject)viewer);CHKERRQ(ierr);
544273d9f13SBarry Smith   xr  = A->n; yr = A->m; h = yr/10.0; w = xr/10.0;
54577ed5343SBarry Smith   xr += w;    yr += h;  xl = -w;     yl = -h;
546b0a32e0cSBarry Smith   ierr = PetscDrawSetCoordinates(draw,xl,yl,xr,yr);CHKERRQ(ierr);
547b0a32e0cSBarry Smith   ierr = PetscDrawZoom(draw,MatView_SeqBAIJ_Draw_Zoom,A);CHKERRQ(ierr);
54877ed5343SBarry Smith   ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",PETSC_NULL);CHKERRQ(ierr);
5493a40ed3dSBarry Smith   PetscFunctionReturn(0);
5503270192aSSatish Balay }
5513270192aSSatish Balay 
5525615d1e5SSatish Balay #undef __FUNC__
553b0a32e0cSBarry Smith #define __FUNC__ "MatView_SeqBAIJ"
554b0a32e0cSBarry Smith int MatView_SeqBAIJ(Mat A,PetscViewer viewer)
5552593348eSBarry Smith {
55619bcc07fSBarry Smith   int        ierr;
5576831982aSBarry Smith   PetscTruth issocket,isascii,isbinary,isdraw;
5582593348eSBarry Smith 
5593a40ed3dSBarry Smith   PetscFunctionBegin;
560b0a32e0cSBarry Smith   ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_SOCKET,&issocket);CHKERRQ(ierr);
561b0a32e0cSBarry Smith   ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&isascii);CHKERRQ(ierr);
562fb9695e5SSatish Balay   ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_BINARY,&isbinary);CHKERRQ(ierr);
563fb9695e5SSatish Balay   ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_DRAW,&isdraw);CHKERRQ(ierr);
5640f5bd95cSBarry Smith   if (issocket) {
56529bbc08cSBarry Smith     SETERRQ(PETSC_ERR_SUP,"Socket viewer not supported");
5660f5bd95cSBarry Smith   } else if (isascii){
5673a40ed3dSBarry Smith     ierr = MatView_SeqBAIJ_ASCII(A,viewer);CHKERRQ(ierr);
5680f5bd95cSBarry Smith   } else if (isbinary) {
5693a40ed3dSBarry Smith     ierr = MatView_SeqBAIJ_Binary(A,viewer);CHKERRQ(ierr);
5700f5bd95cSBarry Smith   } else if (isdraw) {
5713a40ed3dSBarry Smith     ierr = MatView_SeqBAIJ_Draw(A,viewer);CHKERRQ(ierr);
5725cd90555SBarry Smith   } else {
57329bbc08cSBarry Smith     SETERRQ1(1,"Viewer type %s not supported by SeqBAIJ matrices",((PetscObject)viewer)->type_name);
5742593348eSBarry Smith   }
5753a40ed3dSBarry Smith   PetscFunctionReturn(0);
5762593348eSBarry Smith }
577b6490206SBarry Smith 
578cd0e1443SSatish Balay 
5795615d1e5SSatish Balay #undef __FUNC__
580b0a32e0cSBarry Smith #define __FUNC__ "MatGetValues_SeqBAIJ"
5812d61bbb3SSatish Balay int MatGetValues_SeqBAIJ(Mat A,int m,int *im,int n,int *in,Scalar *v)
582cd0e1443SSatish Balay {
583cd0e1443SSatish Balay   Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)A->data;
5842d61bbb3SSatish Balay   int        *rp,k,low,high,t,row,nrow,i,col,l,*aj = a->j;
5852d61bbb3SSatish Balay   int        *ai = a->i,*ailen = a->ilen;
5862d61bbb3SSatish Balay   int        brow,bcol,ridx,cidx,bs=a->bs,bs2=a->bs2;
5873f1db9ecSBarry Smith   MatScalar  *ap,*aa = a->a,zero = 0.0;
588cd0e1443SSatish Balay 
5893a40ed3dSBarry Smith   PetscFunctionBegin;
5902d61bbb3SSatish Balay   for (k=0; k<m; k++) { /* loop over rows */
591cd0e1443SSatish Balay     row  = im[k]; brow = row/bs;
59229bbc08cSBarry Smith     if (row < 0) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Negative row");
593273d9f13SBarry Smith     if (row >= A->m) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Row too large");
5942d61bbb3SSatish Balay     rp   = aj + ai[brow] ; ap = aa + bs2*ai[brow] ;
5952c3acbe9SBarry Smith     nrow = ailen[brow];
5962d61bbb3SSatish Balay     for (l=0; l<n; l++) { /* loop over columns */
59729bbc08cSBarry Smith       if (in[l] < 0) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Negative column");
598273d9f13SBarry Smith       if (in[l] >= A->n) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Column too large");
5992d61bbb3SSatish Balay       col  = in[l] ;
6002d61bbb3SSatish Balay       bcol = col/bs;
6012d61bbb3SSatish Balay       cidx = col%bs;
6022d61bbb3SSatish Balay       ridx = row%bs;
6032d61bbb3SSatish Balay       high = nrow;
6042d61bbb3SSatish Balay       low  = 0; /* assume unsorted */
6052d61bbb3SSatish Balay       while (high-low > 5) {
606cd0e1443SSatish Balay         t = (low+high)/2;
607cd0e1443SSatish Balay         if (rp[t] > bcol) high = t;
608cd0e1443SSatish Balay         else             low  = t;
609cd0e1443SSatish Balay       }
610cd0e1443SSatish Balay       for (i=low; i<high; i++) {
611cd0e1443SSatish Balay         if (rp[i] > bcol) break;
612cd0e1443SSatish Balay         if (rp[i] == bcol) {
6132d61bbb3SSatish Balay           *v++ = ap[bs2*i+bs*cidx+ridx];
6142d61bbb3SSatish Balay           goto finished;
615cd0e1443SSatish Balay         }
616cd0e1443SSatish Balay       }
6172d61bbb3SSatish Balay       *v++ = zero;
6182d61bbb3SSatish Balay       finished:;
619cd0e1443SSatish Balay     }
620cd0e1443SSatish Balay   }
6213a40ed3dSBarry Smith   PetscFunctionReturn(0);
622cd0e1443SSatish Balay }
623cd0e1443SSatish Balay 
62495d5f7c2SBarry Smith #if defined(PETSC_USE_MAT_SINGLE)
62595d5f7c2SBarry Smith #undef __FUNC__
626b0a32e0cSBarry Smith #define __FUNC__ "MatSetValuesBlocked_SeqBAIJ"
62795d5f7c2SBarry Smith int MatSetValuesBlocked_SeqBAIJ(Mat mat,int m,int *im,int n,int *in,Scalar *v,InsertMode addv)
62895d5f7c2SBarry Smith {
629563b5814SBarry Smith   Mat_SeqBAIJ *b = (Mat_SeqBAIJ*)mat->data;
630563b5814SBarry Smith   int         ierr,i,N = m*n*b->bs2;
631563b5814SBarry Smith   MatScalar   *vsingle;
63295d5f7c2SBarry Smith 
63395d5f7c2SBarry Smith   PetscFunctionBegin;
634563b5814SBarry Smith   if (N > b->setvalueslen) {
635563b5814SBarry Smith     if (b->setvaluescopy) {ierr = PetscFree(b->setvaluescopy);CHKERRQ(ierr);}
636b0a32e0cSBarry Smith     ierr = PetscMalloc(N*sizeof(MatScalar),&b->setvaluescopy);CHKERRQ(ierr);
637563b5814SBarry Smith     b->setvalueslen  = N;
638563b5814SBarry Smith   }
639563b5814SBarry Smith   vsingle = b->setvaluescopy;
64095d5f7c2SBarry Smith   for (i=0; i<N; i++) {
64195d5f7c2SBarry Smith     vsingle[i] = v[i];
64295d5f7c2SBarry Smith   }
64395d5f7c2SBarry Smith   ierr = MatSetValuesBlocked_SeqBAIJ_MatScalar(mat,m,im,n,in,vsingle,addv);CHKERRQ(ierr);
64495d5f7c2SBarry Smith   PetscFunctionReturn(0);
64595d5f7c2SBarry Smith }
64695d5f7c2SBarry Smith #endif
64795d5f7c2SBarry Smith 
6482d61bbb3SSatish Balay 
6495615d1e5SSatish Balay #undef __FUNC__
650b0a32e0cSBarry Smith #define __FUNC__ "MatSetValuesBlocked_SeqBAIJ"
65195d5f7c2SBarry Smith int MatSetValuesBlocked_SeqBAIJ_MatScalar(Mat A,int m,int *im,int n,int *in,MatScalar *v,InsertMode is)
65292c4ed94SBarry Smith {
65392c4ed94SBarry Smith   Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)A->data;
6548a84c255SSatish Balay   int         *rp,k,low,high,t,ii,jj,row,nrow,i,col,l,rmax,N,sorted=a->sorted;
655273d9f13SBarry Smith   int         *imax=a->imax,*ai=a->i,*ailen=a->ilen;
656549d3d68SSatish Balay   int         *aj=a->j,nonew=a->nonew,bs2=a->bs2,bs=a->bs,stepval,ierr;
657273d9f13SBarry Smith   PetscTruth  roworiented=a->roworiented;
65895d5f7c2SBarry Smith   MatScalar   *value = v,*ap,*aa = a->a,*bap;
65992c4ed94SBarry Smith 
6603a40ed3dSBarry Smith   PetscFunctionBegin;
6610e324ae4SSatish Balay   if (roworiented) {
6620e324ae4SSatish Balay     stepval = (n-1)*bs;
6630e324ae4SSatish Balay   } else {
6640e324ae4SSatish Balay     stepval = (m-1)*bs;
6650e324ae4SSatish Balay   }
66692c4ed94SBarry Smith   for (k=0; k<m; k++) { /* loop over added rows */
66792c4ed94SBarry Smith     row  = im[k];
6685ef9f2a5SBarry Smith     if (row < 0) continue;
669aa482453SBarry Smith #if defined(PETSC_USE_BOPT_g)
67029bbc08cSBarry Smith     if (row >= a->mbs) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Row too large");
67192c4ed94SBarry Smith #endif
67292c4ed94SBarry Smith     rp   = aj + ai[row];
67392c4ed94SBarry Smith     ap   = aa + bs2*ai[row];
67492c4ed94SBarry Smith     rmax = imax[row];
67592c4ed94SBarry Smith     nrow = ailen[row];
67692c4ed94SBarry Smith     low  = 0;
67792c4ed94SBarry Smith     for (l=0; l<n; l++) { /* loop over added columns */
6785ef9f2a5SBarry Smith       if (in[l] < 0) continue;
679aa482453SBarry Smith #if defined(PETSC_USE_BOPT_g)
68029bbc08cSBarry Smith       if (in[l] >= a->nbs) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Column too large");
68192c4ed94SBarry Smith #endif
68292c4ed94SBarry Smith       col = in[l];
68392c4ed94SBarry Smith       if (roworiented) {
6840e324ae4SSatish Balay         value = v + k*(stepval+bs)*bs + l*bs;
6850e324ae4SSatish Balay       } else {
6860e324ae4SSatish Balay         value = v + l*(stepval+bs)*bs + k*bs;
68792c4ed94SBarry Smith       }
68892c4ed94SBarry Smith       if (!sorted) low = 0; high = nrow;
68992c4ed94SBarry Smith       while (high-low > 7) {
69092c4ed94SBarry Smith         t = (low+high)/2;
69192c4ed94SBarry Smith         if (rp[t] > col) high = t;
69292c4ed94SBarry Smith         else             low  = t;
69392c4ed94SBarry Smith       }
69492c4ed94SBarry Smith       for (i=low; i<high; i++) {
69592c4ed94SBarry Smith         if (rp[i] > col) break;
69692c4ed94SBarry Smith         if (rp[i] == col) {
6978a84c255SSatish Balay           bap  = ap +  bs2*i;
6980e324ae4SSatish Balay           if (roworiented) {
6998a84c255SSatish Balay             if (is == ADD_VALUES) {
700dd9472c6SBarry Smith               for (ii=0; ii<bs; ii++,value+=stepval) {
701dd9472c6SBarry Smith                 for (jj=ii; jj<bs2; jj+=bs) {
7028a84c255SSatish Balay                   bap[jj] += *value++;
703dd9472c6SBarry Smith                 }
704dd9472c6SBarry Smith               }
7050e324ae4SSatish Balay             } else {
706dd9472c6SBarry Smith               for (ii=0; ii<bs; ii++,value+=stepval) {
707dd9472c6SBarry Smith                 for (jj=ii; jj<bs2; jj+=bs) {
7080e324ae4SSatish Balay                   bap[jj] = *value++;
7098a84c255SSatish Balay                 }
710dd9472c6SBarry Smith               }
711dd9472c6SBarry Smith             }
7120e324ae4SSatish Balay           } else {
7130e324ae4SSatish Balay             if (is == ADD_VALUES) {
714dd9472c6SBarry Smith               for (ii=0; ii<bs; ii++,value+=stepval) {
715dd9472c6SBarry Smith                 for (jj=0; jj<bs; jj++) {
7160e324ae4SSatish Balay                   *bap++ += *value++;
717dd9472c6SBarry Smith                 }
718dd9472c6SBarry Smith               }
7190e324ae4SSatish Balay             } else {
720dd9472c6SBarry Smith               for (ii=0; ii<bs; ii++,value+=stepval) {
721dd9472c6SBarry Smith                 for (jj=0; jj<bs; jj++) {
7220e324ae4SSatish Balay                   *bap++  = *value++;
7230e324ae4SSatish Balay                 }
7248a84c255SSatish Balay               }
725dd9472c6SBarry Smith             }
726dd9472c6SBarry Smith           }
727f1241b54SBarry Smith           goto noinsert2;
72892c4ed94SBarry Smith         }
72992c4ed94SBarry Smith       }
73089280ab3SLois Curfman McInnes       if (nonew == 1) goto noinsert2;
73129bbc08cSBarry Smith       else if (nonew == -1) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Inserting a new nonzero in the matrix");
73292c4ed94SBarry Smith       if (nrow >= rmax) {
73392c4ed94SBarry Smith         /* there is no extra room in row, therefore enlarge */
73492c4ed94SBarry Smith         int       new_nz = ai[a->mbs] + CHUNKSIZE,len,*new_i,*new_j;
7353f1db9ecSBarry Smith         MatScalar *new_a;
73692c4ed94SBarry Smith 
73729bbc08cSBarry Smith         if (nonew == -2) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Inserting a new nonzero in the matrix");
73889280ab3SLois Curfman McInnes 
73992c4ed94SBarry Smith         /* malloc new storage space */
7403f1db9ecSBarry Smith         len     = new_nz*(sizeof(int)+bs2*sizeof(MatScalar))+(a->mbs+1)*sizeof(int);
741b0a32e0cSBarry Smith 	ierr    = PetscMalloc(len,&new_a);CHKERRQ(ierr);
74292c4ed94SBarry Smith         new_j   = (int*)(new_a + bs2*new_nz);
74392c4ed94SBarry Smith         new_i   = new_j + new_nz;
74492c4ed94SBarry Smith 
74592c4ed94SBarry Smith         /* copy over old data into new slots */
74692c4ed94SBarry Smith         for (ii=0; ii<row+1; ii++) {new_i[ii] = ai[ii];}
74792c4ed94SBarry Smith         for (ii=row+1; ii<a->mbs+1; ii++) {new_i[ii] = ai[ii]+CHUNKSIZE;}
748549d3d68SSatish Balay         ierr = PetscMemcpy(new_j,aj,(ai[row]+nrow)*sizeof(int));CHKERRQ(ierr);
74992c4ed94SBarry Smith         len  = (new_nz - CHUNKSIZE - ai[row] - nrow);
750549d3d68SSatish Balay         ierr = PetscMemcpy(new_j+ai[row]+nrow+CHUNKSIZE,aj+ai[row]+nrow,len*sizeof(int));CHKERRQ(ierr);
751549d3d68SSatish Balay         ierr = PetscMemcpy(new_a,aa,(ai[row]+nrow)*bs2*sizeof(MatScalar));CHKERRQ(ierr);
752549d3d68SSatish Balay         ierr = PetscMemzero(new_a+bs2*(ai[row]+nrow),bs2*CHUNKSIZE*sizeof(MatScalar));CHKERRQ(ierr);
753549d3d68SSatish Balay         ierr = PetscMemcpy(new_a+bs2*(ai[row]+nrow+CHUNKSIZE),aa+bs2*(ai[row]+nrow),bs2*len*sizeof(MatScalar));CHKERRQ(ierr);
75492c4ed94SBarry Smith         /* free up old matrix storage */
755606d414cSSatish Balay         ierr = PetscFree(a->a);CHKERRQ(ierr);
756606d414cSSatish Balay         if (!a->singlemalloc) {
757606d414cSSatish Balay           ierr = PetscFree(a->i);CHKERRQ(ierr);
758606d414cSSatish Balay           ierr = PetscFree(a->j);CHKERRQ(ierr);
759606d414cSSatish Balay         }
76092c4ed94SBarry Smith         aa = a->a = new_a; ai = a->i = new_i; aj = a->j = new_j;
761c4992f7dSBarry Smith         a->singlemalloc = PETSC_TRUE;
76292c4ed94SBarry Smith 
76392c4ed94SBarry Smith         rp   = aj + ai[row]; ap = aa + bs2*ai[row];
76492c4ed94SBarry Smith         rmax = imax[row] = imax[row] + CHUNKSIZE;
765b0a32e0cSBarry Smith         PetscLogObjectMemory(A,CHUNKSIZE*(sizeof(int) + bs2*sizeof(MatScalar)));
76692c4ed94SBarry Smith         a->maxnz += bs2*CHUNKSIZE;
76792c4ed94SBarry Smith         a->reallocs++;
76892c4ed94SBarry Smith         a->nz++;
76992c4ed94SBarry Smith       }
77092c4ed94SBarry Smith       N = nrow++ - 1;
77192c4ed94SBarry Smith       /* shift up all the later entries in this row */
77292c4ed94SBarry Smith       for (ii=N; ii>=i; ii--) {
77392c4ed94SBarry Smith         rp[ii+1] = rp[ii];
774549d3d68SSatish Balay         ierr = PetscMemcpy(ap+bs2*(ii+1),ap+bs2*(ii),bs2*sizeof(MatScalar));CHKERRQ(ierr);
77592c4ed94SBarry Smith       }
776549d3d68SSatish Balay       if (N >= i) {
777549d3d68SSatish Balay         ierr = PetscMemzero(ap+bs2*i,bs2*sizeof(MatScalar));CHKERRQ(ierr);
778549d3d68SSatish Balay       }
77992c4ed94SBarry Smith       rp[i] = col;
7808a84c255SSatish Balay       bap   = ap +  bs2*i;
7810e324ae4SSatish Balay       if (roworiented) {
782dd9472c6SBarry Smith         for (ii=0; ii<bs; ii++,value+=stepval) {
783dd9472c6SBarry Smith           for (jj=ii; jj<bs2; jj+=bs) {
7840e324ae4SSatish Balay             bap[jj] = *value++;
785dd9472c6SBarry Smith           }
786dd9472c6SBarry Smith         }
7870e324ae4SSatish Balay       } else {
788dd9472c6SBarry Smith         for (ii=0; ii<bs; ii++,value+=stepval) {
789dd9472c6SBarry Smith           for (jj=0; jj<bs; jj++) {
7900e324ae4SSatish Balay             *bap++  = *value++;
7910e324ae4SSatish Balay           }
792dd9472c6SBarry Smith         }
793dd9472c6SBarry Smith       }
794f1241b54SBarry Smith       noinsert2:;
79592c4ed94SBarry Smith       low = i;
79692c4ed94SBarry Smith     }
79792c4ed94SBarry Smith     ailen[row] = nrow;
79892c4ed94SBarry Smith   }
7993a40ed3dSBarry Smith   PetscFunctionReturn(0);
80092c4ed94SBarry Smith }
80192c4ed94SBarry Smith 
802f2501298SSatish Balay 
8035615d1e5SSatish Balay #undef __FUNC__
804b0a32e0cSBarry Smith #define __FUNC__ "MatAssemblyEnd_SeqBAIJ"
8058f6be9afSLois Curfman McInnes int MatAssemblyEnd_SeqBAIJ(Mat A,MatAssemblyType mode)
806584200bdSSatish Balay {
807584200bdSSatish Balay   Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)A->data;
808584200bdSSatish Balay   int        fshift = 0,i,j,*ai = a->i,*aj = a->j,*imax = a->imax;
809273d9f13SBarry Smith   int        m = A->m,*ip,N,*ailen = a->ilen;
810549d3d68SSatish Balay   int        mbs = a->mbs,bs2 = a->bs2,rmax = 0,ierr;
8113f1db9ecSBarry Smith   MatScalar  *aa = a->a,*ap;
812584200bdSSatish Balay 
8133a40ed3dSBarry Smith   PetscFunctionBegin;
8143a40ed3dSBarry Smith   if (mode == MAT_FLUSH_ASSEMBLY) PetscFunctionReturn(0);
815584200bdSSatish Balay 
81643ee02c3SBarry Smith   if (m) rmax = ailen[0];
817584200bdSSatish Balay   for (i=1; i<mbs; i++) {
818584200bdSSatish Balay     /* move each row back by the amount of empty slots (fshift) before it*/
819584200bdSSatish Balay     fshift += imax[i-1] - ailen[i-1];
820d402145bSBarry Smith     rmax   = PetscMax(rmax,ailen[i]);
821584200bdSSatish Balay     if (fshift) {
822a7c10996SSatish Balay       ip = aj + ai[i]; ap = aa + bs2*ai[i];
823584200bdSSatish Balay       N = ailen[i];
824584200bdSSatish Balay       for (j=0; j<N; j++) {
825584200bdSSatish Balay         ip[j-fshift] = ip[j];
826549d3d68SSatish Balay         ierr = PetscMemcpy(ap+(j-fshift)*bs2,ap+j*bs2,bs2*sizeof(MatScalar));CHKERRQ(ierr);
827584200bdSSatish Balay       }
828584200bdSSatish Balay     }
829584200bdSSatish Balay     ai[i] = ai[i-1] + ailen[i-1];
830584200bdSSatish Balay   }
831584200bdSSatish Balay   if (mbs) {
832584200bdSSatish Balay     fshift += imax[mbs-1] - ailen[mbs-1];
833584200bdSSatish Balay     ai[mbs] = ai[mbs-1] + ailen[mbs-1];
834584200bdSSatish Balay   }
835584200bdSSatish Balay   /* reset ilen and imax for each row */
836584200bdSSatish Balay   for (i=0; i<mbs; i++) {
837584200bdSSatish Balay     ailen[i] = imax[i] = ai[i+1] - ai[i];
838584200bdSSatish Balay   }
839a7c10996SSatish Balay   a->nz = ai[mbs];
840584200bdSSatish Balay 
841584200bdSSatish Balay   /* diagonals may have moved, so kill the diagonal pointers */
842584200bdSSatish Balay   if (fshift && a->diag) {
843606d414cSSatish Balay     ierr = PetscFree(a->diag);CHKERRQ(ierr);
844b0a32e0cSBarry Smith     PetscLogObjectMemory(A,-(m+1)*sizeof(int));
845584200bdSSatish Balay     a->diag = 0;
846584200bdSSatish Balay   }
847b0a32e0cSBarry Smith   PetscLogInfo(A,"MatAssemblyEnd_SeqBAIJ:Matrix size: %d X %d, block size %d; storage space: %d unneeded, %d used\n",
848273d9f13SBarry Smith            m,A->n,a->bs,fshift*bs2,a->nz*bs2);
849b0a32e0cSBarry Smith   PetscLogInfo(A,"MatAssemblyEnd_SeqBAIJ:Number of mallocs during MatSetValues is %d\n",
850584200bdSSatish Balay            a->reallocs);
851b0a32e0cSBarry Smith   PetscLogInfo(A,"MatAssemblyEnd_SeqBAIJ:Most nonzeros blocks in any row is %d\n",rmax);
852e2f3b5e9SSatish Balay   a->reallocs          = 0;
8530e6d2581SBarry Smith   A->info.nz_unneeded  = (PetscReal)fshift*bs2;
8544e220ebcSLois Curfman McInnes 
8553a40ed3dSBarry Smith   PetscFunctionReturn(0);
856584200bdSSatish Balay }
857584200bdSSatish Balay 
8585a838052SSatish Balay 
859bea157c4SSatish Balay 
860bea157c4SSatish Balay /*
861bea157c4SSatish Balay    This function returns an array of flags which indicate the locations of contiguous
862bea157c4SSatish Balay    blocks that should be zeroed. for eg: if bs = 3  and is = [0,1,2,3,5,6,7,8,9]
863bea157c4SSatish Balay    then the resulting sizes = [3,1,1,3,1] correspondig to sets [(0,1,2),(3),(5),(6,7,8),(9)]
864bea157c4SSatish Balay    Assume: sizes should be long enough to hold all the values.
865bea157c4SSatish Balay */
8665615d1e5SSatish Balay #undef __FUNC__
867b0a32e0cSBarry Smith #define __FUNC__ "MatZeroRows_SeqBAIJ_Check_Blocks"
868bea157c4SSatish Balay static int MatZeroRows_SeqBAIJ_Check_Blocks(int idx[],int n,int bs,int sizes[], int *bs_max)
869d9b7c43dSSatish Balay {
870bea157c4SSatish Balay   int        i,j,k,row;
871bea157c4SSatish Balay   PetscTruth flg;
8723a40ed3dSBarry Smith 
873433994e6SBarry Smith   PetscFunctionBegin;
874bea157c4SSatish Balay   for (i=0,j=0; i<n; j++) {
875bea157c4SSatish Balay     row = idx[i];
876bea157c4SSatish Balay     if (row%bs!=0) { /* Not the begining of a block */
877bea157c4SSatish Balay       sizes[j] = 1;
878bea157c4SSatish Balay       i++;
879e4fda26cSSatish Balay     } else if (i+bs > n) { /* complete block doesn't exist (at idx end) */
880bea157c4SSatish Balay       sizes[j] = 1;         /* Also makes sure atleast 'bs' values exist for next else */
881bea157c4SSatish Balay       i++;
882bea157c4SSatish Balay     } else { /* Begining of the block, so check if the complete block exists */
883bea157c4SSatish Balay       flg = PETSC_TRUE;
884bea157c4SSatish Balay       for (k=1; k<bs; k++) {
885bea157c4SSatish Balay         if (row+k != idx[i+k]) { /* break in the block */
886bea157c4SSatish Balay           flg = PETSC_FALSE;
887bea157c4SSatish Balay           break;
888d9b7c43dSSatish Balay         }
889bea157c4SSatish Balay       }
890bea157c4SSatish Balay       if (flg == PETSC_TRUE) { /* No break in the bs */
891bea157c4SSatish Balay         sizes[j] = bs;
892bea157c4SSatish Balay         i+= bs;
893bea157c4SSatish Balay       } else {
894bea157c4SSatish Balay         sizes[j] = 1;
895bea157c4SSatish Balay         i++;
896bea157c4SSatish Balay       }
897bea157c4SSatish Balay     }
898bea157c4SSatish Balay   }
899bea157c4SSatish Balay   *bs_max = j;
9003a40ed3dSBarry Smith   PetscFunctionReturn(0);
901d9b7c43dSSatish Balay }
902d9b7c43dSSatish Balay 
9035615d1e5SSatish Balay #undef __FUNC__
904b0a32e0cSBarry Smith #define __FUNC__ "MatZeroRows_SeqBAIJ"
9058f6be9afSLois Curfman McInnes int MatZeroRows_SeqBAIJ(Mat A,IS is,Scalar *diag)
906d9b7c43dSSatish Balay {
907d9b7c43dSSatish Balay   Mat_SeqBAIJ *baij=(Mat_SeqBAIJ*)A->data;
908b6815fffSBarry Smith   int         ierr,i,j,k,count,is_n,*is_idx,*rows;
909bea157c4SSatish Balay   int         bs=baij->bs,bs2=baij->bs2,*sizes,row,bs_max;
9103f1db9ecSBarry Smith   Scalar      zero = 0.0;
9113f1db9ecSBarry Smith   MatScalar   *aa;
912d9b7c43dSSatish Balay 
9133a40ed3dSBarry Smith   PetscFunctionBegin;
914d9b7c43dSSatish Balay   /* Make a copy of the IS and  sort it */
915b9b97703SBarry Smith   ierr = ISGetLocalSize(is,&is_n);CHKERRQ(ierr);
916d9b7c43dSSatish Balay   ierr = ISGetIndices(is,&is_idx);CHKERRQ(ierr);
917d9b7c43dSSatish Balay 
918bea157c4SSatish Balay   /* allocate memory for rows,sizes */
919b0a32e0cSBarry Smith   ierr  = PetscMalloc((3*is_n+1)*sizeof(int),&rows);CHKERRQ(ierr);
920bea157c4SSatish Balay   sizes = rows + is_n;
921bea157c4SSatish Balay 
922563b5814SBarry Smith   /* copy IS values to rows, and sort them */
923bea157c4SSatish Balay   for (i=0; i<is_n; i++) { rows[i] = is_idx[i]; }
924bea157c4SSatish Balay   ierr = PetscSortInt(is_n,rows);CHKERRQ(ierr);
925dffd3267SBarry Smith   if (baij->keepzeroedrows) {
926dffd3267SBarry Smith     for (i=0; i<is_n; i++) { sizes[i] = 1; }
927dffd3267SBarry Smith     bs_max = is_n;
928dffd3267SBarry Smith   } else {
929bea157c4SSatish Balay     ierr = MatZeroRows_SeqBAIJ_Check_Blocks(rows,is_n,bs,sizes,&bs_max);CHKERRQ(ierr);
930dffd3267SBarry Smith   }
931b97a56abSSatish Balay   ierr = ISRestoreIndices(is,&is_idx);CHKERRQ(ierr);
932bea157c4SSatish Balay 
933bea157c4SSatish Balay   for (i=0,j=0; i<bs_max; j+=sizes[i],i++) {
934bea157c4SSatish Balay     row   = rows[j];
935273d9f13SBarry Smith     if (row < 0 || row > A->m) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"row %d out of range",row);
936bea157c4SSatish Balay     count = (baij->i[row/bs +1] - baij->i[row/bs])*bs;
937bea157c4SSatish Balay     aa    = baij->a + baij->i[row/bs]*bs2 + (row%bs);
938dffd3267SBarry Smith     if (sizes[i] == bs && !baij->keepzeroedrows) {
939bea157c4SSatish Balay       if (diag) {
940bea157c4SSatish Balay         if (baij->ilen[row/bs] > 0) {
941bea157c4SSatish Balay           baij->ilen[row/bs]       = 1;
942bea157c4SSatish Balay           baij->j[baij->i[row/bs]] = row/bs;
943bea157c4SSatish Balay           ierr = PetscMemzero(aa,count*bs*sizeof(MatScalar));CHKERRQ(ierr);
944a07cd24cSSatish Balay         }
945563b5814SBarry Smith         /* Now insert all the diagonal values for this bs */
946bea157c4SSatish Balay         for (k=0; k<bs; k++) {
947bea157c4SSatish Balay           ierr = (*A->ops->setvalues)(A,1,rows+j+k,1,rows+j+k,diag,INSERT_VALUES);CHKERRQ(ierr);
948bea157c4SSatish Balay         }
949bea157c4SSatish Balay       } else { /* (!diag) */
950bea157c4SSatish Balay         baij->ilen[row/bs] = 0;
951bea157c4SSatish Balay       } /* end (!diag) */
952bea157c4SSatish Balay     } else { /* (sizes[i] != bs) */
953aa482453SBarry Smith #if defined (PETSC_USE_DEBUG)
95429bbc08cSBarry Smith       if (sizes[i] != 1) SETERRQ(1,"Internal Error. Value should be 1");
955bea157c4SSatish Balay #endif
956bea157c4SSatish Balay       for (k=0; k<count; k++) {
957d9b7c43dSSatish Balay         aa[0] =  zero;
958d9b7c43dSSatish Balay         aa    += bs;
959d9b7c43dSSatish Balay       }
960d9b7c43dSSatish Balay       if (diag) {
961f830108cSBarry Smith         ierr = (*A->ops->setvalues)(A,1,rows+j,1,rows+j,diag,INSERT_VALUES);CHKERRQ(ierr);
962d9b7c43dSSatish Balay       }
963d9b7c43dSSatish Balay     }
964bea157c4SSatish Balay   }
965bea157c4SSatish Balay 
966606d414cSSatish Balay   ierr = PetscFree(rows);CHKERRQ(ierr);
9679a8dea36SBarry Smith   ierr = MatAssemblyEnd_SeqBAIJ(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
9683a40ed3dSBarry Smith   PetscFunctionReturn(0);
969d9b7c43dSSatish Balay }
9701c351548SSatish Balay 
9715615d1e5SSatish Balay #undef __FUNC__
972b0a32e0cSBarry Smith #define __FUNC__ "MatSetValues_SeqBAIJ"
9732d61bbb3SSatish Balay int MatSetValues_SeqBAIJ(Mat A,int m,int *im,int n,int *in,Scalar *v,InsertMode is)
9742d61bbb3SSatish Balay {
9752d61bbb3SSatish Balay   Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)A->data;
9762d61bbb3SSatish Balay   int         *rp,k,low,high,t,ii,row,nrow,i,col,l,rmax,N,sorted=a->sorted;
977273d9f13SBarry Smith   int         *imax=a->imax,*ai=a->i,*ailen=a->ilen;
9782d61bbb3SSatish Balay   int         *aj=a->j,nonew=a->nonew,bs=a->bs,brow,bcol;
979549d3d68SSatish Balay   int         ridx,cidx,bs2=a->bs2,ierr;
980273d9f13SBarry Smith   PetscTruth  roworiented=a->roworiented;
9813f1db9ecSBarry Smith   MatScalar   *ap,value,*aa=a->a,*bap;
9822d61bbb3SSatish Balay 
9832d61bbb3SSatish Balay   PetscFunctionBegin;
9842d61bbb3SSatish Balay   for (k=0; k<m; k++) { /* loop over added rows */
9852d61bbb3SSatish Balay     row  = im[k]; brow = row/bs;
9865ef9f2a5SBarry Smith     if (row < 0) continue;
987aa482453SBarry Smith #if defined(PETSC_USE_BOPT_g)
988273d9f13SBarry Smith     if (row >= A->m) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"Row too large: row %d max %d",row,A->m);
9892d61bbb3SSatish Balay #endif
9902d61bbb3SSatish Balay     rp   = aj + ai[brow];
9912d61bbb3SSatish Balay     ap   = aa + bs2*ai[brow];
9922d61bbb3SSatish Balay     rmax = imax[brow];
9932d61bbb3SSatish Balay     nrow = ailen[brow];
9942d61bbb3SSatish Balay     low  = 0;
9952d61bbb3SSatish Balay     for (l=0; l<n; l++) { /* loop over added columns */
9965ef9f2a5SBarry Smith       if (in[l] < 0) continue;
997aa482453SBarry Smith #if defined(PETSC_USE_BOPT_g)
998273d9f13SBarry Smith       if (in[l] >= A->n) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"Column too large: col %d max %d",in[l],A->n);
9992d61bbb3SSatish Balay #endif
10002d61bbb3SSatish Balay       col = in[l]; bcol = col/bs;
10012d61bbb3SSatish Balay       ridx = row % bs; cidx = col % bs;
10022d61bbb3SSatish Balay       if (roworiented) {
10035ef9f2a5SBarry Smith         value = v[l + k*n];
10042d61bbb3SSatish Balay       } else {
10052d61bbb3SSatish Balay         value = v[k + l*m];
10062d61bbb3SSatish Balay       }
10072d61bbb3SSatish Balay       if (!sorted) low = 0; high = nrow;
10082d61bbb3SSatish Balay       while (high-low > 7) {
10092d61bbb3SSatish Balay         t = (low+high)/2;
10102d61bbb3SSatish Balay         if (rp[t] > bcol) high = t;
10112d61bbb3SSatish Balay         else              low  = t;
10122d61bbb3SSatish Balay       }
10132d61bbb3SSatish Balay       for (i=low; i<high; i++) {
10142d61bbb3SSatish Balay         if (rp[i] > bcol) break;
10152d61bbb3SSatish Balay         if (rp[i] == bcol) {
10162d61bbb3SSatish Balay           bap  = ap +  bs2*i + bs*cidx + ridx;
10172d61bbb3SSatish Balay           if (is == ADD_VALUES) *bap += value;
10182d61bbb3SSatish Balay           else                  *bap  = value;
10192d61bbb3SSatish Balay           goto noinsert1;
10202d61bbb3SSatish Balay         }
10212d61bbb3SSatish Balay       }
10222d61bbb3SSatish Balay       if (nonew == 1) goto noinsert1;
102329bbc08cSBarry Smith       else if (nonew == -1) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Inserting a new nonzero in the matrix");
10242d61bbb3SSatish Balay       if (nrow >= rmax) {
10252d61bbb3SSatish Balay         /* there is no extra room in row, therefore enlarge */
10262d61bbb3SSatish Balay         int       new_nz = ai[a->mbs] + CHUNKSIZE,len,*new_i,*new_j;
10273f1db9ecSBarry Smith         MatScalar *new_a;
10282d61bbb3SSatish Balay 
102929bbc08cSBarry Smith         if (nonew == -2) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Inserting a new nonzero in the matrix");
10302d61bbb3SSatish Balay 
10312d61bbb3SSatish Balay         /* Malloc new storage space */
10323f1db9ecSBarry Smith         len     = new_nz*(sizeof(int)+bs2*sizeof(MatScalar))+(a->mbs+1)*sizeof(int);
1033b0a32e0cSBarry Smith 	ierr    = PetscMalloc(len,&new_a);CHKERRQ(ierr);
10342d61bbb3SSatish Balay         new_j   = (int*)(new_a + bs2*new_nz);
10352d61bbb3SSatish Balay         new_i   = new_j + new_nz;
10362d61bbb3SSatish Balay 
10372d61bbb3SSatish Balay         /* copy over old data into new slots */
10382d61bbb3SSatish Balay         for (ii=0; ii<brow+1; ii++) {new_i[ii] = ai[ii];}
10392d61bbb3SSatish Balay         for (ii=brow+1; ii<a->mbs+1; ii++) {new_i[ii] = ai[ii]+CHUNKSIZE;}
1040549d3d68SSatish Balay         ierr = PetscMemcpy(new_j,aj,(ai[brow]+nrow)*sizeof(int));CHKERRQ(ierr);
10412d61bbb3SSatish Balay         len  = (new_nz - CHUNKSIZE - ai[brow] - nrow);
1042549d3d68SSatish Balay         ierr = PetscMemcpy(new_j+ai[brow]+nrow+CHUNKSIZE,aj+ai[brow]+nrow,len*sizeof(int));CHKERRQ(ierr);
1043549d3d68SSatish Balay         ierr = PetscMemcpy(new_a,aa,(ai[brow]+nrow)*bs2*sizeof(MatScalar));CHKERRQ(ierr);
1044549d3d68SSatish Balay         ierr = PetscMemzero(new_a+bs2*(ai[brow]+nrow),bs2*CHUNKSIZE*sizeof(MatScalar));CHKERRQ(ierr);
1045549d3d68SSatish Balay         ierr = PetscMemcpy(new_a+bs2*(ai[brow]+nrow+CHUNKSIZE),aa+bs2*(ai[brow]+nrow),bs2*len*sizeof(MatScalar));CHKERRQ(ierr);
10462d61bbb3SSatish Balay         /* free up old matrix storage */
1047606d414cSSatish Balay         ierr = PetscFree(a->a);CHKERRQ(ierr);
1048606d414cSSatish Balay         if (!a->singlemalloc) {
1049606d414cSSatish Balay           ierr = PetscFree(a->i);CHKERRQ(ierr);
1050606d414cSSatish Balay           ierr = PetscFree(a->j);CHKERRQ(ierr);
1051606d414cSSatish Balay         }
10522d61bbb3SSatish Balay         aa = a->a = new_a; ai = a->i = new_i; aj = a->j = new_j;
1053c4992f7dSBarry Smith         a->singlemalloc = PETSC_TRUE;
10542d61bbb3SSatish Balay 
10552d61bbb3SSatish Balay         rp   = aj + ai[brow]; ap = aa + bs2*ai[brow];
10562d61bbb3SSatish Balay         rmax = imax[brow] = imax[brow] + CHUNKSIZE;
1057b0a32e0cSBarry Smith         PetscLogObjectMemory(A,CHUNKSIZE*(sizeof(int) + bs2*sizeof(MatScalar)));
10582d61bbb3SSatish Balay         a->maxnz += bs2*CHUNKSIZE;
10592d61bbb3SSatish Balay         a->reallocs++;
10602d61bbb3SSatish Balay         a->nz++;
10612d61bbb3SSatish Balay       }
10622d61bbb3SSatish Balay       N = nrow++ - 1;
10632d61bbb3SSatish Balay       /* shift up all the later entries in this row */
10642d61bbb3SSatish Balay       for (ii=N; ii>=i; ii--) {
10652d61bbb3SSatish Balay         rp[ii+1] = rp[ii];
1066549d3d68SSatish Balay         ierr     = PetscMemcpy(ap+bs2*(ii+1),ap+bs2*(ii),bs2*sizeof(MatScalar));CHKERRQ(ierr);
10672d61bbb3SSatish Balay       }
1068549d3d68SSatish Balay       if (N>=i) {
1069549d3d68SSatish Balay         ierr = PetscMemzero(ap+bs2*i,bs2*sizeof(MatScalar));CHKERRQ(ierr);
1070549d3d68SSatish Balay       }
10712d61bbb3SSatish Balay       rp[i]                      = bcol;
10722d61bbb3SSatish Balay       ap[bs2*i + bs*cidx + ridx] = value;
10732d61bbb3SSatish Balay       noinsert1:;
10742d61bbb3SSatish Balay       low = i;
10752d61bbb3SSatish Balay     }
10762d61bbb3SSatish Balay     ailen[brow] = nrow;
10772d61bbb3SSatish Balay   }
10782d61bbb3SSatish Balay   PetscFunctionReturn(0);
10792d61bbb3SSatish Balay }
10802d61bbb3SSatish Balay 
1081b9b97703SBarry Smith EXTERN int MatLUFactorSymbolic_SeqBAIJ(Mat,IS,IS,MatLUInfo*,Mat*);
1082b9b97703SBarry Smith EXTERN int MatLUFactor_SeqBAIJ(Mat,IS,IS,MatLUInfo*);
1083ca44d042SBarry Smith EXTERN int MatIncreaseOverlap_SeqBAIJ(Mat,int,IS*,int);
1084ca44d042SBarry Smith EXTERN int MatGetSubMatrix_SeqBAIJ(Mat,IS,IS,int,MatReuse,Mat*);
1085ca44d042SBarry Smith EXTERN int MatGetSubMatrices_SeqBAIJ(Mat,int,IS*,IS*,MatReuse,Mat**);
1086ca44d042SBarry Smith EXTERN int MatMultTranspose_SeqBAIJ(Mat,Vec,Vec);
1087ca44d042SBarry Smith EXTERN int MatMultTransposeAdd_SeqBAIJ(Mat,Vec,Vec,Vec);
1088ca44d042SBarry Smith EXTERN int MatScale_SeqBAIJ(Scalar*,Mat);
1089ca44d042SBarry Smith EXTERN int MatNorm_SeqBAIJ(Mat,NormType,PetscReal *);
1090ca44d042SBarry Smith EXTERN int MatEqual_SeqBAIJ(Mat,Mat,PetscTruth*);
1091ca44d042SBarry Smith EXTERN int MatGetDiagonal_SeqBAIJ(Mat,Vec);
1092ca44d042SBarry Smith EXTERN int MatDiagonalScale_SeqBAIJ(Mat,Vec,Vec);
1093ca44d042SBarry Smith EXTERN int MatGetInfo_SeqBAIJ(Mat,MatInfoType,MatInfo *);
1094ca44d042SBarry Smith EXTERN int MatZeroEntries_SeqBAIJ(Mat);
10952d61bbb3SSatish Balay 
1096ca44d042SBarry Smith EXTERN int MatSolve_SeqBAIJ_N(Mat,Vec,Vec);
1097ca44d042SBarry Smith EXTERN int MatSolve_SeqBAIJ_1(Mat,Vec,Vec);
1098ca44d042SBarry Smith EXTERN int MatSolve_SeqBAIJ_2(Mat,Vec,Vec);
1099ca44d042SBarry Smith EXTERN int MatSolve_SeqBAIJ_3(Mat,Vec,Vec);
1100ca44d042SBarry Smith EXTERN int MatSolve_SeqBAIJ_4(Mat,Vec,Vec);
1101ca44d042SBarry Smith EXTERN int MatSolve_SeqBAIJ_5(Mat,Vec,Vec);
1102ca44d042SBarry Smith EXTERN int MatSolve_SeqBAIJ_6(Mat,Vec,Vec);
1103ca44d042SBarry Smith EXTERN int MatSolve_SeqBAIJ_7(Mat,Vec,Vec);
1104ca44d042SBarry Smith EXTERN int MatSolveTranspose_SeqBAIJ_7(Mat,Vec,Vec);
1105ca44d042SBarry Smith EXTERN int MatSolveTranspose_SeqBAIJ_6(Mat,Vec,Vec);
1106ca44d042SBarry Smith EXTERN int MatSolveTranspose_SeqBAIJ_5(Mat,Vec,Vec);
1107ca44d042SBarry Smith EXTERN int MatSolveTranspose_SeqBAIJ_4(Mat,Vec,Vec);
1108ca44d042SBarry Smith EXTERN int MatSolveTranspose_SeqBAIJ_3(Mat,Vec,Vec);
1109ca44d042SBarry Smith EXTERN int MatSolveTranspose_SeqBAIJ_2(Mat,Vec,Vec);
1110ca44d042SBarry Smith EXTERN int MatSolveTranspose_SeqBAIJ_1(Mat,Vec,Vec);
11112d61bbb3SSatish Balay 
1112ca44d042SBarry Smith EXTERN int MatLUFactorNumeric_SeqBAIJ_N(Mat,Mat*);
1113ca44d042SBarry Smith EXTERN int MatLUFactorNumeric_SeqBAIJ_1(Mat,Mat*);
1114ca44d042SBarry Smith EXTERN int MatLUFactorNumeric_SeqBAIJ_2(Mat,Mat*);
1115ca44d042SBarry Smith EXTERN int MatLUFactorNumeric_SeqBAIJ_3(Mat,Mat*);
1116ca44d042SBarry Smith EXTERN int MatLUFactorNumeric_SeqBAIJ_4(Mat,Mat*);
1117ca44d042SBarry Smith EXTERN int MatLUFactorNumeric_SeqBAIJ_5(Mat,Mat*);
1118ca44d042SBarry Smith EXTERN int MatLUFactorNumeric_SeqBAIJ_6(Mat,Mat*);
11192d61bbb3SSatish Balay 
1120ca44d042SBarry Smith EXTERN int MatMult_SeqBAIJ_1(Mat,Vec,Vec);
1121ca44d042SBarry Smith EXTERN int MatMult_SeqBAIJ_2(Mat,Vec,Vec);
1122ca44d042SBarry Smith EXTERN int MatMult_SeqBAIJ_3(Mat,Vec,Vec);
1123ca44d042SBarry Smith EXTERN int MatMult_SeqBAIJ_4(Mat,Vec,Vec);
1124ca44d042SBarry Smith EXTERN int MatMult_SeqBAIJ_5(Mat,Vec,Vec);
1125ca44d042SBarry Smith EXTERN int MatMult_SeqBAIJ_6(Mat,Vec,Vec);
1126ca44d042SBarry Smith EXTERN int MatMult_SeqBAIJ_7(Mat,Vec,Vec);
1127ca44d042SBarry Smith EXTERN int MatMult_SeqBAIJ_N(Mat,Vec,Vec);
11282d61bbb3SSatish Balay 
1129ca44d042SBarry Smith EXTERN int MatMultAdd_SeqBAIJ_1(Mat,Vec,Vec,Vec);
1130ca44d042SBarry Smith EXTERN int MatMultAdd_SeqBAIJ_2(Mat,Vec,Vec,Vec);
1131ca44d042SBarry Smith EXTERN int MatMultAdd_SeqBAIJ_3(Mat,Vec,Vec,Vec);
1132ca44d042SBarry Smith EXTERN int MatMultAdd_SeqBAIJ_4(Mat,Vec,Vec,Vec);
1133ca44d042SBarry Smith EXTERN int MatMultAdd_SeqBAIJ_5(Mat,Vec,Vec,Vec);
1134ca44d042SBarry Smith EXTERN int MatMultAdd_SeqBAIJ_6(Mat,Vec,Vec,Vec);
1135ca44d042SBarry Smith EXTERN int MatMultAdd_SeqBAIJ_7(Mat,Vec,Vec,Vec);
1136ca44d042SBarry Smith EXTERN int MatMultAdd_SeqBAIJ_N(Mat,Vec,Vec,Vec);
11372d61bbb3SSatish Balay 
11382d61bbb3SSatish Balay #undef __FUNC__
1139b0a32e0cSBarry Smith #define __FUNC__ "MatILUFactor_SeqBAIJ"
11405ef9f2a5SBarry Smith int MatILUFactor_SeqBAIJ(Mat inA,IS row,IS col,MatILUInfo *info)
11412d61bbb3SSatish Balay {
11422d61bbb3SSatish Balay   Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)inA->data;
11432d61bbb3SSatish Balay   Mat         outA;
11442d61bbb3SSatish Balay   int         ierr;
1145667159a5SBarry Smith   PetscTruth  row_identity,col_identity;
11462d61bbb3SSatish Balay 
11472d61bbb3SSatish Balay   PetscFunctionBegin;
114829bbc08cSBarry Smith   if (info && info->levels != 0) SETERRQ(PETSC_ERR_SUP,"Only levels = 0 supported for in-place ILU");
1149667159a5SBarry Smith   ierr = ISIdentity(row,&row_identity);CHKERRQ(ierr);
1150667159a5SBarry Smith   ierr = ISIdentity(col,&col_identity);CHKERRQ(ierr);
1151667159a5SBarry Smith   if (!row_identity || !col_identity) {
115229bbc08cSBarry Smith     SETERRQ(1,"Row and column permutations must be identity for in-place ILU");
1153667159a5SBarry Smith   }
11542d61bbb3SSatish Balay 
11552d61bbb3SSatish Balay   outA          = inA;
11562d61bbb3SSatish Balay   inA->factor   = FACTOR_LU;
11572d61bbb3SSatish Balay 
11582d61bbb3SSatish Balay   if (!a->diag) {
1159c4992f7dSBarry Smith     ierr = MatMarkDiagonal_SeqBAIJ(inA);CHKERRQ(ierr);
11602d61bbb3SSatish Balay   }
11612d61bbb3SSatish Balay   /*
116215091d37SBarry Smith       Blocksize 2, 3, 4, 5, 6 and 7 have a special faster factorization/solver
116315091d37SBarry Smith       for ILU(0) factorization with natural ordering
11642d61bbb3SSatish Balay   */
116515091d37SBarry Smith   switch (a->bs) {
1166f1af5d2fSBarry Smith   case 1:
1167e37c484bSBarry Smith     inA->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_1;
1168e37c484bSBarry Smith     inA->ops->solve           = MatSolve_SeqBAIJ_1_NaturalOrdering;
1169e37c484bSBarry Smith     inA->ops->solvetranspose  = MatSolveTranspose_SeqBAIJ_1_NaturalOrdering;
1170b0a32e0cSBarry Smith     PetscLogInfo(inA,"MatILUFactor_SeqBAIJ:Using special in-place natural ordering factor and solve BS=1\n");
117115091d37SBarry Smith   case 2:
117215091d37SBarry Smith     inA->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_2_NaturalOrdering;
117315091d37SBarry Smith     inA->ops->solve           = MatSolve_SeqBAIJ_2_NaturalOrdering;
11747c922b88SBarry Smith     inA->ops->solvetranspose  = MatSolveTranspose_SeqBAIJ_2_NaturalOrdering;
1175b0a32e0cSBarry Smith     PetscLogInfo(inA,"MatILUFactor_SeqBAIJ:Using special in-place natural ordering factor and solve BS=2\n");
117615091d37SBarry Smith     break;
117715091d37SBarry Smith   case 3:
117815091d37SBarry Smith     inA->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_3_NaturalOrdering;
117915091d37SBarry Smith     inA->ops->solve           = MatSolve_SeqBAIJ_3_NaturalOrdering;
11807c922b88SBarry Smith     inA->ops->solvetranspose  = MatSolveTranspose_SeqBAIJ_3_NaturalOrdering;
1181b0a32e0cSBarry Smith     PetscLogInfo(inA,"MatILUFactor_SeqBAIJ:Using special in-place natural ordering factor and solve BS=3\n");
118215091d37SBarry Smith     break;
118315091d37SBarry Smith   case 4:
1184667159a5SBarry Smith     inA->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_4_NaturalOrdering;
1185f830108cSBarry Smith     inA->ops->solve           = MatSolve_SeqBAIJ_4_NaturalOrdering;
11867c922b88SBarry Smith     inA->ops->solvetranspose  = MatSolveTranspose_SeqBAIJ_4_NaturalOrdering;
1187b0a32e0cSBarry Smith     PetscLogInfo(inA,"MatILUFactor_SeqBAIJ:Using special in-place natural ordering factor and solve BS=4\n");
118815091d37SBarry Smith     break;
118915091d37SBarry Smith   case 5:
1190667159a5SBarry Smith     inA->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_5_NaturalOrdering;
1191667159a5SBarry Smith     inA->ops->solve           = MatSolve_SeqBAIJ_5_NaturalOrdering;
11927c922b88SBarry Smith     inA->ops->solvetranspose  = MatSolveTranspose_SeqBAIJ_5_NaturalOrdering;
1193b0a32e0cSBarry Smith     PetscLogInfo(inA,"MatILUFactor_SeqBAIJ:Using special in-place natural ordering factor and solve BS=5\n");
119415091d37SBarry Smith     break;
119515091d37SBarry Smith   case 6:
119615091d37SBarry Smith     inA->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_6_NaturalOrdering;
119715091d37SBarry Smith     inA->ops->solve           = MatSolve_SeqBAIJ_6_NaturalOrdering;
11987c922b88SBarry Smith     inA->ops->solvetranspose  = MatSolveTranspose_SeqBAIJ_6_NaturalOrdering;
1199b0a32e0cSBarry Smith     PetscLogInfo(inA,"MatILUFactor_SeqBAIJ:Using special in-place natural ordering factor and solve BS=6\n");
120015091d37SBarry Smith     break;
120115091d37SBarry Smith   case 7:
120215091d37SBarry Smith     inA->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_7_NaturalOrdering;
12037c922b88SBarry Smith     inA->ops->solvetranspose  = MatSolveTranspose_SeqBAIJ_7_NaturalOrdering;
120415091d37SBarry Smith     inA->ops->solve           = MatSolve_SeqBAIJ_7_NaturalOrdering;
1205b0a32e0cSBarry Smith     PetscLogInfo(inA,"MatILUFactor_SeqBAIJ:Using special in-place natural ordering factor and solve BS=7\n");
120615091d37SBarry Smith     break;
1207c38d4ed2SBarry Smith   default:
1208c38d4ed2SBarry Smith     a->row        = row;
1209c38d4ed2SBarry Smith     a->col        = col;
1210c38d4ed2SBarry Smith     ierr          = PetscObjectReference((PetscObject)row);CHKERRQ(ierr);
1211c38d4ed2SBarry Smith     ierr          = PetscObjectReference((PetscObject)col);CHKERRQ(ierr);
1212c38d4ed2SBarry Smith 
1213c38d4ed2SBarry Smith     /* Create the invert permutation so that it can be used in MatLUFactorNumeric() */
12144c49b128SBarry Smith     ierr = ISInvertPermutation(col,PETSC_DECIDE,&a->icol);CHKERRQ(ierr);
1215b0a32e0cSBarry Smith     PetscLogObjectParent(inA,a->icol);
1216c38d4ed2SBarry Smith 
1217c38d4ed2SBarry Smith     if (!a->solve_work) {
1218b0a32e0cSBarry Smith       ierr = PetscMalloc((inA->m+a->bs)*sizeof(Scalar),&a->solve_work);CHKERRQ(ierr);
1219b0a32e0cSBarry Smith       PetscLogObjectMemory(inA,(inA->m+a->bs)*sizeof(Scalar));
1220c38d4ed2SBarry Smith     }
12212d61bbb3SSatish Balay   }
12222d61bbb3SSatish Balay 
1223667159a5SBarry Smith   ierr = MatLUFactorNumeric(inA,&outA);CHKERRQ(ierr);
1224667159a5SBarry Smith 
12252d61bbb3SSatish Balay   PetscFunctionReturn(0);
12262d61bbb3SSatish Balay }
12272d61bbb3SSatish Balay #undef __FUNC__
1228b0a32e0cSBarry Smith #define __FUNC__ "MatPrintHelp_SeqBAIJ"
1229ba4ca20aSSatish Balay int MatPrintHelp_SeqBAIJ(Mat A)
1230ba4ca20aSSatish Balay {
1231c38d4ed2SBarry Smith   static PetscTruth called = PETSC_FALSE;
1232ba4ca20aSSatish Balay   MPI_Comm          comm = A->comm;
1233d132466eSBarry Smith   int               ierr;
1234ba4ca20aSSatish Balay 
12353a40ed3dSBarry Smith   PetscFunctionBegin;
1236c38d4ed2SBarry Smith   if (called) {PetscFunctionReturn(0);} else called = PETSC_TRUE;
1237d132466eSBarry Smith   ierr = (*PetscHelpPrintf)(comm," Options for MATSEQBAIJ and MATMPIBAIJ matrix formats (the defaults):\n");CHKERRQ(ierr);
1238d132466eSBarry Smith   ierr = (*PetscHelpPrintf)(comm,"  -mat_block_size <block_size>\n");CHKERRQ(ierr);
12393a40ed3dSBarry Smith   PetscFunctionReturn(0);
1240ba4ca20aSSatish Balay }
1241d9b7c43dSSatish Balay 
1242fb2e594dSBarry Smith EXTERN_C_BEGIN
124327a8da17SBarry Smith #undef __FUNC__
1244b0a32e0cSBarry Smith #define __FUNC__ "MatSeqBAIJSetColumnIndices_SeqBAIJ"
124527a8da17SBarry Smith int MatSeqBAIJSetColumnIndices_SeqBAIJ(Mat mat,int *indices)
124627a8da17SBarry Smith {
124727a8da17SBarry Smith   Mat_SeqBAIJ *baij = (Mat_SeqBAIJ *)mat->data;
124827a8da17SBarry Smith   int         i,nz,n;
124927a8da17SBarry Smith 
125027a8da17SBarry Smith   PetscFunctionBegin;
125127a8da17SBarry Smith   nz = baij->maxnz;
1252273d9f13SBarry Smith   n  = mat->n;
125327a8da17SBarry Smith   for (i=0; i<nz; i++) {
125427a8da17SBarry Smith     baij->j[i] = indices[i];
125527a8da17SBarry Smith   }
125627a8da17SBarry Smith   baij->nz = nz;
125727a8da17SBarry Smith   for (i=0; i<n; i++) {
125827a8da17SBarry Smith     baij->ilen[i] = baij->imax[i];
125927a8da17SBarry Smith   }
126027a8da17SBarry Smith 
126127a8da17SBarry Smith   PetscFunctionReturn(0);
126227a8da17SBarry Smith }
1263fb2e594dSBarry Smith EXTERN_C_END
126427a8da17SBarry Smith 
126527a8da17SBarry Smith #undef __FUNC__
1266b0a32e0cSBarry Smith #define __FUNC__ "MatSeqBAIJSetColumnIndices"
126727a8da17SBarry Smith /*@
126827a8da17SBarry Smith     MatSeqBAIJSetColumnIndices - Set the column indices for all the rows
126927a8da17SBarry Smith        in the matrix.
127027a8da17SBarry Smith 
127127a8da17SBarry Smith   Input Parameters:
127227a8da17SBarry Smith +  mat - the SeqBAIJ matrix
127327a8da17SBarry Smith -  indices - the column indices
127427a8da17SBarry Smith 
127515091d37SBarry Smith   Level: advanced
127615091d37SBarry Smith 
127727a8da17SBarry Smith   Notes:
127827a8da17SBarry Smith     This can be called if you have precomputed the nonzero structure of the
127927a8da17SBarry Smith   matrix and want to provide it to the matrix object to improve the performance
128027a8da17SBarry Smith   of the MatSetValues() operation.
128127a8da17SBarry Smith 
128227a8da17SBarry Smith     You MUST have set the correct numbers of nonzeros per row in the call to
128327a8da17SBarry Smith   MatCreateSeqBAIJ().
128427a8da17SBarry Smith 
128527a8da17SBarry Smith     MUST be called before any calls to MatSetValues();
128627a8da17SBarry Smith 
128727a8da17SBarry Smith @*/
128827a8da17SBarry Smith int MatSeqBAIJSetColumnIndices(Mat mat,int *indices)
128927a8da17SBarry Smith {
129027a8da17SBarry Smith   int ierr,(*f)(Mat,int *);
129127a8da17SBarry Smith 
129227a8da17SBarry Smith   PetscFunctionBegin;
129327a8da17SBarry Smith   PetscValidHeaderSpecific(mat,MAT_COOKIE);
1294549d3d68SSatish Balay   ierr = PetscObjectQueryFunction((PetscObject)mat,"MatSeqBAIJSetColumnIndices_C",(void **)&f);CHKERRQ(ierr);
129527a8da17SBarry Smith   if (f) {
129627a8da17SBarry Smith     ierr = (*f)(mat,indices);CHKERRQ(ierr);
129727a8da17SBarry Smith   } else {
129829bbc08cSBarry Smith     SETERRQ(1,"Wrong type of matrix to set column indices");
129927a8da17SBarry Smith   }
130027a8da17SBarry Smith   PetscFunctionReturn(0);
130127a8da17SBarry Smith }
130227a8da17SBarry Smith 
1303273d9f13SBarry Smith #undef __FUNC__
1304273d9f13SBarry Smith #define __FUNC__ "MatGetRowMax_SeqBAIJ"
1305273d9f13SBarry Smith int MatGetRowMax_SeqBAIJ(Mat A,Vec v)
1306273d9f13SBarry Smith {
1307273d9f13SBarry Smith   Mat_SeqBAIJ  *a = (Mat_SeqBAIJ*)A->data;
1308273d9f13SBarry Smith   int          ierr,i,j,n,row,bs,*ai,*aj,mbs;
1309273d9f13SBarry Smith   PetscReal    atmp;
1310273d9f13SBarry Smith   Scalar       *x,zero = 0.0;
1311273d9f13SBarry Smith   MatScalar    *aa;
1312273d9f13SBarry Smith   int          ncols,brow,krow,kcol;
1313273d9f13SBarry Smith 
1314273d9f13SBarry Smith   PetscFunctionBegin;
1315273d9f13SBarry Smith   if (A->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1316273d9f13SBarry Smith   bs   = a->bs;
1317273d9f13SBarry Smith   aa   = a->a;
1318273d9f13SBarry Smith   ai   = a->i;
1319273d9f13SBarry Smith   aj   = a->j;
1320273d9f13SBarry Smith   mbs = a->mbs;
1321273d9f13SBarry Smith 
1322273d9f13SBarry Smith   ierr = VecSet(&zero,v);CHKERRQ(ierr);
1323273d9f13SBarry Smith   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
1324273d9f13SBarry Smith   ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr);
1325273d9f13SBarry Smith   if (n != A->m) SETERRQ(PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector");
1326273d9f13SBarry Smith   for (i=0; i<mbs; i++) {
1327273d9f13SBarry Smith     ncols = ai[1] - ai[0]; ai++;
1328273d9f13SBarry Smith     brow  = bs*i;
1329273d9f13SBarry Smith     for (j=0; j<ncols; j++){
1330273d9f13SBarry Smith       /* bcol = bs*(*aj); */
1331273d9f13SBarry Smith       for (kcol=0; kcol<bs; kcol++){
1332273d9f13SBarry Smith         for (krow=0; krow<bs; krow++){
1333273d9f13SBarry Smith           atmp = PetscAbsScalar(*aa); aa++;
1334273d9f13SBarry Smith           row = brow + krow;    /* row index */
1335273d9f13SBarry Smith           /* printf("val[%d,%d]: %g\n",row,bcol+kcol,atmp); */
1336273d9f13SBarry Smith           if (PetscAbsScalar(x[row]) < atmp) x[row] = atmp;
1337273d9f13SBarry Smith         }
1338273d9f13SBarry Smith       }
1339273d9f13SBarry Smith       aj++;
1340273d9f13SBarry Smith     }
1341273d9f13SBarry Smith   }
1342273d9f13SBarry Smith   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
1343273d9f13SBarry Smith   PetscFunctionReturn(0);
1344273d9f13SBarry Smith }
1345273d9f13SBarry Smith 
1346273d9f13SBarry Smith #undef __FUNC__
1347b0a32e0cSBarry Smith #define __FUNC__ "MatSetUpPreallocation_SeqBAIJ"
1348273d9f13SBarry Smith int MatSetUpPreallocation_SeqBAIJ(Mat A)
1349273d9f13SBarry Smith {
1350273d9f13SBarry Smith   int        ierr;
1351273d9f13SBarry Smith 
1352273d9f13SBarry Smith   PetscFunctionBegin;
1353273d9f13SBarry Smith   ierr =  MatSeqBAIJSetPreallocation(A,1,PETSC_DEFAULT,0);CHKERRQ(ierr);
1354273d9f13SBarry Smith   PetscFunctionReturn(0);
1355273d9f13SBarry Smith }
1356273d9f13SBarry Smith 
1357f2a5309cSSatish Balay #undef __FUNC__
1358f2a5309cSSatish Balay #define __FUNC__ "MatGetArray_SeqBAIJ"
1359f2a5309cSSatish Balay int MatGetArray_SeqBAIJ(Mat A,Scalar **array)
1360f2a5309cSSatish Balay {
1361f2a5309cSSatish Balay   Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)A->data;
1362f2a5309cSSatish Balay   PetscFunctionBegin;
1363f2a5309cSSatish Balay   *array = a->a;
1364f2a5309cSSatish Balay   PetscFunctionReturn(0);
1365f2a5309cSSatish Balay }
1366f2a5309cSSatish Balay 
1367f2a5309cSSatish Balay #undef __FUNC__
1368f2a5309cSSatish Balay #define __FUNC__ "MatRestoreArray_SeqBAIJ"
1369f2a5309cSSatish Balay int MatRestoreArray_SeqBAIJ(Mat A,Scalar **array)
1370f2a5309cSSatish Balay {
1371f2a5309cSSatish Balay   PetscFunctionBegin;
1372f2a5309cSSatish Balay   PetscFunctionReturn(0);
1373f2a5309cSSatish Balay }
1374f2a5309cSSatish Balay 
13752593348eSBarry Smith /* -------------------------------------------------------------------*/
1376cc2dc46cSBarry Smith static struct _MatOps MatOps_Values = {MatSetValues_SeqBAIJ,
1377cc2dc46cSBarry Smith        MatGetRow_SeqBAIJ,
1378cc2dc46cSBarry Smith        MatRestoreRow_SeqBAIJ,
1379cc2dc46cSBarry Smith        MatMult_SeqBAIJ_N,
1380cc2dc46cSBarry Smith        MatMultAdd_SeqBAIJ_N,
13817c922b88SBarry Smith        MatMultTranspose_SeqBAIJ,
13827c922b88SBarry Smith        MatMultTransposeAdd_SeqBAIJ,
1383cc2dc46cSBarry Smith        MatSolve_SeqBAIJ_N,
1384cc2dc46cSBarry Smith        0,
1385cc2dc46cSBarry Smith        0,
1386cc2dc46cSBarry Smith        0,
1387cc2dc46cSBarry Smith        MatLUFactor_SeqBAIJ,
1388cc2dc46cSBarry Smith        0,
1389b6490206SBarry Smith        0,
1390f2501298SSatish Balay        MatTranspose_SeqBAIJ,
1391cc2dc46cSBarry Smith        MatGetInfo_SeqBAIJ,
1392cc2dc46cSBarry Smith        MatEqual_SeqBAIJ,
1393cc2dc46cSBarry Smith        MatGetDiagonal_SeqBAIJ,
1394cc2dc46cSBarry Smith        MatDiagonalScale_SeqBAIJ,
1395cc2dc46cSBarry Smith        MatNorm_SeqBAIJ,
1396b6490206SBarry Smith        0,
1397cc2dc46cSBarry Smith        MatAssemblyEnd_SeqBAIJ,
1398cc2dc46cSBarry Smith        0,
1399cc2dc46cSBarry Smith        MatSetOption_SeqBAIJ,
1400cc2dc46cSBarry Smith        MatZeroEntries_SeqBAIJ,
1401cc2dc46cSBarry Smith        MatZeroRows_SeqBAIJ,
1402cc2dc46cSBarry Smith        MatLUFactorSymbolic_SeqBAIJ,
1403cc2dc46cSBarry Smith        MatLUFactorNumeric_SeqBAIJ_N,
1404cc2dc46cSBarry Smith        0,
1405cc2dc46cSBarry Smith        0,
1406273d9f13SBarry Smith        MatSetUpPreallocation_SeqBAIJ,
1407273d9f13SBarry Smith        0,
1408cc2dc46cSBarry Smith        MatGetOwnershipRange_SeqBAIJ,
1409cc2dc46cSBarry Smith        MatILUFactorSymbolic_SeqBAIJ,
1410cc2dc46cSBarry Smith        0,
1411f2a5309cSSatish Balay        MatGetArray_SeqBAIJ,
1412f2a5309cSSatish Balay        MatRestoreArray_SeqBAIJ,
14132e8a6d31SBarry Smith        MatDuplicate_SeqBAIJ,
1414cc2dc46cSBarry Smith        0,
1415cc2dc46cSBarry Smith        0,
1416cc2dc46cSBarry Smith        MatILUFactor_SeqBAIJ,
1417cc2dc46cSBarry Smith        0,
1418cc2dc46cSBarry Smith        0,
1419cc2dc46cSBarry Smith        MatGetSubMatrices_SeqBAIJ,
1420cc2dc46cSBarry Smith        MatIncreaseOverlap_SeqBAIJ,
1421cc2dc46cSBarry Smith        MatGetValues_SeqBAIJ,
1422cc2dc46cSBarry Smith        0,
1423cc2dc46cSBarry Smith        MatPrintHelp_SeqBAIJ,
1424cc2dc46cSBarry Smith        MatScale_SeqBAIJ,
1425cc2dc46cSBarry Smith        0,
1426cc2dc46cSBarry Smith        0,
1427cc2dc46cSBarry Smith        0,
1428cc2dc46cSBarry Smith        MatGetBlockSize_SeqBAIJ,
14293b2fbd54SBarry Smith        MatGetRowIJ_SeqBAIJ,
143092c4ed94SBarry Smith        MatRestoreRowIJ_SeqBAIJ,
1431cc2dc46cSBarry Smith        0,
1432cc2dc46cSBarry Smith        0,
1433cc2dc46cSBarry Smith        0,
1434cc2dc46cSBarry Smith        0,
1435cc2dc46cSBarry Smith        0,
1436cc2dc46cSBarry Smith        0,
1437d3825aa8SBarry Smith        MatSetValuesBlocked_SeqBAIJ,
1438cc2dc46cSBarry Smith        MatGetSubMatrix_SeqBAIJ,
1439b9b97703SBarry Smith        MatDestroy_SeqBAIJ,
1440b9b97703SBarry Smith        MatView_SeqBAIJ,
1441273d9f13SBarry Smith        MatGetMaps_Petsc,
1442273d9f13SBarry Smith        0,
1443273d9f13SBarry Smith        0,
1444273d9f13SBarry Smith        0,
1445273d9f13SBarry Smith        0,
1446273d9f13SBarry Smith        0,
1447273d9f13SBarry Smith        0,
1448273d9f13SBarry Smith        MatGetRowMax_SeqBAIJ,
1449273d9f13SBarry Smith        MatConvert_Basic};
14502593348eSBarry Smith 
14513e90b805SBarry Smith EXTERN_C_BEGIN
14523e90b805SBarry Smith #undef __FUNC__
1453b0a32e0cSBarry Smith #define __FUNC__ "MatStoreValues_SeqBAIJ"
14543e90b805SBarry Smith int MatStoreValues_SeqBAIJ(Mat mat)
14553e90b805SBarry Smith {
14563e90b805SBarry Smith   Mat_SeqBAIJ *aij = (Mat_SeqBAIJ *)mat->data;
1457273d9f13SBarry Smith   int         nz = aij->i[mat->m]*aij->bs*aij->bs2;
1458d132466eSBarry Smith   int         ierr;
14593e90b805SBarry Smith 
14603e90b805SBarry Smith   PetscFunctionBegin;
14613e90b805SBarry Smith   if (aij->nonew != 1) {
146229bbc08cSBarry Smith     SETERRQ(1,"Must call MatSetOption(A,MAT_NO_NEW_NONZERO_LOCATIONS);first");
14633e90b805SBarry Smith   }
14643e90b805SBarry Smith 
14653e90b805SBarry Smith   /* allocate space for values if not already there */
14663e90b805SBarry Smith   if (!aij->saved_values) {
1467f2a5309cSSatish Balay     ierr = PetscMalloc((nz+1)*sizeof(Scalar),&aij->saved_values);CHKERRQ(ierr);
14683e90b805SBarry Smith   }
14693e90b805SBarry Smith 
14703e90b805SBarry Smith   /* copy values over */
1471d132466eSBarry Smith   ierr = PetscMemcpy(aij->saved_values,aij->a,nz*sizeof(Scalar));CHKERRQ(ierr);
14723e90b805SBarry Smith   PetscFunctionReturn(0);
14733e90b805SBarry Smith }
14743e90b805SBarry Smith EXTERN_C_END
14753e90b805SBarry Smith 
14763e90b805SBarry Smith EXTERN_C_BEGIN
14773e90b805SBarry Smith #undef __FUNC__
1478b0a32e0cSBarry Smith #define __FUNC__ "MatRetrieveValues_SeqBAIJ"
147932e87ba3SBarry Smith int MatRetrieveValues_SeqBAIJ(Mat mat)
14803e90b805SBarry Smith {
14813e90b805SBarry Smith   Mat_SeqBAIJ *aij = (Mat_SeqBAIJ *)mat->data;
1482273d9f13SBarry Smith   int         nz = aij->i[mat->m]*aij->bs*aij->bs2,ierr;
14833e90b805SBarry Smith 
14843e90b805SBarry Smith   PetscFunctionBegin;
14853e90b805SBarry Smith   if (aij->nonew != 1) {
148629bbc08cSBarry Smith     SETERRQ(1,"Must call MatSetOption(A,MAT_NO_NEW_NONZERO_LOCATIONS);first");
14873e90b805SBarry Smith   }
14883e90b805SBarry Smith   if (!aij->saved_values) {
148929bbc08cSBarry Smith     SETERRQ(1,"Must call MatStoreValues(A);first");
14903e90b805SBarry Smith   }
14913e90b805SBarry Smith 
14923e90b805SBarry Smith   /* copy values over */
1493549d3d68SSatish Balay   ierr = PetscMemcpy(aij->a,aij->saved_values,nz*sizeof(Scalar));CHKERRQ(ierr);
14943e90b805SBarry Smith   PetscFunctionReturn(0);
14953e90b805SBarry Smith }
14963e90b805SBarry Smith EXTERN_C_END
14973e90b805SBarry Smith 
1498273d9f13SBarry Smith EXTERN_C_BEGIN
1499273d9f13SBarry Smith extern int MatConvert_SeqBAIJ_SeqAIJ(Mat,MatType,Mat*);
1500273d9f13SBarry Smith EXTERN_C_END
1501273d9f13SBarry Smith 
1502273d9f13SBarry Smith EXTERN_C_BEGIN
15035615d1e5SSatish Balay #undef __FUNC__
1504b0a32e0cSBarry Smith #define __FUNC__ "MatCreate_SeqBAIJ"
1505273d9f13SBarry Smith int MatCreate_SeqBAIJ(Mat B)
15062593348eSBarry Smith {
1507273d9f13SBarry Smith   int         ierr,size;
1508b6490206SBarry Smith   Mat_SeqBAIJ *b;
15093b2fbd54SBarry Smith 
15103a40ed3dSBarry Smith   PetscFunctionBegin;
1511273d9f13SBarry Smith   ierr = MPI_Comm_size(B->comm,&size);CHKERRQ(ierr);
151229bbc08cSBarry Smith   if (size > 1) SETERRQ(PETSC_ERR_ARG_WRONG,"Comm must be of size 1");
1513b6490206SBarry Smith 
1514273d9f13SBarry Smith   B->m = B->M = PetscMax(B->m,B->M);
1515273d9f13SBarry Smith   B->n = B->N = PetscMax(B->n,B->N);
1516b0a32e0cSBarry Smith   ierr    = PetscNew(Mat_SeqBAIJ,&b);CHKERRQ(ierr);
1517b0a32e0cSBarry Smith   B->data = (void*)b;
1518549d3d68SSatish Balay   ierr    = PetscMemzero(b,sizeof(Mat_SeqBAIJ));CHKERRQ(ierr);
1519549d3d68SSatish Balay   ierr    = PetscMemcpy(B->ops,&MatOps_Values,sizeof(struct _MatOps));CHKERRQ(ierr);
15202593348eSBarry Smith   B->factor           = 0;
15212593348eSBarry Smith   B->lupivotthreshold = 1.0;
152290f02eecSBarry Smith   B->mapping          = 0;
15232593348eSBarry Smith   b->row              = 0;
15242593348eSBarry Smith   b->col              = 0;
1525e51c0b9cSSatish Balay   b->icol             = 0;
15262593348eSBarry Smith   b->reallocs         = 0;
15273e90b805SBarry Smith   b->saved_values     = 0;
1528cfce73b9SSatish Balay #if defined(PETSC_USE_MAT_SINGLE)
1529563b5814SBarry Smith   b->setvalueslen     = 0;
1530563b5814SBarry Smith   b->setvaluescopy    = PETSC_NULL;
1531563b5814SBarry Smith #endif
15322593348eSBarry Smith 
1533273d9f13SBarry Smith   ierr = MapCreateMPI(B->comm,B->m,B->m,&B->rmap);CHKERRQ(ierr);
1534273d9f13SBarry Smith   ierr = MapCreateMPI(B->comm,B->n,B->n,&B->cmap);CHKERRQ(ierr);
1535a5ae1ecdSBarry Smith 
1536c4992f7dSBarry Smith   b->sorted           = PETSC_FALSE;
1537c4992f7dSBarry Smith   b->roworiented      = PETSC_TRUE;
15382593348eSBarry Smith   b->nonew            = 0;
15392593348eSBarry Smith   b->diag             = 0;
15402593348eSBarry Smith   b->solve_work       = 0;
1541de6a44a3SBarry Smith   b->mult_work        = 0;
15422593348eSBarry Smith   b->spptr            = 0;
15430e6d2581SBarry Smith   B->info.nz_unneeded = (PetscReal)b->maxnz;
1544883fce79SBarry Smith   b->keepzeroedrows   = PETSC_FALSE;
15454e220ebcSLois Curfman McInnes 
1546f1af5d2fSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatStoreValues_C",
15473e90b805SBarry Smith                                      "MatStoreValues_SeqBAIJ",
1548bc4b532fSSatish Balay                                       MatStoreValues_SeqBAIJ);CHKERRQ(ierr);
1549f1af5d2fSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatRetrieveValues_C",
15503e90b805SBarry Smith                                      "MatRetrieveValues_SeqBAIJ",
1551bc4b532fSSatish Balay                                       MatRetrieveValues_SeqBAIJ);CHKERRQ(ierr);
1552f1af5d2fSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatSeqBAIJSetColumnIndices_C",
155327a8da17SBarry Smith                                      "MatSeqBAIJSetColumnIndices_SeqBAIJ",
1554bc4b532fSSatish Balay                                       MatSeqBAIJSetColumnIndices_SeqBAIJ);CHKERRQ(ierr);
1555273d9f13SBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatConvert_SeqBAIJ_SeqAIJ_C",
1556273d9f13SBarry Smith                                      "MatConvert_SeqBAIJ_SeqAIJ",
1557273d9f13SBarry Smith                                       MatConvert_SeqBAIJ_SeqAIJ);CHKERRQ(ierr);
15583a40ed3dSBarry Smith   PetscFunctionReturn(0);
15592593348eSBarry Smith }
1560273d9f13SBarry Smith EXTERN_C_END
15612593348eSBarry Smith 
15625615d1e5SSatish Balay #undef __FUNC__
1563b0a32e0cSBarry Smith #define __FUNC__ "MatDuplicate_SeqBAIJ"
15642e8a6d31SBarry Smith int MatDuplicate_SeqBAIJ(Mat A,MatDuplicateOption cpvalues,Mat *B)
15652593348eSBarry Smith {
15662593348eSBarry Smith   Mat         C;
1567b6490206SBarry Smith   Mat_SeqBAIJ *c,*a = (Mat_SeqBAIJ*)A->data;
156827a8da17SBarry Smith   int         i,len,mbs = a->mbs,nz = a->nz,bs2 =a->bs2,ierr;
1569de6a44a3SBarry Smith 
15703a40ed3dSBarry Smith   PetscFunctionBegin;
157129bbc08cSBarry Smith   if (a->i[mbs] != nz) SETERRQ(PETSC_ERR_PLIB,"Corrupt matrix");
15722593348eSBarry Smith 
15732593348eSBarry Smith   *B = 0;
1574273d9f13SBarry Smith   ierr = MatCreate(A->comm,A->m,A->n,A->m,A->n,&C);CHKERRQ(ierr);
1575273d9f13SBarry Smith   ierr = MatSetType(C,MATSEQBAIJ);CHKERRQ(ierr);
1576273d9f13SBarry Smith   c    = (Mat_SeqBAIJ*)C->data;
157744cd7ae7SLois Curfman McInnes 
1578b6490206SBarry Smith   c->bs         = a->bs;
15799df24120SSatish Balay   c->bs2        = a->bs2;
1580b6490206SBarry Smith   c->mbs        = a->mbs;
1581b6490206SBarry Smith   c->nbs        = a->nbs;
158235d8aa7fSBarry Smith   ierr = PetscMemcpy(C->ops,A->ops,sizeof(struct _MatOps));CHKERRQ(ierr);
15832593348eSBarry Smith 
1584b0a32e0cSBarry Smith   ierr = PetscMalloc((mbs+1)*sizeof(int),&c->imax);CHKERRQ(ierr);
1585b0a32e0cSBarry Smith   ierr = PetscMalloc((mbs+1)*sizeof(int),&c->ilen);CHKERRQ(ierr);
1586b6490206SBarry Smith   for (i=0; i<mbs; i++) {
15872593348eSBarry Smith     c->imax[i] = a->imax[i];
15882593348eSBarry Smith     c->ilen[i] = a->ilen[i];
15892593348eSBarry Smith   }
15902593348eSBarry Smith 
15912593348eSBarry Smith   /* allocate the matrix space */
1592c4992f7dSBarry Smith   c->singlemalloc = PETSC_TRUE;
15933f1db9ecSBarry Smith   len  = (mbs+1)*sizeof(int) + nz*(bs2*sizeof(MatScalar) + sizeof(int));
1594b0a32e0cSBarry Smith   ierr = PetscMalloc(len,&c->a);CHKERRQ(ierr);
15957e67e3f9SSatish Balay   c->j = (int*)(c->a + nz*bs2);
1596de6a44a3SBarry Smith   c->i = c->j + nz;
1597549d3d68SSatish Balay   ierr = PetscMemcpy(c->i,a->i,(mbs+1)*sizeof(int));CHKERRQ(ierr);
1598b6490206SBarry Smith   if (mbs > 0) {
1599549d3d68SSatish Balay     ierr = PetscMemcpy(c->j,a->j,nz*sizeof(int));CHKERRQ(ierr);
16002e8a6d31SBarry Smith     if (cpvalues == MAT_COPY_VALUES) {
1601549d3d68SSatish Balay       ierr = PetscMemcpy(c->a,a->a,bs2*nz*sizeof(MatScalar));CHKERRQ(ierr);
16022e8a6d31SBarry Smith     } else {
1603549d3d68SSatish Balay       ierr = PetscMemzero(c->a,bs2*nz*sizeof(MatScalar));CHKERRQ(ierr);
16042593348eSBarry Smith     }
16052593348eSBarry Smith   }
16062593348eSBarry Smith 
1607b0a32e0cSBarry Smith   PetscLogObjectMemory(C,len+2*(mbs+1)*sizeof(int)+sizeof(struct _p_Mat)+sizeof(Mat_SeqBAIJ));
16082593348eSBarry Smith   c->sorted      = a->sorted;
16092593348eSBarry Smith   c->roworiented = a->roworiented;
16102593348eSBarry Smith   c->nonew       = a->nonew;
16112593348eSBarry Smith 
16122593348eSBarry Smith   if (a->diag) {
1613b0a32e0cSBarry Smith     ierr = PetscMalloc((mbs+1)*sizeof(int),&c->diag);CHKERRQ(ierr);
1614b0a32e0cSBarry Smith     PetscLogObjectMemory(C,(mbs+1)*sizeof(int));
1615b6490206SBarry Smith     for (i=0; i<mbs; i++) {
16162593348eSBarry Smith       c->diag[i] = a->diag[i];
16172593348eSBarry Smith     }
161898305bb5SBarry Smith   } else c->diag        = 0;
16192593348eSBarry Smith   c->nz                 = a->nz;
16202593348eSBarry Smith   c->maxnz              = a->maxnz;
16212593348eSBarry Smith   c->solve_work         = 0;
16222593348eSBarry Smith   c->spptr              = 0;      /* Dangerous -I'm throwing away a->spptr */
16237fc0212eSBarry Smith   c->mult_work          = 0;
1624273d9f13SBarry Smith   C->preallocated       = PETSC_TRUE;
1625273d9f13SBarry Smith   C->assembled          = PETSC_TRUE;
16262593348eSBarry Smith   *B = C;
1627b0a32e0cSBarry Smith   ierr = PetscFListDuplicate(A->qlist,&C->qlist);CHKERRQ(ierr);
16283a40ed3dSBarry Smith   PetscFunctionReturn(0);
16292593348eSBarry Smith }
16302593348eSBarry Smith 
1631273d9f13SBarry Smith EXTERN_C_BEGIN
16325615d1e5SSatish Balay #undef __FUNC__
1633b0a32e0cSBarry Smith #define __FUNC__ "MatLoad_SeqBAIJ"
1634b0a32e0cSBarry Smith int MatLoad_SeqBAIJ(PetscViewer viewer,MatType type,Mat *A)
16352593348eSBarry Smith {
1636b6490206SBarry Smith   Mat_SeqBAIJ  *a;
16372593348eSBarry Smith   Mat          B;
1638f1af5d2fSBarry Smith   int          i,nz,ierr,fd,header[4],size,*rowlengths=0,M,N,bs=1;
1639b6490206SBarry Smith   int          *mask,mbs,*jj,j,rowcount,nzcount,k,*browlengths,maskcount;
164035aab85fSBarry Smith   int          kmax,jcount,block,idx,point,nzcountb,extra_rows;
1641a7c10996SSatish Balay   int          *masked,nmask,tmp,bs2,ishift;
1642b6490206SBarry Smith   Scalar       *aa;
164319bcc07fSBarry Smith   MPI_Comm     comm = ((PetscObject)viewer)->comm;
16442593348eSBarry Smith 
16453a40ed3dSBarry Smith   PetscFunctionBegin;
1646b0a32e0cSBarry Smith   ierr = PetscOptionsGetInt(PETSC_NULL,"-matload_block_size",&bs,PETSC_NULL);CHKERRQ(ierr);
1647de6a44a3SBarry Smith   bs2  = bs*bs;
1648b6490206SBarry Smith 
1649d132466eSBarry Smith   ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr);
165029bbc08cSBarry Smith   if (size > 1) SETERRQ(PETSC_ERR_ARG_WRONG,"view must have one processor");
1651b0a32e0cSBarry Smith   ierr = PetscViewerBinaryGetDescriptor(viewer,&fd);CHKERRQ(ierr);
16520752156aSBarry Smith   ierr = PetscBinaryRead(fd,header,4,PETSC_INT);CHKERRQ(ierr);
165329bbc08cSBarry Smith   if (header[0] != MAT_COOKIE) SETERRQ(PETSC_ERR_FILE_UNEXPECTED,"not Mat object");
16542593348eSBarry Smith   M = header[1]; N = header[2]; nz = header[3];
16552593348eSBarry Smith 
1656d64ed03dSBarry Smith   if (header[3] < 0) {
165729bbc08cSBarry Smith     SETERRQ(PETSC_ERR_FILE_UNEXPECTED,"Matrix stored in special format, cannot load as SeqBAIJ");
1658d64ed03dSBarry Smith   }
1659d64ed03dSBarry Smith 
166029bbc08cSBarry Smith   if (M != N) SETERRQ(PETSC_ERR_SUP,"Can only do square matrices");
166135aab85fSBarry Smith 
166235aab85fSBarry Smith   /*
166335aab85fSBarry Smith      This code adds extra rows to make sure the number of rows is
166435aab85fSBarry Smith     divisible by the blocksize
166535aab85fSBarry Smith   */
1666b6490206SBarry Smith   mbs        = M/bs;
166735aab85fSBarry Smith   extra_rows = bs - M + bs*(mbs);
166835aab85fSBarry Smith   if (extra_rows == bs) extra_rows = 0;
166935aab85fSBarry Smith   else                  mbs++;
167035aab85fSBarry Smith   if (extra_rows) {
1671b0a32e0cSBarry Smith     PetscLogInfo(0,"MatLoad_SeqBAIJ:Padding loaded matrix to match blocksize\n");
167235aab85fSBarry Smith   }
1673b6490206SBarry Smith 
16742593348eSBarry Smith   /* read in row lengths */
1675b0a32e0cSBarry Smith   ierr = PetscMalloc((M+extra_rows)*sizeof(int),&rowlengths);CHKERRQ(ierr);
16760752156aSBarry Smith   ierr = PetscBinaryRead(fd,rowlengths,M,PETSC_INT);CHKERRQ(ierr);
167735aab85fSBarry Smith   for (i=0; i<extra_rows; i++) rowlengths[M+i] = 1;
16782593348eSBarry Smith 
1679b6490206SBarry Smith   /* read in column indices */
1680b0a32e0cSBarry Smith   ierr = PetscMalloc((nz+extra_rows)*sizeof(int),&jj);CHKERRQ(ierr);
16810752156aSBarry Smith   ierr = PetscBinaryRead(fd,jj,nz,PETSC_INT);CHKERRQ(ierr);
168235aab85fSBarry Smith   for (i=0; i<extra_rows; i++) jj[nz+i] = M+i;
1683b6490206SBarry Smith 
1684b6490206SBarry Smith   /* loop over row lengths determining block row lengths */
1685b0a32e0cSBarry Smith   ierr     = PetscMalloc(mbs*sizeof(int),&browlengths);CHKERRQ(ierr);
1686549d3d68SSatish Balay   ierr     = PetscMemzero(browlengths,mbs*sizeof(int));CHKERRQ(ierr);
1687b0a32e0cSBarry Smith   ierr     = PetscMalloc(2*mbs*sizeof(int),&mask);CHKERRQ(ierr);
1688549d3d68SSatish Balay   ierr     = PetscMemzero(mask,mbs*sizeof(int));CHKERRQ(ierr);
168935aab85fSBarry Smith   masked   = mask + mbs;
1690b6490206SBarry Smith   rowcount = 0; nzcount = 0;
1691b6490206SBarry Smith   for (i=0; i<mbs; i++) {
169235aab85fSBarry Smith     nmask = 0;
1693b6490206SBarry Smith     for (j=0; j<bs; j++) {
1694b6490206SBarry Smith       kmax = rowlengths[rowcount];
1695b6490206SBarry Smith       for (k=0; k<kmax; k++) {
169635aab85fSBarry Smith         tmp = jj[nzcount++]/bs;
169735aab85fSBarry Smith         if (!mask[tmp]) {masked[nmask++] = tmp; mask[tmp] = 1;}
1698b6490206SBarry Smith       }
1699b6490206SBarry Smith       rowcount++;
1700b6490206SBarry Smith     }
170135aab85fSBarry Smith     browlengths[i] += nmask;
170235aab85fSBarry Smith     /* zero out the mask elements we set */
170335aab85fSBarry Smith     for (j=0; j<nmask; j++) mask[masked[j]] = 0;
1704b6490206SBarry Smith   }
1705b6490206SBarry Smith 
17062593348eSBarry Smith   /* create our matrix */
17073eee16b0SBarry Smith   ierr = MatCreateSeqBAIJ(comm,bs,M+extra_rows,N+extra_rows,0,browlengths,A);CHKERRQ(ierr);
17082593348eSBarry Smith   B = *A;
1709b6490206SBarry Smith   a = (Mat_SeqBAIJ*)B->data;
17102593348eSBarry Smith 
17112593348eSBarry Smith   /* set matrix "i" values */
1712de6a44a3SBarry Smith   a->i[0] = 0;
1713b6490206SBarry Smith   for (i=1; i<= mbs; i++) {
1714b6490206SBarry Smith     a->i[i]      = a->i[i-1] + browlengths[i-1];
1715b6490206SBarry Smith     a->ilen[i-1] = browlengths[i-1];
17162593348eSBarry Smith   }
1717b6490206SBarry Smith   a->nz         = 0;
1718b6490206SBarry Smith   for (i=0; i<mbs; i++) a->nz += browlengths[i];
17192593348eSBarry Smith 
1720b6490206SBarry Smith   /* read in nonzero values */
1721b0a32e0cSBarry Smith   ierr = PetscMalloc((nz+extra_rows)*sizeof(Scalar),&aa);CHKERRQ(ierr);
17220752156aSBarry Smith   ierr = PetscBinaryRead(fd,aa,nz,PETSC_SCALAR);CHKERRQ(ierr);
172335aab85fSBarry Smith   for (i=0; i<extra_rows; i++) aa[nz+i] = 1.0;
1724b6490206SBarry Smith 
1725b6490206SBarry Smith   /* set "a" and "j" values into matrix */
1726b6490206SBarry Smith   nzcount = 0; jcount = 0;
1727b6490206SBarry Smith   for (i=0; i<mbs; i++) {
1728b6490206SBarry Smith     nzcountb = nzcount;
172935aab85fSBarry Smith     nmask    = 0;
1730b6490206SBarry Smith     for (j=0; j<bs; j++) {
1731b6490206SBarry Smith       kmax = rowlengths[i*bs+j];
1732b6490206SBarry Smith       for (k=0; k<kmax; k++) {
173335aab85fSBarry Smith         tmp = jj[nzcount++]/bs;
173435aab85fSBarry Smith 	if (!mask[tmp]) { masked[nmask++] = tmp; mask[tmp] = 1;}
1735b6490206SBarry Smith       }
1736b6490206SBarry Smith     }
1737de6a44a3SBarry Smith     /* sort the masked values */
1738433994e6SBarry Smith     ierr = PetscSortInt(nmask,masked);CHKERRQ(ierr);
1739de6a44a3SBarry Smith 
1740b6490206SBarry Smith     /* set "j" values into matrix */
1741b6490206SBarry Smith     maskcount = 1;
174235aab85fSBarry Smith     for (j=0; j<nmask; j++) {
174335aab85fSBarry Smith       a->j[jcount++]  = masked[j];
1744de6a44a3SBarry Smith       mask[masked[j]] = maskcount++;
1745b6490206SBarry Smith     }
1746b6490206SBarry Smith     /* set "a" values into matrix */
1747de6a44a3SBarry Smith     ishift = bs2*a->i[i];
1748b6490206SBarry Smith     for (j=0; j<bs; j++) {
1749b6490206SBarry Smith       kmax = rowlengths[i*bs+j];
1750b6490206SBarry Smith       for (k=0; k<kmax; k++) {
1751de6a44a3SBarry Smith         tmp       = jj[nzcountb]/bs ;
1752de6a44a3SBarry Smith         block     = mask[tmp] - 1;
1753de6a44a3SBarry Smith         point     = jj[nzcountb] - bs*tmp;
1754de6a44a3SBarry Smith         idx       = ishift + bs2*block + j + bs*point;
1755375fe846SBarry Smith         a->a[idx] = (MatScalar)aa[nzcountb++];
1756b6490206SBarry Smith       }
1757b6490206SBarry Smith     }
175835aab85fSBarry Smith     /* zero out the mask elements we set */
175935aab85fSBarry Smith     for (j=0; j<nmask; j++) mask[masked[j]] = 0;
1760b6490206SBarry Smith   }
176129bbc08cSBarry Smith   if (jcount != a->nz) SETERRQ(PETSC_ERR_FILE_UNEXPECTED,"Bad binary matrix");
1762b6490206SBarry Smith 
1763606d414cSSatish Balay   ierr = PetscFree(rowlengths);CHKERRQ(ierr);
1764606d414cSSatish Balay   ierr = PetscFree(browlengths);CHKERRQ(ierr);
1765606d414cSSatish Balay   ierr = PetscFree(aa);CHKERRQ(ierr);
1766606d414cSSatish Balay   ierr = PetscFree(jj);CHKERRQ(ierr);
1767606d414cSSatish Balay   ierr = PetscFree(mask);CHKERRQ(ierr);
1768b6490206SBarry Smith 
1769b6490206SBarry Smith   B->assembled = PETSC_TRUE;
1770de6a44a3SBarry Smith 
17719c01be13SBarry Smith   ierr = MatView_Private(B);CHKERRQ(ierr);
17723a40ed3dSBarry Smith   PetscFunctionReturn(0);
17732593348eSBarry Smith }
1774273d9f13SBarry Smith EXTERN_C_END
17752593348eSBarry Smith 
1776273d9f13SBarry Smith #undef __FUNC__
1777b0a32e0cSBarry Smith #define __FUNC__ "MatCreateSeqBAIJ"
1778273d9f13SBarry Smith /*@C
1779273d9f13SBarry Smith    MatCreateSeqBAIJ - Creates a sparse matrix in block AIJ (block
1780273d9f13SBarry Smith    compressed row) format.  For good matrix assembly performance the
1781273d9f13SBarry Smith    user should preallocate the matrix storage by setting the parameter nz
1782273d9f13SBarry Smith    (or the array nnz).  By setting these parameters accurately, performance
1783273d9f13SBarry Smith    during matrix assembly can be increased by more than a factor of 50.
17842593348eSBarry Smith 
1785273d9f13SBarry Smith    Collective on MPI_Comm
1786273d9f13SBarry Smith 
1787273d9f13SBarry Smith    Input Parameters:
1788273d9f13SBarry Smith +  comm - MPI communicator, set to PETSC_COMM_SELF
1789273d9f13SBarry Smith .  bs - size of block
1790273d9f13SBarry Smith .  m - number of rows
1791273d9f13SBarry Smith .  n - number of columns
179235d8aa7fSBarry Smith .  nz - number of nonzero blocks  per block row (same for all rows)
179335d8aa7fSBarry Smith -  nnz - array containing the number of nonzero blocks in the various block rows
1794273d9f13SBarry Smith          (possibly different for each block row) or PETSC_NULL
1795273d9f13SBarry Smith 
1796273d9f13SBarry Smith    Output Parameter:
1797273d9f13SBarry Smith .  A - the matrix
1798273d9f13SBarry Smith 
1799273d9f13SBarry Smith    Options Database Keys:
1800273d9f13SBarry Smith .   -mat_no_unroll - uses code that does not unroll the loops in the
1801273d9f13SBarry Smith                      block calculations (much slower)
1802273d9f13SBarry Smith .    -mat_block_size - size of the blocks to use
1803273d9f13SBarry Smith 
1804273d9f13SBarry Smith    Level: intermediate
1805273d9f13SBarry Smith 
1806273d9f13SBarry Smith    Notes:
180735d8aa7fSBarry Smith    A nonzero block is any block that as 1 or more nonzeros in it
180835d8aa7fSBarry Smith 
1809273d9f13SBarry Smith    The block AIJ format is fully compatible with standard Fortran 77
1810273d9f13SBarry Smith    storage.  That is, the stored row and column indices can begin at
1811273d9f13SBarry Smith    either one (as in Fortran) or zero.  See the users' manual for details.
1812273d9f13SBarry Smith 
1813273d9f13SBarry Smith    Specify the preallocated storage with either nz or nnz (not both).
1814273d9f13SBarry Smith    Set nz=PETSC_DEFAULT and nnz=PETSC_NULL for PETSc to control dynamic memory
1815273d9f13SBarry Smith    allocation.  For additional details, see the users manual chapter on
1816273d9f13SBarry Smith    matrices.
1817273d9f13SBarry Smith 
1818273d9f13SBarry Smith .seealso: MatCreate(), MatCreateSeqAIJ(), MatSetValues(), MatCreateMPIBAIJ()
1819273d9f13SBarry Smith @*/
1820273d9f13SBarry Smith int MatCreateSeqBAIJ(MPI_Comm comm,int bs,int m,int n,int nz,int *nnz,Mat *A)
1821273d9f13SBarry Smith {
1822273d9f13SBarry Smith   int ierr;
1823273d9f13SBarry Smith 
1824273d9f13SBarry Smith   PetscFunctionBegin;
1825273d9f13SBarry Smith   ierr = MatCreate(comm,m,n,m,n,A);CHKERRQ(ierr);
1826273d9f13SBarry Smith   ierr = MatSetType(*A,MATSEQBAIJ);CHKERRQ(ierr);
1827273d9f13SBarry Smith   ierr = MatSeqBAIJSetPreallocation(*A,bs,nz,nnz);CHKERRQ(ierr);
1828273d9f13SBarry Smith   PetscFunctionReturn(0);
1829273d9f13SBarry Smith }
1830273d9f13SBarry Smith 
1831273d9f13SBarry Smith #undef __FUNC__
1832b0a32e0cSBarry Smith #define __FUNC__ "MatSeqBAIJSetPreallocation"
1833273d9f13SBarry Smith /*@C
1834273d9f13SBarry Smith    MatSeqBAIJSetPreallocation - Sets the block size and expected nonzeros
1835273d9f13SBarry Smith    per row in the matrix. For good matrix assembly performance the
1836273d9f13SBarry Smith    user should preallocate the matrix storage by setting the parameter nz
1837273d9f13SBarry Smith    (or the array nnz).  By setting these parameters accurately, performance
1838273d9f13SBarry Smith    during matrix assembly can be increased by more than a factor of 50.
1839273d9f13SBarry Smith 
1840273d9f13SBarry Smith    Collective on MPI_Comm
1841273d9f13SBarry Smith 
1842273d9f13SBarry Smith    Input Parameters:
1843273d9f13SBarry Smith +  A - the matrix
1844273d9f13SBarry Smith .  bs - size of block
1845273d9f13SBarry Smith .  nz - number of block nonzeros per block row (same for all rows)
1846273d9f13SBarry Smith -  nnz - array containing the number of block nonzeros in the various block rows
1847273d9f13SBarry Smith          (possibly different for each block row) or PETSC_NULL
1848273d9f13SBarry Smith 
1849273d9f13SBarry Smith    Options Database Keys:
1850273d9f13SBarry Smith .   -mat_no_unroll - uses code that does not unroll the loops in the
1851273d9f13SBarry Smith                      block calculations (much slower)
1852273d9f13SBarry Smith .    -mat_block_size - size of the blocks to use
1853273d9f13SBarry Smith 
1854273d9f13SBarry Smith    Level: intermediate
1855273d9f13SBarry Smith 
1856273d9f13SBarry Smith    Notes:
1857273d9f13SBarry Smith    The block AIJ format is fully compatible with standard Fortran 77
1858273d9f13SBarry Smith    storage.  That is, the stored row and column indices can begin at
1859273d9f13SBarry Smith    either one (as in Fortran) or zero.  See the users' manual for details.
1860273d9f13SBarry Smith 
1861273d9f13SBarry Smith    Specify the preallocated storage with either nz or nnz (not both).
1862273d9f13SBarry Smith    Set nz=PETSC_DEFAULT and nnz=PETSC_NULL for PETSc to control dynamic memory
1863273d9f13SBarry Smith    allocation.  For additional details, see the users manual chapter on
1864273d9f13SBarry Smith    matrices.
1865273d9f13SBarry Smith 
1866273d9f13SBarry Smith .seealso: MatCreate(), MatCreateSeqAIJ(), MatSetValues(), MatCreateMPIBAIJ()
1867273d9f13SBarry Smith @*/
1868273d9f13SBarry Smith int MatSeqBAIJSetPreallocation(Mat B,int bs,int nz,int *nnz)
1869273d9f13SBarry Smith {
1870273d9f13SBarry Smith   Mat_SeqBAIJ *b;
1871273d9f13SBarry Smith   int         i,len,ierr,mbs,nbs,bs2,newbs = bs;
1872273d9f13SBarry Smith   PetscTruth  flg;
1873273d9f13SBarry Smith 
1874273d9f13SBarry Smith   PetscFunctionBegin;
1875273d9f13SBarry Smith   ierr = PetscTypeCompare((PetscObject)B,MATSEQBAIJ,&flg);CHKERRQ(ierr);
1876273d9f13SBarry Smith   if (!flg) PetscFunctionReturn(0);
1877273d9f13SBarry Smith 
1878273d9f13SBarry Smith   B->preallocated = PETSC_TRUE;
1879b0a32e0cSBarry Smith   ierr = PetscOptionsGetInt(B->prefix,"-mat_block_size",&newbs,PETSC_NULL);CHKERRQ(ierr);
1880273d9f13SBarry Smith   if (nnz && newbs != bs) {
1881273d9f13SBarry Smith     SETERRQ(1,"Cannot change blocksize from command line if setting nnz");
1882273d9f13SBarry Smith   }
1883273d9f13SBarry Smith   bs   = newbs;
1884273d9f13SBarry Smith 
1885273d9f13SBarry Smith   mbs  = B->m/bs;
1886273d9f13SBarry Smith   nbs  = B->n/bs;
1887273d9f13SBarry Smith   bs2  = bs*bs;
1888273d9f13SBarry Smith 
1889273d9f13SBarry Smith   if (mbs*bs!=B->m || nbs*bs!=B->n) {
189035d8aa7fSBarry Smith     SETERRQ3(PETSC_ERR_ARG_SIZ,"Number rows %d, cols %d must be divisible by blocksize %d",B->m,B->n,bs);
1891273d9f13SBarry Smith   }
1892273d9f13SBarry Smith 
1893*435da068SBarry Smith   if (nz == PETSC_DEFAULT || nz == PETSC_DECIDE) nz = 5;
1894*435da068SBarry Smith   if (nz < 0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"nz cannot be less than 0: value %d",nz);
1895273d9f13SBarry Smith   if (nnz) {
1896273d9f13SBarry Smith     for (i=0; i<mbs; i++) {
1897273d9f13SBarry Smith       if (nnz[i] < 0) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"nnz cannot be less than 0: local row %d value %d",i,nnz[i]);
1898273d9f13SBarry Smith     }
1899273d9f13SBarry Smith   }
1900273d9f13SBarry Smith 
1901273d9f13SBarry Smith   b       = (Mat_SeqBAIJ*)B->data;
1902b0a32e0cSBarry Smith   ierr    = PetscOptionsHasName(PETSC_NULL,"-mat_no_unroll",&flg);CHKERRQ(ierr);
1903273d9f13SBarry Smith   if (!flg) {
1904273d9f13SBarry Smith     switch (bs) {
1905273d9f13SBarry Smith     case 1:
1906273d9f13SBarry Smith       B->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_1;
1907273d9f13SBarry Smith       B->ops->solve           = MatSolve_SeqBAIJ_1;
1908273d9f13SBarry Smith       B->ops->solvetranspose  = MatSolveTranspose_SeqBAIJ_1;
1909273d9f13SBarry Smith       B->ops->mult            = MatMult_SeqBAIJ_1;
1910273d9f13SBarry Smith       B->ops->multadd         = MatMultAdd_SeqBAIJ_1;
1911273d9f13SBarry Smith       break;
1912273d9f13SBarry Smith     case 2:
1913273d9f13SBarry Smith       B->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_2;
1914273d9f13SBarry Smith       B->ops->solve           = MatSolve_SeqBAIJ_2;
1915273d9f13SBarry Smith       B->ops->solvetranspose  = MatSolveTranspose_SeqBAIJ_2;
1916273d9f13SBarry Smith       B->ops->mult            = MatMult_SeqBAIJ_2;
1917273d9f13SBarry Smith       B->ops->multadd         = MatMultAdd_SeqBAIJ_2;
1918273d9f13SBarry Smith       break;
1919273d9f13SBarry Smith     case 3:
1920273d9f13SBarry Smith       B->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_3;
1921273d9f13SBarry Smith       B->ops->solve           = MatSolve_SeqBAIJ_3;
1922273d9f13SBarry Smith       B->ops->solvetranspose  = MatSolveTranspose_SeqBAIJ_3;
1923273d9f13SBarry Smith       B->ops->mult            = MatMult_SeqBAIJ_3;
1924273d9f13SBarry Smith       B->ops->multadd         = MatMultAdd_SeqBAIJ_3;
1925273d9f13SBarry Smith       break;
1926273d9f13SBarry Smith     case 4:
1927273d9f13SBarry Smith       B->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_4;
1928273d9f13SBarry Smith       B->ops->solve           = MatSolve_SeqBAIJ_4;
1929273d9f13SBarry Smith       B->ops->solvetranspose  = MatSolveTranspose_SeqBAIJ_4;
1930273d9f13SBarry Smith       B->ops->mult            = MatMult_SeqBAIJ_4;
1931273d9f13SBarry Smith       B->ops->multadd         = MatMultAdd_SeqBAIJ_4;
1932273d9f13SBarry Smith       break;
1933273d9f13SBarry Smith     case 5:
1934273d9f13SBarry Smith       B->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_5;
1935273d9f13SBarry Smith       B->ops->solve           = MatSolve_SeqBAIJ_5;
1936273d9f13SBarry Smith       B->ops->solvetranspose  = MatSolveTranspose_SeqBAIJ_5;
1937273d9f13SBarry Smith       B->ops->mult            = MatMult_SeqBAIJ_5;
1938273d9f13SBarry Smith       B->ops->multadd         = MatMultAdd_SeqBAIJ_5;
1939273d9f13SBarry Smith       break;
1940273d9f13SBarry Smith     case 6:
1941273d9f13SBarry Smith       B->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_6;
1942273d9f13SBarry Smith       B->ops->solve           = MatSolve_SeqBAIJ_6;
1943273d9f13SBarry Smith       B->ops->solvetranspose  = MatSolveTranspose_SeqBAIJ_6;
1944273d9f13SBarry Smith       B->ops->mult            = MatMult_SeqBAIJ_6;
1945273d9f13SBarry Smith       B->ops->multadd         = MatMultAdd_SeqBAIJ_6;
1946273d9f13SBarry Smith       break;
1947273d9f13SBarry Smith     case 7:
1948273d9f13SBarry Smith       B->ops->mult            = MatMult_SeqBAIJ_7;
1949273d9f13SBarry Smith       B->ops->solve           = MatSolve_SeqBAIJ_7;
1950273d9f13SBarry Smith       B->ops->solvetranspose  = MatSolveTranspose_SeqBAIJ_7;
1951273d9f13SBarry Smith       B->ops->multadd         = MatMultAdd_SeqBAIJ_7;
1952273d9f13SBarry Smith       break;
1953273d9f13SBarry Smith     default:
1954273d9f13SBarry Smith       B->ops->mult            = MatMult_SeqBAIJ_N;
1955273d9f13SBarry Smith       B->ops->solve           = MatSolve_SeqBAIJ_N;
1956273d9f13SBarry Smith       B->ops->multadd         = MatMultAdd_SeqBAIJ_N;
1957273d9f13SBarry Smith       break;
1958273d9f13SBarry Smith     }
1959273d9f13SBarry Smith   }
1960273d9f13SBarry Smith   b->bs      = bs;
1961273d9f13SBarry Smith   b->mbs     = mbs;
1962273d9f13SBarry Smith   b->nbs     = nbs;
1963b0a32e0cSBarry Smith   ierr = PetscMalloc((mbs+1)*sizeof(int),&b->imax);CHKERRQ(ierr);
1964273d9f13SBarry Smith   if (!nnz) {
1965*435da068SBarry Smith     if (nz == PETSC_DEFAULT || nz == PETSC_DECIDE) nz = 5;
1966273d9f13SBarry Smith     else if (nz <= 0)        nz = 1;
1967273d9f13SBarry Smith     for (i=0; i<mbs; i++) b->imax[i] = nz;
1968273d9f13SBarry Smith     nz = nz*mbs;
1969273d9f13SBarry Smith   } else {
1970273d9f13SBarry Smith     nz = 0;
1971273d9f13SBarry Smith     for (i=0; i<mbs; i++) {b->imax[i] = nnz[i]; nz += nnz[i];}
1972273d9f13SBarry Smith   }
1973273d9f13SBarry Smith 
1974273d9f13SBarry Smith   /* allocate the matrix space */
1975273d9f13SBarry Smith   len   = nz*sizeof(int) + nz*bs2*sizeof(MatScalar) + (B->m+1)*sizeof(int);
1976b0a32e0cSBarry Smith   ierr  = PetscMalloc(len,&b->a);CHKERRQ(ierr);
1977273d9f13SBarry Smith   ierr  = PetscMemzero(b->a,nz*bs2*sizeof(MatScalar));CHKERRQ(ierr);
1978273d9f13SBarry Smith   b->j  = (int*)(b->a + nz*bs2);
1979273d9f13SBarry Smith   ierr = PetscMemzero(b->j,nz*sizeof(int));CHKERRQ(ierr);
1980273d9f13SBarry Smith   b->i  = b->j + nz;
1981273d9f13SBarry Smith   b->singlemalloc = PETSC_TRUE;
1982273d9f13SBarry Smith 
1983273d9f13SBarry Smith   b->i[0] = 0;
1984273d9f13SBarry Smith   for (i=1; i<mbs+1; i++) {
1985273d9f13SBarry Smith     b->i[i] = b->i[i-1] + b->imax[i-1];
1986273d9f13SBarry Smith   }
1987273d9f13SBarry Smith 
1988273d9f13SBarry Smith   /* b->ilen will count nonzeros in each block row so far. */
198916d6aa21SSatish Balay   ierr = PetscMalloc((mbs+1)*sizeof(int),&b->ilen);CHKERRQ(ierr);
1990b0a32e0cSBarry Smith   PetscLogObjectMemory(B,len+2*(mbs+1)*sizeof(int)+sizeof(struct _p_Mat)+sizeof(Mat_SeqBAIJ));
1991273d9f13SBarry Smith   for (i=0; i<mbs; i++) { b->ilen[i] = 0;}
1992273d9f13SBarry Smith 
1993273d9f13SBarry Smith   b->bs               = bs;
1994273d9f13SBarry Smith   b->bs2              = bs2;
1995273d9f13SBarry Smith   b->mbs              = mbs;
1996273d9f13SBarry Smith   b->nz               = 0;
1997273d9f13SBarry Smith   b->maxnz            = nz*bs2;
1998273d9f13SBarry Smith   B->info.nz_unneeded = (PetscReal)b->maxnz;
1999273d9f13SBarry Smith   PetscFunctionReturn(0);
2000273d9f13SBarry Smith }
20012593348eSBarry Smith 
2002