xref: /petsc/src/mat/impls/baij/seq/baij.c (revision a45adfd634f538af0df75033dc42d977b3d42dfd)
1bba1ac68SSatish Balay /*$Id: baij.c,v 1.245 2001/08/07 03:02:55 balay Exp bsmith $*/
22593348eSBarry Smith 
32593348eSBarry Smith /*
4b6490206SBarry Smith     Defines the basic matrix operations for the BAIJ (compressed row)
52593348eSBarry Smith   matrix storage format.
62593348eSBarry Smith */
770f55243SBarry Smith #include "src/mat/impls/baij/seq/baij.h"
81a6a6d98SBarry Smith #include "src/vec/vecimpl.h"
91a6a6d98SBarry Smith #include "src/inline/spops.h"
10325e03aeSBarry Smith #include "petscsys.h"                     /*I "petscmat.h" I*/
113b547af2SSatish Balay 
12af674e45SBarry Smith /*
13af674e45SBarry Smith     Special version for Fun3d sequential benchmark
14af674e45SBarry Smith */
15af674e45SBarry Smith #if defined(PETSC_HAVE_FORTRAN_CAPS)
16af674e45SBarry Smith #define matsetvaluesblocked4_ MATSETVALUESBLOCKED4
17af674e45SBarry Smith #elif !defined(PETSC_HAVE_FORTRAN_UNDERSCORE)
18af674e45SBarry Smith #define matsetvaluesblocked4_ matsetvaluesblocked4
19af674e45SBarry Smith #endif
20af674e45SBarry Smith 
219c8c1041SBarry Smith EXTERN_C_BEGIN
22af674e45SBarry Smith #undef __FUNCT__
23af674e45SBarry Smith #define __FUNCT__ "matsetvaluesblocked4_"
24f15d580aSBarry Smith void matsetvaluesblocked4_(Mat *AA,int *mm,const int im[],int *nn,const int in[],const PetscScalar v[])
25af674e45SBarry Smith {
26af674e45SBarry Smith   Mat               A = *AA;
27af674e45SBarry Smith   Mat_SeqBAIJ       *a = (Mat_SeqBAIJ*)A->data;
28a037b02bSBarry Smith   int               *rp,k,low,high,t,ii,jj,row,nrow,i,col,l,N,m = *mm,n = *nn;
2938fde467SHong Zhang   int               *ai=a->i,*ailen=a->ilen;
30a037b02bSBarry Smith   int               *aj=a->j,stepval;
31f15d580aSBarry Smith   const PetscScalar *value = v;
324bb09213Spetsc   MatScalar         *ap,*aa = a->a,*bap;
33af674e45SBarry Smith 
34af674e45SBarry Smith   PetscFunctionBegin;
35af674e45SBarry Smith   stepval = (n-1)*4;
36af674e45SBarry Smith   for (k=0; k<m; k++) { /* loop over added rows */
37af674e45SBarry Smith     row  = im[k];
38af674e45SBarry Smith     rp   = aj + ai[row];
39af674e45SBarry Smith     ap   = aa + 16*ai[row];
40af674e45SBarry Smith     nrow = ailen[row];
41af674e45SBarry Smith     low  = 0;
42af674e45SBarry Smith     for (l=0; l<n; l++) { /* loop over added columns */
43af674e45SBarry Smith       col = in[l];
44af674e45SBarry Smith       value = v + k*(stepval+4)*4 + l*4;
45af674e45SBarry Smith       low = 0; high = nrow;
46af674e45SBarry Smith       while (high-low > 7) {
47af674e45SBarry Smith         t = (low+high)/2;
48af674e45SBarry Smith         if (rp[t] > col) high = t;
49af674e45SBarry Smith         else             low  = t;
50af674e45SBarry Smith       }
51af674e45SBarry Smith       for (i=low; i<high; i++) {
52af674e45SBarry Smith         if (rp[i] > col) break;
53af674e45SBarry Smith         if (rp[i] == col) {
54af674e45SBarry Smith           bap  = ap +  16*i;
55af674e45SBarry Smith           for (ii=0; ii<4; ii++,value+=stepval) {
56af674e45SBarry Smith             for (jj=ii; jj<16; jj+=4) {
57af674e45SBarry Smith               bap[jj] += *value++;
58af674e45SBarry Smith             }
59af674e45SBarry Smith           }
60af674e45SBarry Smith           goto noinsert2;
61af674e45SBarry Smith         }
62af674e45SBarry Smith       }
63af674e45SBarry Smith       N = nrow++ - 1;
64af674e45SBarry Smith       /* shift up all the later entries in this row */
65af674e45SBarry Smith       for (ii=N; ii>=i; ii--) {
66af674e45SBarry Smith         rp[ii+1] = rp[ii];
67a037b02bSBarry Smith         PetscMemcpy(ap+16*(ii+1),ap+16*(ii),16*sizeof(MatScalar));
68af674e45SBarry Smith       }
69af674e45SBarry Smith       if (N >= i) {
70a037b02bSBarry Smith         PetscMemzero(ap+16*i,16*sizeof(MatScalar));
71af674e45SBarry Smith       }
72af674e45SBarry Smith       rp[i] = col;
73af674e45SBarry Smith       bap   = ap +  16*i;
74af674e45SBarry Smith       for (ii=0; ii<4; ii++,value+=stepval) {
75af674e45SBarry Smith         for (jj=ii; jj<16; jj+=4) {
76af674e45SBarry Smith           bap[jj] = *value++;
77af674e45SBarry Smith         }
78af674e45SBarry Smith       }
79af674e45SBarry Smith       noinsert2:;
80af674e45SBarry Smith       low = i;
81af674e45SBarry Smith     }
82af674e45SBarry Smith     ailen[row] = nrow;
83af674e45SBarry Smith   }
84af674e45SBarry Smith }
859c8c1041SBarry Smith EXTERN_C_END
86af674e45SBarry Smith 
87af674e45SBarry Smith #if defined(PETSC_HAVE_FORTRAN_CAPS)
88af674e45SBarry Smith #define matsetvalues4_ MATSETVALUES4
89af674e45SBarry Smith #elif !defined(PETSC_HAVE_FORTRAN_UNDERSCORE)
90af674e45SBarry Smith #define matsetvalues4_ matsetvalues4
91af674e45SBarry Smith #endif
92af674e45SBarry Smith 
939c8c1041SBarry Smith EXTERN_C_BEGIN
94af674e45SBarry Smith #undef __FUNCT__
95af674e45SBarry Smith #define __FUNCT__ "MatSetValues4_"
964bb09213Spetsc void matsetvalues4_(Mat *AA,int *mm,int *im,int *nn,int *in,PetscScalar *v)
97af674e45SBarry Smith {
98af674e45SBarry Smith   Mat         A = *AA;
99af674e45SBarry Smith   Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)A->data;
100a037b02bSBarry Smith   int         *rp,k,low,high,t,ii,row,nrow,i,col,l,N,n = *nn,m = *mm;
10138fde467SHong Zhang   int         *ai=a->i,*ailen=a->ilen;
102af674e45SBarry Smith   int         *aj=a->j,brow,bcol;
10338fde467SHong Zhang   int         ridx,cidx;
104af674e45SBarry Smith   MatScalar   *ap,value,*aa=a->a,*bap;
105af674e45SBarry Smith 
106af674e45SBarry Smith   PetscFunctionBegin;
107af674e45SBarry Smith   for (k=0; k<m; k++) { /* loop over added rows */
108af674e45SBarry Smith     row  = im[k]; brow = row/4;
109af674e45SBarry Smith     rp   = aj + ai[brow];
110af674e45SBarry Smith     ap   = aa + 16*ai[brow];
111af674e45SBarry Smith     nrow = ailen[brow];
112af674e45SBarry Smith     low  = 0;
113af674e45SBarry Smith     for (l=0; l<n; l++) { /* loop over added columns */
114af674e45SBarry Smith       col = in[l]; bcol = col/4;
115af674e45SBarry Smith       ridx = row % 4; cidx = col % 4;
116af674e45SBarry Smith       value = v[l + k*n];
117af674e45SBarry Smith       low = 0; high = nrow;
118af674e45SBarry Smith       while (high-low > 7) {
119af674e45SBarry Smith         t = (low+high)/2;
120af674e45SBarry Smith         if (rp[t] > bcol) high = t;
121af674e45SBarry Smith         else              low  = t;
122af674e45SBarry Smith       }
123af674e45SBarry Smith       for (i=low; i<high; i++) {
124af674e45SBarry Smith         if (rp[i] > bcol) break;
125af674e45SBarry Smith         if (rp[i] == bcol) {
126af674e45SBarry Smith           bap  = ap +  16*i + 4*cidx + ridx;
127af674e45SBarry Smith           *bap += value;
128af674e45SBarry Smith           goto noinsert1;
129af674e45SBarry Smith         }
130af674e45SBarry Smith       }
131af674e45SBarry Smith       N = nrow++ - 1;
132af674e45SBarry Smith       /* shift up all the later entries in this row */
133af674e45SBarry Smith       for (ii=N; ii>=i; ii--) {
134af674e45SBarry Smith         rp[ii+1] = rp[ii];
135a037b02bSBarry Smith         PetscMemcpy(ap+16*(ii+1),ap+16*(ii),16*sizeof(MatScalar));
136af674e45SBarry Smith       }
137af674e45SBarry Smith       if (N>=i) {
138a037b02bSBarry Smith         PetscMemzero(ap+16*i,16*sizeof(MatScalar));
139af674e45SBarry Smith       }
140af674e45SBarry Smith       rp[i]                    = bcol;
141af674e45SBarry Smith       ap[16*i + 4*cidx + ridx] = value;
142af674e45SBarry Smith       noinsert1:;
143af674e45SBarry Smith       low = i;
144af674e45SBarry Smith     }
145af674e45SBarry Smith     ailen[brow] = nrow;
146af674e45SBarry Smith   }
147af674e45SBarry Smith }
1489c8c1041SBarry Smith EXTERN_C_END
149af674e45SBarry Smith 
15095d5f7c2SBarry Smith /*  UGLY, ugly, ugly
15187828ca2SBarry Smith    When MatScalar == PetscScalar the function MatSetValuesBlocked_SeqBAIJ_MatScalar() does
1523477af42SKris Buschelman    not exist. Otherwise ..._MatScalar() takes matrix dlements in single precision and
15395d5f7c2SBarry Smith    inserts them into the single precision data structure. The function MatSetValuesBlocked_SeqBAIJ()
15495d5f7c2SBarry Smith    converts the entries into single precision and then calls ..._MatScalar() to put them
15595d5f7c2SBarry Smith    into the single precision data structures.
15695d5f7c2SBarry Smith */
15795d5f7c2SBarry Smith #if defined(PETSC_USE_MAT_SINGLE)
158f15d580aSBarry Smith EXTERN int MatSetValuesBlocked_SeqBAIJ_MatScalar(Mat,int,const int[],int,const int[],const MatScalar[],InsertMode);
15995d5f7c2SBarry Smith #else
16095d5f7c2SBarry Smith #define MatSetValuesBlocked_SeqBAIJ_MatScalar MatSetValuesBlocked_SeqBAIJ
16195d5f7c2SBarry Smith #endif
16295d5f7c2SBarry Smith 
1632d61bbb3SSatish Balay #define CHUNKSIZE  10
164de6a44a3SBarry Smith 
165be5855fcSBarry Smith /*
166be5855fcSBarry Smith      Checks for missing diagonals
167be5855fcSBarry Smith */
1684a2ae208SSatish Balay #undef __FUNCT__
1694a2ae208SSatish Balay #define __FUNCT__ "MatMissingDiagonal_SeqBAIJ"
170c4992f7dSBarry Smith int MatMissingDiagonal_SeqBAIJ(Mat A)
171be5855fcSBarry Smith {
172be5855fcSBarry Smith   Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)A->data;
173883fce79SBarry Smith   int         *diag,*jj = a->j,i,ierr;
174be5855fcSBarry Smith 
175be5855fcSBarry Smith   PetscFunctionBegin;
176c4992f7dSBarry Smith   ierr = MatMarkDiagonal_SeqBAIJ(A);CHKERRQ(ierr);
177883fce79SBarry Smith   diag = a->diag;
1780e8e8aceSBarry Smith   for (i=0; i<a->mbs; i++) {
179be5855fcSBarry Smith     if (jj[diag[i]] != i) {
18029bbc08cSBarry Smith       SETERRQ1(1,"Matrix is missing diagonal number %d",i);
181be5855fcSBarry Smith     }
182be5855fcSBarry Smith   }
183be5855fcSBarry Smith   PetscFunctionReturn(0);
184be5855fcSBarry Smith }
185be5855fcSBarry Smith 
1864a2ae208SSatish Balay #undef __FUNCT__
1874a2ae208SSatish Balay #define __FUNCT__ "MatMarkDiagonal_SeqBAIJ"
188c4992f7dSBarry Smith int MatMarkDiagonal_SeqBAIJ(Mat A)
189de6a44a3SBarry Smith {
190de6a44a3SBarry Smith   Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)A->data;
19182502324SSatish Balay   int         i,j,*diag,m = a->mbs,ierr;
192de6a44a3SBarry Smith 
1933a40ed3dSBarry Smith   PetscFunctionBegin;
194883fce79SBarry Smith   if (a->diag) PetscFunctionReturn(0);
195883fce79SBarry Smith 
196b0a32e0cSBarry Smith   ierr = PetscMalloc((m+1)*sizeof(int),&diag);CHKERRQ(ierr);
197b0a32e0cSBarry Smith   PetscLogObjectMemory(A,(m+1)*sizeof(int));
1987fc0212eSBarry Smith   for (i=0; i<m; i++) {
199ecc615b2SBarry Smith     diag[i] = a->i[i+1];
200de6a44a3SBarry Smith     for (j=a->i[i]; j<a->i[i+1]; j++) {
201de6a44a3SBarry Smith       if (a->j[j] == i) {
202de6a44a3SBarry Smith         diag[i] = j;
203de6a44a3SBarry Smith         break;
204de6a44a3SBarry Smith       }
205de6a44a3SBarry Smith     }
206de6a44a3SBarry Smith   }
207de6a44a3SBarry Smith   a->diag = diag;
2083a40ed3dSBarry Smith   PetscFunctionReturn(0);
209de6a44a3SBarry Smith }
2102593348eSBarry Smith 
2112593348eSBarry Smith 
212ca44d042SBarry Smith EXTERN int MatToSymmetricIJ_SeqAIJ(int,int*,int*,int,int,int**,int**);
2133b2fbd54SBarry Smith 
2144a2ae208SSatish Balay #undef __FUNCT__
2154a2ae208SSatish Balay #define __FUNCT__ "MatGetRowIJ_SeqBAIJ"
2164e7234bfSBarry Smith static int MatGetRowIJ_SeqBAIJ(Mat A,int oshift,PetscTruth symmetric,int *nn,int *ia[],int *ja[],PetscTruth *done)
2173b2fbd54SBarry Smith {
2183b2fbd54SBarry Smith   Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)A->data;
2193b2fbd54SBarry Smith   int         ierr,n = a->mbs,i;
2203b2fbd54SBarry Smith 
2213a40ed3dSBarry Smith   PetscFunctionBegin;
2223b2fbd54SBarry Smith   *nn = n;
2233a40ed3dSBarry Smith   if (!ia) PetscFunctionReturn(0);
2243b2fbd54SBarry Smith   if (symmetric) {
2253b2fbd54SBarry Smith     ierr = MatToSymmetricIJ_SeqAIJ(n,a->i,a->j,0,oshift,ia,ja);CHKERRQ(ierr);
2263b2fbd54SBarry Smith   } else if (oshift == 1) {
2273b2fbd54SBarry Smith     /* temporarily add 1 to i and j indices */
228435da068SBarry Smith     int nz = a->i[n];
2293b2fbd54SBarry Smith     for (i=0; i<nz; i++) a->j[i]++;
2303b2fbd54SBarry Smith     for (i=0; i<n+1; i++) a->i[i]++;
2313b2fbd54SBarry Smith     *ia = a->i; *ja = a->j;
2323b2fbd54SBarry Smith   } else {
2333b2fbd54SBarry Smith     *ia = a->i; *ja = a->j;
2343b2fbd54SBarry Smith   }
2353b2fbd54SBarry Smith 
2363a40ed3dSBarry Smith   PetscFunctionReturn(0);
2373b2fbd54SBarry Smith }
2383b2fbd54SBarry Smith 
2394a2ae208SSatish Balay #undef __FUNCT__
2404a2ae208SSatish Balay #define __FUNCT__ "MatRestoreRowIJ_SeqBAIJ"
2414e7234bfSBarry Smith static int MatRestoreRowIJ_SeqBAIJ(Mat A,int oshift,PetscTruth symmetric,int *nn,int *ia[],int *ja[],PetscTruth *done)
2423b2fbd54SBarry Smith {
2433b2fbd54SBarry Smith   Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)A->data;
244606d414cSSatish Balay   int         i,n = a->mbs,ierr;
2453b2fbd54SBarry Smith 
2463a40ed3dSBarry Smith   PetscFunctionBegin;
2473a40ed3dSBarry Smith   if (!ia) PetscFunctionReturn(0);
2483b2fbd54SBarry Smith   if (symmetric) {
249606d414cSSatish Balay     ierr = PetscFree(*ia);CHKERRQ(ierr);
250606d414cSSatish Balay     ierr = PetscFree(*ja);CHKERRQ(ierr);
251af5da2bfSBarry Smith   } else if (oshift == 1) {
252435da068SBarry Smith     int nz = a->i[n]-1;
2533b2fbd54SBarry Smith     for (i=0; i<nz; i++) a->j[i]--;
2543b2fbd54SBarry Smith     for (i=0; i<n+1; i++) a->i[i]--;
2553b2fbd54SBarry Smith   }
2563a40ed3dSBarry Smith   PetscFunctionReturn(0);
2573b2fbd54SBarry Smith }
2583b2fbd54SBarry Smith 
2594a2ae208SSatish Balay #undef __FUNCT__
2604a2ae208SSatish Balay #define __FUNCT__ "MatGetBlockSize_SeqBAIJ"
2612d61bbb3SSatish Balay int MatGetBlockSize_SeqBAIJ(Mat mat,int *bs)
2622d61bbb3SSatish Balay {
2632d61bbb3SSatish Balay   Mat_SeqBAIJ *baij = (Mat_SeqBAIJ*)mat->data;
2642d61bbb3SSatish Balay 
2652d61bbb3SSatish Balay   PetscFunctionBegin;
2662d61bbb3SSatish Balay   *bs = baij->bs;
2672d61bbb3SSatish Balay   PetscFunctionReturn(0);
2682d61bbb3SSatish Balay }
2692d61bbb3SSatish Balay 
2702d61bbb3SSatish Balay 
2714a2ae208SSatish Balay #undef __FUNCT__
2724a2ae208SSatish Balay #define __FUNCT__ "MatDestroy_SeqBAIJ"
273e1311b90SBarry Smith int MatDestroy_SeqBAIJ(Mat A)
2742d61bbb3SSatish Balay {
2752d61bbb3SSatish Balay   Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)A->data;
276e51c0b9cSSatish Balay   int         ierr;
2772d61bbb3SSatish Balay 
278433994e6SBarry Smith   PetscFunctionBegin;
279aa482453SBarry Smith #if defined(PETSC_USE_LOG)
280b0a32e0cSBarry Smith   PetscLogObjectState((PetscObject)A,"Rows=%d, Cols=%d, NZ=%d",A->m,A->n,a->nz);
2812d61bbb3SSatish Balay #endif
282606d414cSSatish Balay   ierr = PetscFree(a->a);CHKERRQ(ierr);
283606d414cSSatish Balay   if (!a->singlemalloc) {
284606d414cSSatish Balay     ierr = PetscFree(a->i);CHKERRQ(ierr);
285606d414cSSatish Balay     ierr = PetscFree(a->j);CHKERRQ(ierr);
286606d414cSSatish Balay   }
287c38d4ed2SBarry Smith   if (a->row) {
288c38d4ed2SBarry Smith     ierr = ISDestroy(a->row);CHKERRQ(ierr);
289c38d4ed2SBarry Smith   }
290c38d4ed2SBarry Smith   if (a->col) {
291c38d4ed2SBarry Smith     ierr = ISDestroy(a->col);CHKERRQ(ierr);
292c38d4ed2SBarry Smith   }
293606d414cSSatish Balay   if (a->diag) {ierr = PetscFree(a->diag);CHKERRQ(ierr);}
294606d414cSSatish Balay   if (a->ilen) {ierr = PetscFree(a->ilen);CHKERRQ(ierr);}
295606d414cSSatish Balay   if (a->imax) {ierr = PetscFree(a->imax);CHKERRQ(ierr);}
296606d414cSSatish Balay   if (a->solve_work) {ierr = PetscFree(a->solve_work);CHKERRQ(ierr);}
297606d414cSSatish Balay   if (a->mult_work) {ierr = PetscFree(a->mult_work);CHKERRQ(ierr);}
298e51c0b9cSSatish Balay   if (a->icol) {ierr = ISDestroy(a->icol);CHKERRQ(ierr);}
299606d414cSSatish Balay   if (a->saved_values) {ierr = PetscFree(a->saved_values);CHKERRQ(ierr);}
300563b5814SBarry Smith #if defined(PETSC_USE_MAT_SINGLE)
301563b5814SBarry Smith   if (a->setvaluescopy) {ierr = PetscFree(a->setvaluescopy);CHKERRQ(ierr);}
302563b5814SBarry Smith #endif
303c4319e64SHong Zhang   if (a->xtoy) {ierr = PetscFree(a->xtoy);CHKERRQ(ierr);}
304c4319e64SHong Zhang 
305606d414cSSatish Balay   ierr = PetscFree(a);CHKERRQ(ierr);
3062d61bbb3SSatish Balay   PetscFunctionReturn(0);
3072d61bbb3SSatish Balay }
3082d61bbb3SSatish Balay 
3094a2ae208SSatish Balay #undef __FUNCT__
3104a2ae208SSatish Balay #define __FUNCT__ "MatSetOption_SeqBAIJ"
3112d61bbb3SSatish Balay int MatSetOption_SeqBAIJ(Mat A,MatOption op)
3122d61bbb3SSatish Balay {
3132d61bbb3SSatish Balay   Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)A->data;
3142d61bbb3SSatish Balay 
3152d61bbb3SSatish Balay   PetscFunctionBegin;
316aa275fccSKris Buschelman   switch (op) {
317aa275fccSKris Buschelman   case MAT_ROW_ORIENTED:
318aa275fccSKris Buschelman     a->roworiented    = PETSC_TRUE;
319aa275fccSKris Buschelman     break;
320aa275fccSKris Buschelman   case MAT_COLUMN_ORIENTED:
321aa275fccSKris Buschelman     a->roworiented    = PETSC_FALSE;
322aa275fccSKris Buschelman     break;
323aa275fccSKris Buschelman   case MAT_COLUMNS_SORTED:
324aa275fccSKris Buschelman     a->sorted         = PETSC_TRUE;
325aa275fccSKris Buschelman     break;
326aa275fccSKris Buschelman   case MAT_COLUMNS_UNSORTED:
327aa275fccSKris Buschelman     a->sorted         = PETSC_FALSE;
328aa275fccSKris Buschelman     break;
329aa275fccSKris Buschelman   case MAT_KEEP_ZEROED_ROWS:
330aa275fccSKris Buschelman     a->keepzeroedrows = PETSC_TRUE;
331aa275fccSKris Buschelman     break;
332aa275fccSKris Buschelman   case MAT_NO_NEW_NONZERO_LOCATIONS:
333aa275fccSKris Buschelman     a->nonew          = 1;
334aa275fccSKris Buschelman     break;
335aa275fccSKris Buschelman   case MAT_NEW_NONZERO_LOCATION_ERR:
336aa275fccSKris Buschelman     a->nonew          = -1;
337aa275fccSKris Buschelman     break;
338aa275fccSKris Buschelman   case MAT_NEW_NONZERO_ALLOCATION_ERR:
339aa275fccSKris Buschelman     a->nonew          = -2;
340aa275fccSKris Buschelman     break;
341aa275fccSKris Buschelman   case MAT_YES_NEW_NONZERO_LOCATIONS:
342aa275fccSKris Buschelman     a->nonew          = 0;
343aa275fccSKris Buschelman     break;
344aa275fccSKris Buschelman   case MAT_ROWS_SORTED:
345aa275fccSKris Buschelman   case MAT_ROWS_UNSORTED:
346aa275fccSKris Buschelman   case MAT_YES_NEW_DIAGONALS:
347aa275fccSKris Buschelman   case MAT_IGNORE_OFF_PROC_ENTRIES:
348aa275fccSKris Buschelman   case MAT_USE_HASH_TABLE:
349b0a32e0cSBarry Smith     PetscLogInfo(A,"MatSetOption_SeqBAIJ:Option ignored\n");
350aa275fccSKris Buschelman     break;
351aa275fccSKris Buschelman   case MAT_NO_NEW_DIAGONALS:
35229bbc08cSBarry Smith     SETERRQ(PETSC_ERR_SUP,"MAT_NO_NEW_DIAGONALS");
353aa275fccSKris Buschelman   default:
35429bbc08cSBarry Smith     SETERRQ(PETSC_ERR_SUP,"unknown option");
3552d61bbb3SSatish Balay   }
3562d61bbb3SSatish Balay   PetscFunctionReturn(0);
3572d61bbb3SSatish Balay }
3582d61bbb3SSatish Balay 
3594a2ae208SSatish Balay #undef __FUNCT__
3604a2ae208SSatish Balay #define __FUNCT__ "MatGetRow_SeqBAIJ"
36187828ca2SBarry Smith int MatGetRow_SeqBAIJ(Mat A,int row,int *nz,int **idx,PetscScalar **v)
3622d61bbb3SSatish Balay {
3632d61bbb3SSatish Balay   Mat_SeqBAIJ  *a = (Mat_SeqBAIJ*)A->data;
36482502324SSatish Balay   int          itmp,i,j,k,M,*ai,*aj,bs,bn,bp,*idx_i,bs2,ierr;
3653f1db9ecSBarry Smith   MatScalar    *aa,*aa_i;
36687828ca2SBarry Smith   PetscScalar  *v_i;
3672d61bbb3SSatish Balay 
3682d61bbb3SSatish Balay   PetscFunctionBegin;
3692d61bbb3SSatish Balay   bs  = a->bs;
3702d61bbb3SSatish Balay   ai  = a->i;
3712d61bbb3SSatish Balay   aj  = a->j;
3722d61bbb3SSatish Balay   aa  = a->a;
3732d61bbb3SSatish Balay   bs2 = a->bs2;
3742d61bbb3SSatish Balay 
375*a45adfd6SMatthew Knepley   if (row < 0 || row >= A->m) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Row %d out of range", row);
3762d61bbb3SSatish Balay 
3772d61bbb3SSatish Balay   bn  = row/bs;   /* Block number */
3782d61bbb3SSatish Balay   bp  = row % bs; /* Block Position */
3792d61bbb3SSatish Balay   M   = ai[bn+1] - ai[bn];
3802d61bbb3SSatish Balay   *nz = bs*M;
3812d61bbb3SSatish Balay 
3822d61bbb3SSatish Balay   if (v) {
3832d61bbb3SSatish Balay     *v = 0;
3842d61bbb3SSatish Balay     if (*nz) {
38587828ca2SBarry Smith       ierr = PetscMalloc((*nz)*sizeof(PetscScalar),v);CHKERRQ(ierr);
3862d61bbb3SSatish Balay       for (i=0; i<M; i++) { /* for each block in the block row */
3872d61bbb3SSatish Balay         v_i  = *v + i*bs;
3882d61bbb3SSatish Balay         aa_i = aa + bs2*(ai[bn] + i);
3892d61bbb3SSatish Balay         for (j=bp,k=0; j<bs2; j+=bs,k++) {v_i[k] = aa_i[j];}
3902d61bbb3SSatish Balay       }
3912d61bbb3SSatish Balay     }
3922d61bbb3SSatish Balay   }
3932d61bbb3SSatish Balay 
3942d61bbb3SSatish Balay   if (idx) {
3952d61bbb3SSatish Balay     *idx = 0;
3962d61bbb3SSatish Balay     if (*nz) {
397b0a32e0cSBarry Smith       ierr = PetscMalloc((*nz)*sizeof(int),idx);CHKERRQ(ierr);
3982d61bbb3SSatish Balay       for (i=0; i<M; i++) { /* for each block in the block row */
3992d61bbb3SSatish Balay         idx_i = *idx + i*bs;
4002d61bbb3SSatish Balay         itmp  = bs*aj[ai[bn] + i];
4012d61bbb3SSatish Balay         for (j=0; j<bs; j++) {idx_i[j] = itmp++;}
4022d61bbb3SSatish Balay       }
4032d61bbb3SSatish Balay     }
4042d61bbb3SSatish Balay   }
4052d61bbb3SSatish Balay   PetscFunctionReturn(0);
4062d61bbb3SSatish Balay }
4072d61bbb3SSatish Balay 
4084a2ae208SSatish Balay #undef __FUNCT__
4094a2ae208SSatish Balay #define __FUNCT__ "MatRestoreRow_SeqBAIJ"
41087828ca2SBarry Smith int MatRestoreRow_SeqBAIJ(Mat A,int row,int *nz,int **idx,PetscScalar **v)
4112d61bbb3SSatish Balay {
412606d414cSSatish Balay   int ierr;
413606d414cSSatish Balay 
4142d61bbb3SSatish Balay   PetscFunctionBegin;
415606d414cSSatish Balay   if (idx) {if (*idx) {ierr = PetscFree(*idx);CHKERRQ(ierr);}}
416606d414cSSatish Balay   if (v)   {if (*v)   {ierr = PetscFree(*v);CHKERRQ(ierr);}}
4172d61bbb3SSatish Balay   PetscFunctionReturn(0);
4182d61bbb3SSatish Balay }
4192d61bbb3SSatish Balay 
4204a2ae208SSatish Balay #undef __FUNCT__
4214a2ae208SSatish Balay #define __FUNCT__ "MatTranspose_SeqBAIJ"
4222d61bbb3SSatish Balay int MatTranspose_SeqBAIJ(Mat A,Mat *B)
4232d61bbb3SSatish Balay {
4242d61bbb3SSatish Balay   Mat_SeqBAIJ *a=(Mat_SeqBAIJ *)A->data;
4252d61bbb3SSatish Balay   Mat         C;
4262d61bbb3SSatish Balay   int         i,j,k,ierr,*aj=a->j,*ai=a->i,bs=a->bs,mbs=a->mbs,nbs=a->nbs,len,*col;
427273d9f13SBarry Smith   int         *rows,*cols,bs2=a->bs2;
42887828ca2SBarry Smith   PetscScalar *array;
4292d61bbb3SSatish Balay 
4302d61bbb3SSatish Balay   PetscFunctionBegin;
43129bbc08cSBarry Smith   if (!B && mbs!=nbs) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Square matrix only for in-place");
432b0a32e0cSBarry Smith   ierr = PetscMalloc((1+nbs)*sizeof(int),&col);CHKERRQ(ierr);
433549d3d68SSatish Balay   ierr = PetscMemzero(col,(1+nbs)*sizeof(int));CHKERRQ(ierr);
4342d61bbb3SSatish Balay 
435375fe846SBarry Smith #if defined(PETSC_USE_MAT_SINGLE)
43687828ca2SBarry Smith   ierr = PetscMalloc(a->bs2*a->nz*sizeof(PetscScalar),&array);CHKERRQ(ierr);
43787828ca2SBarry Smith   for (i=0; i<a->bs2*a->nz; i++) array[i] = (PetscScalar)a->a[i];
438375fe846SBarry Smith #else
4393eda8832SBarry Smith   array = a->a;
440375fe846SBarry Smith #endif
441375fe846SBarry Smith 
4422d61bbb3SSatish Balay   for (i=0; i<ai[mbs]; i++) col[aj[i]] += 1;
443273d9f13SBarry Smith   ierr = MatCreateSeqBAIJ(A->comm,bs,A->n,A->m,PETSC_NULL,col,&C);CHKERRQ(ierr);
444606d414cSSatish Balay   ierr = PetscFree(col);CHKERRQ(ierr);
445b0a32e0cSBarry Smith   ierr = PetscMalloc(2*bs*sizeof(int),&rows);CHKERRQ(ierr);
4462d61bbb3SSatish Balay   cols = rows + bs;
4472d61bbb3SSatish Balay   for (i=0; i<mbs; i++) {
4482d61bbb3SSatish Balay     cols[0] = i*bs;
4492d61bbb3SSatish Balay     for (k=1; k<bs; k++) cols[k] = cols[k-1] + 1;
4502d61bbb3SSatish Balay     len = ai[i+1] - ai[i];
4512d61bbb3SSatish Balay     for (j=0; j<len; j++) {
4522d61bbb3SSatish Balay       rows[0] = (*aj++)*bs;
4532d61bbb3SSatish Balay       for (k=1; k<bs; k++) rows[k] = rows[k-1] + 1;
4542d61bbb3SSatish Balay       ierr = MatSetValues(C,bs,rows,bs,cols,array,INSERT_VALUES);CHKERRQ(ierr);
4552d61bbb3SSatish Balay       array += bs2;
4562d61bbb3SSatish Balay     }
4572d61bbb3SSatish Balay   }
458606d414cSSatish Balay   ierr = PetscFree(rows);CHKERRQ(ierr);
459375fe846SBarry Smith #if defined(PETSC_USE_MAT_SINGLE)
460375fe846SBarry Smith   ierr = PetscFree(array);
461375fe846SBarry Smith #endif
4622d61bbb3SSatish Balay 
4632d61bbb3SSatish Balay   ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
4642d61bbb3SSatish Balay   ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
4652d61bbb3SSatish Balay 
466c4992f7dSBarry Smith   if (B) {
4672d61bbb3SSatish Balay     *B = C;
4682d61bbb3SSatish Balay   } else {
469273d9f13SBarry Smith     ierr = MatHeaderCopy(A,C);CHKERRQ(ierr);
4702d61bbb3SSatish Balay   }
4712d61bbb3SSatish Balay   PetscFunctionReturn(0);
4722d61bbb3SSatish Balay }
4732d61bbb3SSatish Balay 
4744a2ae208SSatish Balay #undef __FUNCT__
4754a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqBAIJ_Binary"
476b0a32e0cSBarry Smith static int MatView_SeqBAIJ_Binary(Mat A,PetscViewer viewer)
4772593348eSBarry Smith {
478b6490206SBarry Smith   Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)A->data;
4799df24120SSatish Balay   int         i,fd,*col_lens,ierr,bs = a->bs,count,*jj,j,k,l,bs2=a->bs2;
48087828ca2SBarry Smith   PetscScalar *aa;
481ce6f0cecSBarry Smith   FILE        *file;
4822593348eSBarry Smith 
4833a40ed3dSBarry Smith   PetscFunctionBegin;
484b0a32e0cSBarry Smith   ierr        = PetscViewerBinaryGetDescriptor(viewer,&fd);CHKERRQ(ierr);
485b0a32e0cSBarry Smith   ierr        = PetscMalloc((4+A->m)*sizeof(int),&col_lens);CHKERRQ(ierr);
486552e946dSBarry Smith   col_lens[0] = MAT_FILE_COOKIE;
4873b2fbd54SBarry Smith 
488273d9f13SBarry Smith   col_lens[1] = A->m;
489273d9f13SBarry Smith   col_lens[2] = A->n;
4907e67e3f9SSatish Balay   col_lens[3] = a->nz*bs2;
4912593348eSBarry Smith 
4922593348eSBarry Smith   /* store lengths of each row and write (including header) to file */
493b6490206SBarry Smith   count = 0;
494b6490206SBarry Smith   for (i=0; i<a->mbs; i++) {
495b6490206SBarry Smith     for (j=0; j<bs; j++) {
496b6490206SBarry Smith       col_lens[4+count++] = bs*(a->i[i+1] - a->i[i]);
497b6490206SBarry Smith     }
4982593348eSBarry Smith   }
499273d9f13SBarry Smith   ierr = PetscBinaryWrite(fd,col_lens,4+A->m,PETSC_INT,1);CHKERRQ(ierr);
500606d414cSSatish Balay   ierr = PetscFree(col_lens);CHKERRQ(ierr);
5012593348eSBarry Smith 
5022593348eSBarry Smith   /* store column indices (zero start index) */
503b0a32e0cSBarry Smith   ierr  = PetscMalloc((a->nz+1)*bs2*sizeof(int),&jj);CHKERRQ(ierr);
504b6490206SBarry Smith   count = 0;
505b6490206SBarry Smith   for (i=0; i<a->mbs; i++) {
506b6490206SBarry Smith     for (j=0; j<bs; j++) {
507b6490206SBarry Smith       for (k=a->i[i]; k<a->i[i+1]; k++) {
508b6490206SBarry Smith         for (l=0; l<bs; l++) {
509b6490206SBarry Smith           jj[count++] = bs*a->j[k] + l;
5102593348eSBarry Smith         }
5112593348eSBarry Smith       }
512b6490206SBarry Smith     }
513b6490206SBarry Smith   }
5140752156aSBarry Smith   ierr = PetscBinaryWrite(fd,jj,bs2*a->nz,PETSC_INT,0);CHKERRQ(ierr);
515606d414cSSatish Balay   ierr = PetscFree(jj);CHKERRQ(ierr);
5162593348eSBarry Smith 
5172593348eSBarry Smith   /* store nonzero values */
51887828ca2SBarry Smith   ierr  = PetscMalloc((a->nz+1)*bs2*sizeof(PetscScalar),&aa);CHKERRQ(ierr);
519b6490206SBarry Smith   count = 0;
520b6490206SBarry Smith   for (i=0; i<a->mbs; i++) {
521b6490206SBarry Smith     for (j=0; j<bs; j++) {
522b6490206SBarry Smith       for (k=a->i[i]; k<a->i[i+1]; k++) {
523b6490206SBarry Smith         for (l=0; l<bs; l++) {
5247e67e3f9SSatish Balay           aa[count++] = a->a[bs2*k + l*bs + j];
525b6490206SBarry Smith         }
526b6490206SBarry Smith       }
527b6490206SBarry Smith     }
528b6490206SBarry Smith   }
5290752156aSBarry Smith   ierr = PetscBinaryWrite(fd,aa,bs2*a->nz,PETSC_SCALAR,0);CHKERRQ(ierr);
530606d414cSSatish Balay   ierr = PetscFree(aa);CHKERRQ(ierr);
531ce6f0cecSBarry Smith 
532b0a32e0cSBarry Smith   ierr = PetscViewerBinaryGetInfoPointer(viewer,&file);CHKERRQ(ierr);
533ce6f0cecSBarry Smith   if (file) {
534ce6f0cecSBarry Smith     fprintf(file,"-matload_block_size %d\n",a->bs);
535ce6f0cecSBarry Smith   }
5363a40ed3dSBarry Smith   PetscFunctionReturn(0);
5372593348eSBarry Smith }
5382593348eSBarry Smith 
5394a2ae208SSatish Balay #undef __FUNCT__
5404a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqBAIJ_ASCII"
541b0a32e0cSBarry Smith static int MatView_SeqBAIJ_ASCII(Mat A,PetscViewer viewer)
5422593348eSBarry Smith {
543b6490206SBarry Smith   Mat_SeqBAIJ       *a = (Mat_SeqBAIJ*)A->data;
544fb9695e5SSatish Balay   int               ierr,i,j,bs = a->bs,k,l,bs2=a->bs2;
545f3ef73ceSBarry Smith   PetscViewerFormat format;
5462593348eSBarry Smith 
5473a40ed3dSBarry Smith   PetscFunctionBegin;
548b0a32e0cSBarry Smith   ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr);
549456192e2SBarry Smith   if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) {
550b0a32e0cSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  block size is %d\n",bs);CHKERRQ(ierr);
551fb9695e5SSatish Balay   } else if (format == PETSC_VIEWER_ASCII_MATLAB) {
552bcd9e38bSBarry Smith     Mat aij;
553bcd9e38bSBarry Smith     ierr = MatConvert(A,MATSEQAIJ,&aij);CHKERRQ(ierr);
554bcd9e38bSBarry Smith     ierr = MatView(aij,viewer);CHKERRQ(ierr);
555bcd9e38bSBarry Smith     ierr = MatDestroy(aij);CHKERRQ(ierr);
55604929863SHong Zhang   } else if (format == PETSC_VIEWER_ASCII_FACTOR_INFO) {
55704929863SHong Zhang      PetscFunctionReturn(0);
558fb9695e5SSatish Balay   } else if (format == PETSC_VIEWER_ASCII_COMMON) {
559b0a32e0cSBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_NO);CHKERRQ(ierr);
56044cd7ae7SLois Curfman McInnes     for (i=0; i<a->mbs; i++) {
56144cd7ae7SLois Curfman McInnes       for (j=0; j<bs; j++) {
562b0a32e0cSBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"row %d:",i*bs+j);CHKERRQ(ierr);
56344cd7ae7SLois Curfman McInnes         for (k=a->i[i]; k<a->i[i+1]; k++) {
56444cd7ae7SLois Curfman McInnes           for (l=0; l<bs; l++) {
565aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
5660e6d2581SBarry Smith             if (PetscImaginaryPart(a->a[bs2*k + l*bs + j]) > 0.0 && PetscRealPart(a->a[bs2*k + l*bs + j]) != 0.0) {
56762b941d6SBarry Smith               ierr = PetscViewerASCIIPrintf(viewer," (%d, %g + %gi) ",bs*a->j[k]+l,
5680e6d2581SBarry Smith                       PetscRealPart(a->a[bs2*k + l*bs + j]),PetscImaginaryPart(a->a[bs2*k + l*bs + j]));CHKERRQ(ierr);
5690e6d2581SBarry Smith             } else if (PetscImaginaryPart(a->a[bs2*k + l*bs + j]) < 0.0 && PetscRealPart(a->a[bs2*k + l*bs + j]) != 0.0) {
57062b941d6SBarry Smith               ierr = PetscViewerASCIIPrintf(viewer," (%d, %g - %gi) ",bs*a->j[k]+l,
5710e6d2581SBarry Smith                       PetscRealPart(a->a[bs2*k + l*bs + j]),-PetscImaginaryPart(a->a[bs2*k + l*bs + j]));CHKERRQ(ierr);
5720e6d2581SBarry Smith             } else if (PetscRealPart(a->a[bs2*k + l*bs + j]) != 0.0) {
57362b941d6SBarry Smith               ierr = PetscViewerASCIIPrintf(viewer," (%d, %g) ",bs*a->j[k]+l,PetscRealPart(a->a[bs2*k + l*bs + j]));CHKERRQ(ierr);
5740ef38995SBarry Smith             }
57544cd7ae7SLois Curfman McInnes #else
5760ef38995SBarry Smith             if (a->a[bs2*k + l*bs + j] != 0.0) {
57762b941d6SBarry Smith               ierr = PetscViewerASCIIPrintf(viewer," (%d, %g) ",bs*a->j[k]+l,a->a[bs2*k + l*bs + j]);CHKERRQ(ierr);
5780ef38995SBarry Smith             }
57944cd7ae7SLois Curfman McInnes #endif
58044cd7ae7SLois Curfman McInnes           }
58144cd7ae7SLois Curfman McInnes         }
582b0a32e0cSBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
58344cd7ae7SLois Curfman McInnes       }
58444cd7ae7SLois Curfman McInnes     }
585b0a32e0cSBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_YES);CHKERRQ(ierr);
5860ef38995SBarry Smith   } else {
587b0a32e0cSBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_NO);CHKERRQ(ierr);
588b6490206SBarry Smith     for (i=0; i<a->mbs; i++) {
589b6490206SBarry Smith       for (j=0; j<bs; j++) {
590b0a32e0cSBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"row %d:",i*bs+j);CHKERRQ(ierr);
591b6490206SBarry Smith         for (k=a->i[i]; k<a->i[i+1]; k++) {
592b6490206SBarry Smith           for (l=0; l<bs; l++) {
593aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
5940e6d2581SBarry Smith             if (PetscImaginaryPart(a->a[bs2*k + l*bs + j]) > 0.0) {
59562b941d6SBarry Smith               ierr = PetscViewerASCIIPrintf(viewer," (%d, %g + %g i) ",bs*a->j[k]+l,
5960e6d2581SBarry Smith                 PetscRealPart(a->a[bs2*k + l*bs + j]),PetscImaginaryPart(a->a[bs2*k + l*bs + j]));CHKERRQ(ierr);
5970e6d2581SBarry Smith             } else if (PetscImaginaryPart(a->a[bs2*k + l*bs + j]) < 0.0) {
59862b941d6SBarry Smith               ierr = PetscViewerASCIIPrintf(viewer," (%d, %g - %g i) ",bs*a->j[k]+l,
5990e6d2581SBarry Smith                 PetscRealPart(a->a[bs2*k + l*bs + j]),-PetscImaginaryPart(a->a[bs2*k + l*bs + j]));CHKERRQ(ierr);
6000ef38995SBarry Smith             } else {
60162b941d6SBarry Smith               ierr = PetscViewerASCIIPrintf(viewer," (%d, %g) ",bs*a->j[k]+l,PetscRealPart(a->a[bs2*k + l*bs + j]));CHKERRQ(ierr);
60288685aaeSLois Curfman McInnes             }
60388685aaeSLois Curfman McInnes #else
60462b941d6SBarry Smith             ierr = PetscViewerASCIIPrintf(viewer," (%d, %g) ",bs*a->j[k]+l,a->a[bs2*k + l*bs + j]);CHKERRQ(ierr);
60588685aaeSLois Curfman McInnes #endif
6062593348eSBarry Smith           }
6072593348eSBarry Smith         }
608b0a32e0cSBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
6092593348eSBarry Smith       }
6102593348eSBarry Smith     }
611b0a32e0cSBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_YES);CHKERRQ(ierr);
612b6490206SBarry Smith   }
613b0a32e0cSBarry Smith   ierr = PetscViewerFlush(viewer);CHKERRQ(ierr);
6143a40ed3dSBarry Smith   PetscFunctionReturn(0);
6152593348eSBarry Smith }
6162593348eSBarry Smith 
6174a2ae208SSatish Balay #undef __FUNCT__
6184a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqBAIJ_Draw_Zoom"
619b0a32e0cSBarry Smith static int MatView_SeqBAIJ_Draw_Zoom(PetscDraw draw,void *Aa)
6203270192aSSatish Balay {
62177ed5343SBarry Smith   Mat          A = (Mat) Aa;
6223270192aSSatish Balay   Mat_SeqBAIJ  *a=(Mat_SeqBAIJ*)A->data;
623b65db4caSBarry Smith   int          row,ierr,i,j,k,l,mbs=a->mbs,color,bs=a->bs,bs2=a->bs2;
6240e6d2581SBarry Smith   PetscReal    xl,yl,xr,yr,x_l,x_r,y_l,y_r;
6253f1db9ecSBarry Smith   MatScalar    *aa;
626b0a32e0cSBarry Smith   PetscViewer  viewer;
6273270192aSSatish Balay 
6283a40ed3dSBarry Smith   PetscFunctionBegin;
6293270192aSSatish Balay 
630b65db4caSBarry Smith   /* still need to add support for contour plot of nonzeros; see MatView_SeqAIJ_Draw_Zoom()*/
63177ed5343SBarry Smith   ierr = PetscObjectQuery((PetscObject)A,"Zoomviewer",(PetscObject*)&viewer);CHKERRQ(ierr);
63277ed5343SBarry Smith 
633b0a32e0cSBarry Smith   ierr = PetscDrawGetCoordinates(draw,&xl,&yl,&xr,&yr);CHKERRQ(ierr);
63477ed5343SBarry Smith 
6353270192aSSatish Balay   /* loop over matrix elements drawing boxes */
636b0a32e0cSBarry Smith   color = PETSC_DRAW_BLUE;
6373270192aSSatish Balay   for (i=0,row=0; i<mbs; i++,row+=bs) {
6383270192aSSatish Balay     for (j=a->i[i]; j<a->i[i+1]; j++) {
639273d9f13SBarry Smith       y_l = A->m - row - 1.0; y_r = y_l + 1.0;
6403270192aSSatish Balay       x_l = a->j[j]*bs; x_r = x_l + 1.0;
6413270192aSSatish Balay       aa = a->a + j*bs2;
6423270192aSSatish Balay       for (k=0; k<bs; k++) {
6433270192aSSatish Balay         for (l=0; l<bs; l++) {
6440e6d2581SBarry Smith           if (PetscRealPart(*aa++) >=  0.) continue;
645b0a32e0cSBarry Smith           ierr = PetscDrawRectangle(draw,x_l+k,y_l-l,x_r+k,y_r-l,color,color,color,color);CHKERRQ(ierr);
6463270192aSSatish Balay         }
6473270192aSSatish Balay       }
6483270192aSSatish Balay     }
6493270192aSSatish Balay   }
650b0a32e0cSBarry Smith   color = PETSC_DRAW_CYAN;
6513270192aSSatish Balay   for (i=0,row=0; i<mbs; i++,row+=bs) {
6523270192aSSatish Balay     for (j=a->i[i]; j<a->i[i+1]; j++) {
653273d9f13SBarry Smith       y_l = A->m - row - 1.0; y_r = y_l + 1.0;
6543270192aSSatish Balay       x_l = a->j[j]*bs; x_r = x_l + 1.0;
6553270192aSSatish Balay       aa = a->a + j*bs2;
6563270192aSSatish Balay       for (k=0; k<bs; k++) {
6573270192aSSatish Balay         for (l=0; l<bs; l++) {
6580e6d2581SBarry Smith           if (PetscRealPart(*aa++) != 0.) continue;
659b0a32e0cSBarry Smith           ierr = PetscDrawRectangle(draw,x_l+k,y_l-l,x_r+k,y_r-l,color,color,color,color);CHKERRQ(ierr);
6603270192aSSatish Balay         }
6613270192aSSatish Balay       }
6623270192aSSatish Balay     }
6633270192aSSatish Balay   }
6643270192aSSatish Balay 
665b0a32e0cSBarry Smith   color = PETSC_DRAW_RED;
6663270192aSSatish Balay   for (i=0,row=0; i<mbs; i++,row+=bs) {
6673270192aSSatish Balay     for (j=a->i[i]; j<a->i[i+1]; j++) {
668273d9f13SBarry Smith       y_l = A->m - row - 1.0; y_r = y_l + 1.0;
6693270192aSSatish Balay       x_l = a->j[j]*bs; x_r = x_l + 1.0;
6703270192aSSatish Balay       aa = a->a + j*bs2;
6713270192aSSatish Balay       for (k=0; k<bs; k++) {
6723270192aSSatish Balay         for (l=0; l<bs; l++) {
6730e6d2581SBarry Smith           if (PetscRealPart(*aa++) <= 0.) continue;
674b0a32e0cSBarry Smith           ierr = PetscDrawRectangle(draw,x_l+k,y_l-l,x_r+k,y_r-l,color,color,color,color);CHKERRQ(ierr);
6753270192aSSatish Balay         }
6763270192aSSatish Balay       }
6773270192aSSatish Balay     }
6783270192aSSatish Balay   }
67977ed5343SBarry Smith   PetscFunctionReturn(0);
68077ed5343SBarry Smith }
6813270192aSSatish Balay 
6824a2ae208SSatish Balay #undef __FUNCT__
6834a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqBAIJ_Draw"
684b0a32e0cSBarry Smith static int MatView_SeqBAIJ_Draw(Mat A,PetscViewer viewer)
68577ed5343SBarry Smith {
6867dce120fSSatish Balay   int          ierr;
6870e6d2581SBarry Smith   PetscReal    xl,yl,xr,yr,w,h;
688b0a32e0cSBarry Smith   PetscDraw    draw;
68977ed5343SBarry Smith   PetscTruth   isnull;
6903270192aSSatish Balay 
69177ed5343SBarry Smith   PetscFunctionBegin;
69277ed5343SBarry Smith 
693b0a32e0cSBarry Smith   ierr = PetscViewerDrawGetDraw(viewer,0,&draw);CHKERRQ(ierr);
694b0a32e0cSBarry Smith   ierr = PetscDrawIsNull(draw,&isnull);CHKERRQ(ierr); if (isnull) PetscFunctionReturn(0);
69577ed5343SBarry Smith 
69677ed5343SBarry Smith   ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",(PetscObject)viewer);CHKERRQ(ierr);
697273d9f13SBarry Smith   xr  = A->n; yr = A->m; h = yr/10.0; w = xr/10.0;
69877ed5343SBarry Smith   xr += w;    yr += h;  xl = -w;     yl = -h;
699b0a32e0cSBarry Smith   ierr = PetscDrawSetCoordinates(draw,xl,yl,xr,yr);CHKERRQ(ierr);
700b0a32e0cSBarry Smith   ierr = PetscDrawZoom(draw,MatView_SeqBAIJ_Draw_Zoom,A);CHKERRQ(ierr);
70177ed5343SBarry Smith   ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",PETSC_NULL);CHKERRQ(ierr);
7023a40ed3dSBarry Smith   PetscFunctionReturn(0);
7033270192aSSatish Balay }
7043270192aSSatish Balay 
7054a2ae208SSatish Balay #undef __FUNCT__
7064a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqBAIJ"
707b0a32e0cSBarry Smith int MatView_SeqBAIJ(Mat A,PetscViewer viewer)
7082593348eSBarry Smith {
70919bcc07fSBarry Smith   int        ierr;
7106831982aSBarry Smith   PetscTruth issocket,isascii,isbinary,isdraw;
7112593348eSBarry Smith 
7123a40ed3dSBarry Smith   PetscFunctionBegin;
713b0a32e0cSBarry Smith   ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_SOCKET,&issocket);CHKERRQ(ierr);
714b0a32e0cSBarry Smith   ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&isascii);CHKERRQ(ierr);
715fb9695e5SSatish Balay   ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_BINARY,&isbinary);CHKERRQ(ierr);
716fb9695e5SSatish Balay   ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_DRAW,&isdraw);CHKERRQ(ierr);
7170f5bd95cSBarry Smith   if (issocket) {
71829bbc08cSBarry Smith     SETERRQ(PETSC_ERR_SUP,"Socket viewer not supported");
7190f5bd95cSBarry Smith   } else if (isascii){
7203a40ed3dSBarry Smith     ierr = MatView_SeqBAIJ_ASCII(A,viewer);CHKERRQ(ierr);
7210f5bd95cSBarry Smith   } else if (isbinary) {
7223a40ed3dSBarry Smith     ierr = MatView_SeqBAIJ_Binary(A,viewer);CHKERRQ(ierr);
7230f5bd95cSBarry Smith   } else if (isdraw) {
7243a40ed3dSBarry Smith     ierr = MatView_SeqBAIJ_Draw(A,viewer);CHKERRQ(ierr);
7255cd90555SBarry Smith   } else {
72629bbc08cSBarry Smith     SETERRQ1(1,"Viewer type %s not supported by SeqBAIJ matrices",((PetscObject)viewer)->type_name);
7272593348eSBarry Smith   }
7283a40ed3dSBarry Smith   PetscFunctionReturn(0);
7292593348eSBarry Smith }
730b6490206SBarry Smith 
731cd0e1443SSatish Balay 
7324a2ae208SSatish Balay #undef __FUNCT__
7334a2ae208SSatish Balay #define __FUNCT__ "MatGetValues_SeqBAIJ"
734f15d580aSBarry Smith int MatGetValues_SeqBAIJ(Mat A,int m,const int im[],int n,const int in[],PetscScalar v[])
735cd0e1443SSatish Balay {
736cd0e1443SSatish Balay   Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)A->data;
7372d61bbb3SSatish Balay   int        *rp,k,low,high,t,row,nrow,i,col,l,*aj = a->j;
7382d61bbb3SSatish Balay   int        *ai = a->i,*ailen = a->ilen;
7392d61bbb3SSatish Balay   int        brow,bcol,ridx,cidx,bs=a->bs,bs2=a->bs2;
7403f1db9ecSBarry Smith   MatScalar  *ap,*aa = a->a,zero = 0.0;
741cd0e1443SSatish Balay 
7423a40ed3dSBarry Smith   PetscFunctionBegin;
7432d61bbb3SSatish Balay   for (k=0; k<m; k++) { /* loop over rows */
744cd0e1443SSatish Balay     row  = im[k]; brow = row/bs;
74529bbc08cSBarry Smith     if (row < 0) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Negative row");
746*a45adfd6SMatthew Knepley     if (row >= A->m) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Row %d too large", row);
7472d61bbb3SSatish Balay     rp   = aj + ai[brow] ; ap = aa + bs2*ai[brow] ;
7482c3acbe9SBarry Smith     nrow = ailen[brow];
7492d61bbb3SSatish Balay     for (l=0; l<n; l++) { /* loop over columns */
75029bbc08cSBarry Smith       if (in[l] < 0) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Negative column");
751*a45adfd6SMatthew Knepley       if (in[l] >= A->n) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Column %d too large", in[l]);
7522d61bbb3SSatish Balay       col  = in[l] ;
7532d61bbb3SSatish Balay       bcol = col/bs;
7542d61bbb3SSatish Balay       cidx = col%bs;
7552d61bbb3SSatish Balay       ridx = row%bs;
7562d61bbb3SSatish Balay       high = nrow;
7572d61bbb3SSatish Balay       low  = 0; /* assume unsorted */
7582d61bbb3SSatish Balay       while (high-low > 5) {
759cd0e1443SSatish Balay         t = (low+high)/2;
760cd0e1443SSatish Balay         if (rp[t] > bcol) high = t;
761cd0e1443SSatish Balay         else             low  = t;
762cd0e1443SSatish Balay       }
763cd0e1443SSatish Balay       for (i=low; i<high; i++) {
764cd0e1443SSatish Balay         if (rp[i] > bcol) break;
765cd0e1443SSatish Balay         if (rp[i] == bcol) {
7662d61bbb3SSatish Balay           *v++ = ap[bs2*i+bs*cidx+ridx];
7672d61bbb3SSatish Balay           goto finished;
768cd0e1443SSatish Balay         }
769cd0e1443SSatish Balay       }
7702d61bbb3SSatish Balay       *v++ = zero;
7712d61bbb3SSatish Balay       finished:;
772cd0e1443SSatish Balay     }
773cd0e1443SSatish Balay   }
7743a40ed3dSBarry Smith   PetscFunctionReturn(0);
775cd0e1443SSatish Balay }
776cd0e1443SSatish Balay 
77795d5f7c2SBarry Smith #if defined(PETSC_USE_MAT_SINGLE)
7784a2ae208SSatish Balay #undef __FUNCT__
7794a2ae208SSatish Balay #define __FUNCT__ "MatSetValuesBlocked_SeqBAIJ"
780f15d580aSBarry Smith int MatSetValuesBlocked_SeqBAIJ(Mat mat,int m,const int im[],int n,const int in[],const PetscScalar v[],InsertMode addv)
78195d5f7c2SBarry Smith {
782563b5814SBarry Smith   Mat_SeqBAIJ *b = (Mat_SeqBAIJ*)mat->data;
783563b5814SBarry Smith   int         ierr,i,N = m*n*b->bs2;
784563b5814SBarry Smith   MatScalar   *vsingle;
78595d5f7c2SBarry Smith 
78695d5f7c2SBarry Smith   PetscFunctionBegin;
787563b5814SBarry Smith   if (N > b->setvalueslen) {
788563b5814SBarry Smith     if (b->setvaluescopy) {ierr = PetscFree(b->setvaluescopy);CHKERRQ(ierr);}
789b0a32e0cSBarry Smith     ierr = PetscMalloc(N*sizeof(MatScalar),&b->setvaluescopy);CHKERRQ(ierr);
790563b5814SBarry Smith     b->setvalueslen  = N;
791563b5814SBarry Smith   }
792563b5814SBarry Smith   vsingle = b->setvaluescopy;
79395d5f7c2SBarry Smith   for (i=0; i<N; i++) {
79495d5f7c2SBarry Smith     vsingle[i] = v[i];
79595d5f7c2SBarry Smith   }
79695d5f7c2SBarry Smith   ierr = MatSetValuesBlocked_SeqBAIJ_MatScalar(mat,m,im,n,in,vsingle,addv);CHKERRQ(ierr);
79795d5f7c2SBarry Smith   PetscFunctionReturn(0);
79895d5f7c2SBarry Smith }
79995d5f7c2SBarry Smith #endif
80095d5f7c2SBarry Smith 
8012d61bbb3SSatish Balay 
8024a2ae208SSatish Balay #undef __FUNCT__
8034a2ae208SSatish Balay #define __FUNCT__ "MatSetValuesBlocked_SeqBAIJ"
804f15d580aSBarry Smith int MatSetValuesBlocked_SeqBAIJ_MatScalar(Mat A,int m,const int im[],int n,const int in[],const MatScalar v[],InsertMode is)
80592c4ed94SBarry Smith {
80692c4ed94SBarry Smith   Mat_SeqBAIJ       *a = (Mat_SeqBAIJ*)A->data;
8078a84c255SSatish Balay   int               *rp,k,low,high,t,ii,jj,row,nrow,i,col,l,rmax,N,sorted=a->sorted;
808273d9f13SBarry Smith   int               *imax=a->imax,*ai=a->i,*ailen=a->ilen;
809549d3d68SSatish Balay   int               *aj=a->j,nonew=a->nonew,bs2=a->bs2,bs=a->bs,stepval,ierr;
810273d9f13SBarry Smith   PetscTruth        roworiented=a->roworiented;
811f15d580aSBarry Smith   const MatScalar   *value = v;
812f15d580aSBarry Smith   MatScalar         *ap,*aa = a->a,*bap;
81392c4ed94SBarry Smith 
8143a40ed3dSBarry Smith   PetscFunctionBegin;
8150e324ae4SSatish Balay   if (roworiented) {
8160e324ae4SSatish Balay     stepval = (n-1)*bs;
8170e324ae4SSatish Balay   } else {
8180e324ae4SSatish Balay     stepval = (m-1)*bs;
8190e324ae4SSatish Balay   }
82092c4ed94SBarry Smith   for (k=0; k<m; k++) { /* loop over added rows */
82192c4ed94SBarry Smith     row  = im[k];
8225ef9f2a5SBarry Smith     if (row < 0) continue;
823aa482453SBarry Smith #if defined(PETSC_USE_BOPT_g)
824590ac198SBarry Smith     if (row >= a->mbs) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"Row too large: row %d max %d",row,a->mbs-1);
82592c4ed94SBarry Smith #endif
82692c4ed94SBarry Smith     rp   = aj + ai[row];
82792c4ed94SBarry Smith     ap   = aa + bs2*ai[row];
82892c4ed94SBarry Smith     rmax = imax[row];
82992c4ed94SBarry Smith     nrow = ailen[row];
83092c4ed94SBarry Smith     low  = 0;
83192c4ed94SBarry Smith     for (l=0; l<n; l++) { /* loop over added columns */
8325ef9f2a5SBarry Smith       if (in[l] < 0) continue;
833aa482453SBarry Smith #if defined(PETSC_USE_BOPT_g)
834590ac198SBarry Smith       if (in[l] >= a->nbs) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"Column too large: col %d max %d",in[l],a->nbs-1);
83592c4ed94SBarry Smith #endif
83692c4ed94SBarry Smith       col = in[l];
83792c4ed94SBarry Smith       if (roworiented) {
8380e324ae4SSatish Balay         value = v + k*(stepval+bs)*bs + l*bs;
8390e324ae4SSatish Balay       } else {
8400e324ae4SSatish Balay         value = v + l*(stepval+bs)*bs + k*bs;
84192c4ed94SBarry Smith       }
84292c4ed94SBarry Smith       if (!sorted) low = 0; high = nrow;
84392c4ed94SBarry Smith       while (high-low > 7) {
84492c4ed94SBarry Smith         t = (low+high)/2;
84592c4ed94SBarry Smith         if (rp[t] > col) high = t;
84692c4ed94SBarry Smith         else             low  = t;
84792c4ed94SBarry Smith       }
84892c4ed94SBarry Smith       for (i=low; i<high; i++) {
84992c4ed94SBarry Smith         if (rp[i] > col) break;
85092c4ed94SBarry Smith         if (rp[i] == col) {
8518a84c255SSatish Balay           bap  = ap +  bs2*i;
8520e324ae4SSatish Balay           if (roworiented) {
8538a84c255SSatish Balay             if (is == ADD_VALUES) {
854dd9472c6SBarry Smith               for (ii=0; ii<bs; ii++,value+=stepval) {
855dd9472c6SBarry Smith                 for (jj=ii; jj<bs2; jj+=bs) {
8568a84c255SSatish Balay                   bap[jj] += *value++;
857dd9472c6SBarry Smith                 }
858dd9472c6SBarry Smith               }
8590e324ae4SSatish Balay             } else {
860dd9472c6SBarry Smith               for (ii=0; ii<bs; ii++,value+=stepval) {
861dd9472c6SBarry Smith                 for (jj=ii; jj<bs2; jj+=bs) {
8620e324ae4SSatish Balay                   bap[jj] = *value++;
8638a84c255SSatish Balay                 }
864dd9472c6SBarry Smith               }
865dd9472c6SBarry Smith             }
8660e324ae4SSatish Balay           } else {
8670e324ae4SSatish Balay             if (is == ADD_VALUES) {
868dd9472c6SBarry Smith               for (ii=0; ii<bs; ii++,value+=stepval) {
869dd9472c6SBarry Smith                 for (jj=0; jj<bs; jj++) {
8700e324ae4SSatish Balay                   *bap++ += *value++;
871dd9472c6SBarry Smith                 }
872dd9472c6SBarry Smith               }
8730e324ae4SSatish Balay             } else {
874dd9472c6SBarry Smith               for (ii=0; ii<bs; ii++,value+=stepval) {
875dd9472c6SBarry Smith                 for (jj=0; jj<bs; jj++) {
8760e324ae4SSatish Balay                   *bap++  = *value++;
8770e324ae4SSatish Balay                 }
8788a84c255SSatish Balay               }
879dd9472c6SBarry Smith             }
880dd9472c6SBarry Smith           }
881f1241b54SBarry Smith           goto noinsert2;
88292c4ed94SBarry Smith         }
88392c4ed94SBarry Smith       }
88489280ab3SLois Curfman McInnes       if (nonew == 1) goto noinsert2;
885*a45adfd6SMatthew Knepley       else if (nonew == -1) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"Inserting a new nonzero (%d, %d) in the matrix", row, col);
88692c4ed94SBarry Smith       if (nrow >= rmax) {
88792c4ed94SBarry Smith         /* there is no extra room in row, therefore enlarge */
88892c4ed94SBarry Smith         int       new_nz = ai[a->mbs] + CHUNKSIZE,len,*new_i,*new_j;
8893f1db9ecSBarry Smith         MatScalar *new_a;
89092c4ed94SBarry Smith 
891*a45adfd6SMatthew Knepley         if (nonew == -2) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"Inserting a new nonzero (%d, %d) in the matrix", row, col);
89289280ab3SLois Curfman McInnes 
89392c4ed94SBarry Smith         /* malloc new storage space */
8943f1db9ecSBarry Smith         len     = new_nz*(sizeof(int)+bs2*sizeof(MatScalar))+(a->mbs+1)*sizeof(int);
895b0a32e0cSBarry Smith 	ierr    = PetscMalloc(len,&new_a);CHKERRQ(ierr);
89692c4ed94SBarry Smith         new_j   = (int*)(new_a + bs2*new_nz);
89792c4ed94SBarry Smith         new_i   = new_j + new_nz;
89892c4ed94SBarry Smith 
89992c4ed94SBarry Smith         /* copy over old data into new slots */
90092c4ed94SBarry Smith         for (ii=0; ii<row+1; ii++) {new_i[ii] = ai[ii];}
90192c4ed94SBarry Smith         for (ii=row+1; ii<a->mbs+1; ii++) {new_i[ii] = ai[ii]+CHUNKSIZE;}
902549d3d68SSatish Balay         ierr = PetscMemcpy(new_j,aj,(ai[row]+nrow)*sizeof(int));CHKERRQ(ierr);
90392c4ed94SBarry Smith         len  = (new_nz - CHUNKSIZE - ai[row] - nrow);
904549d3d68SSatish Balay         ierr = PetscMemcpy(new_j+ai[row]+nrow+CHUNKSIZE,aj+ai[row]+nrow,len*sizeof(int));CHKERRQ(ierr);
905549d3d68SSatish Balay         ierr = PetscMemcpy(new_a,aa,(ai[row]+nrow)*bs2*sizeof(MatScalar));CHKERRQ(ierr);
906549d3d68SSatish Balay         ierr = PetscMemzero(new_a+bs2*(ai[row]+nrow),bs2*CHUNKSIZE*sizeof(MatScalar));CHKERRQ(ierr);
907549d3d68SSatish Balay         ierr = PetscMemcpy(new_a+bs2*(ai[row]+nrow+CHUNKSIZE),aa+bs2*(ai[row]+nrow),bs2*len*sizeof(MatScalar));CHKERRQ(ierr);
90892c4ed94SBarry Smith         /* free up old matrix storage */
909606d414cSSatish Balay         ierr = PetscFree(a->a);CHKERRQ(ierr);
910606d414cSSatish Balay         if (!a->singlemalloc) {
911606d414cSSatish Balay           ierr = PetscFree(a->i);CHKERRQ(ierr);
912606d414cSSatish Balay           ierr = PetscFree(a->j);CHKERRQ(ierr);
913606d414cSSatish Balay         }
91492c4ed94SBarry Smith         aa = a->a = new_a; ai = a->i = new_i; aj = a->j = new_j;
915c4992f7dSBarry Smith         a->singlemalloc = PETSC_TRUE;
91692c4ed94SBarry Smith 
91792c4ed94SBarry Smith         rp   = aj + ai[row]; ap = aa + bs2*ai[row];
91892c4ed94SBarry Smith         rmax = imax[row] = imax[row] + CHUNKSIZE;
919b0a32e0cSBarry Smith         PetscLogObjectMemory(A,CHUNKSIZE*(sizeof(int) + bs2*sizeof(MatScalar)));
92092c4ed94SBarry Smith         a->maxnz += bs2*CHUNKSIZE;
92192c4ed94SBarry Smith         a->reallocs++;
92292c4ed94SBarry Smith         a->nz++;
92392c4ed94SBarry Smith       }
92492c4ed94SBarry Smith       N = nrow++ - 1;
92592c4ed94SBarry Smith       /* shift up all the later entries in this row */
92692c4ed94SBarry Smith       for (ii=N; ii>=i; ii--) {
92792c4ed94SBarry Smith         rp[ii+1] = rp[ii];
928549d3d68SSatish Balay         ierr = PetscMemcpy(ap+bs2*(ii+1),ap+bs2*(ii),bs2*sizeof(MatScalar));CHKERRQ(ierr);
92992c4ed94SBarry Smith       }
930549d3d68SSatish Balay       if (N >= i) {
931549d3d68SSatish Balay         ierr = PetscMemzero(ap+bs2*i,bs2*sizeof(MatScalar));CHKERRQ(ierr);
932549d3d68SSatish Balay       }
93392c4ed94SBarry Smith       rp[i] = col;
9348a84c255SSatish Balay       bap   = ap +  bs2*i;
9350e324ae4SSatish Balay       if (roworiented) {
936dd9472c6SBarry Smith         for (ii=0; ii<bs; ii++,value+=stepval) {
937dd9472c6SBarry Smith           for (jj=ii; jj<bs2; jj+=bs) {
9380e324ae4SSatish Balay             bap[jj] = *value++;
939dd9472c6SBarry Smith           }
940dd9472c6SBarry Smith         }
9410e324ae4SSatish Balay       } else {
942dd9472c6SBarry Smith         for (ii=0; ii<bs; ii++,value+=stepval) {
943dd9472c6SBarry Smith           for (jj=0; jj<bs; jj++) {
9440e324ae4SSatish Balay             *bap++  = *value++;
9450e324ae4SSatish Balay           }
946dd9472c6SBarry Smith         }
947dd9472c6SBarry Smith       }
948f1241b54SBarry Smith       noinsert2:;
94992c4ed94SBarry Smith       low = i;
95092c4ed94SBarry Smith     }
95192c4ed94SBarry Smith     ailen[row] = nrow;
95292c4ed94SBarry Smith   }
9533a40ed3dSBarry Smith   PetscFunctionReturn(0);
95492c4ed94SBarry Smith }
95592c4ed94SBarry Smith 
9564a2ae208SSatish Balay #undef __FUNCT__
9574a2ae208SSatish Balay #define __FUNCT__ "MatAssemblyEnd_SeqBAIJ"
9588f6be9afSLois Curfman McInnes int MatAssemblyEnd_SeqBAIJ(Mat A,MatAssemblyType mode)
959584200bdSSatish Balay {
960584200bdSSatish Balay   Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)A->data;
961584200bdSSatish Balay   int        fshift = 0,i,j,*ai = a->i,*aj = a->j,*imax = a->imax;
962273d9f13SBarry Smith   int        m = A->m,*ip,N,*ailen = a->ilen;
963549d3d68SSatish Balay   int        mbs = a->mbs,bs2 = a->bs2,rmax = 0,ierr;
9643f1db9ecSBarry Smith   MatScalar  *aa = a->a,*ap;
965584200bdSSatish Balay 
9663a40ed3dSBarry Smith   PetscFunctionBegin;
9673a40ed3dSBarry Smith   if (mode == MAT_FLUSH_ASSEMBLY) PetscFunctionReturn(0);
968584200bdSSatish Balay 
96943ee02c3SBarry Smith   if (m) rmax = ailen[0];
970584200bdSSatish Balay   for (i=1; i<mbs; i++) {
971584200bdSSatish Balay     /* move each row back by the amount of empty slots (fshift) before it*/
972584200bdSSatish Balay     fshift += imax[i-1] - ailen[i-1];
973d402145bSBarry Smith     rmax   = PetscMax(rmax,ailen[i]);
974584200bdSSatish Balay     if (fshift) {
975a7c10996SSatish Balay       ip = aj + ai[i]; ap = aa + bs2*ai[i];
976584200bdSSatish Balay       N = ailen[i];
977584200bdSSatish Balay       for (j=0; j<N; j++) {
978584200bdSSatish Balay         ip[j-fshift] = ip[j];
979549d3d68SSatish Balay         ierr = PetscMemcpy(ap+(j-fshift)*bs2,ap+j*bs2,bs2*sizeof(MatScalar));CHKERRQ(ierr);
980584200bdSSatish Balay       }
981584200bdSSatish Balay     }
982584200bdSSatish Balay     ai[i] = ai[i-1] + ailen[i-1];
983584200bdSSatish Balay   }
984584200bdSSatish Balay   if (mbs) {
985584200bdSSatish Balay     fshift += imax[mbs-1] - ailen[mbs-1];
986584200bdSSatish Balay     ai[mbs] = ai[mbs-1] + ailen[mbs-1];
987584200bdSSatish Balay   }
988584200bdSSatish Balay   /* reset ilen and imax for each row */
989584200bdSSatish Balay   for (i=0; i<mbs; i++) {
990584200bdSSatish Balay     ailen[i] = imax[i] = ai[i+1] - ai[i];
991584200bdSSatish Balay   }
992a7c10996SSatish Balay   a->nz = ai[mbs];
993584200bdSSatish Balay 
994584200bdSSatish Balay   /* diagonals may have moved, so kill the diagonal pointers */
995584200bdSSatish Balay   if (fshift && a->diag) {
996606d414cSSatish Balay     ierr = PetscFree(a->diag);CHKERRQ(ierr);
997b424e231SHong Zhang     PetscLogObjectMemory(A,-(mbs+1)*sizeof(int));
998584200bdSSatish Balay     a->diag = 0;
999584200bdSSatish Balay   }
1000bba1ac68SSatish Balay   PetscLogInfo(A,"MatAssemblyEnd_SeqBAIJ:Matrix size: %d X %d, block size %d; storage space: %d unneeded, %d used\n",m,A->n,a->bs,fshift*bs2,a->nz*bs2);
1001bba1ac68SSatish Balay   PetscLogInfo(A,"MatAssemblyEnd_SeqBAIJ:Number of mallocs during MatSetValues is %d\n",a->reallocs);
1002b0a32e0cSBarry Smith   PetscLogInfo(A,"MatAssemblyEnd_SeqBAIJ:Most nonzeros blocks in any row is %d\n",rmax);
1003e2f3b5e9SSatish Balay   a->reallocs          = 0;
10040e6d2581SBarry Smith   A->info.nz_unneeded  = (PetscReal)fshift*bs2;
1005cf4441caSHong Zhang 
10063a40ed3dSBarry Smith   PetscFunctionReturn(0);
1007584200bdSSatish Balay }
1008584200bdSSatish Balay 
10095a838052SSatish Balay 
1010bea157c4SSatish Balay 
1011bea157c4SSatish Balay /*
1012bea157c4SSatish Balay    This function returns an array of flags which indicate the locations of contiguous
1013bea157c4SSatish Balay    blocks that should be zeroed. for eg: if bs = 3  and is = [0,1,2,3,5,6,7,8,9]
1014bea157c4SSatish Balay    then the resulting sizes = [3,1,1,3,1] correspondig to sets [(0,1,2),(3),(5),(6,7,8),(9)]
1015bea157c4SSatish Balay    Assume: sizes should be long enough to hold all the values.
1016bea157c4SSatish Balay */
10174a2ae208SSatish Balay #undef __FUNCT__
10184a2ae208SSatish Balay #define __FUNCT__ "MatZeroRows_SeqBAIJ_Check_Blocks"
1019bea157c4SSatish Balay static int MatZeroRows_SeqBAIJ_Check_Blocks(int idx[],int n,int bs,int sizes[], int *bs_max)
1020d9b7c43dSSatish Balay {
1021bea157c4SSatish Balay   int        i,j,k,row;
1022bea157c4SSatish Balay   PetscTruth flg;
10233a40ed3dSBarry Smith 
1024433994e6SBarry Smith   PetscFunctionBegin;
1025bea157c4SSatish Balay   for (i=0,j=0; i<n; j++) {
1026bea157c4SSatish Balay     row = idx[i];
1027bea157c4SSatish Balay     if (row%bs!=0) { /* Not the begining of a block */
1028bea157c4SSatish Balay       sizes[j] = 1;
1029bea157c4SSatish Balay       i++;
1030e4fda26cSSatish Balay     } else if (i+bs > n) { /* complete block doesn't exist (at idx end) */
1031bea157c4SSatish Balay       sizes[j] = 1;         /* Also makes sure atleast 'bs' values exist for next else */
1032bea157c4SSatish Balay       i++;
1033bea157c4SSatish Balay     } else { /* Begining of the block, so check if the complete block exists */
1034bea157c4SSatish Balay       flg = PETSC_TRUE;
1035bea157c4SSatish Balay       for (k=1; k<bs; k++) {
1036bea157c4SSatish Balay         if (row+k != idx[i+k]) { /* break in the block */
1037bea157c4SSatish Balay           flg = PETSC_FALSE;
1038bea157c4SSatish Balay           break;
1039d9b7c43dSSatish Balay         }
1040bea157c4SSatish Balay       }
1041bea157c4SSatish Balay       if (flg == PETSC_TRUE) { /* No break in the bs */
1042bea157c4SSatish Balay         sizes[j] = bs;
1043bea157c4SSatish Balay         i+= bs;
1044bea157c4SSatish Balay       } else {
1045bea157c4SSatish Balay         sizes[j] = 1;
1046bea157c4SSatish Balay         i++;
1047bea157c4SSatish Balay       }
1048bea157c4SSatish Balay     }
1049bea157c4SSatish Balay   }
1050bea157c4SSatish Balay   *bs_max = j;
10513a40ed3dSBarry Smith   PetscFunctionReturn(0);
1052d9b7c43dSSatish Balay }
1053d9b7c43dSSatish Balay 
10544a2ae208SSatish Balay #undef __FUNCT__
10554a2ae208SSatish Balay #define __FUNCT__ "MatZeroRows_SeqBAIJ"
1056268466fbSBarry Smith int MatZeroRows_SeqBAIJ(Mat A,IS is,const PetscScalar *diag)
1057d9b7c43dSSatish Balay {
1058d9b7c43dSSatish Balay   Mat_SeqBAIJ *baij=(Mat_SeqBAIJ*)A->data;
1059b6815fffSBarry Smith   int         ierr,i,j,k,count,is_n,*is_idx,*rows;
1060bea157c4SSatish Balay   int         bs=baij->bs,bs2=baij->bs2,*sizes,row,bs_max;
106187828ca2SBarry Smith   PetscScalar zero = 0.0;
10623f1db9ecSBarry Smith   MatScalar   *aa;
1063d9b7c43dSSatish Balay 
10643a40ed3dSBarry Smith   PetscFunctionBegin;
1065d9b7c43dSSatish Balay   /* Make a copy of the IS and  sort it */
1066b9b97703SBarry Smith   ierr = ISGetLocalSize(is,&is_n);CHKERRQ(ierr);
1067d9b7c43dSSatish Balay   ierr = ISGetIndices(is,&is_idx);CHKERRQ(ierr);
1068d9b7c43dSSatish Balay 
1069bea157c4SSatish Balay   /* allocate memory for rows,sizes */
1070b0a32e0cSBarry Smith   ierr  = PetscMalloc((3*is_n+1)*sizeof(int),&rows);CHKERRQ(ierr);
1071bea157c4SSatish Balay   sizes = rows + is_n;
1072bea157c4SSatish Balay 
1073563b5814SBarry Smith   /* copy IS values to rows, and sort them */
1074bea157c4SSatish Balay   for (i=0; i<is_n; i++) { rows[i] = is_idx[i]; }
1075bea157c4SSatish Balay   ierr = PetscSortInt(is_n,rows);CHKERRQ(ierr);
1076dffd3267SBarry Smith   if (baij->keepzeroedrows) {
1077dffd3267SBarry Smith     for (i=0; i<is_n; i++) { sizes[i] = 1; }
1078dffd3267SBarry Smith     bs_max = is_n;
1079dffd3267SBarry Smith   } else {
1080bea157c4SSatish Balay     ierr = MatZeroRows_SeqBAIJ_Check_Blocks(rows,is_n,bs,sizes,&bs_max);CHKERRQ(ierr);
1081dffd3267SBarry Smith   }
1082b97a56abSSatish Balay   ierr = ISRestoreIndices(is,&is_idx);CHKERRQ(ierr);
1083bea157c4SSatish Balay 
1084bea157c4SSatish Balay   for (i=0,j=0; i<bs_max; j+=sizes[i],i++) {
1085bea157c4SSatish Balay     row   = rows[j];
1086273d9f13SBarry Smith     if (row < 0 || row > A->m) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"row %d out of range",row);
1087bea157c4SSatish Balay     count = (baij->i[row/bs +1] - baij->i[row/bs])*bs;
1088bea157c4SSatish Balay     aa    = baij->a + baij->i[row/bs]*bs2 + (row%bs);
1089dffd3267SBarry Smith     if (sizes[i] == bs && !baij->keepzeroedrows) {
1090bea157c4SSatish Balay       if (diag) {
1091bea157c4SSatish Balay         if (baij->ilen[row/bs] > 0) {
1092bea157c4SSatish Balay           baij->ilen[row/bs]       = 1;
1093bea157c4SSatish Balay           baij->j[baij->i[row/bs]] = row/bs;
1094bea157c4SSatish Balay           ierr = PetscMemzero(aa,count*bs*sizeof(MatScalar));CHKERRQ(ierr);
1095a07cd24cSSatish Balay         }
1096563b5814SBarry Smith         /* Now insert all the diagonal values for this bs */
1097bea157c4SSatish Balay         for (k=0; k<bs; k++) {
1098bea157c4SSatish Balay           ierr = (*A->ops->setvalues)(A,1,rows+j+k,1,rows+j+k,diag,INSERT_VALUES);CHKERRQ(ierr);
1099bea157c4SSatish Balay         }
1100bea157c4SSatish Balay       } else { /* (!diag) */
1101bea157c4SSatish Balay         baij->ilen[row/bs] = 0;
1102bea157c4SSatish Balay       } /* end (!diag) */
1103bea157c4SSatish Balay     } else { /* (sizes[i] != bs) */
1104aa482453SBarry Smith #if defined (PETSC_USE_DEBUG)
110529bbc08cSBarry Smith       if (sizes[i] != 1) SETERRQ(1,"Internal Error. Value should be 1");
1106bea157c4SSatish Balay #endif
1107bea157c4SSatish Balay       for (k=0; k<count; k++) {
1108d9b7c43dSSatish Balay         aa[0] =  zero;
1109d9b7c43dSSatish Balay         aa    += bs;
1110d9b7c43dSSatish Balay       }
1111d9b7c43dSSatish Balay       if (diag) {
1112f830108cSBarry Smith         ierr = (*A->ops->setvalues)(A,1,rows+j,1,rows+j,diag,INSERT_VALUES);CHKERRQ(ierr);
1113d9b7c43dSSatish Balay       }
1114d9b7c43dSSatish Balay     }
1115bea157c4SSatish Balay   }
1116bea157c4SSatish Balay 
1117606d414cSSatish Balay   ierr = PetscFree(rows);CHKERRQ(ierr);
11189a8dea36SBarry Smith   ierr = MatAssemblyEnd_SeqBAIJ(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
11193a40ed3dSBarry Smith   PetscFunctionReturn(0);
1120d9b7c43dSSatish Balay }
11211c351548SSatish Balay 
11224a2ae208SSatish Balay #undef __FUNCT__
11234a2ae208SSatish Balay #define __FUNCT__ "MatSetValues_SeqBAIJ"
1124f15d580aSBarry Smith int MatSetValues_SeqBAIJ(Mat A,int m,const int im[],int n,const int in[],const PetscScalar v[],InsertMode is)
11252d61bbb3SSatish Balay {
11262d61bbb3SSatish Balay   Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)A->data;
11272d61bbb3SSatish Balay   int         *rp,k,low,high,t,ii,row,nrow,i,col,l,rmax,N,sorted=a->sorted;
1128273d9f13SBarry Smith   int         *imax=a->imax,*ai=a->i,*ailen=a->ilen;
11292d61bbb3SSatish Balay   int         *aj=a->j,nonew=a->nonew,bs=a->bs,brow,bcol;
1130549d3d68SSatish Balay   int         ridx,cidx,bs2=a->bs2,ierr;
1131273d9f13SBarry Smith   PetscTruth  roworiented=a->roworiented;
11323f1db9ecSBarry Smith   MatScalar   *ap,value,*aa=a->a,*bap;
11332d61bbb3SSatish Balay 
11342d61bbb3SSatish Balay   PetscFunctionBegin;
11352d61bbb3SSatish Balay   for (k=0; k<m; k++) { /* loop over added rows */
11362d61bbb3SSatish Balay     row  = im[k]; brow = row/bs;
11375ef9f2a5SBarry Smith     if (row < 0) continue;
1138aa482453SBarry Smith #if defined(PETSC_USE_BOPT_g)
1139590ac198SBarry Smith     if (row >= A->m) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"Row too large: row %d max %d",row,A->m-1);
11402d61bbb3SSatish Balay #endif
11412d61bbb3SSatish Balay     rp   = aj + ai[brow];
11422d61bbb3SSatish Balay     ap   = aa + bs2*ai[brow];
11432d61bbb3SSatish Balay     rmax = imax[brow];
11442d61bbb3SSatish Balay     nrow = ailen[brow];
11452d61bbb3SSatish Balay     low  = 0;
11462d61bbb3SSatish Balay     for (l=0; l<n; l++) { /* loop over added columns */
11475ef9f2a5SBarry Smith       if (in[l] < 0) continue;
1148aa482453SBarry Smith #if defined(PETSC_USE_BOPT_g)
1149590ac198SBarry Smith       if (in[l] >= A->n) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"Column too large: col %d max %d",in[l],A->n-1);
11502d61bbb3SSatish Balay #endif
11512d61bbb3SSatish Balay       col = in[l]; bcol = col/bs;
11522d61bbb3SSatish Balay       ridx = row % bs; cidx = col % bs;
11532d61bbb3SSatish Balay       if (roworiented) {
11545ef9f2a5SBarry Smith         value = v[l + k*n];
11552d61bbb3SSatish Balay       } else {
11562d61bbb3SSatish Balay         value = v[k + l*m];
11572d61bbb3SSatish Balay       }
11582d61bbb3SSatish Balay       if (!sorted) low = 0; high = nrow;
11592d61bbb3SSatish Balay       while (high-low > 7) {
11602d61bbb3SSatish Balay         t = (low+high)/2;
11612d61bbb3SSatish Balay         if (rp[t] > bcol) high = t;
11622d61bbb3SSatish Balay         else              low  = t;
11632d61bbb3SSatish Balay       }
11642d61bbb3SSatish Balay       for (i=low; i<high; i++) {
11652d61bbb3SSatish Balay         if (rp[i] > bcol) break;
11662d61bbb3SSatish Balay         if (rp[i] == bcol) {
11672d61bbb3SSatish Balay           bap  = ap +  bs2*i + bs*cidx + ridx;
11682d61bbb3SSatish Balay           if (is == ADD_VALUES) *bap += value;
11692d61bbb3SSatish Balay           else                  *bap  = value;
11702d61bbb3SSatish Balay           goto noinsert1;
11712d61bbb3SSatish Balay         }
11722d61bbb3SSatish Balay       }
11732d61bbb3SSatish Balay       if (nonew == 1) goto noinsert1;
1174*a45adfd6SMatthew Knepley       else if (nonew == -1) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"Inserting a new nonzero (%d, %d) in the matrix", row, col);
11752d61bbb3SSatish Balay       if (nrow >= rmax) {
11762d61bbb3SSatish Balay         /* there is no extra room in row, therefore enlarge */
11772d61bbb3SSatish Balay         int       new_nz = ai[a->mbs] + CHUNKSIZE,len,*new_i,*new_j;
11783f1db9ecSBarry Smith         MatScalar *new_a;
11792d61bbb3SSatish Balay 
1180*a45adfd6SMatthew Knepley         if (nonew == -2) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"Inserting a new nonzero (%d, %d) in the matrix", row, col);
11812d61bbb3SSatish Balay 
11822d61bbb3SSatish Balay         /* Malloc new storage space */
11833f1db9ecSBarry Smith         len     = new_nz*(sizeof(int)+bs2*sizeof(MatScalar))+(a->mbs+1)*sizeof(int);
1184b0a32e0cSBarry Smith 	ierr    = PetscMalloc(len,&new_a);CHKERRQ(ierr);
11852d61bbb3SSatish Balay         new_j   = (int*)(new_a + bs2*new_nz);
11862d61bbb3SSatish Balay         new_i   = new_j + new_nz;
11872d61bbb3SSatish Balay 
11882d61bbb3SSatish Balay         /* copy over old data into new slots */
11892d61bbb3SSatish Balay         for (ii=0; ii<brow+1; ii++) {new_i[ii] = ai[ii];}
11902d61bbb3SSatish Balay         for (ii=brow+1; ii<a->mbs+1; ii++) {new_i[ii] = ai[ii]+CHUNKSIZE;}
1191549d3d68SSatish Balay         ierr = PetscMemcpy(new_j,aj,(ai[brow]+nrow)*sizeof(int));CHKERRQ(ierr);
11922d61bbb3SSatish Balay         len  = (new_nz - CHUNKSIZE - ai[brow] - nrow);
1193549d3d68SSatish Balay         ierr = PetscMemcpy(new_j+ai[brow]+nrow+CHUNKSIZE,aj+ai[brow]+nrow,len*sizeof(int));CHKERRQ(ierr);
1194549d3d68SSatish Balay         ierr = PetscMemcpy(new_a,aa,(ai[brow]+nrow)*bs2*sizeof(MatScalar));CHKERRQ(ierr);
1195549d3d68SSatish Balay         ierr = PetscMemzero(new_a+bs2*(ai[brow]+nrow),bs2*CHUNKSIZE*sizeof(MatScalar));CHKERRQ(ierr);
1196549d3d68SSatish Balay         ierr = PetscMemcpy(new_a+bs2*(ai[brow]+nrow+CHUNKSIZE),aa+bs2*(ai[brow]+nrow),bs2*len*sizeof(MatScalar));CHKERRQ(ierr);
11972d61bbb3SSatish Balay         /* free up old matrix storage */
1198606d414cSSatish Balay         ierr = PetscFree(a->a);CHKERRQ(ierr);
1199606d414cSSatish Balay         if (!a->singlemalloc) {
1200606d414cSSatish Balay           ierr = PetscFree(a->i);CHKERRQ(ierr);
1201606d414cSSatish Balay           ierr = PetscFree(a->j);CHKERRQ(ierr);
1202606d414cSSatish Balay         }
12032d61bbb3SSatish Balay         aa = a->a = new_a; ai = a->i = new_i; aj = a->j = new_j;
1204c4992f7dSBarry Smith         a->singlemalloc = PETSC_TRUE;
12052d61bbb3SSatish Balay 
12062d61bbb3SSatish Balay         rp   = aj + ai[brow]; ap = aa + bs2*ai[brow];
12072d61bbb3SSatish Balay         rmax = imax[brow] = imax[brow] + CHUNKSIZE;
1208b0a32e0cSBarry Smith         PetscLogObjectMemory(A,CHUNKSIZE*(sizeof(int) + bs2*sizeof(MatScalar)));
12092d61bbb3SSatish Balay         a->maxnz += bs2*CHUNKSIZE;
12102d61bbb3SSatish Balay         a->reallocs++;
12112d61bbb3SSatish Balay         a->nz++;
12122d61bbb3SSatish Balay       }
12132d61bbb3SSatish Balay       N = nrow++ - 1;
12142d61bbb3SSatish Balay       /* shift up all the later entries in this row */
12152d61bbb3SSatish Balay       for (ii=N; ii>=i; ii--) {
12162d61bbb3SSatish Balay         rp[ii+1] = rp[ii];
1217549d3d68SSatish Balay         ierr     = PetscMemcpy(ap+bs2*(ii+1),ap+bs2*(ii),bs2*sizeof(MatScalar));CHKERRQ(ierr);
12182d61bbb3SSatish Balay       }
1219549d3d68SSatish Balay       if (N>=i) {
1220549d3d68SSatish Balay         ierr = PetscMemzero(ap+bs2*i,bs2*sizeof(MatScalar));CHKERRQ(ierr);
1221549d3d68SSatish Balay       }
12222d61bbb3SSatish Balay       rp[i]                      = bcol;
12232d61bbb3SSatish Balay       ap[bs2*i + bs*cidx + ridx] = value;
12242d61bbb3SSatish Balay       noinsert1:;
12252d61bbb3SSatish Balay       low = i;
12262d61bbb3SSatish Balay     }
12272d61bbb3SSatish Balay     ailen[brow] = nrow;
12282d61bbb3SSatish Balay   }
12292d61bbb3SSatish Balay   PetscFunctionReturn(0);
12302d61bbb3SSatish Balay }
12312d61bbb3SSatish Balay 
12322d61bbb3SSatish Balay 
12334a2ae208SSatish Balay #undef __FUNCT__
12344a2ae208SSatish Balay #define __FUNCT__ "MatILUFactor_SeqBAIJ"
1235b380c88cSHong Zhang int MatILUFactor_SeqBAIJ(Mat inA,IS row,IS col,MatFactorInfo *info)
12362d61bbb3SSatish Balay {
12372d61bbb3SSatish Balay   Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)inA->data;
12382d61bbb3SSatish Balay   Mat         outA;
12392d61bbb3SSatish Balay   int         ierr;
1240667159a5SBarry Smith   PetscTruth  row_identity,col_identity;
12412d61bbb3SSatish Balay 
12422d61bbb3SSatish Balay   PetscFunctionBegin;
1243d3d32019SBarry Smith   if (info->levels != 0) SETERRQ(PETSC_ERR_SUP,"Only levels = 0 supported for in-place ILU");
1244667159a5SBarry Smith   ierr = ISIdentity(row,&row_identity);CHKERRQ(ierr);
1245667159a5SBarry Smith   ierr = ISIdentity(col,&col_identity);CHKERRQ(ierr);
1246667159a5SBarry Smith   if (!row_identity || !col_identity) {
124729bbc08cSBarry Smith     SETERRQ(1,"Row and column permutations must be identity for in-place ILU");
1248667159a5SBarry Smith   }
12492d61bbb3SSatish Balay 
12502d61bbb3SSatish Balay   outA          = inA;
12512d61bbb3SSatish Balay   inA->factor   = FACTOR_LU;
12522d61bbb3SSatish Balay 
12532d61bbb3SSatish Balay   if (!a->diag) {
1254c4992f7dSBarry Smith     ierr = MatMarkDiagonal_SeqBAIJ(inA);CHKERRQ(ierr);
12552d61bbb3SSatish Balay   }
1256cf242676SKris Buschelman 
1257c38d4ed2SBarry Smith   a->row        = row;
1258c38d4ed2SBarry Smith   a->col        = col;
1259c38d4ed2SBarry Smith   ierr          = PetscObjectReference((PetscObject)row);CHKERRQ(ierr);
1260c38d4ed2SBarry Smith   ierr          = PetscObjectReference((PetscObject)col);CHKERRQ(ierr);
1261c38d4ed2SBarry Smith 
1262c38d4ed2SBarry Smith   /* Create the invert permutation so that it can be used in MatLUFactorNumeric() */
12634c49b128SBarry Smith   ierr = ISInvertPermutation(col,PETSC_DECIDE,&a->icol);CHKERRQ(ierr);
1264b0a32e0cSBarry Smith   PetscLogObjectParent(inA,a->icol);
1265c38d4ed2SBarry Smith 
1266cf242676SKris Buschelman   /*
1267cf242676SKris Buschelman       Blocksize 2, 3, 4, 5, 6 and 7 have a special faster factorization/solver
1268cf242676SKris Buschelman       for ILU(0) factorization with natural ordering
1269cf242676SKris Buschelman   */
1270cf242676SKris Buschelman   if (a->bs < 8) {
1271cf242676SKris Buschelman     ierr = MatSeqBAIJ_UpdateFactorNumeric_NaturalOrdering(inA);CHKERRQ(ierr);
1272cf242676SKris Buschelman   } else {
1273c38d4ed2SBarry Smith     if (!a->solve_work) {
127487828ca2SBarry Smith       ierr = PetscMalloc((inA->m+a->bs)*sizeof(PetscScalar),&a->solve_work);CHKERRQ(ierr);
127587828ca2SBarry Smith       PetscLogObjectMemory(inA,(inA->m+a->bs)*sizeof(PetscScalar));
1276c38d4ed2SBarry Smith     }
12772d61bbb3SSatish Balay   }
12782d61bbb3SSatish Balay 
1279667159a5SBarry Smith   ierr = MatLUFactorNumeric(inA,&outA);CHKERRQ(ierr);
1280667159a5SBarry Smith 
12812d61bbb3SSatish Balay   PetscFunctionReturn(0);
12822d61bbb3SSatish Balay }
12834a2ae208SSatish Balay #undef __FUNCT__
12844a2ae208SSatish Balay #define __FUNCT__ "MatPrintHelp_SeqBAIJ"
1285ba4ca20aSSatish Balay int MatPrintHelp_SeqBAIJ(Mat A)
1286ba4ca20aSSatish Balay {
1287c38d4ed2SBarry Smith   static PetscTruth called = PETSC_FALSE;
1288ba4ca20aSSatish Balay   MPI_Comm          comm = A->comm;
1289d132466eSBarry Smith   int               ierr;
1290ba4ca20aSSatish Balay 
12913a40ed3dSBarry Smith   PetscFunctionBegin;
1292c38d4ed2SBarry Smith   if (called) {PetscFunctionReturn(0);} else called = PETSC_TRUE;
1293d132466eSBarry Smith   ierr = (*PetscHelpPrintf)(comm," Options for MATSEQBAIJ and MATMPIBAIJ matrix formats (the defaults):\n");CHKERRQ(ierr);
1294d132466eSBarry Smith   ierr = (*PetscHelpPrintf)(comm,"  -mat_block_size <block_size>\n");CHKERRQ(ierr);
12953a40ed3dSBarry Smith   PetscFunctionReturn(0);
1296ba4ca20aSSatish Balay }
1297d9b7c43dSSatish Balay 
1298fb2e594dSBarry Smith EXTERN_C_BEGIN
12994a2ae208SSatish Balay #undef __FUNCT__
13004a2ae208SSatish Balay #define __FUNCT__ "MatSeqBAIJSetColumnIndices_SeqBAIJ"
130127a8da17SBarry Smith int MatSeqBAIJSetColumnIndices_SeqBAIJ(Mat mat,int *indices)
130227a8da17SBarry Smith {
130327a8da17SBarry Smith   Mat_SeqBAIJ *baij = (Mat_SeqBAIJ *)mat->data;
130414db4f74SSatish Balay   int         i,nz,nbs;
130527a8da17SBarry Smith 
130627a8da17SBarry Smith   PetscFunctionBegin;
130714db4f74SSatish Balay   nz  = baij->maxnz/baij->bs2;
130814db4f74SSatish Balay   nbs = baij->nbs;
130927a8da17SBarry Smith   for (i=0; i<nz; i++) {
131027a8da17SBarry Smith     baij->j[i] = indices[i];
131127a8da17SBarry Smith   }
131227a8da17SBarry Smith   baij->nz = nz;
131314db4f74SSatish Balay   for (i=0; i<nbs; i++) {
131427a8da17SBarry Smith     baij->ilen[i] = baij->imax[i];
131527a8da17SBarry Smith   }
131627a8da17SBarry Smith 
131727a8da17SBarry Smith   PetscFunctionReturn(0);
131827a8da17SBarry Smith }
1319fb2e594dSBarry Smith EXTERN_C_END
132027a8da17SBarry Smith 
13214a2ae208SSatish Balay #undef __FUNCT__
13224a2ae208SSatish Balay #define __FUNCT__ "MatSeqBAIJSetColumnIndices"
132327a8da17SBarry Smith /*@
132427a8da17SBarry Smith     MatSeqBAIJSetColumnIndices - Set the column indices for all the rows
132527a8da17SBarry Smith        in the matrix.
132627a8da17SBarry Smith 
132727a8da17SBarry Smith   Input Parameters:
132827a8da17SBarry Smith +  mat - the SeqBAIJ matrix
132927a8da17SBarry Smith -  indices - the column indices
133027a8da17SBarry Smith 
133115091d37SBarry Smith   Level: advanced
133215091d37SBarry Smith 
133327a8da17SBarry Smith   Notes:
133427a8da17SBarry Smith     This can be called if you have precomputed the nonzero structure of the
133527a8da17SBarry Smith   matrix and want to provide it to the matrix object to improve the performance
133627a8da17SBarry Smith   of the MatSetValues() operation.
133727a8da17SBarry Smith 
133827a8da17SBarry Smith     You MUST have set the correct numbers of nonzeros per row in the call to
133927a8da17SBarry Smith   MatCreateSeqBAIJ().
134027a8da17SBarry Smith 
134127a8da17SBarry Smith     MUST be called before any calls to MatSetValues();
134227a8da17SBarry Smith 
134327a8da17SBarry Smith @*/
134427a8da17SBarry Smith int MatSeqBAIJSetColumnIndices(Mat mat,int *indices)
134527a8da17SBarry Smith {
134627a8da17SBarry Smith   int ierr,(*f)(Mat,int *);
134727a8da17SBarry Smith 
134827a8da17SBarry Smith   PetscFunctionBegin;
134927a8da17SBarry Smith   PetscValidHeaderSpecific(mat,MAT_COOKIE);
1350c134de8dSSatish Balay   ierr = PetscObjectQueryFunction((PetscObject)mat,"MatSeqBAIJSetColumnIndices_C",(void (**)(void))&f);CHKERRQ(ierr);
135127a8da17SBarry Smith   if (f) {
135227a8da17SBarry Smith     ierr = (*f)(mat,indices);CHKERRQ(ierr);
135327a8da17SBarry Smith   } else {
135429bbc08cSBarry Smith     SETERRQ(1,"Wrong type of matrix to set column indices");
135527a8da17SBarry Smith   }
135627a8da17SBarry Smith   PetscFunctionReturn(0);
135727a8da17SBarry Smith }
135827a8da17SBarry Smith 
13594a2ae208SSatish Balay #undef __FUNCT__
13604a2ae208SSatish Balay #define __FUNCT__ "MatGetRowMax_SeqBAIJ"
1361273d9f13SBarry Smith int MatGetRowMax_SeqBAIJ(Mat A,Vec v)
1362273d9f13SBarry Smith {
1363273d9f13SBarry Smith   Mat_SeqBAIJ  *a = (Mat_SeqBAIJ*)A->data;
1364273d9f13SBarry Smith   int          ierr,i,j,n,row,bs,*ai,*aj,mbs;
1365273d9f13SBarry Smith   PetscReal    atmp;
136687828ca2SBarry Smith   PetscScalar  *x,zero = 0.0;
1367273d9f13SBarry Smith   MatScalar    *aa;
1368273d9f13SBarry Smith   int          ncols,brow,krow,kcol;
1369273d9f13SBarry Smith 
1370273d9f13SBarry Smith   PetscFunctionBegin;
1371273d9f13SBarry Smith   if (A->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1372273d9f13SBarry Smith   bs   = a->bs;
1373273d9f13SBarry Smith   aa   = a->a;
1374273d9f13SBarry Smith   ai   = a->i;
1375273d9f13SBarry Smith   aj   = a->j;
1376273d9f13SBarry Smith   mbs = a->mbs;
1377273d9f13SBarry Smith 
1378273d9f13SBarry Smith   ierr = VecSet(&zero,v);CHKERRQ(ierr);
1379273d9f13SBarry Smith   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
1380273d9f13SBarry Smith   ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr);
1381273d9f13SBarry Smith   if (n != A->m) SETERRQ(PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector");
1382273d9f13SBarry Smith   for (i=0; i<mbs; i++) {
1383273d9f13SBarry Smith     ncols = ai[1] - ai[0]; ai++;
1384273d9f13SBarry Smith     brow  = bs*i;
1385273d9f13SBarry Smith     for (j=0; j<ncols; j++){
1386273d9f13SBarry Smith       /* bcol = bs*(*aj); */
1387273d9f13SBarry Smith       for (kcol=0; kcol<bs; kcol++){
1388273d9f13SBarry Smith         for (krow=0; krow<bs; krow++){
1389273d9f13SBarry Smith           atmp = PetscAbsScalar(*aa); aa++;
1390273d9f13SBarry Smith           row = brow + krow;    /* row index */
1391273d9f13SBarry Smith           /* printf("val[%d,%d]: %g\n",row,bcol+kcol,atmp); */
1392273d9f13SBarry Smith           if (PetscAbsScalar(x[row]) < atmp) x[row] = atmp;
1393273d9f13SBarry Smith         }
1394273d9f13SBarry Smith       }
1395273d9f13SBarry Smith       aj++;
1396273d9f13SBarry Smith     }
1397273d9f13SBarry Smith   }
1398273d9f13SBarry Smith   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
1399273d9f13SBarry Smith   PetscFunctionReturn(0);
1400273d9f13SBarry Smith }
1401273d9f13SBarry Smith 
14024a2ae208SSatish Balay #undef __FUNCT__
14034a2ae208SSatish Balay #define __FUNCT__ "MatSetUpPreallocation_SeqBAIJ"
1404273d9f13SBarry Smith int MatSetUpPreallocation_SeqBAIJ(Mat A)
1405273d9f13SBarry Smith {
1406273d9f13SBarry Smith   int        ierr;
1407273d9f13SBarry Smith 
1408273d9f13SBarry Smith   PetscFunctionBegin;
1409273d9f13SBarry Smith   ierr =  MatSeqBAIJSetPreallocation(A,1,PETSC_DEFAULT,0);CHKERRQ(ierr);
1410273d9f13SBarry Smith   PetscFunctionReturn(0);
1411273d9f13SBarry Smith }
1412273d9f13SBarry Smith 
14134a2ae208SSatish Balay #undef __FUNCT__
14144a2ae208SSatish Balay #define __FUNCT__ "MatGetArray_SeqBAIJ"
14154e7234bfSBarry Smith int MatGetArray_SeqBAIJ(Mat A,PetscScalar *array[])
1416f2a5309cSSatish Balay {
1417f2a5309cSSatish Balay   Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)A->data;
1418f2a5309cSSatish Balay   PetscFunctionBegin;
1419f2a5309cSSatish Balay   *array = a->a;
1420f2a5309cSSatish Balay   PetscFunctionReturn(0);
1421f2a5309cSSatish Balay }
1422f2a5309cSSatish Balay 
14234a2ae208SSatish Balay #undef __FUNCT__
14244a2ae208SSatish Balay #define __FUNCT__ "MatRestoreArray_SeqBAIJ"
14254e7234bfSBarry Smith int MatRestoreArray_SeqBAIJ(Mat A,PetscScalar *array[])
1426f2a5309cSSatish Balay {
1427f2a5309cSSatish Balay   PetscFunctionBegin;
1428f2a5309cSSatish Balay   PetscFunctionReturn(0);
1429f2a5309cSSatish Balay }
1430f2a5309cSSatish Balay 
143142ee4b1aSHong Zhang #include "petscblaslapack.h"
143242ee4b1aSHong Zhang #undef __FUNCT__
143342ee4b1aSHong Zhang #define __FUNCT__ "MatAXPY_SeqBAIJ"
1434268466fbSBarry Smith int MatAXPY_SeqBAIJ(const PetscScalar *a,Mat X,Mat Y,MatStructure str)
143542ee4b1aSHong Zhang {
143642ee4b1aSHong Zhang   Mat_SeqBAIJ  *x  = (Mat_SeqBAIJ *)X->data,*y = (Mat_SeqBAIJ *)Y->data;
14376550863bSHong Zhang   int          ierr,one=1,i,bs=y->bs,j,bs2;
143842ee4b1aSHong Zhang 
143942ee4b1aSHong Zhang   PetscFunctionBegin;
144042ee4b1aSHong Zhang   if (str == SAME_NONZERO_PATTERN) {
1441268466fbSBarry Smith     BLaxpy_(&x->nz,(PetscScalar*)a,x->a,&one,y->a,&one);
1442c537a176SHong Zhang   } else if (str == SUBSET_NONZERO_PATTERN) { /* nonzeros of X is a subset of Y's */
1443c4319e64SHong Zhang     if (y->xtoy && y->XtoY != X) {
1444c4319e64SHong Zhang       ierr = PetscFree(y->xtoy);CHKERRQ(ierr);
1445c4319e64SHong Zhang       ierr = MatDestroy(y->XtoY);CHKERRQ(ierr);
1446c537a176SHong Zhang     }
1447c4319e64SHong Zhang     if (!y->xtoy) { /* get xtoy */
1448c4319e64SHong Zhang       ierr = MatAXPYGetxtoy_Private(x->mbs,x->i,x->j,PETSC_NULL, y->i,y->j,PETSC_NULL, &y->xtoy);CHKERRQ(ierr);
1449c4319e64SHong Zhang       y->XtoY = X;
1450c537a176SHong Zhang     }
1451c4319e64SHong Zhang     bs2 = bs*bs;
1452c537a176SHong Zhang     for (i=0; i<x->nz; i++) {
1453c4319e64SHong Zhang       j = 0;
1454c4319e64SHong Zhang       while (j < bs2){
14556550863bSHong Zhang         y->a[bs2*y->xtoy[i]+j] += (*a)*(x->a[bs2*i+j]);
1456c4319e64SHong Zhang         j++;
1457c537a176SHong Zhang       }
1458c4319e64SHong Zhang     }
1459c4319e64SHong Zhang     PetscLogInfo(0,"MatAXPY_SeqBAIJ: ratio of nnz(X)/nnz(Y): %d/%d = %g\n",bs2*x->nz,bs2*y->nz,(PetscReal)(bs2*x->nz)/(bs2*y->nz));
146042ee4b1aSHong Zhang   } else {
146142ee4b1aSHong Zhang     ierr = MatAXPY_Basic(a,X,Y,str);CHKERRQ(ierr);
146242ee4b1aSHong Zhang   }
146342ee4b1aSHong Zhang   PetscFunctionReturn(0);
146442ee4b1aSHong Zhang }
146542ee4b1aSHong Zhang 
14662593348eSBarry Smith /* -------------------------------------------------------------------*/
1467cc2dc46cSBarry Smith static struct _MatOps MatOps_Values = {MatSetValues_SeqBAIJ,
1468cc2dc46cSBarry Smith        MatGetRow_SeqBAIJ,
1469cc2dc46cSBarry Smith        MatRestoreRow_SeqBAIJ,
1470cc2dc46cSBarry Smith        MatMult_SeqBAIJ_N,
147197304618SKris Buschelman /* 4*/ MatMultAdd_SeqBAIJ_N,
14727c922b88SBarry Smith        MatMultTranspose_SeqBAIJ,
14737c922b88SBarry Smith        MatMultTransposeAdd_SeqBAIJ,
1474cc2dc46cSBarry Smith        MatSolve_SeqBAIJ_N,
1475cc2dc46cSBarry Smith        0,
1476cc2dc46cSBarry Smith        0,
147797304618SKris Buschelman /*10*/ 0,
1478cc2dc46cSBarry Smith        MatLUFactor_SeqBAIJ,
1479cc2dc46cSBarry Smith        0,
1480b6490206SBarry Smith        0,
1481f2501298SSatish Balay        MatTranspose_SeqBAIJ,
148297304618SKris Buschelman /*15*/ MatGetInfo_SeqBAIJ,
1483cc2dc46cSBarry Smith        MatEqual_SeqBAIJ,
1484cc2dc46cSBarry Smith        MatGetDiagonal_SeqBAIJ,
1485cc2dc46cSBarry Smith        MatDiagonalScale_SeqBAIJ,
1486cc2dc46cSBarry Smith        MatNorm_SeqBAIJ,
148797304618SKris Buschelman /*20*/ 0,
1488cc2dc46cSBarry Smith        MatAssemblyEnd_SeqBAIJ,
1489cc2dc46cSBarry Smith        0,
1490cc2dc46cSBarry Smith        MatSetOption_SeqBAIJ,
1491cc2dc46cSBarry Smith        MatZeroEntries_SeqBAIJ,
149297304618SKris Buschelman /*25*/ MatZeroRows_SeqBAIJ,
1493cc2dc46cSBarry Smith        MatLUFactorSymbolic_SeqBAIJ,
1494cc2dc46cSBarry Smith        MatLUFactorNumeric_SeqBAIJ_N,
1495cc2dc46cSBarry Smith        0,
1496cc2dc46cSBarry Smith        0,
149797304618SKris Buschelman /*30*/ MatSetUpPreallocation_SeqBAIJ,
1498cc2dc46cSBarry Smith        MatILUFactorSymbolic_SeqBAIJ,
1499cc2dc46cSBarry Smith        0,
1500f2a5309cSSatish Balay        MatGetArray_SeqBAIJ,
1501f2a5309cSSatish Balay        MatRestoreArray_SeqBAIJ,
150297304618SKris Buschelman /*35*/ MatDuplicate_SeqBAIJ,
1503cc2dc46cSBarry Smith        0,
1504cc2dc46cSBarry Smith        0,
1505cc2dc46cSBarry Smith        MatILUFactor_SeqBAIJ,
1506cc2dc46cSBarry Smith        0,
150797304618SKris Buschelman /*40*/ MatAXPY_SeqBAIJ,
1508cc2dc46cSBarry Smith        MatGetSubMatrices_SeqBAIJ,
1509cc2dc46cSBarry Smith        MatIncreaseOverlap_SeqBAIJ,
1510cc2dc46cSBarry Smith        MatGetValues_SeqBAIJ,
1511cc2dc46cSBarry Smith        0,
151297304618SKris Buschelman /*45*/ MatPrintHelp_SeqBAIJ,
1513cc2dc46cSBarry Smith        MatScale_SeqBAIJ,
1514cc2dc46cSBarry Smith        0,
1515cc2dc46cSBarry Smith        0,
1516cc2dc46cSBarry Smith        0,
151797304618SKris Buschelman /*50*/ MatGetBlockSize_SeqBAIJ,
15183b2fbd54SBarry Smith        MatGetRowIJ_SeqBAIJ,
151992c4ed94SBarry Smith        MatRestoreRowIJ_SeqBAIJ,
1520cc2dc46cSBarry Smith        0,
1521cc2dc46cSBarry Smith        0,
152297304618SKris Buschelman /*55*/ 0,
1523cc2dc46cSBarry Smith        0,
1524cc2dc46cSBarry Smith        0,
1525cc2dc46cSBarry Smith        0,
1526d3825aa8SBarry Smith        MatSetValuesBlocked_SeqBAIJ,
152797304618SKris Buschelman /*60*/ MatGetSubMatrix_SeqBAIJ,
1528b9b97703SBarry Smith        MatDestroy_SeqBAIJ,
1529b9b97703SBarry Smith        MatView_SeqBAIJ,
15303a64cc32SBarry Smith        MatGetPetscMaps_Petsc,
1531273d9f13SBarry Smith        0,
153297304618SKris Buschelman /*65*/ 0,
1533273d9f13SBarry Smith        0,
1534273d9f13SBarry Smith        0,
1535273d9f13SBarry Smith        0,
1536273d9f13SBarry Smith        0,
153797304618SKris Buschelman /*70*/ MatGetRowMax_SeqBAIJ,
153897304618SKris Buschelman        MatConvert_Basic,
1539273d9f13SBarry Smith        0,
154097304618SKris Buschelman        0,
154197304618SKris Buschelman        0,
154297304618SKris Buschelman /*75*/ 0,
154397304618SKris Buschelman        0,
154497304618SKris Buschelman        0,
154597304618SKris Buschelman        0,
154697304618SKris Buschelman        0,
154797304618SKris Buschelman /*80*/ 0,
154897304618SKris Buschelman        0,
154997304618SKris Buschelman        0,
155097304618SKris Buschelman        0,
155197304618SKris Buschelman        0,
155297304618SKris Buschelman /*85*/ MatLoad_SeqBAIJ
155397304618SKris Buschelman };
15542593348eSBarry Smith 
15553e90b805SBarry Smith EXTERN_C_BEGIN
15564a2ae208SSatish Balay #undef __FUNCT__
15574a2ae208SSatish Balay #define __FUNCT__ "MatStoreValues_SeqBAIJ"
15583e90b805SBarry Smith int MatStoreValues_SeqBAIJ(Mat mat)
15593e90b805SBarry Smith {
15603e90b805SBarry Smith   Mat_SeqBAIJ *aij = (Mat_SeqBAIJ *)mat->data;
1561273d9f13SBarry Smith   int         nz = aij->i[mat->m]*aij->bs*aij->bs2;
1562d132466eSBarry Smith   int         ierr;
15633e90b805SBarry Smith 
15643e90b805SBarry Smith   PetscFunctionBegin;
15653e90b805SBarry Smith   if (aij->nonew != 1) {
156629bbc08cSBarry Smith     SETERRQ(1,"Must call MatSetOption(A,MAT_NO_NEW_NONZERO_LOCATIONS);first");
15673e90b805SBarry Smith   }
15683e90b805SBarry Smith 
15693e90b805SBarry Smith   /* allocate space for values if not already there */
15703e90b805SBarry Smith   if (!aij->saved_values) {
157187828ca2SBarry Smith     ierr = PetscMalloc((nz+1)*sizeof(PetscScalar),&aij->saved_values);CHKERRQ(ierr);
15723e90b805SBarry Smith   }
15733e90b805SBarry Smith 
15743e90b805SBarry Smith   /* copy values over */
157587828ca2SBarry Smith   ierr = PetscMemcpy(aij->saved_values,aij->a,nz*sizeof(PetscScalar));CHKERRQ(ierr);
15763e90b805SBarry Smith   PetscFunctionReturn(0);
15773e90b805SBarry Smith }
15783e90b805SBarry Smith EXTERN_C_END
15793e90b805SBarry Smith 
15803e90b805SBarry Smith EXTERN_C_BEGIN
15814a2ae208SSatish Balay #undef __FUNCT__
15824a2ae208SSatish Balay #define __FUNCT__ "MatRetrieveValues_SeqBAIJ"
158332e87ba3SBarry Smith int MatRetrieveValues_SeqBAIJ(Mat mat)
15843e90b805SBarry Smith {
15853e90b805SBarry Smith   Mat_SeqBAIJ *aij = (Mat_SeqBAIJ *)mat->data;
1586273d9f13SBarry Smith   int         nz = aij->i[mat->m]*aij->bs*aij->bs2,ierr;
15873e90b805SBarry Smith 
15883e90b805SBarry Smith   PetscFunctionBegin;
15893e90b805SBarry Smith   if (aij->nonew != 1) {
159029bbc08cSBarry Smith     SETERRQ(1,"Must call MatSetOption(A,MAT_NO_NEW_NONZERO_LOCATIONS);first");
15913e90b805SBarry Smith   }
15923e90b805SBarry Smith   if (!aij->saved_values) {
159329bbc08cSBarry Smith     SETERRQ(1,"Must call MatStoreValues(A);first");
15943e90b805SBarry Smith   }
15953e90b805SBarry Smith 
15963e90b805SBarry Smith   /* copy values over */
159787828ca2SBarry Smith   ierr = PetscMemcpy(aij->a,aij->saved_values,nz*sizeof(PetscScalar));CHKERRQ(ierr);
15983e90b805SBarry Smith   PetscFunctionReturn(0);
15993e90b805SBarry Smith }
16003e90b805SBarry Smith EXTERN_C_END
16013e90b805SBarry Smith 
1602273d9f13SBarry Smith EXTERN_C_BEGIN
1603273d9f13SBarry Smith extern int MatConvert_SeqBAIJ_SeqAIJ(Mat,MatType,Mat*);
1604273d9f13SBarry Smith EXTERN_C_END
1605273d9f13SBarry Smith 
1606273d9f13SBarry Smith EXTERN_C_BEGIN
16074a2ae208SSatish Balay #undef __FUNCT__
1608a23d5eceSKris Buschelman #define __FUNCT__ "MatSeqBAIJSetPreallocation_SeqBAIJ"
1609a23d5eceSKris Buschelman int MatSeqBAIJSetPreallocation_SeqBAIJ(Mat B,int bs,int nz,int *nnz)
1610a23d5eceSKris Buschelman {
1611a23d5eceSKris Buschelman   Mat_SeqBAIJ *b;
1612a23d5eceSKris Buschelman   int         i,len,ierr,mbs,nbs,bs2,newbs = bs;
1613a23d5eceSKris Buschelman   PetscTruth  flg;
1614a23d5eceSKris Buschelman 
1615a23d5eceSKris Buschelman   PetscFunctionBegin;
1616a23d5eceSKris Buschelman 
1617a23d5eceSKris Buschelman   B->preallocated = PETSC_TRUE;
1618a23d5eceSKris Buschelman   ierr = PetscOptionsGetInt(B->prefix,"-mat_block_size",&newbs,PETSC_NULL);CHKERRQ(ierr);
1619a23d5eceSKris Buschelman   if (nnz && newbs != bs) {
1620a23d5eceSKris Buschelman     SETERRQ(1,"Cannot change blocksize from command line if setting nnz");
1621a23d5eceSKris Buschelman   }
1622a23d5eceSKris Buschelman   bs   = newbs;
1623a23d5eceSKris Buschelman 
1624a23d5eceSKris Buschelman   mbs  = B->m/bs;
1625a23d5eceSKris Buschelman   nbs  = B->n/bs;
1626a23d5eceSKris Buschelman   bs2  = bs*bs;
1627a23d5eceSKris Buschelman 
1628a23d5eceSKris Buschelman   if (mbs*bs!=B->m || nbs*bs!=B->n) {
1629a23d5eceSKris Buschelman     SETERRQ3(PETSC_ERR_ARG_SIZ,"Number rows %d, cols %d must be divisible by blocksize %d",B->m,B->n,bs);
1630a23d5eceSKris Buschelman   }
1631a23d5eceSKris Buschelman 
1632a23d5eceSKris Buschelman   if (nz == PETSC_DEFAULT || nz == PETSC_DECIDE) nz = 5;
1633a23d5eceSKris Buschelman   if (nz < 0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"nz cannot be less than 0: value %d",nz);
1634a23d5eceSKris Buschelman   if (nnz) {
1635a23d5eceSKris Buschelman     for (i=0; i<mbs; i++) {
1636a23d5eceSKris Buschelman       if (nnz[i] < 0) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"nnz cannot be less than 0: local row %d value %d",i,nnz[i]);
1637a23d5eceSKris Buschelman       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);
1638a23d5eceSKris Buschelman     }
1639a23d5eceSKris Buschelman   }
1640a23d5eceSKris Buschelman 
1641a23d5eceSKris Buschelman   b       = (Mat_SeqBAIJ*)B->data;
1642a23d5eceSKris Buschelman   ierr    = PetscOptionsHasName(PETSC_NULL,"-mat_no_unroll",&flg);CHKERRQ(ierr);
1643a23d5eceSKris Buschelman   B->ops->solve               = MatSolve_SeqBAIJ_Update;
1644a23d5eceSKris Buschelman   B->ops->solvetranspose      = MatSolveTranspose_SeqBAIJ_Update;
1645a23d5eceSKris Buschelman   if (!flg) {
1646a23d5eceSKris Buschelman     switch (bs) {
1647a23d5eceSKris Buschelman     case 1:
1648a23d5eceSKris Buschelman       B->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_1;
1649a23d5eceSKris Buschelman       B->ops->mult            = MatMult_SeqBAIJ_1;
1650a23d5eceSKris Buschelman       B->ops->multadd         = MatMultAdd_SeqBAIJ_1;
1651a23d5eceSKris Buschelman       break;
1652a23d5eceSKris Buschelman     case 2:
1653a23d5eceSKris Buschelman       B->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_2;
1654a23d5eceSKris Buschelman       B->ops->mult            = MatMult_SeqBAIJ_2;
1655a23d5eceSKris Buschelman       B->ops->multadd         = MatMultAdd_SeqBAIJ_2;
1656a23d5eceSKris Buschelman       break;
1657a23d5eceSKris Buschelman     case 3:
1658a23d5eceSKris Buschelman       B->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_3;
1659a23d5eceSKris Buschelman       B->ops->mult            = MatMult_SeqBAIJ_3;
1660a23d5eceSKris Buschelman       B->ops->multadd         = MatMultAdd_SeqBAIJ_3;
1661a23d5eceSKris Buschelman       break;
1662a23d5eceSKris Buschelman     case 4:
1663a23d5eceSKris Buschelman       B->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_4;
1664a23d5eceSKris Buschelman       B->ops->mult            = MatMult_SeqBAIJ_4;
1665a23d5eceSKris Buschelman       B->ops->multadd         = MatMultAdd_SeqBAIJ_4;
1666a23d5eceSKris Buschelman       break;
1667a23d5eceSKris Buschelman     case 5:
1668a23d5eceSKris Buschelman       B->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_5;
1669a23d5eceSKris Buschelman       B->ops->mult            = MatMult_SeqBAIJ_5;
1670a23d5eceSKris Buschelman       B->ops->multadd         = MatMultAdd_SeqBAIJ_5;
1671a23d5eceSKris Buschelman       break;
1672a23d5eceSKris Buschelman     case 6:
1673a23d5eceSKris Buschelman       B->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_6;
1674a23d5eceSKris Buschelman       B->ops->mult            = MatMult_SeqBAIJ_6;
1675a23d5eceSKris Buschelman       B->ops->multadd         = MatMultAdd_SeqBAIJ_6;
1676a23d5eceSKris Buschelman       break;
1677a23d5eceSKris Buschelman     case 7:
1678a23d5eceSKris Buschelman       B->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_7;
1679a23d5eceSKris Buschelman       B->ops->mult            = MatMult_SeqBAIJ_7;
1680a23d5eceSKris Buschelman       B->ops->multadd         = MatMultAdd_SeqBAIJ_7;
1681a23d5eceSKris Buschelman       break;
1682a23d5eceSKris Buschelman     default:
1683a23d5eceSKris Buschelman       B->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_N;
1684a23d5eceSKris Buschelman       B->ops->mult            = MatMult_SeqBAIJ_N;
1685a23d5eceSKris Buschelman       B->ops->multadd         = MatMultAdd_SeqBAIJ_N;
1686a23d5eceSKris Buschelman       break;
1687a23d5eceSKris Buschelman     }
1688a23d5eceSKris Buschelman   }
1689a23d5eceSKris Buschelman   b->bs      = bs;
1690a23d5eceSKris Buschelman   b->mbs     = mbs;
1691a23d5eceSKris Buschelman   b->nbs     = nbs;
1692a23d5eceSKris Buschelman   ierr = PetscMalloc((mbs+1)*sizeof(int),&b->imax);CHKERRQ(ierr);
1693a23d5eceSKris Buschelman   if (!nnz) {
1694a23d5eceSKris Buschelman     if (nz == PETSC_DEFAULT || nz == PETSC_DECIDE) nz = 5;
1695a23d5eceSKris Buschelman     else if (nz <= 0)        nz = 1;
1696a23d5eceSKris Buschelman     for (i=0; i<mbs; i++) b->imax[i] = nz;
1697a23d5eceSKris Buschelman     nz = nz*mbs;
1698a23d5eceSKris Buschelman   } else {
1699a23d5eceSKris Buschelman     nz = 0;
1700a23d5eceSKris Buschelman     for (i=0; i<mbs; i++) {b->imax[i] = nnz[i]; nz += nnz[i];}
1701a23d5eceSKris Buschelman   }
1702a23d5eceSKris Buschelman 
1703a23d5eceSKris Buschelman   /* allocate the matrix space */
1704a23d5eceSKris Buschelman   len   = nz*sizeof(int) + nz*bs2*sizeof(MatScalar) + (B->m+1)*sizeof(int);
1705a23d5eceSKris Buschelman   ierr  = PetscMalloc(len,&b->a);CHKERRQ(ierr);
1706a23d5eceSKris Buschelman   ierr  = PetscMemzero(b->a,nz*bs2*sizeof(MatScalar));CHKERRQ(ierr);
1707a23d5eceSKris Buschelman   b->j  = (int*)(b->a + nz*bs2);
1708a23d5eceSKris Buschelman   ierr = PetscMemzero(b->j,nz*sizeof(int));CHKERRQ(ierr);
1709a23d5eceSKris Buschelman   b->i  = b->j + nz;
1710a23d5eceSKris Buschelman   b->singlemalloc = PETSC_TRUE;
1711a23d5eceSKris Buschelman 
1712a23d5eceSKris Buschelman   b->i[0] = 0;
1713a23d5eceSKris Buschelman   for (i=1; i<mbs+1; i++) {
1714a23d5eceSKris Buschelman     b->i[i] = b->i[i-1] + b->imax[i-1];
1715a23d5eceSKris Buschelman   }
1716a23d5eceSKris Buschelman 
1717a23d5eceSKris Buschelman   /* b->ilen will count nonzeros in each block row so far. */
1718a23d5eceSKris Buschelman   ierr = PetscMalloc((mbs+1)*sizeof(int),&b->ilen);CHKERRQ(ierr);
1719a23d5eceSKris Buschelman   PetscLogObjectMemory(B,len+2*(mbs+1)*sizeof(int)+sizeof(struct _p_Mat)+sizeof(Mat_SeqBAIJ));
1720a23d5eceSKris Buschelman   for (i=0; i<mbs; i++) { b->ilen[i] = 0;}
1721a23d5eceSKris Buschelman 
1722a23d5eceSKris Buschelman   b->bs               = bs;
1723a23d5eceSKris Buschelman   b->bs2              = bs2;
1724a23d5eceSKris Buschelman   b->mbs              = mbs;
1725a23d5eceSKris Buschelman   b->nz               = 0;
1726a23d5eceSKris Buschelman   b->maxnz            = nz*bs2;
1727a23d5eceSKris Buschelman   B->info.nz_unneeded = (PetscReal)b->maxnz;
1728a23d5eceSKris Buschelman   PetscFunctionReturn(0);
1729a23d5eceSKris Buschelman }
1730a23d5eceSKris Buschelman EXTERN_C_END
1731a23d5eceSKris Buschelman 
17320bad9183SKris Buschelman /*MC
1733fafad747SKris Buschelman    MATSEQBAIJ - MATSEQBAIJ = "seqbaij" - A matrix type to be used for sequential block sparse matrices, based on
17340bad9183SKris Buschelman    block sparse compressed row format.
17350bad9183SKris Buschelman 
17360bad9183SKris Buschelman    Options Database Keys:
17370bad9183SKris Buschelman . -mat_type seqbaij - sets the matrix type to "seqbaij" during a call to MatSetFromOptions()
17380bad9183SKris Buschelman 
17390bad9183SKris Buschelman   Level: beginner
17400bad9183SKris Buschelman 
17410bad9183SKris Buschelman .seealso: MatCreateSeqBAIJ
17420bad9183SKris Buschelman M*/
17430bad9183SKris Buschelman 
1744a23d5eceSKris Buschelman EXTERN_C_BEGIN
1745a23d5eceSKris Buschelman #undef __FUNCT__
17464a2ae208SSatish Balay #define __FUNCT__ "MatCreate_SeqBAIJ"
1747273d9f13SBarry Smith int MatCreate_SeqBAIJ(Mat B)
17482593348eSBarry Smith {
1749273d9f13SBarry Smith   int         ierr,size;
1750b6490206SBarry Smith   Mat_SeqBAIJ *b;
17513b2fbd54SBarry Smith 
17523a40ed3dSBarry Smith   PetscFunctionBegin;
1753273d9f13SBarry Smith   ierr = MPI_Comm_size(B->comm,&size);CHKERRQ(ierr);
175429bbc08cSBarry Smith   if (size > 1) SETERRQ(PETSC_ERR_ARG_WRONG,"Comm must be of size 1");
1755b6490206SBarry Smith 
1756273d9f13SBarry Smith   B->m = B->M = PetscMax(B->m,B->M);
1757273d9f13SBarry Smith   B->n = B->N = PetscMax(B->n,B->N);
1758b0a32e0cSBarry Smith   ierr    = PetscNew(Mat_SeqBAIJ,&b);CHKERRQ(ierr);
1759b0a32e0cSBarry Smith   B->data = (void*)b;
1760549d3d68SSatish Balay   ierr    = PetscMemzero(b,sizeof(Mat_SeqBAIJ));CHKERRQ(ierr);
1761549d3d68SSatish Balay   ierr    = PetscMemcpy(B->ops,&MatOps_Values,sizeof(struct _MatOps));CHKERRQ(ierr);
17622593348eSBarry Smith   B->factor           = 0;
17632593348eSBarry Smith   B->lupivotthreshold = 1.0;
176490f02eecSBarry Smith   B->mapping          = 0;
17652593348eSBarry Smith   b->row              = 0;
17662593348eSBarry Smith   b->col              = 0;
1767e51c0b9cSSatish Balay   b->icol             = 0;
17682593348eSBarry Smith   b->reallocs         = 0;
17693e90b805SBarry Smith   b->saved_values     = 0;
1770cfce73b9SSatish Balay #if defined(PETSC_USE_MAT_SINGLE)
1771563b5814SBarry Smith   b->setvalueslen     = 0;
1772563b5814SBarry Smith   b->setvaluescopy    = PETSC_NULL;
1773563b5814SBarry Smith #endif
17742593348eSBarry Smith 
17753a64cc32SBarry Smith   ierr = PetscMapCreateMPI(B->comm,B->m,B->m,&B->rmap);CHKERRQ(ierr);
17763a64cc32SBarry Smith   ierr = PetscMapCreateMPI(B->comm,B->n,B->n,&B->cmap);CHKERRQ(ierr);
1777a5ae1ecdSBarry Smith 
1778c4992f7dSBarry Smith   b->sorted           = PETSC_FALSE;
1779c4992f7dSBarry Smith   b->roworiented      = PETSC_TRUE;
17802593348eSBarry Smith   b->nonew            = 0;
17812593348eSBarry Smith   b->diag             = 0;
17822593348eSBarry Smith   b->solve_work       = 0;
1783de6a44a3SBarry Smith   b->mult_work        = 0;
17842a1b7f2aSHong Zhang   B->spptr            = 0;
17850e6d2581SBarry Smith   B->info.nz_unneeded = (PetscReal)b->maxnz;
1786883fce79SBarry Smith   b->keepzeroedrows   = PETSC_FALSE;
1787c4319e64SHong Zhang   b->xtoy              = 0;
1788c4319e64SHong Zhang   b->XtoY              = 0;
17894e220ebcSLois Curfman McInnes 
1790f1af5d2fSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatStoreValues_C",
17913e90b805SBarry Smith                                      "MatStoreValues_SeqBAIJ",
1792bc4b532fSSatish Balay                                       MatStoreValues_SeqBAIJ);CHKERRQ(ierr);
1793f1af5d2fSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatRetrieveValues_C",
17943e90b805SBarry Smith                                      "MatRetrieveValues_SeqBAIJ",
1795bc4b532fSSatish Balay                                       MatRetrieveValues_SeqBAIJ);CHKERRQ(ierr);
1796f1af5d2fSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatSeqBAIJSetColumnIndices_C",
179727a8da17SBarry Smith                                      "MatSeqBAIJSetColumnIndices_SeqBAIJ",
1798bc4b532fSSatish Balay                                       MatSeqBAIJSetColumnIndices_SeqBAIJ);CHKERRQ(ierr);
1799a6175056SHong Zhang   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatConvert_seqbaij_seqaij_C",
1800273d9f13SBarry Smith                                      "MatConvert_SeqBAIJ_SeqAIJ",
1801273d9f13SBarry Smith                                       MatConvert_SeqBAIJ_SeqAIJ);CHKERRQ(ierr);
1802a23d5eceSKris Buschelman   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatSeqBAIJSetPreallocation_C",
1803a23d5eceSKris Buschelman                                      "MatSeqBAIJSetPreallocation_SeqBAIJ",
1804a23d5eceSKris Buschelman                                       MatSeqBAIJSetPreallocation_SeqBAIJ);CHKERRQ(ierr);
18053a40ed3dSBarry Smith   PetscFunctionReturn(0);
18062593348eSBarry Smith }
1807273d9f13SBarry Smith EXTERN_C_END
18082593348eSBarry Smith 
18094a2ae208SSatish Balay #undef __FUNCT__
18104a2ae208SSatish Balay #define __FUNCT__ "MatDuplicate_SeqBAIJ"
18112e8a6d31SBarry Smith int MatDuplicate_SeqBAIJ(Mat A,MatDuplicateOption cpvalues,Mat *B)
18122593348eSBarry Smith {
18132593348eSBarry Smith   Mat         C;
1814b6490206SBarry Smith   Mat_SeqBAIJ *c,*a = (Mat_SeqBAIJ*)A->data;
181527a8da17SBarry Smith   int         i,len,mbs = a->mbs,nz = a->nz,bs2 =a->bs2,ierr;
1816de6a44a3SBarry Smith 
18173a40ed3dSBarry Smith   PetscFunctionBegin;
181829bbc08cSBarry Smith   if (a->i[mbs] != nz) SETERRQ(PETSC_ERR_PLIB,"Corrupt matrix");
18192593348eSBarry Smith 
18202593348eSBarry Smith   *B = 0;
1821273d9f13SBarry Smith   ierr = MatCreate(A->comm,A->m,A->n,A->m,A->n,&C);CHKERRQ(ierr);
1822273d9f13SBarry Smith   ierr = MatSetType(C,MATSEQBAIJ);CHKERRQ(ierr);
1823273d9f13SBarry Smith   c    = (Mat_SeqBAIJ*)C->data;
182444cd7ae7SLois Curfman McInnes 
1825b6490206SBarry Smith   c->bs         = a->bs;
18269df24120SSatish Balay   c->bs2        = a->bs2;
1827b6490206SBarry Smith   c->mbs        = a->mbs;
1828b6490206SBarry Smith   c->nbs        = a->nbs;
182935d8aa7fSBarry Smith   ierr = PetscMemcpy(C->ops,A->ops,sizeof(struct _MatOps));CHKERRQ(ierr);
18302593348eSBarry Smith 
1831b0a32e0cSBarry Smith   ierr = PetscMalloc((mbs+1)*sizeof(int),&c->imax);CHKERRQ(ierr);
1832b0a32e0cSBarry Smith   ierr = PetscMalloc((mbs+1)*sizeof(int),&c->ilen);CHKERRQ(ierr);
1833b6490206SBarry Smith   for (i=0; i<mbs; i++) {
18342593348eSBarry Smith     c->imax[i] = a->imax[i];
18352593348eSBarry Smith     c->ilen[i] = a->ilen[i];
18362593348eSBarry Smith   }
18372593348eSBarry Smith 
18382593348eSBarry Smith   /* allocate the matrix space */
1839c4992f7dSBarry Smith   c->singlemalloc = PETSC_TRUE;
18403f1db9ecSBarry Smith   len  = (mbs+1)*sizeof(int) + nz*(bs2*sizeof(MatScalar) + sizeof(int));
1841b0a32e0cSBarry Smith   ierr = PetscMalloc(len,&c->a);CHKERRQ(ierr);
18427e67e3f9SSatish Balay   c->j = (int*)(c->a + nz*bs2);
1843de6a44a3SBarry Smith   c->i = c->j + nz;
1844549d3d68SSatish Balay   ierr = PetscMemcpy(c->i,a->i,(mbs+1)*sizeof(int));CHKERRQ(ierr);
1845b6490206SBarry Smith   if (mbs > 0) {
1846549d3d68SSatish Balay     ierr = PetscMemcpy(c->j,a->j,nz*sizeof(int));CHKERRQ(ierr);
18472e8a6d31SBarry Smith     if (cpvalues == MAT_COPY_VALUES) {
1848549d3d68SSatish Balay       ierr = PetscMemcpy(c->a,a->a,bs2*nz*sizeof(MatScalar));CHKERRQ(ierr);
18492e8a6d31SBarry Smith     } else {
1850549d3d68SSatish Balay       ierr = PetscMemzero(c->a,bs2*nz*sizeof(MatScalar));CHKERRQ(ierr);
18512593348eSBarry Smith     }
18522593348eSBarry Smith   }
18532593348eSBarry Smith 
1854b0a32e0cSBarry Smith   PetscLogObjectMemory(C,len+2*(mbs+1)*sizeof(int)+sizeof(struct _p_Mat)+sizeof(Mat_SeqBAIJ));
18552593348eSBarry Smith   c->sorted      = a->sorted;
18562593348eSBarry Smith   c->roworiented = a->roworiented;
18572593348eSBarry Smith   c->nonew       = a->nonew;
18582593348eSBarry Smith 
18592593348eSBarry Smith   if (a->diag) {
1860b0a32e0cSBarry Smith     ierr = PetscMalloc((mbs+1)*sizeof(int),&c->diag);CHKERRQ(ierr);
1861b0a32e0cSBarry Smith     PetscLogObjectMemory(C,(mbs+1)*sizeof(int));
1862b6490206SBarry Smith     for (i=0; i<mbs; i++) {
18632593348eSBarry Smith       c->diag[i] = a->diag[i];
18642593348eSBarry Smith     }
186598305bb5SBarry Smith   } else c->diag        = 0;
18662593348eSBarry Smith   c->nz                 = a->nz;
18672593348eSBarry Smith   c->maxnz              = a->maxnz;
18682593348eSBarry Smith   c->solve_work         = 0;
18692a1b7f2aSHong Zhang   C->spptr              = 0;     /* Dangerous -I'm throwing away a->spptr */
18707fc0212eSBarry Smith   c->mult_work          = 0;
1871273d9f13SBarry Smith   C->preallocated       = PETSC_TRUE;
1872273d9f13SBarry Smith   C->assembled          = PETSC_TRUE;
18732593348eSBarry Smith   *B = C;
1874b0a32e0cSBarry Smith   ierr = PetscFListDuplicate(A->qlist,&C->qlist);CHKERRQ(ierr);
18753a40ed3dSBarry Smith   PetscFunctionReturn(0);
18762593348eSBarry Smith }
18772593348eSBarry Smith 
18784a2ae208SSatish Balay #undef __FUNCT__
18794a2ae208SSatish Balay #define __FUNCT__ "MatLoad_SeqBAIJ"
1880b0a32e0cSBarry Smith int MatLoad_SeqBAIJ(PetscViewer viewer,MatType type,Mat *A)
18812593348eSBarry Smith {
1882b6490206SBarry Smith   Mat_SeqBAIJ  *a;
18832593348eSBarry Smith   Mat          B;
1884f1af5d2fSBarry Smith   int          i,nz,ierr,fd,header[4],size,*rowlengths=0,M,N,bs=1;
1885b6490206SBarry Smith   int          *mask,mbs,*jj,j,rowcount,nzcount,k,*browlengths,maskcount;
188635aab85fSBarry Smith   int          kmax,jcount,block,idx,point,nzcountb,extra_rows;
1887a7c10996SSatish Balay   int          *masked,nmask,tmp,bs2,ishift;
188887828ca2SBarry Smith   PetscScalar  *aa;
188919bcc07fSBarry Smith   MPI_Comm     comm = ((PetscObject)viewer)->comm;
18902593348eSBarry Smith 
18913a40ed3dSBarry Smith   PetscFunctionBegin;
1892b0a32e0cSBarry Smith   ierr = PetscOptionsGetInt(PETSC_NULL,"-matload_block_size",&bs,PETSC_NULL);CHKERRQ(ierr);
1893de6a44a3SBarry Smith   bs2  = bs*bs;
1894b6490206SBarry Smith 
1895d132466eSBarry Smith   ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr);
189629bbc08cSBarry Smith   if (size > 1) SETERRQ(PETSC_ERR_ARG_WRONG,"view must have one processor");
1897b0a32e0cSBarry Smith   ierr = PetscViewerBinaryGetDescriptor(viewer,&fd);CHKERRQ(ierr);
18980752156aSBarry Smith   ierr = PetscBinaryRead(fd,header,4,PETSC_INT);CHKERRQ(ierr);
1899552e946dSBarry Smith   if (header[0] != MAT_FILE_COOKIE) SETERRQ(PETSC_ERR_FILE_UNEXPECTED,"not Mat object");
19002593348eSBarry Smith   M = header[1]; N = header[2]; nz = header[3];
19012593348eSBarry Smith 
1902d64ed03dSBarry Smith   if (header[3] < 0) {
190329bbc08cSBarry Smith     SETERRQ(PETSC_ERR_FILE_UNEXPECTED,"Matrix stored in special format, cannot load as SeqBAIJ");
1904d64ed03dSBarry Smith   }
1905d64ed03dSBarry Smith 
190629bbc08cSBarry Smith   if (M != N) SETERRQ(PETSC_ERR_SUP,"Can only do square matrices");
190735aab85fSBarry Smith 
190835aab85fSBarry Smith   /*
190935aab85fSBarry Smith      This code adds extra rows to make sure the number of rows is
191035aab85fSBarry Smith     divisible by the blocksize
191135aab85fSBarry Smith   */
1912b6490206SBarry Smith   mbs        = M/bs;
191335aab85fSBarry Smith   extra_rows = bs - M + bs*(mbs);
191435aab85fSBarry Smith   if (extra_rows == bs) extra_rows = 0;
191535aab85fSBarry Smith   else                  mbs++;
191635aab85fSBarry Smith   if (extra_rows) {
1917b0a32e0cSBarry Smith     PetscLogInfo(0,"MatLoad_SeqBAIJ:Padding loaded matrix to match blocksize\n");
191835aab85fSBarry Smith   }
1919b6490206SBarry Smith 
19202593348eSBarry Smith   /* read in row lengths */
1921b0a32e0cSBarry Smith   ierr = PetscMalloc((M+extra_rows)*sizeof(int),&rowlengths);CHKERRQ(ierr);
19220752156aSBarry Smith   ierr = PetscBinaryRead(fd,rowlengths,M,PETSC_INT);CHKERRQ(ierr);
192335aab85fSBarry Smith   for (i=0; i<extra_rows; i++) rowlengths[M+i] = 1;
19242593348eSBarry Smith 
1925b6490206SBarry Smith   /* read in column indices */
1926b0a32e0cSBarry Smith   ierr = PetscMalloc((nz+extra_rows)*sizeof(int),&jj);CHKERRQ(ierr);
19270752156aSBarry Smith   ierr = PetscBinaryRead(fd,jj,nz,PETSC_INT);CHKERRQ(ierr);
192835aab85fSBarry Smith   for (i=0; i<extra_rows; i++) jj[nz+i] = M+i;
1929b6490206SBarry Smith 
1930b6490206SBarry Smith   /* loop over row lengths determining block row lengths */
1931b0a32e0cSBarry Smith   ierr     = PetscMalloc(mbs*sizeof(int),&browlengths);CHKERRQ(ierr);
1932549d3d68SSatish Balay   ierr     = PetscMemzero(browlengths,mbs*sizeof(int));CHKERRQ(ierr);
1933b0a32e0cSBarry Smith   ierr     = PetscMalloc(2*mbs*sizeof(int),&mask);CHKERRQ(ierr);
1934549d3d68SSatish Balay   ierr     = PetscMemzero(mask,mbs*sizeof(int));CHKERRQ(ierr);
193535aab85fSBarry Smith   masked   = mask + mbs;
1936b6490206SBarry Smith   rowcount = 0; nzcount = 0;
1937b6490206SBarry Smith   for (i=0; i<mbs; i++) {
193835aab85fSBarry Smith     nmask = 0;
1939b6490206SBarry Smith     for (j=0; j<bs; j++) {
1940b6490206SBarry Smith       kmax = rowlengths[rowcount];
1941b6490206SBarry Smith       for (k=0; k<kmax; k++) {
194235aab85fSBarry Smith         tmp = jj[nzcount++]/bs;
194335aab85fSBarry Smith         if (!mask[tmp]) {masked[nmask++] = tmp; mask[tmp] = 1;}
1944b6490206SBarry Smith       }
1945b6490206SBarry Smith       rowcount++;
1946b6490206SBarry Smith     }
194735aab85fSBarry Smith     browlengths[i] += nmask;
194835aab85fSBarry Smith     /* zero out the mask elements we set */
194935aab85fSBarry Smith     for (j=0; j<nmask; j++) mask[masked[j]] = 0;
1950b6490206SBarry Smith   }
1951b6490206SBarry Smith 
19522593348eSBarry Smith   /* create our matrix */
1953dd23797bSKris Buschelman   ierr = MatCreate(comm,PETSC_DECIDE,PETSC_DECIDE,M+extra_rows,N+extra_rows,&B);
195478ae41b4SKris Buschelman   ierr = MatSetType(B,type);CHKERRQ(ierr);
195578ae41b4SKris Buschelman   ierr = MatSeqBAIJSetPreallocation(B,bs,0,browlengths);CHKERRQ(ierr);
1956b6490206SBarry Smith   a = (Mat_SeqBAIJ*)B->data;
19572593348eSBarry Smith 
19582593348eSBarry Smith   /* set matrix "i" values */
1959de6a44a3SBarry Smith   a->i[0] = 0;
1960b6490206SBarry Smith   for (i=1; i<= mbs; i++) {
1961b6490206SBarry Smith     a->i[i]      = a->i[i-1] + browlengths[i-1];
1962b6490206SBarry Smith     a->ilen[i-1] = browlengths[i-1];
19632593348eSBarry Smith   }
1964b6490206SBarry Smith   a->nz         = 0;
1965b6490206SBarry Smith   for (i=0; i<mbs; i++) a->nz += browlengths[i];
19662593348eSBarry Smith 
1967b6490206SBarry Smith   /* read in nonzero values */
196887828ca2SBarry Smith   ierr = PetscMalloc((nz+extra_rows)*sizeof(PetscScalar),&aa);CHKERRQ(ierr);
19690752156aSBarry Smith   ierr = PetscBinaryRead(fd,aa,nz,PETSC_SCALAR);CHKERRQ(ierr);
197035aab85fSBarry Smith   for (i=0; i<extra_rows; i++) aa[nz+i] = 1.0;
1971b6490206SBarry Smith 
1972b6490206SBarry Smith   /* set "a" and "j" values into matrix */
1973b6490206SBarry Smith   nzcount = 0; jcount = 0;
1974b6490206SBarry Smith   for (i=0; i<mbs; i++) {
1975b6490206SBarry Smith     nzcountb = nzcount;
197635aab85fSBarry Smith     nmask    = 0;
1977b6490206SBarry Smith     for (j=0; j<bs; j++) {
1978b6490206SBarry Smith       kmax = rowlengths[i*bs+j];
1979b6490206SBarry Smith       for (k=0; k<kmax; k++) {
198035aab85fSBarry Smith         tmp = jj[nzcount++]/bs;
198135aab85fSBarry Smith 	if (!mask[tmp]) { masked[nmask++] = tmp; mask[tmp] = 1;}
1982b6490206SBarry Smith       }
1983b6490206SBarry Smith     }
1984de6a44a3SBarry Smith     /* sort the masked values */
1985433994e6SBarry Smith     ierr = PetscSortInt(nmask,masked);CHKERRQ(ierr);
1986de6a44a3SBarry Smith 
1987b6490206SBarry Smith     /* set "j" values into matrix */
1988b6490206SBarry Smith     maskcount = 1;
198935aab85fSBarry Smith     for (j=0; j<nmask; j++) {
199035aab85fSBarry Smith       a->j[jcount++]  = masked[j];
1991de6a44a3SBarry Smith       mask[masked[j]] = maskcount++;
1992b6490206SBarry Smith     }
1993b6490206SBarry Smith     /* set "a" values into matrix */
1994de6a44a3SBarry Smith     ishift = bs2*a->i[i];
1995b6490206SBarry Smith     for (j=0; j<bs; j++) {
1996b6490206SBarry Smith       kmax = rowlengths[i*bs+j];
1997b6490206SBarry Smith       for (k=0; k<kmax; k++) {
1998de6a44a3SBarry Smith         tmp       = jj[nzcountb]/bs ;
1999de6a44a3SBarry Smith         block     = mask[tmp] - 1;
2000de6a44a3SBarry Smith         point     = jj[nzcountb] - bs*tmp;
2001de6a44a3SBarry Smith         idx       = ishift + bs2*block + j + bs*point;
2002375fe846SBarry Smith         a->a[idx] = (MatScalar)aa[nzcountb++];
2003b6490206SBarry Smith       }
2004b6490206SBarry Smith     }
200535aab85fSBarry Smith     /* zero out the mask elements we set */
200635aab85fSBarry Smith     for (j=0; j<nmask; j++) mask[masked[j]] = 0;
2007b6490206SBarry Smith   }
200829bbc08cSBarry Smith   if (jcount != a->nz) SETERRQ(PETSC_ERR_FILE_UNEXPECTED,"Bad binary matrix");
2009b6490206SBarry Smith 
2010606d414cSSatish Balay   ierr = PetscFree(rowlengths);CHKERRQ(ierr);
2011606d414cSSatish Balay   ierr = PetscFree(browlengths);CHKERRQ(ierr);
2012606d414cSSatish Balay   ierr = PetscFree(aa);CHKERRQ(ierr);
2013606d414cSSatish Balay   ierr = PetscFree(jj);CHKERRQ(ierr);
2014606d414cSSatish Balay   ierr = PetscFree(mask);CHKERRQ(ierr);
2015b6490206SBarry Smith 
201678ae41b4SKris Buschelman   ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
201778ae41b4SKris Buschelman   ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
20189c01be13SBarry Smith   ierr = MatView_Private(B);CHKERRQ(ierr);
201978ae41b4SKris Buschelman 
202078ae41b4SKris Buschelman   *A = B;
20213a40ed3dSBarry Smith   PetscFunctionReturn(0);
20222593348eSBarry Smith }
20232593348eSBarry Smith 
20244a2ae208SSatish Balay #undef __FUNCT__
20254a2ae208SSatish Balay #define __FUNCT__ "MatCreateSeqBAIJ"
2026273d9f13SBarry Smith /*@C
2027273d9f13SBarry Smith    MatCreateSeqBAIJ - Creates a sparse matrix in block AIJ (block
2028273d9f13SBarry Smith    compressed row) format.  For good matrix assembly performance the
2029273d9f13SBarry Smith    user should preallocate the matrix storage by setting the parameter nz
2030273d9f13SBarry Smith    (or the array nnz).  By setting these parameters accurately, performance
2031273d9f13SBarry Smith    during matrix assembly can be increased by more than a factor of 50.
20322593348eSBarry Smith 
2033273d9f13SBarry Smith    Collective on MPI_Comm
2034273d9f13SBarry Smith 
2035273d9f13SBarry Smith    Input Parameters:
2036273d9f13SBarry Smith +  comm - MPI communicator, set to PETSC_COMM_SELF
2037273d9f13SBarry Smith .  bs - size of block
2038273d9f13SBarry Smith .  m - number of rows
2039273d9f13SBarry Smith .  n - number of columns
204035d8aa7fSBarry Smith .  nz - number of nonzero blocks  per block row (same for all rows)
204135d8aa7fSBarry Smith -  nnz - array containing the number of nonzero blocks in the various block rows
2042273d9f13SBarry Smith          (possibly different for each block row) or PETSC_NULL
2043273d9f13SBarry Smith 
2044273d9f13SBarry Smith    Output Parameter:
2045273d9f13SBarry Smith .  A - the matrix
2046273d9f13SBarry Smith 
2047273d9f13SBarry Smith    Options Database Keys:
2048273d9f13SBarry Smith .   -mat_no_unroll - uses code that does not unroll the loops in the
2049273d9f13SBarry Smith                      block calculations (much slower)
2050273d9f13SBarry Smith .    -mat_block_size - size of the blocks to use
2051273d9f13SBarry Smith 
2052273d9f13SBarry Smith    Level: intermediate
2053273d9f13SBarry Smith 
2054273d9f13SBarry Smith    Notes:
205535d8aa7fSBarry Smith    A nonzero block is any block that as 1 or more nonzeros in it
205635d8aa7fSBarry Smith 
2057273d9f13SBarry Smith    The block AIJ format is fully compatible with standard Fortran 77
2058273d9f13SBarry Smith    storage.  That is, the stored row and column indices can begin at
2059273d9f13SBarry Smith    either one (as in Fortran) or zero.  See the users' manual for details.
2060273d9f13SBarry Smith 
2061273d9f13SBarry Smith    Specify the preallocated storage with either nz or nnz (not both).
2062273d9f13SBarry Smith    Set nz=PETSC_DEFAULT and nnz=PETSC_NULL for PETSc to control dynamic memory
2063273d9f13SBarry Smith    allocation.  For additional details, see the users manual chapter on
2064273d9f13SBarry Smith    matrices.
2065273d9f13SBarry Smith 
2066273d9f13SBarry Smith .seealso: MatCreate(), MatCreateSeqAIJ(), MatSetValues(), MatCreateMPIBAIJ()
2067273d9f13SBarry Smith @*/
2068ca01db9bSBarry Smith int MatCreateSeqBAIJ(MPI_Comm comm,int bs,int m,int n,int nz,const int nnz[],Mat *A)
2069273d9f13SBarry Smith {
2070273d9f13SBarry Smith   int ierr;
2071273d9f13SBarry Smith 
2072273d9f13SBarry Smith   PetscFunctionBegin;
2073273d9f13SBarry Smith   ierr = MatCreate(comm,m,n,m,n,A);CHKERRQ(ierr);
2074273d9f13SBarry Smith   ierr = MatSetType(*A,MATSEQBAIJ);CHKERRQ(ierr);
2075273d9f13SBarry Smith   ierr = MatSeqBAIJSetPreallocation(*A,bs,nz,nnz);CHKERRQ(ierr);
2076273d9f13SBarry Smith   PetscFunctionReturn(0);
2077273d9f13SBarry Smith }
2078273d9f13SBarry Smith 
20794a2ae208SSatish Balay #undef __FUNCT__
20804a2ae208SSatish Balay #define __FUNCT__ "MatSeqBAIJSetPreallocation"
2081273d9f13SBarry Smith /*@C
2082273d9f13SBarry Smith    MatSeqBAIJSetPreallocation - Sets the block size and expected nonzeros
2083273d9f13SBarry Smith    per row in the matrix. For good matrix assembly performance the
2084273d9f13SBarry Smith    user should preallocate the matrix storage by setting the parameter nz
2085273d9f13SBarry Smith    (or the array nnz).  By setting these parameters accurately, performance
2086273d9f13SBarry Smith    during matrix assembly can be increased by more than a factor of 50.
2087273d9f13SBarry Smith 
2088273d9f13SBarry Smith    Collective on MPI_Comm
2089273d9f13SBarry Smith 
2090273d9f13SBarry Smith    Input Parameters:
2091273d9f13SBarry Smith +  A - the matrix
2092273d9f13SBarry Smith .  bs - size of block
2093273d9f13SBarry Smith .  nz - number of block nonzeros per block row (same for all rows)
2094273d9f13SBarry Smith -  nnz - array containing the number of block nonzeros in the various block rows
2095273d9f13SBarry Smith          (possibly different for each block row) or PETSC_NULL
2096273d9f13SBarry Smith 
2097273d9f13SBarry Smith    Options Database Keys:
2098273d9f13SBarry Smith .   -mat_no_unroll - uses code that does not unroll the loops in the
2099273d9f13SBarry Smith                      block calculations (much slower)
2100273d9f13SBarry Smith .    -mat_block_size - size of the blocks to use
2101273d9f13SBarry Smith 
2102273d9f13SBarry Smith    Level: intermediate
2103273d9f13SBarry Smith 
2104273d9f13SBarry Smith    Notes:
2105273d9f13SBarry Smith    The block AIJ format is fully compatible with standard Fortran 77
2106273d9f13SBarry Smith    storage.  That is, the stored row and column indices can begin at
2107273d9f13SBarry Smith    either one (as in Fortran) or zero.  See the users' manual for details.
2108273d9f13SBarry Smith 
2109273d9f13SBarry Smith    Specify the preallocated storage with either nz or nnz (not both).
2110273d9f13SBarry Smith    Set nz=PETSC_DEFAULT and nnz=PETSC_NULL for PETSc to control dynamic memory
2111273d9f13SBarry Smith    allocation.  For additional details, see the users manual chapter on
2112273d9f13SBarry Smith    matrices.
2113273d9f13SBarry Smith 
2114273d9f13SBarry Smith .seealso: MatCreate(), MatCreateSeqAIJ(), MatSetValues(), MatCreateMPIBAIJ()
2115273d9f13SBarry Smith @*/
2116ca01db9bSBarry Smith int MatSeqBAIJSetPreallocation(Mat B,int bs,int nz,const int nnz[])
2117273d9f13SBarry Smith {
2118ca01db9bSBarry Smith   int ierr,(*f)(Mat,int,int,const int[]);
2119273d9f13SBarry Smith 
2120273d9f13SBarry Smith   PetscFunctionBegin;
2121a23d5eceSKris Buschelman   ierr = PetscObjectQueryFunction((PetscObject)B,"MatSeqBAIJSetPreallocation_C",(void (**)(void))&f);CHKERRQ(ierr);
2122a23d5eceSKris Buschelman   if (f) {
2123a23d5eceSKris Buschelman     ierr = (*f)(B,bs,nz,nnz);CHKERRQ(ierr);
2124273d9f13SBarry Smith   }
2125273d9f13SBarry Smith   PetscFunctionReturn(0);
2126273d9f13SBarry Smith }
2127