xref: /petsc/src/mat/impls/baij/seq/baij.c (revision 35662bc641e14803d18e397cf3bf394182c736cb)
1*35662bc6SKris Buschelman /*$Id: baij.c,v 1.228 2001/06/21 22:55:30 buschelm Exp buschelm $*/
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;
176aa275fccSKris Buschelman   switch (op) {
177aa275fccSKris Buschelman   case MAT_ROW_ORIENTED:
178aa275fccSKris Buschelman     a->roworiented    = PETSC_TRUE;
179aa275fccSKris Buschelman     break;
180aa275fccSKris Buschelman   case MAT_COLUMN_ORIENTED:
181aa275fccSKris Buschelman     a->roworiented    = PETSC_FALSE;
182aa275fccSKris Buschelman     break;
183aa275fccSKris Buschelman   case MAT_COLUMNS_SORTED:
184aa275fccSKris Buschelman     a->sorted         = PETSC_TRUE;
185aa275fccSKris Buschelman     break;
186aa275fccSKris Buschelman   case MAT_COLUMNS_UNSORTED:
187aa275fccSKris Buschelman     a->sorted         = PETSC_FALSE;
188aa275fccSKris Buschelman     break;
189aa275fccSKris Buschelman   case MAT_KEEP_ZEROED_ROWS:
190aa275fccSKris Buschelman     a->keepzeroedrows = PETSC_TRUE;
191aa275fccSKris Buschelman     break;
192aa275fccSKris Buschelman   case MAT_NO_NEW_NONZERO_LOCATIONS:
193aa275fccSKris Buschelman     a->nonew          = 1;
194aa275fccSKris Buschelman     break;
195aa275fccSKris Buschelman   case MAT_NEW_NONZERO_LOCATION_ERR:
196aa275fccSKris Buschelman     a->nonew          = -1;
197aa275fccSKris Buschelman     break;
198aa275fccSKris Buschelman   case MAT_NEW_NONZERO_ALLOCATION_ERR:
199aa275fccSKris Buschelman     a->nonew          = -2;
200aa275fccSKris Buschelman     break;
201aa275fccSKris Buschelman   case MAT_YES_NEW_NONZERO_LOCATIONS:
202aa275fccSKris Buschelman     a->nonew          = 0;
203aa275fccSKris Buschelman     break;
204aa275fccSKris Buschelman   case MAT_ROWS_SORTED:
205aa275fccSKris Buschelman   case MAT_ROWS_UNSORTED:
206aa275fccSKris Buschelman   case MAT_YES_NEW_DIAGONALS:
207aa275fccSKris Buschelman   case MAT_IGNORE_OFF_PROC_ENTRIES:
208aa275fccSKris Buschelman   case MAT_USE_HASH_TABLE:
209b0a32e0cSBarry Smith     PetscLogInfo(A,"MatSetOption_SeqBAIJ:Option ignored\n");
210aa275fccSKris Buschelman     break;
211aa275fccSKris Buschelman   case MAT_NO_NEW_DIAGONALS:
21229bbc08cSBarry Smith     SETERRQ(PETSC_ERR_SUP,"MAT_NO_NEW_DIAGONALS");
213aa275fccSKris Buschelman   default:
21429bbc08cSBarry Smith     SETERRQ(PETSC_ERR_SUP,"unknown option");
2152d61bbb3SSatish Balay   }
2162d61bbb3SSatish Balay   PetscFunctionReturn(0);
2172d61bbb3SSatish Balay }
2182d61bbb3SSatish Balay 
2194a2ae208SSatish Balay #undef __FUNCT__
2204a2ae208SSatish Balay #define __FUNCT__ "MatGetOwnershipRange_SeqBAIJ"
2212d61bbb3SSatish Balay int MatGetOwnershipRange_SeqBAIJ(Mat A,int *m,int *n)
2222d61bbb3SSatish Balay {
2232d61bbb3SSatish Balay   PetscFunctionBegin;
2244c49b128SBarry Smith   if (m) *m = 0;
225273d9f13SBarry Smith   if (n) *n = A->m;
2262d61bbb3SSatish Balay   PetscFunctionReturn(0);
2272d61bbb3SSatish Balay }
2282d61bbb3SSatish Balay 
2294a2ae208SSatish Balay #undef __FUNCT__
2304a2ae208SSatish Balay #define __FUNCT__ "MatGetRow_SeqBAIJ"
2312d61bbb3SSatish Balay int MatGetRow_SeqBAIJ(Mat A,int row,int *nz,int **idx,Scalar **v)
2322d61bbb3SSatish Balay {
2332d61bbb3SSatish Balay   Mat_SeqBAIJ  *a = (Mat_SeqBAIJ*)A->data;
23482502324SSatish Balay   int          itmp,i,j,k,M,*ai,*aj,bs,bn,bp,*idx_i,bs2,ierr;
2353f1db9ecSBarry Smith   MatScalar    *aa,*aa_i;
2363f1db9ecSBarry Smith   Scalar       *v_i;
2372d61bbb3SSatish Balay 
2382d61bbb3SSatish Balay   PetscFunctionBegin;
2392d61bbb3SSatish Balay   bs  = a->bs;
2402d61bbb3SSatish Balay   ai  = a->i;
2412d61bbb3SSatish Balay   aj  = a->j;
2422d61bbb3SSatish Balay   aa  = a->a;
2432d61bbb3SSatish Balay   bs2 = a->bs2;
2442d61bbb3SSatish Balay 
245273d9f13SBarry Smith   if (row < 0 || row >= A->m) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Row out of range");
2462d61bbb3SSatish Balay 
2472d61bbb3SSatish Balay   bn  = row/bs;   /* Block number */
2482d61bbb3SSatish Balay   bp  = row % bs; /* Block Position */
2492d61bbb3SSatish Balay   M   = ai[bn+1] - ai[bn];
2502d61bbb3SSatish Balay   *nz = bs*M;
2512d61bbb3SSatish Balay 
2522d61bbb3SSatish Balay   if (v) {
2532d61bbb3SSatish Balay     *v = 0;
2542d61bbb3SSatish Balay     if (*nz) {
255b0a32e0cSBarry Smith       ierr = PetscMalloc((*nz)*sizeof(Scalar),v);CHKERRQ(ierr);
2562d61bbb3SSatish Balay       for (i=0; i<M; i++) { /* for each block in the block row */
2572d61bbb3SSatish Balay         v_i  = *v + i*bs;
2582d61bbb3SSatish Balay         aa_i = aa + bs2*(ai[bn] + i);
2592d61bbb3SSatish Balay         for (j=bp,k=0; j<bs2; j+=bs,k++) {v_i[k] = aa_i[j];}
2602d61bbb3SSatish Balay       }
2612d61bbb3SSatish Balay     }
2622d61bbb3SSatish Balay   }
2632d61bbb3SSatish Balay 
2642d61bbb3SSatish Balay   if (idx) {
2652d61bbb3SSatish Balay     *idx = 0;
2662d61bbb3SSatish Balay     if (*nz) {
267b0a32e0cSBarry Smith       ierr = PetscMalloc((*nz)*sizeof(int),idx);CHKERRQ(ierr);
2682d61bbb3SSatish Balay       for (i=0; i<M; i++) { /* for each block in the block row */
2692d61bbb3SSatish Balay         idx_i = *idx + i*bs;
2702d61bbb3SSatish Balay         itmp  = bs*aj[ai[bn] + i];
2712d61bbb3SSatish Balay         for (j=0; j<bs; j++) {idx_i[j] = itmp++;}
2722d61bbb3SSatish Balay       }
2732d61bbb3SSatish Balay     }
2742d61bbb3SSatish Balay   }
2752d61bbb3SSatish Balay   PetscFunctionReturn(0);
2762d61bbb3SSatish Balay }
2772d61bbb3SSatish Balay 
2784a2ae208SSatish Balay #undef __FUNCT__
2794a2ae208SSatish Balay #define __FUNCT__ "MatRestoreRow_SeqBAIJ"
2802d61bbb3SSatish Balay int MatRestoreRow_SeqBAIJ(Mat A,int row,int *nz,int **idx,Scalar **v)
2812d61bbb3SSatish Balay {
282606d414cSSatish Balay   int ierr;
283606d414cSSatish Balay 
2842d61bbb3SSatish Balay   PetscFunctionBegin;
285606d414cSSatish Balay   if (idx) {if (*idx) {ierr = PetscFree(*idx);CHKERRQ(ierr);}}
286606d414cSSatish Balay   if (v)   {if (*v)   {ierr = PetscFree(*v);CHKERRQ(ierr);}}
2872d61bbb3SSatish Balay   PetscFunctionReturn(0);
2882d61bbb3SSatish Balay }
2892d61bbb3SSatish Balay 
2904a2ae208SSatish Balay #undef __FUNCT__
2914a2ae208SSatish Balay #define __FUNCT__ "MatTranspose_SeqBAIJ"
2922d61bbb3SSatish Balay int MatTranspose_SeqBAIJ(Mat A,Mat *B)
2932d61bbb3SSatish Balay {
2942d61bbb3SSatish Balay   Mat_SeqBAIJ *a=(Mat_SeqBAIJ *)A->data;
2952d61bbb3SSatish Balay   Mat         C;
2962d61bbb3SSatish Balay   int         i,j,k,ierr,*aj=a->j,*ai=a->i,bs=a->bs,mbs=a->mbs,nbs=a->nbs,len,*col;
297273d9f13SBarry Smith   int         *rows,*cols,bs2=a->bs2;
298375fe846SBarry Smith   Scalar      *array;
2992d61bbb3SSatish Balay 
3002d61bbb3SSatish Balay   PetscFunctionBegin;
30129bbc08cSBarry Smith   if (!B && mbs!=nbs) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Square matrix only for in-place");
302b0a32e0cSBarry Smith   ierr = PetscMalloc((1+nbs)*sizeof(int),&col);CHKERRQ(ierr);
303549d3d68SSatish Balay   ierr = PetscMemzero(col,(1+nbs)*sizeof(int));CHKERRQ(ierr);
3042d61bbb3SSatish Balay 
305375fe846SBarry Smith #if defined(PETSC_USE_MAT_SINGLE)
306b0a32e0cSBarry Smith   ierr = PetscMalloc(a->bs2*a->nz*sizeof(Scalar),&array);CHKERRQ(ierr);
307375fe846SBarry Smith   for (i=0; i<a->bs2*a->nz; i++) array[i] = (Scalar)a->a[i];
308375fe846SBarry Smith #else
3093eda8832SBarry Smith   array = a->a;
310375fe846SBarry Smith #endif
311375fe846SBarry Smith 
3122d61bbb3SSatish Balay   for (i=0; i<ai[mbs]; i++) col[aj[i]] += 1;
313273d9f13SBarry Smith   ierr = MatCreateSeqBAIJ(A->comm,bs,A->n,A->m,PETSC_NULL,col,&C);CHKERRQ(ierr);
314606d414cSSatish Balay   ierr = PetscFree(col);CHKERRQ(ierr);
315b0a32e0cSBarry Smith   ierr = PetscMalloc(2*bs*sizeof(int),&rows);CHKERRQ(ierr);
3162d61bbb3SSatish Balay   cols = rows + bs;
3172d61bbb3SSatish Balay   for (i=0; i<mbs; i++) {
3182d61bbb3SSatish Balay     cols[0] = i*bs;
3192d61bbb3SSatish Balay     for (k=1; k<bs; k++) cols[k] = cols[k-1] + 1;
3202d61bbb3SSatish Balay     len = ai[i+1] - ai[i];
3212d61bbb3SSatish Balay     for (j=0; j<len; j++) {
3222d61bbb3SSatish Balay       rows[0] = (*aj++)*bs;
3232d61bbb3SSatish Balay       for (k=1; k<bs; k++) rows[k] = rows[k-1] + 1;
3242d61bbb3SSatish Balay       ierr = MatSetValues(C,bs,rows,bs,cols,array,INSERT_VALUES);CHKERRQ(ierr);
3252d61bbb3SSatish Balay       array += bs2;
3262d61bbb3SSatish Balay     }
3272d61bbb3SSatish Balay   }
328606d414cSSatish Balay   ierr = PetscFree(rows);CHKERRQ(ierr);
329375fe846SBarry Smith #if defined(PETSC_USE_MAT_SINGLE)
330375fe846SBarry Smith   ierr = PetscFree(array);
331375fe846SBarry Smith #endif
3322d61bbb3SSatish Balay 
3332d61bbb3SSatish Balay   ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
3342d61bbb3SSatish Balay   ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
3352d61bbb3SSatish Balay 
336c4992f7dSBarry Smith   if (B) {
3372d61bbb3SSatish Balay     *B = C;
3382d61bbb3SSatish Balay   } else {
339273d9f13SBarry Smith     ierr = MatHeaderCopy(A,C);CHKERRQ(ierr);
3402d61bbb3SSatish Balay   }
3412d61bbb3SSatish Balay   PetscFunctionReturn(0);
3422d61bbb3SSatish Balay }
3432d61bbb3SSatish Balay 
3444a2ae208SSatish Balay #undef __FUNCT__
3454a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqBAIJ_Binary"
346b0a32e0cSBarry Smith static int MatView_SeqBAIJ_Binary(Mat A,PetscViewer viewer)
3472593348eSBarry Smith {
348b6490206SBarry Smith   Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)A->data;
3499df24120SSatish Balay   int         i,fd,*col_lens,ierr,bs = a->bs,count,*jj,j,k,l,bs2=a->bs2;
350b6490206SBarry Smith   Scalar      *aa;
351ce6f0cecSBarry Smith   FILE        *file;
3522593348eSBarry Smith 
3533a40ed3dSBarry Smith   PetscFunctionBegin;
354b0a32e0cSBarry Smith   ierr        = PetscViewerBinaryGetDescriptor(viewer,&fd);CHKERRQ(ierr);
355b0a32e0cSBarry Smith   ierr        = PetscMalloc((4+A->m)*sizeof(int),&col_lens);CHKERRQ(ierr);
3562593348eSBarry Smith   col_lens[0] = MAT_COOKIE;
3573b2fbd54SBarry Smith 
358273d9f13SBarry Smith   col_lens[1] = A->m;
359273d9f13SBarry Smith   col_lens[2] = A->n;
3607e67e3f9SSatish Balay   col_lens[3] = a->nz*bs2;
3612593348eSBarry Smith 
3622593348eSBarry Smith   /* store lengths of each row and write (including header) to file */
363b6490206SBarry Smith   count = 0;
364b6490206SBarry Smith   for (i=0; i<a->mbs; i++) {
365b6490206SBarry Smith     for (j=0; j<bs; j++) {
366b6490206SBarry Smith       col_lens[4+count++] = bs*(a->i[i+1] - a->i[i]);
367b6490206SBarry Smith     }
3682593348eSBarry Smith   }
369273d9f13SBarry Smith   ierr = PetscBinaryWrite(fd,col_lens,4+A->m,PETSC_INT,1);CHKERRQ(ierr);
370606d414cSSatish Balay   ierr = PetscFree(col_lens);CHKERRQ(ierr);
3712593348eSBarry Smith 
3722593348eSBarry Smith   /* store column indices (zero start index) */
373b0a32e0cSBarry Smith   ierr  = PetscMalloc((a->nz+1)*bs2*sizeof(int),&jj);CHKERRQ(ierr);
374b6490206SBarry Smith   count = 0;
375b6490206SBarry Smith   for (i=0; i<a->mbs; i++) {
376b6490206SBarry Smith     for (j=0; j<bs; j++) {
377b6490206SBarry Smith       for (k=a->i[i]; k<a->i[i+1]; k++) {
378b6490206SBarry Smith         for (l=0; l<bs; l++) {
379b6490206SBarry Smith           jj[count++] = bs*a->j[k] + l;
3802593348eSBarry Smith         }
3812593348eSBarry Smith       }
382b6490206SBarry Smith     }
383b6490206SBarry Smith   }
3840752156aSBarry Smith   ierr = PetscBinaryWrite(fd,jj,bs2*a->nz,PETSC_INT,0);CHKERRQ(ierr);
385606d414cSSatish Balay   ierr = PetscFree(jj);CHKERRQ(ierr);
3862593348eSBarry Smith 
3872593348eSBarry Smith   /* store nonzero values */
388b0a32e0cSBarry Smith   ierr  = PetscMalloc((a->nz+1)*bs2*sizeof(Scalar),&aa);CHKERRQ(ierr);
389b6490206SBarry Smith   count = 0;
390b6490206SBarry Smith   for (i=0; i<a->mbs; i++) {
391b6490206SBarry Smith     for (j=0; j<bs; j++) {
392b6490206SBarry Smith       for (k=a->i[i]; k<a->i[i+1]; k++) {
393b6490206SBarry Smith         for (l=0; l<bs; l++) {
3947e67e3f9SSatish Balay           aa[count++] = a->a[bs2*k + l*bs + j];
395b6490206SBarry Smith         }
396b6490206SBarry Smith       }
397b6490206SBarry Smith     }
398b6490206SBarry Smith   }
3990752156aSBarry Smith   ierr = PetscBinaryWrite(fd,aa,bs2*a->nz,PETSC_SCALAR,0);CHKERRQ(ierr);
400606d414cSSatish Balay   ierr = PetscFree(aa);CHKERRQ(ierr);
401ce6f0cecSBarry Smith 
402b0a32e0cSBarry Smith   ierr = PetscViewerBinaryGetInfoPointer(viewer,&file);CHKERRQ(ierr);
403ce6f0cecSBarry Smith   if (file) {
404ce6f0cecSBarry Smith     fprintf(file,"-matload_block_size %d\n",a->bs);
405ce6f0cecSBarry Smith   }
4063a40ed3dSBarry Smith   PetscFunctionReturn(0);
4072593348eSBarry Smith }
4082593348eSBarry Smith 
4094a2ae208SSatish Balay #undef __FUNCT__
4104a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqBAIJ_ASCII"
411b0a32e0cSBarry Smith static int MatView_SeqBAIJ_ASCII(Mat A,PetscViewer viewer)
4122593348eSBarry Smith {
413b6490206SBarry Smith   Mat_SeqBAIJ       *a = (Mat_SeqBAIJ*)A->data;
414fb9695e5SSatish Balay   int               ierr,i,j,bs = a->bs,k,l,bs2=a->bs2;
415f3ef73ceSBarry Smith   PetscViewerFormat format;
4162593348eSBarry Smith 
4173a40ed3dSBarry Smith   PetscFunctionBegin;
418b0a32e0cSBarry Smith   ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr);
419fb9695e5SSatish Balay   if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_LONG) {
420b0a32e0cSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  block size is %d\n",bs);CHKERRQ(ierr);
421fb9695e5SSatish Balay   } else if (format == PETSC_VIEWER_ASCII_MATLAB) {
42229bbc08cSBarry Smith     SETERRQ(PETSC_ERR_SUP,"Matlab format not supported");
423fb9695e5SSatish Balay   } else if (format == PETSC_VIEWER_ASCII_COMMON) {
424b0a32e0cSBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_NO);CHKERRQ(ierr);
42544cd7ae7SLois Curfman McInnes     for (i=0; i<a->mbs; i++) {
42644cd7ae7SLois Curfman McInnes       for (j=0; j<bs; j++) {
427b0a32e0cSBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"row %d:",i*bs+j);CHKERRQ(ierr);
42844cd7ae7SLois Curfman McInnes         for (k=a->i[i]; k<a->i[i+1]; k++) {
42944cd7ae7SLois Curfman McInnes           for (l=0; l<bs; l++) {
430aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
4310e6d2581SBarry Smith             if (PetscImaginaryPart(a->a[bs2*k + l*bs + j]) > 0.0 && PetscRealPart(a->a[bs2*k + l*bs + j]) != 0.0) {
432b0a32e0cSBarry Smith               ierr = PetscViewerASCIIPrintf(viewer," %d %g + %gi",bs*a->j[k]+l,
4330e6d2581SBarry Smith                       PetscRealPart(a->a[bs2*k + l*bs + j]),PetscImaginaryPart(a->a[bs2*k + l*bs + j]));CHKERRQ(ierr);
4340e6d2581SBarry Smith             } else if (PetscImaginaryPart(a->a[bs2*k + l*bs + j]) < 0.0 && PetscRealPart(a->a[bs2*k + l*bs + j]) != 0.0) {
435b0a32e0cSBarry Smith               ierr = PetscViewerASCIIPrintf(viewer," %d %g - %gi",bs*a->j[k]+l,
4360e6d2581SBarry Smith                       PetscRealPart(a->a[bs2*k + l*bs + j]),-PetscImaginaryPart(a->a[bs2*k + l*bs + j]));CHKERRQ(ierr);
4370e6d2581SBarry Smith             } else if (PetscRealPart(a->a[bs2*k + l*bs + j]) != 0.0) {
438b0a32e0cSBarry Smith               ierr = PetscViewerASCIIPrintf(viewer," %d %g ",bs*a->j[k]+l,PetscRealPart(a->a[bs2*k + l*bs + j]));CHKERRQ(ierr);
4390ef38995SBarry Smith             }
44044cd7ae7SLois Curfman McInnes #else
4410ef38995SBarry Smith             if (a->a[bs2*k + l*bs + j] != 0.0) {
442b0a32e0cSBarry Smith               ierr = PetscViewerASCIIPrintf(viewer," %d %g ",bs*a->j[k]+l,a->a[bs2*k + l*bs + j]);CHKERRQ(ierr);
4430ef38995SBarry Smith             }
44444cd7ae7SLois Curfman McInnes #endif
44544cd7ae7SLois Curfman McInnes           }
44644cd7ae7SLois Curfman McInnes         }
447b0a32e0cSBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
44844cd7ae7SLois Curfman McInnes       }
44944cd7ae7SLois Curfman McInnes     }
450b0a32e0cSBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_YES);CHKERRQ(ierr);
4510ef38995SBarry Smith   } else {
452b0a32e0cSBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_NO);CHKERRQ(ierr);
453b6490206SBarry Smith     for (i=0; i<a->mbs; i++) {
454b6490206SBarry Smith       for (j=0; j<bs; j++) {
455b0a32e0cSBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"row %d:",i*bs+j);CHKERRQ(ierr);
456b6490206SBarry Smith         for (k=a->i[i]; k<a->i[i+1]; k++) {
457b6490206SBarry Smith           for (l=0; l<bs; l++) {
458aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
4590e6d2581SBarry Smith             if (PetscImaginaryPart(a->a[bs2*k + l*bs + j]) > 0.0) {
460b0a32e0cSBarry Smith               ierr = PetscViewerASCIIPrintf(viewer," %d %g + %g i",bs*a->j[k]+l,
4610e6d2581SBarry Smith                 PetscRealPart(a->a[bs2*k + l*bs + j]),PetscImaginaryPart(a->a[bs2*k + l*bs + j]));CHKERRQ(ierr);
4620e6d2581SBarry Smith             } else if (PetscImaginaryPart(a->a[bs2*k + l*bs + j]) < 0.0) {
463b0a32e0cSBarry Smith               ierr = PetscViewerASCIIPrintf(viewer," %d %g - %g i",bs*a->j[k]+l,
4640e6d2581SBarry Smith                 PetscRealPart(a->a[bs2*k + l*bs + j]),-PetscImaginaryPart(a->a[bs2*k + l*bs + j]));CHKERRQ(ierr);
4650ef38995SBarry Smith             } else {
466b0a32e0cSBarry Smith               ierr = PetscViewerASCIIPrintf(viewer," %d %g ",bs*a->j[k]+l,PetscRealPart(a->a[bs2*k + l*bs + j]));CHKERRQ(ierr);
46788685aaeSLois Curfman McInnes             }
46888685aaeSLois Curfman McInnes #else
469b0a32e0cSBarry Smith             ierr = PetscViewerASCIIPrintf(viewer," %d %g ",bs*a->j[k]+l,a->a[bs2*k + l*bs + j]);CHKERRQ(ierr);
47088685aaeSLois Curfman McInnes #endif
4712593348eSBarry Smith           }
4722593348eSBarry Smith         }
473b0a32e0cSBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
4742593348eSBarry Smith       }
4752593348eSBarry Smith     }
476b0a32e0cSBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_YES);CHKERRQ(ierr);
477b6490206SBarry Smith   }
478b0a32e0cSBarry Smith   ierr = PetscViewerFlush(viewer);CHKERRQ(ierr);
4793a40ed3dSBarry Smith   PetscFunctionReturn(0);
4802593348eSBarry Smith }
4812593348eSBarry Smith 
4824a2ae208SSatish Balay #undef __FUNCT__
4834a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqBAIJ_Draw_Zoom"
484b0a32e0cSBarry Smith static int MatView_SeqBAIJ_Draw_Zoom(PetscDraw draw,void *Aa)
4853270192aSSatish Balay {
48677ed5343SBarry Smith   Mat          A = (Mat) Aa;
4873270192aSSatish Balay   Mat_SeqBAIJ  *a=(Mat_SeqBAIJ*)A->data;
488b65db4caSBarry Smith   int          row,ierr,i,j,k,l,mbs=a->mbs,color,bs=a->bs,bs2=a->bs2;
4890e6d2581SBarry Smith   PetscReal    xl,yl,xr,yr,x_l,x_r,y_l,y_r;
4903f1db9ecSBarry Smith   MatScalar    *aa;
491b0a32e0cSBarry Smith   PetscViewer  viewer;
4923270192aSSatish Balay 
4933a40ed3dSBarry Smith   PetscFunctionBegin;
4943270192aSSatish Balay 
495b65db4caSBarry Smith   /* still need to add support for contour plot of nonzeros; see MatView_SeqAIJ_Draw_Zoom()*/
49677ed5343SBarry Smith   ierr = PetscObjectQuery((PetscObject)A,"Zoomviewer",(PetscObject*)&viewer);CHKERRQ(ierr);
49777ed5343SBarry Smith 
498b0a32e0cSBarry Smith   ierr = PetscDrawGetCoordinates(draw,&xl,&yl,&xr,&yr);CHKERRQ(ierr);
49977ed5343SBarry Smith 
5003270192aSSatish Balay   /* loop over matrix elements drawing boxes */
501b0a32e0cSBarry Smith   color = PETSC_DRAW_BLUE;
5023270192aSSatish Balay   for (i=0,row=0; i<mbs; i++,row+=bs) {
5033270192aSSatish Balay     for (j=a->i[i]; j<a->i[i+1]; j++) {
504273d9f13SBarry Smith       y_l = A->m - row - 1.0; y_r = y_l + 1.0;
5053270192aSSatish Balay       x_l = a->j[j]*bs; x_r = x_l + 1.0;
5063270192aSSatish Balay       aa = a->a + j*bs2;
5073270192aSSatish Balay       for (k=0; k<bs; k++) {
5083270192aSSatish Balay         for (l=0; l<bs; l++) {
5090e6d2581SBarry Smith           if (PetscRealPart(*aa++) >=  0.) continue;
510b0a32e0cSBarry Smith           ierr = PetscDrawRectangle(draw,x_l+k,y_l-l,x_r+k,y_r-l,color,color,color,color);CHKERRQ(ierr);
5113270192aSSatish Balay         }
5123270192aSSatish Balay       }
5133270192aSSatish Balay     }
5143270192aSSatish Balay   }
515b0a32e0cSBarry Smith   color = PETSC_DRAW_CYAN;
5163270192aSSatish Balay   for (i=0,row=0; i<mbs; i++,row+=bs) {
5173270192aSSatish Balay     for (j=a->i[i]; j<a->i[i+1]; j++) {
518273d9f13SBarry Smith       y_l = A->m - row - 1.0; y_r = y_l + 1.0;
5193270192aSSatish Balay       x_l = a->j[j]*bs; x_r = x_l + 1.0;
5203270192aSSatish Balay       aa = a->a + j*bs2;
5213270192aSSatish Balay       for (k=0; k<bs; k++) {
5223270192aSSatish Balay         for (l=0; l<bs; l++) {
5230e6d2581SBarry Smith           if (PetscRealPart(*aa++) != 0.) continue;
524b0a32e0cSBarry Smith           ierr = PetscDrawRectangle(draw,x_l+k,y_l-l,x_r+k,y_r-l,color,color,color,color);CHKERRQ(ierr);
5253270192aSSatish Balay         }
5263270192aSSatish Balay       }
5273270192aSSatish Balay     }
5283270192aSSatish Balay   }
5293270192aSSatish Balay 
530b0a32e0cSBarry Smith   color = PETSC_DRAW_RED;
5313270192aSSatish Balay   for (i=0,row=0; i<mbs; i++,row+=bs) {
5323270192aSSatish Balay     for (j=a->i[i]; j<a->i[i+1]; j++) {
533273d9f13SBarry Smith       y_l = A->m - row - 1.0; y_r = y_l + 1.0;
5343270192aSSatish Balay       x_l = a->j[j]*bs; x_r = x_l + 1.0;
5353270192aSSatish Balay       aa = a->a + j*bs2;
5363270192aSSatish Balay       for (k=0; k<bs; k++) {
5373270192aSSatish Balay         for (l=0; l<bs; l++) {
5380e6d2581SBarry Smith           if (PetscRealPart(*aa++) <= 0.) continue;
539b0a32e0cSBarry Smith           ierr = PetscDrawRectangle(draw,x_l+k,y_l-l,x_r+k,y_r-l,color,color,color,color);CHKERRQ(ierr);
5403270192aSSatish Balay         }
5413270192aSSatish Balay       }
5423270192aSSatish Balay     }
5433270192aSSatish Balay   }
54477ed5343SBarry Smith   PetscFunctionReturn(0);
54577ed5343SBarry Smith }
5463270192aSSatish Balay 
5474a2ae208SSatish Balay #undef __FUNCT__
5484a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqBAIJ_Draw"
549b0a32e0cSBarry Smith static int MatView_SeqBAIJ_Draw(Mat A,PetscViewer viewer)
55077ed5343SBarry Smith {
5517dce120fSSatish Balay   int          ierr;
5520e6d2581SBarry Smith   PetscReal    xl,yl,xr,yr,w,h;
553b0a32e0cSBarry Smith   PetscDraw    draw;
55477ed5343SBarry Smith   PetscTruth   isnull;
5553270192aSSatish Balay 
55677ed5343SBarry Smith   PetscFunctionBegin;
55777ed5343SBarry Smith 
558b0a32e0cSBarry Smith   ierr = PetscViewerDrawGetDraw(viewer,0,&draw);CHKERRQ(ierr);
559b0a32e0cSBarry Smith   ierr = PetscDrawIsNull(draw,&isnull);CHKERRQ(ierr); if (isnull) PetscFunctionReturn(0);
56077ed5343SBarry Smith 
56177ed5343SBarry Smith   ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",(PetscObject)viewer);CHKERRQ(ierr);
562273d9f13SBarry Smith   xr  = A->n; yr = A->m; h = yr/10.0; w = xr/10.0;
56377ed5343SBarry Smith   xr += w;    yr += h;  xl = -w;     yl = -h;
564b0a32e0cSBarry Smith   ierr = PetscDrawSetCoordinates(draw,xl,yl,xr,yr);CHKERRQ(ierr);
565b0a32e0cSBarry Smith   ierr = PetscDrawZoom(draw,MatView_SeqBAIJ_Draw_Zoom,A);CHKERRQ(ierr);
56677ed5343SBarry Smith   ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",PETSC_NULL);CHKERRQ(ierr);
5673a40ed3dSBarry Smith   PetscFunctionReturn(0);
5683270192aSSatish Balay }
5693270192aSSatish Balay 
5704a2ae208SSatish Balay #undef __FUNCT__
5714a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqBAIJ"
572b0a32e0cSBarry Smith int MatView_SeqBAIJ(Mat A,PetscViewer viewer)
5732593348eSBarry Smith {
57419bcc07fSBarry Smith   int        ierr;
5756831982aSBarry Smith   PetscTruth issocket,isascii,isbinary,isdraw;
5762593348eSBarry Smith 
5773a40ed3dSBarry Smith   PetscFunctionBegin;
578b0a32e0cSBarry Smith   ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_SOCKET,&issocket);CHKERRQ(ierr);
579b0a32e0cSBarry Smith   ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&isascii);CHKERRQ(ierr);
580fb9695e5SSatish Balay   ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_BINARY,&isbinary);CHKERRQ(ierr);
581fb9695e5SSatish Balay   ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_DRAW,&isdraw);CHKERRQ(ierr);
5820f5bd95cSBarry Smith   if (issocket) {
58329bbc08cSBarry Smith     SETERRQ(PETSC_ERR_SUP,"Socket viewer not supported");
5840f5bd95cSBarry Smith   } else if (isascii){
5853a40ed3dSBarry Smith     ierr = MatView_SeqBAIJ_ASCII(A,viewer);CHKERRQ(ierr);
5860f5bd95cSBarry Smith   } else if (isbinary) {
5873a40ed3dSBarry Smith     ierr = MatView_SeqBAIJ_Binary(A,viewer);CHKERRQ(ierr);
5880f5bd95cSBarry Smith   } else if (isdraw) {
5893a40ed3dSBarry Smith     ierr = MatView_SeqBAIJ_Draw(A,viewer);CHKERRQ(ierr);
5905cd90555SBarry Smith   } else {
59129bbc08cSBarry Smith     SETERRQ1(1,"Viewer type %s not supported by SeqBAIJ matrices",((PetscObject)viewer)->type_name);
5922593348eSBarry Smith   }
5933a40ed3dSBarry Smith   PetscFunctionReturn(0);
5942593348eSBarry Smith }
595b6490206SBarry Smith 
596cd0e1443SSatish Balay 
5974a2ae208SSatish Balay #undef __FUNCT__
5984a2ae208SSatish Balay #define __FUNCT__ "MatGetValues_SeqBAIJ"
5992d61bbb3SSatish Balay int MatGetValues_SeqBAIJ(Mat A,int m,int *im,int n,int *in,Scalar *v)
600cd0e1443SSatish Balay {
601cd0e1443SSatish Balay   Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)A->data;
6022d61bbb3SSatish Balay   int        *rp,k,low,high,t,row,nrow,i,col,l,*aj = a->j;
6032d61bbb3SSatish Balay   int        *ai = a->i,*ailen = a->ilen;
6042d61bbb3SSatish Balay   int        brow,bcol,ridx,cidx,bs=a->bs,bs2=a->bs2;
6053f1db9ecSBarry Smith   MatScalar  *ap,*aa = a->a,zero = 0.0;
606cd0e1443SSatish Balay 
6073a40ed3dSBarry Smith   PetscFunctionBegin;
6082d61bbb3SSatish Balay   for (k=0; k<m; k++) { /* loop over rows */
609cd0e1443SSatish Balay     row  = im[k]; brow = row/bs;
61029bbc08cSBarry Smith     if (row < 0) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Negative row");
611273d9f13SBarry Smith     if (row >= A->m) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Row too large");
6122d61bbb3SSatish Balay     rp   = aj + ai[brow] ; ap = aa + bs2*ai[brow] ;
6132c3acbe9SBarry Smith     nrow = ailen[brow];
6142d61bbb3SSatish Balay     for (l=0; l<n; l++) { /* loop over columns */
61529bbc08cSBarry Smith       if (in[l] < 0) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Negative column");
616273d9f13SBarry Smith       if (in[l] >= A->n) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Column too large");
6172d61bbb3SSatish Balay       col  = in[l] ;
6182d61bbb3SSatish Balay       bcol = col/bs;
6192d61bbb3SSatish Balay       cidx = col%bs;
6202d61bbb3SSatish Balay       ridx = row%bs;
6212d61bbb3SSatish Balay       high = nrow;
6222d61bbb3SSatish Balay       low  = 0; /* assume unsorted */
6232d61bbb3SSatish Balay       while (high-low > 5) {
624cd0e1443SSatish Balay         t = (low+high)/2;
625cd0e1443SSatish Balay         if (rp[t] > bcol) high = t;
626cd0e1443SSatish Balay         else             low  = t;
627cd0e1443SSatish Balay       }
628cd0e1443SSatish Balay       for (i=low; i<high; i++) {
629cd0e1443SSatish Balay         if (rp[i] > bcol) break;
630cd0e1443SSatish Balay         if (rp[i] == bcol) {
6312d61bbb3SSatish Balay           *v++ = ap[bs2*i+bs*cidx+ridx];
6322d61bbb3SSatish Balay           goto finished;
633cd0e1443SSatish Balay         }
634cd0e1443SSatish Balay       }
6352d61bbb3SSatish Balay       *v++ = zero;
6362d61bbb3SSatish Balay       finished:;
637cd0e1443SSatish Balay     }
638cd0e1443SSatish Balay   }
6393a40ed3dSBarry Smith   PetscFunctionReturn(0);
640cd0e1443SSatish Balay }
641cd0e1443SSatish Balay 
64295d5f7c2SBarry Smith #if defined(PETSC_USE_MAT_SINGLE)
6434a2ae208SSatish Balay #undef __FUNCT__
6444a2ae208SSatish Balay #define __FUNCT__ "MatSetValuesBlocked_SeqBAIJ"
64595d5f7c2SBarry Smith int MatSetValuesBlocked_SeqBAIJ(Mat mat,int m,int *im,int n,int *in,Scalar *v,InsertMode addv)
64695d5f7c2SBarry Smith {
647563b5814SBarry Smith   Mat_SeqBAIJ *b = (Mat_SeqBAIJ*)mat->data;
648563b5814SBarry Smith   int         ierr,i,N = m*n*b->bs2;
649563b5814SBarry Smith   MatScalar   *vsingle;
65095d5f7c2SBarry Smith 
65195d5f7c2SBarry Smith   PetscFunctionBegin;
652563b5814SBarry Smith   if (N > b->setvalueslen) {
653563b5814SBarry Smith     if (b->setvaluescopy) {ierr = PetscFree(b->setvaluescopy);CHKERRQ(ierr);}
654b0a32e0cSBarry Smith     ierr = PetscMalloc(N*sizeof(MatScalar),&b->setvaluescopy);CHKERRQ(ierr);
655563b5814SBarry Smith     b->setvalueslen  = N;
656563b5814SBarry Smith   }
657563b5814SBarry Smith   vsingle = b->setvaluescopy;
65895d5f7c2SBarry Smith   for (i=0; i<N; i++) {
65995d5f7c2SBarry Smith     vsingle[i] = v[i];
66095d5f7c2SBarry Smith   }
66195d5f7c2SBarry Smith   ierr = MatSetValuesBlocked_SeqBAIJ_MatScalar(mat,m,im,n,in,vsingle,addv);CHKERRQ(ierr);
66295d5f7c2SBarry Smith   PetscFunctionReturn(0);
66395d5f7c2SBarry Smith }
66495d5f7c2SBarry Smith #endif
66595d5f7c2SBarry Smith 
6662d61bbb3SSatish Balay 
6674a2ae208SSatish Balay #undef __FUNCT__
6684a2ae208SSatish Balay #define __FUNCT__ "MatSetValuesBlocked_SeqBAIJ"
66995d5f7c2SBarry Smith int MatSetValuesBlocked_SeqBAIJ_MatScalar(Mat A,int m,int *im,int n,int *in,MatScalar *v,InsertMode is)
67092c4ed94SBarry Smith {
67192c4ed94SBarry Smith   Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)A->data;
6728a84c255SSatish Balay   int         *rp,k,low,high,t,ii,jj,row,nrow,i,col,l,rmax,N,sorted=a->sorted;
673273d9f13SBarry Smith   int         *imax=a->imax,*ai=a->i,*ailen=a->ilen;
674549d3d68SSatish Balay   int         *aj=a->j,nonew=a->nonew,bs2=a->bs2,bs=a->bs,stepval,ierr;
675273d9f13SBarry Smith   PetscTruth  roworiented=a->roworiented;
67695d5f7c2SBarry Smith   MatScalar   *value = v,*ap,*aa = a->a,*bap;
67792c4ed94SBarry Smith 
6783a40ed3dSBarry Smith   PetscFunctionBegin;
6790e324ae4SSatish Balay   if (roworiented) {
6800e324ae4SSatish Balay     stepval = (n-1)*bs;
6810e324ae4SSatish Balay   } else {
6820e324ae4SSatish Balay     stepval = (m-1)*bs;
6830e324ae4SSatish Balay   }
68492c4ed94SBarry Smith   for (k=0; k<m; k++) { /* loop over added rows */
68592c4ed94SBarry Smith     row  = im[k];
6865ef9f2a5SBarry Smith     if (row < 0) continue;
687aa482453SBarry Smith #if defined(PETSC_USE_BOPT_g)
68829bbc08cSBarry Smith     if (row >= a->mbs) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Row too large");
68992c4ed94SBarry Smith #endif
69092c4ed94SBarry Smith     rp   = aj + ai[row];
69192c4ed94SBarry Smith     ap   = aa + bs2*ai[row];
69292c4ed94SBarry Smith     rmax = imax[row];
69392c4ed94SBarry Smith     nrow = ailen[row];
69492c4ed94SBarry Smith     low  = 0;
69592c4ed94SBarry Smith     for (l=0; l<n; l++) { /* loop over added columns */
6965ef9f2a5SBarry Smith       if (in[l] < 0) continue;
697aa482453SBarry Smith #if defined(PETSC_USE_BOPT_g)
69829bbc08cSBarry Smith       if (in[l] >= a->nbs) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Column too large");
69992c4ed94SBarry Smith #endif
70092c4ed94SBarry Smith       col = in[l];
70192c4ed94SBarry Smith       if (roworiented) {
7020e324ae4SSatish Balay         value = v + k*(stepval+bs)*bs + l*bs;
7030e324ae4SSatish Balay       } else {
7040e324ae4SSatish Balay         value = v + l*(stepval+bs)*bs + k*bs;
70592c4ed94SBarry Smith       }
70692c4ed94SBarry Smith       if (!sorted) low = 0; high = nrow;
70792c4ed94SBarry Smith       while (high-low > 7) {
70892c4ed94SBarry Smith         t = (low+high)/2;
70992c4ed94SBarry Smith         if (rp[t] > col) high = t;
71092c4ed94SBarry Smith         else             low  = t;
71192c4ed94SBarry Smith       }
71292c4ed94SBarry Smith       for (i=low; i<high; i++) {
71392c4ed94SBarry Smith         if (rp[i] > col) break;
71492c4ed94SBarry Smith         if (rp[i] == col) {
7158a84c255SSatish Balay           bap  = ap +  bs2*i;
7160e324ae4SSatish Balay           if (roworiented) {
7178a84c255SSatish Balay             if (is == ADD_VALUES) {
718dd9472c6SBarry Smith               for (ii=0; ii<bs; ii++,value+=stepval) {
719dd9472c6SBarry Smith                 for (jj=ii; jj<bs2; jj+=bs) {
7208a84c255SSatish Balay                   bap[jj] += *value++;
721dd9472c6SBarry Smith                 }
722dd9472c6SBarry Smith               }
7230e324ae4SSatish Balay             } else {
724dd9472c6SBarry Smith               for (ii=0; ii<bs; ii++,value+=stepval) {
725dd9472c6SBarry Smith                 for (jj=ii; jj<bs2; jj+=bs) {
7260e324ae4SSatish Balay                   bap[jj] = *value++;
7278a84c255SSatish Balay                 }
728dd9472c6SBarry Smith               }
729dd9472c6SBarry Smith             }
7300e324ae4SSatish Balay           } else {
7310e324ae4SSatish Balay             if (is == ADD_VALUES) {
732dd9472c6SBarry Smith               for (ii=0; ii<bs; ii++,value+=stepval) {
733dd9472c6SBarry Smith                 for (jj=0; jj<bs; jj++) {
7340e324ae4SSatish Balay                   *bap++ += *value++;
735dd9472c6SBarry Smith                 }
736dd9472c6SBarry Smith               }
7370e324ae4SSatish Balay             } else {
738dd9472c6SBarry Smith               for (ii=0; ii<bs; ii++,value+=stepval) {
739dd9472c6SBarry Smith                 for (jj=0; jj<bs; jj++) {
7400e324ae4SSatish Balay                   *bap++  = *value++;
7410e324ae4SSatish Balay                 }
7428a84c255SSatish Balay               }
743dd9472c6SBarry Smith             }
744dd9472c6SBarry Smith           }
745f1241b54SBarry Smith           goto noinsert2;
74692c4ed94SBarry Smith         }
74792c4ed94SBarry Smith       }
74889280ab3SLois Curfman McInnes       if (nonew == 1) goto noinsert2;
74929bbc08cSBarry Smith       else if (nonew == -1) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Inserting a new nonzero in the matrix");
75092c4ed94SBarry Smith       if (nrow >= rmax) {
75192c4ed94SBarry Smith         /* there is no extra room in row, therefore enlarge */
75292c4ed94SBarry Smith         int       new_nz = ai[a->mbs] + CHUNKSIZE,len,*new_i,*new_j;
7533f1db9ecSBarry Smith         MatScalar *new_a;
75492c4ed94SBarry Smith 
75529bbc08cSBarry Smith         if (nonew == -2) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Inserting a new nonzero in the matrix");
75689280ab3SLois Curfman McInnes 
75792c4ed94SBarry Smith         /* malloc new storage space */
7583f1db9ecSBarry Smith         len     = new_nz*(sizeof(int)+bs2*sizeof(MatScalar))+(a->mbs+1)*sizeof(int);
759b0a32e0cSBarry Smith 	ierr    = PetscMalloc(len,&new_a);CHKERRQ(ierr);
76092c4ed94SBarry Smith         new_j   = (int*)(new_a + bs2*new_nz);
76192c4ed94SBarry Smith         new_i   = new_j + new_nz;
76292c4ed94SBarry Smith 
76392c4ed94SBarry Smith         /* copy over old data into new slots */
76492c4ed94SBarry Smith         for (ii=0; ii<row+1; ii++) {new_i[ii] = ai[ii];}
76592c4ed94SBarry Smith         for (ii=row+1; ii<a->mbs+1; ii++) {new_i[ii] = ai[ii]+CHUNKSIZE;}
766549d3d68SSatish Balay         ierr = PetscMemcpy(new_j,aj,(ai[row]+nrow)*sizeof(int));CHKERRQ(ierr);
76792c4ed94SBarry Smith         len  = (new_nz - CHUNKSIZE - ai[row] - nrow);
768549d3d68SSatish Balay         ierr = PetscMemcpy(new_j+ai[row]+nrow+CHUNKSIZE,aj+ai[row]+nrow,len*sizeof(int));CHKERRQ(ierr);
769549d3d68SSatish Balay         ierr = PetscMemcpy(new_a,aa,(ai[row]+nrow)*bs2*sizeof(MatScalar));CHKERRQ(ierr);
770549d3d68SSatish Balay         ierr = PetscMemzero(new_a+bs2*(ai[row]+nrow),bs2*CHUNKSIZE*sizeof(MatScalar));CHKERRQ(ierr);
771549d3d68SSatish Balay         ierr = PetscMemcpy(new_a+bs2*(ai[row]+nrow+CHUNKSIZE),aa+bs2*(ai[row]+nrow),bs2*len*sizeof(MatScalar));CHKERRQ(ierr);
77292c4ed94SBarry Smith         /* free up old matrix storage */
773606d414cSSatish Balay         ierr = PetscFree(a->a);CHKERRQ(ierr);
774606d414cSSatish Balay         if (!a->singlemalloc) {
775606d414cSSatish Balay           ierr = PetscFree(a->i);CHKERRQ(ierr);
776606d414cSSatish Balay           ierr = PetscFree(a->j);CHKERRQ(ierr);
777606d414cSSatish Balay         }
77892c4ed94SBarry Smith         aa = a->a = new_a; ai = a->i = new_i; aj = a->j = new_j;
779c4992f7dSBarry Smith         a->singlemalloc = PETSC_TRUE;
78092c4ed94SBarry Smith 
78192c4ed94SBarry Smith         rp   = aj + ai[row]; ap = aa + bs2*ai[row];
78292c4ed94SBarry Smith         rmax = imax[row] = imax[row] + CHUNKSIZE;
783b0a32e0cSBarry Smith         PetscLogObjectMemory(A,CHUNKSIZE*(sizeof(int) + bs2*sizeof(MatScalar)));
78492c4ed94SBarry Smith         a->maxnz += bs2*CHUNKSIZE;
78592c4ed94SBarry Smith         a->reallocs++;
78692c4ed94SBarry Smith         a->nz++;
78792c4ed94SBarry Smith       }
78892c4ed94SBarry Smith       N = nrow++ - 1;
78992c4ed94SBarry Smith       /* shift up all the later entries in this row */
79092c4ed94SBarry Smith       for (ii=N; ii>=i; ii--) {
79192c4ed94SBarry Smith         rp[ii+1] = rp[ii];
792549d3d68SSatish Balay         ierr = PetscMemcpy(ap+bs2*(ii+1),ap+bs2*(ii),bs2*sizeof(MatScalar));CHKERRQ(ierr);
79392c4ed94SBarry Smith       }
794549d3d68SSatish Balay       if (N >= i) {
795549d3d68SSatish Balay         ierr = PetscMemzero(ap+bs2*i,bs2*sizeof(MatScalar));CHKERRQ(ierr);
796549d3d68SSatish Balay       }
79792c4ed94SBarry Smith       rp[i] = col;
7988a84c255SSatish Balay       bap   = ap +  bs2*i;
7990e324ae4SSatish Balay       if (roworiented) {
800dd9472c6SBarry Smith         for (ii=0; ii<bs; ii++,value+=stepval) {
801dd9472c6SBarry Smith           for (jj=ii; jj<bs2; jj+=bs) {
8020e324ae4SSatish Balay             bap[jj] = *value++;
803dd9472c6SBarry Smith           }
804dd9472c6SBarry Smith         }
8050e324ae4SSatish Balay       } else {
806dd9472c6SBarry Smith         for (ii=0; ii<bs; ii++,value+=stepval) {
807dd9472c6SBarry Smith           for (jj=0; jj<bs; jj++) {
8080e324ae4SSatish Balay             *bap++  = *value++;
8090e324ae4SSatish Balay           }
810dd9472c6SBarry Smith         }
811dd9472c6SBarry Smith       }
812f1241b54SBarry Smith       noinsert2:;
81392c4ed94SBarry Smith       low = i;
81492c4ed94SBarry Smith     }
81592c4ed94SBarry Smith     ailen[row] = nrow;
81692c4ed94SBarry Smith   }
8173a40ed3dSBarry Smith   PetscFunctionReturn(0);
81892c4ed94SBarry Smith }
81992c4ed94SBarry Smith 
820f2501298SSatish Balay 
8214a2ae208SSatish Balay #undef __FUNCT__
8224a2ae208SSatish Balay #define __FUNCT__ "MatAssemblyEnd_SeqBAIJ"
8238f6be9afSLois Curfman McInnes int MatAssemblyEnd_SeqBAIJ(Mat A,MatAssemblyType mode)
824584200bdSSatish Balay {
825584200bdSSatish Balay   Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)A->data;
826584200bdSSatish Balay   int        fshift = 0,i,j,*ai = a->i,*aj = a->j,*imax = a->imax;
827273d9f13SBarry Smith   int        m = A->m,*ip,N,*ailen = a->ilen;
828549d3d68SSatish Balay   int        mbs = a->mbs,bs2 = a->bs2,rmax = 0,ierr;
8293f1db9ecSBarry Smith   MatScalar  *aa = a->a,*ap;
830584200bdSSatish Balay 
8313a40ed3dSBarry Smith   PetscFunctionBegin;
8323a40ed3dSBarry Smith   if (mode == MAT_FLUSH_ASSEMBLY) PetscFunctionReturn(0);
833584200bdSSatish Balay 
83443ee02c3SBarry Smith   if (m) rmax = ailen[0];
835584200bdSSatish Balay   for (i=1; i<mbs; i++) {
836584200bdSSatish Balay     /* move each row back by the amount of empty slots (fshift) before it*/
837584200bdSSatish Balay     fshift += imax[i-1] - ailen[i-1];
838d402145bSBarry Smith     rmax   = PetscMax(rmax,ailen[i]);
839584200bdSSatish Balay     if (fshift) {
840a7c10996SSatish Balay       ip = aj + ai[i]; ap = aa + bs2*ai[i];
841584200bdSSatish Balay       N = ailen[i];
842584200bdSSatish Balay       for (j=0; j<N; j++) {
843584200bdSSatish Balay         ip[j-fshift] = ip[j];
844549d3d68SSatish Balay         ierr = PetscMemcpy(ap+(j-fshift)*bs2,ap+j*bs2,bs2*sizeof(MatScalar));CHKERRQ(ierr);
845584200bdSSatish Balay       }
846584200bdSSatish Balay     }
847584200bdSSatish Balay     ai[i] = ai[i-1] + ailen[i-1];
848584200bdSSatish Balay   }
849584200bdSSatish Balay   if (mbs) {
850584200bdSSatish Balay     fshift += imax[mbs-1] - ailen[mbs-1];
851584200bdSSatish Balay     ai[mbs] = ai[mbs-1] + ailen[mbs-1];
852584200bdSSatish Balay   }
853584200bdSSatish Balay   /* reset ilen and imax for each row */
854584200bdSSatish Balay   for (i=0; i<mbs; i++) {
855584200bdSSatish Balay     ailen[i] = imax[i] = ai[i+1] - ai[i];
856584200bdSSatish Balay   }
857a7c10996SSatish Balay   a->nz = ai[mbs];
858584200bdSSatish Balay 
859584200bdSSatish Balay   /* diagonals may have moved, so kill the diagonal pointers */
860584200bdSSatish Balay   if (fshift && a->diag) {
861606d414cSSatish Balay     ierr = PetscFree(a->diag);CHKERRQ(ierr);
862b0a32e0cSBarry Smith     PetscLogObjectMemory(A,-(m+1)*sizeof(int));
863584200bdSSatish Balay     a->diag = 0;
864584200bdSSatish Balay   }
865b0a32e0cSBarry Smith   PetscLogInfo(A,"MatAssemblyEnd_SeqBAIJ:Matrix size: %d X %d, block size %d; storage space: %d unneeded, %d used\n",
866273d9f13SBarry Smith            m,A->n,a->bs,fshift*bs2,a->nz*bs2);
867b0a32e0cSBarry Smith   PetscLogInfo(A,"MatAssemblyEnd_SeqBAIJ:Number of mallocs during MatSetValues is %d\n",
868584200bdSSatish Balay            a->reallocs);
869b0a32e0cSBarry Smith   PetscLogInfo(A,"MatAssemblyEnd_SeqBAIJ:Most nonzeros blocks in any row is %d\n",rmax);
870e2f3b5e9SSatish Balay   a->reallocs          = 0;
8710e6d2581SBarry Smith   A->info.nz_unneeded  = (PetscReal)fshift*bs2;
8724e220ebcSLois Curfman McInnes 
8733a40ed3dSBarry Smith   PetscFunctionReturn(0);
874584200bdSSatish Balay }
875584200bdSSatish Balay 
8765a838052SSatish Balay 
877bea157c4SSatish Balay 
878bea157c4SSatish Balay /*
879bea157c4SSatish Balay    This function returns an array of flags which indicate the locations of contiguous
880bea157c4SSatish Balay    blocks that should be zeroed. for eg: if bs = 3  and is = [0,1,2,3,5,6,7,8,9]
881bea157c4SSatish Balay    then the resulting sizes = [3,1,1,3,1] correspondig to sets [(0,1,2),(3),(5),(6,7,8),(9)]
882bea157c4SSatish Balay    Assume: sizes should be long enough to hold all the values.
883bea157c4SSatish Balay */
8844a2ae208SSatish Balay #undef __FUNCT__
8854a2ae208SSatish Balay #define __FUNCT__ "MatZeroRows_SeqBAIJ_Check_Blocks"
886bea157c4SSatish Balay static int MatZeroRows_SeqBAIJ_Check_Blocks(int idx[],int n,int bs,int sizes[], int *bs_max)
887d9b7c43dSSatish Balay {
888bea157c4SSatish Balay   int        i,j,k,row;
889bea157c4SSatish Balay   PetscTruth flg;
8903a40ed3dSBarry Smith 
891433994e6SBarry Smith   PetscFunctionBegin;
892bea157c4SSatish Balay   for (i=0,j=0; i<n; j++) {
893bea157c4SSatish Balay     row = idx[i];
894bea157c4SSatish Balay     if (row%bs!=0) { /* Not the begining of a block */
895bea157c4SSatish Balay       sizes[j] = 1;
896bea157c4SSatish Balay       i++;
897e4fda26cSSatish Balay     } else if (i+bs > n) { /* complete block doesn't exist (at idx end) */
898bea157c4SSatish Balay       sizes[j] = 1;         /* Also makes sure atleast 'bs' values exist for next else */
899bea157c4SSatish Balay       i++;
900bea157c4SSatish Balay     } else { /* Begining of the block, so check if the complete block exists */
901bea157c4SSatish Balay       flg = PETSC_TRUE;
902bea157c4SSatish Balay       for (k=1; k<bs; k++) {
903bea157c4SSatish Balay         if (row+k != idx[i+k]) { /* break in the block */
904bea157c4SSatish Balay           flg = PETSC_FALSE;
905bea157c4SSatish Balay           break;
906d9b7c43dSSatish Balay         }
907bea157c4SSatish Balay       }
908bea157c4SSatish Balay       if (flg == PETSC_TRUE) { /* No break in the bs */
909bea157c4SSatish Balay         sizes[j] = bs;
910bea157c4SSatish Balay         i+= bs;
911bea157c4SSatish Balay       } else {
912bea157c4SSatish Balay         sizes[j] = 1;
913bea157c4SSatish Balay         i++;
914bea157c4SSatish Balay       }
915bea157c4SSatish Balay     }
916bea157c4SSatish Balay   }
917bea157c4SSatish Balay   *bs_max = j;
9183a40ed3dSBarry Smith   PetscFunctionReturn(0);
919d9b7c43dSSatish Balay }
920d9b7c43dSSatish Balay 
9214a2ae208SSatish Balay #undef __FUNCT__
9224a2ae208SSatish Balay #define __FUNCT__ "MatZeroRows_SeqBAIJ"
9238f6be9afSLois Curfman McInnes int MatZeroRows_SeqBAIJ(Mat A,IS is,Scalar *diag)
924d9b7c43dSSatish Balay {
925d9b7c43dSSatish Balay   Mat_SeqBAIJ *baij=(Mat_SeqBAIJ*)A->data;
926b6815fffSBarry Smith   int         ierr,i,j,k,count,is_n,*is_idx,*rows;
927bea157c4SSatish Balay   int         bs=baij->bs,bs2=baij->bs2,*sizes,row,bs_max;
9283f1db9ecSBarry Smith   Scalar      zero = 0.0;
9293f1db9ecSBarry Smith   MatScalar   *aa;
930d9b7c43dSSatish Balay 
9313a40ed3dSBarry Smith   PetscFunctionBegin;
932d9b7c43dSSatish Balay   /* Make a copy of the IS and  sort it */
933b9b97703SBarry Smith   ierr = ISGetLocalSize(is,&is_n);CHKERRQ(ierr);
934d9b7c43dSSatish Balay   ierr = ISGetIndices(is,&is_idx);CHKERRQ(ierr);
935d9b7c43dSSatish Balay 
936bea157c4SSatish Balay   /* allocate memory for rows,sizes */
937b0a32e0cSBarry Smith   ierr  = PetscMalloc((3*is_n+1)*sizeof(int),&rows);CHKERRQ(ierr);
938bea157c4SSatish Balay   sizes = rows + is_n;
939bea157c4SSatish Balay 
940563b5814SBarry Smith   /* copy IS values to rows, and sort them */
941bea157c4SSatish Balay   for (i=0; i<is_n; i++) { rows[i] = is_idx[i]; }
942bea157c4SSatish Balay   ierr = PetscSortInt(is_n,rows);CHKERRQ(ierr);
943dffd3267SBarry Smith   if (baij->keepzeroedrows) {
944dffd3267SBarry Smith     for (i=0; i<is_n; i++) { sizes[i] = 1; }
945dffd3267SBarry Smith     bs_max = is_n;
946dffd3267SBarry Smith   } else {
947bea157c4SSatish Balay     ierr = MatZeroRows_SeqBAIJ_Check_Blocks(rows,is_n,bs,sizes,&bs_max);CHKERRQ(ierr);
948dffd3267SBarry Smith   }
949b97a56abSSatish Balay   ierr = ISRestoreIndices(is,&is_idx);CHKERRQ(ierr);
950bea157c4SSatish Balay 
951bea157c4SSatish Balay   for (i=0,j=0; i<bs_max; j+=sizes[i],i++) {
952bea157c4SSatish Balay     row   = rows[j];
953273d9f13SBarry Smith     if (row < 0 || row > A->m) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"row %d out of range",row);
954bea157c4SSatish Balay     count = (baij->i[row/bs +1] - baij->i[row/bs])*bs;
955bea157c4SSatish Balay     aa    = baij->a + baij->i[row/bs]*bs2 + (row%bs);
956dffd3267SBarry Smith     if (sizes[i] == bs && !baij->keepzeroedrows) {
957bea157c4SSatish Balay       if (diag) {
958bea157c4SSatish Balay         if (baij->ilen[row/bs] > 0) {
959bea157c4SSatish Balay           baij->ilen[row/bs]       = 1;
960bea157c4SSatish Balay           baij->j[baij->i[row/bs]] = row/bs;
961bea157c4SSatish Balay           ierr = PetscMemzero(aa,count*bs*sizeof(MatScalar));CHKERRQ(ierr);
962a07cd24cSSatish Balay         }
963563b5814SBarry Smith         /* Now insert all the diagonal values for this bs */
964bea157c4SSatish Balay         for (k=0; k<bs; k++) {
965bea157c4SSatish Balay           ierr = (*A->ops->setvalues)(A,1,rows+j+k,1,rows+j+k,diag,INSERT_VALUES);CHKERRQ(ierr);
966bea157c4SSatish Balay         }
967bea157c4SSatish Balay       } else { /* (!diag) */
968bea157c4SSatish Balay         baij->ilen[row/bs] = 0;
969bea157c4SSatish Balay       } /* end (!diag) */
970bea157c4SSatish Balay     } else { /* (sizes[i] != bs) */
971aa482453SBarry Smith #if defined (PETSC_USE_DEBUG)
97229bbc08cSBarry Smith       if (sizes[i] != 1) SETERRQ(1,"Internal Error. Value should be 1");
973bea157c4SSatish Balay #endif
974bea157c4SSatish Balay       for (k=0; k<count; k++) {
975d9b7c43dSSatish Balay         aa[0] =  zero;
976d9b7c43dSSatish Balay         aa    += bs;
977d9b7c43dSSatish Balay       }
978d9b7c43dSSatish Balay       if (diag) {
979f830108cSBarry Smith         ierr = (*A->ops->setvalues)(A,1,rows+j,1,rows+j,diag,INSERT_VALUES);CHKERRQ(ierr);
980d9b7c43dSSatish Balay       }
981d9b7c43dSSatish Balay     }
982bea157c4SSatish Balay   }
983bea157c4SSatish Balay 
984606d414cSSatish Balay   ierr = PetscFree(rows);CHKERRQ(ierr);
9859a8dea36SBarry Smith   ierr = MatAssemblyEnd_SeqBAIJ(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
9863a40ed3dSBarry Smith   PetscFunctionReturn(0);
987d9b7c43dSSatish Balay }
9881c351548SSatish Balay 
9894a2ae208SSatish Balay #undef __FUNCT__
9904a2ae208SSatish Balay #define __FUNCT__ "MatSetValues_SeqBAIJ"
9912d61bbb3SSatish Balay int MatSetValues_SeqBAIJ(Mat A,int m,int *im,int n,int *in,Scalar *v,InsertMode is)
9922d61bbb3SSatish Balay {
9932d61bbb3SSatish Balay   Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)A->data;
9942d61bbb3SSatish Balay   int         *rp,k,low,high,t,ii,row,nrow,i,col,l,rmax,N,sorted=a->sorted;
995273d9f13SBarry Smith   int         *imax=a->imax,*ai=a->i,*ailen=a->ilen;
9962d61bbb3SSatish Balay   int         *aj=a->j,nonew=a->nonew,bs=a->bs,brow,bcol;
997549d3d68SSatish Balay   int         ridx,cidx,bs2=a->bs2,ierr;
998273d9f13SBarry Smith   PetscTruth  roworiented=a->roworiented;
9993f1db9ecSBarry Smith   MatScalar   *ap,value,*aa=a->a,*bap;
10002d61bbb3SSatish Balay 
10012d61bbb3SSatish Balay   PetscFunctionBegin;
10022d61bbb3SSatish Balay   for (k=0; k<m; k++) { /* loop over added rows */
10032d61bbb3SSatish Balay     row  = im[k]; brow = row/bs;
10045ef9f2a5SBarry Smith     if (row < 0) continue;
1005aa482453SBarry Smith #if defined(PETSC_USE_BOPT_g)
1006273d9f13SBarry Smith     if (row >= A->m) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"Row too large: row %d max %d",row,A->m);
10072d61bbb3SSatish Balay #endif
10082d61bbb3SSatish Balay     rp   = aj + ai[brow];
10092d61bbb3SSatish Balay     ap   = aa + bs2*ai[brow];
10102d61bbb3SSatish Balay     rmax = imax[brow];
10112d61bbb3SSatish Balay     nrow = ailen[brow];
10122d61bbb3SSatish Balay     low  = 0;
10132d61bbb3SSatish Balay     for (l=0; l<n; l++) { /* loop over added columns */
10145ef9f2a5SBarry Smith       if (in[l] < 0) continue;
1015aa482453SBarry Smith #if defined(PETSC_USE_BOPT_g)
1016273d9f13SBarry Smith       if (in[l] >= A->n) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"Column too large: col %d max %d",in[l],A->n);
10172d61bbb3SSatish Balay #endif
10182d61bbb3SSatish Balay       col = in[l]; bcol = col/bs;
10192d61bbb3SSatish Balay       ridx = row % bs; cidx = col % bs;
10202d61bbb3SSatish Balay       if (roworiented) {
10215ef9f2a5SBarry Smith         value = v[l + k*n];
10222d61bbb3SSatish Balay       } else {
10232d61bbb3SSatish Balay         value = v[k + l*m];
10242d61bbb3SSatish Balay       }
10252d61bbb3SSatish Balay       if (!sorted) low = 0; high = nrow;
10262d61bbb3SSatish Balay       while (high-low > 7) {
10272d61bbb3SSatish Balay         t = (low+high)/2;
10282d61bbb3SSatish Balay         if (rp[t] > bcol) high = t;
10292d61bbb3SSatish Balay         else              low  = t;
10302d61bbb3SSatish Balay       }
10312d61bbb3SSatish Balay       for (i=low; i<high; i++) {
10322d61bbb3SSatish Balay         if (rp[i] > bcol) break;
10332d61bbb3SSatish Balay         if (rp[i] == bcol) {
10342d61bbb3SSatish Balay           bap  = ap +  bs2*i + bs*cidx + ridx;
10352d61bbb3SSatish Balay           if (is == ADD_VALUES) *bap += value;
10362d61bbb3SSatish Balay           else                  *bap  = value;
10372d61bbb3SSatish Balay           goto noinsert1;
10382d61bbb3SSatish Balay         }
10392d61bbb3SSatish Balay       }
10402d61bbb3SSatish Balay       if (nonew == 1) goto noinsert1;
104129bbc08cSBarry Smith       else if (nonew == -1) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Inserting a new nonzero in the matrix");
10422d61bbb3SSatish Balay       if (nrow >= rmax) {
10432d61bbb3SSatish Balay         /* there is no extra room in row, therefore enlarge */
10442d61bbb3SSatish Balay         int       new_nz = ai[a->mbs] + CHUNKSIZE,len,*new_i,*new_j;
10453f1db9ecSBarry Smith         MatScalar *new_a;
10462d61bbb3SSatish Balay 
104729bbc08cSBarry Smith         if (nonew == -2) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Inserting a new nonzero in the matrix");
10482d61bbb3SSatish Balay 
10492d61bbb3SSatish Balay         /* Malloc new storage space */
10503f1db9ecSBarry Smith         len     = new_nz*(sizeof(int)+bs2*sizeof(MatScalar))+(a->mbs+1)*sizeof(int);
1051b0a32e0cSBarry Smith 	ierr    = PetscMalloc(len,&new_a);CHKERRQ(ierr);
10522d61bbb3SSatish Balay         new_j   = (int*)(new_a + bs2*new_nz);
10532d61bbb3SSatish Balay         new_i   = new_j + new_nz;
10542d61bbb3SSatish Balay 
10552d61bbb3SSatish Balay         /* copy over old data into new slots */
10562d61bbb3SSatish Balay         for (ii=0; ii<brow+1; ii++) {new_i[ii] = ai[ii];}
10572d61bbb3SSatish Balay         for (ii=brow+1; ii<a->mbs+1; ii++) {new_i[ii] = ai[ii]+CHUNKSIZE;}
1058549d3d68SSatish Balay         ierr = PetscMemcpy(new_j,aj,(ai[brow]+nrow)*sizeof(int));CHKERRQ(ierr);
10592d61bbb3SSatish Balay         len  = (new_nz - CHUNKSIZE - ai[brow] - nrow);
1060549d3d68SSatish Balay         ierr = PetscMemcpy(new_j+ai[brow]+nrow+CHUNKSIZE,aj+ai[brow]+nrow,len*sizeof(int));CHKERRQ(ierr);
1061549d3d68SSatish Balay         ierr = PetscMemcpy(new_a,aa,(ai[brow]+nrow)*bs2*sizeof(MatScalar));CHKERRQ(ierr);
1062549d3d68SSatish Balay         ierr = PetscMemzero(new_a+bs2*(ai[brow]+nrow),bs2*CHUNKSIZE*sizeof(MatScalar));CHKERRQ(ierr);
1063549d3d68SSatish Balay         ierr = PetscMemcpy(new_a+bs2*(ai[brow]+nrow+CHUNKSIZE),aa+bs2*(ai[brow]+nrow),bs2*len*sizeof(MatScalar));CHKERRQ(ierr);
10642d61bbb3SSatish Balay         /* free up old matrix storage */
1065606d414cSSatish Balay         ierr = PetscFree(a->a);CHKERRQ(ierr);
1066606d414cSSatish Balay         if (!a->singlemalloc) {
1067606d414cSSatish Balay           ierr = PetscFree(a->i);CHKERRQ(ierr);
1068606d414cSSatish Balay           ierr = PetscFree(a->j);CHKERRQ(ierr);
1069606d414cSSatish Balay         }
10702d61bbb3SSatish Balay         aa = a->a = new_a; ai = a->i = new_i; aj = a->j = new_j;
1071c4992f7dSBarry Smith         a->singlemalloc = PETSC_TRUE;
10722d61bbb3SSatish Balay 
10732d61bbb3SSatish Balay         rp   = aj + ai[brow]; ap = aa + bs2*ai[brow];
10742d61bbb3SSatish Balay         rmax = imax[brow] = imax[brow] + CHUNKSIZE;
1075b0a32e0cSBarry Smith         PetscLogObjectMemory(A,CHUNKSIZE*(sizeof(int) + bs2*sizeof(MatScalar)));
10762d61bbb3SSatish Balay         a->maxnz += bs2*CHUNKSIZE;
10772d61bbb3SSatish Balay         a->reallocs++;
10782d61bbb3SSatish Balay         a->nz++;
10792d61bbb3SSatish Balay       }
10802d61bbb3SSatish Balay       N = nrow++ - 1;
10812d61bbb3SSatish Balay       /* shift up all the later entries in this row */
10822d61bbb3SSatish Balay       for (ii=N; ii>=i; ii--) {
10832d61bbb3SSatish Balay         rp[ii+1] = rp[ii];
1084549d3d68SSatish Balay         ierr     = PetscMemcpy(ap+bs2*(ii+1),ap+bs2*(ii),bs2*sizeof(MatScalar));CHKERRQ(ierr);
10852d61bbb3SSatish Balay       }
1086549d3d68SSatish Balay       if (N>=i) {
1087549d3d68SSatish Balay         ierr = PetscMemzero(ap+bs2*i,bs2*sizeof(MatScalar));CHKERRQ(ierr);
1088549d3d68SSatish Balay       }
10892d61bbb3SSatish Balay       rp[i]                      = bcol;
10902d61bbb3SSatish Balay       ap[bs2*i + bs*cidx + ridx] = value;
10912d61bbb3SSatish Balay       noinsert1:;
10922d61bbb3SSatish Balay       low = i;
10932d61bbb3SSatish Balay     }
10942d61bbb3SSatish Balay     ailen[brow] = nrow;
10952d61bbb3SSatish Balay   }
10962d61bbb3SSatish Balay   PetscFunctionReturn(0);
10972d61bbb3SSatish Balay }
10982d61bbb3SSatish Balay 
1099b9b97703SBarry Smith EXTERN int MatLUFactorSymbolic_SeqBAIJ(Mat,IS,IS,MatLUInfo*,Mat*);
1100b9b97703SBarry Smith EXTERN int MatLUFactor_SeqBAIJ(Mat,IS,IS,MatLUInfo*);
1101ca44d042SBarry Smith EXTERN int MatIncreaseOverlap_SeqBAIJ(Mat,int,IS*,int);
1102ca44d042SBarry Smith EXTERN int MatGetSubMatrix_SeqBAIJ(Mat,IS,IS,int,MatReuse,Mat*);
1103ca44d042SBarry Smith EXTERN int MatGetSubMatrices_SeqBAIJ(Mat,int,IS*,IS*,MatReuse,Mat**);
1104ca44d042SBarry Smith EXTERN int MatMultTranspose_SeqBAIJ(Mat,Vec,Vec);
1105ca44d042SBarry Smith EXTERN int MatMultTransposeAdd_SeqBAIJ(Mat,Vec,Vec,Vec);
1106ca44d042SBarry Smith EXTERN int MatScale_SeqBAIJ(Scalar*,Mat);
1107ca44d042SBarry Smith EXTERN int MatNorm_SeqBAIJ(Mat,NormType,PetscReal *);
1108ca44d042SBarry Smith EXTERN int MatEqual_SeqBAIJ(Mat,Mat,PetscTruth*);
1109ca44d042SBarry Smith EXTERN int MatGetDiagonal_SeqBAIJ(Mat,Vec);
1110ca44d042SBarry Smith EXTERN int MatDiagonalScale_SeqBAIJ(Mat,Vec,Vec);
1111ca44d042SBarry Smith EXTERN int MatGetInfo_SeqBAIJ(Mat,MatInfoType,MatInfo *);
1112ca44d042SBarry Smith EXTERN int MatZeroEntries_SeqBAIJ(Mat);
11132d61bbb3SSatish Balay 
1114ca44d042SBarry Smith EXTERN int MatSolve_SeqBAIJ_N(Mat,Vec,Vec);
1115ca44d042SBarry Smith EXTERN int MatSolve_SeqBAIJ_1(Mat,Vec,Vec);
1116ca44d042SBarry Smith EXTERN int MatSolve_SeqBAIJ_2(Mat,Vec,Vec);
1117ca44d042SBarry Smith EXTERN int MatSolve_SeqBAIJ_3(Mat,Vec,Vec);
1118ca44d042SBarry Smith EXTERN int MatSolve_SeqBAIJ_4(Mat,Vec,Vec);
1119ca44d042SBarry Smith EXTERN int MatSolve_SeqBAIJ_5(Mat,Vec,Vec);
1120ca44d042SBarry Smith EXTERN int MatSolve_SeqBAIJ_6(Mat,Vec,Vec);
1121ca44d042SBarry Smith EXTERN int MatSolve_SeqBAIJ_7(Mat,Vec,Vec);
1122ca44d042SBarry Smith EXTERN int MatSolveTranspose_SeqBAIJ_7(Mat,Vec,Vec);
1123ca44d042SBarry Smith EXTERN int MatSolveTranspose_SeqBAIJ_6(Mat,Vec,Vec);
1124ca44d042SBarry Smith EXTERN int MatSolveTranspose_SeqBAIJ_5(Mat,Vec,Vec);
1125ca44d042SBarry Smith EXTERN int MatSolveTranspose_SeqBAIJ_4(Mat,Vec,Vec);
1126ca44d042SBarry Smith EXTERN int MatSolveTranspose_SeqBAIJ_3(Mat,Vec,Vec);
1127ca44d042SBarry Smith EXTERN int MatSolveTranspose_SeqBAIJ_2(Mat,Vec,Vec);
1128ca44d042SBarry Smith EXTERN int MatSolveTranspose_SeqBAIJ_1(Mat,Vec,Vec);
11292d61bbb3SSatish Balay 
1130ca44d042SBarry Smith EXTERN int MatLUFactorNumeric_SeqBAIJ_N(Mat,Mat*);
1131ca44d042SBarry Smith EXTERN int MatLUFactorNumeric_SeqBAIJ_1(Mat,Mat*);
1132ca44d042SBarry Smith EXTERN int MatLUFactorNumeric_SeqBAIJ_2(Mat,Mat*);
1133ca44d042SBarry Smith EXTERN int MatLUFactorNumeric_SeqBAIJ_3(Mat,Mat*);
1134ca44d042SBarry Smith EXTERN int MatLUFactorNumeric_SeqBAIJ_4(Mat,Mat*);
1135ca44d042SBarry Smith EXTERN int MatLUFactorNumeric_SeqBAIJ_5(Mat,Mat*);
1136ca44d042SBarry Smith EXTERN int MatLUFactorNumeric_SeqBAIJ_6(Mat,Mat*);
11372d61bbb3SSatish Balay 
1138ca44d042SBarry Smith EXTERN int MatMult_SeqBAIJ_1(Mat,Vec,Vec);
1139ca44d042SBarry Smith EXTERN int MatMult_SeqBAIJ_2(Mat,Vec,Vec);
1140ca44d042SBarry Smith EXTERN int MatMult_SeqBAIJ_3(Mat,Vec,Vec);
1141ca44d042SBarry Smith EXTERN int MatMult_SeqBAIJ_4(Mat,Vec,Vec);
1142ca44d042SBarry Smith EXTERN int MatMult_SeqBAIJ_5(Mat,Vec,Vec);
1143ca44d042SBarry Smith EXTERN int MatMult_SeqBAIJ_6(Mat,Vec,Vec);
1144ca44d042SBarry Smith EXTERN int MatMult_SeqBAIJ_7(Mat,Vec,Vec);
1145ca44d042SBarry Smith EXTERN int MatMult_SeqBAIJ_N(Mat,Vec,Vec);
11462d61bbb3SSatish Balay 
1147ca44d042SBarry Smith EXTERN int MatMultAdd_SeqBAIJ_1(Mat,Vec,Vec,Vec);
1148ca44d042SBarry Smith EXTERN int MatMultAdd_SeqBAIJ_2(Mat,Vec,Vec,Vec);
1149ca44d042SBarry Smith EXTERN int MatMultAdd_SeqBAIJ_3(Mat,Vec,Vec,Vec);
1150ca44d042SBarry Smith EXTERN int MatMultAdd_SeqBAIJ_4(Mat,Vec,Vec,Vec);
1151ca44d042SBarry Smith EXTERN int MatMultAdd_SeqBAIJ_5(Mat,Vec,Vec,Vec);
1152ca44d042SBarry Smith EXTERN int MatMultAdd_SeqBAIJ_6(Mat,Vec,Vec,Vec);
1153ca44d042SBarry Smith EXTERN int MatMultAdd_SeqBAIJ_7(Mat,Vec,Vec,Vec);
1154ca44d042SBarry Smith EXTERN int MatMultAdd_SeqBAIJ_N(Mat,Vec,Vec,Vec);
11552d61bbb3SSatish Balay 
11564a2ae208SSatish Balay #undef __FUNCT__
11574a2ae208SSatish Balay #define __FUNCT__ "MatILUFactor_SeqBAIJ"
11585ef9f2a5SBarry Smith int MatILUFactor_SeqBAIJ(Mat inA,IS row,IS col,MatILUInfo *info)
11592d61bbb3SSatish Balay {
11602d61bbb3SSatish Balay   Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)inA->data;
11612d61bbb3SSatish Balay   Mat         outA;
11622d61bbb3SSatish Balay   int         ierr;
1163667159a5SBarry Smith   PetscTruth  row_identity,col_identity;
11642d61bbb3SSatish Balay 
11652d61bbb3SSatish Balay   PetscFunctionBegin;
116629bbc08cSBarry Smith   if (info && info->levels != 0) SETERRQ(PETSC_ERR_SUP,"Only levels = 0 supported for in-place ILU");
1167667159a5SBarry Smith   ierr = ISIdentity(row,&row_identity);CHKERRQ(ierr);
1168667159a5SBarry Smith   ierr = ISIdentity(col,&col_identity);CHKERRQ(ierr);
1169667159a5SBarry Smith   if (!row_identity || !col_identity) {
117029bbc08cSBarry Smith     SETERRQ(1,"Row and column permutations must be identity for in-place ILU");
1171667159a5SBarry Smith   }
11722d61bbb3SSatish Balay 
11732d61bbb3SSatish Balay   outA          = inA;
11742d61bbb3SSatish Balay   inA->factor   = FACTOR_LU;
11752d61bbb3SSatish Balay 
11762d61bbb3SSatish Balay   if (!a->diag) {
1177c4992f7dSBarry Smith     ierr = MatMarkDiagonal_SeqBAIJ(inA);CHKERRQ(ierr);
11782d61bbb3SSatish Balay   }
11792d61bbb3SSatish Balay   /*
118015091d37SBarry Smith       Blocksize 2, 3, 4, 5, 6 and 7 have a special faster factorization/solver
118115091d37SBarry Smith       for ILU(0) factorization with natural ordering
11822d61bbb3SSatish Balay   */
118315091d37SBarry Smith   switch (a->bs) {
1184f1af5d2fSBarry Smith   case 1:
1185e37c484bSBarry Smith     inA->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_1;
1186e37c484bSBarry Smith     inA->ops->solve           = MatSolve_SeqBAIJ_1_NaturalOrdering;
1187e37c484bSBarry Smith     inA->ops->solvetranspose  = MatSolveTranspose_SeqBAIJ_1_NaturalOrdering;
1188b0a32e0cSBarry Smith     PetscLogInfo(inA,"MatILUFactor_SeqBAIJ:Using special in-place natural ordering factor and solve BS=1\n");
118915091d37SBarry Smith   case 2:
119015091d37SBarry Smith     inA->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_2_NaturalOrdering;
119115091d37SBarry Smith     inA->ops->solve           = MatSolve_SeqBAIJ_2_NaturalOrdering;
11927c922b88SBarry Smith     inA->ops->solvetranspose  = MatSolveTranspose_SeqBAIJ_2_NaturalOrdering;
1193b0a32e0cSBarry Smith     PetscLogInfo(inA,"MatILUFactor_SeqBAIJ:Using special in-place natural ordering factor and solve BS=2\n");
119415091d37SBarry Smith     break;
119515091d37SBarry Smith   case 3:
119615091d37SBarry Smith     inA->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_3_NaturalOrdering;
119715091d37SBarry Smith     inA->ops->solve           = MatSolve_SeqBAIJ_3_NaturalOrdering;
11987c922b88SBarry Smith     inA->ops->solvetranspose  = MatSolveTranspose_SeqBAIJ_3_NaturalOrdering;
1199b0a32e0cSBarry Smith     PetscLogInfo(inA,"MatILUFactor_SeqBAIJ:Using special in-place natural ordering factor and solve BS=3\n");
120015091d37SBarry Smith     break;
120115091d37SBarry Smith   case 4:
1202*35662bc6SKris Buschelman #if defined(PETSC_HAVE_SSE)
1203*35662bc6SKris Buschelman     PetscTruth sse_enabled;
1204*35662bc6SKris Buschelman     ierr = PetscSSEIsEnabled(&sse_enabled);CHKERRQ(ierr);
1205*35662bc6SKris Buschelman     if (sse_enabled) {
1206*35662bc6SKris Buschelman       inA->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_4_NaturalOrdering_SSE;
1207*35662bc6SKris Buschelman     } else {
1208667159a5SBarry Smith       inA->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_4_NaturalOrdering;
1209*35662bc6SKris Buschelman     }
1210*35662bc6SKris Buschelman #else
1211*35662bc6SKris Buschelman     inA->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_4_NaturalOrdering;
1212*35662bc6SKris Buschelman #endif
1213f830108cSBarry Smith     inA->ops->solve           = MatSolve_SeqBAIJ_4_NaturalOrdering;
12147c922b88SBarry Smith     inA->ops->solvetranspose  = MatSolveTranspose_SeqBAIJ_4_NaturalOrdering;
1215b0a32e0cSBarry Smith     PetscLogInfo(inA,"MatILUFactor_SeqBAIJ:Using special in-place natural ordering factor and solve BS=4\n");
121615091d37SBarry Smith     break;
121715091d37SBarry Smith   case 5:
1218667159a5SBarry Smith     inA->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_5_NaturalOrdering;
1219667159a5SBarry Smith     inA->ops->solve           = MatSolve_SeqBAIJ_5_NaturalOrdering;
12207c922b88SBarry Smith     inA->ops->solvetranspose  = MatSolveTranspose_SeqBAIJ_5_NaturalOrdering;
1221b0a32e0cSBarry Smith     PetscLogInfo(inA,"MatILUFactor_SeqBAIJ:Using special in-place natural ordering factor and solve BS=5\n");
122215091d37SBarry Smith     break;
122315091d37SBarry Smith   case 6:
122415091d37SBarry Smith     inA->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_6_NaturalOrdering;
122515091d37SBarry Smith     inA->ops->solve           = MatSolve_SeqBAIJ_6_NaturalOrdering;
12267c922b88SBarry Smith     inA->ops->solvetranspose  = MatSolveTranspose_SeqBAIJ_6_NaturalOrdering;
1227b0a32e0cSBarry Smith     PetscLogInfo(inA,"MatILUFactor_SeqBAIJ:Using special in-place natural ordering factor and solve BS=6\n");
122815091d37SBarry Smith     break;
122915091d37SBarry Smith   case 7:
123015091d37SBarry Smith     inA->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_7_NaturalOrdering;
12317c922b88SBarry Smith     inA->ops->solvetranspose  = MatSolveTranspose_SeqBAIJ_7_NaturalOrdering;
123215091d37SBarry Smith     inA->ops->solve           = MatSolve_SeqBAIJ_7_NaturalOrdering;
1233b0a32e0cSBarry Smith     PetscLogInfo(inA,"MatILUFactor_SeqBAIJ:Using special in-place natural ordering factor and solve BS=7\n");
123415091d37SBarry Smith     break;
1235c38d4ed2SBarry Smith   default:
1236c38d4ed2SBarry Smith     a->row        = row;
1237c38d4ed2SBarry Smith     a->col        = col;
1238c38d4ed2SBarry Smith     ierr          = PetscObjectReference((PetscObject)row);CHKERRQ(ierr);
1239c38d4ed2SBarry Smith     ierr          = PetscObjectReference((PetscObject)col);CHKERRQ(ierr);
1240c38d4ed2SBarry Smith 
1241c38d4ed2SBarry Smith     /* Create the invert permutation so that it can be used in MatLUFactorNumeric() */
12424c49b128SBarry Smith     ierr = ISInvertPermutation(col,PETSC_DECIDE,&a->icol);CHKERRQ(ierr);
1243b0a32e0cSBarry Smith     PetscLogObjectParent(inA,a->icol);
1244c38d4ed2SBarry Smith 
1245c38d4ed2SBarry Smith     if (!a->solve_work) {
1246b0a32e0cSBarry Smith       ierr = PetscMalloc((inA->m+a->bs)*sizeof(Scalar),&a->solve_work);CHKERRQ(ierr);
1247b0a32e0cSBarry Smith       PetscLogObjectMemory(inA,(inA->m+a->bs)*sizeof(Scalar));
1248c38d4ed2SBarry Smith     }
12492d61bbb3SSatish Balay   }
12502d61bbb3SSatish Balay 
1251667159a5SBarry Smith   ierr = MatLUFactorNumeric(inA,&outA);CHKERRQ(ierr);
1252667159a5SBarry Smith 
12532d61bbb3SSatish Balay   PetscFunctionReturn(0);
12542d61bbb3SSatish Balay }
12554a2ae208SSatish Balay #undef __FUNCT__
12564a2ae208SSatish Balay #define __FUNCT__ "MatPrintHelp_SeqBAIJ"
1257ba4ca20aSSatish Balay int MatPrintHelp_SeqBAIJ(Mat A)
1258ba4ca20aSSatish Balay {
1259c38d4ed2SBarry Smith   static PetscTruth called = PETSC_FALSE;
1260ba4ca20aSSatish Balay   MPI_Comm          comm = A->comm;
1261d132466eSBarry Smith   int               ierr;
1262ba4ca20aSSatish Balay 
12633a40ed3dSBarry Smith   PetscFunctionBegin;
1264c38d4ed2SBarry Smith   if (called) {PetscFunctionReturn(0);} else called = PETSC_TRUE;
1265d132466eSBarry Smith   ierr = (*PetscHelpPrintf)(comm," Options for MATSEQBAIJ and MATMPIBAIJ matrix formats (the defaults):\n");CHKERRQ(ierr);
1266d132466eSBarry Smith   ierr = (*PetscHelpPrintf)(comm,"  -mat_block_size <block_size>\n");CHKERRQ(ierr);
12673a40ed3dSBarry Smith   PetscFunctionReturn(0);
1268ba4ca20aSSatish Balay }
1269d9b7c43dSSatish Balay 
1270fb2e594dSBarry Smith EXTERN_C_BEGIN
12714a2ae208SSatish Balay #undef __FUNCT__
12724a2ae208SSatish Balay #define __FUNCT__ "MatSeqBAIJSetColumnIndices_SeqBAIJ"
127327a8da17SBarry Smith int MatSeqBAIJSetColumnIndices_SeqBAIJ(Mat mat,int *indices)
127427a8da17SBarry Smith {
127527a8da17SBarry Smith   Mat_SeqBAIJ *baij = (Mat_SeqBAIJ *)mat->data;
127627a8da17SBarry Smith   int         i,nz,n;
127727a8da17SBarry Smith 
127827a8da17SBarry Smith   PetscFunctionBegin;
127927a8da17SBarry Smith   nz = baij->maxnz;
1280273d9f13SBarry Smith   n  = mat->n;
128127a8da17SBarry Smith   for (i=0; i<nz; i++) {
128227a8da17SBarry Smith     baij->j[i] = indices[i];
128327a8da17SBarry Smith   }
128427a8da17SBarry Smith   baij->nz = nz;
128527a8da17SBarry Smith   for (i=0; i<n; i++) {
128627a8da17SBarry Smith     baij->ilen[i] = baij->imax[i];
128727a8da17SBarry Smith   }
128827a8da17SBarry Smith 
128927a8da17SBarry Smith   PetscFunctionReturn(0);
129027a8da17SBarry Smith }
1291fb2e594dSBarry Smith EXTERN_C_END
129227a8da17SBarry Smith 
12934a2ae208SSatish Balay #undef __FUNCT__
12944a2ae208SSatish Balay #define __FUNCT__ "MatSeqBAIJSetColumnIndices"
129527a8da17SBarry Smith /*@
129627a8da17SBarry Smith     MatSeqBAIJSetColumnIndices - Set the column indices for all the rows
129727a8da17SBarry Smith        in the matrix.
129827a8da17SBarry Smith 
129927a8da17SBarry Smith   Input Parameters:
130027a8da17SBarry Smith +  mat - the SeqBAIJ matrix
130127a8da17SBarry Smith -  indices - the column indices
130227a8da17SBarry Smith 
130315091d37SBarry Smith   Level: advanced
130415091d37SBarry Smith 
130527a8da17SBarry Smith   Notes:
130627a8da17SBarry Smith     This can be called if you have precomputed the nonzero structure of the
130727a8da17SBarry Smith   matrix and want to provide it to the matrix object to improve the performance
130827a8da17SBarry Smith   of the MatSetValues() operation.
130927a8da17SBarry Smith 
131027a8da17SBarry Smith     You MUST have set the correct numbers of nonzeros per row in the call to
131127a8da17SBarry Smith   MatCreateSeqBAIJ().
131227a8da17SBarry Smith 
131327a8da17SBarry Smith     MUST be called before any calls to MatSetValues();
131427a8da17SBarry Smith 
131527a8da17SBarry Smith @*/
131627a8da17SBarry Smith int MatSeqBAIJSetColumnIndices(Mat mat,int *indices)
131727a8da17SBarry Smith {
131827a8da17SBarry Smith   int ierr,(*f)(Mat,int *);
131927a8da17SBarry Smith 
132027a8da17SBarry Smith   PetscFunctionBegin;
132127a8da17SBarry Smith   PetscValidHeaderSpecific(mat,MAT_COOKIE);
1322b9617806SBarry Smith   ierr = PetscObjectQueryFunction((PetscObject)mat,"MatSeqBAIJSetColumnIndices_C",(void (**)())&f);CHKERRQ(ierr);
132327a8da17SBarry Smith   if (f) {
132427a8da17SBarry Smith     ierr = (*f)(mat,indices);CHKERRQ(ierr);
132527a8da17SBarry Smith   } else {
132629bbc08cSBarry Smith     SETERRQ(1,"Wrong type of matrix to set column indices");
132727a8da17SBarry Smith   }
132827a8da17SBarry Smith   PetscFunctionReturn(0);
132927a8da17SBarry Smith }
133027a8da17SBarry Smith 
13314a2ae208SSatish Balay #undef __FUNCT__
13324a2ae208SSatish Balay #define __FUNCT__ "MatGetRowMax_SeqBAIJ"
1333273d9f13SBarry Smith int MatGetRowMax_SeqBAIJ(Mat A,Vec v)
1334273d9f13SBarry Smith {
1335273d9f13SBarry Smith   Mat_SeqBAIJ  *a = (Mat_SeqBAIJ*)A->data;
1336273d9f13SBarry Smith   int          ierr,i,j,n,row,bs,*ai,*aj,mbs;
1337273d9f13SBarry Smith   PetscReal    atmp;
1338273d9f13SBarry Smith   Scalar       *x,zero = 0.0;
1339273d9f13SBarry Smith   MatScalar    *aa;
1340273d9f13SBarry Smith   int          ncols,brow,krow,kcol;
1341273d9f13SBarry Smith 
1342273d9f13SBarry Smith   PetscFunctionBegin;
1343273d9f13SBarry Smith   if (A->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1344273d9f13SBarry Smith   bs   = a->bs;
1345273d9f13SBarry Smith   aa   = a->a;
1346273d9f13SBarry Smith   ai   = a->i;
1347273d9f13SBarry Smith   aj   = a->j;
1348273d9f13SBarry Smith   mbs = a->mbs;
1349273d9f13SBarry Smith 
1350273d9f13SBarry Smith   ierr = VecSet(&zero,v);CHKERRQ(ierr);
1351273d9f13SBarry Smith   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
1352273d9f13SBarry Smith   ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr);
1353273d9f13SBarry Smith   if (n != A->m) SETERRQ(PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector");
1354273d9f13SBarry Smith   for (i=0; i<mbs; i++) {
1355273d9f13SBarry Smith     ncols = ai[1] - ai[0]; ai++;
1356273d9f13SBarry Smith     brow  = bs*i;
1357273d9f13SBarry Smith     for (j=0; j<ncols; j++){
1358273d9f13SBarry Smith       /* bcol = bs*(*aj); */
1359273d9f13SBarry Smith       for (kcol=0; kcol<bs; kcol++){
1360273d9f13SBarry Smith         for (krow=0; krow<bs; krow++){
1361273d9f13SBarry Smith           atmp = PetscAbsScalar(*aa); aa++;
1362273d9f13SBarry Smith           row = brow + krow;    /* row index */
1363273d9f13SBarry Smith           /* printf("val[%d,%d]: %g\n",row,bcol+kcol,atmp); */
1364273d9f13SBarry Smith           if (PetscAbsScalar(x[row]) < atmp) x[row] = atmp;
1365273d9f13SBarry Smith         }
1366273d9f13SBarry Smith       }
1367273d9f13SBarry Smith       aj++;
1368273d9f13SBarry Smith     }
1369273d9f13SBarry Smith   }
1370273d9f13SBarry Smith   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
1371273d9f13SBarry Smith   PetscFunctionReturn(0);
1372273d9f13SBarry Smith }
1373273d9f13SBarry Smith 
13744a2ae208SSatish Balay #undef __FUNCT__
13754a2ae208SSatish Balay #define __FUNCT__ "MatSetUpPreallocation_SeqBAIJ"
1376273d9f13SBarry Smith int MatSetUpPreallocation_SeqBAIJ(Mat A)
1377273d9f13SBarry Smith {
1378273d9f13SBarry Smith   int        ierr;
1379273d9f13SBarry Smith 
1380273d9f13SBarry Smith   PetscFunctionBegin;
1381273d9f13SBarry Smith   ierr =  MatSeqBAIJSetPreallocation(A,1,PETSC_DEFAULT,0);CHKERRQ(ierr);
1382273d9f13SBarry Smith   PetscFunctionReturn(0);
1383273d9f13SBarry Smith }
1384273d9f13SBarry Smith 
13854a2ae208SSatish Balay #undef __FUNCT__
13864a2ae208SSatish Balay #define __FUNCT__ "MatGetArray_SeqBAIJ"
1387f2a5309cSSatish Balay int MatGetArray_SeqBAIJ(Mat A,Scalar **array)
1388f2a5309cSSatish Balay {
1389f2a5309cSSatish Balay   Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)A->data;
1390f2a5309cSSatish Balay   PetscFunctionBegin;
1391f2a5309cSSatish Balay   *array = a->a;
1392f2a5309cSSatish Balay   PetscFunctionReturn(0);
1393f2a5309cSSatish Balay }
1394f2a5309cSSatish Balay 
13954a2ae208SSatish Balay #undef __FUNCT__
13964a2ae208SSatish Balay #define __FUNCT__ "MatRestoreArray_SeqBAIJ"
1397f2a5309cSSatish Balay int MatRestoreArray_SeqBAIJ(Mat A,Scalar **array)
1398f2a5309cSSatish Balay {
1399f2a5309cSSatish Balay   PetscFunctionBegin;
1400f2a5309cSSatish Balay   PetscFunctionReturn(0);
1401f2a5309cSSatish Balay }
1402f2a5309cSSatish Balay 
14032593348eSBarry Smith /* -------------------------------------------------------------------*/
1404cc2dc46cSBarry Smith static struct _MatOps MatOps_Values = {MatSetValues_SeqBAIJ,
1405cc2dc46cSBarry Smith        MatGetRow_SeqBAIJ,
1406cc2dc46cSBarry Smith        MatRestoreRow_SeqBAIJ,
1407cc2dc46cSBarry Smith        MatMult_SeqBAIJ_N,
1408cc2dc46cSBarry Smith        MatMultAdd_SeqBAIJ_N,
14097c922b88SBarry Smith        MatMultTranspose_SeqBAIJ,
14107c922b88SBarry Smith        MatMultTransposeAdd_SeqBAIJ,
1411cc2dc46cSBarry Smith        MatSolve_SeqBAIJ_N,
1412cc2dc46cSBarry Smith        0,
1413cc2dc46cSBarry Smith        0,
1414cc2dc46cSBarry Smith        0,
1415cc2dc46cSBarry Smith        MatLUFactor_SeqBAIJ,
1416cc2dc46cSBarry Smith        0,
1417b6490206SBarry Smith        0,
1418f2501298SSatish Balay        MatTranspose_SeqBAIJ,
1419cc2dc46cSBarry Smith        MatGetInfo_SeqBAIJ,
1420cc2dc46cSBarry Smith        MatEqual_SeqBAIJ,
1421cc2dc46cSBarry Smith        MatGetDiagonal_SeqBAIJ,
1422cc2dc46cSBarry Smith        MatDiagonalScale_SeqBAIJ,
1423cc2dc46cSBarry Smith        MatNorm_SeqBAIJ,
1424b6490206SBarry Smith        0,
1425cc2dc46cSBarry Smith        MatAssemblyEnd_SeqBAIJ,
1426cc2dc46cSBarry Smith        0,
1427cc2dc46cSBarry Smith        MatSetOption_SeqBAIJ,
1428cc2dc46cSBarry Smith        MatZeroEntries_SeqBAIJ,
1429cc2dc46cSBarry Smith        MatZeroRows_SeqBAIJ,
1430cc2dc46cSBarry Smith        MatLUFactorSymbolic_SeqBAIJ,
1431cc2dc46cSBarry Smith        MatLUFactorNumeric_SeqBAIJ_N,
1432cc2dc46cSBarry Smith        0,
1433cc2dc46cSBarry Smith        0,
1434273d9f13SBarry Smith        MatSetUpPreallocation_SeqBAIJ,
1435273d9f13SBarry Smith        0,
1436cc2dc46cSBarry Smith        MatGetOwnershipRange_SeqBAIJ,
1437cc2dc46cSBarry Smith        MatILUFactorSymbolic_SeqBAIJ,
1438cc2dc46cSBarry Smith        0,
1439f2a5309cSSatish Balay        MatGetArray_SeqBAIJ,
1440f2a5309cSSatish Balay        MatRestoreArray_SeqBAIJ,
14412e8a6d31SBarry Smith        MatDuplicate_SeqBAIJ,
1442cc2dc46cSBarry Smith        0,
1443cc2dc46cSBarry Smith        0,
1444cc2dc46cSBarry Smith        MatILUFactor_SeqBAIJ,
1445cc2dc46cSBarry Smith        0,
1446cc2dc46cSBarry Smith        0,
1447cc2dc46cSBarry Smith        MatGetSubMatrices_SeqBAIJ,
1448cc2dc46cSBarry Smith        MatIncreaseOverlap_SeqBAIJ,
1449cc2dc46cSBarry Smith        MatGetValues_SeqBAIJ,
1450cc2dc46cSBarry Smith        0,
1451cc2dc46cSBarry Smith        MatPrintHelp_SeqBAIJ,
1452cc2dc46cSBarry Smith        MatScale_SeqBAIJ,
1453cc2dc46cSBarry Smith        0,
1454cc2dc46cSBarry Smith        0,
1455cc2dc46cSBarry Smith        0,
1456cc2dc46cSBarry Smith        MatGetBlockSize_SeqBAIJ,
14573b2fbd54SBarry Smith        MatGetRowIJ_SeqBAIJ,
145892c4ed94SBarry Smith        MatRestoreRowIJ_SeqBAIJ,
1459cc2dc46cSBarry Smith        0,
1460cc2dc46cSBarry Smith        0,
1461cc2dc46cSBarry Smith        0,
1462cc2dc46cSBarry Smith        0,
1463cc2dc46cSBarry Smith        0,
1464cc2dc46cSBarry Smith        0,
1465d3825aa8SBarry Smith        MatSetValuesBlocked_SeqBAIJ,
1466cc2dc46cSBarry Smith        MatGetSubMatrix_SeqBAIJ,
1467b9b97703SBarry Smith        MatDestroy_SeqBAIJ,
1468b9b97703SBarry Smith        MatView_SeqBAIJ,
1469273d9f13SBarry Smith        MatGetMaps_Petsc,
1470273d9f13SBarry Smith        0,
1471273d9f13SBarry Smith        0,
1472273d9f13SBarry Smith        0,
1473273d9f13SBarry Smith        0,
1474273d9f13SBarry Smith        0,
1475273d9f13SBarry Smith        0,
1476273d9f13SBarry Smith        MatGetRowMax_SeqBAIJ,
1477273d9f13SBarry Smith        MatConvert_Basic};
14782593348eSBarry Smith 
14793e90b805SBarry Smith EXTERN_C_BEGIN
14804a2ae208SSatish Balay #undef __FUNCT__
14814a2ae208SSatish Balay #define __FUNCT__ "MatStoreValues_SeqBAIJ"
14823e90b805SBarry Smith int MatStoreValues_SeqBAIJ(Mat mat)
14833e90b805SBarry Smith {
14843e90b805SBarry Smith   Mat_SeqBAIJ *aij = (Mat_SeqBAIJ *)mat->data;
1485273d9f13SBarry Smith   int         nz = aij->i[mat->m]*aij->bs*aij->bs2;
1486d132466eSBarry Smith   int         ierr;
14873e90b805SBarry Smith 
14883e90b805SBarry Smith   PetscFunctionBegin;
14893e90b805SBarry Smith   if (aij->nonew != 1) {
149029bbc08cSBarry Smith     SETERRQ(1,"Must call MatSetOption(A,MAT_NO_NEW_NONZERO_LOCATIONS);first");
14913e90b805SBarry Smith   }
14923e90b805SBarry Smith 
14933e90b805SBarry Smith   /* allocate space for values if not already there */
14943e90b805SBarry Smith   if (!aij->saved_values) {
1495f2a5309cSSatish Balay     ierr = PetscMalloc((nz+1)*sizeof(Scalar),&aij->saved_values);CHKERRQ(ierr);
14963e90b805SBarry Smith   }
14973e90b805SBarry Smith 
14983e90b805SBarry Smith   /* copy values over */
1499d132466eSBarry Smith   ierr = PetscMemcpy(aij->saved_values,aij->a,nz*sizeof(Scalar));CHKERRQ(ierr);
15003e90b805SBarry Smith   PetscFunctionReturn(0);
15013e90b805SBarry Smith }
15023e90b805SBarry Smith EXTERN_C_END
15033e90b805SBarry Smith 
15043e90b805SBarry Smith EXTERN_C_BEGIN
15054a2ae208SSatish Balay #undef __FUNCT__
15064a2ae208SSatish Balay #define __FUNCT__ "MatRetrieveValues_SeqBAIJ"
150732e87ba3SBarry Smith int MatRetrieveValues_SeqBAIJ(Mat mat)
15083e90b805SBarry Smith {
15093e90b805SBarry Smith   Mat_SeqBAIJ *aij = (Mat_SeqBAIJ *)mat->data;
1510273d9f13SBarry Smith   int         nz = aij->i[mat->m]*aij->bs*aij->bs2,ierr;
15113e90b805SBarry Smith 
15123e90b805SBarry Smith   PetscFunctionBegin;
15133e90b805SBarry Smith   if (aij->nonew != 1) {
151429bbc08cSBarry Smith     SETERRQ(1,"Must call MatSetOption(A,MAT_NO_NEW_NONZERO_LOCATIONS);first");
15153e90b805SBarry Smith   }
15163e90b805SBarry Smith   if (!aij->saved_values) {
151729bbc08cSBarry Smith     SETERRQ(1,"Must call MatStoreValues(A);first");
15183e90b805SBarry Smith   }
15193e90b805SBarry Smith 
15203e90b805SBarry Smith   /* copy values over */
1521549d3d68SSatish Balay   ierr = PetscMemcpy(aij->a,aij->saved_values,nz*sizeof(Scalar));CHKERRQ(ierr);
15223e90b805SBarry Smith   PetscFunctionReturn(0);
15233e90b805SBarry Smith }
15243e90b805SBarry Smith EXTERN_C_END
15253e90b805SBarry Smith 
1526273d9f13SBarry Smith EXTERN_C_BEGIN
1527273d9f13SBarry Smith extern int MatConvert_SeqBAIJ_SeqAIJ(Mat,MatType,Mat*);
1528273d9f13SBarry Smith EXTERN_C_END
1529273d9f13SBarry Smith 
1530273d9f13SBarry Smith EXTERN_C_BEGIN
15314a2ae208SSatish Balay #undef __FUNCT__
15324a2ae208SSatish Balay #define __FUNCT__ "MatCreate_SeqBAIJ"
1533273d9f13SBarry Smith int MatCreate_SeqBAIJ(Mat B)
15342593348eSBarry Smith {
1535273d9f13SBarry Smith   int         ierr,size;
1536b6490206SBarry Smith   Mat_SeqBAIJ *b;
15373b2fbd54SBarry Smith 
15383a40ed3dSBarry Smith   PetscFunctionBegin;
1539273d9f13SBarry Smith   ierr = MPI_Comm_size(B->comm,&size);CHKERRQ(ierr);
154029bbc08cSBarry Smith   if (size > 1) SETERRQ(PETSC_ERR_ARG_WRONG,"Comm must be of size 1");
1541b6490206SBarry Smith 
1542273d9f13SBarry Smith   B->m = B->M = PetscMax(B->m,B->M);
1543273d9f13SBarry Smith   B->n = B->N = PetscMax(B->n,B->N);
1544b0a32e0cSBarry Smith   ierr    = PetscNew(Mat_SeqBAIJ,&b);CHKERRQ(ierr);
1545b0a32e0cSBarry Smith   B->data = (void*)b;
1546549d3d68SSatish Balay   ierr    = PetscMemzero(b,sizeof(Mat_SeqBAIJ));CHKERRQ(ierr);
1547549d3d68SSatish Balay   ierr    = PetscMemcpy(B->ops,&MatOps_Values,sizeof(struct _MatOps));CHKERRQ(ierr);
15482593348eSBarry Smith   B->factor           = 0;
15492593348eSBarry Smith   B->lupivotthreshold = 1.0;
155090f02eecSBarry Smith   B->mapping          = 0;
15512593348eSBarry Smith   b->row              = 0;
15522593348eSBarry Smith   b->col              = 0;
1553e51c0b9cSSatish Balay   b->icol             = 0;
15542593348eSBarry Smith   b->reallocs         = 0;
15553e90b805SBarry Smith   b->saved_values     = 0;
1556cfce73b9SSatish Balay #if defined(PETSC_USE_MAT_SINGLE)
1557563b5814SBarry Smith   b->setvalueslen     = 0;
1558563b5814SBarry Smith   b->setvaluescopy    = PETSC_NULL;
1559563b5814SBarry Smith #endif
15602593348eSBarry Smith 
1561273d9f13SBarry Smith   ierr = MapCreateMPI(B->comm,B->m,B->m,&B->rmap);CHKERRQ(ierr);
1562273d9f13SBarry Smith   ierr = MapCreateMPI(B->comm,B->n,B->n,&B->cmap);CHKERRQ(ierr);
1563a5ae1ecdSBarry Smith 
1564c4992f7dSBarry Smith   b->sorted           = PETSC_FALSE;
1565c4992f7dSBarry Smith   b->roworiented      = PETSC_TRUE;
15662593348eSBarry Smith   b->nonew            = 0;
15672593348eSBarry Smith   b->diag             = 0;
15682593348eSBarry Smith   b->solve_work       = 0;
1569de6a44a3SBarry Smith   b->mult_work        = 0;
15702593348eSBarry Smith   b->spptr            = 0;
15710e6d2581SBarry Smith   B->info.nz_unneeded = (PetscReal)b->maxnz;
1572883fce79SBarry Smith   b->keepzeroedrows   = PETSC_FALSE;
15734e220ebcSLois Curfman McInnes 
1574f1af5d2fSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatStoreValues_C",
15753e90b805SBarry Smith                                      "MatStoreValues_SeqBAIJ",
1576bc4b532fSSatish Balay                                       MatStoreValues_SeqBAIJ);CHKERRQ(ierr);
1577f1af5d2fSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatRetrieveValues_C",
15783e90b805SBarry Smith                                      "MatRetrieveValues_SeqBAIJ",
1579bc4b532fSSatish Balay                                       MatRetrieveValues_SeqBAIJ);CHKERRQ(ierr);
1580f1af5d2fSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatSeqBAIJSetColumnIndices_C",
158127a8da17SBarry Smith                                      "MatSeqBAIJSetColumnIndices_SeqBAIJ",
1582bc4b532fSSatish Balay                                       MatSeqBAIJSetColumnIndices_SeqBAIJ);CHKERRQ(ierr);
1583273d9f13SBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatConvert_SeqBAIJ_SeqAIJ_C",
1584273d9f13SBarry Smith                                      "MatConvert_SeqBAIJ_SeqAIJ",
1585273d9f13SBarry Smith                                       MatConvert_SeqBAIJ_SeqAIJ);CHKERRQ(ierr);
15863a40ed3dSBarry Smith   PetscFunctionReturn(0);
15872593348eSBarry Smith }
1588273d9f13SBarry Smith EXTERN_C_END
15892593348eSBarry Smith 
15904a2ae208SSatish Balay #undef __FUNCT__
15914a2ae208SSatish Balay #define __FUNCT__ "MatDuplicate_SeqBAIJ"
15922e8a6d31SBarry Smith int MatDuplicate_SeqBAIJ(Mat A,MatDuplicateOption cpvalues,Mat *B)
15932593348eSBarry Smith {
15942593348eSBarry Smith   Mat         C;
1595b6490206SBarry Smith   Mat_SeqBAIJ *c,*a = (Mat_SeqBAIJ*)A->data;
159627a8da17SBarry Smith   int         i,len,mbs = a->mbs,nz = a->nz,bs2 =a->bs2,ierr;
1597de6a44a3SBarry Smith 
15983a40ed3dSBarry Smith   PetscFunctionBegin;
159929bbc08cSBarry Smith   if (a->i[mbs] != nz) SETERRQ(PETSC_ERR_PLIB,"Corrupt matrix");
16002593348eSBarry Smith 
16012593348eSBarry Smith   *B = 0;
1602273d9f13SBarry Smith   ierr = MatCreate(A->comm,A->m,A->n,A->m,A->n,&C);CHKERRQ(ierr);
1603273d9f13SBarry Smith   ierr = MatSetType(C,MATSEQBAIJ);CHKERRQ(ierr);
1604273d9f13SBarry Smith   c    = (Mat_SeqBAIJ*)C->data;
160544cd7ae7SLois Curfman McInnes 
1606b6490206SBarry Smith   c->bs         = a->bs;
16079df24120SSatish Balay   c->bs2        = a->bs2;
1608b6490206SBarry Smith   c->mbs        = a->mbs;
1609b6490206SBarry Smith   c->nbs        = a->nbs;
161035d8aa7fSBarry Smith   ierr = PetscMemcpy(C->ops,A->ops,sizeof(struct _MatOps));CHKERRQ(ierr);
16112593348eSBarry Smith 
1612b0a32e0cSBarry Smith   ierr = PetscMalloc((mbs+1)*sizeof(int),&c->imax);CHKERRQ(ierr);
1613b0a32e0cSBarry Smith   ierr = PetscMalloc((mbs+1)*sizeof(int),&c->ilen);CHKERRQ(ierr);
1614b6490206SBarry Smith   for (i=0; i<mbs; i++) {
16152593348eSBarry Smith     c->imax[i] = a->imax[i];
16162593348eSBarry Smith     c->ilen[i] = a->ilen[i];
16172593348eSBarry Smith   }
16182593348eSBarry Smith 
16192593348eSBarry Smith   /* allocate the matrix space */
1620c4992f7dSBarry Smith   c->singlemalloc = PETSC_TRUE;
16213f1db9ecSBarry Smith   len  = (mbs+1)*sizeof(int) + nz*(bs2*sizeof(MatScalar) + sizeof(int));
1622b0a32e0cSBarry Smith   ierr = PetscMalloc(len,&c->a);CHKERRQ(ierr);
16237e67e3f9SSatish Balay   c->j = (int*)(c->a + nz*bs2);
1624de6a44a3SBarry Smith   c->i = c->j + nz;
1625549d3d68SSatish Balay   ierr = PetscMemcpy(c->i,a->i,(mbs+1)*sizeof(int));CHKERRQ(ierr);
1626b6490206SBarry Smith   if (mbs > 0) {
1627549d3d68SSatish Balay     ierr = PetscMemcpy(c->j,a->j,nz*sizeof(int));CHKERRQ(ierr);
16282e8a6d31SBarry Smith     if (cpvalues == MAT_COPY_VALUES) {
1629549d3d68SSatish Balay       ierr = PetscMemcpy(c->a,a->a,bs2*nz*sizeof(MatScalar));CHKERRQ(ierr);
16302e8a6d31SBarry Smith     } else {
1631549d3d68SSatish Balay       ierr = PetscMemzero(c->a,bs2*nz*sizeof(MatScalar));CHKERRQ(ierr);
16322593348eSBarry Smith     }
16332593348eSBarry Smith   }
16342593348eSBarry Smith 
1635b0a32e0cSBarry Smith   PetscLogObjectMemory(C,len+2*(mbs+1)*sizeof(int)+sizeof(struct _p_Mat)+sizeof(Mat_SeqBAIJ));
16362593348eSBarry Smith   c->sorted      = a->sorted;
16372593348eSBarry Smith   c->roworiented = a->roworiented;
16382593348eSBarry Smith   c->nonew       = a->nonew;
16392593348eSBarry Smith 
16402593348eSBarry Smith   if (a->diag) {
1641b0a32e0cSBarry Smith     ierr = PetscMalloc((mbs+1)*sizeof(int),&c->diag);CHKERRQ(ierr);
1642b0a32e0cSBarry Smith     PetscLogObjectMemory(C,(mbs+1)*sizeof(int));
1643b6490206SBarry Smith     for (i=0; i<mbs; i++) {
16442593348eSBarry Smith       c->diag[i] = a->diag[i];
16452593348eSBarry Smith     }
164698305bb5SBarry Smith   } else c->diag        = 0;
16472593348eSBarry Smith   c->nz                 = a->nz;
16482593348eSBarry Smith   c->maxnz              = a->maxnz;
16492593348eSBarry Smith   c->solve_work         = 0;
16502593348eSBarry Smith   c->spptr              = 0;      /* Dangerous -I'm throwing away a->spptr */
16517fc0212eSBarry Smith   c->mult_work          = 0;
1652273d9f13SBarry Smith   C->preallocated       = PETSC_TRUE;
1653273d9f13SBarry Smith   C->assembled          = PETSC_TRUE;
16542593348eSBarry Smith   *B = C;
1655b0a32e0cSBarry Smith   ierr = PetscFListDuplicate(A->qlist,&C->qlist);CHKERRQ(ierr);
16563a40ed3dSBarry Smith   PetscFunctionReturn(0);
16572593348eSBarry Smith }
16582593348eSBarry Smith 
1659273d9f13SBarry Smith EXTERN_C_BEGIN
16604a2ae208SSatish Balay #undef __FUNCT__
16614a2ae208SSatish Balay #define __FUNCT__ "MatLoad_SeqBAIJ"
1662b0a32e0cSBarry Smith int MatLoad_SeqBAIJ(PetscViewer viewer,MatType type,Mat *A)
16632593348eSBarry Smith {
1664b6490206SBarry Smith   Mat_SeqBAIJ  *a;
16652593348eSBarry Smith   Mat          B;
1666f1af5d2fSBarry Smith   int          i,nz,ierr,fd,header[4],size,*rowlengths=0,M,N,bs=1;
1667b6490206SBarry Smith   int          *mask,mbs,*jj,j,rowcount,nzcount,k,*browlengths,maskcount;
166835aab85fSBarry Smith   int          kmax,jcount,block,idx,point,nzcountb,extra_rows;
1669a7c10996SSatish Balay   int          *masked,nmask,tmp,bs2,ishift;
1670b6490206SBarry Smith   Scalar       *aa;
167119bcc07fSBarry Smith   MPI_Comm     comm = ((PetscObject)viewer)->comm;
16722593348eSBarry Smith 
16733a40ed3dSBarry Smith   PetscFunctionBegin;
1674b0a32e0cSBarry Smith   ierr = PetscOptionsGetInt(PETSC_NULL,"-matload_block_size",&bs,PETSC_NULL);CHKERRQ(ierr);
1675de6a44a3SBarry Smith   bs2  = bs*bs;
1676b6490206SBarry Smith 
1677d132466eSBarry Smith   ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr);
167829bbc08cSBarry Smith   if (size > 1) SETERRQ(PETSC_ERR_ARG_WRONG,"view must have one processor");
1679b0a32e0cSBarry Smith   ierr = PetscViewerBinaryGetDescriptor(viewer,&fd);CHKERRQ(ierr);
16800752156aSBarry Smith   ierr = PetscBinaryRead(fd,header,4,PETSC_INT);CHKERRQ(ierr);
168129bbc08cSBarry Smith   if (header[0] != MAT_COOKIE) SETERRQ(PETSC_ERR_FILE_UNEXPECTED,"not Mat object");
16822593348eSBarry Smith   M = header[1]; N = header[2]; nz = header[3];
16832593348eSBarry Smith 
1684d64ed03dSBarry Smith   if (header[3] < 0) {
168529bbc08cSBarry Smith     SETERRQ(PETSC_ERR_FILE_UNEXPECTED,"Matrix stored in special format, cannot load as SeqBAIJ");
1686d64ed03dSBarry Smith   }
1687d64ed03dSBarry Smith 
168829bbc08cSBarry Smith   if (M != N) SETERRQ(PETSC_ERR_SUP,"Can only do square matrices");
168935aab85fSBarry Smith 
169035aab85fSBarry Smith   /*
169135aab85fSBarry Smith      This code adds extra rows to make sure the number of rows is
169235aab85fSBarry Smith     divisible by the blocksize
169335aab85fSBarry Smith   */
1694b6490206SBarry Smith   mbs        = M/bs;
169535aab85fSBarry Smith   extra_rows = bs - M + bs*(mbs);
169635aab85fSBarry Smith   if (extra_rows == bs) extra_rows = 0;
169735aab85fSBarry Smith   else                  mbs++;
169835aab85fSBarry Smith   if (extra_rows) {
1699b0a32e0cSBarry Smith     PetscLogInfo(0,"MatLoad_SeqBAIJ:Padding loaded matrix to match blocksize\n");
170035aab85fSBarry Smith   }
1701b6490206SBarry Smith 
17022593348eSBarry Smith   /* read in row lengths */
1703b0a32e0cSBarry Smith   ierr = PetscMalloc((M+extra_rows)*sizeof(int),&rowlengths);CHKERRQ(ierr);
17040752156aSBarry Smith   ierr = PetscBinaryRead(fd,rowlengths,M,PETSC_INT);CHKERRQ(ierr);
170535aab85fSBarry Smith   for (i=0; i<extra_rows; i++) rowlengths[M+i] = 1;
17062593348eSBarry Smith 
1707b6490206SBarry Smith   /* read in column indices */
1708b0a32e0cSBarry Smith   ierr = PetscMalloc((nz+extra_rows)*sizeof(int),&jj);CHKERRQ(ierr);
17090752156aSBarry Smith   ierr = PetscBinaryRead(fd,jj,nz,PETSC_INT);CHKERRQ(ierr);
171035aab85fSBarry Smith   for (i=0; i<extra_rows; i++) jj[nz+i] = M+i;
1711b6490206SBarry Smith 
1712b6490206SBarry Smith   /* loop over row lengths determining block row lengths */
1713b0a32e0cSBarry Smith   ierr     = PetscMalloc(mbs*sizeof(int),&browlengths);CHKERRQ(ierr);
1714549d3d68SSatish Balay   ierr     = PetscMemzero(browlengths,mbs*sizeof(int));CHKERRQ(ierr);
1715b0a32e0cSBarry Smith   ierr     = PetscMalloc(2*mbs*sizeof(int),&mask);CHKERRQ(ierr);
1716549d3d68SSatish Balay   ierr     = PetscMemzero(mask,mbs*sizeof(int));CHKERRQ(ierr);
171735aab85fSBarry Smith   masked   = mask + mbs;
1718b6490206SBarry Smith   rowcount = 0; nzcount = 0;
1719b6490206SBarry Smith   for (i=0; i<mbs; i++) {
172035aab85fSBarry Smith     nmask = 0;
1721b6490206SBarry Smith     for (j=0; j<bs; j++) {
1722b6490206SBarry Smith       kmax = rowlengths[rowcount];
1723b6490206SBarry Smith       for (k=0; k<kmax; k++) {
172435aab85fSBarry Smith         tmp = jj[nzcount++]/bs;
172535aab85fSBarry Smith         if (!mask[tmp]) {masked[nmask++] = tmp; mask[tmp] = 1;}
1726b6490206SBarry Smith       }
1727b6490206SBarry Smith       rowcount++;
1728b6490206SBarry Smith     }
172935aab85fSBarry Smith     browlengths[i] += nmask;
173035aab85fSBarry Smith     /* zero out the mask elements we set */
173135aab85fSBarry Smith     for (j=0; j<nmask; j++) mask[masked[j]] = 0;
1732b6490206SBarry Smith   }
1733b6490206SBarry Smith 
17342593348eSBarry Smith   /* create our matrix */
17353eee16b0SBarry Smith   ierr = MatCreateSeqBAIJ(comm,bs,M+extra_rows,N+extra_rows,0,browlengths,A);CHKERRQ(ierr);
17362593348eSBarry Smith   B = *A;
1737b6490206SBarry Smith   a = (Mat_SeqBAIJ*)B->data;
17382593348eSBarry Smith 
17392593348eSBarry Smith   /* set matrix "i" values */
1740de6a44a3SBarry Smith   a->i[0] = 0;
1741b6490206SBarry Smith   for (i=1; i<= mbs; i++) {
1742b6490206SBarry Smith     a->i[i]      = a->i[i-1] + browlengths[i-1];
1743b6490206SBarry Smith     a->ilen[i-1] = browlengths[i-1];
17442593348eSBarry Smith   }
1745b6490206SBarry Smith   a->nz         = 0;
1746b6490206SBarry Smith   for (i=0; i<mbs; i++) a->nz += browlengths[i];
17472593348eSBarry Smith 
1748b6490206SBarry Smith   /* read in nonzero values */
1749b0a32e0cSBarry Smith   ierr = PetscMalloc((nz+extra_rows)*sizeof(Scalar),&aa);CHKERRQ(ierr);
17500752156aSBarry Smith   ierr = PetscBinaryRead(fd,aa,nz,PETSC_SCALAR);CHKERRQ(ierr);
175135aab85fSBarry Smith   for (i=0; i<extra_rows; i++) aa[nz+i] = 1.0;
1752b6490206SBarry Smith 
1753b6490206SBarry Smith   /* set "a" and "j" values into matrix */
1754b6490206SBarry Smith   nzcount = 0; jcount = 0;
1755b6490206SBarry Smith   for (i=0; i<mbs; i++) {
1756b6490206SBarry Smith     nzcountb = nzcount;
175735aab85fSBarry Smith     nmask    = 0;
1758b6490206SBarry Smith     for (j=0; j<bs; j++) {
1759b6490206SBarry Smith       kmax = rowlengths[i*bs+j];
1760b6490206SBarry Smith       for (k=0; k<kmax; k++) {
176135aab85fSBarry Smith         tmp = jj[nzcount++]/bs;
176235aab85fSBarry Smith 	if (!mask[tmp]) { masked[nmask++] = tmp; mask[tmp] = 1;}
1763b6490206SBarry Smith       }
1764b6490206SBarry Smith     }
1765de6a44a3SBarry Smith     /* sort the masked values */
1766433994e6SBarry Smith     ierr = PetscSortInt(nmask,masked);CHKERRQ(ierr);
1767de6a44a3SBarry Smith 
1768b6490206SBarry Smith     /* set "j" values into matrix */
1769b6490206SBarry Smith     maskcount = 1;
177035aab85fSBarry Smith     for (j=0; j<nmask; j++) {
177135aab85fSBarry Smith       a->j[jcount++]  = masked[j];
1772de6a44a3SBarry Smith       mask[masked[j]] = maskcount++;
1773b6490206SBarry Smith     }
1774b6490206SBarry Smith     /* set "a" values into matrix */
1775de6a44a3SBarry Smith     ishift = bs2*a->i[i];
1776b6490206SBarry Smith     for (j=0; j<bs; j++) {
1777b6490206SBarry Smith       kmax = rowlengths[i*bs+j];
1778b6490206SBarry Smith       for (k=0; k<kmax; k++) {
1779de6a44a3SBarry Smith         tmp       = jj[nzcountb]/bs ;
1780de6a44a3SBarry Smith         block     = mask[tmp] - 1;
1781de6a44a3SBarry Smith         point     = jj[nzcountb] - bs*tmp;
1782de6a44a3SBarry Smith         idx       = ishift + bs2*block + j + bs*point;
1783375fe846SBarry Smith         a->a[idx] = (MatScalar)aa[nzcountb++];
1784b6490206SBarry Smith       }
1785b6490206SBarry Smith     }
178635aab85fSBarry Smith     /* zero out the mask elements we set */
178735aab85fSBarry Smith     for (j=0; j<nmask; j++) mask[masked[j]] = 0;
1788b6490206SBarry Smith   }
178929bbc08cSBarry Smith   if (jcount != a->nz) SETERRQ(PETSC_ERR_FILE_UNEXPECTED,"Bad binary matrix");
1790b6490206SBarry Smith 
1791606d414cSSatish Balay   ierr = PetscFree(rowlengths);CHKERRQ(ierr);
1792606d414cSSatish Balay   ierr = PetscFree(browlengths);CHKERRQ(ierr);
1793606d414cSSatish Balay   ierr = PetscFree(aa);CHKERRQ(ierr);
1794606d414cSSatish Balay   ierr = PetscFree(jj);CHKERRQ(ierr);
1795606d414cSSatish Balay   ierr = PetscFree(mask);CHKERRQ(ierr);
1796b6490206SBarry Smith 
1797b6490206SBarry Smith   B->assembled = PETSC_TRUE;
1798de6a44a3SBarry Smith 
17999c01be13SBarry Smith   ierr = MatView_Private(B);CHKERRQ(ierr);
18003a40ed3dSBarry Smith   PetscFunctionReturn(0);
18012593348eSBarry Smith }
1802273d9f13SBarry Smith EXTERN_C_END
18032593348eSBarry Smith 
18044a2ae208SSatish Balay #undef __FUNCT__
18054a2ae208SSatish Balay #define __FUNCT__ "MatCreateSeqBAIJ"
1806273d9f13SBarry Smith /*@C
1807273d9f13SBarry Smith    MatCreateSeqBAIJ - Creates a sparse matrix in block AIJ (block
1808273d9f13SBarry Smith    compressed row) format.  For good matrix assembly performance the
1809273d9f13SBarry Smith    user should preallocate the matrix storage by setting the parameter nz
1810273d9f13SBarry Smith    (or the array nnz).  By setting these parameters accurately, performance
1811273d9f13SBarry Smith    during matrix assembly can be increased by more than a factor of 50.
18122593348eSBarry Smith 
1813273d9f13SBarry Smith    Collective on MPI_Comm
1814273d9f13SBarry Smith 
1815273d9f13SBarry Smith    Input Parameters:
1816273d9f13SBarry Smith +  comm - MPI communicator, set to PETSC_COMM_SELF
1817273d9f13SBarry Smith .  bs - size of block
1818273d9f13SBarry Smith .  m - number of rows
1819273d9f13SBarry Smith .  n - number of columns
182035d8aa7fSBarry Smith .  nz - number of nonzero blocks  per block row (same for all rows)
182135d8aa7fSBarry Smith -  nnz - array containing the number of nonzero blocks in the various block rows
1822273d9f13SBarry Smith          (possibly different for each block row) or PETSC_NULL
1823273d9f13SBarry Smith 
1824273d9f13SBarry Smith    Output Parameter:
1825273d9f13SBarry Smith .  A - the matrix
1826273d9f13SBarry Smith 
1827273d9f13SBarry Smith    Options Database Keys:
1828273d9f13SBarry Smith .   -mat_no_unroll - uses code that does not unroll the loops in the
1829273d9f13SBarry Smith                      block calculations (much slower)
1830273d9f13SBarry Smith .    -mat_block_size - size of the blocks to use
1831273d9f13SBarry Smith 
1832273d9f13SBarry Smith    Level: intermediate
1833273d9f13SBarry Smith 
1834273d9f13SBarry Smith    Notes:
183535d8aa7fSBarry Smith    A nonzero block is any block that as 1 or more nonzeros in it
183635d8aa7fSBarry Smith 
1837273d9f13SBarry Smith    The block AIJ format is fully compatible with standard Fortran 77
1838273d9f13SBarry Smith    storage.  That is, the stored row and column indices can begin at
1839273d9f13SBarry Smith    either one (as in Fortran) or zero.  See the users' manual for details.
1840273d9f13SBarry Smith 
1841273d9f13SBarry Smith    Specify the preallocated storage with either nz or nnz (not both).
1842273d9f13SBarry Smith    Set nz=PETSC_DEFAULT and nnz=PETSC_NULL for PETSc to control dynamic memory
1843273d9f13SBarry Smith    allocation.  For additional details, see the users manual chapter on
1844273d9f13SBarry Smith    matrices.
1845273d9f13SBarry Smith 
1846273d9f13SBarry Smith .seealso: MatCreate(), MatCreateSeqAIJ(), MatSetValues(), MatCreateMPIBAIJ()
1847273d9f13SBarry Smith @*/
1848273d9f13SBarry Smith int MatCreateSeqBAIJ(MPI_Comm comm,int bs,int m,int n,int nz,int *nnz,Mat *A)
1849273d9f13SBarry Smith {
1850273d9f13SBarry Smith   int ierr;
1851273d9f13SBarry Smith 
1852273d9f13SBarry Smith   PetscFunctionBegin;
1853273d9f13SBarry Smith   ierr = MatCreate(comm,m,n,m,n,A);CHKERRQ(ierr);
1854273d9f13SBarry Smith   ierr = MatSetType(*A,MATSEQBAIJ);CHKERRQ(ierr);
1855273d9f13SBarry Smith   ierr = MatSeqBAIJSetPreallocation(*A,bs,nz,nnz);CHKERRQ(ierr);
1856273d9f13SBarry Smith   PetscFunctionReturn(0);
1857273d9f13SBarry Smith }
1858273d9f13SBarry Smith 
18594a2ae208SSatish Balay #undef __FUNCT__
18604a2ae208SSatish Balay #define __FUNCT__ "MatSeqBAIJSetPreallocation"
1861273d9f13SBarry Smith /*@C
1862273d9f13SBarry Smith    MatSeqBAIJSetPreallocation - Sets the block size and expected nonzeros
1863273d9f13SBarry Smith    per row in the matrix. For good matrix assembly performance the
1864273d9f13SBarry Smith    user should preallocate the matrix storage by setting the parameter nz
1865273d9f13SBarry Smith    (or the array nnz).  By setting these parameters accurately, performance
1866273d9f13SBarry Smith    during matrix assembly can be increased by more than a factor of 50.
1867273d9f13SBarry Smith 
1868273d9f13SBarry Smith    Collective on MPI_Comm
1869273d9f13SBarry Smith 
1870273d9f13SBarry Smith    Input Parameters:
1871273d9f13SBarry Smith +  A - the matrix
1872273d9f13SBarry Smith .  bs - size of block
1873273d9f13SBarry Smith .  nz - number of block nonzeros per block row (same for all rows)
1874273d9f13SBarry Smith -  nnz - array containing the number of block nonzeros in the various block rows
1875273d9f13SBarry Smith          (possibly different for each block row) or PETSC_NULL
1876273d9f13SBarry Smith 
1877273d9f13SBarry Smith    Options Database Keys:
1878273d9f13SBarry Smith .   -mat_no_unroll - uses code that does not unroll the loops in the
1879273d9f13SBarry Smith                      block calculations (much slower)
1880273d9f13SBarry Smith .    -mat_block_size - size of the blocks to use
1881273d9f13SBarry Smith 
1882273d9f13SBarry Smith    Level: intermediate
1883273d9f13SBarry Smith 
1884273d9f13SBarry Smith    Notes:
1885273d9f13SBarry Smith    The block AIJ format is fully compatible with standard Fortran 77
1886273d9f13SBarry Smith    storage.  That is, the stored row and column indices can begin at
1887273d9f13SBarry Smith    either one (as in Fortran) or zero.  See the users' manual for details.
1888273d9f13SBarry Smith 
1889273d9f13SBarry Smith    Specify the preallocated storage with either nz or nnz (not both).
1890273d9f13SBarry Smith    Set nz=PETSC_DEFAULT and nnz=PETSC_NULL for PETSc to control dynamic memory
1891273d9f13SBarry Smith    allocation.  For additional details, see the users manual chapter on
1892273d9f13SBarry Smith    matrices.
1893273d9f13SBarry Smith 
1894273d9f13SBarry Smith .seealso: MatCreate(), MatCreateSeqAIJ(), MatSetValues(), MatCreateMPIBAIJ()
1895273d9f13SBarry Smith @*/
1896273d9f13SBarry Smith int MatSeqBAIJSetPreallocation(Mat B,int bs,int nz,int *nnz)
1897273d9f13SBarry Smith {
1898273d9f13SBarry Smith   Mat_SeqBAIJ *b;
1899273d9f13SBarry Smith   int         i,len,ierr,mbs,nbs,bs2,newbs = bs;
1900273d9f13SBarry Smith   PetscTruth  flg;
1901273d9f13SBarry Smith 
1902273d9f13SBarry Smith   PetscFunctionBegin;
1903273d9f13SBarry Smith   ierr = PetscTypeCompare((PetscObject)B,MATSEQBAIJ,&flg);CHKERRQ(ierr);
1904273d9f13SBarry Smith   if (!flg) PetscFunctionReturn(0);
1905273d9f13SBarry Smith 
1906273d9f13SBarry Smith   B->preallocated = PETSC_TRUE;
1907b0a32e0cSBarry Smith   ierr = PetscOptionsGetInt(B->prefix,"-mat_block_size",&newbs,PETSC_NULL);CHKERRQ(ierr);
1908273d9f13SBarry Smith   if (nnz && newbs != bs) {
1909273d9f13SBarry Smith     SETERRQ(1,"Cannot change blocksize from command line if setting nnz");
1910273d9f13SBarry Smith   }
1911273d9f13SBarry Smith   bs   = newbs;
1912273d9f13SBarry Smith 
1913273d9f13SBarry Smith   mbs  = B->m/bs;
1914273d9f13SBarry Smith   nbs  = B->n/bs;
1915273d9f13SBarry Smith   bs2  = bs*bs;
1916273d9f13SBarry Smith 
1917273d9f13SBarry Smith   if (mbs*bs!=B->m || nbs*bs!=B->n) {
191835d8aa7fSBarry Smith     SETERRQ3(PETSC_ERR_ARG_SIZ,"Number rows %d, cols %d must be divisible by blocksize %d",B->m,B->n,bs);
1919273d9f13SBarry Smith   }
1920273d9f13SBarry Smith 
1921435da068SBarry Smith   if (nz == PETSC_DEFAULT || nz == PETSC_DECIDE) nz = 5;
1922435da068SBarry Smith   if (nz < 0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"nz cannot be less than 0: value %d",nz);
1923273d9f13SBarry Smith   if (nnz) {
1924273d9f13SBarry Smith     for (i=0; i<mbs; i++) {
1925273d9f13SBarry Smith       if (nnz[i] < 0) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"nnz cannot be less than 0: local row %d value %d",i,nnz[i]);
19263a7fca6bSBarry 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);
1927273d9f13SBarry Smith     }
1928273d9f13SBarry Smith   }
1929273d9f13SBarry Smith 
1930273d9f13SBarry Smith   b       = (Mat_SeqBAIJ*)B->data;
1931b0a32e0cSBarry Smith   ierr    = PetscOptionsHasName(PETSC_NULL,"-mat_no_unroll",&flg);CHKERRQ(ierr);
1932273d9f13SBarry Smith   if (!flg) {
1933273d9f13SBarry Smith     switch (bs) {
1934273d9f13SBarry Smith     case 1:
1935273d9f13SBarry Smith       B->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_1;
1936273d9f13SBarry Smith       B->ops->solve           = MatSolve_SeqBAIJ_1;
1937273d9f13SBarry Smith       B->ops->solvetranspose  = MatSolveTranspose_SeqBAIJ_1;
1938273d9f13SBarry Smith       B->ops->mult            = MatMult_SeqBAIJ_1;
1939273d9f13SBarry Smith       B->ops->multadd         = MatMultAdd_SeqBAIJ_1;
1940273d9f13SBarry Smith       break;
1941273d9f13SBarry Smith     case 2:
1942273d9f13SBarry Smith       B->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_2;
1943273d9f13SBarry Smith       B->ops->solve           = MatSolve_SeqBAIJ_2;
1944273d9f13SBarry Smith       B->ops->solvetranspose  = MatSolveTranspose_SeqBAIJ_2;
1945273d9f13SBarry Smith       B->ops->mult            = MatMult_SeqBAIJ_2;
1946273d9f13SBarry Smith       B->ops->multadd         = MatMultAdd_SeqBAIJ_2;
1947273d9f13SBarry Smith       break;
1948273d9f13SBarry Smith     case 3:
1949273d9f13SBarry Smith       B->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_3;
1950273d9f13SBarry Smith       B->ops->solve           = MatSolve_SeqBAIJ_3;
1951273d9f13SBarry Smith       B->ops->solvetranspose  = MatSolveTranspose_SeqBAIJ_3;
1952273d9f13SBarry Smith       B->ops->mult            = MatMult_SeqBAIJ_3;
1953273d9f13SBarry Smith       B->ops->multadd         = MatMultAdd_SeqBAIJ_3;
1954273d9f13SBarry Smith       break;
1955273d9f13SBarry Smith     case 4:
1956273d9f13SBarry Smith       B->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_4;
1957273d9f13SBarry Smith       B->ops->solve           = MatSolve_SeqBAIJ_4;
1958273d9f13SBarry Smith       B->ops->solvetranspose  = MatSolveTranspose_SeqBAIJ_4;
1959273d9f13SBarry Smith       B->ops->mult            = MatMult_SeqBAIJ_4;
1960273d9f13SBarry Smith       B->ops->multadd         = MatMultAdd_SeqBAIJ_4;
1961273d9f13SBarry Smith       break;
1962273d9f13SBarry Smith     case 5:
1963273d9f13SBarry Smith       B->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_5;
1964273d9f13SBarry Smith       B->ops->solve           = MatSolve_SeqBAIJ_5;
1965273d9f13SBarry Smith       B->ops->solvetranspose  = MatSolveTranspose_SeqBAIJ_5;
1966273d9f13SBarry Smith       B->ops->mult            = MatMult_SeqBAIJ_5;
1967273d9f13SBarry Smith       B->ops->multadd         = MatMultAdd_SeqBAIJ_5;
1968273d9f13SBarry Smith       break;
1969273d9f13SBarry Smith     case 6:
1970273d9f13SBarry Smith       B->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_6;
1971273d9f13SBarry Smith       B->ops->solve           = MatSolve_SeqBAIJ_6;
1972273d9f13SBarry Smith       B->ops->solvetranspose  = MatSolveTranspose_SeqBAIJ_6;
1973273d9f13SBarry Smith       B->ops->mult            = MatMult_SeqBAIJ_6;
1974273d9f13SBarry Smith       B->ops->multadd         = MatMultAdd_SeqBAIJ_6;
1975273d9f13SBarry Smith       break;
1976273d9f13SBarry Smith     case 7:
1977273d9f13SBarry Smith       B->ops->mult            = MatMult_SeqBAIJ_7;
1978273d9f13SBarry Smith       B->ops->solve           = MatSolve_SeqBAIJ_7;
1979273d9f13SBarry Smith       B->ops->solvetranspose  = MatSolveTranspose_SeqBAIJ_7;
1980273d9f13SBarry Smith       B->ops->multadd         = MatMultAdd_SeqBAIJ_7;
1981273d9f13SBarry Smith       break;
1982273d9f13SBarry Smith     default:
1983273d9f13SBarry Smith       B->ops->mult            = MatMult_SeqBAIJ_N;
1984273d9f13SBarry Smith       B->ops->solve           = MatSolve_SeqBAIJ_N;
1985273d9f13SBarry Smith       B->ops->multadd         = MatMultAdd_SeqBAIJ_N;
1986273d9f13SBarry Smith       break;
1987273d9f13SBarry Smith     }
1988273d9f13SBarry Smith   }
1989273d9f13SBarry Smith   b->bs      = bs;
1990273d9f13SBarry Smith   b->mbs     = mbs;
1991273d9f13SBarry Smith   b->nbs     = nbs;
1992b0a32e0cSBarry Smith   ierr = PetscMalloc((mbs+1)*sizeof(int),&b->imax);CHKERRQ(ierr);
1993273d9f13SBarry Smith   if (!nnz) {
1994435da068SBarry Smith     if (nz == PETSC_DEFAULT || nz == PETSC_DECIDE) nz = 5;
1995273d9f13SBarry Smith     else if (nz <= 0)        nz = 1;
1996273d9f13SBarry Smith     for (i=0; i<mbs; i++) b->imax[i] = nz;
1997273d9f13SBarry Smith     nz = nz*mbs;
1998273d9f13SBarry Smith   } else {
1999273d9f13SBarry Smith     nz = 0;
2000273d9f13SBarry Smith     for (i=0; i<mbs; i++) {b->imax[i] = nnz[i]; nz += nnz[i];}
2001273d9f13SBarry Smith   }
2002273d9f13SBarry Smith 
2003273d9f13SBarry Smith   /* allocate the matrix space */
2004273d9f13SBarry Smith   len   = nz*sizeof(int) + nz*bs2*sizeof(MatScalar) + (B->m+1)*sizeof(int);
2005b0a32e0cSBarry Smith   ierr  = PetscMalloc(len,&b->a);CHKERRQ(ierr);
2006273d9f13SBarry Smith   ierr  = PetscMemzero(b->a,nz*bs2*sizeof(MatScalar));CHKERRQ(ierr);
2007273d9f13SBarry Smith   b->j  = (int*)(b->a + nz*bs2);
2008273d9f13SBarry Smith   ierr = PetscMemzero(b->j,nz*sizeof(int));CHKERRQ(ierr);
2009273d9f13SBarry Smith   b->i  = b->j + nz;
2010273d9f13SBarry Smith   b->singlemalloc = PETSC_TRUE;
2011273d9f13SBarry Smith 
2012273d9f13SBarry Smith   b->i[0] = 0;
2013273d9f13SBarry Smith   for (i=1; i<mbs+1; i++) {
2014273d9f13SBarry Smith     b->i[i] = b->i[i-1] + b->imax[i-1];
2015273d9f13SBarry Smith   }
2016273d9f13SBarry Smith 
2017273d9f13SBarry Smith   /* b->ilen will count nonzeros in each block row so far. */
201816d6aa21SSatish Balay   ierr = PetscMalloc((mbs+1)*sizeof(int),&b->ilen);CHKERRQ(ierr);
2019b0a32e0cSBarry Smith   PetscLogObjectMemory(B,len+2*(mbs+1)*sizeof(int)+sizeof(struct _p_Mat)+sizeof(Mat_SeqBAIJ));
2020273d9f13SBarry Smith   for (i=0; i<mbs; i++) { b->ilen[i] = 0;}
2021273d9f13SBarry Smith 
2022273d9f13SBarry Smith   b->bs               = bs;
2023273d9f13SBarry Smith   b->bs2              = bs2;
2024273d9f13SBarry Smith   b->mbs              = mbs;
2025273d9f13SBarry Smith   b->nz               = 0;
2026273d9f13SBarry Smith   b->maxnz            = nz*bs2;
2027273d9f13SBarry Smith   B->info.nz_unneeded = (PetscReal)b->maxnz;
2028273d9f13SBarry Smith   PetscFunctionReturn(0);
2029273d9f13SBarry Smith }
20302593348eSBarry Smith 
2031