xref: /petsc/src/mat/impls/baij/seq/baij.c (revision c537a17644e75ddee54e85f4b8155d17b42d28e5)
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_"
244bb09213Spetsc void matsetvaluesblocked4_(Mat *AA,int *mm,int *im,int *nn,int *in,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;
314bb09213Spetsc   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)
158ca44d042SBarry Smith EXTERN int MatSetValuesBlocked_SeqBAIJ_MatScalar(Mat,int,int*,int,int*,MatScalar*,InsertMode);
15995d5f7c2SBarry Smith #else
16095d5f7c2SBarry Smith #define MatSetValuesBlocked_SeqBAIJ_MatScalar MatSetValuesBlocked_SeqBAIJ
16195d5f7c2SBarry Smith #endif
16204929863SHong Zhang #if defined(PETSC_HAVE_DSCPACK)
16304929863SHong Zhang EXTERN int MatUseDSCPACK_MPIBAIJ(Mat);
16404929863SHong Zhang #endif
16595d5f7c2SBarry Smith 
1662d61bbb3SSatish Balay #define CHUNKSIZE  10
167de6a44a3SBarry Smith 
168be5855fcSBarry Smith /*
169be5855fcSBarry Smith      Checks for missing diagonals
170be5855fcSBarry Smith */
1714a2ae208SSatish Balay #undef __FUNCT__
1724a2ae208SSatish Balay #define __FUNCT__ "MatMissingDiagonal_SeqBAIJ"
173c4992f7dSBarry Smith int MatMissingDiagonal_SeqBAIJ(Mat A)
174be5855fcSBarry Smith {
175be5855fcSBarry Smith   Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)A->data;
176883fce79SBarry Smith   int         *diag,*jj = a->j,i,ierr;
177be5855fcSBarry Smith 
178be5855fcSBarry Smith   PetscFunctionBegin;
179c4992f7dSBarry Smith   ierr = MatMarkDiagonal_SeqBAIJ(A);CHKERRQ(ierr);
180883fce79SBarry Smith   diag = a->diag;
1810e8e8aceSBarry Smith   for (i=0; i<a->mbs; i++) {
182be5855fcSBarry Smith     if (jj[diag[i]] != i) {
18329bbc08cSBarry Smith       SETERRQ1(1,"Matrix is missing diagonal number %d",i);
184be5855fcSBarry Smith     }
185be5855fcSBarry Smith   }
186be5855fcSBarry Smith   PetscFunctionReturn(0);
187be5855fcSBarry Smith }
188be5855fcSBarry Smith 
1894a2ae208SSatish Balay #undef __FUNCT__
1904a2ae208SSatish Balay #define __FUNCT__ "MatMarkDiagonal_SeqBAIJ"
191c4992f7dSBarry Smith int MatMarkDiagonal_SeqBAIJ(Mat A)
192de6a44a3SBarry Smith {
193de6a44a3SBarry Smith   Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)A->data;
19482502324SSatish Balay   int         i,j,*diag,m = a->mbs,ierr;
195de6a44a3SBarry Smith 
1963a40ed3dSBarry Smith   PetscFunctionBegin;
197883fce79SBarry Smith   if (a->diag) PetscFunctionReturn(0);
198883fce79SBarry Smith 
199b0a32e0cSBarry Smith   ierr = PetscMalloc((m+1)*sizeof(int),&diag);CHKERRQ(ierr);
200b0a32e0cSBarry Smith   PetscLogObjectMemory(A,(m+1)*sizeof(int));
2017fc0212eSBarry Smith   for (i=0; i<m; i++) {
202ecc615b2SBarry Smith     diag[i] = a->i[i+1];
203de6a44a3SBarry Smith     for (j=a->i[i]; j<a->i[i+1]; j++) {
204de6a44a3SBarry Smith       if (a->j[j] == i) {
205de6a44a3SBarry Smith         diag[i] = j;
206de6a44a3SBarry Smith         break;
207de6a44a3SBarry Smith       }
208de6a44a3SBarry Smith     }
209de6a44a3SBarry Smith   }
210de6a44a3SBarry Smith   a->diag = diag;
2113a40ed3dSBarry Smith   PetscFunctionReturn(0);
212de6a44a3SBarry Smith }
2132593348eSBarry Smith 
2142593348eSBarry Smith 
215ca44d042SBarry Smith EXTERN int MatToSymmetricIJ_SeqAIJ(int,int*,int*,int,int,int**,int**);
2163b2fbd54SBarry Smith 
2174a2ae208SSatish Balay #undef __FUNCT__
2184a2ae208SSatish Balay #define __FUNCT__ "MatGetRowIJ_SeqBAIJ"
2190e6d2581SBarry Smith static int MatGetRowIJ_SeqBAIJ(Mat A,int oshift,PetscTruth symmetric,int *nn,int **ia,int **ja,PetscTruth *done)
2203b2fbd54SBarry Smith {
2213b2fbd54SBarry Smith   Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)A->data;
2223b2fbd54SBarry Smith   int         ierr,n = a->mbs,i;
2233b2fbd54SBarry Smith 
2243a40ed3dSBarry Smith   PetscFunctionBegin;
2253b2fbd54SBarry Smith   *nn = n;
2263a40ed3dSBarry Smith   if (!ia) PetscFunctionReturn(0);
2273b2fbd54SBarry Smith   if (symmetric) {
2283b2fbd54SBarry Smith     ierr = MatToSymmetricIJ_SeqAIJ(n,a->i,a->j,0,oshift,ia,ja);CHKERRQ(ierr);
2293b2fbd54SBarry Smith   } else if (oshift == 1) {
2303b2fbd54SBarry Smith     /* temporarily add 1 to i and j indices */
231435da068SBarry Smith     int nz = a->i[n];
2323b2fbd54SBarry Smith     for (i=0; i<nz; i++) a->j[i]++;
2333b2fbd54SBarry Smith     for (i=0; i<n+1; i++) a->i[i]++;
2343b2fbd54SBarry Smith     *ia = a->i; *ja = a->j;
2353b2fbd54SBarry Smith   } else {
2363b2fbd54SBarry Smith     *ia = a->i; *ja = a->j;
2373b2fbd54SBarry Smith   }
2383b2fbd54SBarry Smith 
2393a40ed3dSBarry Smith   PetscFunctionReturn(0);
2403b2fbd54SBarry Smith }
2413b2fbd54SBarry Smith 
2424a2ae208SSatish Balay #undef __FUNCT__
2434a2ae208SSatish Balay #define __FUNCT__ "MatRestoreRowIJ_SeqBAIJ"
244435da068SBarry Smith static int MatRestoreRowIJ_SeqBAIJ(Mat A,int oshift,PetscTruth symmetric,int *nn,int **ia,int **ja,PetscTruth *done)
2453b2fbd54SBarry Smith {
2463b2fbd54SBarry Smith   Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)A->data;
247606d414cSSatish Balay   int         i,n = a->mbs,ierr;
2483b2fbd54SBarry Smith 
2493a40ed3dSBarry Smith   PetscFunctionBegin;
2503a40ed3dSBarry Smith   if (!ia) PetscFunctionReturn(0);
2513b2fbd54SBarry Smith   if (symmetric) {
252606d414cSSatish Balay     ierr = PetscFree(*ia);CHKERRQ(ierr);
253606d414cSSatish Balay     ierr = PetscFree(*ja);CHKERRQ(ierr);
254af5da2bfSBarry Smith   } else if (oshift == 1) {
255435da068SBarry Smith     int nz = a->i[n]-1;
2563b2fbd54SBarry Smith     for (i=0; i<nz; i++) a->j[i]--;
2573b2fbd54SBarry Smith     for (i=0; i<n+1; i++) a->i[i]--;
2583b2fbd54SBarry Smith   }
2593a40ed3dSBarry Smith   PetscFunctionReturn(0);
2603b2fbd54SBarry Smith }
2613b2fbd54SBarry Smith 
2624a2ae208SSatish Balay #undef __FUNCT__
2634a2ae208SSatish Balay #define __FUNCT__ "MatGetBlockSize_SeqBAIJ"
2642d61bbb3SSatish Balay int MatGetBlockSize_SeqBAIJ(Mat mat,int *bs)
2652d61bbb3SSatish Balay {
2662d61bbb3SSatish Balay   Mat_SeqBAIJ *baij = (Mat_SeqBAIJ*)mat->data;
2672d61bbb3SSatish Balay 
2682d61bbb3SSatish Balay   PetscFunctionBegin;
2692d61bbb3SSatish Balay   *bs = baij->bs;
2702d61bbb3SSatish Balay   PetscFunctionReturn(0);
2712d61bbb3SSatish Balay }
2722d61bbb3SSatish Balay 
2732d61bbb3SSatish Balay 
2744a2ae208SSatish Balay #undef __FUNCT__
2754a2ae208SSatish Balay #define __FUNCT__ "MatDestroy_SeqBAIJ"
276e1311b90SBarry Smith int MatDestroy_SeqBAIJ(Mat A)
2772d61bbb3SSatish Balay {
2782d61bbb3SSatish Balay   Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)A->data;
279e51c0b9cSSatish Balay   int         ierr;
2802d61bbb3SSatish Balay 
281433994e6SBarry Smith   PetscFunctionBegin;
282aa482453SBarry Smith #if defined(PETSC_USE_LOG)
283b0a32e0cSBarry Smith   PetscLogObjectState((PetscObject)A,"Rows=%d, Cols=%d, NZ=%d",A->m,A->n,a->nz);
2842d61bbb3SSatish Balay #endif
285606d414cSSatish Balay   ierr = PetscFree(a->a);CHKERRQ(ierr);
286606d414cSSatish Balay   if (!a->singlemalloc) {
287606d414cSSatish Balay     ierr = PetscFree(a->i);CHKERRQ(ierr);
288606d414cSSatish Balay     ierr = PetscFree(a->j);CHKERRQ(ierr);
289606d414cSSatish Balay   }
290c38d4ed2SBarry Smith   if (a->row) {
291c38d4ed2SBarry Smith     ierr = ISDestroy(a->row);CHKERRQ(ierr);
292c38d4ed2SBarry Smith   }
293c38d4ed2SBarry Smith   if (a->col) {
294c38d4ed2SBarry Smith     ierr = ISDestroy(a->col);CHKERRQ(ierr);
295c38d4ed2SBarry Smith   }
296606d414cSSatish Balay   if (a->diag) {ierr = PetscFree(a->diag);CHKERRQ(ierr);}
297606d414cSSatish Balay   if (a->ilen) {ierr = PetscFree(a->ilen);CHKERRQ(ierr);}
298606d414cSSatish Balay   if (a->imax) {ierr = PetscFree(a->imax);CHKERRQ(ierr);}
299606d414cSSatish Balay   if (a->solve_work) {ierr = PetscFree(a->solve_work);CHKERRQ(ierr);}
300606d414cSSatish Balay   if (a->mult_work) {ierr = PetscFree(a->mult_work);CHKERRQ(ierr);}
301e51c0b9cSSatish Balay   if (a->icol) {ierr = ISDestroy(a->icol);CHKERRQ(ierr);}
302606d414cSSatish Balay   if (a->saved_values) {ierr = PetscFree(a->saved_values);CHKERRQ(ierr);}
303563b5814SBarry Smith #if defined(PETSC_USE_MAT_SINGLE)
304563b5814SBarry Smith   if (a->setvaluescopy) {ierr = PetscFree(a->setvaluescopy);CHKERRQ(ierr);}
305563b5814SBarry Smith #endif
306606d414cSSatish Balay   ierr = PetscFree(a);CHKERRQ(ierr);
3072d61bbb3SSatish Balay   PetscFunctionReturn(0);
3082d61bbb3SSatish Balay }
3092d61bbb3SSatish Balay 
3104a2ae208SSatish Balay #undef __FUNCT__
3114a2ae208SSatish Balay #define __FUNCT__ "MatSetOption_SeqBAIJ"
3122d61bbb3SSatish Balay int MatSetOption_SeqBAIJ(Mat A,MatOption op)
3132d61bbb3SSatish Balay {
3142d61bbb3SSatish Balay   Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)A->data;
3152d61bbb3SSatish Balay 
3162d61bbb3SSatish Balay   PetscFunctionBegin;
317aa275fccSKris Buschelman   switch (op) {
318aa275fccSKris Buschelman   case MAT_ROW_ORIENTED:
319aa275fccSKris Buschelman     a->roworiented    = PETSC_TRUE;
320aa275fccSKris Buschelman     break;
321aa275fccSKris Buschelman   case MAT_COLUMN_ORIENTED:
322aa275fccSKris Buschelman     a->roworiented    = PETSC_FALSE;
323aa275fccSKris Buschelman     break;
324aa275fccSKris Buschelman   case MAT_COLUMNS_SORTED:
325aa275fccSKris Buschelman     a->sorted         = PETSC_TRUE;
326aa275fccSKris Buschelman     break;
327aa275fccSKris Buschelman   case MAT_COLUMNS_UNSORTED:
328aa275fccSKris Buschelman     a->sorted         = PETSC_FALSE;
329aa275fccSKris Buschelman     break;
330aa275fccSKris Buschelman   case MAT_KEEP_ZEROED_ROWS:
331aa275fccSKris Buschelman     a->keepzeroedrows = PETSC_TRUE;
332aa275fccSKris Buschelman     break;
333aa275fccSKris Buschelman   case MAT_NO_NEW_NONZERO_LOCATIONS:
334aa275fccSKris Buschelman     a->nonew          = 1;
335aa275fccSKris Buschelman     break;
336aa275fccSKris Buschelman   case MAT_NEW_NONZERO_LOCATION_ERR:
337aa275fccSKris Buschelman     a->nonew          = -1;
338aa275fccSKris Buschelman     break;
339aa275fccSKris Buschelman   case MAT_NEW_NONZERO_ALLOCATION_ERR:
340aa275fccSKris Buschelman     a->nonew          = -2;
341aa275fccSKris Buschelman     break;
342aa275fccSKris Buschelman   case MAT_YES_NEW_NONZERO_LOCATIONS:
343aa275fccSKris Buschelman     a->nonew          = 0;
344aa275fccSKris Buschelman     break;
345aa275fccSKris Buschelman   case MAT_ROWS_SORTED:
346aa275fccSKris Buschelman   case MAT_ROWS_UNSORTED:
347aa275fccSKris Buschelman   case MAT_YES_NEW_DIAGONALS:
348aa275fccSKris Buschelman   case MAT_IGNORE_OFF_PROC_ENTRIES:
349aa275fccSKris Buschelman   case MAT_USE_HASH_TABLE:
350b0a32e0cSBarry Smith     PetscLogInfo(A,"MatSetOption_SeqBAIJ:Option ignored\n");
351aa275fccSKris Buschelman     break;
352aa275fccSKris Buschelman   case MAT_NO_NEW_DIAGONALS:
35329bbc08cSBarry Smith     SETERRQ(PETSC_ERR_SUP,"MAT_NO_NEW_DIAGONALS");
354aa275fccSKris Buschelman   default:
35529bbc08cSBarry Smith     SETERRQ(PETSC_ERR_SUP,"unknown option");
3562d61bbb3SSatish Balay   }
3572d61bbb3SSatish Balay   PetscFunctionReturn(0);
3582d61bbb3SSatish Balay }
3592d61bbb3SSatish Balay 
3604a2ae208SSatish Balay #undef __FUNCT__
3614a2ae208SSatish Balay #define __FUNCT__ "MatGetRow_SeqBAIJ"
36287828ca2SBarry Smith int MatGetRow_SeqBAIJ(Mat A,int row,int *nz,int **idx,PetscScalar **v)
3632d61bbb3SSatish Balay {
3642d61bbb3SSatish Balay   Mat_SeqBAIJ  *a = (Mat_SeqBAIJ*)A->data;
36582502324SSatish Balay   int          itmp,i,j,k,M,*ai,*aj,bs,bn,bp,*idx_i,bs2,ierr;
3663f1db9ecSBarry Smith   MatScalar    *aa,*aa_i;
36787828ca2SBarry Smith   PetscScalar  *v_i;
3682d61bbb3SSatish Balay 
3692d61bbb3SSatish Balay   PetscFunctionBegin;
3702d61bbb3SSatish Balay   bs  = a->bs;
3712d61bbb3SSatish Balay   ai  = a->i;
3722d61bbb3SSatish Balay   aj  = a->j;
3732d61bbb3SSatish Balay   aa  = a->a;
3742d61bbb3SSatish Balay   bs2 = a->bs2;
3752d61bbb3SSatish Balay 
376273d9f13SBarry Smith   if (row < 0 || row >= A->m) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Row out of range");
3772d61bbb3SSatish Balay 
3782d61bbb3SSatish Balay   bn  = row/bs;   /* Block number */
3792d61bbb3SSatish Balay   bp  = row % bs; /* Block Position */
3802d61bbb3SSatish Balay   M   = ai[bn+1] - ai[bn];
3812d61bbb3SSatish Balay   *nz = bs*M;
3822d61bbb3SSatish Balay 
3832d61bbb3SSatish Balay   if (v) {
3842d61bbb3SSatish Balay     *v = 0;
3852d61bbb3SSatish Balay     if (*nz) {
38687828ca2SBarry Smith       ierr = PetscMalloc((*nz)*sizeof(PetscScalar),v);CHKERRQ(ierr);
3872d61bbb3SSatish Balay       for (i=0; i<M; i++) { /* for each block in the block row */
3882d61bbb3SSatish Balay         v_i  = *v + i*bs;
3892d61bbb3SSatish Balay         aa_i = aa + bs2*(ai[bn] + i);
3902d61bbb3SSatish Balay         for (j=bp,k=0; j<bs2; j+=bs,k++) {v_i[k] = aa_i[j];}
3912d61bbb3SSatish Balay       }
3922d61bbb3SSatish Balay     }
3932d61bbb3SSatish Balay   }
3942d61bbb3SSatish Balay 
3952d61bbb3SSatish Balay   if (idx) {
3962d61bbb3SSatish Balay     *idx = 0;
3972d61bbb3SSatish Balay     if (*nz) {
398b0a32e0cSBarry Smith       ierr = PetscMalloc((*nz)*sizeof(int),idx);CHKERRQ(ierr);
3992d61bbb3SSatish Balay       for (i=0; i<M; i++) { /* for each block in the block row */
4002d61bbb3SSatish Balay         idx_i = *idx + i*bs;
4012d61bbb3SSatish Balay         itmp  = bs*aj[ai[bn] + i];
4022d61bbb3SSatish Balay         for (j=0; j<bs; j++) {idx_i[j] = itmp++;}
4032d61bbb3SSatish Balay       }
4042d61bbb3SSatish Balay     }
4052d61bbb3SSatish Balay   }
4062d61bbb3SSatish Balay   PetscFunctionReturn(0);
4072d61bbb3SSatish Balay }
4082d61bbb3SSatish Balay 
4094a2ae208SSatish Balay #undef __FUNCT__
4104a2ae208SSatish Balay #define __FUNCT__ "MatRestoreRow_SeqBAIJ"
41187828ca2SBarry Smith int MatRestoreRow_SeqBAIJ(Mat A,int row,int *nz,int **idx,PetscScalar **v)
4122d61bbb3SSatish Balay {
413606d414cSSatish Balay   int ierr;
414606d414cSSatish Balay 
4152d61bbb3SSatish Balay   PetscFunctionBegin;
416606d414cSSatish Balay   if (idx) {if (*idx) {ierr = PetscFree(*idx);CHKERRQ(ierr);}}
417606d414cSSatish Balay   if (v)   {if (*v)   {ierr = PetscFree(*v);CHKERRQ(ierr);}}
4182d61bbb3SSatish Balay   PetscFunctionReturn(0);
4192d61bbb3SSatish Balay }
4202d61bbb3SSatish Balay 
4214a2ae208SSatish Balay #undef __FUNCT__
4224a2ae208SSatish Balay #define __FUNCT__ "MatTranspose_SeqBAIJ"
4232d61bbb3SSatish Balay int MatTranspose_SeqBAIJ(Mat A,Mat *B)
4242d61bbb3SSatish Balay {
4252d61bbb3SSatish Balay   Mat_SeqBAIJ *a=(Mat_SeqBAIJ *)A->data;
4262d61bbb3SSatish Balay   Mat         C;
4272d61bbb3SSatish Balay   int         i,j,k,ierr,*aj=a->j,*ai=a->i,bs=a->bs,mbs=a->mbs,nbs=a->nbs,len,*col;
428273d9f13SBarry Smith   int         *rows,*cols,bs2=a->bs2;
42987828ca2SBarry Smith   PetscScalar *array;
4302d61bbb3SSatish Balay 
4312d61bbb3SSatish Balay   PetscFunctionBegin;
43229bbc08cSBarry Smith   if (!B && mbs!=nbs) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Square matrix only for in-place");
433b0a32e0cSBarry Smith   ierr = PetscMalloc((1+nbs)*sizeof(int),&col);CHKERRQ(ierr);
434549d3d68SSatish Balay   ierr = PetscMemzero(col,(1+nbs)*sizeof(int));CHKERRQ(ierr);
4352d61bbb3SSatish Balay 
436375fe846SBarry Smith #if defined(PETSC_USE_MAT_SINGLE)
43787828ca2SBarry Smith   ierr = PetscMalloc(a->bs2*a->nz*sizeof(PetscScalar),&array);CHKERRQ(ierr);
43887828ca2SBarry Smith   for (i=0; i<a->bs2*a->nz; i++) array[i] = (PetscScalar)a->a[i];
439375fe846SBarry Smith #else
4403eda8832SBarry Smith   array = a->a;
441375fe846SBarry Smith #endif
442375fe846SBarry Smith 
4432d61bbb3SSatish Balay   for (i=0; i<ai[mbs]; i++) col[aj[i]] += 1;
444273d9f13SBarry Smith   ierr = MatCreateSeqBAIJ(A->comm,bs,A->n,A->m,PETSC_NULL,col,&C);CHKERRQ(ierr);
445606d414cSSatish Balay   ierr = PetscFree(col);CHKERRQ(ierr);
446b0a32e0cSBarry Smith   ierr = PetscMalloc(2*bs*sizeof(int),&rows);CHKERRQ(ierr);
4472d61bbb3SSatish Balay   cols = rows + bs;
4482d61bbb3SSatish Balay   for (i=0; i<mbs; i++) {
4492d61bbb3SSatish Balay     cols[0] = i*bs;
4502d61bbb3SSatish Balay     for (k=1; k<bs; k++) cols[k] = cols[k-1] + 1;
4512d61bbb3SSatish Balay     len = ai[i+1] - ai[i];
4522d61bbb3SSatish Balay     for (j=0; j<len; j++) {
4532d61bbb3SSatish Balay       rows[0] = (*aj++)*bs;
4542d61bbb3SSatish Balay       for (k=1; k<bs; k++) rows[k] = rows[k-1] + 1;
4552d61bbb3SSatish Balay       ierr = MatSetValues(C,bs,rows,bs,cols,array,INSERT_VALUES);CHKERRQ(ierr);
4562d61bbb3SSatish Balay       array += bs2;
4572d61bbb3SSatish Balay     }
4582d61bbb3SSatish Balay   }
459606d414cSSatish Balay   ierr = PetscFree(rows);CHKERRQ(ierr);
460375fe846SBarry Smith #if defined(PETSC_USE_MAT_SINGLE)
461375fe846SBarry Smith   ierr = PetscFree(array);
462375fe846SBarry Smith #endif
4632d61bbb3SSatish Balay 
4642d61bbb3SSatish Balay   ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
4652d61bbb3SSatish Balay   ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
4662d61bbb3SSatish Balay 
467c4992f7dSBarry Smith   if (B) {
4682d61bbb3SSatish Balay     *B = C;
4692d61bbb3SSatish Balay   } else {
470273d9f13SBarry Smith     ierr = MatHeaderCopy(A,C);CHKERRQ(ierr);
4712d61bbb3SSatish Balay   }
4722d61bbb3SSatish Balay   PetscFunctionReturn(0);
4732d61bbb3SSatish Balay }
4742d61bbb3SSatish Balay 
4754a2ae208SSatish Balay #undef __FUNCT__
4764a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqBAIJ_Binary"
477b0a32e0cSBarry Smith static int MatView_SeqBAIJ_Binary(Mat A,PetscViewer viewer)
4782593348eSBarry Smith {
479b6490206SBarry Smith   Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)A->data;
4809df24120SSatish Balay   int         i,fd,*col_lens,ierr,bs = a->bs,count,*jj,j,k,l,bs2=a->bs2;
48187828ca2SBarry Smith   PetscScalar *aa;
482ce6f0cecSBarry Smith   FILE        *file;
4832593348eSBarry Smith 
4843a40ed3dSBarry Smith   PetscFunctionBegin;
485b0a32e0cSBarry Smith   ierr        = PetscViewerBinaryGetDescriptor(viewer,&fd);CHKERRQ(ierr);
486b0a32e0cSBarry Smith   ierr        = PetscMalloc((4+A->m)*sizeof(int),&col_lens);CHKERRQ(ierr);
487552e946dSBarry Smith   col_lens[0] = MAT_FILE_COOKIE;
4883b2fbd54SBarry Smith 
489273d9f13SBarry Smith   col_lens[1] = A->m;
490273d9f13SBarry Smith   col_lens[2] = A->n;
4917e67e3f9SSatish Balay   col_lens[3] = a->nz*bs2;
4922593348eSBarry Smith 
4932593348eSBarry Smith   /* store lengths of each row and write (including header) to file */
494b6490206SBarry Smith   count = 0;
495b6490206SBarry Smith   for (i=0; i<a->mbs; i++) {
496b6490206SBarry Smith     for (j=0; j<bs; j++) {
497b6490206SBarry Smith       col_lens[4+count++] = bs*(a->i[i+1] - a->i[i]);
498b6490206SBarry Smith     }
4992593348eSBarry Smith   }
500273d9f13SBarry Smith   ierr = PetscBinaryWrite(fd,col_lens,4+A->m,PETSC_INT,1);CHKERRQ(ierr);
501606d414cSSatish Balay   ierr = PetscFree(col_lens);CHKERRQ(ierr);
5022593348eSBarry Smith 
5032593348eSBarry Smith   /* store column indices (zero start index) */
504b0a32e0cSBarry Smith   ierr  = PetscMalloc((a->nz+1)*bs2*sizeof(int),&jj);CHKERRQ(ierr);
505b6490206SBarry Smith   count = 0;
506b6490206SBarry Smith   for (i=0; i<a->mbs; i++) {
507b6490206SBarry Smith     for (j=0; j<bs; j++) {
508b6490206SBarry Smith       for (k=a->i[i]; k<a->i[i+1]; k++) {
509b6490206SBarry Smith         for (l=0; l<bs; l++) {
510b6490206SBarry Smith           jj[count++] = bs*a->j[k] + l;
5112593348eSBarry Smith         }
5122593348eSBarry Smith       }
513b6490206SBarry Smith     }
514b6490206SBarry Smith   }
5150752156aSBarry Smith   ierr = PetscBinaryWrite(fd,jj,bs2*a->nz,PETSC_INT,0);CHKERRQ(ierr);
516606d414cSSatish Balay   ierr = PetscFree(jj);CHKERRQ(ierr);
5172593348eSBarry Smith 
5182593348eSBarry Smith   /* store nonzero values */
51987828ca2SBarry Smith   ierr  = PetscMalloc((a->nz+1)*bs2*sizeof(PetscScalar),&aa);CHKERRQ(ierr);
520b6490206SBarry Smith   count = 0;
521b6490206SBarry Smith   for (i=0; i<a->mbs; i++) {
522b6490206SBarry Smith     for (j=0; j<bs; j++) {
523b6490206SBarry Smith       for (k=a->i[i]; k<a->i[i+1]; k++) {
524b6490206SBarry Smith         for (l=0; l<bs; l++) {
5257e67e3f9SSatish Balay           aa[count++] = a->a[bs2*k + l*bs + j];
526b6490206SBarry Smith         }
527b6490206SBarry Smith       }
528b6490206SBarry Smith     }
529b6490206SBarry Smith   }
5300752156aSBarry Smith   ierr = PetscBinaryWrite(fd,aa,bs2*a->nz,PETSC_SCALAR,0);CHKERRQ(ierr);
531606d414cSSatish Balay   ierr = PetscFree(aa);CHKERRQ(ierr);
532ce6f0cecSBarry Smith 
533b0a32e0cSBarry Smith   ierr = PetscViewerBinaryGetInfoPointer(viewer,&file);CHKERRQ(ierr);
534ce6f0cecSBarry Smith   if (file) {
535ce6f0cecSBarry Smith     fprintf(file,"-matload_block_size %d\n",a->bs);
536ce6f0cecSBarry Smith   }
5373a40ed3dSBarry Smith   PetscFunctionReturn(0);
5382593348eSBarry Smith }
5392593348eSBarry Smith 
54004929863SHong Zhang extern int MatMPIBAIJFactorInfo_DSCPACK(Mat,PetscViewer);
54104929863SHong Zhang 
5424a2ae208SSatish Balay #undef __FUNCT__
5434a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqBAIJ_ASCII"
544b0a32e0cSBarry Smith static int MatView_SeqBAIJ_ASCII(Mat A,PetscViewer viewer)
5452593348eSBarry Smith {
546b6490206SBarry Smith   Mat_SeqBAIJ       *a = (Mat_SeqBAIJ*)A->data;
547fb9695e5SSatish Balay   int               ierr,i,j,bs = a->bs,k,l,bs2=a->bs2;
548f3ef73ceSBarry Smith   PetscViewerFormat format;
5492593348eSBarry Smith 
5503a40ed3dSBarry Smith   PetscFunctionBegin;
551b0a32e0cSBarry Smith   ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr);
552456192e2SBarry Smith   if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) {
553b0a32e0cSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  block size is %d\n",bs);CHKERRQ(ierr);
554fb9695e5SSatish Balay   } else if (format == PETSC_VIEWER_ASCII_MATLAB) {
555bcd9e38bSBarry Smith     Mat aij;
556bcd9e38bSBarry Smith     ierr = MatConvert(A,MATSEQAIJ,&aij);CHKERRQ(ierr);
557bcd9e38bSBarry Smith     ierr = MatView(aij,viewer);CHKERRQ(ierr);
558bcd9e38bSBarry Smith     ierr = MatDestroy(aij);CHKERRQ(ierr);
55904929863SHong Zhang   } else if (format == PETSC_VIEWER_ASCII_FACTOR_INFO) {
56004929863SHong Zhang #if defined(PETSC_HAVE_DSCPACK) && !defined(PETSC_USE_SINGLE) && !defined(PETSC_USE_COMPLEX)
56104929863SHong Zhang      ierr = MatMPIBAIJFactorInfo_DSCPACK(A,viewer);CHKERRQ(ierr);
56204929863SHong Zhang #endif
56304929863SHong Zhang      PetscFunctionReturn(0);
564fb9695e5SSatish Balay   } else if (format == PETSC_VIEWER_ASCII_COMMON) {
565b0a32e0cSBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_NO);CHKERRQ(ierr);
56644cd7ae7SLois Curfman McInnes     for (i=0; i<a->mbs; i++) {
56744cd7ae7SLois Curfman McInnes       for (j=0; j<bs; j++) {
568b0a32e0cSBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"row %d:",i*bs+j);CHKERRQ(ierr);
56944cd7ae7SLois Curfman McInnes         for (k=a->i[i]; k<a->i[i+1]; k++) {
57044cd7ae7SLois Curfman McInnes           for (l=0; l<bs; l++) {
571aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
5720e6d2581SBarry Smith             if (PetscImaginaryPart(a->a[bs2*k + l*bs + j]) > 0.0 && PetscRealPart(a->a[bs2*k + l*bs + j]) != 0.0) {
57362b941d6SBarry Smith               ierr = PetscViewerASCIIPrintf(viewer," (%d, %g + %gi) ",bs*a->j[k]+l,
5740e6d2581SBarry Smith                       PetscRealPart(a->a[bs2*k + l*bs + j]),PetscImaginaryPart(a->a[bs2*k + l*bs + j]));CHKERRQ(ierr);
5750e6d2581SBarry Smith             } else if (PetscImaginaryPart(a->a[bs2*k + l*bs + j]) < 0.0 && PetscRealPart(a->a[bs2*k + l*bs + j]) != 0.0) {
57662b941d6SBarry Smith               ierr = PetscViewerASCIIPrintf(viewer," (%d, %g - %gi) ",bs*a->j[k]+l,
5770e6d2581SBarry Smith                       PetscRealPart(a->a[bs2*k + l*bs + j]),-PetscImaginaryPart(a->a[bs2*k + l*bs + j]));CHKERRQ(ierr);
5780e6d2581SBarry Smith             } else if (PetscRealPart(a->a[bs2*k + l*bs + j]) != 0.0) {
57962b941d6SBarry Smith               ierr = PetscViewerASCIIPrintf(viewer," (%d, %g) ",bs*a->j[k]+l,PetscRealPart(a->a[bs2*k + l*bs + j]));CHKERRQ(ierr);
5800ef38995SBarry Smith             }
58144cd7ae7SLois Curfman McInnes #else
5820ef38995SBarry Smith             if (a->a[bs2*k + l*bs + j] != 0.0) {
58362b941d6SBarry Smith               ierr = PetscViewerASCIIPrintf(viewer," (%d, %g) ",bs*a->j[k]+l,a->a[bs2*k + l*bs + j]);CHKERRQ(ierr);
5840ef38995SBarry Smith             }
58544cd7ae7SLois Curfman McInnes #endif
58644cd7ae7SLois Curfman McInnes           }
58744cd7ae7SLois Curfman McInnes         }
588b0a32e0cSBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
58944cd7ae7SLois Curfman McInnes       }
59044cd7ae7SLois Curfman McInnes     }
591b0a32e0cSBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_YES);CHKERRQ(ierr);
5920ef38995SBarry Smith   } else {
593b0a32e0cSBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_NO);CHKERRQ(ierr);
594b6490206SBarry Smith     for (i=0; i<a->mbs; i++) {
595b6490206SBarry Smith       for (j=0; j<bs; j++) {
596b0a32e0cSBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"row %d:",i*bs+j);CHKERRQ(ierr);
597b6490206SBarry Smith         for (k=a->i[i]; k<a->i[i+1]; k++) {
598b6490206SBarry Smith           for (l=0; l<bs; l++) {
599aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
6000e6d2581SBarry Smith             if (PetscImaginaryPart(a->a[bs2*k + l*bs + j]) > 0.0) {
60162b941d6SBarry Smith               ierr = PetscViewerASCIIPrintf(viewer," (%d, %g + %g i) ",bs*a->j[k]+l,
6020e6d2581SBarry Smith                 PetscRealPart(a->a[bs2*k + l*bs + j]),PetscImaginaryPart(a->a[bs2*k + l*bs + j]));CHKERRQ(ierr);
6030e6d2581SBarry Smith             } else if (PetscImaginaryPart(a->a[bs2*k + l*bs + j]) < 0.0) {
60462b941d6SBarry Smith               ierr = PetscViewerASCIIPrintf(viewer," (%d, %g - %g i) ",bs*a->j[k]+l,
6050e6d2581SBarry Smith                 PetscRealPart(a->a[bs2*k + l*bs + j]),-PetscImaginaryPart(a->a[bs2*k + l*bs + j]));CHKERRQ(ierr);
6060ef38995SBarry Smith             } else {
60762b941d6SBarry Smith               ierr = PetscViewerASCIIPrintf(viewer," (%d, %g) ",bs*a->j[k]+l,PetscRealPart(a->a[bs2*k + l*bs + j]));CHKERRQ(ierr);
60888685aaeSLois Curfman McInnes             }
60988685aaeSLois Curfman McInnes #else
61062b941d6SBarry Smith             ierr = PetscViewerASCIIPrintf(viewer," (%d, %g) ",bs*a->j[k]+l,a->a[bs2*k + l*bs + j]);CHKERRQ(ierr);
61188685aaeSLois Curfman McInnes #endif
6122593348eSBarry Smith           }
6132593348eSBarry Smith         }
614b0a32e0cSBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
6152593348eSBarry Smith       }
6162593348eSBarry Smith     }
617b0a32e0cSBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_YES);CHKERRQ(ierr);
618b6490206SBarry Smith   }
619b0a32e0cSBarry Smith   ierr = PetscViewerFlush(viewer);CHKERRQ(ierr);
6203a40ed3dSBarry Smith   PetscFunctionReturn(0);
6212593348eSBarry Smith }
6222593348eSBarry Smith 
6234a2ae208SSatish Balay #undef __FUNCT__
6244a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqBAIJ_Draw_Zoom"
625b0a32e0cSBarry Smith static int MatView_SeqBAIJ_Draw_Zoom(PetscDraw draw,void *Aa)
6263270192aSSatish Balay {
62777ed5343SBarry Smith   Mat          A = (Mat) Aa;
6283270192aSSatish Balay   Mat_SeqBAIJ  *a=(Mat_SeqBAIJ*)A->data;
629b65db4caSBarry Smith   int          row,ierr,i,j,k,l,mbs=a->mbs,color,bs=a->bs,bs2=a->bs2;
6300e6d2581SBarry Smith   PetscReal    xl,yl,xr,yr,x_l,x_r,y_l,y_r;
6313f1db9ecSBarry Smith   MatScalar    *aa;
632b0a32e0cSBarry Smith   PetscViewer  viewer;
6333270192aSSatish Balay 
6343a40ed3dSBarry Smith   PetscFunctionBegin;
6353270192aSSatish Balay 
636b65db4caSBarry Smith   /* still need to add support for contour plot of nonzeros; see MatView_SeqAIJ_Draw_Zoom()*/
63777ed5343SBarry Smith   ierr = PetscObjectQuery((PetscObject)A,"Zoomviewer",(PetscObject*)&viewer);CHKERRQ(ierr);
63877ed5343SBarry Smith 
639b0a32e0cSBarry Smith   ierr = PetscDrawGetCoordinates(draw,&xl,&yl,&xr,&yr);CHKERRQ(ierr);
64077ed5343SBarry Smith 
6413270192aSSatish Balay   /* loop over matrix elements drawing boxes */
642b0a32e0cSBarry Smith   color = PETSC_DRAW_BLUE;
6433270192aSSatish Balay   for (i=0,row=0; i<mbs; i++,row+=bs) {
6443270192aSSatish Balay     for (j=a->i[i]; j<a->i[i+1]; j++) {
645273d9f13SBarry Smith       y_l = A->m - row - 1.0; y_r = y_l + 1.0;
6463270192aSSatish Balay       x_l = a->j[j]*bs; x_r = x_l + 1.0;
6473270192aSSatish Balay       aa = a->a + j*bs2;
6483270192aSSatish Balay       for (k=0; k<bs; k++) {
6493270192aSSatish Balay         for (l=0; l<bs; l++) {
6500e6d2581SBarry Smith           if (PetscRealPart(*aa++) >=  0.) continue;
651b0a32e0cSBarry Smith           ierr = PetscDrawRectangle(draw,x_l+k,y_l-l,x_r+k,y_r-l,color,color,color,color);CHKERRQ(ierr);
6523270192aSSatish Balay         }
6533270192aSSatish Balay       }
6543270192aSSatish Balay     }
6553270192aSSatish Balay   }
656b0a32e0cSBarry Smith   color = PETSC_DRAW_CYAN;
6573270192aSSatish Balay   for (i=0,row=0; i<mbs; i++,row+=bs) {
6583270192aSSatish Balay     for (j=a->i[i]; j<a->i[i+1]; j++) {
659273d9f13SBarry Smith       y_l = A->m - row - 1.0; y_r = y_l + 1.0;
6603270192aSSatish Balay       x_l = a->j[j]*bs; x_r = x_l + 1.0;
6613270192aSSatish Balay       aa = a->a + j*bs2;
6623270192aSSatish Balay       for (k=0; k<bs; k++) {
6633270192aSSatish Balay         for (l=0; l<bs; l++) {
6640e6d2581SBarry Smith           if (PetscRealPart(*aa++) != 0.) continue;
665b0a32e0cSBarry Smith           ierr = PetscDrawRectangle(draw,x_l+k,y_l-l,x_r+k,y_r-l,color,color,color,color);CHKERRQ(ierr);
6663270192aSSatish Balay         }
6673270192aSSatish Balay       }
6683270192aSSatish Balay     }
6693270192aSSatish Balay   }
6703270192aSSatish Balay 
671b0a32e0cSBarry Smith   color = PETSC_DRAW_RED;
6723270192aSSatish Balay   for (i=0,row=0; i<mbs; i++,row+=bs) {
6733270192aSSatish Balay     for (j=a->i[i]; j<a->i[i+1]; j++) {
674273d9f13SBarry Smith       y_l = A->m - row - 1.0; y_r = y_l + 1.0;
6753270192aSSatish Balay       x_l = a->j[j]*bs; x_r = x_l + 1.0;
6763270192aSSatish Balay       aa = a->a + j*bs2;
6773270192aSSatish Balay       for (k=0; k<bs; k++) {
6783270192aSSatish Balay         for (l=0; l<bs; l++) {
6790e6d2581SBarry Smith           if (PetscRealPart(*aa++) <= 0.) continue;
680b0a32e0cSBarry Smith           ierr = PetscDrawRectangle(draw,x_l+k,y_l-l,x_r+k,y_r-l,color,color,color,color);CHKERRQ(ierr);
6813270192aSSatish Balay         }
6823270192aSSatish Balay       }
6833270192aSSatish Balay     }
6843270192aSSatish Balay   }
68577ed5343SBarry Smith   PetscFunctionReturn(0);
68677ed5343SBarry Smith }
6873270192aSSatish Balay 
6884a2ae208SSatish Balay #undef __FUNCT__
6894a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqBAIJ_Draw"
690b0a32e0cSBarry Smith static int MatView_SeqBAIJ_Draw(Mat A,PetscViewer viewer)
69177ed5343SBarry Smith {
6927dce120fSSatish Balay   int          ierr;
6930e6d2581SBarry Smith   PetscReal    xl,yl,xr,yr,w,h;
694b0a32e0cSBarry Smith   PetscDraw    draw;
69577ed5343SBarry Smith   PetscTruth   isnull;
6963270192aSSatish Balay 
69777ed5343SBarry Smith   PetscFunctionBegin;
69877ed5343SBarry Smith 
699b0a32e0cSBarry Smith   ierr = PetscViewerDrawGetDraw(viewer,0,&draw);CHKERRQ(ierr);
700b0a32e0cSBarry Smith   ierr = PetscDrawIsNull(draw,&isnull);CHKERRQ(ierr); if (isnull) PetscFunctionReturn(0);
70177ed5343SBarry Smith 
70277ed5343SBarry Smith   ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",(PetscObject)viewer);CHKERRQ(ierr);
703273d9f13SBarry Smith   xr  = A->n; yr = A->m; h = yr/10.0; w = xr/10.0;
70477ed5343SBarry Smith   xr += w;    yr += h;  xl = -w;     yl = -h;
705b0a32e0cSBarry Smith   ierr = PetscDrawSetCoordinates(draw,xl,yl,xr,yr);CHKERRQ(ierr);
706b0a32e0cSBarry Smith   ierr = PetscDrawZoom(draw,MatView_SeqBAIJ_Draw_Zoom,A);CHKERRQ(ierr);
70777ed5343SBarry Smith   ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",PETSC_NULL);CHKERRQ(ierr);
7083a40ed3dSBarry Smith   PetscFunctionReturn(0);
7093270192aSSatish Balay }
7103270192aSSatish Balay 
7114a2ae208SSatish Balay #undef __FUNCT__
7124a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqBAIJ"
713b0a32e0cSBarry Smith int MatView_SeqBAIJ(Mat A,PetscViewer viewer)
7142593348eSBarry Smith {
71519bcc07fSBarry Smith   int        ierr;
7166831982aSBarry Smith   PetscTruth issocket,isascii,isbinary,isdraw;
7172593348eSBarry Smith 
7183a40ed3dSBarry Smith   PetscFunctionBegin;
719b0a32e0cSBarry Smith   ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_SOCKET,&issocket);CHKERRQ(ierr);
720b0a32e0cSBarry Smith   ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&isascii);CHKERRQ(ierr);
721fb9695e5SSatish Balay   ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_BINARY,&isbinary);CHKERRQ(ierr);
722fb9695e5SSatish Balay   ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_DRAW,&isdraw);CHKERRQ(ierr);
7230f5bd95cSBarry Smith   if (issocket) {
72429bbc08cSBarry Smith     SETERRQ(PETSC_ERR_SUP,"Socket viewer not supported");
7250f5bd95cSBarry Smith   } else if (isascii){
7263a40ed3dSBarry Smith     ierr = MatView_SeqBAIJ_ASCII(A,viewer);CHKERRQ(ierr);
7270f5bd95cSBarry Smith   } else if (isbinary) {
7283a40ed3dSBarry Smith     ierr = MatView_SeqBAIJ_Binary(A,viewer);CHKERRQ(ierr);
7290f5bd95cSBarry Smith   } else if (isdraw) {
7303a40ed3dSBarry Smith     ierr = MatView_SeqBAIJ_Draw(A,viewer);CHKERRQ(ierr);
7315cd90555SBarry Smith   } else {
73229bbc08cSBarry Smith     SETERRQ1(1,"Viewer type %s not supported by SeqBAIJ matrices",((PetscObject)viewer)->type_name);
7332593348eSBarry Smith   }
7343a40ed3dSBarry Smith   PetscFunctionReturn(0);
7352593348eSBarry Smith }
736b6490206SBarry Smith 
737cd0e1443SSatish Balay 
7384a2ae208SSatish Balay #undef __FUNCT__
7394a2ae208SSatish Balay #define __FUNCT__ "MatGetValues_SeqBAIJ"
74087828ca2SBarry Smith int MatGetValues_SeqBAIJ(Mat A,int m,int *im,int n,int *in,PetscScalar *v)
741cd0e1443SSatish Balay {
742cd0e1443SSatish Balay   Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)A->data;
7432d61bbb3SSatish Balay   int        *rp,k,low,high,t,row,nrow,i,col,l,*aj = a->j;
7442d61bbb3SSatish Balay   int        *ai = a->i,*ailen = a->ilen;
7452d61bbb3SSatish Balay   int        brow,bcol,ridx,cidx,bs=a->bs,bs2=a->bs2;
7463f1db9ecSBarry Smith   MatScalar  *ap,*aa = a->a,zero = 0.0;
747cd0e1443SSatish Balay 
7483a40ed3dSBarry Smith   PetscFunctionBegin;
7492d61bbb3SSatish Balay   for (k=0; k<m; k++) { /* loop over rows */
750cd0e1443SSatish Balay     row  = im[k]; brow = row/bs;
75129bbc08cSBarry Smith     if (row < 0) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Negative row");
752273d9f13SBarry Smith     if (row >= A->m) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Row too large");
7532d61bbb3SSatish Balay     rp   = aj + ai[brow] ; ap = aa + bs2*ai[brow] ;
7542c3acbe9SBarry Smith     nrow = ailen[brow];
7552d61bbb3SSatish Balay     for (l=0; l<n; l++) { /* loop over columns */
75629bbc08cSBarry Smith       if (in[l] < 0) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Negative column");
757273d9f13SBarry Smith       if (in[l] >= A->n) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Column too large");
7582d61bbb3SSatish Balay       col  = in[l] ;
7592d61bbb3SSatish Balay       bcol = col/bs;
7602d61bbb3SSatish Balay       cidx = col%bs;
7612d61bbb3SSatish Balay       ridx = row%bs;
7622d61bbb3SSatish Balay       high = nrow;
7632d61bbb3SSatish Balay       low  = 0; /* assume unsorted */
7642d61bbb3SSatish Balay       while (high-low > 5) {
765cd0e1443SSatish Balay         t = (low+high)/2;
766cd0e1443SSatish Balay         if (rp[t] > bcol) high = t;
767cd0e1443SSatish Balay         else             low  = t;
768cd0e1443SSatish Balay       }
769cd0e1443SSatish Balay       for (i=low; i<high; i++) {
770cd0e1443SSatish Balay         if (rp[i] > bcol) break;
771cd0e1443SSatish Balay         if (rp[i] == bcol) {
7722d61bbb3SSatish Balay           *v++ = ap[bs2*i+bs*cidx+ridx];
7732d61bbb3SSatish Balay           goto finished;
774cd0e1443SSatish Balay         }
775cd0e1443SSatish Balay       }
7762d61bbb3SSatish Balay       *v++ = zero;
7772d61bbb3SSatish Balay       finished:;
778cd0e1443SSatish Balay     }
779cd0e1443SSatish Balay   }
7803a40ed3dSBarry Smith   PetscFunctionReturn(0);
781cd0e1443SSatish Balay }
782cd0e1443SSatish Balay 
78395d5f7c2SBarry Smith #if defined(PETSC_USE_MAT_SINGLE)
7844a2ae208SSatish Balay #undef __FUNCT__
7854a2ae208SSatish Balay #define __FUNCT__ "MatSetValuesBlocked_SeqBAIJ"
78687828ca2SBarry Smith int MatSetValuesBlocked_SeqBAIJ(Mat mat,int m,int *im,int n,int *in,PetscScalar *v,InsertMode addv)
78795d5f7c2SBarry Smith {
788563b5814SBarry Smith   Mat_SeqBAIJ *b = (Mat_SeqBAIJ*)mat->data;
789563b5814SBarry Smith   int         ierr,i,N = m*n*b->bs2;
790563b5814SBarry Smith   MatScalar   *vsingle;
79195d5f7c2SBarry Smith 
79295d5f7c2SBarry Smith   PetscFunctionBegin;
793563b5814SBarry Smith   if (N > b->setvalueslen) {
794563b5814SBarry Smith     if (b->setvaluescopy) {ierr = PetscFree(b->setvaluescopy);CHKERRQ(ierr);}
795b0a32e0cSBarry Smith     ierr = PetscMalloc(N*sizeof(MatScalar),&b->setvaluescopy);CHKERRQ(ierr);
796563b5814SBarry Smith     b->setvalueslen  = N;
797563b5814SBarry Smith   }
798563b5814SBarry Smith   vsingle = b->setvaluescopy;
79995d5f7c2SBarry Smith   for (i=0; i<N; i++) {
80095d5f7c2SBarry Smith     vsingle[i] = v[i];
80195d5f7c2SBarry Smith   }
80295d5f7c2SBarry Smith   ierr = MatSetValuesBlocked_SeqBAIJ_MatScalar(mat,m,im,n,in,vsingle,addv);CHKERRQ(ierr);
80395d5f7c2SBarry Smith   PetscFunctionReturn(0);
80495d5f7c2SBarry Smith }
80595d5f7c2SBarry Smith #endif
80695d5f7c2SBarry Smith 
8072d61bbb3SSatish Balay 
8084a2ae208SSatish Balay #undef __FUNCT__
8094a2ae208SSatish Balay #define __FUNCT__ "MatSetValuesBlocked_SeqBAIJ"
81095d5f7c2SBarry Smith int MatSetValuesBlocked_SeqBAIJ_MatScalar(Mat A,int m,int *im,int n,int *in,MatScalar *v,InsertMode is)
81192c4ed94SBarry Smith {
81292c4ed94SBarry Smith   Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)A->data;
8138a84c255SSatish Balay   int         *rp,k,low,high,t,ii,jj,row,nrow,i,col,l,rmax,N,sorted=a->sorted;
814273d9f13SBarry Smith   int         *imax=a->imax,*ai=a->i,*ailen=a->ilen;
815549d3d68SSatish Balay   int         *aj=a->j,nonew=a->nonew,bs2=a->bs2,bs=a->bs,stepval,ierr;
816273d9f13SBarry Smith   PetscTruth  roworiented=a->roworiented;
81795d5f7c2SBarry Smith   MatScalar   *value = v,*ap,*aa = a->a,*bap;
81892c4ed94SBarry Smith 
8193a40ed3dSBarry Smith   PetscFunctionBegin;
8200e324ae4SSatish Balay   if (roworiented) {
8210e324ae4SSatish Balay     stepval = (n-1)*bs;
8220e324ae4SSatish Balay   } else {
8230e324ae4SSatish Balay     stepval = (m-1)*bs;
8240e324ae4SSatish Balay   }
82592c4ed94SBarry Smith   for (k=0; k<m; k++) { /* loop over added rows */
82692c4ed94SBarry Smith     row  = im[k];
8275ef9f2a5SBarry Smith     if (row < 0) continue;
828aa482453SBarry Smith #if defined(PETSC_USE_BOPT_g)
82929bbc08cSBarry Smith     if (row >= a->mbs) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Row too large");
83092c4ed94SBarry Smith #endif
83192c4ed94SBarry Smith     rp   = aj + ai[row];
83292c4ed94SBarry Smith     ap   = aa + bs2*ai[row];
83392c4ed94SBarry Smith     rmax = imax[row];
83492c4ed94SBarry Smith     nrow = ailen[row];
83592c4ed94SBarry Smith     low  = 0;
83692c4ed94SBarry Smith     for (l=0; l<n; l++) { /* loop over added columns */
8375ef9f2a5SBarry Smith       if (in[l] < 0) continue;
838aa482453SBarry Smith #if defined(PETSC_USE_BOPT_g)
83929bbc08cSBarry Smith       if (in[l] >= a->nbs) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Column too large");
84092c4ed94SBarry Smith #endif
84192c4ed94SBarry Smith       col = in[l];
84292c4ed94SBarry Smith       if (roworiented) {
8430e324ae4SSatish Balay         value = v + k*(stepval+bs)*bs + l*bs;
8440e324ae4SSatish Balay       } else {
8450e324ae4SSatish Balay         value = v + l*(stepval+bs)*bs + k*bs;
84692c4ed94SBarry Smith       }
84792c4ed94SBarry Smith       if (!sorted) low = 0; high = nrow;
84892c4ed94SBarry Smith       while (high-low > 7) {
84992c4ed94SBarry Smith         t = (low+high)/2;
85092c4ed94SBarry Smith         if (rp[t] > col) high = t;
85192c4ed94SBarry Smith         else             low  = t;
85292c4ed94SBarry Smith       }
85392c4ed94SBarry Smith       for (i=low; i<high; i++) {
85492c4ed94SBarry Smith         if (rp[i] > col) break;
85592c4ed94SBarry Smith         if (rp[i] == col) {
8568a84c255SSatish Balay           bap  = ap +  bs2*i;
8570e324ae4SSatish Balay           if (roworiented) {
8588a84c255SSatish Balay             if (is == ADD_VALUES) {
859dd9472c6SBarry Smith               for (ii=0; ii<bs; ii++,value+=stepval) {
860dd9472c6SBarry Smith                 for (jj=ii; jj<bs2; jj+=bs) {
8618a84c255SSatish Balay                   bap[jj] += *value++;
862dd9472c6SBarry Smith                 }
863dd9472c6SBarry Smith               }
8640e324ae4SSatish Balay             } else {
865dd9472c6SBarry Smith               for (ii=0; ii<bs; ii++,value+=stepval) {
866dd9472c6SBarry Smith                 for (jj=ii; jj<bs2; jj+=bs) {
8670e324ae4SSatish Balay                   bap[jj] = *value++;
8688a84c255SSatish Balay                 }
869dd9472c6SBarry Smith               }
870dd9472c6SBarry Smith             }
8710e324ae4SSatish Balay           } else {
8720e324ae4SSatish Balay             if (is == ADD_VALUES) {
873dd9472c6SBarry Smith               for (ii=0; ii<bs; ii++,value+=stepval) {
874dd9472c6SBarry Smith                 for (jj=0; jj<bs; jj++) {
8750e324ae4SSatish Balay                   *bap++ += *value++;
876dd9472c6SBarry Smith                 }
877dd9472c6SBarry Smith               }
8780e324ae4SSatish Balay             } else {
879dd9472c6SBarry Smith               for (ii=0; ii<bs; ii++,value+=stepval) {
880dd9472c6SBarry Smith                 for (jj=0; jj<bs; jj++) {
8810e324ae4SSatish Balay                   *bap++  = *value++;
8820e324ae4SSatish Balay                 }
8838a84c255SSatish Balay               }
884dd9472c6SBarry Smith             }
885dd9472c6SBarry Smith           }
886f1241b54SBarry Smith           goto noinsert2;
88792c4ed94SBarry Smith         }
88892c4ed94SBarry Smith       }
88989280ab3SLois Curfman McInnes       if (nonew == 1) goto noinsert2;
89029bbc08cSBarry Smith       else if (nonew == -1) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Inserting a new nonzero in the matrix");
89192c4ed94SBarry Smith       if (nrow >= rmax) {
89292c4ed94SBarry Smith         /* there is no extra room in row, therefore enlarge */
89392c4ed94SBarry Smith         int       new_nz = ai[a->mbs] + CHUNKSIZE,len,*new_i,*new_j;
8943f1db9ecSBarry Smith         MatScalar *new_a;
89592c4ed94SBarry Smith 
89629bbc08cSBarry Smith         if (nonew == -2) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Inserting a new nonzero in the matrix");
89789280ab3SLois Curfman McInnes 
89892c4ed94SBarry Smith         /* malloc new storage space */
8993f1db9ecSBarry Smith         len     = new_nz*(sizeof(int)+bs2*sizeof(MatScalar))+(a->mbs+1)*sizeof(int);
900b0a32e0cSBarry Smith 	ierr    = PetscMalloc(len,&new_a);CHKERRQ(ierr);
90192c4ed94SBarry Smith         new_j   = (int*)(new_a + bs2*new_nz);
90292c4ed94SBarry Smith         new_i   = new_j + new_nz;
90392c4ed94SBarry Smith 
90492c4ed94SBarry Smith         /* copy over old data into new slots */
90592c4ed94SBarry Smith         for (ii=0; ii<row+1; ii++) {new_i[ii] = ai[ii];}
90692c4ed94SBarry Smith         for (ii=row+1; ii<a->mbs+1; ii++) {new_i[ii] = ai[ii]+CHUNKSIZE;}
907549d3d68SSatish Balay         ierr = PetscMemcpy(new_j,aj,(ai[row]+nrow)*sizeof(int));CHKERRQ(ierr);
90892c4ed94SBarry Smith         len  = (new_nz - CHUNKSIZE - ai[row] - nrow);
909549d3d68SSatish Balay         ierr = PetscMemcpy(new_j+ai[row]+nrow+CHUNKSIZE,aj+ai[row]+nrow,len*sizeof(int));CHKERRQ(ierr);
910549d3d68SSatish Balay         ierr = PetscMemcpy(new_a,aa,(ai[row]+nrow)*bs2*sizeof(MatScalar));CHKERRQ(ierr);
911549d3d68SSatish Balay         ierr = PetscMemzero(new_a+bs2*(ai[row]+nrow),bs2*CHUNKSIZE*sizeof(MatScalar));CHKERRQ(ierr);
912549d3d68SSatish Balay         ierr = PetscMemcpy(new_a+bs2*(ai[row]+nrow+CHUNKSIZE),aa+bs2*(ai[row]+nrow),bs2*len*sizeof(MatScalar));CHKERRQ(ierr);
91392c4ed94SBarry Smith         /* free up old matrix storage */
914606d414cSSatish Balay         ierr = PetscFree(a->a);CHKERRQ(ierr);
915606d414cSSatish Balay         if (!a->singlemalloc) {
916606d414cSSatish Balay           ierr = PetscFree(a->i);CHKERRQ(ierr);
917606d414cSSatish Balay           ierr = PetscFree(a->j);CHKERRQ(ierr);
918606d414cSSatish Balay         }
91992c4ed94SBarry Smith         aa = a->a = new_a; ai = a->i = new_i; aj = a->j = new_j;
920c4992f7dSBarry Smith         a->singlemalloc = PETSC_TRUE;
92192c4ed94SBarry Smith 
92292c4ed94SBarry Smith         rp   = aj + ai[row]; ap = aa + bs2*ai[row];
92392c4ed94SBarry Smith         rmax = imax[row] = imax[row] + CHUNKSIZE;
924b0a32e0cSBarry Smith         PetscLogObjectMemory(A,CHUNKSIZE*(sizeof(int) + bs2*sizeof(MatScalar)));
92592c4ed94SBarry Smith         a->maxnz += bs2*CHUNKSIZE;
92692c4ed94SBarry Smith         a->reallocs++;
92792c4ed94SBarry Smith         a->nz++;
92892c4ed94SBarry Smith       }
92992c4ed94SBarry Smith       N = nrow++ - 1;
93092c4ed94SBarry Smith       /* shift up all the later entries in this row */
93192c4ed94SBarry Smith       for (ii=N; ii>=i; ii--) {
93292c4ed94SBarry Smith         rp[ii+1] = rp[ii];
933549d3d68SSatish Balay         ierr = PetscMemcpy(ap+bs2*(ii+1),ap+bs2*(ii),bs2*sizeof(MatScalar));CHKERRQ(ierr);
93492c4ed94SBarry Smith       }
935549d3d68SSatish Balay       if (N >= i) {
936549d3d68SSatish Balay         ierr = PetscMemzero(ap+bs2*i,bs2*sizeof(MatScalar));CHKERRQ(ierr);
937549d3d68SSatish Balay       }
93892c4ed94SBarry Smith       rp[i] = col;
9398a84c255SSatish Balay       bap   = ap +  bs2*i;
9400e324ae4SSatish Balay       if (roworiented) {
941dd9472c6SBarry Smith         for (ii=0; ii<bs; ii++,value+=stepval) {
942dd9472c6SBarry Smith           for (jj=ii; jj<bs2; jj+=bs) {
9430e324ae4SSatish Balay             bap[jj] = *value++;
944dd9472c6SBarry Smith           }
945dd9472c6SBarry Smith         }
9460e324ae4SSatish Balay       } else {
947dd9472c6SBarry Smith         for (ii=0; ii<bs; ii++,value+=stepval) {
948dd9472c6SBarry Smith           for (jj=0; jj<bs; jj++) {
9490e324ae4SSatish Balay             *bap++  = *value++;
9500e324ae4SSatish Balay           }
951dd9472c6SBarry Smith         }
952dd9472c6SBarry Smith       }
953f1241b54SBarry Smith       noinsert2:;
95492c4ed94SBarry Smith       low = i;
95592c4ed94SBarry Smith     }
95692c4ed94SBarry Smith     ailen[row] = nrow;
95792c4ed94SBarry Smith   }
9583a40ed3dSBarry Smith   PetscFunctionReturn(0);
95992c4ed94SBarry Smith }
96092c4ed94SBarry Smith 
9614a2ae208SSatish Balay #undef __FUNCT__
9624a2ae208SSatish Balay #define __FUNCT__ "MatAssemblyEnd_SeqBAIJ"
9638f6be9afSLois Curfman McInnes int MatAssemblyEnd_SeqBAIJ(Mat A,MatAssemblyType mode)
964584200bdSSatish Balay {
965584200bdSSatish Balay   Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)A->data;
966584200bdSSatish Balay   int        fshift = 0,i,j,*ai = a->i,*aj = a->j,*imax = a->imax;
967273d9f13SBarry Smith   int        m = A->m,*ip,N,*ailen = a->ilen;
968549d3d68SSatish Balay   int        mbs = a->mbs,bs2 = a->bs2,rmax = 0,ierr;
9693f1db9ecSBarry Smith   MatScalar  *aa = a->a,*ap;
970a56a16c8SHong Zhang #if defined(PETSC_HAVE_DSCPACK)
971a56a16c8SHong Zhang   PetscTruth   flag;
972a56a16c8SHong Zhang #endif
973584200bdSSatish Balay 
9743a40ed3dSBarry Smith   PetscFunctionBegin;
9753a40ed3dSBarry Smith   if (mode == MAT_FLUSH_ASSEMBLY) PetscFunctionReturn(0);
976584200bdSSatish Balay 
97743ee02c3SBarry Smith   if (m) rmax = ailen[0];
978584200bdSSatish Balay   for (i=1; i<mbs; i++) {
979584200bdSSatish Balay     /* move each row back by the amount of empty slots (fshift) before it*/
980584200bdSSatish Balay     fshift += imax[i-1] - ailen[i-1];
981d402145bSBarry Smith     rmax   = PetscMax(rmax,ailen[i]);
982584200bdSSatish Balay     if (fshift) {
983a7c10996SSatish Balay       ip = aj + ai[i]; ap = aa + bs2*ai[i];
984584200bdSSatish Balay       N = ailen[i];
985584200bdSSatish Balay       for (j=0; j<N; j++) {
986584200bdSSatish Balay         ip[j-fshift] = ip[j];
987549d3d68SSatish Balay         ierr = PetscMemcpy(ap+(j-fshift)*bs2,ap+j*bs2,bs2*sizeof(MatScalar));CHKERRQ(ierr);
988584200bdSSatish Balay       }
989584200bdSSatish Balay     }
990584200bdSSatish Balay     ai[i] = ai[i-1] + ailen[i-1];
991584200bdSSatish Balay   }
992584200bdSSatish Balay   if (mbs) {
993584200bdSSatish Balay     fshift += imax[mbs-1] - ailen[mbs-1];
994584200bdSSatish Balay     ai[mbs] = ai[mbs-1] + ailen[mbs-1];
995584200bdSSatish Balay   }
996584200bdSSatish Balay   /* reset ilen and imax for each row */
997584200bdSSatish Balay   for (i=0; i<mbs; i++) {
998584200bdSSatish Balay     ailen[i] = imax[i] = ai[i+1] - ai[i];
999584200bdSSatish Balay   }
1000a7c10996SSatish Balay   a->nz = ai[mbs];
1001584200bdSSatish Balay 
1002584200bdSSatish Balay   /* diagonals may have moved, so kill the diagonal pointers */
1003584200bdSSatish Balay   if (fshift && a->diag) {
1004606d414cSSatish Balay     ierr = PetscFree(a->diag);CHKERRQ(ierr);
1005b424e231SHong Zhang     PetscLogObjectMemory(A,-(mbs+1)*sizeof(int));
1006584200bdSSatish Balay     a->diag = 0;
1007584200bdSSatish Balay   }
1008bba1ac68SSatish 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);
1009bba1ac68SSatish Balay   PetscLogInfo(A,"MatAssemblyEnd_SeqBAIJ:Number of mallocs during MatSetValues is %d\n",a->reallocs);
1010b0a32e0cSBarry Smith   PetscLogInfo(A,"MatAssemblyEnd_SeqBAIJ:Most nonzeros blocks in any row is %d\n",rmax);
1011e2f3b5e9SSatish Balay   a->reallocs          = 0;
10120e6d2581SBarry Smith   A->info.nz_unneeded  = (PetscReal)fshift*bs2;
1013cf4441caSHong Zhang 
1014a56a16c8SHong Zhang #if defined(PETSC_HAVE_DSCPACK)
10152c535e4dSHong Zhang   ierr = PetscOptionsHasName(A->prefix,"-mat_baij_dscpack",&flag);CHKERRQ(ierr);
1016a56a16c8SHong Zhang   if (flag) { ierr = MatUseDSCPACK_MPIBAIJ(A);CHKERRQ(ierr); }
1017a56a16c8SHong Zhang #endif
1018a56a16c8SHong Zhang 
10193a40ed3dSBarry Smith   PetscFunctionReturn(0);
1020584200bdSSatish Balay }
1021584200bdSSatish Balay 
10225a838052SSatish Balay 
1023bea157c4SSatish Balay 
1024bea157c4SSatish Balay /*
1025bea157c4SSatish Balay    This function returns an array of flags which indicate the locations of contiguous
1026bea157c4SSatish Balay    blocks that should be zeroed. for eg: if bs = 3  and is = [0,1,2,3,5,6,7,8,9]
1027bea157c4SSatish Balay    then the resulting sizes = [3,1,1,3,1] correspondig to sets [(0,1,2),(3),(5),(6,7,8),(9)]
1028bea157c4SSatish Balay    Assume: sizes should be long enough to hold all the values.
1029bea157c4SSatish Balay */
10304a2ae208SSatish Balay #undef __FUNCT__
10314a2ae208SSatish Balay #define __FUNCT__ "MatZeroRows_SeqBAIJ_Check_Blocks"
1032bea157c4SSatish Balay static int MatZeroRows_SeqBAIJ_Check_Blocks(int idx[],int n,int bs,int sizes[], int *bs_max)
1033d9b7c43dSSatish Balay {
1034bea157c4SSatish Balay   int        i,j,k,row;
1035bea157c4SSatish Balay   PetscTruth flg;
10363a40ed3dSBarry Smith 
1037433994e6SBarry Smith   PetscFunctionBegin;
1038bea157c4SSatish Balay   for (i=0,j=0; i<n; j++) {
1039bea157c4SSatish Balay     row = idx[i];
1040bea157c4SSatish Balay     if (row%bs!=0) { /* Not the begining of a block */
1041bea157c4SSatish Balay       sizes[j] = 1;
1042bea157c4SSatish Balay       i++;
1043e4fda26cSSatish Balay     } else if (i+bs > n) { /* complete block doesn't exist (at idx end) */
1044bea157c4SSatish Balay       sizes[j] = 1;         /* Also makes sure atleast 'bs' values exist for next else */
1045bea157c4SSatish Balay       i++;
1046bea157c4SSatish Balay     } else { /* Begining of the block, so check if the complete block exists */
1047bea157c4SSatish Balay       flg = PETSC_TRUE;
1048bea157c4SSatish Balay       for (k=1; k<bs; k++) {
1049bea157c4SSatish Balay         if (row+k != idx[i+k]) { /* break in the block */
1050bea157c4SSatish Balay           flg = PETSC_FALSE;
1051bea157c4SSatish Balay           break;
1052d9b7c43dSSatish Balay         }
1053bea157c4SSatish Balay       }
1054bea157c4SSatish Balay       if (flg == PETSC_TRUE) { /* No break in the bs */
1055bea157c4SSatish Balay         sizes[j] = bs;
1056bea157c4SSatish Balay         i+= bs;
1057bea157c4SSatish Balay       } else {
1058bea157c4SSatish Balay         sizes[j] = 1;
1059bea157c4SSatish Balay         i++;
1060bea157c4SSatish Balay       }
1061bea157c4SSatish Balay     }
1062bea157c4SSatish Balay   }
1063bea157c4SSatish Balay   *bs_max = j;
10643a40ed3dSBarry Smith   PetscFunctionReturn(0);
1065d9b7c43dSSatish Balay }
1066d9b7c43dSSatish Balay 
10674a2ae208SSatish Balay #undef __FUNCT__
10684a2ae208SSatish Balay #define __FUNCT__ "MatZeroRows_SeqBAIJ"
106987828ca2SBarry Smith int MatZeroRows_SeqBAIJ(Mat A,IS is,PetscScalar *diag)
1070d9b7c43dSSatish Balay {
1071d9b7c43dSSatish Balay   Mat_SeqBAIJ *baij=(Mat_SeqBAIJ*)A->data;
1072b6815fffSBarry Smith   int         ierr,i,j,k,count,is_n,*is_idx,*rows;
1073bea157c4SSatish Balay   int         bs=baij->bs,bs2=baij->bs2,*sizes,row,bs_max;
107487828ca2SBarry Smith   PetscScalar zero = 0.0;
10753f1db9ecSBarry Smith   MatScalar   *aa;
1076d9b7c43dSSatish Balay 
10773a40ed3dSBarry Smith   PetscFunctionBegin;
1078d9b7c43dSSatish Balay   /* Make a copy of the IS and  sort it */
1079b9b97703SBarry Smith   ierr = ISGetLocalSize(is,&is_n);CHKERRQ(ierr);
1080d9b7c43dSSatish Balay   ierr = ISGetIndices(is,&is_idx);CHKERRQ(ierr);
1081d9b7c43dSSatish Balay 
1082bea157c4SSatish Balay   /* allocate memory for rows,sizes */
1083b0a32e0cSBarry Smith   ierr  = PetscMalloc((3*is_n+1)*sizeof(int),&rows);CHKERRQ(ierr);
1084bea157c4SSatish Balay   sizes = rows + is_n;
1085bea157c4SSatish Balay 
1086563b5814SBarry Smith   /* copy IS values to rows, and sort them */
1087bea157c4SSatish Balay   for (i=0; i<is_n; i++) { rows[i] = is_idx[i]; }
1088bea157c4SSatish Balay   ierr = PetscSortInt(is_n,rows);CHKERRQ(ierr);
1089dffd3267SBarry Smith   if (baij->keepzeroedrows) {
1090dffd3267SBarry Smith     for (i=0; i<is_n; i++) { sizes[i] = 1; }
1091dffd3267SBarry Smith     bs_max = is_n;
1092dffd3267SBarry Smith   } else {
1093bea157c4SSatish Balay     ierr = MatZeroRows_SeqBAIJ_Check_Blocks(rows,is_n,bs,sizes,&bs_max);CHKERRQ(ierr);
1094dffd3267SBarry Smith   }
1095b97a56abSSatish Balay   ierr = ISRestoreIndices(is,&is_idx);CHKERRQ(ierr);
1096bea157c4SSatish Balay 
1097bea157c4SSatish Balay   for (i=0,j=0; i<bs_max; j+=sizes[i],i++) {
1098bea157c4SSatish Balay     row   = rows[j];
1099273d9f13SBarry Smith     if (row < 0 || row > A->m) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"row %d out of range",row);
1100bea157c4SSatish Balay     count = (baij->i[row/bs +1] - baij->i[row/bs])*bs;
1101bea157c4SSatish Balay     aa    = baij->a + baij->i[row/bs]*bs2 + (row%bs);
1102dffd3267SBarry Smith     if (sizes[i] == bs && !baij->keepzeroedrows) {
1103bea157c4SSatish Balay       if (diag) {
1104bea157c4SSatish Balay         if (baij->ilen[row/bs] > 0) {
1105bea157c4SSatish Balay           baij->ilen[row/bs]       = 1;
1106bea157c4SSatish Balay           baij->j[baij->i[row/bs]] = row/bs;
1107bea157c4SSatish Balay           ierr = PetscMemzero(aa,count*bs*sizeof(MatScalar));CHKERRQ(ierr);
1108a07cd24cSSatish Balay         }
1109563b5814SBarry Smith         /* Now insert all the diagonal values for this bs */
1110bea157c4SSatish Balay         for (k=0; k<bs; k++) {
1111bea157c4SSatish Balay           ierr = (*A->ops->setvalues)(A,1,rows+j+k,1,rows+j+k,diag,INSERT_VALUES);CHKERRQ(ierr);
1112bea157c4SSatish Balay         }
1113bea157c4SSatish Balay       } else { /* (!diag) */
1114bea157c4SSatish Balay         baij->ilen[row/bs] = 0;
1115bea157c4SSatish Balay       } /* end (!diag) */
1116bea157c4SSatish Balay     } else { /* (sizes[i] != bs) */
1117aa482453SBarry Smith #if defined (PETSC_USE_DEBUG)
111829bbc08cSBarry Smith       if (sizes[i] != 1) SETERRQ(1,"Internal Error. Value should be 1");
1119bea157c4SSatish Balay #endif
1120bea157c4SSatish Balay       for (k=0; k<count; k++) {
1121d9b7c43dSSatish Balay         aa[0] =  zero;
1122d9b7c43dSSatish Balay         aa    += bs;
1123d9b7c43dSSatish Balay       }
1124d9b7c43dSSatish Balay       if (diag) {
1125f830108cSBarry Smith         ierr = (*A->ops->setvalues)(A,1,rows+j,1,rows+j,diag,INSERT_VALUES);CHKERRQ(ierr);
1126d9b7c43dSSatish Balay       }
1127d9b7c43dSSatish Balay     }
1128bea157c4SSatish Balay   }
1129bea157c4SSatish Balay 
1130606d414cSSatish Balay   ierr = PetscFree(rows);CHKERRQ(ierr);
11319a8dea36SBarry Smith   ierr = MatAssemblyEnd_SeqBAIJ(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
11323a40ed3dSBarry Smith   PetscFunctionReturn(0);
1133d9b7c43dSSatish Balay }
11341c351548SSatish Balay 
11354a2ae208SSatish Balay #undef __FUNCT__
11364a2ae208SSatish Balay #define __FUNCT__ "MatSetValues_SeqBAIJ"
113787828ca2SBarry Smith int MatSetValues_SeqBAIJ(Mat A,int m,int *im,int n,int *in,PetscScalar *v,InsertMode is)
11382d61bbb3SSatish Balay {
11392d61bbb3SSatish Balay   Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)A->data;
11402d61bbb3SSatish Balay   int         *rp,k,low,high,t,ii,row,nrow,i,col,l,rmax,N,sorted=a->sorted;
1141273d9f13SBarry Smith   int         *imax=a->imax,*ai=a->i,*ailen=a->ilen;
11422d61bbb3SSatish Balay   int         *aj=a->j,nonew=a->nonew,bs=a->bs,brow,bcol;
1143549d3d68SSatish Balay   int         ridx,cidx,bs2=a->bs2,ierr;
1144273d9f13SBarry Smith   PetscTruth  roworiented=a->roworiented;
11453f1db9ecSBarry Smith   MatScalar   *ap,value,*aa=a->a,*bap;
11462d61bbb3SSatish Balay 
11472d61bbb3SSatish Balay   PetscFunctionBegin;
11482d61bbb3SSatish Balay   for (k=0; k<m; k++) { /* loop over added rows */
11492d61bbb3SSatish Balay     row  = im[k]; brow = row/bs;
11505ef9f2a5SBarry Smith     if (row < 0) continue;
1151aa482453SBarry Smith #if defined(PETSC_USE_BOPT_g)
1152273d9f13SBarry Smith     if (row >= A->m) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"Row too large: row %d max %d",row,A->m);
11532d61bbb3SSatish Balay #endif
11542d61bbb3SSatish Balay     rp   = aj + ai[brow];
11552d61bbb3SSatish Balay     ap   = aa + bs2*ai[brow];
11562d61bbb3SSatish Balay     rmax = imax[brow];
11572d61bbb3SSatish Balay     nrow = ailen[brow];
11582d61bbb3SSatish Balay     low  = 0;
11592d61bbb3SSatish Balay     for (l=0; l<n; l++) { /* loop over added columns */
11605ef9f2a5SBarry Smith       if (in[l] < 0) continue;
1161aa482453SBarry Smith #if defined(PETSC_USE_BOPT_g)
1162273d9f13SBarry Smith       if (in[l] >= A->n) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"Column too large: col %d max %d",in[l],A->n);
11632d61bbb3SSatish Balay #endif
11642d61bbb3SSatish Balay       col = in[l]; bcol = col/bs;
11652d61bbb3SSatish Balay       ridx = row % bs; cidx = col % bs;
11662d61bbb3SSatish Balay       if (roworiented) {
11675ef9f2a5SBarry Smith         value = v[l + k*n];
11682d61bbb3SSatish Balay       } else {
11692d61bbb3SSatish Balay         value = v[k + l*m];
11702d61bbb3SSatish Balay       }
11712d61bbb3SSatish Balay       if (!sorted) low = 0; high = nrow;
11722d61bbb3SSatish Balay       while (high-low > 7) {
11732d61bbb3SSatish Balay         t = (low+high)/2;
11742d61bbb3SSatish Balay         if (rp[t] > bcol) high = t;
11752d61bbb3SSatish Balay         else              low  = t;
11762d61bbb3SSatish Balay       }
11772d61bbb3SSatish Balay       for (i=low; i<high; i++) {
11782d61bbb3SSatish Balay         if (rp[i] > bcol) break;
11792d61bbb3SSatish Balay         if (rp[i] == bcol) {
11802d61bbb3SSatish Balay           bap  = ap +  bs2*i + bs*cidx + ridx;
11812d61bbb3SSatish Balay           if (is == ADD_VALUES) *bap += value;
11822d61bbb3SSatish Balay           else                  *bap  = value;
11832d61bbb3SSatish Balay           goto noinsert1;
11842d61bbb3SSatish Balay         }
11852d61bbb3SSatish Balay       }
11862d61bbb3SSatish Balay       if (nonew == 1) goto noinsert1;
118729bbc08cSBarry Smith       else if (nonew == -1) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Inserting a new nonzero in the matrix");
11882d61bbb3SSatish Balay       if (nrow >= rmax) {
11892d61bbb3SSatish Balay         /* there is no extra room in row, therefore enlarge */
11902d61bbb3SSatish Balay         int       new_nz = ai[a->mbs] + CHUNKSIZE,len,*new_i,*new_j;
11913f1db9ecSBarry Smith         MatScalar *new_a;
11922d61bbb3SSatish Balay 
119329bbc08cSBarry Smith         if (nonew == -2) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Inserting a new nonzero in the matrix");
11942d61bbb3SSatish Balay 
11952d61bbb3SSatish Balay         /* Malloc new storage space */
11963f1db9ecSBarry Smith         len     = new_nz*(sizeof(int)+bs2*sizeof(MatScalar))+(a->mbs+1)*sizeof(int);
1197b0a32e0cSBarry Smith 	ierr    = PetscMalloc(len,&new_a);CHKERRQ(ierr);
11982d61bbb3SSatish Balay         new_j   = (int*)(new_a + bs2*new_nz);
11992d61bbb3SSatish Balay         new_i   = new_j + new_nz;
12002d61bbb3SSatish Balay 
12012d61bbb3SSatish Balay         /* copy over old data into new slots */
12022d61bbb3SSatish Balay         for (ii=0; ii<brow+1; ii++) {new_i[ii] = ai[ii];}
12032d61bbb3SSatish Balay         for (ii=brow+1; ii<a->mbs+1; ii++) {new_i[ii] = ai[ii]+CHUNKSIZE;}
1204549d3d68SSatish Balay         ierr = PetscMemcpy(new_j,aj,(ai[brow]+nrow)*sizeof(int));CHKERRQ(ierr);
12052d61bbb3SSatish Balay         len  = (new_nz - CHUNKSIZE - ai[brow] - nrow);
1206549d3d68SSatish Balay         ierr = PetscMemcpy(new_j+ai[brow]+nrow+CHUNKSIZE,aj+ai[brow]+nrow,len*sizeof(int));CHKERRQ(ierr);
1207549d3d68SSatish Balay         ierr = PetscMemcpy(new_a,aa,(ai[brow]+nrow)*bs2*sizeof(MatScalar));CHKERRQ(ierr);
1208549d3d68SSatish Balay         ierr = PetscMemzero(new_a+bs2*(ai[brow]+nrow),bs2*CHUNKSIZE*sizeof(MatScalar));CHKERRQ(ierr);
1209549d3d68SSatish Balay         ierr = PetscMemcpy(new_a+bs2*(ai[brow]+nrow+CHUNKSIZE),aa+bs2*(ai[brow]+nrow),bs2*len*sizeof(MatScalar));CHKERRQ(ierr);
12102d61bbb3SSatish Balay         /* free up old matrix storage */
1211606d414cSSatish Balay         ierr = PetscFree(a->a);CHKERRQ(ierr);
1212606d414cSSatish Balay         if (!a->singlemalloc) {
1213606d414cSSatish Balay           ierr = PetscFree(a->i);CHKERRQ(ierr);
1214606d414cSSatish Balay           ierr = PetscFree(a->j);CHKERRQ(ierr);
1215606d414cSSatish Balay         }
12162d61bbb3SSatish Balay         aa = a->a = new_a; ai = a->i = new_i; aj = a->j = new_j;
1217c4992f7dSBarry Smith         a->singlemalloc = PETSC_TRUE;
12182d61bbb3SSatish Balay 
12192d61bbb3SSatish Balay         rp   = aj + ai[brow]; ap = aa + bs2*ai[brow];
12202d61bbb3SSatish Balay         rmax = imax[brow] = imax[brow] + CHUNKSIZE;
1221b0a32e0cSBarry Smith         PetscLogObjectMemory(A,CHUNKSIZE*(sizeof(int) + bs2*sizeof(MatScalar)));
12222d61bbb3SSatish Balay         a->maxnz += bs2*CHUNKSIZE;
12232d61bbb3SSatish Balay         a->reallocs++;
12242d61bbb3SSatish Balay         a->nz++;
12252d61bbb3SSatish Balay       }
12262d61bbb3SSatish Balay       N = nrow++ - 1;
12272d61bbb3SSatish Balay       /* shift up all the later entries in this row */
12282d61bbb3SSatish Balay       for (ii=N; ii>=i; ii--) {
12292d61bbb3SSatish Balay         rp[ii+1] = rp[ii];
1230549d3d68SSatish Balay         ierr     = PetscMemcpy(ap+bs2*(ii+1),ap+bs2*(ii),bs2*sizeof(MatScalar));CHKERRQ(ierr);
12312d61bbb3SSatish Balay       }
1232549d3d68SSatish Balay       if (N>=i) {
1233549d3d68SSatish Balay         ierr = PetscMemzero(ap+bs2*i,bs2*sizeof(MatScalar));CHKERRQ(ierr);
1234549d3d68SSatish Balay       }
12352d61bbb3SSatish Balay       rp[i]                      = bcol;
12362d61bbb3SSatish Balay       ap[bs2*i + bs*cidx + ridx] = value;
12372d61bbb3SSatish Balay       noinsert1:;
12382d61bbb3SSatish Balay       low = i;
12392d61bbb3SSatish Balay     }
12402d61bbb3SSatish Balay     ailen[brow] = nrow;
12412d61bbb3SSatish Balay   }
12422d61bbb3SSatish Balay   PetscFunctionReturn(0);
12432d61bbb3SSatish Balay }
12442d61bbb3SSatish Balay 
12452d61bbb3SSatish Balay 
12464a2ae208SSatish Balay #undef __FUNCT__
12474a2ae208SSatish Balay #define __FUNCT__ "MatILUFactor_SeqBAIJ"
1248b380c88cSHong Zhang int MatILUFactor_SeqBAIJ(Mat inA,IS row,IS col,MatFactorInfo *info)
12492d61bbb3SSatish Balay {
12502d61bbb3SSatish Balay   Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)inA->data;
12512d61bbb3SSatish Balay   Mat         outA;
12522d61bbb3SSatish Balay   int         ierr;
1253667159a5SBarry Smith   PetscTruth  row_identity,col_identity;
12542d61bbb3SSatish Balay 
12552d61bbb3SSatish Balay   PetscFunctionBegin;
1256d3d32019SBarry Smith   if (info->levels != 0) SETERRQ(PETSC_ERR_SUP,"Only levels = 0 supported for in-place ILU");
1257667159a5SBarry Smith   ierr = ISIdentity(row,&row_identity);CHKERRQ(ierr);
1258667159a5SBarry Smith   ierr = ISIdentity(col,&col_identity);CHKERRQ(ierr);
1259667159a5SBarry Smith   if (!row_identity || !col_identity) {
126029bbc08cSBarry Smith     SETERRQ(1,"Row and column permutations must be identity for in-place ILU");
1261667159a5SBarry Smith   }
12622d61bbb3SSatish Balay 
12632d61bbb3SSatish Balay   outA          = inA;
12642d61bbb3SSatish Balay   inA->factor   = FACTOR_LU;
12652d61bbb3SSatish Balay 
12662d61bbb3SSatish Balay   if (!a->diag) {
1267c4992f7dSBarry Smith     ierr = MatMarkDiagonal_SeqBAIJ(inA);CHKERRQ(ierr);
12682d61bbb3SSatish Balay   }
1269cf242676SKris Buschelman 
1270c38d4ed2SBarry Smith   a->row        = row;
1271c38d4ed2SBarry Smith   a->col        = col;
1272c38d4ed2SBarry Smith   ierr          = PetscObjectReference((PetscObject)row);CHKERRQ(ierr);
1273c38d4ed2SBarry Smith   ierr          = PetscObjectReference((PetscObject)col);CHKERRQ(ierr);
1274c38d4ed2SBarry Smith 
1275c38d4ed2SBarry Smith   /* Create the invert permutation so that it can be used in MatLUFactorNumeric() */
12764c49b128SBarry Smith   ierr = ISInvertPermutation(col,PETSC_DECIDE,&a->icol);CHKERRQ(ierr);
1277b0a32e0cSBarry Smith   PetscLogObjectParent(inA,a->icol);
1278c38d4ed2SBarry Smith 
1279cf242676SKris Buschelman   /*
1280cf242676SKris Buschelman       Blocksize 2, 3, 4, 5, 6 and 7 have a special faster factorization/solver
1281cf242676SKris Buschelman       for ILU(0) factorization with natural ordering
1282cf242676SKris Buschelman   */
1283cf242676SKris Buschelman   if (a->bs < 8) {
1284cf242676SKris Buschelman     ierr = MatSeqBAIJ_UpdateFactorNumeric_NaturalOrdering(inA);CHKERRQ(ierr);
1285cf242676SKris Buschelman   } else {
1286c38d4ed2SBarry Smith     if (!a->solve_work) {
128787828ca2SBarry Smith       ierr = PetscMalloc((inA->m+a->bs)*sizeof(PetscScalar),&a->solve_work);CHKERRQ(ierr);
128887828ca2SBarry Smith       PetscLogObjectMemory(inA,(inA->m+a->bs)*sizeof(PetscScalar));
1289c38d4ed2SBarry Smith     }
12902d61bbb3SSatish Balay   }
12912d61bbb3SSatish Balay 
1292667159a5SBarry Smith   ierr = MatLUFactorNumeric(inA,&outA);CHKERRQ(ierr);
1293667159a5SBarry Smith 
12942d61bbb3SSatish Balay   PetscFunctionReturn(0);
12952d61bbb3SSatish Balay }
12964a2ae208SSatish Balay #undef __FUNCT__
12974a2ae208SSatish Balay #define __FUNCT__ "MatPrintHelp_SeqBAIJ"
1298ba4ca20aSSatish Balay int MatPrintHelp_SeqBAIJ(Mat A)
1299ba4ca20aSSatish Balay {
1300c38d4ed2SBarry Smith   static PetscTruth called = PETSC_FALSE;
1301ba4ca20aSSatish Balay   MPI_Comm          comm = A->comm;
1302d132466eSBarry Smith   int               ierr;
1303ba4ca20aSSatish Balay 
13043a40ed3dSBarry Smith   PetscFunctionBegin;
1305c38d4ed2SBarry Smith   if (called) {PetscFunctionReturn(0);} else called = PETSC_TRUE;
1306d132466eSBarry Smith   ierr = (*PetscHelpPrintf)(comm," Options for MATSEQBAIJ and MATMPIBAIJ matrix formats (the defaults):\n");CHKERRQ(ierr);
1307d132466eSBarry Smith   ierr = (*PetscHelpPrintf)(comm,"  -mat_block_size <block_size>\n");CHKERRQ(ierr);
13083a40ed3dSBarry Smith   PetscFunctionReturn(0);
1309ba4ca20aSSatish Balay }
1310d9b7c43dSSatish Balay 
1311fb2e594dSBarry Smith EXTERN_C_BEGIN
13124a2ae208SSatish Balay #undef __FUNCT__
13134a2ae208SSatish Balay #define __FUNCT__ "MatSeqBAIJSetColumnIndices_SeqBAIJ"
131427a8da17SBarry Smith int MatSeqBAIJSetColumnIndices_SeqBAIJ(Mat mat,int *indices)
131527a8da17SBarry Smith {
131627a8da17SBarry Smith   Mat_SeqBAIJ *baij = (Mat_SeqBAIJ *)mat->data;
131714db4f74SSatish Balay   int         i,nz,nbs;
131827a8da17SBarry Smith 
131927a8da17SBarry Smith   PetscFunctionBegin;
132014db4f74SSatish Balay   nz  = baij->maxnz/baij->bs2;
132114db4f74SSatish Balay   nbs = baij->nbs;
132227a8da17SBarry Smith   for (i=0; i<nz; i++) {
132327a8da17SBarry Smith     baij->j[i] = indices[i];
132427a8da17SBarry Smith   }
132527a8da17SBarry Smith   baij->nz = nz;
132614db4f74SSatish Balay   for (i=0; i<nbs; i++) {
132727a8da17SBarry Smith     baij->ilen[i] = baij->imax[i];
132827a8da17SBarry Smith   }
132927a8da17SBarry Smith 
133027a8da17SBarry Smith   PetscFunctionReturn(0);
133127a8da17SBarry Smith }
1332fb2e594dSBarry Smith EXTERN_C_END
133327a8da17SBarry Smith 
13344a2ae208SSatish Balay #undef __FUNCT__
13354a2ae208SSatish Balay #define __FUNCT__ "MatSeqBAIJSetColumnIndices"
133627a8da17SBarry Smith /*@
133727a8da17SBarry Smith     MatSeqBAIJSetColumnIndices - Set the column indices for all the rows
133827a8da17SBarry Smith        in the matrix.
133927a8da17SBarry Smith 
134027a8da17SBarry Smith   Input Parameters:
134127a8da17SBarry Smith +  mat - the SeqBAIJ matrix
134227a8da17SBarry Smith -  indices - the column indices
134327a8da17SBarry Smith 
134415091d37SBarry Smith   Level: advanced
134515091d37SBarry Smith 
134627a8da17SBarry Smith   Notes:
134727a8da17SBarry Smith     This can be called if you have precomputed the nonzero structure of the
134827a8da17SBarry Smith   matrix and want to provide it to the matrix object to improve the performance
134927a8da17SBarry Smith   of the MatSetValues() operation.
135027a8da17SBarry Smith 
135127a8da17SBarry Smith     You MUST have set the correct numbers of nonzeros per row in the call to
135227a8da17SBarry Smith   MatCreateSeqBAIJ().
135327a8da17SBarry Smith 
135427a8da17SBarry Smith     MUST be called before any calls to MatSetValues();
135527a8da17SBarry Smith 
135627a8da17SBarry Smith @*/
135727a8da17SBarry Smith int MatSeqBAIJSetColumnIndices(Mat mat,int *indices)
135827a8da17SBarry Smith {
135927a8da17SBarry Smith   int ierr,(*f)(Mat,int *);
136027a8da17SBarry Smith 
136127a8da17SBarry Smith   PetscFunctionBegin;
136227a8da17SBarry Smith   PetscValidHeaderSpecific(mat,MAT_COOKIE);
1363c134de8dSSatish Balay   ierr = PetscObjectQueryFunction((PetscObject)mat,"MatSeqBAIJSetColumnIndices_C",(void (**)(void))&f);CHKERRQ(ierr);
136427a8da17SBarry Smith   if (f) {
136527a8da17SBarry Smith     ierr = (*f)(mat,indices);CHKERRQ(ierr);
136627a8da17SBarry Smith   } else {
136729bbc08cSBarry Smith     SETERRQ(1,"Wrong type of matrix to set column indices");
136827a8da17SBarry Smith   }
136927a8da17SBarry Smith   PetscFunctionReturn(0);
137027a8da17SBarry Smith }
137127a8da17SBarry Smith 
13724a2ae208SSatish Balay #undef __FUNCT__
13734a2ae208SSatish Balay #define __FUNCT__ "MatGetRowMax_SeqBAIJ"
1374273d9f13SBarry Smith int MatGetRowMax_SeqBAIJ(Mat A,Vec v)
1375273d9f13SBarry Smith {
1376273d9f13SBarry Smith   Mat_SeqBAIJ  *a = (Mat_SeqBAIJ*)A->data;
1377273d9f13SBarry Smith   int          ierr,i,j,n,row,bs,*ai,*aj,mbs;
1378273d9f13SBarry Smith   PetscReal    atmp;
137987828ca2SBarry Smith   PetscScalar  *x,zero = 0.0;
1380273d9f13SBarry Smith   MatScalar    *aa;
1381273d9f13SBarry Smith   int          ncols,brow,krow,kcol;
1382273d9f13SBarry Smith 
1383273d9f13SBarry Smith   PetscFunctionBegin;
1384273d9f13SBarry Smith   if (A->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1385273d9f13SBarry Smith   bs   = a->bs;
1386273d9f13SBarry Smith   aa   = a->a;
1387273d9f13SBarry Smith   ai   = a->i;
1388273d9f13SBarry Smith   aj   = a->j;
1389273d9f13SBarry Smith   mbs = a->mbs;
1390273d9f13SBarry Smith 
1391273d9f13SBarry Smith   ierr = VecSet(&zero,v);CHKERRQ(ierr);
1392273d9f13SBarry Smith   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
1393273d9f13SBarry Smith   ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr);
1394273d9f13SBarry Smith   if (n != A->m) SETERRQ(PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector");
1395273d9f13SBarry Smith   for (i=0; i<mbs; i++) {
1396273d9f13SBarry Smith     ncols = ai[1] - ai[0]; ai++;
1397273d9f13SBarry Smith     brow  = bs*i;
1398273d9f13SBarry Smith     for (j=0; j<ncols; j++){
1399273d9f13SBarry Smith       /* bcol = bs*(*aj); */
1400273d9f13SBarry Smith       for (kcol=0; kcol<bs; kcol++){
1401273d9f13SBarry Smith         for (krow=0; krow<bs; krow++){
1402273d9f13SBarry Smith           atmp = PetscAbsScalar(*aa); aa++;
1403273d9f13SBarry Smith           row = brow + krow;    /* row index */
1404273d9f13SBarry Smith           /* printf("val[%d,%d]: %g\n",row,bcol+kcol,atmp); */
1405273d9f13SBarry Smith           if (PetscAbsScalar(x[row]) < atmp) x[row] = atmp;
1406273d9f13SBarry Smith         }
1407273d9f13SBarry Smith       }
1408273d9f13SBarry Smith       aj++;
1409273d9f13SBarry Smith     }
1410273d9f13SBarry Smith   }
1411273d9f13SBarry Smith   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
1412273d9f13SBarry Smith   PetscFunctionReturn(0);
1413273d9f13SBarry Smith }
1414273d9f13SBarry Smith 
14154a2ae208SSatish Balay #undef __FUNCT__
14164a2ae208SSatish Balay #define __FUNCT__ "MatSetUpPreallocation_SeqBAIJ"
1417273d9f13SBarry Smith int MatSetUpPreallocation_SeqBAIJ(Mat A)
1418273d9f13SBarry Smith {
1419273d9f13SBarry Smith   int        ierr;
1420273d9f13SBarry Smith 
1421273d9f13SBarry Smith   PetscFunctionBegin;
1422273d9f13SBarry Smith   ierr =  MatSeqBAIJSetPreallocation(A,1,PETSC_DEFAULT,0);CHKERRQ(ierr);
1423273d9f13SBarry Smith   PetscFunctionReturn(0);
1424273d9f13SBarry Smith }
1425273d9f13SBarry Smith 
14264a2ae208SSatish Balay #undef __FUNCT__
14274a2ae208SSatish Balay #define __FUNCT__ "MatGetArray_SeqBAIJ"
142887828ca2SBarry Smith int MatGetArray_SeqBAIJ(Mat A,PetscScalar **array)
1429f2a5309cSSatish Balay {
1430f2a5309cSSatish Balay   Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)A->data;
1431f2a5309cSSatish Balay   PetscFunctionBegin;
1432f2a5309cSSatish Balay   *array = a->a;
1433f2a5309cSSatish Balay   PetscFunctionReturn(0);
1434f2a5309cSSatish Balay }
1435f2a5309cSSatish Balay 
14364a2ae208SSatish Balay #undef __FUNCT__
14374a2ae208SSatish Balay #define __FUNCT__ "MatRestoreArray_SeqBAIJ"
143887828ca2SBarry Smith int MatRestoreArray_SeqBAIJ(Mat A,PetscScalar **array)
1439f2a5309cSSatish Balay {
1440f2a5309cSSatish Balay   PetscFunctionBegin;
1441f2a5309cSSatish Balay   PetscFunctionReturn(0);
1442f2a5309cSSatish Balay }
1443f2a5309cSSatish Balay 
144442ee4b1aSHong Zhang #include "petscblaslapack.h"
144542ee4b1aSHong Zhang #undef __FUNCT__
144642ee4b1aSHong Zhang #define __FUNCT__ "MatAXPY_SeqBAIJ"
144742ee4b1aSHong Zhang int MatAXPY_SeqBAIJ(PetscScalar *a,Mat X,Mat Y,MatStructure str)
144842ee4b1aSHong Zhang {
1449*c537a176SHong Zhang   int          ierr,one=1,i;
145042ee4b1aSHong Zhang   Mat_SeqBAIJ  *x  = (Mat_SeqBAIJ *)X->data,*y = (Mat_SeqBAIJ *)Y->data;
1451*c537a176SHong Zhang   int          *xtoy,nz,row,xcol,ycol,jx,jy,*xi=x->i,*xj=x->j,*yi=y->i,*yj=y->j;
145242ee4b1aSHong Zhang 
145342ee4b1aSHong Zhang   PetscFunctionBegin;
145442ee4b1aSHong Zhang   if (str == SAME_NONZERO_PATTERN) {
145542ee4b1aSHong Zhang     BLaxpy_(&x->nz,a,x->a,&one,y->a,&one);
1456*c537a176SHong Zhang   } else if (str == SUBSET_NONZERO_PATTERN) { /* nonzeros of X is a subset of Y's */
1457*c537a176SHong Zhang     if (x->bs > 1) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not support for bs>1");
1458*c537a176SHong Zhang     ierr = PetscMalloc(x->nz*sizeof(int),&xtoy);CHKERRQ(ierr);
1459*c537a176SHong Zhang     i = 0;
1460*c537a176SHong Zhang     for (row=0; row<x->mbs; row++){
1461*c537a176SHong Zhang       nz = xi[1] - xi[0];
1462*c537a176SHong Zhang       jy = 0;
1463*c537a176SHong Zhang       for (jx=0; jx<nz; jx++,jy++){
1464*c537a176SHong Zhang         xcol = xj[*xi + jx];
1465*c537a176SHong Zhang         ycol = yj[*yi + jy];  /* col index for y */
1466*c537a176SHong Zhang         while ( ycol < xcol ) {
1467*c537a176SHong Zhang           jy++;
1468*c537a176SHong Zhang           ycol = yj[*yi + jy];
1469*c537a176SHong Zhang         }
1470*c537a176SHong Zhang         if (xcol != ycol) SETERRQ2(PETSC_ERR_ARG_WRONG,"X matrix entry (%d,%d) is not in Y matrix",row,ycol);
1471*c537a176SHong Zhang         xtoy[i++] = *yi + jy;
1472*c537a176SHong Zhang       }
1473*c537a176SHong Zhang       xi++; yi++;
1474*c537a176SHong Zhang     }
1475*c537a176SHong Zhang 
1476*c537a176SHong Zhang     for (i=0; i<x->nz; i++) {
1477*c537a176SHong Zhang       y->a[xtoy[i]] += (*a)*(x->a[i]);
1478*c537a176SHong Zhang     }
1479*c537a176SHong Zhang     ierr = PetscFree(xtoy);CHKERRQ(ierr);
148042ee4b1aSHong Zhang   } else {
148142ee4b1aSHong Zhang     ierr = MatAXPY_Basic(a,X,Y,str);CHKERRQ(ierr);
148242ee4b1aSHong Zhang   }
148342ee4b1aSHong Zhang   PetscFunctionReturn(0);
148442ee4b1aSHong Zhang }
148542ee4b1aSHong Zhang 
14862593348eSBarry Smith /* -------------------------------------------------------------------*/
1487cc2dc46cSBarry Smith static struct _MatOps MatOps_Values = {MatSetValues_SeqBAIJ,
1488cc2dc46cSBarry Smith        MatGetRow_SeqBAIJ,
1489cc2dc46cSBarry Smith        MatRestoreRow_SeqBAIJ,
1490cc2dc46cSBarry Smith        MatMult_SeqBAIJ_N,
1491cc2dc46cSBarry Smith        MatMultAdd_SeqBAIJ_N,
14927c922b88SBarry Smith        MatMultTranspose_SeqBAIJ,
14937c922b88SBarry Smith        MatMultTransposeAdd_SeqBAIJ,
1494cc2dc46cSBarry Smith        MatSolve_SeqBAIJ_N,
1495cc2dc46cSBarry Smith        0,
1496cc2dc46cSBarry Smith        0,
1497cc2dc46cSBarry Smith        0,
1498cc2dc46cSBarry Smith        MatLUFactor_SeqBAIJ,
1499cc2dc46cSBarry Smith        0,
1500b6490206SBarry Smith        0,
1501f2501298SSatish Balay        MatTranspose_SeqBAIJ,
1502cc2dc46cSBarry Smith        MatGetInfo_SeqBAIJ,
1503cc2dc46cSBarry Smith        MatEqual_SeqBAIJ,
1504cc2dc46cSBarry Smith        MatGetDiagonal_SeqBAIJ,
1505cc2dc46cSBarry Smith        MatDiagonalScale_SeqBAIJ,
1506cc2dc46cSBarry Smith        MatNorm_SeqBAIJ,
1507b6490206SBarry Smith        0,
1508cc2dc46cSBarry Smith        MatAssemblyEnd_SeqBAIJ,
1509cc2dc46cSBarry Smith        0,
1510cc2dc46cSBarry Smith        MatSetOption_SeqBAIJ,
1511cc2dc46cSBarry Smith        MatZeroEntries_SeqBAIJ,
1512cc2dc46cSBarry Smith        MatZeroRows_SeqBAIJ,
1513cc2dc46cSBarry Smith        MatLUFactorSymbolic_SeqBAIJ,
1514cc2dc46cSBarry Smith        MatLUFactorNumeric_SeqBAIJ_N,
1515cc2dc46cSBarry Smith        0,
1516cc2dc46cSBarry Smith        0,
1517273d9f13SBarry Smith        MatSetUpPreallocation_SeqBAIJ,
1518cc2dc46cSBarry Smith        MatILUFactorSymbolic_SeqBAIJ,
1519cc2dc46cSBarry Smith        0,
1520f2a5309cSSatish Balay        MatGetArray_SeqBAIJ,
1521f2a5309cSSatish Balay        MatRestoreArray_SeqBAIJ,
15222e8a6d31SBarry Smith        MatDuplicate_SeqBAIJ,
1523cc2dc46cSBarry Smith        0,
1524cc2dc46cSBarry Smith        0,
1525cc2dc46cSBarry Smith        MatILUFactor_SeqBAIJ,
1526cc2dc46cSBarry Smith        0,
152742ee4b1aSHong Zhang        MatAXPY_SeqBAIJ,
1528cc2dc46cSBarry Smith        MatGetSubMatrices_SeqBAIJ,
1529cc2dc46cSBarry Smith        MatIncreaseOverlap_SeqBAIJ,
1530cc2dc46cSBarry Smith        MatGetValues_SeqBAIJ,
1531cc2dc46cSBarry Smith        0,
1532cc2dc46cSBarry Smith        MatPrintHelp_SeqBAIJ,
1533cc2dc46cSBarry Smith        MatScale_SeqBAIJ,
1534cc2dc46cSBarry Smith        0,
1535cc2dc46cSBarry Smith        0,
1536cc2dc46cSBarry Smith        0,
1537cc2dc46cSBarry Smith        MatGetBlockSize_SeqBAIJ,
15383b2fbd54SBarry Smith        MatGetRowIJ_SeqBAIJ,
153992c4ed94SBarry Smith        MatRestoreRowIJ_SeqBAIJ,
1540cc2dc46cSBarry Smith        0,
1541cc2dc46cSBarry Smith        0,
1542cc2dc46cSBarry Smith        0,
1543cc2dc46cSBarry Smith        0,
1544cc2dc46cSBarry Smith        0,
1545cc2dc46cSBarry Smith        0,
1546d3825aa8SBarry Smith        MatSetValuesBlocked_SeqBAIJ,
1547cc2dc46cSBarry Smith        MatGetSubMatrix_SeqBAIJ,
1548b9b97703SBarry Smith        MatDestroy_SeqBAIJ,
1549b9b97703SBarry Smith        MatView_SeqBAIJ,
15503a64cc32SBarry Smith        MatGetPetscMaps_Petsc,
1551273d9f13SBarry Smith        0,
1552273d9f13SBarry Smith        0,
1553273d9f13SBarry Smith        0,
1554273d9f13SBarry Smith        0,
1555273d9f13SBarry Smith        0,
1556273d9f13SBarry Smith        0,
1557273d9f13SBarry Smith        MatGetRowMax_SeqBAIJ,
1558273d9f13SBarry Smith        MatConvert_Basic};
15592593348eSBarry Smith 
15603e90b805SBarry Smith EXTERN_C_BEGIN
15614a2ae208SSatish Balay #undef __FUNCT__
15624a2ae208SSatish Balay #define __FUNCT__ "MatStoreValues_SeqBAIJ"
15633e90b805SBarry Smith int MatStoreValues_SeqBAIJ(Mat mat)
15643e90b805SBarry Smith {
15653e90b805SBarry Smith   Mat_SeqBAIJ *aij = (Mat_SeqBAIJ *)mat->data;
1566273d9f13SBarry Smith   int         nz = aij->i[mat->m]*aij->bs*aij->bs2;
1567d132466eSBarry Smith   int         ierr;
15683e90b805SBarry Smith 
15693e90b805SBarry Smith   PetscFunctionBegin;
15703e90b805SBarry Smith   if (aij->nonew != 1) {
157129bbc08cSBarry Smith     SETERRQ(1,"Must call MatSetOption(A,MAT_NO_NEW_NONZERO_LOCATIONS);first");
15723e90b805SBarry Smith   }
15733e90b805SBarry Smith 
15743e90b805SBarry Smith   /* allocate space for values if not already there */
15753e90b805SBarry Smith   if (!aij->saved_values) {
157687828ca2SBarry Smith     ierr = PetscMalloc((nz+1)*sizeof(PetscScalar),&aij->saved_values);CHKERRQ(ierr);
15773e90b805SBarry Smith   }
15783e90b805SBarry Smith 
15793e90b805SBarry Smith   /* copy values over */
158087828ca2SBarry Smith   ierr = PetscMemcpy(aij->saved_values,aij->a,nz*sizeof(PetscScalar));CHKERRQ(ierr);
15813e90b805SBarry Smith   PetscFunctionReturn(0);
15823e90b805SBarry Smith }
15833e90b805SBarry Smith EXTERN_C_END
15843e90b805SBarry Smith 
15853e90b805SBarry Smith EXTERN_C_BEGIN
15864a2ae208SSatish Balay #undef __FUNCT__
15874a2ae208SSatish Balay #define __FUNCT__ "MatRetrieveValues_SeqBAIJ"
158832e87ba3SBarry Smith int MatRetrieveValues_SeqBAIJ(Mat mat)
15893e90b805SBarry Smith {
15903e90b805SBarry Smith   Mat_SeqBAIJ *aij = (Mat_SeqBAIJ *)mat->data;
1591273d9f13SBarry Smith   int         nz = aij->i[mat->m]*aij->bs*aij->bs2,ierr;
15923e90b805SBarry Smith 
15933e90b805SBarry Smith   PetscFunctionBegin;
15943e90b805SBarry Smith   if (aij->nonew != 1) {
159529bbc08cSBarry Smith     SETERRQ(1,"Must call MatSetOption(A,MAT_NO_NEW_NONZERO_LOCATIONS);first");
15963e90b805SBarry Smith   }
15973e90b805SBarry Smith   if (!aij->saved_values) {
159829bbc08cSBarry Smith     SETERRQ(1,"Must call MatStoreValues(A);first");
15993e90b805SBarry Smith   }
16003e90b805SBarry Smith 
16013e90b805SBarry Smith   /* copy values over */
160287828ca2SBarry Smith   ierr = PetscMemcpy(aij->a,aij->saved_values,nz*sizeof(PetscScalar));CHKERRQ(ierr);
16033e90b805SBarry Smith   PetscFunctionReturn(0);
16043e90b805SBarry Smith }
16053e90b805SBarry Smith EXTERN_C_END
16063e90b805SBarry Smith 
1607273d9f13SBarry Smith EXTERN_C_BEGIN
1608273d9f13SBarry Smith extern int MatConvert_SeqBAIJ_SeqAIJ(Mat,MatType,Mat*);
1609273d9f13SBarry Smith EXTERN_C_END
1610273d9f13SBarry Smith 
1611273d9f13SBarry Smith EXTERN_C_BEGIN
16124a2ae208SSatish Balay #undef __FUNCT__
16134a2ae208SSatish Balay #define __FUNCT__ "MatCreate_SeqBAIJ"
1614273d9f13SBarry Smith int MatCreate_SeqBAIJ(Mat B)
16152593348eSBarry Smith {
1616273d9f13SBarry Smith   int         ierr,size;
1617b6490206SBarry Smith   Mat_SeqBAIJ *b;
16183b2fbd54SBarry Smith 
16193a40ed3dSBarry Smith   PetscFunctionBegin;
1620273d9f13SBarry Smith   ierr = MPI_Comm_size(B->comm,&size);CHKERRQ(ierr);
162129bbc08cSBarry Smith   if (size > 1) SETERRQ(PETSC_ERR_ARG_WRONG,"Comm must be of size 1");
1622b6490206SBarry Smith 
1623273d9f13SBarry Smith   B->m = B->M = PetscMax(B->m,B->M);
1624273d9f13SBarry Smith   B->n = B->N = PetscMax(B->n,B->N);
1625b0a32e0cSBarry Smith   ierr    = PetscNew(Mat_SeqBAIJ,&b);CHKERRQ(ierr);
1626b0a32e0cSBarry Smith   B->data = (void*)b;
1627549d3d68SSatish Balay   ierr    = PetscMemzero(b,sizeof(Mat_SeqBAIJ));CHKERRQ(ierr);
1628549d3d68SSatish Balay   ierr    = PetscMemcpy(B->ops,&MatOps_Values,sizeof(struct _MatOps));CHKERRQ(ierr);
16292593348eSBarry Smith   B->factor           = 0;
16302593348eSBarry Smith   B->lupivotthreshold = 1.0;
163190f02eecSBarry Smith   B->mapping          = 0;
16322593348eSBarry Smith   b->row              = 0;
16332593348eSBarry Smith   b->col              = 0;
1634e51c0b9cSSatish Balay   b->icol             = 0;
16352593348eSBarry Smith   b->reallocs         = 0;
16363e90b805SBarry Smith   b->saved_values     = 0;
1637cfce73b9SSatish Balay #if defined(PETSC_USE_MAT_SINGLE)
1638563b5814SBarry Smith   b->setvalueslen     = 0;
1639563b5814SBarry Smith   b->setvaluescopy    = PETSC_NULL;
1640563b5814SBarry Smith #endif
16412593348eSBarry Smith 
16423a64cc32SBarry Smith   ierr = PetscMapCreateMPI(B->comm,B->m,B->m,&B->rmap);CHKERRQ(ierr);
16433a64cc32SBarry Smith   ierr = PetscMapCreateMPI(B->comm,B->n,B->n,&B->cmap);CHKERRQ(ierr);
1644a5ae1ecdSBarry Smith 
1645c4992f7dSBarry Smith   b->sorted           = PETSC_FALSE;
1646c4992f7dSBarry Smith   b->roworiented      = PETSC_TRUE;
16472593348eSBarry Smith   b->nonew            = 0;
16482593348eSBarry Smith   b->diag             = 0;
16492593348eSBarry Smith   b->solve_work       = 0;
1650de6a44a3SBarry Smith   b->mult_work        = 0;
16512a1b7f2aSHong Zhang   B->spptr            = 0;
16520e6d2581SBarry Smith   B->info.nz_unneeded = (PetscReal)b->maxnz;
1653883fce79SBarry Smith   b->keepzeroedrows   = PETSC_FALSE;
16544e220ebcSLois Curfman McInnes 
1655f1af5d2fSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatStoreValues_C",
16563e90b805SBarry Smith                                      "MatStoreValues_SeqBAIJ",
1657bc4b532fSSatish Balay                                       MatStoreValues_SeqBAIJ);CHKERRQ(ierr);
1658f1af5d2fSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatRetrieveValues_C",
16593e90b805SBarry Smith                                      "MatRetrieveValues_SeqBAIJ",
1660bc4b532fSSatish Balay                                       MatRetrieveValues_SeqBAIJ);CHKERRQ(ierr);
1661f1af5d2fSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatSeqBAIJSetColumnIndices_C",
166227a8da17SBarry Smith                                      "MatSeqBAIJSetColumnIndices_SeqBAIJ",
1663bc4b532fSSatish Balay                                       MatSeqBAIJSetColumnIndices_SeqBAIJ);CHKERRQ(ierr);
1664a6175056SHong Zhang   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatConvert_seqbaij_seqaij_C",
1665273d9f13SBarry Smith                                      "MatConvert_SeqBAIJ_SeqAIJ",
1666273d9f13SBarry Smith                                       MatConvert_SeqBAIJ_SeqAIJ);CHKERRQ(ierr);
16673a40ed3dSBarry Smith   PetscFunctionReturn(0);
16682593348eSBarry Smith }
1669273d9f13SBarry Smith EXTERN_C_END
16702593348eSBarry Smith 
16714a2ae208SSatish Balay #undef __FUNCT__
16724a2ae208SSatish Balay #define __FUNCT__ "MatDuplicate_SeqBAIJ"
16732e8a6d31SBarry Smith int MatDuplicate_SeqBAIJ(Mat A,MatDuplicateOption cpvalues,Mat *B)
16742593348eSBarry Smith {
16752593348eSBarry Smith   Mat         C;
1676b6490206SBarry Smith   Mat_SeqBAIJ *c,*a = (Mat_SeqBAIJ*)A->data;
167727a8da17SBarry Smith   int         i,len,mbs = a->mbs,nz = a->nz,bs2 =a->bs2,ierr;
1678de6a44a3SBarry Smith 
16793a40ed3dSBarry Smith   PetscFunctionBegin;
168029bbc08cSBarry Smith   if (a->i[mbs] != nz) SETERRQ(PETSC_ERR_PLIB,"Corrupt matrix");
16812593348eSBarry Smith 
16822593348eSBarry Smith   *B = 0;
1683273d9f13SBarry Smith   ierr = MatCreate(A->comm,A->m,A->n,A->m,A->n,&C);CHKERRQ(ierr);
1684273d9f13SBarry Smith   ierr = MatSetType(C,MATSEQBAIJ);CHKERRQ(ierr);
1685273d9f13SBarry Smith   c    = (Mat_SeqBAIJ*)C->data;
168644cd7ae7SLois Curfman McInnes 
1687b6490206SBarry Smith   c->bs         = a->bs;
16889df24120SSatish Balay   c->bs2        = a->bs2;
1689b6490206SBarry Smith   c->mbs        = a->mbs;
1690b6490206SBarry Smith   c->nbs        = a->nbs;
169135d8aa7fSBarry Smith   ierr = PetscMemcpy(C->ops,A->ops,sizeof(struct _MatOps));CHKERRQ(ierr);
16922593348eSBarry Smith 
1693b0a32e0cSBarry Smith   ierr = PetscMalloc((mbs+1)*sizeof(int),&c->imax);CHKERRQ(ierr);
1694b0a32e0cSBarry Smith   ierr = PetscMalloc((mbs+1)*sizeof(int),&c->ilen);CHKERRQ(ierr);
1695b6490206SBarry Smith   for (i=0; i<mbs; i++) {
16962593348eSBarry Smith     c->imax[i] = a->imax[i];
16972593348eSBarry Smith     c->ilen[i] = a->ilen[i];
16982593348eSBarry Smith   }
16992593348eSBarry Smith 
17002593348eSBarry Smith   /* allocate the matrix space */
1701c4992f7dSBarry Smith   c->singlemalloc = PETSC_TRUE;
17023f1db9ecSBarry Smith   len  = (mbs+1)*sizeof(int) + nz*(bs2*sizeof(MatScalar) + sizeof(int));
1703b0a32e0cSBarry Smith   ierr = PetscMalloc(len,&c->a);CHKERRQ(ierr);
17047e67e3f9SSatish Balay   c->j = (int*)(c->a + nz*bs2);
1705de6a44a3SBarry Smith   c->i = c->j + nz;
1706549d3d68SSatish Balay   ierr = PetscMemcpy(c->i,a->i,(mbs+1)*sizeof(int));CHKERRQ(ierr);
1707b6490206SBarry Smith   if (mbs > 0) {
1708549d3d68SSatish Balay     ierr = PetscMemcpy(c->j,a->j,nz*sizeof(int));CHKERRQ(ierr);
17092e8a6d31SBarry Smith     if (cpvalues == MAT_COPY_VALUES) {
1710549d3d68SSatish Balay       ierr = PetscMemcpy(c->a,a->a,bs2*nz*sizeof(MatScalar));CHKERRQ(ierr);
17112e8a6d31SBarry Smith     } else {
1712549d3d68SSatish Balay       ierr = PetscMemzero(c->a,bs2*nz*sizeof(MatScalar));CHKERRQ(ierr);
17132593348eSBarry Smith     }
17142593348eSBarry Smith   }
17152593348eSBarry Smith 
1716b0a32e0cSBarry Smith   PetscLogObjectMemory(C,len+2*(mbs+1)*sizeof(int)+sizeof(struct _p_Mat)+sizeof(Mat_SeqBAIJ));
17172593348eSBarry Smith   c->sorted      = a->sorted;
17182593348eSBarry Smith   c->roworiented = a->roworiented;
17192593348eSBarry Smith   c->nonew       = a->nonew;
17202593348eSBarry Smith 
17212593348eSBarry Smith   if (a->diag) {
1722b0a32e0cSBarry Smith     ierr = PetscMalloc((mbs+1)*sizeof(int),&c->diag);CHKERRQ(ierr);
1723b0a32e0cSBarry Smith     PetscLogObjectMemory(C,(mbs+1)*sizeof(int));
1724b6490206SBarry Smith     for (i=0; i<mbs; i++) {
17252593348eSBarry Smith       c->diag[i] = a->diag[i];
17262593348eSBarry Smith     }
172798305bb5SBarry Smith   } else c->diag        = 0;
17282593348eSBarry Smith   c->nz                 = a->nz;
17292593348eSBarry Smith   c->maxnz              = a->maxnz;
17302593348eSBarry Smith   c->solve_work         = 0;
17312a1b7f2aSHong Zhang   C->spptr              = 0;     /* Dangerous -I'm throwing away a->spptr */
17327fc0212eSBarry Smith   c->mult_work          = 0;
1733273d9f13SBarry Smith   C->preallocated       = PETSC_TRUE;
1734273d9f13SBarry Smith   C->assembled          = PETSC_TRUE;
17352593348eSBarry Smith   *B = C;
1736b0a32e0cSBarry Smith   ierr = PetscFListDuplicate(A->qlist,&C->qlist);CHKERRQ(ierr);
17373a40ed3dSBarry Smith   PetscFunctionReturn(0);
17382593348eSBarry Smith }
17392593348eSBarry Smith 
1740273d9f13SBarry Smith EXTERN_C_BEGIN
17414a2ae208SSatish Balay #undef __FUNCT__
17424a2ae208SSatish Balay #define __FUNCT__ "MatLoad_SeqBAIJ"
1743b0a32e0cSBarry Smith int MatLoad_SeqBAIJ(PetscViewer viewer,MatType type,Mat *A)
17442593348eSBarry Smith {
1745b6490206SBarry Smith   Mat_SeqBAIJ  *a;
17462593348eSBarry Smith   Mat          B;
1747f1af5d2fSBarry Smith   int          i,nz,ierr,fd,header[4],size,*rowlengths=0,M,N,bs=1;
1748b6490206SBarry Smith   int          *mask,mbs,*jj,j,rowcount,nzcount,k,*browlengths,maskcount;
174935aab85fSBarry Smith   int          kmax,jcount,block,idx,point,nzcountb,extra_rows;
1750a7c10996SSatish Balay   int          *masked,nmask,tmp,bs2,ishift;
175187828ca2SBarry Smith   PetscScalar  *aa;
175219bcc07fSBarry Smith   MPI_Comm     comm = ((PetscObject)viewer)->comm;
1753ecc4ab6dSBarry Smith #if defined(PETSC_HAVE_DSCPACK)
1754ecc4ab6dSBarry Smith   PetscTruth   flag;
1755ecc4ab6dSBarry Smith #endif
17562593348eSBarry Smith 
17573a40ed3dSBarry Smith   PetscFunctionBegin;
1758b0a32e0cSBarry Smith   ierr = PetscOptionsGetInt(PETSC_NULL,"-matload_block_size",&bs,PETSC_NULL);CHKERRQ(ierr);
1759de6a44a3SBarry Smith   bs2  = bs*bs;
1760b6490206SBarry Smith 
1761d132466eSBarry Smith   ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr);
176229bbc08cSBarry Smith   if (size > 1) SETERRQ(PETSC_ERR_ARG_WRONG,"view must have one processor");
1763b0a32e0cSBarry Smith   ierr = PetscViewerBinaryGetDescriptor(viewer,&fd);CHKERRQ(ierr);
17640752156aSBarry Smith   ierr = PetscBinaryRead(fd,header,4,PETSC_INT);CHKERRQ(ierr);
1765552e946dSBarry Smith   if (header[0] != MAT_FILE_COOKIE) SETERRQ(PETSC_ERR_FILE_UNEXPECTED,"not Mat object");
17662593348eSBarry Smith   M = header[1]; N = header[2]; nz = header[3];
17672593348eSBarry Smith 
1768d64ed03dSBarry Smith   if (header[3] < 0) {
176929bbc08cSBarry Smith     SETERRQ(PETSC_ERR_FILE_UNEXPECTED,"Matrix stored in special format, cannot load as SeqBAIJ");
1770d64ed03dSBarry Smith   }
1771d64ed03dSBarry Smith 
177229bbc08cSBarry Smith   if (M != N) SETERRQ(PETSC_ERR_SUP,"Can only do square matrices");
177335aab85fSBarry Smith 
177435aab85fSBarry Smith   /*
177535aab85fSBarry Smith      This code adds extra rows to make sure the number of rows is
177635aab85fSBarry Smith     divisible by the blocksize
177735aab85fSBarry Smith   */
1778b6490206SBarry Smith   mbs        = M/bs;
177935aab85fSBarry Smith   extra_rows = bs - M + bs*(mbs);
178035aab85fSBarry Smith   if (extra_rows == bs) extra_rows = 0;
178135aab85fSBarry Smith   else                  mbs++;
178235aab85fSBarry Smith   if (extra_rows) {
1783b0a32e0cSBarry Smith     PetscLogInfo(0,"MatLoad_SeqBAIJ:Padding loaded matrix to match blocksize\n");
178435aab85fSBarry Smith   }
1785b6490206SBarry Smith 
17862593348eSBarry Smith   /* read in row lengths */
1787b0a32e0cSBarry Smith   ierr = PetscMalloc((M+extra_rows)*sizeof(int),&rowlengths);CHKERRQ(ierr);
17880752156aSBarry Smith   ierr = PetscBinaryRead(fd,rowlengths,M,PETSC_INT);CHKERRQ(ierr);
178935aab85fSBarry Smith   for (i=0; i<extra_rows; i++) rowlengths[M+i] = 1;
17902593348eSBarry Smith 
1791b6490206SBarry Smith   /* read in column indices */
1792b0a32e0cSBarry Smith   ierr = PetscMalloc((nz+extra_rows)*sizeof(int),&jj);CHKERRQ(ierr);
17930752156aSBarry Smith   ierr = PetscBinaryRead(fd,jj,nz,PETSC_INT);CHKERRQ(ierr);
179435aab85fSBarry Smith   for (i=0; i<extra_rows; i++) jj[nz+i] = M+i;
1795b6490206SBarry Smith 
1796b6490206SBarry Smith   /* loop over row lengths determining block row lengths */
1797b0a32e0cSBarry Smith   ierr     = PetscMalloc(mbs*sizeof(int),&browlengths);CHKERRQ(ierr);
1798549d3d68SSatish Balay   ierr     = PetscMemzero(browlengths,mbs*sizeof(int));CHKERRQ(ierr);
1799b0a32e0cSBarry Smith   ierr     = PetscMalloc(2*mbs*sizeof(int),&mask);CHKERRQ(ierr);
1800549d3d68SSatish Balay   ierr     = PetscMemzero(mask,mbs*sizeof(int));CHKERRQ(ierr);
180135aab85fSBarry Smith   masked   = mask + mbs;
1802b6490206SBarry Smith   rowcount = 0; nzcount = 0;
1803b6490206SBarry Smith   for (i=0; i<mbs; i++) {
180435aab85fSBarry Smith     nmask = 0;
1805b6490206SBarry Smith     for (j=0; j<bs; j++) {
1806b6490206SBarry Smith       kmax = rowlengths[rowcount];
1807b6490206SBarry Smith       for (k=0; k<kmax; k++) {
180835aab85fSBarry Smith         tmp = jj[nzcount++]/bs;
180935aab85fSBarry Smith         if (!mask[tmp]) {masked[nmask++] = tmp; mask[tmp] = 1;}
1810b6490206SBarry Smith       }
1811b6490206SBarry Smith       rowcount++;
1812b6490206SBarry Smith     }
181335aab85fSBarry Smith     browlengths[i] += nmask;
181435aab85fSBarry Smith     /* zero out the mask elements we set */
181535aab85fSBarry Smith     for (j=0; j<nmask; j++) mask[masked[j]] = 0;
1816b6490206SBarry Smith   }
1817b6490206SBarry Smith 
18182593348eSBarry Smith   /* create our matrix */
18193eee16b0SBarry Smith   ierr = MatCreateSeqBAIJ(comm,bs,M+extra_rows,N+extra_rows,0,browlengths,A);CHKERRQ(ierr);
18202593348eSBarry Smith   B = *A;
1821b6490206SBarry Smith   a = (Mat_SeqBAIJ*)B->data;
18222593348eSBarry Smith 
18232593348eSBarry Smith   /* set matrix "i" values */
1824de6a44a3SBarry Smith   a->i[0] = 0;
1825b6490206SBarry Smith   for (i=1; i<= mbs; i++) {
1826b6490206SBarry Smith     a->i[i]      = a->i[i-1] + browlengths[i-1];
1827b6490206SBarry Smith     a->ilen[i-1] = browlengths[i-1];
18282593348eSBarry Smith   }
1829b6490206SBarry Smith   a->nz         = 0;
1830b6490206SBarry Smith   for (i=0; i<mbs; i++) a->nz += browlengths[i];
18312593348eSBarry Smith 
1832b6490206SBarry Smith   /* read in nonzero values */
183387828ca2SBarry Smith   ierr = PetscMalloc((nz+extra_rows)*sizeof(PetscScalar),&aa);CHKERRQ(ierr);
18340752156aSBarry Smith   ierr = PetscBinaryRead(fd,aa,nz,PETSC_SCALAR);CHKERRQ(ierr);
183535aab85fSBarry Smith   for (i=0; i<extra_rows; i++) aa[nz+i] = 1.0;
1836b6490206SBarry Smith 
1837b6490206SBarry Smith   /* set "a" and "j" values into matrix */
1838b6490206SBarry Smith   nzcount = 0; jcount = 0;
1839b6490206SBarry Smith   for (i=0; i<mbs; i++) {
1840b6490206SBarry Smith     nzcountb = nzcount;
184135aab85fSBarry Smith     nmask    = 0;
1842b6490206SBarry Smith     for (j=0; j<bs; j++) {
1843b6490206SBarry Smith       kmax = rowlengths[i*bs+j];
1844b6490206SBarry Smith       for (k=0; k<kmax; k++) {
184535aab85fSBarry Smith         tmp = jj[nzcount++]/bs;
184635aab85fSBarry Smith 	if (!mask[tmp]) { masked[nmask++] = tmp; mask[tmp] = 1;}
1847b6490206SBarry Smith       }
1848b6490206SBarry Smith     }
1849de6a44a3SBarry Smith     /* sort the masked values */
1850433994e6SBarry Smith     ierr = PetscSortInt(nmask,masked);CHKERRQ(ierr);
1851de6a44a3SBarry Smith 
1852b6490206SBarry Smith     /* set "j" values into matrix */
1853b6490206SBarry Smith     maskcount = 1;
185435aab85fSBarry Smith     for (j=0; j<nmask; j++) {
185535aab85fSBarry Smith       a->j[jcount++]  = masked[j];
1856de6a44a3SBarry Smith       mask[masked[j]] = maskcount++;
1857b6490206SBarry Smith     }
1858b6490206SBarry Smith     /* set "a" values into matrix */
1859de6a44a3SBarry Smith     ishift = bs2*a->i[i];
1860b6490206SBarry Smith     for (j=0; j<bs; j++) {
1861b6490206SBarry Smith       kmax = rowlengths[i*bs+j];
1862b6490206SBarry Smith       for (k=0; k<kmax; k++) {
1863de6a44a3SBarry Smith         tmp       = jj[nzcountb]/bs ;
1864de6a44a3SBarry Smith         block     = mask[tmp] - 1;
1865de6a44a3SBarry Smith         point     = jj[nzcountb] - bs*tmp;
1866de6a44a3SBarry Smith         idx       = ishift + bs2*block + j + bs*point;
1867375fe846SBarry Smith         a->a[idx] = (MatScalar)aa[nzcountb++];
1868b6490206SBarry Smith       }
1869b6490206SBarry Smith     }
187035aab85fSBarry Smith     /* zero out the mask elements we set */
187135aab85fSBarry Smith     for (j=0; j<nmask; j++) mask[masked[j]] = 0;
1872b6490206SBarry Smith   }
187329bbc08cSBarry Smith   if (jcount != a->nz) SETERRQ(PETSC_ERR_FILE_UNEXPECTED,"Bad binary matrix");
1874b6490206SBarry Smith 
1875606d414cSSatish Balay   ierr = PetscFree(rowlengths);CHKERRQ(ierr);
1876606d414cSSatish Balay   ierr = PetscFree(browlengths);CHKERRQ(ierr);
1877606d414cSSatish Balay   ierr = PetscFree(aa);CHKERRQ(ierr);
1878606d414cSSatish Balay   ierr = PetscFree(jj);CHKERRQ(ierr);
1879606d414cSSatish Balay   ierr = PetscFree(mask);CHKERRQ(ierr);
1880b6490206SBarry Smith 
1881b6490206SBarry Smith   B->assembled = PETSC_TRUE;
1882de6a44a3SBarry Smith 
1883ecc4ab6dSBarry Smith #if defined(PETSC_HAVE_DSCPACK)
1884ecc4ab6dSBarry Smith   ierr = PetscOptionsHasName(B->prefix,"-mat_baij_dscpack",&flag);CHKERRQ(ierr);
1885ecc4ab6dSBarry Smith   if (flag) { ierr = MatUseDSCPACK_MPIBAIJ(B);CHKERRQ(ierr); }
1886ecc4ab6dSBarry Smith #endif
1887ecc4ab6dSBarry Smith 
18889c01be13SBarry Smith   ierr = MatView_Private(B);CHKERRQ(ierr);
18893a40ed3dSBarry Smith   PetscFunctionReturn(0);
18902593348eSBarry Smith }
1891273d9f13SBarry Smith EXTERN_C_END
18922593348eSBarry Smith 
18934a2ae208SSatish Balay #undef __FUNCT__
18944a2ae208SSatish Balay #define __FUNCT__ "MatCreateSeqBAIJ"
1895273d9f13SBarry Smith /*@C
1896273d9f13SBarry Smith    MatCreateSeqBAIJ - Creates a sparse matrix in block AIJ (block
1897273d9f13SBarry Smith    compressed row) format.  For good matrix assembly performance the
1898273d9f13SBarry Smith    user should preallocate the matrix storage by setting the parameter nz
1899273d9f13SBarry Smith    (or the array nnz).  By setting these parameters accurately, performance
1900273d9f13SBarry Smith    during matrix assembly can be increased by more than a factor of 50.
19012593348eSBarry Smith 
1902273d9f13SBarry Smith    Collective on MPI_Comm
1903273d9f13SBarry Smith 
1904273d9f13SBarry Smith    Input Parameters:
1905273d9f13SBarry Smith +  comm - MPI communicator, set to PETSC_COMM_SELF
1906273d9f13SBarry Smith .  bs - size of block
1907273d9f13SBarry Smith .  m - number of rows
1908273d9f13SBarry Smith .  n - number of columns
190935d8aa7fSBarry Smith .  nz - number of nonzero blocks  per block row (same for all rows)
191035d8aa7fSBarry Smith -  nnz - array containing the number of nonzero blocks in the various block rows
1911273d9f13SBarry Smith          (possibly different for each block row) or PETSC_NULL
1912273d9f13SBarry Smith 
1913273d9f13SBarry Smith    Output Parameter:
1914273d9f13SBarry Smith .  A - the matrix
1915273d9f13SBarry Smith 
1916273d9f13SBarry Smith    Options Database Keys:
1917273d9f13SBarry Smith .   -mat_no_unroll - uses code that does not unroll the loops in the
1918273d9f13SBarry Smith                      block calculations (much slower)
1919273d9f13SBarry Smith .    -mat_block_size - size of the blocks to use
1920273d9f13SBarry Smith 
1921273d9f13SBarry Smith    Level: intermediate
1922273d9f13SBarry Smith 
1923273d9f13SBarry Smith    Notes:
192435d8aa7fSBarry Smith    A nonzero block is any block that as 1 or more nonzeros in it
192535d8aa7fSBarry Smith 
1926273d9f13SBarry Smith    The block AIJ format is fully compatible with standard Fortran 77
1927273d9f13SBarry Smith    storage.  That is, the stored row and column indices can begin at
1928273d9f13SBarry Smith    either one (as in Fortran) or zero.  See the users' manual for details.
1929273d9f13SBarry Smith 
1930273d9f13SBarry Smith    Specify the preallocated storage with either nz or nnz (not both).
1931273d9f13SBarry Smith    Set nz=PETSC_DEFAULT and nnz=PETSC_NULL for PETSc to control dynamic memory
1932273d9f13SBarry Smith    allocation.  For additional details, see the users manual chapter on
1933273d9f13SBarry Smith    matrices.
1934273d9f13SBarry Smith 
1935273d9f13SBarry Smith .seealso: MatCreate(), MatCreateSeqAIJ(), MatSetValues(), MatCreateMPIBAIJ()
1936273d9f13SBarry Smith @*/
1937273d9f13SBarry Smith int MatCreateSeqBAIJ(MPI_Comm comm,int bs,int m,int n,int nz,int *nnz,Mat *A)
1938273d9f13SBarry Smith {
1939273d9f13SBarry Smith   int ierr;
1940273d9f13SBarry Smith 
1941273d9f13SBarry Smith   PetscFunctionBegin;
1942273d9f13SBarry Smith   ierr = MatCreate(comm,m,n,m,n,A);CHKERRQ(ierr);
1943273d9f13SBarry Smith   ierr = MatSetType(*A,MATSEQBAIJ);CHKERRQ(ierr);
1944273d9f13SBarry Smith   ierr = MatSeqBAIJSetPreallocation(*A,bs,nz,nnz);CHKERRQ(ierr);
1945273d9f13SBarry Smith   PetscFunctionReturn(0);
1946273d9f13SBarry Smith }
1947273d9f13SBarry Smith 
19484a2ae208SSatish Balay #undef __FUNCT__
19494a2ae208SSatish Balay #define __FUNCT__ "MatSeqBAIJSetPreallocation"
1950273d9f13SBarry Smith /*@C
1951273d9f13SBarry Smith    MatSeqBAIJSetPreallocation - Sets the block size and expected nonzeros
1952273d9f13SBarry Smith    per row in the matrix. For good matrix assembly performance the
1953273d9f13SBarry Smith    user should preallocate the matrix storage by setting the parameter nz
1954273d9f13SBarry Smith    (or the array nnz).  By setting these parameters accurately, performance
1955273d9f13SBarry Smith    during matrix assembly can be increased by more than a factor of 50.
1956273d9f13SBarry Smith 
1957273d9f13SBarry Smith    Collective on MPI_Comm
1958273d9f13SBarry Smith 
1959273d9f13SBarry Smith    Input Parameters:
1960273d9f13SBarry Smith +  A - the matrix
1961273d9f13SBarry Smith .  bs - size of block
1962273d9f13SBarry Smith .  nz - number of block nonzeros per block row (same for all rows)
1963273d9f13SBarry Smith -  nnz - array containing the number of block nonzeros in the various block rows
1964273d9f13SBarry Smith          (possibly different for each block row) or PETSC_NULL
1965273d9f13SBarry Smith 
1966273d9f13SBarry Smith    Options Database Keys:
1967273d9f13SBarry Smith .   -mat_no_unroll - uses code that does not unroll the loops in the
1968273d9f13SBarry Smith                      block calculations (much slower)
1969273d9f13SBarry Smith .    -mat_block_size - size of the blocks to use
1970273d9f13SBarry Smith 
1971273d9f13SBarry Smith    Level: intermediate
1972273d9f13SBarry Smith 
1973273d9f13SBarry Smith    Notes:
1974273d9f13SBarry Smith    The block AIJ format is fully compatible with standard Fortran 77
1975273d9f13SBarry Smith    storage.  That is, the stored row and column indices can begin at
1976273d9f13SBarry Smith    either one (as in Fortran) or zero.  See the users' manual for details.
1977273d9f13SBarry Smith 
1978273d9f13SBarry Smith    Specify the preallocated storage with either nz or nnz (not both).
1979273d9f13SBarry Smith    Set nz=PETSC_DEFAULT and nnz=PETSC_NULL for PETSc to control dynamic memory
1980273d9f13SBarry Smith    allocation.  For additional details, see the users manual chapter on
1981273d9f13SBarry Smith    matrices.
1982273d9f13SBarry Smith 
1983273d9f13SBarry Smith .seealso: MatCreate(), MatCreateSeqAIJ(), MatSetValues(), MatCreateMPIBAIJ()
1984273d9f13SBarry Smith @*/
1985273d9f13SBarry Smith int MatSeqBAIJSetPreallocation(Mat B,int bs,int nz,int *nnz)
1986273d9f13SBarry Smith {
1987273d9f13SBarry Smith   Mat_SeqBAIJ *b;
1988273d9f13SBarry Smith   int         i,len,ierr,mbs,nbs,bs2,newbs = bs;
1989273d9f13SBarry Smith   PetscTruth  flg;
1990273d9f13SBarry Smith 
1991273d9f13SBarry Smith   PetscFunctionBegin;
1992273d9f13SBarry Smith   ierr = PetscTypeCompare((PetscObject)B,MATSEQBAIJ,&flg);CHKERRQ(ierr);
1993273d9f13SBarry Smith   if (!flg) PetscFunctionReturn(0);
1994273d9f13SBarry Smith 
1995273d9f13SBarry Smith   B->preallocated = PETSC_TRUE;
1996b0a32e0cSBarry Smith   ierr = PetscOptionsGetInt(B->prefix,"-mat_block_size",&newbs,PETSC_NULL);CHKERRQ(ierr);
1997273d9f13SBarry Smith   if (nnz && newbs != bs) {
1998273d9f13SBarry Smith     SETERRQ(1,"Cannot change blocksize from command line if setting nnz");
1999273d9f13SBarry Smith   }
2000273d9f13SBarry Smith   bs   = newbs;
2001273d9f13SBarry Smith 
2002273d9f13SBarry Smith   mbs  = B->m/bs;
2003273d9f13SBarry Smith   nbs  = B->n/bs;
2004273d9f13SBarry Smith   bs2  = bs*bs;
2005273d9f13SBarry Smith 
2006273d9f13SBarry Smith   if (mbs*bs!=B->m || nbs*bs!=B->n) {
200735d8aa7fSBarry Smith     SETERRQ3(PETSC_ERR_ARG_SIZ,"Number rows %d, cols %d must be divisible by blocksize %d",B->m,B->n,bs);
2008273d9f13SBarry Smith   }
2009273d9f13SBarry Smith 
2010435da068SBarry Smith   if (nz == PETSC_DEFAULT || nz == PETSC_DECIDE) nz = 5;
2011435da068SBarry Smith   if (nz < 0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"nz cannot be less than 0: value %d",nz);
2012273d9f13SBarry Smith   if (nnz) {
2013273d9f13SBarry Smith     for (i=0; i<mbs; i++) {
2014273d9f13SBarry Smith       if (nnz[i] < 0) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"nnz cannot be less than 0: local row %d value %d",i,nnz[i]);
20153a7fca6bSBarry Smith       if (nnz[i] > nbs) SETERRQ3(PETSC_ERR_ARG_OUTOFRANGE,"nnz cannot be greater than block row length: local row %d value %d rowlength %d",i,nnz[i],nbs);
2016273d9f13SBarry Smith     }
2017273d9f13SBarry Smith   }
2018273d9f13SBarry Smith 
2019273d9f13SBarry Smith   b       = (Mat_SeqBAIJ*)B->data;
2020b0a32e0cSBarry Smith   ierr    = PetscOptionsHasName(PETSC_NULL,"-mat_no_unroll",&flg);CHKERRQ(ierr);
202154138f6bSKris Buschelman   B->ops->solve               = MatSolve_SeqBAIJ_Update;
202254138f6bSKris Buschelman   B->ops->solvetranspose      = MatSolveTranspose_SeqBAIJ_Update;
2023273d9f13SBarry Smith   if (!flg) {
2024273d9f13SBarry Smith     switch (bs) {
2025273d9f13SBarry Smith     case 1:
2026273d9f13SBarry Smith       B->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_1;
2027273d9f13SBarry Smith       B->ops->mult            = MatMult_SeqBAIJ_1;
2028273d9f13SBarry Smith       B->ops->multadd         = MatMultAdd_SeqBAIJ_1;
2029273d9f13SBarry Smith       break;
2030273d9f13SBarry Smith     case 2:
2031273d9f13SBarry Smith       B->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_2;
2032273d9f13SBarry Smith       B->ops->mult            = MatMult_SeqBAIJ_2;
2033273d9f13SBarry Smith       B->ops->multadd         = MatMultAdd_SeqBAIJ_2;
2034273d9f13SBarry Smith       break;
2035273d9f13SBarry Smith     case 3:
2036273d9f13SBarry Smith       B->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_3;
2037273d9f13SBarry Smith       B->ops->mult            = MatMult_SeqBAIJ_3;
2038273d9f13SBarry Smith       B->ops->multadd         = MatMultAdd_SeqBAIJ_3;
2039273d9f13SBarry Smith       break;
2040273d9f13SBarry Smith     case 4:
2041273d9f13SBarry Smith       B->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_4;
2042273d9f13SBarry Smith       B->ops->mult            = MatMult_SeqBAIJ_4;
2043273d9f13SBarry Smith       B->ops->multadd         = MatMultAdd_SeqBAIJ_4;
2044273d9f13SBarry Smith       break;
2045273d9f13SBarry Smith     case 5:
2046273d9f13SBarry Smith       B->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_5;
2047273d9f13SBarry Smith       B->ops->mult            = MatMult_SeqBAIJ_5;
2048273d9f13SBarry Smith       B->ops->multadd         = MatMultAdd_SeqBAIJ_5;
2049273d9f13SBarry Smith       break;
2050273d9f13SBarry Smith     case 6:
2051273d9f13SBarry Smith       B->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_6;
2052273d9f13SBarry Smith       B->ops->mult            = MatMult_SeqBAIJ_6;
2053273d9f13SBarry Smith       B->ops->multadd         = MatMultAdd_SeqBAIJ_6;
2054273d9f13SBarry Smith       break;
2055273d9f13SBarry Smith     case 7:
205654138f6bSKris Buschelman       B->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_7;
2057273d9f13SBarry Smith       B->ops->mult            = MatMult_SeqBAIJ_7;
2058273d9f13SBarry Smith       B->ops->multadd         = MatMultAdd_SeqBAIJ_7;
2059273d9f13SBarry Smith       break;
2060273d9f13SBarry Smith     default:
206154138f6bSKris Buschelman       B->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_N;
2062273d9f13SBarry Smith       B->ops->mult            = MatMult_SeqBAIJ_N;
2063273d9f13SBarry Smith       B->ops->multadd         = MatMultAdd_SeqBAIJ_N;
2064273d9f13SBarry Smith       break;
2065273d9f13SBarry Smith     }
2066273d9f13SBarry Smith   }
2067273d9f13SBarry Smith   b->bs      = bs;
2068273d9f13SBarry Smith   b->mbs     = mbs;
2069273d9f13SBarry Smith   b->nbs     = nbs;
2070b0a32e0cSBarry Smith   ierr = PetscMalloc((mbs+1)*sizeof(int),&b->imax);CHKERRQ(ierr);
2071273d9f13SBarry Smith   if (!nnz) {
2072435da068SBarry Smith     if (nz == PETSC_DEFAULT || nz == PETSC_DECIDE) nz = 5;
2073273d9f13SBarry Smith     else if (nz <= 0)        nz = 1;
2074273d9f13SBarry Smith     for (i=0; i<mbs; i++) b->imax[i] = nz;
2075273d9f13SBarry Smith     nz = nz*mbs;
2076273d9f13SBarry Smith   } else {
2077273d9f13SBarry Smith     nz = 0;
2078273d9f13SBarry Smith     for (i=0; i<mbs; i++) {b->imax[i] = nnz[i]; nz += nnz[i];}
2079273d9f13SBarry Smith   }
2080273d9f13SBarry Smith 
2081273d9f13SBarry Smith   /* allocate the matrix space */
2082273d9f13SBarry Smith   len   = nz*sizeof(int) + nz*bs2*sizeof(MatScalar) + (B->m+1)*sizeof(int);
2083b0a32e0cSBarry Smith   ierr  = PetscMalloc(len,&b->a);CHKERRQ(ierr);
2084273d9f13SBarry Smith   ierr  = PetscMemzero(b->a,nz*bs2*sizeof(MatScalar));CHKERRQ(ierr);
2085273d9f13SBarry Smith   b->j  = (int*)(b->a + nz*bs2);
2086273d9f13SBarry Smith   ierr = PetscMemzero(b->j,nz*sizeof(int));CHKERRQ(ierr);
2087273d9f13SBarry Smith   b->i  = b->j + nz;
2088273d9f13SBarry Smith   b->singlemalloc = PETSC_TRUE;
2089273d9f13SBarry Smith 
2090273d9f13SBarry Smith   b->i[0] = 0;
2091273d9f13SBarry Smith   for (i=1; i<mbs+1; i++) {
2092273d9f13SBarry Smith     b->i[i] = b->i[i-1] + b->imax[i-1];
2093273d9f13SBarry Smith   }
2094273d9f13SBarry Smith 
2095273d9f13SBarry Smith   /* b->ilen will count nonzeros in each block row so far. */
209616d6aa21SSatish Balay   ierr = PetscMalloc((mbs+1)*sizeof(int),&b->ilen);CHKERRQ(ierr);
2097b0a32e0cSBarry Smith   PetscLogObjectMemory(B,len+2*(mbs+1)*sizeof(int)+sizeof(struct _p_Mat)+sizeof(Mat_SeqBAIJ));
2098273d9f13SBarry Smith   for (i=0; i<mbs; i++) { b->ilen[i] = 0;}
2099273d9f13SBarry Smith 
2100273d9f13SBarry Smith   b->bs               = bs;
2101273d9f13SBarry Smith   b->bs2              = bs2;
2102273d9f13SBarry Smith   b->mbs              = mbs;
2103273d9f13SBarry Smith   b->nz               = 0;
2104273d9f13SBarry Smith   b->maxnz            = nz*bs2;
2105273d9f13SBarry Smith   B->info.nz_unneeded = (PetscReal)b->maxnz;
2106273d9f13SBarry Smith   PetscFunctionReturn(0);
2107273d9f13SBarry Smith }
21082593348eSBarry Smith 
2109