xref: /petsc/src/mat/impls/baij/seq/baij.c (revision 3a7fca6b988f1faea172e46abdf950477dbfaf76)
1*3a7fca6bSBarry Smith /*$Id: baij.c,v 1.226 2001/05/31 22:25:50 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 */
7a2ccead7SSatish Balay #include "petscsys.h"                     /*I "petscmat.h" I*/
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 */
304a2ae208SSatish Balay #undef __FUNCT__
314a2ae208SSatish Balay #define __FUNCT__ "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 
484a2ae208SSatish Balay #undef __FUNCT__
494a2ae208SSatish Balay #define __FUNCT__ "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 
764a2ae208SSatish Balay #undef __FUNCT__
774a2ae208SSatish Balay #define __FUNCT__ "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 */
90435da068SBarry 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 
1014a2ae208SSatish Balay #undef __FUNCT__
1024a2ae208SSatish Balay #define __FUNCT__ "MatRestoreRowIJ_SeqBAIJ"
103435da068SBarry 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) {
114435da068SBarry 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 
1214a2ae208SSatish Balay #undef __FUNCT__
1224a2ae208SSatish Balay #define __FUNCT__ "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 
1334a2ae208SSatish Balay #undef __FUNCT__
1344a2ae208SSatish Balay #define __FUNCT__ "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 
1694a2ae208SSatish Balay #undef __FUNCT__
1704a2ae208SSatish Balay #define __FUNCT__ "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_YES_NEW_DIAGONALS ||
188b51ba29fSSatish Balay            op == MAT_IGNORE_OFF_PROC_ENTRIES ||
189b51ba29fSSatish Balay            op == MAT_USE_HASH_TABLE) {
190b0a32e0cSBarry Smith     PetscLogInfo(A,"MatSetOption_SeqBAIJ:Option ignored\n");
1912d61bbb3SSatish Balay   } else if (op == MAT_NO_NEW_DIAGONALS) {
19229bbc08cSBarry Smith     SETERRQ(PETSC_ERR_SUP,"MAT_NO_NEW_DIAGONALS");
1932d61bbb3SSatish Balay   } else {
19429bbc08cSBarry Smith     SETERRQ(PETSC_ERR_SUP,"unknown option");
1952d61bbb3SSatish Balay   }
1962d61bbb3SSatish Balay   PetscFunctionReturn(0);
1972d61bbb3SSatish Balay }
1982d61bbb3SSatish Balay 
1994a2ae208SSatish Balay #undef __FUNCT__
2004a2ae208SSatish Balay #define __FUNCT__ "MatGetOwnershipRange_SeqBAIJ"
2012d61bbb3SSatish Balay int MatGetOwnershipRange_SeqBAIJ(Mat A,int *m,int *n)
2022d61bbb3SSatish Balay {
2032d61bbb3SSatish Balay   PetscFunctionBegin;
2044c49b128SBarry Smith   if (m) *m = 0;
205273d9f13SBarry Smith   if (n) *n = A->m;
2062d61bbb3SSatish Balay   PetscFunctionReturn(0);
2072d61bbb3SSatish Balay }
2082d61bbb3SSatish Balay 
2094a2ae208SSatish Balay #undef __FUNCT__
2104a2ae208SSatish Balay #define __FUNCT__ "MatGetRow_SeqBAIJ"
2112d61bbb3SSatish Balay int MatGetRow_SeqBAIJ(Mat A,int row,int *nz,int **idx,Scalar **v)
2122d61bbb3SSatish Balay {
2132d61bbb3SSatish Balay   Mat_SeqBAIJ  *a = (Mat_SeqBAIJ*)A->data;
21482502324SSatish Balay   int          itmp,i,j,k,M,*ai,*aj,bs,bn,bp,*idx_i,bs2,ierr;
2153f1db9ecSBarry Smith   MatScalar    *aa,*aa_i;
2163f1db9ecSBarry Smith   Scalar       *v_i;
2172d61bbb3SSatish Balay 
2182d61bbb3SSatish Balay   PetscFunctionBegin;
2192d61bbb3SSatish Balay   bs  = a->bs;
2202d61bbb3SSatish Balay   ai  = a->i;
2212d61bbb3SSatish Balay   aj  = a->j;
2222d61bbb3SSatish Balay   aa  = a->a;
2232d61bbb3SSatish Balay   bs2 = a->bs2;
2242d61bbb3SSatish Balay 
225273d9f13SBarry Smith   if (row < 0 || row >= A->m) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Row out of range");
2262d61bbb3SSatish Balay 
2272d61bbb3SSatish Balay   bn  = row/bs;   /* Block number */
2282d61bbb3SSatish Balay   bp  = row % bs; /* Block Position */
2292d61bbb3SSatish Balay   M   = ai[bn+1] - ai[bn];
2302d61bbb3SSatish Balay   *nz = bs*M;
2312d61bbb3SSatish Balay 
2322d61bbb3SSatish Balay   if (v) {
2332d61bbb3SSatish Balay     *v = 0;
2342d61bbb3SSatish Balay     if (*nz) {
235b0a32e0cSBarry Smith       ierr = PetscMalloc((*nz)*sizeof(Scalar),v);CHKERRQ(ierr);
2362d61bbb3SSatish Balay       for (i=0; i<M; i++) { /* for each block in the block row */
2372d61bbb3SSatish Balay         v_i  = *v + i*bs;
2382d61bbb3SSatish Balay         aa_i = aa + bs2*(ai[bn] + i);
2392d61bbb3SSatish Balay         for (j=bp,k=0; j<bs2; j+=bs,k++) {v_i[k] = aa_i[j];}
2402d61bbb3SSatish Balay       }
2412d61bbb3SSatish Balay     }
2422d61bbb3SSatish Balay   }
2432d61bbb3SSatish Balay 
2442d61bbb3SSatish Balay   if (idx) {
2452d61bbb3SSatish Balay     *idx = 0;
2462d61bbb3SSatish Balay     if (*nz) {
247b0a32e0cSBarry Smith       ierr = PetscMalloc((*nz)*sizeof(int),idx);CHKERRQ(ierr);
2482d61bbb3SSatish Balay       for (i=0; i<M; i++) { /* for each block in the block row */
2492d61bbb3SSatish Balay         idx_i = *idx + i*bs;
2502d61bbb3SSatish Balay         itmp  = bs*aj[ai[bn] + i];
2512d61bbb3SSatish Balay         for (j=0; j<bs; j++) {idx_i[j] = itmp++;}
2522d61bbb3SSatish Balay       }
2532d61bbb3SSatish Balay     }
2542d61bbb3SSatish Balay   }
2552d61bbb3SSatish Balay   PetscFunctionReturn(0);
2562d61bbb3SSatish Balay }
2572d61bbb3SSatish Balay 
2584a2ae208SSatish Balay #undef __FUNCT__
2594a2ae208SSatish Balay #define __FUNCT__ "MatRestoreRow_SeqBAIJ"
2602d61bbb3SSatish Balay int MatRestoreRow_SeqBAIJ(Mat A,int row,int *nz,int **idx,Scalar **v)
2612d61bbb3SSatish Balay {
262606d414cSSatish Balay   int ierr;
263606d414cSSatish Balay 
2642d61bbb3SSatish Balay   PetscFunctionBegin;
265606d414cSSatish Balay   if (idx) {if (*idx) {ierr = PetscFree(*idx);CHKERRQ(ierr);}}
266606d414cSSatish Balay   if (v)   {if (*v)   {ierr = PetscFree(*v);CHKERRQ(ierr);}}
2672d61bbb3SSatish Balay   PetscFunctionReturn(0);
2682d61bbb3SSatish Balay }
2692d61bbb3SSatish Balay 
2704a2ae208SSatish Balay #undef __FUNCT__
2714a2ae208SSatish Balay #define __FUNCT__ "MatTranspose_SeqBAIJ"
2722d61bbb3SSatish Balay int MatTranspose_SeqBAIJ(Mat A,Mat *B)
2732d61bbb3SSatish Balay {
2742d61bbb3SSatish Balay   Mat_SeqBAIJ *a=(Mat_SeqBAIJ *)A->data;
2752d61bbb3SSatish Balay   Mat         C;
2762d61bbb3SSatish Balay   int         i,j,k,ierr,*aj=a->j,*ai=a->i,bs=a->bs,mbs=a->mbs,nbs=a->nbs,len,*col;
277273d9f13SBarry Smith   int         *rows,*cols,bs2=a->bs2;
278375fe846SBarry Smith   Scalar      *array;
2792d61bbb3SSatish Balay 
2802d61bbb3SSatish Balay   PetscFunctionBegin;
28129bbc08cSBarry Smith   if (!B && mbs!=nbs) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Square matrix only for in-place");
282b0a32e0cSBarry Smith   ierr = PetscMalloc((1+nbs)*sizeof(int),&col);CHKERRQ(ierr);
283549d3d68SSatish Balay   ierr = PetscMemzero(col,(1+nbs)*sizeof(int));CHKERRQ(ierr);
2842d61bbb3SSatish Balay 
285375fe846SBarry Smith #if defined(PETSC_USE_MAT_SINGLE)
286b0a32e0cSBarry Smith   ierr = PetscMalloc(a->bs2*a->nz*sizeof(Scalar),&array);CHKERRQ(ierr);
287375fe846SBarry Smith   for (i=0; i<a->bs2*a->nz; i++) array[i] = (Scalar)a->a[i];
288375fe846SBarry Smith #else
2893eda8832SBarry Smith   array = a->a;
290375fe846SBarry Smith #endif
291375fe846SBarry Smith 
2922d61bbb3SSatish Balay   for (i=0; i<ai[mbs]; i++) col[aj[i]] += 1;
293273d9f13SBarry Smith   ierr = MatCreateSeqBAIJ(A->comm,bs,A->n,A->m,PETSC_NULL,col,&C);CHKERRQ(ierr);
294606d414cSSatish Balay   ierr = PetscFree(col);CHKERRQ(ierr);
295b0a32e0cSBarry Smith   ierr = PetscMalloc(2*bs*sizeof(int),&rows);CHKERRQ(ierr);
2962d61bbb3SSatish Balay   cols = rows + bs;
2972d61bbb3SSatish Balay   for (i=0; i<mbs; i++) {
2982d61bbb3SSatish Balay     cols[0] = i*bs;
2992d61bbb3SSatish Balay     for (k=1; k<bs; k++) cols[k] = cols[k-1] + 1;
3002d61bbb3SSatish Balay     len = ai[i+1] - ai[i];
3012d61bbb3SSatish Balay     for (j=0; j<len; j++) {
3022d61bbb3SSatish Balay       rows[0] = (*aj++)*bs;
3032d61bbb3SSatish Balay       for (k=1; k<bs; k++) rows[k] = rows[k-1] + 1;
3042d61bbb3SSatish Balay       ierr = MatSetValues(C,bs,rows,bs,cols,array,INSERT_VALUES);CHKERRQ(ierr);
3052d61bbb3SSatish Balay       array += bs2;
3062d61bbb3SSatish Balay     }
3072d61bbb3SSatish Balay   }
308606d414cSSatish Balay   ierr = PetscFree(rows);CHKERRQ(ierr);
309375fe846SBarry Smith #if defined(PETSC_USE_MAT_SINGLE)
310375fe846SBarry Smith   ierr = PetscFree(array);
311375fe846SBarry Smith #endif
3122d61bbb3SSatish Balay 
3132d61bbb3SSatish Balay   ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
3142d61bbb3SSatish Balay   ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
3152d61bbb3SSatish Balay 
316c4992f7dSBarry Smith   if (B) {
3172d61bbb3SSatish Balay     *B = C;
3182d61bbb3SSatish Balay   } else {
319273d9f13SBarry Smith     ierr = MatHeaderCopy(A,C);CHKERRQ(ierr);
3202d61bbb3SSatish Balay   }
3212d61bbb3SSatish Balay   PetscFunctionReturn(0);
3222d61bbb3SSatish Balay }
3232d61bbb3SSatish Balay 
3244a2ae208SSatish Balay #undef __FUNCT__
3254a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqBAIJ_Binary"
326b0a32e0cSBarry Smith static int MatView_SeqBAIJ_Binary(Mat A,PetscViewer viewer)
3272593348eSBarry Smith {
328b6490206SBarry Smith   Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)A->data;
3299df24120SSatish Balay   int         i,fd,*col_lens,ierr,bs = a->bs,count,*jj,j,k,l,bs2=a->bs2;
330b6490206SBarry Smith   Scalar      *aa;
331ce6f0cecSBarry Smith   FILE        *file;
3322593348eSBarry Smith 
3333a40ed3dSBarry Smith   PetscFunctionBegin;
334b0a32e0cSBarry Smith   ierr        = PetscViewerBinaryGetDescriptor(viewer,&fd);CHKERRQ(ierr);
335b0a32e0cSBarry Smith   ierr        = PetscMalloc((4+A->m)*sizeof(int),&col_lens);CHKERRQ(ierr);
3362593348eSBarry Smith   col_lens[0] = MAT_COOKIE;
3373b2fbd54SBarry Smith 
338273d9f13SBarry Smith   col_lens[1] = A->m;
339273d9f13SBarry Smith   col_lens[2] = A->n;
3407e67e3f9SSatish Balay   col_lens[3] = a->nz*bs2;
3412593348eSBarry Smith 
3422593348eSBarry Smith   /* store lengths of each row and write (including header) to file */
343b6490206SBarry Smith   count = 0;
344b6490206SBarry Smith   for (i=0; i<a->mbs; i++) {
345b6490206SBarry Smith     for (j=0; j<bs; j++) {
346b6490206SBarry Smith       col_lens[4+count++] = bs*(a->i[i+1] - a->i[i]);
347b6490206SBarry Smith     }
3482593348eSBarry Smith   }
349273d9f13SBarry Smith   ierr = PetscBinaryWrite(fd,col_lens,4+A->m,PETSC_INT,1);CHKERRQ(ierr);
350606d414cSSatish Balay   ierr = PetscFree(col_lens);CHKERRQ(ierr);
3512593348eSBarry Smith 
3522593348eSBarry Smith   /* store column indices (zero start index) */
353b0a32e0cSBarry Smith   ierr  = PetscMalloc((a->nz+1)*bs2*sizeof(int),&jj);CHKERRQ(ierr);
354b6490206SBarry Smith   count = 0;
355b6490206SBarry Smith   for (i=0; i<a->mbs; i++) {
356b6490206SBarry Smith     for (j=0; j<bs; j++) {
357b6490206SBarry Smith       for (k=a->i[i]; k<a->i[i+1]; k++) {
358b6490206SBarry Smith         for (l=0; l<bs; l++) {
359b6490206SBarry Smith           jj[count++] = bs*a->j[k] + l;
3602593348eSBarry Smith         }
3612593348eSBarry Smith       }
362b6490206SBarry Smith     }
363b6490206SBarry Smith   }
3640752156aSBarry Smith   ierr = PetscBinaryWrite(fd,jj,bs2*a->nz,PETSC_INT,0);CHKERRQ(ierr);
365606d414cSSatish Balay   ierr = PetscFree(jj);CHKERRQ(ierr);
3662593348eSBarry Smith 
3672593348eSBarry Smith   /* store nonzero values */
368b0a32e0cSBarry Smith   ierr  = PetscMalloc((a->nz+1)*bs2*sizeof(Scalar),&aa);CHKERRQ(ierr);
369b6490206SBarry Smith   count = 0;
370b6490206SBarry Smith   for (i=0; i<a->mbs; i++) {
371b6490206SBarry Smith     for (j=0; j<bs; j++) {
372b6490206SBarry Smith       for (k=a->i[i]; k<a->i[i+1]; k++) {
373b6490206SBarry Smith         for (l=0; l<bs; l++) {
3747e67e3f9SSatish Balay           aa[count++] = a->a[bs2*k + l*bs + j];
375b6490206SBarry Smith         }
376b6490206SBarry Smith       }
377b6490206SBarry Smith     }
378b6490206SBarry Smith   }
3790752156aSBarry Smith   ierr = PetscBinaryWrite(fd,aa,bs2*a->nz,PETSC_SCALAR,0);CHKERRQ(ierr);
380606d414cSSatish Balay   ierr = PetscFree(aa);CHKERRQ(ierr);
381ce6f0cecSBarry Smith 
382b0a32e0cSBarry Smith   ierr = PetscViewerBinaryGetInfoPointer(viewer,&file);CHKERRQ(ierr);
383ce6f0cecSBarry Smith   if (file) {
384ce6f0cecSBarry Smith     fprintf(file,"-matload_block_size %d\n",a->bs);
385ce6f0cecSBarry Smith   }
3863a40ed3dSBarry Smith   PetscFunctionReturn(0);
3872593348eSBarry Smith }
3882593348eSBarry Smith 
3894a2ae208SSatish Balay #undef __FUNCT__
3904a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqBAIJ_ASCII"
391b0a32e0cSBarry Smith static int MatView_SeqBAIJ_ASCII(Mat A,PetscViewer viewer)
3922593348eSBarry Smith {
393b6490206SBarry Smith   Mat_SeqBAIJ       *a = (Mat_SeqBAIJ*)A->data;
394fb9695e5SSatish Balay   int               ierr,i,j,bs = a->bs,k,l,bs2=a->bs2;
395f3ef73ceSBarry Smith   PetscViewerFormat format;
3962593348eSBarry Smith 
3973a40ed3dSBarry Smith   PetscFunctionBegin;
398b0a32e0cSBarry Smith   ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr);
399fb9695e5SSatish Balay   if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_LONG) {
400b0a32e0cSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  block size is %d\n",bs);CHKERRQ(ierr);
401fb9695e5SSatish Balay   } else if (format == PETSC_VIEWER_ASCII_MATLAB) {
40229bbc08cSBarry Smith     SETERRQ(PETSC_ERR_SUP,"Matlab format not supported");
403fb9695e5SSatish Balay   } else if (format == PETSC_VIEWER_ASCII_COMMON) {
404b0a32e0cSBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_NO);CHKERRQ(ierr);
40544cd7ae7SLois Curfman McInnes     for (i=0; i<a->mbs; i++) {
40644cd7ae7SLois Curfman McInnes       for (j=0; j<bs; j++) {
407b0a32e0cSBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"row %d:",i*bs+j);CHKERRQ(ierr);
40844cd7ae7SLois Curfman McInnes         for (k=a->i[i]; k<a->i[i+1]; k++) {
40944cd7ae7SLois Curfman McInnes           for (l=0; l<bs; l++) {
410aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
4110e6d2581SBarry Smith             if (PetscImaginaryPart(a->a[bs2*k + l*bs + j]) > 0.0 && PetscRealPart(a->a[bs2*k + l*bs + j]) != 0.0) {
412b0a32e0cSBarry Smith               ierr = PetscViewerASCIIPrintf(viewer," %d %g + %gi",bs*a->j[k]+l,
4130e6d2581SBarry Smith                       PetscRealPart(a->a[bs2*k + l*bs + j]),PetscImaginaryPart(a->a[bs2*k + l*bs + j]));CHKERRQ(ierr);
4140e6d2581SBarry Smith             } else if (PetscImaginaryPart(a->a[bs2*k + l*bs + j]) < 0.0 && PetscRealPart(a->a[bs2*k + l*bs + j]) != 0.0) {
415b0a32e0cSBarry Smith               ierr = PetscViewerASCIIPrintf(viewer," %d %g - %gi",bs*a->j[k]+l,
4160e6d2581SBarry Smith                       PetscRealPart(a->a[bs2*k + l*bs + j]),-PetscImaginaryPart(a->a[bs2*k + l*bs + j]));CHKERRQ(ierr);
4170e6d2581SBarry Smith             } else if (PetscRealPart(a->a[bs2*k + l*bs + j]) != 0.0) {
418b0a32e0cSBarry Smith               ierr = PetscViewerASCIIPrintf(viewer," %d %g ",bs*a->j[k]+l,PetscRealPart(a->a[bs2*k + l*bs + j]));CHKERRQ(ierr);
4190ef38995SBarry Smith             }
42044cd7ae7SLois Curfman McInnes #else
4210ef38995SBarry Smith             if (a->a[bs2*k + l*bs + j] != 0.0) {
422b0a32e0cSBarry Smith               ierr = PetscViewerASCIIPrintf(viewer," %d %g ",bs*a->j[k]+l,a->a[bs2*k + l*bs + j]);CHKERRQ(ierr);
4230ef38995SBarry Smith             }
42444cd7ae7SLois Curfman McInnes #endif
42544cd7ae7SLois Curfman McInnes           }
42644cd7ae7SLois Curfman McInnes         }
427b0a32e0cSBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
42844cd7ae7SLois Curfman McInnes       }
42944cd7ae7SLois Curfman McInnes     }
430b0a32e0cSBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_YES);CHKERRQ(ierr);
4310ef38995SBarry Smith   } else {
432b0a32e0cSBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_NO);CHKERRQ(ierr);
433b6490206SBarry Smith     for (i=0; i<a->mbs; i++) {
434b6490206SBarry Smith       for (j=0; j<bs; j++) {
435b0a32e0cSBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"row %d:",i*bs+j);CHKERRQ(ierr);
436b6490206SBarry Smith         for (k=a->i[i]; k<a->i[i+1]; k++) {
437b6490206SBarry Smith           for (l=0; l<bs; l++) {
438aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
4390e6d2581SBarry Smith             if (PetscImaginaryPart(a->a[bs2*k + l*bs + j]) > 0.0) {
440b0a32e0cSBarry Smith               ierr = PetscViewerASCIIPrintf(viewer," %d %g + %g i",bs*a->j[k]+l,
4410e6d2581SBarry Smith                 PetscRealPart(a->a[bs2*k + l*bs + j]),PetscImaginaryPart(a->a[bs2*k + l*bs + j]));CHKERRQ(ierr);
4420e6d2581SBarry Smith             } else if (PetscImaginaryPart(a->a[bs2*k + l*bs + j]) < 0.0) {
443b0a32e0cSBarry Smith               ierr = PetscViewerASCIIPrintf(viewer," %d %g - %g i",bs*a->j[k]+l,
4440e6d2581SBarry Smith                 PetscRealPart(a->a[bs2*k + l*bs + j]),-PetscImaginaryPart(a->a[bs2*k + l*bs + j]));CHKERRQ(ierr);
4450ef38995SBarry Smith             } else {
446b0a32e0cSBarry Smith               ierr = PetscViewerASCIIPrintf(viewer," %d %g ",bs*a->j[k]+l,PetscRealPart(a->a[bs2*k + l*bs + j]));CHKERRQ(ierr);
44788685aaeSLois Curfman McInnes             }
44888685aaeSLois Curfman McInnes #else
449b0a32e0cSBarry Smith             ierr = PetscViewerASCIIPrintf(viewer," %d %g ",bs*a->j[k]+l,a->a[bs2*k + l*bs + j]);CHKERRQ(ierr);
45088685aaeSLois Curfman McInnes #endif
4512593348eSBarry Smith           }
4522593348eSBarry Smith         }
453b0a32e0cSBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
4542593348eSBarry Smith       }
4552593348eSBarry Smith     }
456b0a32e0cSBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_YES);CHKERRQ(ierr);
457b6490206SBarry Smith   }
458b0a32e0cSBarry Smith   ierr = PetscViewerFlush(viewer);CHKERRQ(ierr);
4593a40ed3dSBarry Smith   PetscFunctionReturn(0);
4602593348eSBarry Smith }
4612593348eSBarry Smith 
4624a2ae208SSatish Balay #undef __FUNCT__
4634a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqBAIJ_Draw_Zoom"
464b0a32e0cSBarry Smith static int MatView_SeqBAIJ_Draw_Zoom(PetscDraw draw,void *Aa)
4653270192aSSatish Balay {
46677ed5343SBarry Smith   Mat          A = (Mat) Aa;
4673270192aSSatish Balay   Mat_SeqBAIJ  *a=(Mat_SeqBAIJ*)A->data;
468b65db4caSBarry Smith   int          row,ierr,i,j,k,l,mbs=a->mbs,color,bs=a->bs,bs2=a->bs2;
4690e6d2581SBarry Smith   PetscReal    xl,yl,xr,yr,x_l,x_r,y_l,y_r;
4703f1db9ecSBarry Smith   MatScalar    *aa;
471b0a32e0cSBarry Smith   PetscViewer  viewer;
4723270192aSSatish Balay 
4733a40ed3dSBarry Smith   PetscFunctionBegin;
4743270192aSSatish Balay 
475b65db4caSBarry Smith   /* still need to add support for contour plot of nonzeros; see MatView_SeqAIJ_Draw_Zoom()*/
47677ed5343SBarry Smith   ierr = PetscObjectQuery((PetscObject)A,"Zoomviewer",(PetscObject*)&viewer);CHKERRQ(ierr);
47777ed5343SBarry Smith 
478b0a32e0cSBarry Smith   ierr = PetscDrawGetCoordinates(draw,&xl,&yl,&xr,&yr);CHKERRQ(ierr);
47977ed5343SBarry Smith 
4803270192aSSatish Balay   /* loop over matrix elements drawing boxes */
481b0a32e0cSBarry Smith   color = PETSC_DRAW_BLUE;
4823270192aSSatish Balay   for (i=0,row=0; i<mbs; i++,row+=bs) {
4833270192aSSatish Balay     for (j=a->i[i]; j<a->i[i+1]; j++) {
484273d9f13SBarry Smith       y_l = A->m - row - 1.0; y_r = y_l + 1.0;
4853270192aSSatish Balay       x_l = a->j[j]*bs; x_r = x_l + 1.0;
4863270192aSSatish Balay       aa = a->a + j*bs2;
4873270192aSSatish Balay       for (k=0; k<bs; k++) {
4883270192aSSatish Balay         for (l=0; l<bs; l++) {
4890e6d2581SBarry Smith           if (PetscRealPart(*aa++) >=  0.) continue;
490b0a32e0cSBarry Smith           ierr = PetscDrawRectangle(draw,x_l+k,y_l-l,x_r+k,y_r-l,color,color,color,color);CHKERRQ(ierr);
4913270192aSSatish Balay         }
4923270192aSSatish Balay       }
4933270192aSSatish Balay     }
4943270192aSSatish Balay   }
495b0a32e0cSBarry Smith   color = PETSC_DRAW_CYAN;
4963270192aSSatish Balay   for (i=0,row=0; i<mbs; i++,row+=bs) {
4973270192aSSatish Balay     for (j=a->i[i]; j<a->i[i+1]; j++) {
498273d9f13SBarry Smith       y_l = A->m - row - 1.0; y_r = y_l + 1.0;
4993270192aSSatish Balay       x_l = a->j[j]*bs; x_r = x_l + 1.0;
5003270192aSSatish Balay       aa = a->a + j*bs2;
5013270192aSSatish Balay       for (k=0; k<bs; k++) {
5023270192aSSatish Balay         for (l=0; l<bs; l++) {
5030e6d2581SBarry Smith           if (PetscRealPart(*aa++) != 0.) continue;
504b0a32e0cSBarry Smith           ierr = PetscDrawRectangle(draw,x_l+k,y_l-l,x_r+k,y_r-l,color,color,color,color);CHKERRQ(ierr);
5053270192aSSatish Balay         }
5063270192aSSatish Balay       }
5073270192aSSatish Balay     }
5083270192aSSatish Balay   }
5093270192aSSatish Balay 
510b0a32e0cSBarry Smith   color = PETSC_DRAW_RED;
5113270192aSSatish Balay   for (i=0,row=0; i<mbs; i++,row+=bs) {
5123270192aSSatish Balay     for (j=a->i[i]; j<a->i[i+1]; j++) {
513273d9f13SBarry Smith       y_l = A->m - row - 1.0; y_r = y_l + 1.0;
5143270192aSSatish Balay       x_l = a->j[j]*bs; x_r = x_l + 1.0;
5153270192aSSatish Balay       aa = a->a + j*bs2;
5163270192aSSatish Balay       for (k=0; k<bs; k++) {
5173270192aSSatish Balay         for (l=0; l<bs; l++) {
5180e6d2581SBarry Smith           if (PetscRealPart(*aa++) <= 0.) continue;
519b0a32e0cSBarry Smith           ierr = PetscDrawRectangle(draw,x_l+k,y_l-l,x_r+k,y_r-l,color,color,color,color);CHKERRQ(ierr);
5203270192aSSatish Balay         }
5213270192aSSatish Balay       }
5223270192aSSatish Balay     }
5233270192aSSatish Balay   }
52477ed5343SBarry Smith   PetscFunctionReturn(0);
52577ed5343SBarry Smith }
5263270192aSSatish Balay 
5274a2ae208SSatish Balay #undef __FUNCT__
5284a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqBAIJ_Draw"
529b0a32e0cSBarry Smith static int MatView_SeqBAIJ_Draw(Mat A,PetscViewer viewer)
53077ed5343SBarry Smith {
5317dce120fSSatish Balay   int          ierr;
5320e6d2581SBarry Smith   PetscReal    xl,yl,xr,yr,w,h;
533b0a32e0cSBarry Smith   PetscDraw    draw;
53477ed5343SBarry Smith   PetscTruth   isnull;
5353270192aSSatish Balay 
53677ed5343SBarry Smith   PetscFunctionBegin;
53777ed5343SBarry Smith 
538b0a32e0cSBarry Smith   ierr = PetscViewerDrawGetDraw(viewer,0,&draw);CHKERRQ(ierr);
539b0a32e0cSBarry Smith   ierr = PetscDrawIsNull(draw,&isnull);CHKERRQ(ierr); if (isnull) PetscFunctionReturn(0);
54077ed5343SBarry Smith 
54177ed5343SBarry Smith   ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",(PetscObject)viewer);CHKERRQ(ierr);
542273d9f13SBarry Smith   xr  = A->n; yr = A->m; h = yr/10.0; w = xr/10.0;
54377ed5343SBarry Smith   xr += w;    yr += h;  xl = -w;     yl = -h;
544b0a32e0cSBarry Smith   ierr = PetscDrawSetCoordinates(draw,xl,yl,xr,yr);CHKERRQ(ierr);
545b0a32e0cSBarry Smith   ierr = PetscDrawZoom(draw,MatView_SeqBAIJ_Draw_Zoom,A);CHKERRQ(ierr);
54677ed5343SBarry Smith   ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",PETSC_NULL);CHKERRQ(ierr);
5473a40ed3dSBarry Smith   PetscFunctionReturn(0);
5483270192aSSatish Balay }
5493270192aSSatish Balay 
5504a2ae208SSatish Balay #undef __FUNCT__
5514a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqBAIJ"
552b0a32e0cSBarry Smith int MatView_SeqBAIJ(Mat A,PetscViewer viewer)
5532593348eSBarry Smith {
55419bcc07fSBarry Smith   int        ierr;
5556831982aSBarry Smith   PetscTruth issocket,isascii,isbinary,isdraw;
5562593348eSBarry Smith 
5573a40ed3dSBarry Smith   PetscFunctionBegin;
558b0a32e0cSBarry Smith   ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_SOCKET,&issocket);CHKERRQ(ierr);
559b0a32e0cSBarry Smith   ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&isascii);CHKERRQ(ierr);
560fb9695e5SSatish Balay   ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_BINARY,&isbinary);CHKERRQ(ierr);
561fb9695e5SSatish Balay   ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_DRAW,&isdraw);CHKERRQ(ierr);
5620f5bd95cSBarry Smith   if (issocket) {
56329bbc08cSBarry Smith     SETERRQ(PETSC_ERR_SUP,"Socket viewer not supported");
5640f5bd95cSBarry Smith   } else if (isascii){
5653a40ed3dSBarry Smith     ierr = MatView_SeqBAIJ_ASCII(A,viewer);CHKERRQ(ierr);
5660f5bd95cSBarry Smith   } else if (isbinary) {
5673a40ed3dSBarry Smith     ierr = MatView_SeqBAIJ_Binary(A,viewer);CHKERRQ(ierr);
5680f5bd95cSBarry Smith   } else if (isdraw) {
5693a40ed3dSBarry Smith     ierr = MatView_SeqBAIJ_Draw(A,viewer);CHKERRQ(ierr);
5705cd90555SBarry Smith   } else {
57129bbc08cSBarry Smith     SETERRQ1(1,"Viewer type %s not supported by SeqBAIJ matrices",((PetscObject)viewer)->type_name);
5722593348eSBarry Smith   }
5733a40ed3dSBarry Smith   PetscFunctionReturn(0);
5742593348eSBarry Smith }
575b6490206SBarry Smith 
576cd0e1443SSatish Balay 
5774a2ae208SSatish Balay #undef __FUNCT__
5784a2ae208SSatish Balay #define __FUNCT__ "MatGetValues_SeqBAIJ"
5792d61bbb3SSatish Balay int MatGetValues_SeqBAIJ(Mat A,int m,int *im,int n,int *in,Scalar *v)
580cd0e1443SSatish Balay {
581cd0e1443SSatish Balay   Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)A->data;
5822d61bbb3SSatish Balay   int        *rp,k,low,high,t,row,nrow,i,col,l,*aj = a->j;
5832d61bbb3SSatish Balay   int        *ai = a->i,*ailen = a->ilen;
5842d61bbb3SSatish Balay   int        brow,bcol,ridx,cidx,bs=a->bs,bs2=a->bs2;
5853f1db9ecSBarry Smith   MatScalar  *ap,*aa = a->a,zero = 0.0;
586cd0e1443SSatish Balay 
5873a40ed3dSBarry Smith   PetscFunctionBegin;
5882d61bbb3SSatish Balay   for (k=0; k<m; k++) { /* loop over rows */
589cd0e1443SSatish Balay     row  = im[k]; brow = row/bs;
59029bbc08cSBarry Smith     if (row < 0) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Negative row");
591273d9f13SBarry Smith     if (row >= A->m) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Row too large");
5922d61bbb3SSatish Balay     rp   = aj + ai[brow] ; ap = aa + bs2*ai[brow] ;
5932c3acbe9SBarry Smith     nrow = ailen[brow];
5942d61bbb3SSatish Balay     for (l=0; l<n; l++) { /* loop over columns */
59529bbc08cSBarry Smith       if (in[l] < 0) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Negative column");
596273d9f13SBarry Smith       if (in[l] >= A->n) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Column too large");
5972d61bbb3SSatish Balay       col  = in[l] ;
5982d61bbb3SSatish Balay       bcol = col/bs;
5992d61bbb3SSatish Balay       cidx = col%bs;
6002d61bbb3SSatish Balay       ridx = row%bs;
6012d61bbb3SSatish Balay       high = nrow;
6022d61bbb3SSatish Balay       low  = 0; /* assume unsorted */
6032d61bbb3SSatish Balay       while (high-low > 5) {
604cd0e1443SSatish Balay         t = (low+high)/2;
605cd0e1443SSatish Balay         if (rp[t] > bcol) high = t;
606cd0e1443SSatish Balay         else             low  = t;
607cd0e1443SSatish Balay       }
608cd0e1443SSatish Balay       for (i=low; i<high; i++) {
609cd0e1443SSatish Balay         if (rp[i] > bcol) break;
610cd0e1443SSatish Balay         if (rp[i] == bcol) {
6112d61bbb3SSatish Balay           *v++ = ap[bs2*i+bs*cidx+ridx];
6122d61bbb3SSatish Balay           goto finished;
613cd0e1443SSatish Balay         }
614cd0e1443SSatish Balay       }
6152d61bbb3SSatish Balay       *v++ = zero;
6162d61bbb3SSatish Balay       finished:;
617cd0e1443SSatish Balay     }
618cd0e1443SSatish Balay   }
6193a40ed3dSBarry Smith   PetscFunctionReturn(0);
620cd0e1443SSatish Balay }
621cd0e1443SSatish Balay 
62295d5f7c2SBarry Smith #if defined(PETSC_USE_MAT_SINGLE)
6234a2ae208SSatish Balay #undef __FUNCT__
6244a2ae208SSatish Balay #define __FUNCT__ "MatSetValuesBlocked_SeqBAIJ"
62595d5f7c2SBarry Smith int MatSetValuesBlocked_SeqBAIJ(Mat mat,int m,int *im,int n,int *in,Scalar *v,InsertMode addv)
62695d5f7c2SBarry Smith {
627563b5814SBarry Smith   Mat_SeqBAIJ *b = (Mat_SeqBAIJ*)mat->data;
628563b5814SBarry Smith   int         ierr,i,N = m*n*b->bs2;
629563b5814SBarry Smith   MatScalar   *vsingle;
63095d5f7c2SBarry Smith 
63195d5f7c2SBarry Smith   PetscFunctionBegin;
632563b5814SBarry Smith   if (N > b->setvalueslen) {
633563b5814SBarry Smith     if (b->setvaluescopy) {ierr = PetscFree(b->setvaluescopy);CHKERRQ(ierr);}
634b0a32e0cSBarry Smith     ierr = PetscMalloc(N*sizeof(MatScalar),&b->setvaluescopy);CHKERRQ(ierr);
635563b5814SBarry Smith     b->setvalueslen  = N;
636563b5814SBarry Smith   }
637563b5814SBarry Smith   vsingle = b->setvaluescopy;
63895d5f7c2SBarry Smith   for (i=0; i<N; i++) {
63995d5f7c2SBarry Smith     vsingle[i] = v[i];
64095d5f7c2SBarry Smith   }
64195d5f7c2SBarry Smith   ierr = MatSetValuesBlocked_SeqBAIJ_MatScalar(mat,m,im,n,in,vsingle,addv);CHKERRQ(ierr);
64295d5f7c2SBarry Smith   PetscFunctionReturn(0);
64395d5f7c2SBarry Smith }
64495d5f7c2SBarry Smith #endif
64595d5f7c2SBarry Smith 
6462d61bbb3SSatish Balay 
6474a2ae208SSatish Balay #undef __FUNCT__
6484a2ae208SSatish Balay #define __FUNCT__ "MatSetValuesBlocked_SeqBAIJ"
64995d5f7c2SBarry Smith int MatSetValuesBlocked_SeqBAIJ_MatScalar(Mat A,int m,int *im,int n,int *in,MatScalar *v,InsertMode is)
65092c4ed94SBarry Smith {
65192c4ed94SBarry Smith   Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)A->data;
6528a84c255SSatish Balay   int         *rp,k,low,high,t,ii,jj,row,nrow,i,col,l,rmax,N,sorted=a->sorted;
653273d9f13SBarry Smith   int         *imax=a->imax,*ai=a->i,*ailen=a->ilen;
654549d3d68SSatish Balay   int         *aj=a->j,nonew=a->nonew,bs2=a->bs2,bs=a->bs,stepval,ierr;
655273d9f13SBarry Smith   PetscTruth  roworiented=a->roworiented;
65695d5f7c2SBarry Smith   MatScalar   *value = v,*ap,*aa = a->a,*bap;
65792c4ed94SBarry Smith 
6583a40ed3dSBarry Smith   PetscFunctionBegin;
6590e324ae4SSatish Balay   if (roworiented) {
6600e324ae4SSatish Balay     stepval = (n-1)*bs;
6610e324ae4SSatish Balay   } else {
6620e324ae4SSatish Balay     stepval = (m-1)*bs;
6630e324ae4SSatish Balay   }
66492c4ed94SBarry Smith   for (k=0; k<m; k++) { /* loop over added rows */
66592c4ed94SBarry Smith     row  = im[k];
6665ef9f2a5SBarry Smith     if (row < 0) continue;
667aa482453SBarry Smith #if defined(PETSC_USE_BOPT_g)
66829bbc08cSBarry Smith     if (row >= a->mbs) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Row too large");
66992c4ed94SBarry Smith #endif
67092c4ed94SBarry Smith     rp   = aj + ai[row];
67192c4ed94SBarry Smith     ap   = aa + bs2*ai[row];
67292c4ed94SBarry Smith     rmax = imax[row];
67392c4ed94SBarry Smith     nrow = ailen[row];
67492c4ed94SBarry Smith     low  = 0;
67592c4ed94SBarry Smith     for (l=0; l<n; l++) { /* loop over added columns */
6765ef9f2a5SBarry Smith       if (in[l] < 0) continue;
677aa482453SBarry Smith #if defined(PETSC_USE_BOPT_g)
67829bbc08cSBarry Smith       if (in[l] >= a->nbs) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Column too large");
67992c4ed94SBarry Smith #endif
68092c4ed94SBarry Smith       col = in[l];
68192c4ed94SBarry Smith       if (roworiented) {
6820e324ae4SSatish Balay         value = v + k*(stepval+bs)*bs + l*bs;
6830e324ae4SSatish Balay       } else {
6840e324ae4SSatish Balay         value = v + l*(stepval+bs)*bs + k*bs;
68592c4ed94SBarry Smith       }
68692c4ed94SBarry Smith       if (!sorted) low = 0; high = nrow;
68792c4ed94SBarry Smith       while (high-low > 7) {
68892c4ed94SBarry Smith         t = (low+high)/2;
68992c4ed94SBarry Smith         if (rp[t] > col) high = t;
69092c4ed94SBarry Smith         else             low  = t;
69192c4ed94SBarry Smith       }
69292c4ed94SBarry Smith       for (i=low; i<high; i++) {
69392c4ed94SBarry Smith         if (rp[i] > col) break;
69492c4ed94SBarry Smith         if (rp[i] == col) {
6958a84c255SSatish Balay           bap  = ap +  bs2*i;
6960e324ae4SSatish Balay           if (roworiented) {
6978a84c255SSatish Balay             if (is == ADD_VALUES) {
698dd9472c6SBarry Smith               for (ii=0; ii<bs; ii++,value+=stepval) {
699dd9472c6SBarry Smith                 for (jj=ii; jj<bs2; jj+=bs) {
7008a84c255SSatish Balay                   bap[jj] += *value++;
701dd9472c6SBarry Smith                 }
702dd9472c6SBarry Smith               }
7030e324ae4SSatish Balay             } else {
704dd9472c6SBarry Smith               for (ii=0; ii<bs; ii++,value+=stepval) {
705dd9472c6SBarry Smith                 for (jj=ii; jj<bs2; jj+=bs) {
7060e324ae4SSatish Balay                   bap[jj] = *value++;
7078a84c255SSatish Balay                 }
708dd9472c6SBarry Smith               }
709dd9472c6SBarry Smith             }
7100e324ae4SSatish Balay           } else {
7110e324ae4SSatish Balay             if (is == ADD_VALUES) {
712dd9472c6SBarry Smith               for (ii=0; ii<bs; ii++,value+=stepval) {
713dd9472c6SBarry Smith                 for (jj=0; jj<bs; jj++) {
7140e324ae4SSatish Balay                   *bap++ += *value++;
715dd9472c6SBarry Smith                 }
716dd9472c6SBarry Smith               }
7170e324ae4SSatish Balay             } else {
718dd9472c6SBarry Smith               for (ii=0; ii<bs; ii++,value+=stepval) {
719dd9472c6SBarry Smith                 for (jj=0; jj<bs; jj++) {
7200e324ae4SSatish Balay                   *bap++  = *value++;
7210e324ae4SSatish Balay                 }
7228a84c255SSatish Balay               }
723dd9472c6SBarry Smith             }
724dd9472c6SBarry Smith           }
725f1241b54SBarry Smith           goto noinsert2;
72692c4ed94SBarry Smith         }
72792c4ed94SBarry Smith       }
72889280ab3SLois Curfman McInnes       if (nonew == 1) goto noinsert2;
72929bbc08cSBarry Smith       else if (nonew == -1) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Inserting a new nonzero in the matrix");
73092c4ed94SBarry Smith       if (nrow >= rmax) {
73192c4ed94SBarry Smith         /* there is no extra room in row, therefore enlarge */
73292c4ed94SBarry Smith         int       new_nz = ai[a->mbs] + CHUNKSIZE,len,*new_i,*new_j;
7333f1db9ecSBarry Smith         MatScalar *new_a;
73492c4ed94SBarry Smith 
73529bbc08cSBarry Smith         if (nonew == -2) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Inserting a new nonzero in the matrix");
73689280ab3SLois Curfman McInnes 
73792c4ed94SBarry Smith         /* malloc new storage space */
7383f1db9ecSBarry Smith         len     = new_nz*(sizeof(int)+bs2*sizeof(MatScalar))+(a->mbs+1)*sizeof(int);
739b0a32e0cSBarry Smith 	ierr    = PetscMalloc(len,&new_a);CHKERRQ(ierr);
74092c4ed94SBarry Smith         new_j   = (int*)(new_a + bs2*new_nz);
74192c4ed94SBarry Smith         new_i   = new_j + new_nz;
74292c4ed94SBarry Smith 
74392c4ed94SBarry Smith         /* copy over old data into new slots */
74492c4ed94SBarry Smith         for (ii=0; ii<row+1; ii++) {new_i[ii] = ai[ii];}
74592c4ed94SBarry Smith         for (ii=row+1; ii<a->mbs+1; ii++) {new_i[ii] = ai[ii]+CHUNKSIZE;}
746549d3d68SSatish Balay         ierr = PetscMemcpy(new_j,aj,(ai[row]+nrow)*sizeof(int));CHKERRQ(ierr);
74792c4ed94SBarry Smith         len  = (new_nz - CHUNKSIZE - ai[row] - nrow);
748549d3d68SSatish Balay         ierr = PetscMemcpy(new_j+ai[row]+nrow+CHUNKSIZE,aj+ai[row]+nrow,len*sizeof(int));CHKERRQ(ierr);
749549d3d68SSatish Balay         ierr = PetscMemcpy(new_a,aa,(ai[row]+nrow)*bs2*sizeof(MatScalar));CHKERRQ(ierr);
750549d3d68SSatish Balay         ierr = PetscMemzero(new_a+bs2*(ai[row]+nrow),bs2*CHUNKSIZE*sizeof(MatScalar));CHKERRQ(ierr);
751549d3d68SSatish Balay         ierr = PetscMemcpy(new_a+bs2*(ai[row]+nrow+CHUNKSIZE),aa+bs2*(ai[row]+nrow),bs2*len*sizeof(MatScalar));CHKERRQ(ierr);
75292c4ed94SBarry Smith         /* free up old matrix storage */
753606d414cSSatish Balay         ierr = PetscFree(a->a);CHKERRQ(ierr);
754606d414cSSatish Balay         if (!a->singlemalloc) {
755606d414cSSatish Balay           ierr = PetscFree(a->i);CHKERRQ(ierr);
756606d414cSSatish Balay           ierr = PetscFree(a->j);CHKERRQ(ierr);
757606d414cSSatish Balay         }
75892c4ed94SBarry Smith         aa = a->a = new_a; ai = a->i = new_i; aj = a->j = new_j;
759c4992f7dSBarry Smith         a->singlemalloc = PETSC_TRUE;
76092c4ed94SBarry Smith 
76192c4ed94SBarry Smith         rp   = aj + ai[row]; ap = aa + bs2*ai[row];
76292c4ed94SBarry Smith         rmax = imax[row] = imax[row] + CHUNKSIZE;
763b0a32e0cSBarry Smith         PetscLogObjectMemory(A,CHUNKSIZE*(sizeof(int) + bs2*sizeof(MatScalar)));
76492c4ed94SBarry Smith         a->maxnz += bs2*CHUNKSIZE;
76592c4ed94SBarry Smith         a->reallocs++;
76692c4ed94SBarry Smith         a->nz++;
76792c4ed94SBarry Smith       }
76892c4ed94SBarry Smith       N = nrow++ - 1;
76992c4ed94SBarry Smith       /* shift up all the later entries in this row */
77092c4ed94SBarry Smith       for (ii=N; ii>=i; ii--) {
77192c4ed94SBarry Smith         rp[ii+1] = rp[ii];
772549d3d68SSatish Balay         ierr = PetscMemcpy(ap+bs2*(ii+1),ap+bs2*(ii),bs2*sizeof(MatScalar));CHKERRQ(ierr);
77392c4ed94SBarry Smith       }
774549d3d68SSatish Balay       if (N >= i) {
775549d3d68SSatish Balay         ierr = PetscMemzero(ap+bs2*i,bs2*sizeof(MatScalar));CHKERRQ(ierr);
776549d3d68SSatish Balay       }
77792c4ed94SBarry Smith       rp[i] = col;
7788a84c255SSatish Balay       bap   = ap +  bs2*i;
7790e324ae4SSatish Balay       if (roworiented) {
780dd9472c6SBarry Smith         for (ii=0; ii<bs; ii++,value+=stepval) {
781dd9472c6SBarry Smith           for (jj=ii; jj<bs2; jj+=bs) {
7820e324ae4SSatish Balay             bap[jj] = *value++;
783dd9472c6SBarry Smith           }
784dd9472c6SBarry Smith         }
7850e324ae4SSatish Balay       } else {
786dd9472c6SBarry Smith         for (ii=0; ii<bs; ii++,value+=stepval) {
787dd9472c6SBarry Smith           for (jj=0; jj<bs; jj++) {
7880e324ae4SSatish Balay             *bap++  = *value++;
7890e324ae4SSatish Balay           }
790dd9472c6SBarry Smith         }
791dd9472c6SBarry Smith       }
792f1241b54SBarry Smith       noinsert2:;
79392c4ed94SBarry Smith       low = i;
79492c4ed94SBarry Smith     }
79592c4ed94SBarry Smith     ailen[row] = nrow;
79692c4ed94SBarry Smith   }
7973a40ed3dSBarry Smith   PetscFunctionReturn(0);
79892c4ed94SBarry Smith }
79992c4ed94SBarry Smith 
800f2501298SSatish Balay 
8014a2ae208SSatish Balay #undef __FUNCT__
8024a2ae208SSatish Balay #define __FUNCT__ "MatAssemblyEnd_SeqBAIJ"
8038f6be9afSLois Curfman McInnes int MatAssemblyEnd_SeqBAIJ(Mat A,MatAssemblyType mode)
804584200bdSSatish Balay {
805584200bdSSatish Balay   Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)A->data;
806584200bdSSatish Balay   int        fshift = 0,i,j,*ai = a->i,*aj = a->j,*imax = a->imax;
807273d9f13SBarry Smith   int        m = A->m,*ip,N,*ailen = a->ilen;
808549d3d68SSatish Balay   int        mbs = a->mbs,bs2 = a->bs2,rmax = 0,ierr;
8093f1db9ecSBarry Smith   MatScalar  *aa = a->a,*ap;
810584200bdSSatish Balay 
8113a40ed3dSBarry Smith   PetscFunctionBegin;
8123a40ed3dSBarry Smith   if (mode == MAT_FLUSH_ASSEMBLY) PetscFunctionReturn(0);
813584200bdSSatish Balay 
81443ee02c3SBarry Smith   if (m) rmax = ailen[0];
815584200bdSSatish Balay   for (i=1; i<mbs; i++) {
816584200bdSSatish Balay     /* move each row back by the amount of empty slots (fshift) before it*/
817584200bdSSatish Balay     fshift += imax[i-1] - ailen[i-1];
818d402145bSBarry Smith     rmax   = PetscMax(rmax,ailen[i]);
819584200bdSSatish Balay     if (fshift) {
820a7c10996SSatish Balay       ip = aj + ai[i]; ap = aa + bs2*ai[i];
821584200bdSSatish Balay       N = ailen[i];
822584200bdSSatish Balay       for (j=0; j<N; j++) {
823584200bdSSatish Balay         ip[j-fshift] = ip[j];
824549d3d68SSatish Balay         ierr = PetscMemcpy(ap+(j-fshift)*bs2,ap+j*bs2,bs2*sizeof(MatScalar));CHKERRQ(ierr);
825584200bdSSatish Balay       }
826584200bdSSatish Balay     }
827584200bdSSatish Balay     ai[i] = ai[i-1] + ailen[i-1];
828584200bdSSatish Balay   }
829584200bdSSatish Balay   if (mbs) {
830584200bdSSatish Balay     fshift += imax[mbs-1] - ailen[mbs-1];
831584200bdSSatish Balay     ai[mbs] = ai[mbs-1] + ailen[mbs-1];
832584200bdSSatish Balay   }
833584200bdSSatish Balay   /* reset ilen and imax for each row */
834584200bdSSatish Balay   for (i=0; i<mbs; i++) {
835584200bdSSatish Balay     ailen[i] = imax[i] = ai[i+1] - ai[i];
836584200bdSSatish Balay   }
837a7c10996SSatish Balay   a->nz = ai[mbs];
838584200bdSSatish Balay 
839584200bdSSatish Balay   /* diagonals may have moved, so kill the diagonal pointers */
840584200bdSSatish Balay   if (fshift && a->diag) {
841606d414cSSatish Balay     ierr = PetscFree(a->diag);CHKERRQ(ierr);
842b0a32e0cSBarry Smith     PetscLogObjectMemory(A,-(m+1)*sizeof(int));
843584200bdSSatish Balay     a->diag = 0;
844584200bdSSatish Balay   }
845b0a32e0cSBarry Smith   PetscLogInfo(A,"MatAssemblyEnd_SeqBAIJ:Matrix size: %d X %d, block size %d; storage space: %d unneeded, %d used\n",
846273d9f13SBarry Smith            m,A->n,a->bs,fshift*bs2,a->nz*bs2);
847b0a32e0cSBarry Smith   PetscLogInfo(A,"MatAssemblyEnd_SeqBAIJ:Number of mallocs during MatSetValues is %d\n",
848584200bdSSatish Balay            a->reallocs);
849b0a32e0cSBarry Smith   PetscLogInfo(A,"MatAssemblyEnd_SeqBAIJ:Most nonzeros blocks in any row is %d\n",rmax);
850e2f3b5e9SSatish Balay   a->reallocs          = 0;
8510e6d2581SBarry Smith   A->info.nz_unneeded  = (PetscReal)fshift*bs2;
8524e220ebcSLois Curfman McInnes 
8533a40ed3dSBarry Smith   PetscFunctionReturn(0);
854584200bdSSatish Balay }
855584200bdSSatish Balay 
8565a838052SSatish Balay 
857bea157c4SSatish Balay 
858bea157c4SSatish Balay /*
859bea157c4SSatish Balay    This function returns an array of flags which indicate the locations of contiguous
860bea157c4SSatish Balay    blocks that should be zeroed. for eg: if bs = 3  and is = [0,1,2,3,5,6,7,8,9]
861bea157c4SSatish Balay    then the resulting sizes = [3,1,1,3,1] correspondig to sets [(0,1,2),(3),(5),(6,7,8),(9)]
862bea157c4SSatish Balay    Assume: sizes should be long enough to hold all the values.
863bea157c4SSatish Balay */
8644a2ae208SSatish Balay #undef __FUNCT__
8654a2ae208SSatish Balay #define __FUNCT__ "MatZeroRows_SeqBAIJ_Check_Blocks"
866bea157c4SSatish Balay static int MatZeroRows_SeqBAIJ_Check_Blocks(int idx[],int n,int bs,int sizes[], int *bs_max)
867d9b7c43dSSatish Balay {
868bea157c4SSatish Balay   int        i,j,k,row;
869bea157c4SSatish Balay   PetscTruth flg;
8703a40ed3dSBarry Smith 
871433994e6SBarry Smith   PetscFunctionBegin;
872bea157c4SSatish Balay   for (i=0,j=0; i<n; j++) {
873bea157c4SSatish Balay     row = idx[i];
874bea157c4SSatish Balay     if (row%bs!=0) { /* Not the begining of a block */
875bea157c4SSatish Balay       sizes[j] = 1;
876bea157c4SSatish Balay       i++;
877e4fda26cSSatish Balay     } else if (i+bs > n) { /* complete block doesn't exist (at idx end) */
878bea157c4SSatish Balay       sizes[j] = 1;         /* Also makes sure atleast 'bs' values exist for next else */
879bea157c4SSatish Balay       i++;
880bea157c4SSatish Balay     } else { /* Begining of the block, so check if the complete block exists */
881bea157c4SSatish Balay       flg = PETSC_TRUE;
882bea157c4SSatish Balay       for (k=1; k<bs; k++) {
883bea157c4SSatish Balay         if (row+k != idx[i+k]) { /* break in the block */
884bea157c4SSatish Balay           flg = PETSC_FALSE;
885bea157c4SSatish Balay           break;
886d9b7c43dSSatish Balay         }
887bea157c4SSatish Balay       }
888bea157c4SSatish Balay       if (flg == PETSC_TRUE) { /* No break in the bs */
889bea157c4SSatish Balay         sizes[j] = bs;
890bea157c4SSatish Balay         i+= bs;
891bea157c4SSatish Balay       } else {
892bea157c4SSatish Balay         sizes[j] = 1;
893bea157c4SSatish Balay         i++;
894bea157c4SSatish Balay       }
895bea157c4SSatish Balay     }
896bea157c4SSatish Balay   }
897bea157c4SSatish Balay   *bs_max = j;
8983a40ed3dSBarry Smith   PetscFunctionReturn(0);
899d9b7c43dSSatish Balay }
900d9b7c43dSSatish Balay 
9014a2ae208SSatish Balay #undef __FUNCT__
9024a2ae208SSatish Balay #define __FUNCT__ "MatZeroRows_SeqBAIJ"
9038f6be9afSLois Curfman McInnes int MatZeroRows_SeqBAIJ(Mat A,IS is,Scalar *diag)
904d9b7c43dSSatish Balay {
905d9b7c43dSSatish Balay   Mat_SeqBAIJ *baij=(Mat_SeqBAIJ*)A->data;
906b6815fffSBarry Smith   int         ierr,i,j,k,count,is_n,*is_idx,*rows;
907bea157c4SSatish Balay   int         bs=baij->bs,bs2=baij->bs2,*sizes,row,bs_max;
9083f1db9ecSBarry Smith   Scalar      zero = 0.0;
9093f1db9ecSBarry Smith   MatScalar   *aa;
910d9b7c43dSSatish Balay 
9113a40ed3dSBarry Smith   PetscFunctionBegin;
912d9b7c43dSSatish Balay   /* Make a copy of the IS and  sort it */
913b9b97703SBarry Smith   ierr = ISGetLocalSize(is,&is_n);CHKERRQ(ierr);
914d9b7c43dSSatish Balay   ierr = ISGetIndices(is,&is_idx);CHKERRQ(ierr);
915d9b7c43dSSatish Balay 
916bea157c4SSatish Balay   /* allocate memory for rows,sizes */
917b0a32e0cSBarry Smith   ierr  = PetscMalloc((3*is_n+1)*sizeof(int),&rows);CHKERRQ(ierr);
918bea157c4SSatish Balay   sizes = rows + is_n;
919bea157c4SSatish Balay 
920563b5814SBarry Smith   /* copy IS values to rows, and sort them */
921bea157c4SSatish Balay   for (i=0; i<is_n; i++) { rows[i] = is_idx[i]; }
922bea157c4SSatish Balay   ierr = PetscSortInt(is_n,rows);CHKERRQ(ierr);
923dffd3267SBarry Smith   if (baij->keepzeroedrows) {
924dffd3267SBarry Smith     for (i=0; i<is_n; i++) { sizes[i] = 1; }
925dffd3267SBarry Smith     bs_max = is_n;
926dffd3267SBarry Smith   } else {
927bea157c4SSatish Balay     ierr = MatZeroRows_SeqBAIJ_Check_Blocks(rows,is_n,bs,sizes,&bs_max);CHKERRQ(ierr);
928dffd3267SBarry Smith   }
929b97a56abSSatish Balay   ierr = ISRestoreIndices(is,&is_idx);CHKERRQ(ierr);
930bea157c4SSatish Balay 
931bea157c4SSatish Balay   for (i=0,j=0; i<bs_max; j+=sizes[i],i++) {
932bea157c4SSatish Balay     row   = rows[j];
933273d9f13SBarry Smith     if (row < 0 || row > A->m) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"row %d out of range",row);
934bea157c4SSatish Balay     count = (baij->i[row/bs +1] - baij->i[row/bs])*bs;
935bea157c4SSatish Balay     aa    = baij->a + baij->i[row/bs]*bs2 + (row%bs);
936dffd3267SBarry Smith     if (sizes[i] == bs && !baij->keepzeroedrows) {
937bea157c4SSatish Balay       if (diag) {
938bea157c4SSatish Balay         if (baij->ilen[row/bs] > 0) {
939bea157c4SSatish Balay           baij->ilen[row/bs]       = 1;
940bea157c4SSatish Balay           baij->j[baij->i[row/bs]] = row/bs;
941bea157c4SSatish Balay           ierr = PetscMemzero(aa,count*bs*sizeof(MatScalar));CHKERRQ(ierr);
942a07cd24cSSatish Balay         }
943563b5814SBarry Smith         /* Now insert all the diagonal values for this bs */
944bea157c4SSatish Balay         for (k=0; k<bs; k++) {
945bea157c4SSatish Balay           ierr = (*A->ops->setvalues)(A,1,rows+j+k,1,rows+j+k,diag,INSERT_VALUES);CHKERRQ(ierr);
946bea157c4SSatish Balay         }
947bea157c4SSatish Balay       } else { /* (!diag) */
948bea157c4SSatish Balay         baij->ilen[row/bs] = 0;
949bea157c4SSatish Balay       } /* end (!diag) */
950bea157c4SSatish Balay     } else { /* (sizes[i] != bs) */
951aa482453SBarry Smith #if defined (PETSC_USE_DEBUG)
95229bbc08cSBarry Smith       if (sizes[i] != 1) SETERRQ(1,"Internal Error. Value should be 1");
953bea157c4SSatish Balay #endif
954bea157c4SSatish Balay       for (k=0; k<count; k++) {
955d9b7c43dSSatish Balay         aa[0] =  zero;
956d9b7c43dSSatish Balay         aa    += bs;
957d9b7c43dSSatish Balay       }
958d9b7c43dSSatish Balay       if (diag) {
959f830108cSBarry Smith         ierr = (*A->ops->setvalues)(A,1,rows+j,1,rows+j,diag,INSERT_VALUES);CHKERRQ(ierr);
960d9b7c43dSSatish Balay       }
961d9b7c43dSSatish Balay     }
962bea157c4SSatish Balay   }
963bea157c4SSatish Balay 
964606d414cSSatish Balay   ierr = PetscFree(rows);CHKERRQ(ierr);
9659a8dea36SBarry Smith   ierr = MatAssemblyEnd_SeqBAIJ(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
9663a40ed3dSBarry Smith   PetscFunctionReturn(0);
967d9b7c43dSSatish Balay }
9681c351548SSatish Balay 
9694a2ae208SSatish Balay #undef __FUNCT__
9704a2ae208SSatish Balay #define __FUNCT__ "MatSetValues_SeqBAIJ"
9712d61bbb3SSatish Balay int MatSetValues_SeqBAIJ(Mat A,int m,int *im,int n,int *in,Scalar *v,InsertMode is)
9722d61bbb3SSatish Balay {
9732d61bbb3SSatish Balay   Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)A->data;
9742d61bbb3SSatish Balay   int         *rp,k,low,high,t,ii,row,nrow,i,col,l,rmax,N,sorted=a->sorted;
975273d9f13SBarry Smith   int         *imax=a->imax,*ai=a->i,*ailen=a->ilen;
9762d61bbb3SSatish Balay   int         *aj=a->j,nonew=a->nonew,bs=a->bs,brow,bcol;
977549d3d68SSatish Balay   int         ridx,cidx,bs2=a->bs2,ierr;
978273d9f13SBarry Smith   PetscTruth  roworiented=a->roworiented;
9793f1db9ecSBarry Smith   MatScalar   *ap,value,*aa=a->a,*bap;
9802d61bbb3SSatish Balay 
9812d61bbb3SSatish Balay   PetscFunctionBegin;
9822d61bbb3SSatish Balay   for (k=0; k<m; k++) { /* loop over added rows */
9832d61bbb3SSatish Balay     row  = im[k]; brow = row/bs;
9845ef9f2a5SBarry Smith     if (row < 0) continue;
985aa482453SBarry Smith #if defined(PETSC_USE_BOPT_g)
986273d9f13SBarry Smith     if (row >= A->m) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"Row too large: row %d max %d",row,A->m);
9872d61bbb3SSatish Balay #endif
9882d61bbb3SSatish Balay     rp   = aj + ai[brow];
9892d61bbb3SSatish Balay     ap   = aa + bs2*ai[brow];
9902d61bbb3SSatish Balay     rmax = imax[brow];
9912d61bbb3SSatish Balay     nrow = ailen[brow];
9922d61bbb3SSatish Balay     low  = 0;
9932d61bbb3SSatish Balay     for (l=0; l<n; l++) { /* loop over added columns */
9945ef9f2a5SBarry Smith       if (in[l] < 0) continue;
995aa482453SBarry Smith #if defined(PETSC_USE_BOPT_g)
996273d9f13SBarry Smith       if (in[l] >= A->n) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"Column too large: col %d max %d",in[l],A->n);
9972d61bbb3SSatish Balay #endif
9982d61bbb3SSatish Balay       col = in[l]; bcol = col/bs;
9992d61bbb3SSatish Balay       ridx = row % bs; cidx = col % bs;
10002d61bbb3SSatish Balay       if (roworiented) {
10015ef9f2a5SBarry Smith         value = v[l + k*n];
10022d61bbb3SSatish Balay       } else {
10032d61bbb3SSatish Balay         value = v[k + l*m];
10042d61bbb3SSatish Balay       }
10052d61bbb3SSatish Balay       if (!sorted) low = 0; high = nrow;
10062d61bbb3SSatish Balay       while (high-low > 7) {
10072d61bbb3SSatish Balay         t = (low+high)/2;
10082d61bbb3SSatish Balay         if (rp[t] > bcol) high = t;
10092d61bbb3SSatish Balay         else              low  = t;
10102d61bbb3SSatish Balay       }
10112d61bbb3SSatish Balay       for (i=low; i<high; i++) {
10122d61bbb3SSatish Balay         if (rp[i] > bcol) break;
10132d61bbb3SSatish Balay         if (rp[i] == bcol) {
10142d61bbb3SSatish Balay           bap  = ap +  bs2*i + bs*cidx + ridx;
10152d61bbb3SSatish Balay           if (is == ADD_VALUES) *bap += value;
10162d61bbb3SSatish Balay           else                  *bap  = value;
10172d61bbb3SSatish Balay           goto noinsert1;
10182d61bbb3SSatish Balay         }
10192d61bbb3SSatish Balay       }
10202d61bbb3SSatish Balay       if (nonew == 1) goto noinsert1;
102129bbc08cSBarry Smith       else if (nonew == -1) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Inserting a new nonzero in the matrix");
10222d61bbb3SSatish Balay       if (nrow >= rmax) {
10232d61bbb3SSatish Balay         /* there is no extra room in row, therefore enlarge */
10242d61bbb3SSatish Balay         int       new_nz = ai[a->mbs] + CHUNKSIZE,len,*new_i,*new_j;
10253f1db9ecSBarry Smith         MatScalar *new_a;
10262d61bbb3SSatish Balay 
102729bbc08cSBarry Smith         if (nonew == -2) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Inserting a new nonzero in the matrix");
10282d61bbb3SSatish Balay 
10292d61bbb3SSatish Balay         /* Malloc new storage space */
10303f1db9ecSBarry Smith         len     = new_nz*(sizeof(int)+bs2*sizeof(MatScalar))+(a->mbs+1)*sizeof(int);
1031b0a32e0cSBarry Smith 	ierr    = PetscMalloc(len,&new_a);CHKERRQ(ierr);
10322d61bbb3SSatish Balay         new_j   = (int*)(new_a + bs2*new_nz);
10332d61bbb3SSatish Balay         new_i   = new_j + new_nz;
10342d61bbb3SSatish Balay 
10352d61bbb3SSatish Balay         /* copy over old data into new slots */
10362d61bbb3SSatish Balay         for (ii=0; ii<brow+1; ii++) {new_i[ii] = ai[ii];}
10372d61bbb3SSatish Balay         for (ii=brow+1; ii<a->mbs+1; ii++) {new_i[ii] = ai[ii]+CHUNKSIZE;}
1038549d3d68SSatish Balay         ierr = PetscMemcpy(new_j,aj,(ai[brow]+nrow)*sizeof(int));CHKERRQ(ierr);
10392d61bbb3SSatish Balay         len  = (new_nz - CHUNKSIZE - ai[brow] - nrow);
1040549d3d68SSatish Balay         ierr = PetscMemcpy(new_j+ai[brow]+nrow+CHUNKSIZE,aj+ai[brow]+nrow,len*sizeof(int));CHKERRQ(ierr);
1041549d3d68SSatish Balay         ierr = PetscMemcpy(new_a,aa,(ai[brow]+nrow)*bs2*sizeof(MatScalar));CHKERRQ(ierr);
1042549d3d68SSatish Balay         ierr = PetscMemzero(new_a+bs2*(ai[brow]+nrow),bs2*CHUNKSIZE*sizeof(MatScalar));CHKERRQ(ierr);
1043549d3d68SSatish Balay         ierr = PetscMemcpy(new_a+bs2*(ai[brow]+nrow+CHUNKSIZE),aa+bs2*(ai[brow]+nrow),bs2*len*sizeof(MatScalar));CHKERRQ(ierr);
10442d61bbb3SSatish Balay         /* free up old matrix storage */
1045606d414cSSatish Balay         ierr = PetscFree(a->a);CHKERRQ(ierr);
1046606d414cSSatish Balay         if (!a->singlemalloc) {
1047606d414cSSatish Balay           ierr = PetscFree(a->i);CHKERRQ(ierr);
1048606d414cSSatish Balay           ierr = PetscFree(a->j);CHKERRQ(ierr);
1049606d414cSSatish Balay         }
10502d61bbb3SSatish Balay         aa = a->a = new_a; ai = a->i = new_i; aj = a->j = new_j;
1051c4992f7dSBarry Smith         a->singlemalloc = PETSC_TRUE;
10522d61bbb3SSatish Balay 
10532d61bbb3SSatish Balay         rp   = aj + ai[brow]; ap = aa + bs2*ai[brow];
10542d61bbb3SSatish Balay         rmax = imax[brow] = imax[brow] + CHUNKSIZE;
1055b0a32e0cSBarry Smith         PetscLogObjectMemory(A,CHUNKSIZE*(sizeof(int) + bs2*sizeof(MatScalar)));
10562d61bbb3SSatish Balay         a->maxnz += bs2*CHUNKSIZE;
10572d61bbb3SSatish Balay         a->reallocs++;
10582d61bbb3SSatish Balay         a->nz++;
10592d61bbb3SSatish Balay       }
10602d61bbb3SSatish Balay       N = nrow++ - 1;
10612d61bbb3SSatish Balay       /* shift up all the later entries in this row */
10622d61bbb3SSatish Balay       for (ii=N; ii>=i; ii--) {
10632d61bbb3SSatish Balay         rp[ii+1] = rp[ii];
1064549d3d68SSatish Balay         ierr     = PetscMemcpy(ap+bs2*(ii+1),ap+bs2*(ii),bs2*sizeof(MatScalar));CHKERRQ(ierr);
10652d61bbb3SSatish Balay       }
1066549d3d68SSatish Balay       if (N>=i) {
1067549d3d68SSatish Balay         ierr = PetscMemzero(ap+bs2*i,bs2*sizeof(MatScalar));CHKERRQ(ierr);
1068549d3d68SSatish Balay       }
10692d61bbb3SSatish Balay       rp[i]                      = bcol;
10702d61bbb3SSatish Balay       ap[bs2*i + bs*cidx + ridx] = value;
10712d61bbb3SSatish Balay       noinsert1:;
10722d61bbb3SSatish Balay       low = i;
10732d61bbb3SSatish Balay     }
10742d61bbb3SSatish Balay     ailen[brow] = nrow;
10752d61bbb3SSatish Balay   }
10762d61bbb3SSatish Balay   PetscFunctionReturn(0);
10772d61bbb3SSatish Balay }
10782d61bbb3SSatish Balay 
1079b9b97703SBarry Smith EXTERN int MatLUFactorSymbolic_SeqBAIJ(Mat,IS,IS,MatLUInfo*,Mat*);
1080b9b97703SBarry Smith EXTERN int MatLUFactor_SeqBAIJ(Mat,IS,IS,MatLUInfo*);
1081ca44d042SBarry Smith EXTERN int MatIncreaseOverlap_SeqBAIJ(Mat,int,IS*,int);
1082ca44d042SBarry Smith EXTERN int MatGetSubMatrix_SeqBAIJ(Mat,IS,IS,int,MatReuse,Mat*);
1083ca44d042SBarry Smith EXTERN int MatGetSubMatrices_SeqBAIJ(Mat,int,IS*,IS*,MatReuse,Mat**);
1084ca44d042SBarry Smith EXTERN int MatMultTranspose_SeqBAIJ(Mat,Vec,Vec);
1085ca44d042SBarry Smith EXTERN int MatMultTransposeAdd_SeqBAIJ(Mat,Vec,Vec,Vec);
1086ca44d042SBarry Smith EXTERN int MatScale_SeqBAIJ(Scalar*,Mat);
1087ca44d042SBarry Smith EXTERN int MatNorm_SeqBAIJ(Mat,NormType,PetscReal *);
1088ca44d042SBarry Smith EXTERN int MatEqual_SeqBAIJ(Mat,Mat,PetscTruth*);
1089ca44d042SBarry Smith EXTERN int MatGetDiagonal_SeqBAIJ(Mat,Vec);
1090ca44d042SBarry Smith EXTERN int MatDiagonalScale_SeqBAIJ(Mat,Vec,Vec);
1091ca44d042SBarry Smith EXTERN int MatGetInfo_SeqBAIJ(Mat,MatInfoType,MatInfo *);
1092ca44d042SBarry Smith EXTERN int MatZeroEntries_SeqBAIJ(Mat);
10932d61bbb3SSatish Balay 
1094ca44d042SBarry Smith EXTERN int MatSolve_SeqBAIJ_N(Mat,Vec,Vec);
1095ca44d042SBarry Smith EXTERN int MatSolve_SeqBAIJ_1(Mat,Vec,Vec);
1096ca44d042SBarry Smith EXTERN int MatSolve_SeqBAIJ_2(Mat,Vec,Vec);
1097ca44d042SBarry Smith EXTERN int MatSolve_SeqBAIJ_3(Mat,Vec,Vec);
1098ca44d042SBarry Smith EXTERN int MatSolve_SeqBAIJ_4(Mat,Vec,Vec);
1099ca44d042SBarry Smith EXTERN int MatSolve_SeqBAIJ_5(Mat,Vec,Vec);
1100ca44d042SBarry Smith EXTERN int MatSolve_SeqBAIJ_6(Mat,Vec,Vec);
1101ca44d042SBarry Smith EXTERN int MatSolve_SeqBAIJ_7(Mat,Vec,Vec);
1102ca44d042SBarry Smith EXTERN int MatSolveTranspose_SeqBAIJ_7(Mat,Vec,Vec);
1103ca44d042SBarry Smith EXTERN int MatSolveTranspose_SeqBAIJ_6(Mat,Vec,Vec);
1104ca44d042SBarry Smith EXTERN int MatSolveTranspose_SeqBAIJ_5(Mat,Vec,Vec);
1105ca44d042SBarry Smith EXTERN int MatSolveTranspose_SeqBAIJ_4(Mat,Vec,Vec);
1106ca44d042SBarry Smith EXTERN int MatSolveTranspose_SeqBAIJ_3(Mat,Vec,Vec);
1107ca44d042SBarry Smith EXTERN int MatSolveTranspose_SeqBAIJ_2(Mat,Vec,Vec);
1108ca44d042SBarry Smith EXTERN int MatSolveTranspose_SeqBAIJ_1(Mat,Vec,Vec);
11092d61bbb3SSatish Balay 
1110ca44d042SBarry Smith EXTERN int MatLUFactorNumeric_SeqBAIJ_N(Mat,Mat*);
1111ca44d042SBarry Smith EXTERN int MatLUFactorNumeric_SeqBAIJ_1(Mat,Mat*);
1112ca44d042SBarry Smith EXTERN int MatLUFactorNumeric_SeqBAIJ_2(Mat,Mat*);
1113ca44d042SBarry Smith EXTERN int MatLUFactorNumeric_SeqBAIJ_3(Mat,Mat*);
1114ca44d042SBarry Smith EXTERN int MatLUFactorNumeric_SeqBAIJ_4(Mat,Mat*);
1115ca44d042SBarry Smith EXTERN int MatLUFactorNumeric_SeqBAIJ_5(Mat,Mat*);
1116ca44d042SBarry Smith EXTERN int MatLUFactorNumeric_SeqBAIJ_6(Mat,Mat*);
11172d61bbb3SSatish Balay 
1118ca44d042SBarry Smith EXTERN int MatMult_SeqBAIJ_1(Mat,Vec,Vec);
1119ca44d042SBarry Smith EXTERN int MatMult_SeqBAIJ_2(Mat,Vec,Vec);
1120ca44d042SBarry Smith EXTERN int MatMult_SeqBAIJ_3(Mat,Vec,Vec);
1121ca44d042SBarry Smith EXTERN int MatMult_SeqBAIJ_4(Mat,Vec,Vec);
1122ca44d042SBarry Smith EXTERN int MatMult_SeqBAIJ_5(Mat,Vec,Vec);
1123ca44d042SBarry Smith EXTERN int MatMult_SeqBAIJ_6(Mat,Vec,Vec);
1124ca44d042SBarry Smith EXTERN int MatMult_SeqBAIJ_7(Mat,Vec,Vec);
1125ca44d042SBarry Smith EXTERN int MatMult_SeqBAIJ_N(Mat,Vec,Vec);
11262d61bbb3SSatish Balay 
1127ca44d042SBarry Smith EXTERN int MatMultAdd_SeqBAIJ_1(Mat,Vec,Vec,Vec);
1128ca44d042SBarry Smith EXTERN int MatMultAdd_SeqBAIJ_2(Mat,Vec,Vec,Vec);
1129ca44d042SBarry Smith EXTERN int MatMultAdd_SeqBAIJ_3(Mat,Vec,Vec,Vec);
1130ca44d042SBarry Smith EXTERN int MatMultAdd_SeqBAIJ_4(Mat,Vec,Vec,Vec);
1131ca44d042SBarry Smith EXTERN int MatMultAdd_SeqBAIJ_5(Mat,Vec,Vec,Vec);
1132ca44d042SBarry Smith EXTERN int MatMultAdd_SeqBAIJ_6(Mat,Vec,Vec,Vec);
1133ca44d042SBarry Smith EXTERN int MatMultAdd_SeqBAIJ_7(Mat,Vec,Vec,Vec);
1134ca44d042SBarry Smith EXTERN int MatMultAdd_SeqBAIJ_N(Mat,Vec,Vec,Vec);
11352d61bbb3SSatish Balay 
11364a2ae208SSatish Balay #undef __FUNCT__
11374a2ae208SSatish Balay #define __FUNCT__ "MatILUFactor_SeqBAIJ"
11385ef9f2a5SBarry Smith int MatILUFactor_SeqBAIJ(Mat inA,IS row,IS col,MatILUInfo *info)
11392d61bbb3SSatish Balay {
11402d61bbb3SSatish Balay   Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)inA->data;
11412d61bbb3SSatish Balay   Mat         outA;
11422d61bbb3SSatish Balay   int         ierr;
1143667159a5SBarry Smith   PetscTruth  row_identity,col_identity;
11442d61bbb3SSatish Balay 
11452d61bbb3SSatish Balay   PetscFunctionBegin;
114629bbc08cSBarry Smith   if (info && info->levels != 0) SETERRQ(PETSC_ERR_SUP,"Only levels = 0 supported for in-place ILU");
1147667159a5SBarry Smith   ierr = ISIdentity(row,&row_identity);CHKERRQ(ierr);
1148667159a5SBarry Smith   ierr = ISIdentity(col,&col_identity);CHKERRQ(ierr);
1149667159a5SBarry Smith   if (!row_identity || !col_identity) {
115029bbc08cSBarry Smith     SETERRQ(1,"Row and column permutations must be identity for in-place ILU");
1151667159a5SBarry Smith   }
11522d61bbb3SSatish Balay 
11532d61bbb3SSatish Balay   outA          = inA;
11542d61bbb3SSatish Balay   inA->factor   = FACTOR_LU;
11552d61bbb3SSatish Balay 
11562d61bbb3SSatish Balay   if (!a->diag) {
1157c4992f7dSBarry Smith     ierr = MatMarkDiagonal_SeqBAIJ(inA);CHKERRQ(ierr);
11582d61bbb3SSatish Balay   }
11592d61bbb3SSatish Balay   /*
116015091d37SBarry Smith       Blocksize 2, 3, 4, 5, 6 and 7 have a special faster factorization/solver
116115091d37SBarry Smith       for ILU(0) factorization with natural ordering
11622d61bbb3SSatish Balay   */
116315091d37SBarry Smith   switch (a->bs) {
1164f1af5d2fSBarry Smith   case 1:
1165e37c484bSBarry Smith     inA->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_1;
1166e37c484bSBarry Smith     inA->ops->solve           = MatSolve_SeqBAIJ_1_NaturalOrdering;
1167e37c484bSBarry Smith     inA->ops->solvetranspose  = MatSolveTranspose_SeqBAIJ_1_NaturalOrdering;
1168b0a32e0cSBarry Smith     PetscLogInfo(inA,"MatILUFactor_SeqBAIJ:Using special in-place natural ordering factor and solve BS=1\n");
116915091d37SBarry Smith   case 2:
117015091d37SBarry Smith     inA->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_2_NaturalOrdering;
117115091d37SBarry Smith     inA->ops->solve           = MatSolve_SeqBAIJ_2_NaturalOrdering;
11727c922b88SBarry Smith     inA->ops->solvetranspose  = MatSolveTranspose_SeqBAIJ_2_NaturalOrdering;
1173b0a32e0cSBarry Smith     PetscLogInfo(inA,"MatILUFactor_SeqBAIJ:Using special in-place natural ordering factor and solve BS=2\n");
117415091d37SBarry Smith     break;
117515091d37SBarry Smith   case 3:
117615091d37SBarry Smith     inA->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_3_NaturalOrdering;
117715091d37SBarry Smith     inA->ops->solve           = MatSolve_SeqBAIJ_3_NaturalOrdering;
11787c922b88SBarry Smith     inA->ops->solvetranspose  = MatSolveTranspose_SeqBAIJ_3_NaturalOrdering;
1179b0a32e0cSBarry Smith     PetscLogInfo(inA,"MatILUFactor_SeqBAIJ:Using special in-place natural ordering factor and solve BS=3\n");
118015091d37SBarry Smith     break;
118115091d37SBarry Smith   case 4:
1182667159a5SBarry Smith     inA->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_4_NaturalOrdering;
1183f830108cSBarry Smith     inA->ops->solve           = MatSolve_SeqBAIJ_4_NaturalOrdering;
11847c922b88SBarry Smith     inA->ops->solvetranspose  = MatSolveTranspose_SeqBAIJ_4_NaturalOrdering;
1185b0a32e0cSBarry Smith     PetscLogInfo(inA,"MatILUFactor_SeqBAIJ:Using special in-place natural ordering factor and solve BS=4\n");
118615091d37SBarry Smith     break;
118715091d37SBarry Smith   case 5:
1188667159a5SBarry Smith     inA->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_5_NaturalOrdering;
1189667159a5SBarry Smith     inA->ops->solve           = MatSolve_SeqBAIJ_5_NaturalOrdering;
11907c922b88SBarry Smith     inA->ops->solvetranspose  = MatSolveTranspose_SeqBAIJ_5_NaturalOrdering;
1191b0a32e0cSBarry Smith     PetscLogInfo(inA,"MatILUFactor_SeqBAIJ:Using special in-place natural ordering factor and solve BS=5\n");
119215091d37SBarry Smith     break;
119315091d37SBarry Smith   case 6:
119415091d37SBarry Smith     inA->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_6_NaturalOrdering;
119515091d37SBarry Smith     inA->ops->solve           = MatSolve_SeqBAIJ_6_NaturalOrdering;
11967c922b88SBarry Smith     inA->ops->solvetranspose  = MatSolveTranspose_SeqBAIJ_6_NaturalOrdering;
1197b0a32e0cSBarry Smith     PetscLogInfo(inA,"MatILUFactor_SeqBAIJ:Using special in-place natural ordering factor and solve BS=6\n");
119815091d37SBarry Smith     break;
119915091d37SBarry Smith   case 7:
120015091d37SBarry Smith     inA->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_7_NaturalOrdering;
12017c922b88SBarry Smith     inA->ops->solvetranspose  = MatSolveTranspose_SeqBAIJ_7_NaturalOrdering;
120215091d37SBarry Smith     inA->ops->solve           = MatSolve_SeqBAIJ_7_NaturalOrdering;
1203b0a32e0cSBarry Smith     PetscLogInfo(inA,"MatILUFactor_SeqBAIJ:Using special in-place natural ordering factor and solve BS=7\n");
120415091d37SBarry Smith     break;
1205c38d4ed2SBarry Smith   default:
1206c38d4ed2SBarry Smith     a->row        = row;
1207c38d4ed2SBarry Smith     a->col        = col;
1208c38d4ed2SBarry Smith     ierr          = PetscObjectReference((PetscObject)row);CHKERRQ(ierr);
1209c38d4ed2SBarry Smith     ierr          = PetscObjectReference((PetscObject)col);CHKERRQ(ierr);
1210c38d4ed2SBarry Smith 
1211c38d4ed2SBarry Smith     /* Create the invert permutation so that it can be used in MatLUFactorNumeric() */
12124c49b128SBarry Smith     ierr = ISInvertPermutation(col,PETSC_DECIDE,&a->icol);CHKERRQ(ierr);
1213b0a32e0cSBarry Smith     PetscLogObjectParent(inA,a->icol);
1214c38d4ed2SBarry Smith 
1215c38d4ed2SBarry Smith     if (!a->solve_work) {
1216b0a32e0cSBarry Smith       ierr = PetscMalloc((inA->m+a->bs)*sizeof(Scalar),&a->solve_work);CHKERRQ(ierr);
1217b0a32e0cSBarry Smith       PetscLogObjectMemory(inA,(inA->m+a->bs)*sizeof(Scalar));
1218c38d4ed2SBarry Smith     }
12192d61bbb3SSatish Balay   }
12202d61bbb3SSatish Balay 
1221667159a5SBarry Smith   ierr = MatLUFactorNumeric(inA,&outA);CHKERRQ(ierr);
1222667159a5SBarry Smith 
12232d61bbb3SSatish Balay   PetscFunctionReturn(0);
12242d61bbb3SSatish Balay }
12254a2ae208SSatish Balay #undef __FUNCT__
12264a2ae208SSatish Balay #define __FUNCT__ "MatPrintHelp_SeqBAIJ"
1227ba4ca20aSSatish Balay int MatPrintHelp_SeqBAIJ(Mat A)
1228ba4ca20aSSatish Balay {
1229c38d4ed2SBarry Smith   static PetscTruth called = PETSC_FALSE;
1230ba4ca20aSSatish Balay   MPI_Comm          comm = A->comm;
1231d132466eSBarry Smith   int               ierr;
1232ba4ca20aSSatish Balay 
12333a40ed3dSBarry Smith   PetscFunctionBegin;
1234c38d4ed2SBarry Smith   if (called) {PetscFunctionReturn(0);} else called = PETSC_TRUE;
1235d132466eSBarry Smith   ierr = (*PetscHelpPrintf)(comm," Options for MATSEQBAIJ and MATMPIBAIJ matrix formats (the defaults):\n");CHKERRQ(ierr);
1236d132466eSBarry Smith   ierr = (*PetscHelpPrintf)(comm,"  -mat_block_size <block_size>\n");CHKERRQ(ierr);
12373a40ed3dSBarry Smith   PetscFunctionReturn(0);
1238ba4ca20aSSatish Balay }
1239d9b7c43dSSatish Balay 
1240fb2e594dSBarry Smith EXTERN_C_BEGIN
12414a2ae208SSatish Balay #undef __FUNCT__
12424a2ae208SSatish Balay #define __FUNCT__ "MatSeqBAIJSetColumnIndices_SeqBAIJ"
124327a8da17SBarry Smith int MatSeqBAIJSetColumnIndices_SeqBAIJ(Mat mat,int *indices)
124427a8da17SBarry Smith {
124527a8da17SBarry Smith   Mat_SeqBAIJ *baij = (Mat_SeqBAIJ *)mat->data;
124627a8da17SBarry Smith   int         i,nz,n;
124727a8da17SBarry Smith 
124827a8da17SBarry Smith   PetscFunctionBegin;
124927a8da17SBarry Smith   nz = baij->maxnz;
1250273d9f13SBarry Smith   n  = mat->n;
125127a8da17SBarry Smith   for (i=0; i<nz; i++) {
125227a8da17SBarry Smith     baij->j[i] = indices[i];
125327a8da17SBarry Smith   }
125427a8da17SBarry Smith   baij->nz = nz;
125527a8da17SBarry Smith   for (i=0; i<n; i++) {
125627a8da17SBarry Smith     baij->ilen[i] = baij->imax[i];
125727a8da17SBarry Smith   }
125827a8da17SBarry Smith 
125927a8da17SBarry Smith   PetscFunctionReturn(0);
126027a8da17SBarry Smith }
1261fb2e594dSBarry Smith EXTERN_C_END
126227a8da17SBarry Smith 
12634a2ae208SSatish Balay #undef __FUNCT__
12644a2ae208SSatish Balay #define __FUNCT__ "MatSeqBAIJSetColumnIndices"
126527a8da17SBarry Smith /*@
126627a8da17SBarry Smith     MatSeqBAIJSetColumnIndices - Set the column indices for all the rows
126727a8da17SBarry Smith        in the matrix.
126827a8da17SBarry Smith 
126927a8da17SBarry Smith   Input Parameters:
127027a8da17SBarry Smith +  mat - the SeqBAIJ matrix
127127a8da17SBarry Smith -  indices - the column indices
127227a8da17SBarry Smith 
127315091d37SBarry Smith   Level: advanced
127415091d37SBarry Smith 
127527a8da17SBarry Smith   Notes:
127627a8da17SBarry Smith     This can be called if you have precomputed the nonzero structure of the
127727a8da17SBarry Smith   matrix and want to provide it to the matrix object to improve the performance
127827a8da17SBarry Smith   of the MatSetValues() operation.
127927a8da17SBarry Smith 
128027a8da17SBarry Smith     You MUST have set the correct numbers of nonzeros per row in the call to
128127a8da17SBarry Smith   MatCreateSeqBAIJ().
128227a8da17SBarry Smith 
128327a8da17SBarry Smith     MUST be called before any calls to MatSetValues();
128427a8da17SBarry Smith 
128527a8da17SBarry Smith @*/
128627a8da17SBarry Smith int MatSeqBAIJSetColumnIndices(Mat mat,int *indices)
128727a8da17SBarry Smith {
128827a8da17SBarry Smith   int ierr,(*f)(Mat,int *);
128927a8da17SBarry Smith 
129027a8da17SBarry Smith   PetscFunctionBegin;
129127a8da17SBarry Smith   PetscValidHeaderSpecific(mat,MAT_COOKIE);
1292b9617806SBarry Smith   ierr = PetscObjectQueryFunction((PetscObject)mat,"MatSeqBAIJSetColumnIndices_C",(void (**)())&f);CHKERRQ(ierr);
129327a8da17SBarry Smith   if (f) {
129427a8da17SBarry Smith     ierr = (*f)(mat,indices);CHKERRQ(ierr);
129527a8da17SBarry Smith   } else {
129629bbc08cSBarry Smith     SETERRQ(1,"Wrong type of matrix to set column indices");
129727a8da17SBarry Smith   }
129827a8da17SBarry Smith   PetscFunctionReturn(0);
129927a8da17SBarry Smith }
130027a8da17SBarry Smith 
13014a2ae208SSatish Balay #undef __FUNCT__
13024a2ae208SSatish Balay #define __FUNCT__ "MatGetRowMax_SeqBAIJ"
1303273d9f13SBarry Smith int MatGetRowMax_SeqBAIJ(Mat A,Vec v)
1304273d9f13SBarry Smith {
1305273d9f13SBarry Smith   Mat_SeqBAIJ  *a = (Mat_SeqBAIJ*)A->data;
1306273d9f13SBarry Smith   int          ierr,i,j,n,row,bs,*ai,*aj,mbs;
1307273d9f13SBarry Smith   PetscReal    atmp;
1308273d9f13SBarry Smith   Scalar       *x,zero = 0.0;
1309273d9f13SBarry Smith   MatScalar    *aa;
1310273d9f13SBarry Smith   int          ncols,brow,krow,kcol;
1311273d9f13SBarry Smith 
1312273d9f13SBarry Smith   PetscFunctionBegin;
1313273d9f13SBarry Smith   if (A->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1314273d9f13SBarry Smith   bs   = a->bs;
1315273d9f13SBarry Smith   aa   = a->a;
1316273d9f13SBarry Smith   ai   = a->i;
1317273d9f13SBarry Smith   aj   = a->j;
1318273d9f13SBarry Smith   mbs = a->mbs;
1319273d9f13SBarry Smith 
1320273d9f13SBarry Smith   ierr = VecSet(&zero,v);CHKERRQ(ierr);
1321273d9f13SBarry Smith   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
1322273d9f13SBarry Smith   ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr);
1323273d9f13SBarry Smith   if (n != A->m) SETERRQ(PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector");
1324273d9f13SBarry Smith   for (i=0; i<mbs; i++) {
1325273d9f13SBarry Smith     ncols = ai[1] - ai[0]; ai++;
1326273d9f13SBarry Smith     brow  = bs*i;
1327273d9f13SBarry Smith     for (j=0; j<ncols; j++){
1328273d9f13SBarry Smith       /* bcol = bs*(*aj); */
1329273d9f13SBarry Smith       for (kcol=0; kcol<bs; kcol++){
1330273d9f13SBarry Smith         for (krow=0; krow<bs; krow++){
1331273d9f13SBarry Smith           atmp = PetscAbsScalar(*aa); aa++;
1332273d9f13SBarry Smith           row = brow + krow;    /* row index */
1333273d9f13SBarry Smith           /* printf("val[%d,%d]: %g\n",row,bcol+kcol,atmp); */
1334273d9f13SBarry Smith           if (PetscAbsScalar(x[row]) < atmp) x[row] = atmp;
1335273d9f13SBarry Smith         }
1336273d9f13SBarry Smith       }
1337273d9f13SBarry Smith       aj++;
1338273d9f13SBarry Smith     }
1339273d9f13SBarry Smith   }
1340273d9f13SBarry Smith   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
1341273d9f13SBarry Smith   PetscFunctionReturn(0);
1342273d9f13SBarry Smith }
1343273d9f13SBarry Smith 
13444a2ae208SSatish Balay #undef __FUNCT__
13454a2ae208SSatish Balay #define __FUNCT__ "MatSetUpPreallocation_SeqBAIJ"
1346273d9f13SBarry Smith int MatSetUpPreallocation_SeqBAIJ(Mat A)
1347273d9f13SBarry Smith {
1348273d9f13SBarry Smith   int        ierr;
1349273d9f13SBarry Smith 
1350273d9f13SBarry Smith   PetscFunctionBegin;
1351273d9f13SBarry Smith   ierr =  MatSeqBAIJSetPreallocation(A,1,PETSC_DEFAULT,0);CHKERRQ(ierr);
1352273d9f13SBarry Smith   PetscFunctionReturn(0);
1353273d9f13SBarry Smith }
1354273d9f13SBarry Smith 
13554a2ae208SSatish Balay #undef __FUNCT__
13564a2ae208SSatish Balay #define __FUNCT__ "MatGetArray_SeqBAIJ"
1357f2a5309cSSatish Balay int MatGetArray_SeqBAIJ(Mat A,Scalar **array)
1358f2a5309cSSatish Balay {
1359f2a5309cSSatish Balay   Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)A->data;
1360f2a5309cSSatish Balay   PetscFunctionBegin;
1361f2a5309cSSatish Balay   *array = a->a;
1362f2a5309cSSatish Balay   PetscFunctionReturn(0);
1363f2a5309cSSatish Balay }
1364f2a5309cSSatish Balay 
13654a2ae208SSatish Balay #undef __FUNCT__
13664a2ae208SSatish Balay #define __FUNCT__ "MatRestoreArray_SeqBAIJ"
1367f2a5309cSSatish Balay int MatRestoreArray_SeqBAIJ(Mat A,Scalar **array)
1368f2a5309cSSatish Balay {
1369f2a5309cSSatish Balay   PetscFunctionBegin;
1370f2a5309cSSatish Balay   PetscFunctionReturn(0);
1371f2a5309cSSatish Balay }
1372f2a5309cSSatish Balay 
13732593348eSBarry Smith /* -------------------------------------------------------------------*/
1374cc2dc46cSBarry Smith static struct _MatOps MatOps_Values = {MatSetValues_SeqBAIJ,
1375cc2dc46cSBarry Smith        MatGetRow_SeqBAIJ,
1376cc2dc46cSBarry Smith        MatRestoreRow_SeqBAIJ,
1377cc2dc46cSBarry Smith        MatMult_SeqBAIJ_N,
1378cc2dc46cSBarry Smith        MatMultAdd_SeqBAIJ_N,
13797c922b88SBarry Smith        MatMultTranspose_SeqBAIJ,
13807c922b88SBarry Smith        MatMultTransposeAdd_SeqBAIJ,
1381cc2dc46cSBarry Smith        MatSolve_SeqBAIJ_N,
1382cc2dc46cSBarry Smith        0,
1383cc2dc46cSBarry Smith        0,
1384cc2dc46cSBarry Smith        0,
1385cc2dc46cSBarry Smith        MatLUFactor_SeqBAIJ,
1386cc2dc46cSBarry Smith        0,
1387b6490206SBarry Smith        0,
1388f2501298SSatish Balay        MatTranspose_SeqBAIJ,
1389cc2dc46cSBarry Smith        MatGetInfo_SeqBAIJ,
1390cc2dc46cSBarry Smith        MatEqual_SeqBAIJ,
1391cc2dc46cSBarry Smith        MatGetDiagonal_SeqBAIJ,
1392cc2dc46cSBarry Smith        MatDiagonalScale_SeqBAIJ,
1393cc2dc46cSBarry Smith        MatNorm_SeqBAIJ,
1394b6490206SBarry Smith        0,
1395cc2dc46cSBarry Smith        MatAssemblyEnd_SeqBAIJ,
1396cc2dc46cSBarry Smith        0,
1397cc2dc46cSBarry Smith        MatSetOption_SeqBAIJ,
1398cc2dc46cSBarry Smith        MatZeroEntries_SeqBAIJ,
1399cc2dc46cSBarry Smith        MatZeroRows_SeqBAIJ,
1400cc2dc46cSBarry Smith        MatLUFactorSymbolic_SeqBAIJ,
1401cc2dc46cSBarry Smith        MatLUFactorNumeric_SeqBAIJ_N,
1402cc2dc46cSBarry Smith        0,
1403cc2dc46cSBarry Smith        0,
1404273d9f13SBarry Smith        MatSetUpPreallocation_SeqBAIJ,
1405273d9f13SBarry Smith        0,
1406cc2dc46cSBarry Smith        MatGetOwnershipRange_SeqBAIJ,
1407cc2dc46cSBarry Smith        MatILUFactorSymbolic_SeqBAIJ,
1408cc2dc46cSBarry Smith        0,
1409f2a5309cSSatish Balay        MatGetArray_SeqBAIJ,
1410f2a5309cSSatish Balay        MatRestoreArray_SeqBAIJ,
14112e8a6d31SBarry Smith        MatDuplicate_SeqBAIJ,
1412cc2dc46cSBarry Smith        0,
1413cc2dc46cSBarry Smith        0,
1414cc2dc46cSBarry Smith        MatILUFactor_SeqBAIJ,
1415cc2dc46cSBarry Smith        0,
1416cc2dc46cSBarry Smith        0,
1417cc2dc46cSBarry Smith        MatGetSubMatrices_SeqBAIJ,
1418cc2dc46cSBarry Smith        MatIncreaseOverlap_SeqBAIJ,
1419cc2dc46cSBarry Smith        MatGetValues_SeqBAIJ,
1420cc2dc46cSBarry Smith        0,
1421cc2dc46cSBarry Smith        MatPrintHelp_SeqBAIJ,
1422cc2dc46cSBarry Smith        MatScale_SeqBAIJ,
1423cc2dc46cSBarry Smith        0,
1424cc2dc46cSBarry Smith        0,
1425cc2dc46cSBarry Smith        0,
1426cc2dc46cSBarry Smith        MatGetBlockSize_SeqBAIJ,
14273b2fbd54SBarry Smith        MatGetRowIJ_SeqBAIJ,
142892c4ed94SBarry Smith        MatRestoreRowIJ_SeqBAIJ,
1429cc2dc46cSBarry Smith        0,
1430cc2dc46cSBarry Smith        0,
1431cc2dc46cSBarry Smith        0,
1432cc2dc46cSBarry Smith        0,
1433cc2dc46cSBarry Smith        0,
1434cc2dc46cSBarry Smith        0,
1435d3825aa8SBarry Smith        MatSetValuesBlocked_SeqBAIJ,
1436cc2dc46cSBarry Smith        MatGetSubMatrix_SeqBAIJ,
1437b9b97703SBarry Smith        MatDestroy_SeqBAIJ,
1438b9b97703SBarry Smith        MatView_SeqBAIJ,
1439273d9f13SBarry Smith        MatGetMaps_Petsc,
1440273d9f13SBarry Smith        0,
1441273d9f13SBarry Smith        0,
1442273d9f13SBarry Smith        0,
1443273d9f13SBarry Smith        0,
1444273d9f13SBarry Smith        0,
1445273d9f13SBarry Smith        0,
1446273d9f13SBarry Smith        MatGetRowMax_SeqBAIJ,
1447273d9f13SBarry Smith        MatConvert_Basic};
14482593348eSBarry Smith 
14493e90b805SBarry Smith EXTERN_C_BEGIN
14504a2ae208SSatish Balay #undef __FUNCT__
14514a2ae208SSatish Balay #define __FUNCT__ "MatStoreValues_SeqBAIJ"
14523e90b805SBarry Smith int MatStoreValues_SeqBAIJ(Mat mat)
14533e90b805SBarry Smith {
14543e90b805SBarry Smith   Mat_SeqBAIJ *aij = (Mat_SeqBAIJ *)mat->data;
1455273d9f13SBarry Smith   int         nz = aij->i[mat->m]*aij->bs*aij->bs2;
1456d132466eSBarry Smith   int         ierr;
14573e90b805SBarry Smith 
14583e90b805SBarry Smith   PetscFunctionBegin;
14593e90b805SBarry Smith   if (aij->nonew != 1) {
146029bbc08cSBarry Smith     SETERRQ(1,"Must call MatSetOption(A,MAT_NO_NEW_NONZERO_LOCATIONS);first");
14613e90b805SBarry Smith   }
14623e90b805SBarry Smith 
14633e90b805SBarry Smith   /* allocate space for values if not already there */
14643e90b805SBarry Smith   if (!aij->saved_values) {
1465f2a5309cSSatish Balay     ierr = PetscMalloc((nz+1)*sizeof(Scalar),&aij->saved_values);CHKERRQ(ierr);
14663e90b805SBarry Smith   }
14673e90b805SBarry Smith 
14683e90b805SBarry Smith   /* copy values over */
1469d132466eSBarry Smith   ierr = PetscMemcpy(aij->saved_values,aij->a,nz*sizeof(Scalar));CHKERRQ(ierr);
14703e90b805SBarry Smith   PetscFunctionReturn(0);
14713e90b805SBarry Smith }
14723e90b805SBarry Smith EXTERN_C_END
14733e90b805SBarry Smith 
14743e90b805SBarry Smith EXTERN_C_BEGIN
14754a2ae208SSatish Balay #undef __FUNCT__
14764a2ae208SSatish Balay #define __FUNCT__ "MatRetrieveValues_SeqBAIJ"
147732e87ba3SBarry Smith int MatRetrieveValues_SeqBAIJ(Mat mat)
14783e90b805SBarry Smith {
14793e90b805SBarry Smith   Mat_SeqBAIJ *aij = (Mat_SeqBAIJ *)mat->data;
1480273d9f13SBarry Smith   int         nz = aij->i[mat->m]*aij->bs*aij->bs2,ierr;
14813e90b805SBarry Smith 
14823e90b805SBarry Smith   PetscFunctionBegin;
14833e90b805SBarry Smith   if (aij->nonew != 1) {
148429bbc08cSBarry Smith     SETERRQ(1,"Must call MatSetOption(A,MAT_NO_NEW_NONZERO_LOCATIONS);first");
14853e90b805SBarry Smith   }
14863e90b805SBarry Smith   if (!aij->saved_values) {
148729bbc08cSBarry Smith     SETERRQ(1,"Must call MatStoreValues(A);first");
14883e90b805SBarry Smith   }
14893e90b805SBarry Smith 
14903e90b805SBarry Smith   /* copy values over */
1491549d3d68SSatish Balay   ierr = PetscMemcpy(aij->a,aij->saved_values,nz*sizeof(Scalar));CHKERRQ(ierr);
14923e90b805SBarry Smith   PetscFunctionReturn(0);
14933e90b805SBarry Smith }
14943e90b805SBarry Smith EXTERN_C_END
14953e90b805SBarry Smith 
1496273d9f13SBarry Smith EXTERN_C_BEGIN
1497273d9f13SBarry Smith extern int MatConvert_SeqBAIJ_SeqAIJ(Mat,MatType,Mat*);
1498273d9f13SBarry Smith EXTERN_C_END
1499273d9f13SBarry Smith 
1500273d9f13SBarry Smith EXTERN_C_BEGIN
15014a2ae208SSatish Balay #undef __FUNCT__
15024a2ae208SSatish Balay #define __FUNCT__ "MatCreate_SeqBAIJ"
1503273d9f13SBarry Smith int MatCreate_SeqBAIJ(Mat B)
15042593348eSBarry Smith {
1505273d9f13SBarry Smith   int         ierr,size;
1506b6490206SBarry Smith   Mat_SeqBAIJ *b;
15073b2fbd54SBarry Smith 
15083a40ed3dSBarry Smith   PetscFunctionBegin;
1509273d9f13SBarry Smith   ierr = MPI_Comm_size(B->comm,&size);CHKERRQ(ierr);
151029bbc08cSBarry Smith   if (size > 1) SETERRQ(PETSC_ERR_ARG_WRONG,"Comm must be of size 1");
1511b6490206SBarry Smith 
1512273d9f13SBarry Smith   B->m = B->M = PetscMax(B->m,B->M);
1513273d9f13SBarry Smith   B->n = B->N = PetscMax(B->n,B->N);
1514b0a32e0cSBarry Smith   ierr    = PetscNew(Mat_SeqBAIJ,&b);CHKERRQ(ierr);
1515b0a32e0cSBarry Smith   B->data = (void*)b;
1516549d3d68SSatish Balay   ierr    = PetscMemzero(b,sizeof(Mat_SeqBAIJ));CHKERRQ(ierr);
1517549d3d68SSatish Balay   ierr    = PetscMemcpy(B->ops,&MatOps_Values,sizeof(struct _MatOps));CHKERRQ(ierr);
15182593348eSBarry Smith   B->factor           = 0;
15192593348eSBarry Smith   B->lupivotthreshold = 1.0;
152090f02eecSBarry Smith   B->mapping          = 0;
15212593348eSBarry Smith   b->row              = 0;
15222593348eSBarry Smith   b->col              = 0;
1523e51c0b9cSSatish Balay   b->icol             = 0;
15242593348eSBarry Smith   b->reallocs         = 0;
15253e90b805SBarry Smith   b->saved_values     = 0;
1526cfce73b9SSatish Balay #if defined(PETSC_USE_MAT_SINGLE)
1527563b5814SBarry Smith   b->setvalueslen     = 0;
1528563b5814SBarry Smith   b->setvaluescopy    = PETSC_NULL;
1529563b5814SBarry Smith #endif
15302593348eSBarry Smith 
1531273d9f13SBarry Smith   ierr = MapCreateMPI(B->comm,B->m,B->m,&B->rmap);CHKERRQ(ierr);
1532273d9f13SBarry Smith   ierr = MapCreateMPI(B->comm,B->n,B->n,&B->cmap);CHKERRQ(ierr);
1533a5ae1ecdSBarry Smith 
1534c4992f7dSBarry Smith   b->sorted           = PETSC_FALSE;
1535c4992f7dSBarry Smith   b->roworiented      = PETSC_TRUE;
15362593348eSBarry Smith   b->nonew            = 0;
15372593348eSBarry Smith   b->diag             = 0;
15382593348eSBarry Smith   b->solve_work       = 0;
1539de6a44a3SBarry Smith   b->mult_work        = 0;
15402593348eSBarry Smith   b->spptr            = 0;
15410e6d2581SBarry Smith   B->info.nz_unneeded = (PetscReal)b->maxnz;
1542883fce79SBarry Smith   b->keepzeroedrows   = PETSC_FALSE;
15434e220ebcSLois Curfman McInnes 
1544f1af5d2fSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatStoreValues_C",
15453e90b805SBarry Smith                                      "MatStoreValues_SeqBAIJ",
1546bc4b532fSSatish Balay                                       MatStoreValues_SeqBAIJ);CHKERRQ(ierr);
1547f1af5d2fSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatRetrieveValues_C",
15483e90b805SBarry Smith                                      "MatRetrieveValues_SeqBAIJ",
1549bc4b532fSSatish Balay                                       MatRetrieveValues_SeqBAIJ);CHKERRQ(ierr);
1550f1af5d2fSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatSeqBAIJSetColumnIndices_C",
155127a8da17SBarry Smith                                      "MatSeqBAIJSetColumnIndices_SeqBAIJ",
1552bc4b532fSSatish Balay                                       MatSeqBAIJSetColumnIndices_SeqBAIJ);CHKERRQ(ierr);
1553273d9f13SBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatConvert_SeqBAIJ_SeqAIJ_C",
1554273d9f13SBarry Smith                                      "MatConvert_SeqBAIJ_SeqAIJ",
1555273d9f13SBarry Smith                                       MatConvert_SeqBAIJ_SeqAIJ);CHKERRQ(ierr);
15563a40ed3dSBarry Smith   PetscFunctionReturn(0);
15572593348eSBarry Smith }
1558273d9f13SBarry Smith EXTERN_C_END
15592593348eSBarry Smith 
15604a2ae208SSatish Balay #undef __FUNCT__
15614a2ae208SSatish Balay #define __FUNCT__ "MatDuplicate_SeqBAIJ"
15622e8a6d31SBarry Smith int MatDuplicate_SeqBAIJ(Mat A,MatDuplicateOption cpvalues,Mat *B)
15632593348eSBarry Smith {
15642593348eSBarry Smith   Mat         C;
1565b6490206SBarry Smith   Mat_SeqBAIJ *c,*a = (Mat_SeqBAIJ*)A->data;
156627a8da17SBarry Smith   int         i,len,mbs = a->mbs,nz = a->nz,bs2 =a->bs2,ierr;
1567de6a44a3SBarry Smith 
15683a40ed3dSBarry Smith   PetscFunctionBegin;
156929bbc08cSBarry Smith   if (a->i[mbs] != nz) SETERRQ(PETSC_ERR_PLIB,"Corrupt matrix");
15702593348eSBarry Smith 
15712593348eSBarry Smith   *B = 0;
1572273d9f13SBarry Smith   ierr = MatCreate(A->comm,A->m,A->n,A->m,A->n,&C);CHKERRQ(ierr);
1573273d9f13SBarry Smith   ierr = MatSetType(C,MATSEQBAIJ);CHKERRQ(ierr);
1574273d9f13SBarry Smith   c    = (Mat_SeqBAIJ*)C->data;
157544cd7ae7SLois Curfman McInnes 
1576b6490206SBarry Smith   c->bs         = a->bs;
15779df24120SSatish Balay   c->bs2        = a->bs2;
1578b6490206SBarry Smith   c->mbs        = a->mbs;
1579b6490206SBarry Smith   c->nbs        = a->nbs;
158035d8aa7fSBarry Smith   ierr = PetscMemcpy(C->ops,A->ops,sizeof(struct _MatOps));CHKERRQ(ierr);
15812593348eSBarry Smith 
1582b0a32e0cSBarry Smith   ierr = PetscMalloc((mbs+1)*sizeof(int),&c->imax);CHKERRQ(ierr);
1583b0a32e0cSBarry Smith   ierr = PetscMalloc((mbs+1)*sizeof(int),&c->ilen);CHKERRQ(ierr);
1584b6490206SBarry Smith   for (i=0; i<mbs; i++) {
15852593348eSBarry Smith     c->imax[i] = a->imax[i];
15862593348eSBarry Smith     c->ilen[i] = a->ilen[i];
15872593348eSBarry Smith   }
15882593348eSBarry Smith 
15892593348eSBarry Smith   /* allocate the matrix space */
1590c4992f7dSBarry Smith   c->singlemalloc = PETSC_TRUE;
15913f1db9ecSBarry Smith   len  = (mbs+1)*sizeof(int) + nz*(bs2*sizeof(MatScalar) + sizeof(int));
1592b0a32e0cSBarry Smith   ierr = PetscMalloc(len,&c->a);CHKERRQ(ierr);
15937e67e3f9SSatish Balay   c->j = (int*)(c->a + nz*bs2);
1594de6a44a3SBarry Smith   c->i = c->j + nz;
1595549d3d68SSatish Balay   ierr = PetscMemcpy(c->i,a->i,(mbs+1)*sizeof(int));CHKERRQ(ierr);
1596b6490206SBarry Smith   if (mbs > 0) {
1597549d3d68SSatish Balay     ierr = PetscMemcpy(c->j,a->j,nz*sizeof(int));CHKERRQ(ierr);
15982e8a6d31SBarry Smith     if (cpvalues == MAT_COPY_VALUES) {
1599549d3d68SSatish Balay       ierr = PetscMemcpy(c->a,a->a,bs2*nz*sizeof(MatScalar));CHKERRQ(ierr);
16002e8a6d31SBarry Smith     } else {
1601549d3d68SSatish Balay       ierr = PetscMemzero(c->a,bs2*nz*sizeof(MatScalar));CHKERRQ(ierr);
16022593348eSBarry Smith     }
16032593348eSBarry Smith   }
16042593348eSBarry Smith 
1605b0a32e0cSBarry Smith   PetscLogObjectMemory(C,len+2*(mbs+1)*sizeof(int)+sizeof(struct _p_Mat)+sizeof(Mat_SeqBAIJ));
16062593348eSBarry Smith   c->sorted      = a->sorted;
16072593348eSBarry Smith   c->roworiented = a->roworiented;
16082593348eSBarry Smith   c->nonew       = a->nonew;
16092593348eSBarry Smith 
16102593348eSBarry Smith   if (a->diag) {
1611b0a32e0cSBarry Smith     ierr = PetscMalloc((mbs+1)*sizeof(int),&c->diag);CHKERRQ(ierr);
1612b0a32e0cSBarry Smith     PetscLogObjectMemory(C,(mbs+1)*sizeof(int));
1613b6490206SBarry Smith     for (i=0; i<mbs; i++) {
16142593348eSBarry Smith       c->diag[i] = a->diag[i];
16152593348eSBarry Smith     }
161698305bb5SBarry Smith   } else c->diag        = 0;
16172593348eSBarry Smith   c->nz                 = a->nz;
16182593348eSBarry Smith   c->maxnz              = a->maxnz;
16192593348eSBarry Smith   c->solve_work         = 0;
16202593348eSBarry Smith   c->spptr              = 0;      /* Dangerous -I'm throwing away a->spptr */
16217fc0212eSBarry Smith   c->mult_work          = 0;
1622273d9f13SBarry Smith   C->preallocated       = PETSC_TRUE;
1623273d9f13SBarry Smith   C->assembled          = PETSC_TRUE;
16242593348eSBarry Smith   *B = C;
1625b0a32e0cSBarry Smith   ierr = PetscFListDuplicate(A->qlist,&C->qlist);CHKERRQ(ierr);
16263a40ed3dSBarry Smith   PetscFunctionReturn(0);
16272593348eSBarry Smith }
16282593348eSBarry Smith 
1629273d9f13SBarry Smith EXTERN_C_BEGIN
16304a2ae208SSatish Balay #undef __FUNCT__
16314a2ae208SSatish Balay #define __FUNCT__ "MatLoad_SeqBAIJ"
1632b0a32e0cSBarry Smith int MatLoad_SeqBAIJ(PetscViewer viewer,MatType type,Mat *A)
16332593348eSBarry Smith {
1634b6490206SBarry Smith   Mat_SeqBAIJ  *a;
16352593348eSBarry Smith   Mat          B;
1636f1af5d2fSBarry Smith   int          i,nz,ierr,fd,header[4],size,*rowlengths=0,M,N,bs=1;
1637b6490206SBarry Smith   int          *mask,mbs,*jj,j,rowcount,nzcount,k,*browlengths,maskcount;
163835aab85fSBarry Smith   int          kmax,jcount,block,idx,point,nzcountb,extra_rows;
1639a7c10996SSatish Balay   int          *masked,nmask,tmp,bs2,ishift;
1640b6490206SBarry Smith   Scalar       *aa;
164119bcc07fSBarry Smith   MPI_Comm     comm = ((PetscObject)viewer)->comm;
16422593348eSBarry Smith 
16433a40ed3dSBarry Smith   PetscFunctionBegin;
1644b0a32e0cSBarry Smith   ierr = PetscOptionsGetInt(PETSC_NULL,"-matload_block_size",&bs,PETSC_NULL);CHKERRQ(ierr);
1645de6a44a3SBarry Smith   bs2  = bs*bs;
1646b6490206SBarry Smith 
1647d132466eSBarry Smith   ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr);
164829bbc08cSBarry Smith   if (size > 1) SETERRQ(PETSC_ERR_ARG_WRONG,"view must have one processor");
1649b0a32e0cSBarry Smith   ierr = PetscViewerBinaryGetDescriptor(viewer,&fd);CHKERRQ(ierr);
16500752156aSBarry Smith   ierr = PetscBinaryRead(fd,header,4,PETSC_INT);CHKERRQ(ierr);
165129bbc08cSBarry Smith   if (header[0] != MAT_COOKIE) SETERRQ(PETSC_ERR_FILE_UNEXPECTED,"not Mat object");
16522593348eSBarry Smith   M = header[1]; N = header[2]; nz = header[3];
16532593348eSBarry Smith 
1654d64ed03dSBarry Smith   if (header[3] < 0) {
165529bbc08cSBarry Smith     SETERRQ(PETSC_ERR_FILE_UNEXPECTED,"Matrix stored in special format, cannot load as SeqBAIJ");
1656d64ed03dSBarry Smith   }
1657d64ed03dSBarry Smith 
165829bbc08cSBarry Smith   if (M != N) SETERRQ(PETSC_ERR_SUP,"Can only do square matrices");
165935aab85fSBarry Smith 
166035aab85fSBarry Smith   /*
166135aab85fSBarry Smith      This code adds extra rows to make sure the number of rows is
166235aab85fSBarry Smith     divisible by the blocksize
166335aab85fSBarry Smith   */
1664b6490206SBarry Smith   mbs        = M/bs;
166535aab85fSBarry Smith   extra_rows = bs - M + bs*(mbs);
166635aab85fSBarry Smith   if (extra_rows == bs) extra_rows = 0;
166735aab85fSBarry Smith   else                  mbs++;
166835aab85fSBarry Smith   if (extra_rows) {
1669b0a32e0cSBarry Smith     PetscLogInfo(0,"MatLoad_SeqBAIJ:Padding loaded matrix to match blocksize\n");
167035aab85fSBarry Smith   }
1671b6490206SBarry Smith 
16722593348eSBarry Smith   /* read in row lengths */
1673b0a32e0cSBarry Smith   ierr = PetscMalloc((M+extra_rows)*sizeof(int),&rowlengths);CHKERRQ(ierr);
16740752156aSBarry Smith   ierr = PetscBinaryRead(fd,rowlengths,M,PETSC_INT);CHKERRQ(ierr);
167535aab85fSBarry Smith   for (i=0; i<extra_rows; i++) rowlengths[M+i] = 1;
16762593348eSBarry Smith 
1677b6490206SBarry Smith   /* read in column indices */
1678b0a32e0cSBarry Smith   ierr = PetscMalloc((nz+extra_rows)*sizeof(int),&jj);CHKERRQ(ierr);
16790752156aSBarry Smith   ierr = PetscBinaryRead(fd,jj,nz,PETSC_INT);CHKERRQ(ierr);
168035aab85fSBarry Smith   for (i=0; i<extra_rows; i++) jj[nz+i] = M+i;
1681b6490206SBarry Smith 
1682b6490206SBarry Smith   /* loop over row lengths determining block row lengths */
1683b0a32e0cSBarry Smith   ierr     = PetscMalloc(mbs*sizeof(int),&browlengths);CHKERRQ(ierr);
1684549d3d68SSatish Balay   ierr     = PetscMemzero(browlengths,mbs*sizeof(int));CHKERRQ(ierr);
1685b0a32e0cSBarry Smith   ierr     = PetscMalloc(2*mbs*sizeof(int),&mask);CHKERRQ(ierr);
1686549d3d68SSatish Balay   ierr     = PetscMemzero(mask,mbs*sizeof(int));CHKERRQ(ierr);
168735aab85fSBarry Smith   masked   = mask + mbs;
1688b6490206SBarry Smith   rowcount = 0; nzcount = 0;
1689b6490206SBarry Smith   for (i=0; i<mbs; i++) {
169035aab85fSBarry Smith     nmask = 0;
1691b6490206SBarry Smith     for (j=0; j<bs; j++) {
1692b6490206SBarry Smith       kmax = rowlengths[rowcount];
1693b6490206SBarry Smith       for (k=0; k<kmax; k++) {
169435aab85fSBarry Smith         tmp = jj[nzcount++]/bs;
169535aab85fSBarry Smith         if (!mask[tmp]) {masked[nmask++] = tmp; mask[tmp] = 1;}
1696b6490206SBarry Smith       }
1697b6490206SBarry Smith       rowcount++;
1698b6490206SBarry Smith     }
169935aab85fSBarry Smith     browlengths[i] += nmask;
170035aab85fSBarry Smith     /* zero out the mask elements we set */
170135aab85fSBarry Smith     for (j=0; j<nmask; j++) mask[masked[j]] = 0;
1702b6490206SBarry Smith   }
1703b6490206SBarry Smith 
17042593348eSBarry Smith   /* create our matrix */
17053eee16b0SBarry Smith   ierr = MatCreateSeqBAIJ(comm,bs,M+extra_rows,N+extra_rows,0,browlengths,A);CHKERRQ(ierr);
17062593348eSBarry Smith   B = *A;
1707b6490206SBarry Smith   a = (Mat_SeqBAIJ*)B->data;
17082593348eSBarry Smith 
17092593348eSBarry Smith   /* set matrix "i" values */
1710de6a44a3SBarry Smith   a->i[0] = 0;
1711b6490206SBarry Smith   for (i=1; i<= mbs; i++) {
1712b6490206SBarry Smith     a->i[i]      = a->i[i-1] + browlengths[i-1];
1713b6490206SBarry Smith     a->ilen[i-1] = browlengths[i-1];
17142593348eSBarry Smith   }
1715b6490206SBarry Smith   a->nz         = 0;
1716b6490206SBarry Smith   for (i=0; i<mbs; i++) a->nz += browlengths[i];
17172593348eSBarry Smith 
1718b6490206SBarry Smith   /* read in nonzero values */
1719b0a32e0cSBarry Smith   ierr = PetscMalloc((nz+extra_rows)*sizeof(Scalar),&aa);CHKERRQ(ierr);
17200752156aSBarry Smith   ierr = PetscBinaryRead(fd,aa,nz,PETSC_SCALAR);CHKERRQ(ierr);
172135aab85fSBarry Smith   for (i=0; i<extra_rows; i++) aa[nz+i] = 1.0;
1722b6490206SBarry Smith 
1723b6490206SBarry Smith   /* set "a" and "j" values into matrix */
1724b6490206SBarry Smith   nzcount = 0; jcount = 0;
1725b6490206SBarry Smith   for (i=0; i<mbs; i++) {
1726b6490206SBarry Smith     nzcountb = nzcount;
172735aab85fSBarry Smith     nmask    = 0;
1728b6490206SBarry Smith     for (j=0; j<bs; j++) {
1729b6490206SBarry Smith       kmax = rowlengths[i*bs+j];
1730b6490206SBarry Smith       for (k=0; k<kmax; k++) {
173135aab85fSBarry Smith         tmp = jj[nzcount++]/bs;
173235aab85fSBarry Smith 	if (!mask[tmp]) { masked[nmask++] = tmp; mask[tmp] = 1;}
1733b6490206SBarry Smith       }
1734b6490206SBarry Smith     }
1735de6a44a3SBarry Smith     /* sort the masked values */
1736433994e6SBarry Smith     ierr = PetscSortInt(nmask,masked);CHKERRQ(ierr);
1737de6a44a3SBarry Smith 
1738b6490206SBarry Smith     /* set "j" values into matrix */
1739b6490206SBarry Smith     maskcount = 1;
174035aab85fSBarry Smith     for (j=0; j<nmask; j++) {
174135aab85fSBarry Smith       a->j[jcount++]  = masked[j];
1742de6a44a3SBarry Smith       mask[masked[j]] = maskcount++;
1743b6490206SBarry Smith     }
1744b6490206SBarry Smith     /* set "a" values into matrix */
1745de6a44a3SBarry Smith     ishift = bs2*a->i[i];
1746b6490206SBarry Smith     for (j=0; j<bs; j++) {
1747b6490206SBarry Smith       kmax = rowlengths[i*bs+j];
1748b6490206SBarry Smith       for (k=0; k<kmax; k++) {
1749de6a44a3SBarry Smith         tmp       = jj[nzcountb]/bs ;
1750de6a44a3SBarry Smith         block     = mask[tmp] - 1;
1751de6a44a3SBarry Smith         point     = jj[nzcountb] - bs*tmp;
1752de6a44a3SBarry Smith         idx       = ishift + bs2*block + j + bs*point;
1753375fe846SBarry Smith         a->a[idx] = (MatScalar)aa[nzcountb++];
1754b6490206SBarry Smith       }
1755b6490206SBarry Smith     }
175635aab85fSBarry Smith     /* zero out the mask elements we set */
175735aab85fSBarry Smith     for (j=0; j<nmask; j++) mask[masked[j]] = 0;
1758b6490206SBarry Smith   }
175929bbc08cSBarry Smith   if (jcount != a->nz) SETERRQ(PETSC_ERR_FILE_UNEXPECTED,"Bad binary matrix");
1760b6490206SBarry Smith 
1761606d414cSSatish Balay   ierr = PetscFree(rowlengths);CHKERRQ(ierr);
1762606d414cSSatish Balay   ierr = PetscFree(browlengths);CHKERRQ(ierr);
1763606d414cSSatish Balay   ierr = PetscFree(aa);CHKERRQ(ierr);
1764606d414cSSatish Balay   ierr = PetscFree(jj);CHKERRQ(ierr);
1765606d414cSSatish Balay   ierr = PetscFree(mask);CHKERRQ(ierr);
1766b6490206SBarry Smith 
1767b6490206SBarry Smith   B->assembled = PETSC_TRUE;
1768de6a44a3SBarry Smith 
17699c01be13SBarry Smith   ierr = MatView_Private(B);CHKERRQ(ierr);
17703a40ed3dSBarry Smith   PetscFunctionReturn(0);
17712593348eSBarry Smith }
1772273d9f13SBarry Smith EXTERN_C_END
17732593348eSBarry Smith 
17744a2ae208SSatish Balay #undef __FUNCT__
17754a2ae208SSatish Balay #define __FUNCT__ "MatCreateSeqBAIJ"
1776273d9f13SBarry Smith /*@C
1777273d9f13SBarry Smith    MatCreateSeqBAIJ - Creates a sparse matrix in block AIJ (block
1778273d9f13SBarry Smith    compressed row) format.  For good matrix assembly performance the
1779273d9f13SBarry Smith    user should preallocate the matrix storage by setting the parameter nz
1780273d9f13SBarry Smith    (or the array nnz).  By setting these parameters accurately, performance
1781273d9f13SBarry Smith    during matrix assembly can be increased by more than a factor of 50.
17822593348eSBarry Smith 
1783273d9f13SBarry Smith    Collective on MPI_Comm
1784273d9f13SBarry Smith 
1785273d9f13SBarry Smith    Input Parameters:
1786273d9f13SBarry Smith +  comm - MPI communicator, set to PETSC_COMM_SELF
1787273d9f13SBarry Smith .  bs - size of block
1788273d9f13SBarry Smith .  m - number of rows
1789273d9f13SBarry Smith .  n - number of columns
179035d8aa7fSBarry Smith .  nz - number of nonzero blocks  per block row (same for all rows)
179135d8aa7fSBarry Smith -  nnz - array containing the number of nonzero blocks in the various block rows
1792273d9f13SBarry Smith          (possibly different for each block row) or PETSC_NULL
1793273d9f13SBarry Smith 
1794273d9f13SBarry Smith    Output Parameter:
1795273d9f13SBarry Smith .  A - the matrix
1796273d9f13SBarry Smith 
1797273d9f13SBarry Smith    Options Database Keys:
1798273d9f13SBarry Smith .   -mat_no_unroll - uses code that does not unroll the loops in the
1799273d9f13SBarry Smith                      block calculations (much slower)
1800273d9f13SBarry Smith .    -mat_block_size - size of the blocks to use
1801273d9f13SBarry Smith 
1802273d9f13SBarry Smith    Level: intermediate
1803273d9f13SBarry Smith 
1804273d9f13SBarry Smith    Notes:
180535d8aa7fSBarry Smith    A nonzero block is any block that as 1 or more nonzeros in it
180635d8aa7fSBarry Smith 
1807273d9f13SBarry Smith    The block AIJ format is fully compatible with standard Fortran 77
1808273d9f13SBarry Smith    storage.  That is, the stored row and column indices can begin at
1809273d9f13SBarry Smith    either one (as in Fortran) or zero.  See the users' manual for details.
1810273d9f13SBarry Smith 
1811273d9f13SBarry Smith    Specify the preallocated storage with either nz or nnz (not both).
1812273d9f13SBarry Smith    Set nz=PETSC_DEFAULT and nnz=PETSC_NULL for PETSc to control dynamic memory
1813273d9f13SBarry Smith    allocation.  For additional details, see the users manual chapter on
1814273d9f13SBarry Smith    matrices.
1815273d9f13SBarry Smith 
1816273d9f13SBarry Smith .seealso: MatCreate(), MatCreateSeqAIJ(), MatSetValues(), MatCreateMPIBAIJ()
1817273d9f13SBarry Smith @*/
1818273d9f13SBarry Smith int MatCreateSeqBAIJ(MPI_Comm comm,int bs,int m,int n,int nz,int *nnz,Mat *A)
1819273d9f13SBarry Smith {
1820273d9f13SBarry Smith   int ierr;
1821273d9f13SBarry Smith 
1822273d9f13SBarry Smith   PetscFunctionBegin;
1823273d9f13SBarry Smith   ierr = MatCreate(comm,m,n,m,n,A);CHKERRQ(ierr);
1824273d9f13SBarry Smith   ierr = MatSetType(*A,MATSEQBAIJ);CHKERRQ(ierr);
1825273d9f13SBarry Smith   ierr = MatSeqBAIJSetPreallocation(*A,bs,nz,nnz);CHKERRQ(ierr);
1826273d9f13SBarry Smith   PetscFunctionReturn(0);
1827273d9f13SBarry Smith }
1828273d9f13SBarry Smith 
18294a2ae208SSatish Balay #undef __FUNCT__
18304a2ae208SSatish Balay #define __FUNCT__ "MatSeqBAIJSetPreallocation"
1831273d9f13SBarry Smith /*@C
1832273d9f13SBarry Smith    MatSeqBAIJSetPreallocation - Sets the block size and expected nonzeros
1833273d9f13SBarry Smith    per row in the matrix. For good matrix assembly performance the
1834273d9f13SBarry Smith    user should preallocate the matrix storage by setting the parameter nz
1835273d9f13SBarry Smith    (or the array nnz).  By setting these parameters accurately, performance
1836273d9f13SBarry Smith    during matrix assembly can be increased by more than a factor of 50.
1837273d9f13SBarry Smith 
1838273d9f13SBarry Smith    Collective on MPI_Comm
1839273d9f13SBarry Smith 
1840273d9f13SBarry Smith    Input Parameters:
1841273d9f13SBarry Smith +  A - the matrix
1842273d9f13SBarry Smith .  bs - size of block
1843273d9f13SBarry Smith .  nz - number of block nonzeros per block row (same for all rows)
1844273d9f13SBarry Smith -  nnz - array containing the number of block nonzeros in the various block rows
1845273d9f13SBarry Smith          (possibly different for each block row) or PETSC_NULL
1846273d9f13SBarry Smith 
1847273d9f13SBarry Smith    Options Database Keys:
1848273d9f13SBarry Smith .   -mat_no_unroll - uses code that does not unroll the loops in the
1849273d9f13SBarry Smith                      block calculations (much slower)
1850273d9f13SBarry Smith .    -mat_block_size - size of the blocks to use
1851273d9f13SBarry Smith 
1852273d9f13SBarry Smith    Level: intermediate
1853273d9f13SBarry Smith 
1854273d9f13SBarry Smith    Notes:
1855273d9f13SBarry Smith    The block AIJ format is fully compatible with standard Fortran 77
1856273d9f13SBarry Smith    storage.  That is, the stored row and column indices can begin at
1857273d9f13SBarry Smith    either one (as in Fortran) or zero.  See the users' manual for details.
1858273d9f13SBarry Smith 
1859273d9f13SBarry Smith    Specify the preallocated storage with either nz or nnz (not both).
1860273d9f13SBarry Smith    Set nz=PETSC_DEFAULT and nnz=PETSC_NULL for PETSc to control dynamic memory
1861273d9f13SBarry Smith    allocation.  For additional details, see the users manual chapter on
1862273d9f13SBarry Smith    matrices.
1863273d9f13SBarry Smith 
1864273d9f13SBarry Smith .seealso: MatCreate(), MatCreateSeqAIJ(), MatSetValues(), MatCreateMPIBAIJ()
1865273d9f13SBarry Smith @*/
1866273d9f13SBarry Smith int MatSeqBAIJSetPreallocation(Mat B,int bs,int nz,int *nnz)
1867273d9f13SBarry Smith {
1868273d9f13SBarry Smith   Mat_SeqBAIJ *b;
1869273d9f13SBarry Smith   int         i,len,ierr,mbs,nbs,bs2,newbs = bs;
1870273d9f13SBarry Smith   PetscTruth  flg;
1871273d9f13SBarry Smith 
1872273d9f13SBarry Smith   PetscFunctionBegin;
1873273d9f13SBarry Smith   ierr = PetscTypeCompare((PetscObject)B,MATSEQBAIJ,&flg);CHKERRQ(ierr);
1874273d9f13SBarry Smith   if (!flg) PetscFunctionReturn(0);
1875273d9f13SBarry Smith 
1876273d9f13SBarry Smith   B->preallocated = PETSC_TRUE;
1877b0a32e0cSBarry Smith   ierr = PetscOptionsGetInt(B->prefix,"-mat_block_size",&newbs,PETSC_NULL);CHKERRQ(ierr);
1878273d9f13SBarry Smith   if (nnz && newbs != bs) {
1879273d9f13SBarry Smith     SETERRQ(1,"Cannot change blocksize from command line if setting nnz");
1880273d9f13SBarry Smith   }
1881273d9f13SBarry Smith   bs   = newbs;
1882273d9f13SBarry Smith 
1883273d9f13SBarry Smith   mbs  = B->m/bs;
1884273d9f13SBarry Smith   nbs  = B->n/bs;
1885273d9f13SBarry Smith   bs2  = bs*bs;
1886273d9f13SBarry Smith 
1887273d9f13SBarry Smith   if (mbs*bs!=B->m || nbs*bs!=B->n) {
188835d8aa7fSBarry Smith     SETERRQ3(PETSC_ERR_ARG_SIZ,"Number rows %d, cols %d must be divisible by blocksize %d",B->m,B->n,bs);
1889273d9f13SBarry Smith   }
1890273d9f13SBarry Smith 
1891435da068SBarry Smith   if (nz == PETSC_DEFAULT || nz == PETSC_DECIDE) nz = 5;
1892435da068SBarry Smith   if (nz < 0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"nz cannot be less than 0: value %d",nz);
1893273d9f13SBarry Smith   if (nnz) {
1894273d9f13SBarry Smith     for (i=0; i<mbs; i++) {
1895273d9f13SBarry Smith       if (nnz[i] < 0) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"nnz cannot be less than 0: local row %d value %d",i,nnz[i]);
1896*3a7fca6bSBarry Smith       if (nnz[i] > nbs) SETERRQ3(PETSC_ERR_ARG_OUTOFRANGE,"nnz cannot be greater than block row length: local row %d value %d rowlength %d",i,nnz[i],nbs);
1897273d9f13SBarry Smith     }
1898273d9f13SBarry Smith   }
1899273d9f13SBarry Smith 
1900273d9f13SBarry Smith   b       = (Mat_SeqBAIJ*)B->data;
1901b0a32e0cSBarry Smith   ierr    = PetscOptionsHasName(PETSC_NULL,"-mat_no_unroll",&flg);CHKERRQ(ierr);
1902273d9f13SBarry Smith   if (!flg) {
1903273d9f13SBarry Smith     switch (bs) {
1904273d9f13SBarry Smith     case 1:
1905273d9f13SBarry Smith       B->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_1;
1906273d9f13SBarry Smith       B->ops->solve           = MatSolve_SeqBAIJ_1;
1907273d9f13SBarry Smith       B->ops->solvetranspose  = MatSolveTranspose_SeqBAIJ_1;
1908273d9f13SBarry Smith       B->ops->mult            = MatMult_SeqBAIJ_1;
1909273d9f13SBarry Smith       B->ops->multadd         = MatMultAdd_SeqBAIJ_1;
1910273d9f13SBarry Smith       break;
1911273d9f13SBarry Smith     case 2:
1912273d9f13SBarry Smith       B->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_2;
1913273d9f13SBarry Smith       B->ops->solve           = MatSolve_SeqBAIJ_2;
1914273d9f13SBarry Smith       B->ops->solvetranspose  = MatSolveTranspose_SeqBAIJ_2;
1915273d9f13SBarry Smith       B->ops->mult            = MatMult_SeqBAIJ_2;
1916273d9f13SBarry Smith       B->ops->multadd         = MatMultAdd_SeqBAIJ_2;
1917273d9f13SBarry Smith       break;
1918273d9f13SBarry Smith     case 3:
1919273d9f13SBarry Smith       B->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_3;
1920273d9f13SBarry Smith       B->ops->solve           = MatSolve_SeqBAIJ_3;
1921273d9f13SBarry Smith       B->ops->solvetranspose  = MatSolveTranspose_SeqBAIJ_3;
1922273d9f13SBarry Smith       B->ops->mult            = MatMult_SeqBAIJ_3;
1923273d9f13SBarry Smith       B->ops->multadd         = MatMultAdd_SeqBAIJ_3;
1924273d9f13SBarry Smith       break;
1925273d9f13SBarry Smith     case 4:
1926273d9f13SBarry Smith       B->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_4;
1927273d9f13SBarry Smith       B->ops->solve           = MatSolve_SeqBAIJ_4;
1928273d9f13SBarry Smith       B->ops->solvetranspose  = MatSolveTranspose_SeqBAIJ_4;
1929273d9f13SBarry Smith       B->ops->mult            = MatMult_SeqBAIJ_4;
1930273d9f13SBarry Smith       B->ops->multadd         = MatMultAdd_SeqBAIJ_4;
1931273d9f13SBarry Smith       break;
1932273d9f13SBarry Smith     case 5:
1933273d9f13SBarry Smith       B->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_5;
1934273d9f13SBarry Smith       B->ops->solve           = MatSolve_SeqBAIJ_5;
1935273d9f13SBarry Smith       B->ops->solvetranspose  = MatSolveTranspose_SeqBAIJ_5;
1936273d9f13SBarry Smith       B->ops->mult            = MatMult_SeqBAIJ_5;
1937273d9f13SBarry Smith       B->ops->multadd         = MatMultAdd_SeqBAIJ_5;
1938273d9f13SBarry Smith       break;
1939273d9f13SBarry Smith     case 6:
1940273d9f13SBarry Smith       B->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_6;
1941273d9f13SBarry Smith       B->ops->solve           = MatSolve_SeqBAIJ_6;
1942273d9f13SBarry Smith       B->ops->solvetranspose  = MatSolveTranspose_SeqBAIJ_6;
1943273d9f13SBarry Smith       B->ops->mult            = MatMult_SeqBAIJ_6;
1944273d9f13SBarry Smith       B->ops->multadd         = MatMultAdd_SeqBAIJ_6;
1945273d9f13SBarry Smith       break;
1946273d9f13SBarry Smith     case 7:
1947273d9f13SBarry Smith       B->ops->mult            = MatMult_SeqBAIJ_7;
1948273d9f13SBarry Smith       B->ops->solve           = MatSolve_SeqBAIJ_7;
1949273d9f13SBarry Smith       B->ops->solvetranspose  = MatSolveTranspose_SeqBAIJ_7;
1950273d9f13SBarry Smith       B->ops->multadd         = MatMultAdd_SeqBAIJ_7;
1951273d9f13SBarry Smith       break;
1952273d9f13SBarry Smith     default:
1953273d9f13SBarry Smith       B->ops->mult            = MatMult_SeqBAIJ_N;
1954273d9f13SBarry Smith       B->ops->solve           = MatSolve_SeqBAIJ_N;
1955273d9f13SBarry Smith       B->ops->multadd         = MatMultAdd_SeqBAIJ_N;
1956273d9f13SBarry Smith       break;
1957273d9f13SBarry Smith     }
1958273d9f13SBarry Smith   }
1959273d9f13SBarry Smith   b->bs      = bs;
1960273d9f13SBarry Smith   b->mbs     = mbs;
1961273d9f13SBarry Smith   b->nbs     = nbs;
1962b0a32e0cSBarry Smith   ierr = PetscMalloc((mbs+1)*sizeof(int),&b->imax);CHKERRQ(ierr);
1963273d9f13SBarry Smith   if (!nnz) {
1964435da068SBarry Smith     if (nz == PETSC_DEFAULT || nz == PETSC_DECIDE) nz = 5;
1965273d9f13SBarry Smith     else if (nz <= 0)        nz = 1;
1966273d9f13SBarry Smith     for (i=0; i<mbs; i++) b->imax[i] = nz;
1967273d9f13SBarry Smith     nz = nz*mbs;
1968273d9f13SBarry Smith   } else {
1969273d9f13SBarry Smith     nz = 0;
1970273d9f13SBarry Smith     for (i=0; i<mbs; i++) {b->imax[i] = nnz[i]; nz += nnz[i];}
1971273d9f13SBarry Smith   }
1972273d9f13SBarry Smith 
1973273d9f13SBarry Smith   /* allocate the matrix space */
1974273d9f13SBarry Smith   len   = nz*sizeof(int) + nz*bs2*sizeof(MatScalar) + (B->m+1)*sizeof(int);
1975b0a32e0cSBarry Smith   ierr  = PetscMalloc(len,&b->a);CHKERRQ(ierr);
1976273d9f13SBarry Smith   ierr  = PetscMemzero(b->a,nz*bs2*sizeof(MatScalar));CHKERRQ(ierr);
1977273d9f13SBarry Smith   b->j  = (int*)(b->a + nz*bs2);
1978273d9f13SBarry Smith   ierr = PetscMemzero(b->j,nz*sizeof(int));CHKERRQ(ierr);
1979273d9f13SBarry Smith   b->i  = b->j + nz;
1980273d9f13SBarry Smith   b->singlemalloc = PETSC_TRUE;
1981273d9f13SBarry Smith 
1982273d9f13SBarry Smith   b->i[0] = 0;
1983273d9f13SBarry Smith   for (i=1; i<mbs+1; i++) {
1984273d9f13SBarry Smith     b->i[i] = b->i[i-1] + b->imax[i-1];
1985273d9f13SBarry Smith   }
1986273d9f13SBarry Smith 
1987273d9f13SBarry Smith   /* b->ilen will count nonzeros in each block row so far. */
198816d6aa21SSatish Balay   ierr = PetscMalloc((mbs+1)*sizeof(int),&b->ilen);CHKERRQ(ierr);
1989b0a32e0cSBarry Smith   PetscLogObjectMemory(B,len+2*(mbs+1)*sizeof(int)+sizeof(struct _p_Mat)+sizeof(Mat_SeqBAIJ));
1990273d9f13SBarry Smith   for (i=0; i<mbs; i++) { b->ilen[i] = 0;}
1991273d9f13SBarry Smith 
1992273d9f13SBarry Smith   b->bs               = bs;
1993273d9f13SBarry Smith   b->bs2              = bs2;
1994273d9f13SBarry Smith   b->mbs              = mbs;
1995273d9f13SBarry Smith   b->nz               = 0;
1996273d9f13SBarry Smith   b->maxnz            = nz*bs2;
1997273d9f13SBarry Smith   B->info.nz_unneeded = (PetscReal)b->maxnz;
1998273d9f13SBarry Smith   PetscFunctionReturn(0);
1999273d9f13SBarry Smith }
20002593348eSBarry Smith 
2001