xref: /petsc/src/mat/impls/baij/seq/baij.c (revision 2d61bbb30bb97bd30a1404e6f75b18e940946690)
1a5eb4965SSatish Balay #ifdef PETSC_RCS_HEADER
2*2d61bbb3SSatish Balay static char vcid[] = "$Id: baij.c,v 1.119 1997/12/04 19:30:16 bsmith Exp balay $";
32593348eSBarry Smith #endif
42593348eSBarry Smith 
52593348eSBarry Smith /*
6b6490206SBarry Smith     Defines the basic matrix operations for the BAIJ (compressed row)
72593348eSBarry Smith   matrix storage format.
82593348eSBarry Smith */
93369ce9aSBarry Smith 
103369ce9aSBarry Smith #include "pinclude/pviewer.h"
113369ce9aSBarry Smith #include "sys.h"
1270f55243SBarry Smith #include "src/mat/impls/baij/seq/baij.h"
131a6a6d98SBarry Smith #include "src/vec/vecimpl.h"
141a6a6d98SBarry Smith #include "src/inline/spops.h"
152593348eSBarry Smith #include "petsc.h"
163b547af2SSatish Balay 
17*2d61bbb3SSatish Balay #define CHUNKSIZE  10
18de6a44a3SBarry Smith 
195615d1e5SSatish Balay #undef __FUNC__
205615d1e5SSatish Balay #define __FUNC__ "MatMarkDiag_SeqBAIJ"
21de6a44a3SBarry Smith int MatMarkDiag_SeqBAIJ(Mat A)
22de6a44a3SBarry Smith {
23de6a44a3SBarry Smith   Mat_SeqBAIJ *a = (Mat_SeqBAIJ *) A->data;
247fc0212eSBarry Smith   int         i,j, *diag, m = a->mbs;
25de6a44a3SBarry Smith 
263a40ed3dSBarry Smith   PetscFunctionBegin;
27de6a44a3SBarry Smith   diag = (int *) PetscMalloc( (m+1)*sizeof(int)); CHKPTRQ(diag);
28de6a44a3SBarry Smith   PLogObjectMemory(A,(m+1)*sizeof(int));
297fc0212eSBarry Smith   for ( i=0; i<m; i++ ) {
30de6a44a3SBarry Smith     for ( j=a->i[i]; j<a->i[i+1]; j++ ) {
31de6a44a3SBarry Smith       if (a->j[j] == i) {
32de6a44a3SBarry Smith         diag[i] = j;
33de6a44a3SBarry Smith         break;
34de6a44a3SBarry Smith       }
35de6a44a3SBarry Smith     }
36de6a44a3SBarry Smith   }
37de6a44a3SBarry Smith   a->diag = diag;
383a40ed3dSBarry Smith   PetscFunctionReturn(0);
39de6a44a3SBarry Smith }
402593348eSBarry Smith 
412593348eSBarry Smith 
423b2fbd54SBarry Smith extern int MatToSymmetricIJ_SeqAIJ(int,int*,int*,int,int,int**,int**);
433b2fbd54SBarry Smith 
445615d1e5SSatish Balay #undef __FUNC__
455615d1e5SSatish Balay #define __FUNC__ "MatGetRowIJ_SeqBAIJ"
463b2fbd54SBarry Smith static int MatGetRowIJ_SeqBAIJ(Mat A,int oshift,PetscTruth symmetric,int *nn,int **ia,int **ja,
473b2fbd54SBarry Smith                             PetscTruth *done)
483b2fbd54SBarry Smith {
493b2fbd54SBarry Smith   Mat_SeqBAIJ *a = (Mat_SeqBAIJ *) A->data;
503b2fbd54SBarry Smith   int         ierr, n = a->mbs,i;
513b2fbd54SBarry Smith 
523a40ed3dSBarry Smith   PetscFunctionBegin;
533b2fbd54SBarry Smith   *nn = n;
543a40ed3dSBarry Smith   if (!ia) PetscFunctionReturn(0);
553b2fbd54SBarry Smith   if (symmetric) {
563b2fbd54SBarry Smith     ierr = MatToSymmetricIJ_SeqAIJ(n,a->i,a->j,0,oshift,ia,ja);CHKERRQ(ierr);
573b2fbd54SBarry Smith   } else if (oshift == 1) {
583b2fbd54SBarry Smith     /* temporarily add 1 to i and j indices */
593b2fbd54SBarry Smith     int nz = a->i[n] + 1;
603b2fbd54SBarry Smith     for ( i=0; i<nz; i++ ) a->j[i]++;
613b2fbd54SBarry Smith     for ( i=0; i<n+1; i++ ) a->i[i]++;
623b2fbd54SBarry Smith     *ia = a->i; *ja = a->j;
633b2fbd54SBarry Smith   } else {
643b2fbd54SBarry Smith     *ia = a->i; *ja = a->j;
653b2fbd54SBarry Smith   }
663b2fbd54SBarry Smith 
673a40ed3dSBarry Smith   PetscFunctionReturn(0);
683b2fbd54SBarry Smith }
693b2fbd54SBarry Smith 
705615d1e5SSatish Balay #undef __FUNC__
71d4bb536fSBarry Smith #define __FUNC__ "MatRestoreRowIJ_SeqBAIJ"
723b2fbd54SBarry Smith static int MatRestoreRowIJ_SeqBAIJ(Mat A,int oshift,PetscTruth symmetric,int *nn,int **ia,int **ja,
733b2fbd54SBarry Smith                                 PetscTruth *done)
743b2fbd54SBarry Smith {
753b2fbd54SBarry Smith   Mat_SeqBAIJ *a = (Mat_SeqBAIJ *) A->data;
763b2fbd54SBarry Smith   int         i,n = a->mbs;
773b2fbd54SBarry Smith 
783a40ed3dSBarry Smith   PetscFunctionBegin;
793a40ed3dSBarry Smith   if (!ia) PetscFunctionReturn(0);
803b2fbd54SBarry Smith   if (symmetric) {
813b2fbd54SBarry Smith     PetscFree(*ia);
823b2fbd54SBarry Smith     PetscFree(*ja);
83af5da2bfSBarry Smith   } else if (oshift == 1) {
843b2fbd54SBarry Smith     int nz = a->i[n];
853b2fbd54SBarry Smith     for ( i=0; i<nz; i++ ) a->j[i]--;
863b2fbd54SBarry Smith     for ( i=0; i<n+1; i++ ) a->i[i]--;
873b2fbd54SBarry Smith   }
883a40ed3dSBarry Smith   PetscFunctionReturn(0);
893b2fbd54SBarry Smith }
903b2fbd54SBarry Smith 
91*2d61bbb3SSatish Balay #undef __FUNC__
92*2d61bbb3SSatish Balay #define __FUNC__ "MatGetBlockSize_SeqBAIJ"
93*2d61bbb3SSatish Balay int MatGetBlockSize_SeqBAIJ(Mat mat, int *bs)
94*2d61bbb3SSatish Balay {
95*2d61bbb3SSatish Balay   Mat_SeqBAIJ *baij = (Mat_SeqBAIJ *) mat->data;
96*2d61bbb3SSatish Balay 
97*2d61bbb3SSatish Balay   PetscFunctionBegin;
98*2d61bbb3SSatish Balay   *bs = baij->bs;
99*2d61bbb3SSatish Balay   PetscFunctionReturn(0);
100*2d61bbb3SSatish Balay }
101*2d61bbb3SSatish Balay 
102*2d61bbb3SSatish Balay 
103*2d61bbb3SSatish Balay #undef __FUNC__
104*2d61bbb3SSatish Balay #define __FUNC__ "MatDestroy_SeqBAIJ"
105*2d61bbb3SSatish Balay int MatDestroy_SeqBAIJ(PetscObject obj)
106*2d61bbb3SSatish Balay {
107*2d61bbb3SSatish Balay   Mat         A  = (Mat) obj;
108*2d61bbb3SSatish Balay   Mat_SeqBAIJ *a = (Mat_SeqBAIJ *) A->data;
109*2d61bbb3SSatish Balay 
110*2d61bbb3SSatish Balay #if defined(USE_PETSC_LOG)
111*2d61bbb3SSatish Balay   PLogObjectState(obj,"Rows=%d, Cols=%d, NZ=%d",a->m,a->n,a->nz);
112*2d61bbb3SSatish Balay #endif
113*2d61bbb3SSatish Balay   PetscFree(a->a);
114*2d61bbb3SSatish Balay   if (!a->singlemalloc) { PetscFree(a->i); PetscFree(a->j);}
115*2d61bbb3SSatish Balay   if (a->diag) PetscFree(a->diag);
116*2d61bbb3SSatish Balay   if (a->ilen) PetscFree(a->ilen);
117*2d61bbb3SSatish Balay   if (a->imax) PetscFree(a->imax);
118*2d61bbb3SSatish Balay   if (a->solve_work) PetscFree(a->solve_work);
119*2d61bbb3SSatish Balay   if (a->mult_work) PetscFree(a->mult_work);
120*2d61bbb3SSatish Balay   PetscFree(a);
121*2d61bbb3SSatish Balay   PLogObjectDestroy(A);
122*2d61bbb3SSatish Balay   PetscHeaderDestroy(A);
123*2d61bbb3SSatish Balay   PetscFunctionReturn(0);
124*2d61bbb3SSatish Balay }
125*2d61bbb3SSatish Balay 
126*2d61bbb3SSatish Balay #undef __FUNC__
127*2d61bbb3SSatish Balay #define __FUNC__ "MatSetOption_SeqBAIJ"
128*2d61bbb3SSatish Balay int MatSetOption_SeqBAIJ(Mat A,MatOption op)
129*2d61bbb3SSatish Balay {
130*2d61bbb3SSatish Balay   Mat_SeqBAIJ *a = (Mat_SeqBAIJ *) A->data;
131*2d61bbb3SSatish Balay 
132*2d61bbb3SSatish Balay   PetscFunctionBegin;
133*2d61bbb3SSatish Balay   if      (op == MAT_ROW_ORIENTED)                 a->roworiented = 1;
134*2d61bbb3SSatish Balay   else if (op == MAT_COLUMN_ORIENTED)              a->roworiented = 0;
135*2d61bbb3SSatish Balay   else if (op == MAT_COLUMNS_SORTED)               a->sorted      = 1;
136*2d61bbb3SSatish Balay   else if (op == MAT_COLUMNS_UNSORTED)             a->sorted      = 0;
137*2d61bbb3SSatish Balay   else if (op == MAT_NO_NEW_NONZERO_LOCATIONS)     a->nonew       = 1;
138*2d61bbb3SSatish Balay   else if (op == MAT_NEW_NONZERO_LOCATION_ERROR)   a->nonew       = -1;
139*2d61bbb3SSatish Balay   else if (op == MAT_NEW_NONZERO_ALLOCATION_ERROR) a->nonew       = -2;
140*2d61bbb3SSatish Balay   else if (op == MAT_YES_NEW_NONZERO_LOCATIONS)    a->nonew       = 0;
141*2d61bbb3SSatish Balay   else if (op == MAT_ROWS_SORTED ||
142*2d61bbb3SSatish Balay            op == MAT_ROWS_UNSORTED ||
143*2d61bbb3SSatish Balay            op == MAT_SYMMETRIC ||
144*2d61bbb3SSatish Balay            op == MAT_STRUCTURALLY_SYMMETRIC ||
145*2d61bbb3SSatish Balay            op == MAT_YES_NEW_DIAGONALS ||
146*2d61bbb3SSatish Balay            op == MAT_IGNORE_OFF_PROC_ENTRIES) {
147*2d61bbb3SSatish Balay     PLogInfo(A,"Info:MatSetOption_SeqBAIJ:Option ignored\n");
148*2d61bbb3SSatish Balay   } else if (op == MAT_NO_NEW_DIAGONALS) {
149*2d61bbb3SSatish Balay     SETERRQ(PETSC_ERR_SUP,0,"MAT_NO_NEW_DIAGONALS");
150*2d61bbb3SSatish Balay   } else {
151*2d61bbb3SSatish Balay     SETERRQ(PETSC_ERR_SUP,0,"unknown option");
152*2d61bbb3SSatish Balay   }
153*2d61bbb3SSatish Balay   PetscFunctionReturn(0);
154*2d61bbb3SSatish Balay }
155*2d61bbb3SSatish Balay 
156*2d61bbb3SSatish Balay 
157*2d61bbb3SSatish Balay #undef __FUNC__
158*2d61bbb3SSatish Balay #define __FUNC__ "MatGetSize_SeqBAIJ"
159*2d61bbb3SSatish Balay int MatGetSize_SeqBAIJ(Mat A,int *m,int *n)
160*2d61bbb3SSatish Balay {
161*2d61bbb3SSatish Balay   Mat_SeqBAIJ *a = (Mat_SeqBAIJ *) A->data;
162*2d61bbb3SSatish Balay 
163*2d61bbb3SSatish Balay   PetscFunctionBegin;
164*2d61bbb3SSatish Balay   if (m) *m = a->m;
165*2d61bbb3SSatish Balay   if (n) *n = a->n;
166*2d61bbb3SSatish Balay   PetscFunctionReturn(0);
167*2d61bbb3SSatish Balay }
168*2d61bbb3SSatish Balay 
169*2d61bbb3SSatish Balay #undef __FUNC__
170*2d61bbb3SSatish Balay #define __FUNC__ "MatGetOwnershipRange_SeqBAIJ"
171*2d61bbb3SSatish Balay int MatGetOwnershipRange_SeqBAIJ(Mat A,int *m,int *n)
172*2d61bbb3SSatish Balay {
173*2d61bbb3SSatish Balay   Mat_SeqBAIJ *a = (Mat_SeqBAIJ *) A->data;
174*2d61bbb3SSatish Balay 
175*2d61bbb3SSatish Balay   PetscFunctionBegin;
176*2d61bbb3SSatish Balay   *m = 0; *n = a->m;
177*2d61bbb3SSatish Balay   PetscFunctionReturn(0);
178*2d61bbb3SSatish Balay }
179*2d61bbb3SSatish Balay 
180*2d61bbb3SSatish Balay #undef __FUNC__
181*2d61bbb3SSatish Balay #define __FUNC__ "MatGetRow_SeqBAIJ"
182*2d61bbb3SSatish Balay int MatGetRow_SeqBAIJ(Mat A,int row,int *nz,int **idx,Scalar **v)
183*2d61bbb3SSatish Balay {
184*2d61bbb3SSatish Balay   Mat_SeqBAIJ *a = (Mat_SeqBAIJ *) A->data;
185*2d61bbb3SSatish Balay   int          itmp,i,j,k,M,*ai,*aj,bs,bn,bp,*idx_i,bs2;
186*2d61bbb3SSatish Balay   Scalar      *aa,*v_i,*aa_i;
187*2d61bbb3SSatish Balay 
188*2d61bbb3SSatish Balay   PetscFunctionBegin;
189*2d61bbb3SSatish Balay   bs  = a->bs;
190*2d61bbb3SSatish Balay   ai  = a->i;
191*2d61bbb3SSatish Balay   aj  = a->j;
192*2d61bbb3SSatish Balay   aa  = a->a;
193*2d61bbb3SSatish Balay   bs2 = a->bs2;
194*2d61bbb3SSatish Balay 
195*2d61bbb3SSatish Balay   if (row < 0 || row >= a->m) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Row out of range");
196*2d61bbb3SSatish Balay 
197*2d61bbb3SSatish Balay   bn  = row/bs;   /* Block number */
198*2d61bbb3SSatish Balay   bp  = row % bs; /* Block Position */
199*2d61bbb3SSatish Balay   M   = ai[bn+1] - ai[bn];
200*2d61bbb3SSatish Balay   *nz = bs*M;
201*2d61bbb3SSatish Balay 
202*2d61bbb3SSatish Balay   if (v) {
203*2d61bbb3SSatish Balay     *v = 0;
204*2d61bbb3SSatish Balay     if (*nz) {
205*2d61bbb3SSatish Balay       *v = (Scalar *) PetscMalloc( (*nz)*sizeof(Scalar) ); CHKPTRQ(*v);
206*2d61bbb3SSatish Balay       for ( i=0; i<M; i++ ) { /* for each block in the block row */
207*2d61bbb3SSatish Balay         v_i  = *v + i*bs;
208*2d61bbb3SSatish Balay         aa_i = aa + bs2*(ai[bn] + i);
209*2d61bbb3SSatish Balay         for ( j=bp,k=0; j<bs2; j+=bs,k++ ) {v_i[k] = aa_i[j];}
210*2d61bbb3SSatish Balay       }
211*2d61bbb3SSatish Balay     }
212*2d61bbb3SSatish Balay   }
213*2d61bbb3SSatish Balay 
214*2d61bbb3SSatish Balay   if (idx) {
215*2d61bbb3SSatish Balay     *idx = 0;
216*2d61bbb3SSatish Balay     if (*nz) {
217*2d61bbb3SSatish Balay       *idx = (int *) PetscMalloc( (*nz)*sizeof(int) ); CHKPTRQ(*idx);
218*2d61bbb3SSatish Balay       for ( i=0; i<M; i++ ) { /* for each block in the block row */
219*2d61bbb3SSatish Balay         idx_i = *idx + i*bs;
220*2d61bbb3SSatish Balay         itmp  = bs*aj[ai[bn] + i];
221*2d61bbb3SSatish Balay         for ( j=0; j<bs; j++ ) {idx_i[j] = itmp++;}
222*2d61bbb3SSatish Balay       }
223*2d61bbb3SSatish Balay     }
224*2d61bbb3SSatish Balay   }
225*2d61bbb3SSatish Balay   PetscFunctionReturn(0);
226*2d61bbb3SSatish Balay }
227*2d61bbb3SSatish Balay 
228*2d61bbb3SSatish Balay #undef __FUNC__
229*2d61bbb3SSatish Balay #define __FUNC__ "MatRestoreRow_SeqBAIJ"
230*2d61bbb3SSatish Balay int MatRestoreRow_SeqBAIJ(Mat A,int row,int *nz,int **idx,Scalar **v)
231*2d61bbb3SSatish Balay {
232*2d61bbb3SSatish Balay   PetscFunctionBegin;
233*2d61bbb3SSatish Balay   if (idx) {if (*idx) PetscFree(*idx);}
234*2d61bbb3SSatish Balay   if (v)   {if (*v)   PetscFree(*v);}
235*2d61bbb3SSatish Balay   PetscFunctionReturn(0);
236*2d61bbb3SSatish Balay }
237*2d61bbb3SSatish Balay 
238*2d61bbb3SSatish Balay #undef __FUNC__
239*2d61bbb3SSatish Balay #define __FUNC__ "MatTranspose_SeqBAIJ"
240*2d61bbb3SSatish Balay int MatTranspose_SeqBAIJ(Mat A,Mat *B)
241*2d61bbb3SSatish Balay {
242*2d61bbb3SSatish Balay   Mat_SeqBAIJ *a=(Mat_SeqBAIJ *)A->data;
243*2d61bbb3SSatish Balay   Mat         C;
244*2d61bbb3SSatish Balay   int         i,j,k,ierr,*aj=a->j,*ai=a->i,bs=a->bs,mbs=a->mbs,nbs=a->nbs,len,*col;
245*2d61bbb3SSatish Balay   int         *rows,*cols,bs2=a->bs2;
246*2d61bbb3SSatish Balay   Scalar      *array=a->a;
247*2d61bbb3SSatish Balay 
248*2d61bbb3SSatish Balay   PetscFunctionBegin;
249*2d61bbb3SSatish Balay   if (B==PETSC_NULL && mbs!=nbs) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Square matrix only for in-place");
250*2d61bbb3SSatish Balay   col = (int *) PetscMalloc((1+nbs)*sizeof(int)); CHKPTRQ(col);
251*2d61bbb3SSatish Balay   PetscMemzero(col,(1+nbs)*sizeof(int));
252*2d61bbb3SSatish Balay 
253*2d61bbb3SSatish Balay   for ( i=0; i<ai[mbs]; i++ ) col[aj[i]] += 1;
254*2d61bbb3SSatish Balay   ierr = MatCreateSeqBAIJ(A->comm,bs,a->n,a->m,PETSC_NULL,col,&C); CHKERRQ(ierr);
255*2d61bbb3SSatish Balay   PetscFree(col);
256*2d61bbb3SSatish Balay   rows = (int *) PetscMalloc(2*bs*sizeof(int)); CHKPTRQ(rows);
257*2d61bbb3SSatish Balay   cols = rows + bs;
258*2d61bbb3SSatish Balay   for ( i=0; i<mbs; i++ ) {
259*2d61bbb3SSatish Balay     cols[0] = i*bs;
260*2d61bbb3SSatish Balay     for (k=1; k<bs; k++ ) cols[k] = cols[k-1] + 1;
261*2d61bbb3SSatish Balay     len = ai[i+1] - ai[i];
262*2d61bbb3SSatish Balay     for ( j=0; j<len; j++ ) {
263*2d61bbb3SSatish Balay       rows[0] = (*aj++)*bs;
264*2d61bbb3SSatish Balay       for (k=1; k<bs; k++ ) rows[k] = rows[k-1] + 1;
265*2d61bbb3SSatish Balay       ierr = MatSetValues(C,bs,rows,bs,cols,array,INSERT_VALUES); CHKERRQ(ierr);
266*2d61bbb3SSatish Balay       array += bs2;
267*2d61bbb3SSatish Balay     }
268*2d61bbb3SSatish Balay   }
269*2d61bbb3SSatish Balay   PetscFree(rows);
270*2d61bbb3SSatish Balay 
271*2d61bbb3SSatish Balay   ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY); CHKERRQ(ierr);
272*2d61bbb3SSatish Balay   ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY); CHKERRQ(ierr);
273*2d61bbb3SSatish Balay 
274*2d61bbb3SSatish Balay   if (B != PETSC_NULL) {
275*2d61bbb3SSatish Balay     *B = C;
276*2d61bbb3SSatish Balay   } else {
277*2d61bbb3SSatish Balay     /* This isn't really an in-place transpose */
278*2d61bbb3SSatish Balay     PetscFree(a->a);
279*2d61bbb3SSatish Balay     if (!a->singlemalloc) {PetscFree(a->i); PetscFree(a->j);}
280*2d61bbb3SSatish Balay     if (a->diag) PetscFree(a->diag);
281*2d61bbb3SSatish Balay     if (a->ilen) PetscFree(a->ilen);
282*2d61bbb3SSatish Balay     if (a->imax) PetscFree(a->imax);
283*2d61bbb3SSatish Balay     if (a->solve_work) PetscFree(a->solve_work);
284*2d61bbb3SSatish Balay     PetscFree(a);
285*2d61bbb3SSatish Balay     PetscMemcpy(A,C,sizeof(struct _p_Mat));
286*2d61bbb3SSatish Balay     PetscHeaderDestroy(C);
287*2d61bbb3SSatish Balay   }
288*2d61bbb3SSatish Balay   PetscFunctionReturn(0);
289*2d61bbb3SSatish Balay }
290*2d61bbb3SSatish Balay 
291*2d61bbb3SSatish Balay 
292*2d61bbb3SSatish Balay 
2933b2fbd54SBarry Smith 
2945615d1e5SSatish Balay #undef __FUNC__
295d4bb536fSBarry Smith #define __FUNC__ "MatView_SeqBAIJ_Binary"
296b6490206SBarry Smith static int MatView_SeqBAIJ_Binary(Mat A,Viewer viewer)
2972593348eSBarry Smith {
298b6490206SBarry Smith   Mat_SeqBAIJ *a = (Mat_SeqBAIJ *) A->data;
2999df24120SSatish Balay   int         i, fd, *col_lens, ierr, bs = a->bs,count,*jj,j,k,l,bs2=a->bs2;
300b6490206SBarry Smith   Scalar      *aa;
3012593348eSBarry Smith 
3023a40ed3dSBarry Smith   PetscFunctionBegin;
30390ace30eSBarry Smith   ierr = ViewerBinaryGetDescriptor(viewer,&fd); CHKERRQ(ierr);
3042593348eSBarry Smith   col_lens = (int *) PetscMalloc((4+a->m)*sizeof(int));CHKPTRQ(col_lens);
3052593348eSBarry Smith   col_lens[0] = MAT_COOKIE;
3063b2fbd54SBarry Smith 
3072593348eSBarry Smith   col_lens[1] = a->m;
3082593348eSBarry Smith   col_lens[2] = a->n;
3097e67e3f9SSatish Balay   col_lens[3] = a->nz*bs2;
3102593348eSBarry Smith 
3112593348eSBarry Smith   /* store lengths of each row and write (including header) to file */
312b6490206SBarry Smith   count = 0;
313b6490206SBarry Smith   for ( i=0; i<a->mbs; i++ ) {
314b6490206SBarry Smith     for ( j=0; j<bs; j++ ) {
315b6490206SBarry Smith       col_lens[4+count++] = bs*(a->i[i+1] - a->i[i]);
316b6490206SBarry Smith     }
3172593348eSBarry Smith   }
3180752156aSBarry Smith   ierr = PetscBinaryWrite(fd,col_lens,4+a->m,PETSC_INT,1); CHKERRQ(ierr);
3192593348eSBarry Smith   PetscFree(col_lens);
3202593348eSBarry Smith 
3212593348eSBarry Smith   /* store column indices (zero start index) */
32266963ce1SSatish Balay   jj = (int *) PetscMalloc( (a->nz+1)*bs2*sizeof(int) ); CHKPTRQ(jj);
323b6490206SBarry Smith   count = 0;
324b6490206SBarry Smith   for ( i=0; i<a->mbs; i++ ) {
325b6490206SBarry Smith     for ( j=0; j<bs; j++ ) {
326b6490206SBarry Smith       for ( k=a->i[i]; k<a->i[i+1]; k++ ) {
327b6490206SBarry Smith         for ( l=0; l<bs; l++ ) {
328b6490206SBarry Smith           jj[count++] = bs*a->j[k] + l;
3292593348eSBarry Smith         }
3302593348eSBarry Smith       }
331b6490206SBarry Smith     }
332b6490206SBarry Smith   }
3330752156aSBarry Smith   ierr = PetscBinaryWrite(fd,jj,bs2*a->nz,PETSC_INT,0); CHKERRQ(ierr);
334b6490206SBarry Smith   PetscFree(jj);
3352593348eSBarry Smith 
3362593348eSBarry Smith   /* store nonzero values */
33766963ce1SSatish Balay   aa = (Scalar *) PetscMalloc((a->nz+1)*bs2*sizeof(Scalar)); CHKPTRQ(aa);
338b6490206SBarry Smith   count = 0;
339b6490206SBarry Smith   for ( i=0; i<a->mbs; i++ ) {
340b6490206SBarry Smith     for ( j=0; j<bs; j++ ) {
341b6490206SBarry Smith       for ( k=a->i[i]; k<a->i[i+1]; k++ ) {
342b6490206SBarry Smith         for ( l=0; l<bs; l++ ) {
3437e67e3f9SSatish Balay           aa[count++] = a->a[bs2*k + l*bs + j];
344b6490206SBarry Smith         }
345b6490206SBarry Smith       }
346b6490206SBarry Smith     }
347b6490206SBarry Smith   }
3480752156aSBarry Smith   ierr = PetscBinaryWrite(fd,aa,bs2*a->nz,PETSC_SCALAR,0); CHKERRQ(ierr);
349b6490206SBarry Smith   PetscFree(aa);
3503a40ed3dSBarry Smith   PetscFunctionReturn(0);
3512593348eSBarry Smith }
3522593348eSBarry Smith 
3535615d1e5SSatish Balay #undef __FUNC__
354d4bb536fSBarry Smith #define __FUNC__ "MatView_SeqBAIJ_ASCII"
355b6490206SBarry Smith static int MatView_SeqBAIJ_ASCII(Mat A,Viewer viewer)
3562593348eSBarry Smith {
357b6490206SBarry Smith   Mat_SeqBAIJ *a = (Mat_SeqBAIJ *) A->data;
3589df24120SSatish Balay   int         ierr, i,j,format,bs = a->bs,k,l,bs2=a->bs2;
3592593348eSBarry Smith   FILE        *fd;
3602593348eSBarry Smith   char        *outputname;
3612593348eSBarry Smith 
3623a40ed3dSBarry Smith   PetscFunctionBegin;
36390ace30eSBarry Smith   ierr = ViewerASCIIGetPointer(viewer,&fd); CHKERRQ(ierr);
3642593348eSBarry Smith   ierr = ViewerFileGetOutputname_Private(viewer,&outputname);CHKERRQ(ierr);
36590ace30eSBarry Smith   ierr = ViewerGetFormat(viewer,&format);
366639f9d9dSBarry Smith   if (format == VIEWER_FORMAT_ASCII_INFO || format == VIEWER_FORMAT_ASCII_INFO_LONG) {
3677ddc982cSLois Curfman McInnes     fprintf(fd,"  block size is %d\n",bs);
3682593348eSBarry Smith   }
369639f9d9dSBarry Smith   else if (format == VIEWER_FORMAT_ASCII_MATLAB) {
370a8c6a408SBarry Smith     SETERRQ(PETSC_ERR_SUP,0,"Matlab format not supported");
3712593348eSBarry Smith   }
372639f9d9dSBarry Smith   else if (format == VIEWER_FORMAT_ASCII_COMMON) {
37344cd7ae7SLois Curfman McInnes     for ( i=0; i<a->mbs; i++ ) {
37444cd7ae7SLois Curfman McInnes       for ( j=0; j<bs; j++ ) {
37544cd7ae7SLois Curfman McInnes         fprintf(fd,"row %d:",i*bs+j);
37644cd7ae7SLois Curfman McInnes         for ( k=a->i[i]; k<a->i[i+1]; k++ ) {
37744cd7ae7SLois Curfman McInnes           for ( l=0; l<bs; l++ ) {
3783a40ed3dSBarry Smith #if defined(USE_PETSC_COMPLEX)
379766eeae4SLois Curfman McInnes           if (imag(a->a[bs2*k + l*bs + j]) > 0.0 && real(a->a[bs2*k + l*bs + j]) != 0.0)
38044cd7ae7SLois Curfman McInnes             fprintf(fd," %d %g + %g i",bs*a->j[k]+l,
38144cd7ae7SLois Curfman McInnes               real(a->a[bs2*k + l*bs + j]),imag(a->a[bs2*k + l*bs + j]));
382766eeae4SLois Curfman McInnes           else if (imag(a->a[bs2*k + l*bs + j]) < 0.0 && real(a->a[bs2*k + l*bs + j]) != 0.0)
383766eeae4SLois Curfman McInnes             fprintf(fd," %d %g - %g i",bs*a->j[k]+l,
384766eeae4SLois Curfman McInnes               real(a->a[bs2*k + l*bs + j]),-imag(a->a[bs2*k + l*bs + j]));
38544cd7ae7SLois Curfman McInnes           else if (real(a->a[bs2*k + l*bs + j]) != 0.0)
38644cd7ae7SLois Curfman McInnes             fprintf(fd," %d %g ",bs*a->j[k]+l,real(a->a[bs2*k + l*bs + j]));
38744cd7ae7SLois Curfman McInnes #else
38844cd7ae7SLois Curfman McInnes           if (a->a[bs2*k + l*bs + j] != 0.0)
38944cd7ae7SLois Curfman McInnes             fprintf(fd," %d %g ",bs*a->j[k]+l,a->a[bs2*k + l*bs + j]);
39044cd7ae7SLois Curfman McInnes #endif
39144cd7ae7SLois Curfman McInnes           }
39244cd7ae7SLois Curfman McInnes         }
39344cd7ae7SLois Curfman McInnes         fprintf(fd,"\n");
39444cd7ae7SLois Curfman McInnes       }
39544cd7ae7SLois Curfman McInnes     }
39644cd7ae7SLois Curfman McInnes   }
3972593348eSBarry Smith   else {
398b6490206SBarry Smith     for ( i=0; i<a->mbs; i++ ) {
399b6490206SBarry Smith       for ( j=0; j<bs; j++ ) {
400b6490206SBarry Smith         fprintf(fd,"row %d:",i*bs+j);
401b6490206SBarry Smith         for ( k=a->i[i]; k<a->i[i+1]; k++ ) {
402b6490206SBarry Smith           for ( l=0; l<bs; l++ ) {
4033a40ed3dSBarry Smith #if defined(USE_PETSC_COMPLEX)
404766eeae4SLois Curfman McInnes           if (imag(a->a[bs2*k + l*bs + j]) > 0.0) {
40588685aaeSLois Curfman McInnes             fprintf(fd," %d %g + %g i",bs*a->j[k]+l,
4067e67e3f9SSatish Balay               real(a->a[bs2*k + l*bs + j]),imag(a->a[bs2*k + l*bs + j]));
40788685aaeSLois Curfman McInnes           }
408766eeae4SLois Curfman McInnes           else if (imag(a->a[bs2*k + l*bs + j]) < 0.0) {
409766eeae4SLois Curfman McInnes             fprintf(fd," %d %g - %g i",bs*a->j[k]+l,
410766eeae4SLois Curfman McInnes               real(a->a[bs2*k + l*bs + j]),-imag(a->a[bs2*k + l*bs + j]));
411766eeae4SLois Curfman McInnes           }
41288685aaeSLois Curfman McInnes           else {
4137e67e3f9SSatish Balay             fprintf(fd," %d %g ",bs*a->j[k]+l,real(a->a[bs2*k + l*bs + j]));
41488685aaeSLois Curfman McInnes           }
41588685aaeSLois Curfman McInnes #else
4167e67e3f9SSatish Balay             fprintf(fd," %d %g ",bs*a->j[k]+l,a->a[bs2*k + l*bs + j]);
41788685aaeSLois Curfman McInnes #endif
4182593348eSBarry Smith           }
4192593348eSBarry Smith         }
4202593348eSBarry Smith         fprintf(fd,"\n");
4212593348eSBarry Smith       }
4222593348eSBarry Smith     }
423b6490206SBarry Smith   }
4242593348eSBarry Smith   fflush(fd);
4253a40ed3dSBarry Smith   PetscFunctionReturn(0);
4262593348eSBarry Smith }
4272593348eSBarry Smith 
4285615d1e5SSatish Balay #undef __FUNC__
429d4bb536fSBarry Smith #define __FUNC__ "MatView_SeqBAIJ_Draw"
4303270192aSSatish Balay static int MatView_SeqBAIJ_Draw(Mat A,Viewer viewer)
4313270192aSSatish Balay {
4323270192aSSatish Balay   Mat_SeqBAIJ  *a=(Mat_SeqBAIJ *) A->data;
4333270192aSSatish Balay   int          row,ierr,i,j,k,l,mbs=a->mbs,pause,color,bs=a->bs,bs2=a->bs2;
4343270192aSSatish Balay   double       xl,yl,xr,yr,w,h,xc,yc,scale = 1.0,x_l,x_r,y_l,y_r;
4353270192aSSatish Balay   Scalar       *aa;
4363270192aSSatish Balay   Draw         draw;
4373270192aSSatish Balay   DrawButton   button;
4383270192aSSatish Balay   PetscTruth   isnull;
4393270192aSSatish Balay 
4403a40ed3dSBarry Smith   PetscFunctionBegin;
4413a40ed3dSBarry Smith   ierr = ViewerDrawGetDraw(viewer,&draw);CHKERRQ(ierr);
4423a40ed3dSBarry Smith   ierr = DrawIsNull(draw,&isnull); CHKERRQ(ierr); if (isnull) PetscFunctionReturn(0);
4433270192aSSatish Balay 
4443270192aSSatish Balay   xr  = a->n; yr = a->m; h = yr/10.0; w = xr/10.0;
4453270192aSSatish Balay   xr += w;    yr += h;  xl = -w;     yl = -h;
4463270192aSSatish Balay   ierr = DrawSetCoordinates(draw,xl,yl,xr,yr); CHKERRQ(ierr);
4473270192aSSatish Balay   /* loop over matrix elements drawing boxes */
4483270192aSSatish Balay   color = DRAW_BLUE;
4493270192aSSatish Balay   for ( i=0,row=0; i<mbs; i++,row+=bs ) {
4503270192aSSatish Balay     for ( j=a->i[i]; j<a->i[i+1]; j++ ) {
4513270192aSSatish Balay       y_l = a->m - row - 1.0; y_r = y_l + 1.0;
4523270192aSSatish Balay       x_l = a->j[j]*bs; x_r = x_l + 1.0;
4533270192aSSatish Balay       aa = a->a + j*bs2;
4543270192aSSatish Balay       for ( k=0; k<bs; k++ ) {
4553270192aSSatish Balay         for ( l=0; l<bs; l++ ) {
4563270192aSSatish Balay           if (PetscReal(*aa++) >=  0.) continue;
457b34f160eSSatish Balay           DrawRectangle(draw,x_l+k,y_l-l,x_r+k,y_r-l,color,color,color,color);
4583270192aSSatish Balay         }
4593270192aSSatish Balay       }
4603270192aSSatish Balay     }
4613270192aSSatish Balay   }
4623270192aSSatish Balay   color = DRAW_CYAN;
4633270192aSSatish Balay   for ( i=0,row=0; i<mbs; i++,row+=bs ) {
4643270192aSSatish Balay     for ( j=a->i[i]; j<a->i[i+1]; j++ ) {
4653270192aSSatish Balay       y_l = a->m - row - 1.0; y_r = y_l + 1.0;
4663270192aSSatish Balay       x_l = a->j[j]*bs; x_r = x_l + 1.0;
4673270192aSSatish Balay       aa = a->a + j*bs2;
4683270192aSSatish Balay       for ( k=0; k<bs; k++ ) {
4693270192aSSatish Balay         for ( l=0; l<bs; l++ ) {
4703270192aSSatish Balay           if (PetscReal(*aa++) != 0.) continue;
471b34f160eSSatish Balay           DrawRectangle(draw,x_l+k,y_l-l,x_r+k,y_r-l,color,color,color,color);
4723270192aSSatish Balay         }
4733270192aSSatish Balay       }
4743270192aSSatish Balay     }
4753270192aSSatish Balay   }
4763270192aSSatish Balay 
4773270192aSSatish Balay   color = DRAW_RED;
4783270192aSSatish Balay   for ( i=0,row=0; i<mbs; i++,row+=bs ) {
4793270192aSSatish Balay     for ( j=a->i[i]; j<a->i[i+1]; j++ ) {
4803270192aSSatish Balay       y_l = a->m - row - 1.0; y_r = y_l + 1.0;
4813270192aSSatish Balay       x_l = a->j[j]*bs; x_r = x_l + 1.0;
4823270192aSSatish Balay       aa = a->a + j*bs2;
4833270192aSSatish Balay       for ( k=0; k<bs; k++ ) {
4843270192aSSatish Balay         for ( l=0; l<bs; l++ ) {
4853270192aSSatish Balay           if (PetscReal(*aa++) <= 0.) continue;
486b34f160eSSatish Balay           DrawRectangle(draw,x_l+k,y_l-l,x_r+k,y_r-l,color,color,color,color);
4873270192aSSatish Balay         }
4883270192aSSatish Balay       }
4893270192aSSatish Balay     }
4903270192aSSatish Balay   }
4913270192aSSatish Balay 
49255843e3eSBarry Smith   DrawSynchronizedFlush(draw);
4933270192aSSatish Balay   DrawGetPause(draw,&pause);
4943a40ed3dSBarry Smith   if (pause >= 0) { PetscSleep(pause); PetscFunctionReturn(0);}
4953270192aSSatish Balay 
4963270192aSSatish Balay   /* allow the matrix to zoom or shrink */
49755843e3eSBarry Smith   ierr = DrawSynchronizedGetMouseButton(draw,&button,&xc,&yc,0,0);
4983270192aSSatish Balay   while (button != BUTTON_RIGHT) {
49955843e3eSBarry Smith     DrawSynchronizedClear(draw);
5003270192aSSatish Balay     if (button == BUTTON_LEFT) scale = .5;
5013270192aSSatish Balay     else if (button == BUTTON_CENTER) scale = 2.;
5023270192aSSatish Balay     xl = scale*(xl + w - xc) + xc - w*scale;
5033270192aSSatish Balay     xr = scale*(xr - w - xc) + xc + w*scale;
5043270192aSSatish Balay     yl = scale*(yl + h - yc) + yc - h*scale;
5053270192aSSatish Balay     yr = scale*(yr - h - yc) + yc + h*scale;
5063270192aSSatish Balay     w *= scale; h *= scale;
5073270192aSSatish Balay     ierr = DrawSetCoordinates(draw,xl,yl,xr,yr); CHKERRQ(ierr);
5083270192aSSatish Balay     color = DRAW_BLUE;
5093270192aSSatish Balay     for ( i=0,row=0; i<mbs; i++,row+=bs ) {
5103270192aSSatish Balay       for ( j=a->i[i]; j<a->i[i+1]; j++ ) {
5113270192aSSatish Balay         y_l = a->m - row - 1.0; y_r = y_l + 1.0;
5123270192aSSatish Balay         x_l = a->j[j]*bs; x_r = x_l + 1.0;
5133270192aSSatish Balay         aa = a->a + j*bs2;
5143270192aSSatish Balay         for ( k=0; k<bs; k++ ) {
5153270192aSSatish Balay           for ( l=0; l<bs; l++ ) {
5163270192aSSatish Balay             if (PetscReal(*aa++) >=  0.) continue;
517b34f160eSSatish Balay             DrawRectangle(draw,x_l+k,y_l-l,x_r+k,y_r-l,color,color,color,color);
5183270192aSSatish Balay           }
5193270192aSSatish Balay         }
5203270192aSSatish Balay       }
5213270192aSSatish Balay     }
5223270192aSSatish Balay     color = DRAW_CYAN;
5233270192aSSatish Balay     for ( i=0,row=0; i<mbs; i++,row+=bs ) {
5243270192aSSatish Balay       for ( j=a->i[i]; j<a->i[i+1]; j++ ) {
5253270192aSSatish Balay         y_l = a->m - row - 1.0; y_r = y_l + 1.0;
5263270192aSSatish Balay         x_l = a->j[j]*bs; x_r = x_l + 1.0;
5273270192aSSatish Balay         aa = a->a + j*bs2;
5283270192aSSatish Balay         for ( k=0; k<bs; k++ ) {
5293270192aSSatish Balay           for ( l=0; l<bs; l++ ) {
5303270192aSSatish Balay           if (PetscReal(*aa++) != 0.) continue;
531b34f160eSSatish Balay           DrawRectangle(draw,x_l+k,y_l-l,x_r+k,y_r-l,color,color,color,color);
5323270192aSSatish Balay           }
5333270192aSSatish Balay         }
5343270192aSSatish Balay       }
5353270192aSSatish Balay     }
5363270192aSSatish Balay 
5373270192aSSatish Balay     color = DRAW_RED;
5383270192aSSatish Balay     for ( i=0,row=0; i<mbs; i++,row+=bs ) {
5393270192aSSatish Balay       for ( j=a->i[i]; j<a->i[i+1]; j++ ) {
5403270192aSSatish Balay         y_l = a->m - row - 1.0; y_r = y_l + 1.0;
5413270192aSSatish Balay         x_l = a->j[j]*bs; x_r = x_l + 1.0;
5423270192aSSatish Balay         aa = a->a + j*bs2;
5433270192aSSatish Balay         for ( k=0; k<bs; k++ ) {
5443270192aSSatish Balay           for ( l=0; l<bs; l++ ) {
5453270192aSSatish Balay             if (PetscReal(*aa++) <= 0.) continue;
546b34f160eSSatish Balay             DrawRectangle(draw,x_l+k,y_l-l,x_r+k,y_r-l,color,color,color,color);
5473270192aSSatish Balay           }
5483270192aSSatish Balay         }
5493270192aSSatish Balay       }
5503270192aSSatish Balay     }
55155843e3eSBarry Smith     ierr = DrawSynchronizedGetMouseButton(draw,&button,&xc,&yc,0,0);
5523270192aSSatish Balay   }
5533a40ed3dSBarry Smith   PetscFunctionReturn(0);
5543270192aSSatish Balay }
5553270192aSSatish Balay 
5565615d1e5SSatish Balay #undef __FUNC__
557d4bb536fSBarry Smith #define __FUNC__ "MatView_SeqBAIJ"
5588f6be9afSLois Curfman McInnes int MatView_SeqBAIJ(PetscObject obj,Viewer viewer)
5592593348eSBarry Smith {
5602593348eSBarry Smith   Mat         A = (Mat) obj;
56119bcc07fSBarry Smith   ViewerType  vtype;
56219bcc07fSBarry Smith   int         ierr;
5632593348eSBarry Smith 
5643a40ed3dSBarry Smith   PetscFunctionBegin;
56519bcc07fSBarry Smith   ierr = ViewerGetType(viewer,&vtype); CHKERRQ(ierr);
56619bcc07fSBarry Smith   if (vtype == MATLAB_VIEWER) {
567a8c6a408SBarry Smith     SETERRQ(PETSC_ERR_SUP,0,"Matlab viewer not supported");
5683a40ed3dSBarry Smith   } else if (vtype == ASCII_FILE_VIEWER || vtype == ASCII_FILES_VIEWER){
5693a40ed3dSBarry Smith     ierr = MatView_SeqBAIJ_ASCII(A,viewer);CHKERRQ(ierr);
5703a40ed3dSBarry Smith   } else if (vtype == BINARY_FILE_VIEWER) {
5713a40ed3dSBarry Smith     ierr = MatView_SeqBAIJ_Binary(A,viewer);CHKERRQ(ierr);
5723a40ed3dSBarry Smith   } else if (vtype == DRAW_VIEWER) {
5733a40ed3dSBarry Smith     ierr = MatView_SeqBAIJ_Draw(A,viewer);CHKERRQ(ierr);
5742593348eSBarry Smith   }
5753a40ed3dSBarry Smith   PetscFunctionReturn(0);
5762593348eSBarry Smith }
577b6490206SBarry Smith 
578cd0e1443SSatish Balay 
5795615d1e5SSatish Balay #undef __FUNC__
580*2d61bbb3SSatish Balay #define __FUNC__ "MatGetValues_SeqBAIJ"
581*2d61bbb3SSatish Balay int MatGetValues_SeqBAIJ(Mat A,int m,int *im,int n,int *in,Scalar *v)
582cd0e1443SSatish Balay {
583cd0e1443SSatish Balay   Mat_SeqBAIJ *a = (Mat_SeqBAIJ *) A->data;
584*2d61bbb3SSatish Balay   int        *rp, k, low, high, t, row, nrow, i, col, l, *aj = a->j;
585*2d61bbb3SSatish Balay   int        *ai = a->i, *ailen = a->ilen;
586*2d61bbb3SSatish Balay   int        brow,bcol,ridx,cidx,bs=a->bs,bs2=a->bs2;
587*2d61bbb3SSatish Balay   Scalar     *ap, *aa = a->a, zero = 0.0;
588cd0e1443SSatish Balay 
5893a40ed3dSBarry Smith   PetscFunctionBegin;
590*2d61bbb3SSatish Balay   for ( k=0; k<m; k++ ) { /* loop over rows */
591cd0e1443SSatish Balay     row  = im[k]; brow = row/bs;
592a8c6a408SBarry Smith     if (row < 0) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Negative row");
593a8c6a408SBarry Smith     if (row >= a->m) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Row too large");
594*2d61bbb3SSatish Balay     rp   = aj + ai[brow] ; ap = aa + bs2*ai[brow] ;
5952c3acbe9SBarry Smith     nrow = ailen[brow];
596*2d61bbb3SSatish Balay     for ( l=0; l<n; l++ ) { /* loop over columns */
597a8c6a408SBarry Smith       if (in[l] < 0) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Negative column");
598a8c6a408SBarry Smith       if (in[l] >= a->n) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Column too large");
599*2d61bbb3SSatish Balay       col  = in[l] ;
600*2d61bbb3SSatish Balay       bcol = col/bs;
601*2d61bbb3SSatish Balay       cidx = col%bs;
602*2d61bbb3SSatish Balay       ridx = row%bs;
603*2d61bbb3SSatish Balay       high = nrow;
604*2d61bbb3SSatish Balay       low  = 0; /* assume unsorted */
605*2d61bbb3SSatish Balay       while (high-low > 5) {
606cd0e1443SSatish Balay         t = (low+high)/2;
607cd0e1443SSatish Balay         if (rp[t] > bcol) high = t;
608cd0e1443SSatish Balay         else             low  = t;
609cd0e1443SSatish Balay       }
610cd0e1443SSatish Balay       for ( i=low; i<high; i++ ) {
611cd0e1443SSatish Balay         if (rp[i] > bcol) break;
612cd0e1443SSatish Balay         if (rp[i] == bcol) {
613*2d61bbb3SSatish Balay           *v++ = ap[bs2*i+bs*cidx+ridx];
614*2d61bbb3SSatish Balay           goto finished;
615cd0e1443SSatish Balay         }
616cd0e1443SSatish Balay       }
617*2d61bbb3SSatish Balay       *v++ = zero;
618*2d61bbb3SSatish Balay       finished:;
619cd0e1443SSatish Balay     }
620cd0e1443SSatish Balay   }
6213a40ed3dSBarry Smith   PetscFunctionReturn(0);
622cd0e1443SSatish Balay }
623cd0e1443SSatish Balay 
624*2d61bbb3SSatish Balay 
6255615d1e5SSatish Balay #undef __FUNC__
62605a5f48eSSatish Balay #define __FUNC__ "MatSetValuesBlocked_SeqBAIJ"
62792c4ed94SBarry Smith int MatSetValuesBlocked_SeqBAIJ(Mat A,int m,int *im,int n,int *in,Scalar *v,InsertMode is)
62892c4ed94SBarry Smith {
62992c4ed94SBarry Smith   Mat_SeqBAIJ *a = (Mat_SeqBAIJ *) A->data;
6308a84c255SSatish Balay   int         *rp,k,low,high,t,ii,jj,row,nrow,i,col,l,rmax,N,sorted=a->sorted;
631dd9472c6SBarry Smith   int         *imax=a->imax,*ai=a->i,*ailen=a->ilen, roworiented=a->roworiented;
632dd9472c6SBarry Smith   int         *aj=a->j,nonew=a->nonew,bs2=a->bs2,bs=a->bs,stepval;
6330e324ae4SSatish Balay   Scalar      *ap,*value=v,*aa=a->a,*bap;
63492c4ed94SBarry Smith 
6353a40ed3dSBarry Smith   PetscFunctionBegin;
6360e324ae4SSatish Balay   if (roworiented) {
6370e324ae4SSatish Balay     stepval = (n-1)*bs;
6380e324ae4SSatish Balay   } else {
6390e324ae4SSatish Balay     stepval = (m-1)*bs;
6400e324ae4SSatish Balay   }
64192c4ed94SBarry Smith   for ( k=0; k<m; k++ ) { /* loop over added rows */
64292c4ed94SBarry Smith     row  = im[k];
6433a40ed3dSBarry Smith #if defined(USE_PETSC_BOPT_g)
644a8c6a408SBarry Smith     if (row < 0) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Negative row");
645a8c6a408SBarry Smith     if (row >= a->mbs) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Row too large");
64692c4ed94SBarry Smith #endif
64792c4ed94SBarry Smith     rp   = aj + ai[row];
64892c4ed94SBarry Smith     ap   = aa + bs2*ai[row];
64992c4ed94SBarry Smith     rmax = imax[row];
65092c4ed94SBarry Smith     nrow = ailen[row];
65192c4ed94SBarry Smith     low  = 0;
65292c4ed94SBarry Smith     for ( l=0; l<n; l++ ) { /* loop over added columns */
6533a40ed3dSBarry Smith #if defined(USE_PETSC_BOPT_g)
654a8c6a408SBarry Smith       if (in[l] < 0) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Negative column");
655a8c6a408SBarry Smith       if (in[l] >= a->nbs) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Column too large");
65692c4ed94SBarry Smith #endif
65792c4ed94SBarry Smith       col = in[l];
65892c4ed94SBarry Smith       if (roworiented) {
6590e324ae4SSatish Balay         value = v + k*(stepval+bs)*bs + l*bs;
6600e324ae4SSatish Balay       } else {
6610e324ae4SSatish Balay         value = v + l*(stepval+bs)*bs + k*bs;
66292c4ed94SBarry Smith       }
66392c4ed94SBarry Smith       if (!sorted) low = 0; high = nrow;
66492c4ed94SBarry Smith       while (high-low > 7) {
66592c4ed94SBarry Smith         t = (low+high)/2;
66692c4ed94SBarry Smith         if (rp[t] > col) high = t;
66792c4ed94SBarry Smith         else             low  = t;
66892c4ed94SBarry Smith       }
66992c4ed94SBarry Smith       for ( i=low; i<high; i++ ) {
67092c4ed94SBarry Smith         if (rp[i] > col) break;
67192c4ed94SBarry Smith         if (rp[i] == col) {
6728a84c255SSatish Balay           bap  = ap +  bs2*i;
6730e324ae4SSatish Balay           if (roworiented) {
6748a84c255SSatish Balay             if (is == ADD_VALUES) {
675dd9472c6SBarry Smith               for ( ii=0; ii<bs; ii++,value+=stepval ) {
676dd9472c6SBarry Smith                 for (jj=ii; jj<bs2; jj+=bs ) {
6778a84c255SSatish Balay                   bap[jj] += *value++;
678dd9472c6SBarry Smith                 }
679dd9472c6SBarry Smith               }
6800e324ae4SSatish Balay             } else {
681dd9472c6SBarry Smith               for ( ii=0; ii<bs; ii++,value+=stepval ) {
682dd9472c6SBarry Smith                 for (jj=ii; jj<bs2; jj+=bs ) {
6830e324ae4SSatish Balay                   bap[jj] = *value++;
6848a84c255SSatish Balay                 }
685dd9472c6SBarry Smith               }
686dd9472c6SBarry Smith             }
6870e324ae4SSatish Balay           } else {
6880e324ae4SSatish Balay             if (is == ADD_VALUES) {
689dd9472c6SBarry Smith               for ( ii=0; ii<bs; ii++,value+=stepval ) {
690dd9472c6SBarry Smith                 for (jj=0; jj<bs; jj++ ) {
6910e324ae4SSatish Balay                   *bap++ += *value++;
692dd9472c6SBarry Smith                 }
693dd9472c6SBarry Smith               }
6940e324ae4SSatish Balay             } else {
695dd9472c6SBarry Smith               for ( ii=0; ii<bs; ii++,value+=stepval ) {
696dd9472c6SBarry Smith                 for (jj=0; jj<bs; jj++ ) {
6970e324ae4SSatish Balay                   *bap++  = *value++;
6980e324ae4SSatish Balay                 }
6998a84c255SSatish Balay               }
700dd9472c6SBarry Smith             }
701dd9472c6SBarry Smith           }
702f1241b54SBarry Smith           goto noinsert2;
70392c4ed94SBarry Smith         }
70492c4ed94SBarry Smith       }
70589280ab3SLois Curfman McInnes       if (nonew == 1) goto noinsert2;
706a8c6a408SBarry Smith       else if (nonew == -1) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Inserting a new nonzero in the matrix");
70792c4ed94SBarry Smith       if (nrow >= rmax) {
70892c4ed94SBarry Smith         /* there is no extra room in row, therefore enlarge */
70992c4ed94SBarry Smith         int    new_nz = ai[a->mbs] + CHUNKSIZE,len,*new_i,*new_j;
71092c4ed94SBarry Smith         Scalar *new_a;
71192c4ed94SBarry Smith 
712a8c6a408SBarry Smith         if (nonew == -2) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Inserting a new nonzero in the matrix");
71389280ab3SLois Curfman McInnes 
71492c4ed94SBarry Smith         /* malloc new storage space */
71592c4ed94SBarry Smith         len     = new_nz*(sizeof(int)+bs2*sizeof(Scalar))+(a->mbs+1)*sizeof(int);
71692c4ed94SBarry Smith         new_a   = (Scalar *) PetscMalloc( len ); CHKPTRQ(new_a);
71792c4ed94SBarry Smith         new_j   = (int *) (new_a + bs2*new_nz);
71892c4ed94SBarry Smith         new_i   = new_j + new_nz;
71992c4ed94SBarry Smith 
72092c4ed94SBarry Smith         /* copy over old data into new slots */
72192c4ed94SBarry Smith         for ( ii=0; ii<row+1; ii++ ) {new_i[ii] = ai[ii];}
72292c4ed94SBarry Smith         for ( ii=row+1; ii<a->mbs+1; ii++ ) {new_i[ii] = ai[ii]+CHUNKSIZE;}
72392c4ed94SBarry Smith         PetscMemcpy(new_j,aj,(ai[row]+nrow)*sizeof(int));
72492c4ed94SBarry Smith         len = (new_nz - CHUNKSIZE - ai[row] - nrow);
725dd9472c6SBarry Smith         PetscMemcpy(new_j+ai[row]+nrow+CHUNKSIZE,aj+ai[row]+nrow,len*sizeof(int));
72692c4ed94SBarry Smith         PetscMemcpy(new_a,aa,(ai[row]+nrow)*bs2*sizeof(Scalar));
72792c4ed94SBarry Smith         PetscMemzero(new_a+bs2*(ai[row]+nrow),bs2*CHUNKSIZE*sizeof(Scalar));
728dd9472c6SBarry Smith         PetscMemcpy(new_a+bs2*(ai[row]+nrow+CHUNKSIZE),aa+bs2*(ai[row]+nrow),bs2*len*sizeof(Scalar));
72992c4ed94SBarry Smith         /* free up old matrix storage */
73092c4ed94SBarry Smith         PetscFree(a->a);
73192c4ed94SBarry Smith         if (!a->singlemalloc) {PetscFree(a->i);PetscFree(a->j);}
73292c4ed94SBarry Smith         aa = a->a = new_a; ai = a->i = new_i; aj = a->j = new_j;
73392c4ed94SBarry Smith         a->singlemalloc = 1;
73492c4ed94SBarry Smith 
73592c4ed94SBarry Smith         rp   = aj + ai[row]; ap = aa + bs2*ai[row];
73692c4ed94SBarry Smith         rmax = imax[row] = imax[row] + CHUNKSIZE;
73792c4ed94SBarry Smith         PLogObjectMemory(A,CHUNKSIZE*(sizeof(int) + bs2*sizeof(Scalar)));
73892c4ed94SBarry Smith         a->maxnz += bs2*CHUNKSIZE;
73992c4ed94SBarry Smith         a->reallocs++;
74092c4ed94SBarry Smith         a->nz++;
74192c4ed94SBarry Smith       }
74292c4ed94SBarry Smith       N = nrow++ - 1;
74392c4ed94SBarry Smith       /* shift up all the later entries in this row */
74492c4ed94SBarry Smith       for ( ii=N; ii>=i; ii-- ) {
74592c4ed94SBarry Smith         rp[ii+1] = rp[ii];
74692c4ed94SBarry Smith         PetscMemcpy(ap+bs2*(ii+1),ap+bs2*(ii),bs2*sizeof(Scalar));
74792c4ed94SBarry Smith       }
74892c4ed94SBarry Smith       if (N >= i) PetscMemzero(ap+bs2*i,bs2*sizeof(Scalar));
74992c4ed94SBarry Smith       rp[i] = col;
7508a84c255SSatish Balay       bap   = ap +  bs2*i;
7510e324ae4SSatish Balay       if (roworiented) {
752dd9472c6SBarry Smith         for ( ii=0; ii<bs; ii++,value+=stepval) {
753dd9472c6SBarry Smith           for (jj=ii; jj<bs2; jj+=bs ) {
7540e324ae4SSatish Balay             bap[jj] = *value++;
755dd9472c6SBarry Smith           }
756dd9472c6SBarry Smith         }
7570e324ae4SSatish Balay       } else {
758dd9472c6SBarry Smith         for ( ii=0; ii<bs; ii++,value+=stepval ) {
759dd9472c6SBarry Smith           for (jj=0; jj<bs; jj++ ) {
7600e324ae4SSatish Balay             *bap++  = *value++;
7610e324ae4SSatish Balay           }
762dd9472c6SBarry Smith         }
763dd9472c6SBarry Smith       }
764f1241b54SBarry Smith       noinsert2:;
76592c4ed94SBarry Smith       low = i;
76692c4ed94SBarry Smith     }
76792c4ed94SBarry Smith     ailen[row] = nrow;
76892c4ed94SBarry Smith   }
7693a40ed3dSBarry Smith   PetscFunctionReturn(0);
77092c4ed94SBarry Smith }
77192c4ed94SBarry Smith 
772f2501298SSatish Balay 
7735615d1e5SSatish Balay #undef __FUNC__
7745615d1e5SSatish Balay #define __FUNC__ "MatAssemblyEnd_SeqBAIJ"
7758f6be9afSLois Curfman McInnes int MatAssemblyEnd_SeqBAIJ(Mat A,MatAssemblyType mode)
776584200bdSSatish Balay {
777584200bdSSatish Balay   Mat_SeqBAIJ *a = (Mat_SeqBAIJ *) A->data;
778584200bdSSatish Balay   int        fshift = 0,i,j,*ai = a->i, *aj = a->j, *imax = a->imax;
779a7c10996SSatish Balay   int        m = a->m,*ip, N, *ailen = a->ilen;
78043ee02c3SBarry Smith   int        mbs = a->mbs, bs2 = a->bs2,rmax = 0;
781584200bdSSatish Balay   Scalar     *aa = a->a, *ap;
782584200bdSSatish Balay 
7833a40ed3dSBarry Smith   PetscFunctionBegin;
7843a40ed3dSBarry Smith   if (mode == MAT_FLUSH_ASSEMBLY) PetscFunctionReturn(0);
785584200bdSSatish Balay 
78643ee02c3SBarry Smith   if (m) rmax = ailen[0];
787584200bdSSatish Balay   for ( i=1; i<mbs; i++ ) {
788584200bdSSatish Balay     /* move each row back by the amount of empty slots (fshift) before it*/
789584200bdSSatish Balay     fshift += imax[i-1] - ailen[i-1];
790d402145bSBarry Smith     rmax   = PetscMax(rmax,ailen[i]);
791584200bdSSatish Balay     if (fshift) {
792a7c10996SSatish Balay       ip = aj + ai[i]; ap = aa + bs2*ai[i];
793584200bdSSatish Balay       N = ailen[i];
794584200bdSSatish Balay       for ( j=0; j<N; j++ ) {
795584200bdSSatish Balay         ip[j-fshift] = ip[j];
7967e67e3f9SSatish Balay         PetscMemcpy(ap+(j-fshift)*bs2,ap+j*bs2,bs2*sizeof(Scalar));
797584200bdSSatish Balay       }
798584200bdSSatish Balay     }
799584200bdSSatish Balay     ai[i] = ai[i-1] + ailen[i-1];
800584200bdSSatish Balay   }
801584200bdSSatish Balay   if (mbs) {
802584200bdSSatish Balay     fshift += imax[mbs-1] - ailen[mbs-1];
803584200bdSSatish Balay     ai[mbs] = ai[mbs-1] + ailen[mbs-1];
804584200bdSSatish Balay   }
805584200bdSSatish Balay   /* reset ilen and imax for each row */
806584200bdSSatish Balay   for ( i=0; i<mbs; i++ ) {
807584200bdSSatish Balay     ailen[i] = imax[i] = ai[i+1] - ai[i];
808584200bdSSatish Balay   }
809a7c10996SSatish Balay   a->nz = ai[mbs];
810584200bdSSatish Balay 
811584200bdSSatish Balay   /* diagonals may have moved, so kill the diagonal pointers */
812584200bdSSatish Balay   if (fshift && a->diag) {
813584200bdSSatish Balay     PetscFree(a->diag);
814584200bdSSatish Balay     PLogObjectMemory(A,-(m+1)*sizeof(int));
815584200bdSSatish Balay     a->diag = 0;
816584200bdSSatish Balay   }
8173d2013a6SLois Curfman McInnes   PLogInfo(A,"MatAssemblyEnd_SeqBAIJ:Matrix size: %d X %d, block size %d; storage space: %d unneeded, %d used\n",
818219d9a1aSLois Curfman McInnes            m,a->n,a->bs,fshift*bs2,a->nz*bs2);
8193d2013a6SLois Curfman McInnes   PLogInfo(A,"MatAssemblyEnd_SeqBAIJ:Number of mallocs during MatSetValues is %d\n",
820584200bdSSatish Balay            a->reallocs);
821d402145bSBarry Smith   PLogInfo(A,"MatAssemblyEnd_SeqBAIJ:Most nonzeros blocks in any row is %d\n",rmax);
822e2f3b5e9SSatish Balay   a->reallocs          = 0;
8234e220ebcSLois Curfman McInnes   A->info.nz_unneeded  = (double)fshift*bs2;
8244e220ebcSLois Curfman McInnes 
8253a40ed3dSBarry Smith   PetscFunctionReturn(0);
826584200bdSSatish Balay }
827584200bdSSatish Balay 
8285a838052SSatish Balay 
829d9b7c43dSSatish Balay /* idx should be of length atlease bs */
8305615d1e5SSatish Balay #undef __FUNC__
8315615d1e5SSatish Balay #define __FUNC__ "MatZeroRows_SeqBAIJ_Check_Block"
832d9b7c43dSSatish Balay static int MatZeroRows_SeqBAIJ_Check_Block(int *idx, int bs, PetscTruth *flg)
833d9b7c43dSSatish Balay {
834d9b7c43dSSatish Balay   int i,row;
8353a40ed3dSBarry Smith 
8363a40ed3dSBarry Smith   PetscFunctionBegin;
837d9b7c43dSSatish Balay   row = idx[0];
8383a40ed3dSBarry Smith   if (row%bs!=0) { *flg = PETSC_FALSE; PetscFunctionReturn(0); }
839d9b7c43dSSatish Balay 
840d9b7c43dSSatish Balay   for ( i=1; i<bs; i++ ) {
8413a40ed3dSBarry Smith     if (row+i != idx[i]) { *flg = PETSC_FALSE; PetscFunctionReturn(0); }
842d9b7c43dSSatish Balay   }
843d9b7c43dSSatish Balay   *flg = PETSC_TRUE;
8443a40ed3dSBarry Smith   PetscFunctionReturn(0);
845d9b7c43dSSatish Balay }
846d9b7c43dSSatish Balay 
8475615d1e5SSatish Balay #undef __FUNC__
8485615d1e5SSatish Balay #define __FUNC__ "MatZeroRows_SeqBAIJ"
8498f6be9afSLois Curfman McInnes int MatZeroRows_SeqBAIJ(Mat A,IS is, Scalar *diag)
850d9b7c43dSSatish Balay {
851d9b7c43dSSatish Balay   Mat_SeqBAIJ *baij=(Mat_SeqBAIJ*)A->data;
852d9b7c43dSSatish Balay   IS          is_local;
853d9b7c43dSSatish Balay   int         ierr,i,j,count,m=baij->m,is_n,*is_idx,*rows,bs=baij->bs,bs2=baij->bs2;
854d9b7c43dSSatish Balay   PetscTruth  flg;
855d9b7c43dSSatish Balay   Scalar      zero = 0.0,*aa;
856d9b7c43dSSatish Balay 
8573a40ed3dSBarry Smith   PetscFunctionBegin;
858d9b7c43dSSatish Balay   /* Make a copy of the IS and  sort it */
859d9b7c43dSSatish Balay   ierr = ISGetSize(is,&is_n);CHKERRQ(ierr);
860d9b7c43dSSatish Balay   ierr = ISGetIndices(is,&is_idx);CHKERRQ(ierr);
861537820f0SBarry Smith   ierr = ISCreateGeneral(A->comm,is_n,is_idx,&is_local); CHKERRQ(ierr);
862d9b7c43dSSatish Balay   ierr = ISSort(is_local); CHKERRQ(ierr);
863d9b7c43dSSatish Balay   ierr = ISGetIndices(is_local,&rows); CHKERRQ(ierr);
864d9b7c43dSSatish Balay 
865d9b7c43dSSatish Balay   i = 0;
866d9b7c43dSSatish Balay   while (i < is_n) {
867a8c6a408SBarry Smith     if (rows[i]<0 || rows[i]>m) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"row out of range");
868d9b7c43dSSatish Balay     flg = PETSC_FALSE;
869d9b7c43dSSatish Balay     if (i+bs <= is_n) {ierr = MatZeroRows_SeqBAIJ_Check_Block(rows+i,bs,&flg); CHKERRQ(ierr); }
870d9b7c43dSSatish Balay     count = (baij->i[rows[i]/bs +1] - baij->i[rows[i]/bs])*bs;
871d9b7c43dSSatish Balay     aa    = baij->a + baij->i[rows[i]/bs]*bs2 + (rows[i]%bs);
872*2d61bbb3SSatish Balay     if (flg) { /* There exists a block of rows to be Zerowed */
873*2d61bbb3SSatish Balay       PetscMemzero(aa,count*bs*sizeof(Scalar));
874*2d61bbb3SSatish Balay       baij->ilen[rows[i]/bs] = 1;
875*2d61bbb3SSatish Balay        baij->j[baij->i[rows[i]/bs]] = rows[i]/bs;
876*2d61bbb3SSatish Balay       i += bs;
877*2d61bbb3SSatish Balay     } else { /* Zero out only the requested row */
878d9b7c43dSSatish Balay       for ( j=0; j<count; j++ ) {
879d9b7c43dSSatish Balay         aa[0] = zero;
880d9b7c43dSSatish Balay         aa+=bs;
881d9b7c43dSSatish Balay       }
882d9b7c43dSSatish Balay       i++;
883d9b7c43dSSatish Balay     }
884d9b7c43dSSatish Balay   }
885d9b7c43dSSatish Balay   if (diag) {
886d9b7c43dSSatish Balay     for ( j=0; j<is_n; j++ ) {
887d9b7c43dSSatish Balay       ierr = (*A->ops.setvalues)(A,1,rows+j,1,rows+j,diag,INSERT_VALUES);CHKERRQ(ierr);
888*2d61bbb3SSatish Balay       /* ierr = MatSetValues(A,1,rows+j,1,rows+j,diag,INSERT_VALUES);CHKERRQ(ierr); */
889d9b7c43dSSatish Balay     }
890d9b7c43dSSatish Balay   }
891d9b7c43dSSatish Balay   ierr = ISRestoreIndices(is,&is_idx); CHKERRQ(ierr);
892d9b7c43dSSatish Balay   ierr = ISRestoreIndices(is_local,&rows); CHKERRQ(ierr);
893d9b7c43dSSatish Balay   ierr = ISDestroy(is_local); CHKERRQ(ierr);
8949a8dea36SBarry Smith   ierr = MatAssemblyEnd_SeqBAIJ(A,MAT_FINAL_ASSEMBLY); CHKERRQ(ierr);
8953a40ed3dSBarry Smith   PetscFunctionReturn(0);
896d9b7c43dSSatish Balay }
8971c351548SSatish Balay 
8985615d1e5SSatish Balay #undef __FUNC__
899*2d61bbb3SSatish Balay #define __FUNC__ "MatSetValues_SeqBAIJ"
900*2d61bbb3SSatish Balay int MatSetValues_SeqBAIJ(Mat A,int m,int *im,int n,int *in,Scalar *v,InsertMode is)
901*2d61bbb3SSatish Balay {
902*2d61bbb3SSatish Balay   Mat_SeqBAIJ *a = (Mat_SeqBAIJ *) A->data;
903*2d61bbb3SSatish Balay   int         *rp,k,low,high,t,ii,row,nrow,i,col,l,rmax,N,sorted=a->sorted;
904*2d61bbb3SSatish Balay   int         *imax=a->imax,*ai=a->i,*ailen=a->ilen,roworiented=a->roworiented;
905*2d61bbb3SSatish Balay   int         *aj=a->j,nonew=a->nonew,bs=a->bs,brow,bcol;
906*2d61bbb3SSatish Balay   int          ridx,cidx,bs2=a->bs2;
907*2d61bbb3SSatish Balay   Scalar      *ap,value,*aa=a->a,*bap;
908*2d61bbb3SSatish Balay 
909*2d61bbb3SSatish Balay   PetscFunctionBegin;
910*2d61bbb3SSatish Balay   for ( k=0; k<m; k++ ) { /* loop over added rows */
911*2d61bbb3SSatish Balay     row  = im[k]; brow = row/bs;
912*2d61bbb3SSatish Balay #if defined(USE_PETSC_BOPT_g)
913*2d61bbb3SSatish Balay     if (row < 0) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Negative row");
914*2d61bbb3SSatish Balay     if (row >= a->m) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Row too large");
915*2d61bbb3SSatish Balay #endif
916*2d61bbb3SSatish Balay     rp   = aj + ai[brow];
917*2d61bbb3SSatish Balay     ap   = aa + bs2*ai[brow];
918*2d61bbb3SSatish Balay     rmax = imax[brow];
919*2d61bbb3SSatish Balay     nrow = ailen[brow];
920*2d61bbb3SSatish Balay     low  = 0;
921*2d61bbb3SSatish Balay     for ( l=0; l<n; l++ ) { /* loop over added columns */
922*2d61bbb3SSatish Balay #if defined(USE_PETSC_BOPT_g)
923*2d61bbb3SSatish Balay       if (in[l] < 0) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Negative column");
924*2d61bbb3SSatish Balay       if (in[l] >= a->n) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Column too large");
925*2d61bbb3SSatish Balay #endif
926*2d61bbb3SSatish Balay       col = in[l]; bcol = col/bs;
927*2d61bbb3SSatish Balay       ridx = row % bs; cidx = col % bs;
928*2d61bbb3SSatish Balay       if (roworiented) {
929*2d61bbb3SSatish Balay         value = *v++;
930*2d61bbb3SSatish Balay       } else {
931*2d61bbb3SSatish Balay         value = v[k + l*m];
932*2d61bbb3SSatish Balay       }
933*2d61bbb3SSatish Balay       if (!sorted) low = 0; high = nrow;
934*2d61bbb3SSatish Balay       while (high-low > 7) {
935*2d61bbb3SSatish Balay         t = (low+high)/2;
936*2d61bbb3SSatish Balay         if (rp[t] > bcol) high = t;
937*2d61bbb3SSatish Balay         else              low  = t;
938*2d61bbb3SSatish Balay       }
939*2d61bbb3SSatish Balay       for ( i=low; i<high; i++ ) {
940*2d61bbb3SSatish Balay         if (rp[i] > bcol) break;
941*2d61bbb3SSatish Balay         if (rp[i] == bcol) {
942*2d61bbb3SSatish Balay           bap  = ap +  bs2*i + bs*cidx + ridx;
943*2d61bbb3SSatish Balay           if (is == ADD_VALUES) *bap += value;
944*2d61bbb3SSatish Balay           else                  *bap  = value;
945*2d61bbb3SSatish Balay           goto noinsert1;
946*2d61bbb3SSatish Balay         }
947*2d61bbb3SSatish Balay       }
948*2d61bbb3SSatish Balay       if (nonew == 1) goto noinsert1;
949*2d61bbb3SSatish Balay       else if (nonew == -1) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Inserting a new nonzero in the matrix");
950*2d61bbb3SSatish Balay       if (nrow >= rmax) {
951*2d61bbb3SSatish Balay         /* there is no extra room in row, therefore enlarge */
952*2d61bbb3SSatish Balay         int    new_nz = ai[a->mbs] + CHUNKSIZE,len,*new_i,*new_j;
953*2d61bbb3SSatish Balay         Scalar *new_a;
954*2d61bbb3SSatish Balay 
955*2d61bbb3SSatish Balay         if (nonew == -2) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Inserting a new nonzero in the matrix");
956*2d61bbb3SSatish Balay 
957*2d61bbb3SSatish Balay         /* Malloc new storage space */
958*2d61bbb3SSatish Balay         len     = new_nz*(sizeof(int)+bs2*sizeof(Scalar))+(a->mbs+1)*sizeof(int);
959*2d61bbb3SSatish Balay         new_a   = (Scalar *) PetscMalloc( len ); CHKPTRQ(new_a);
960*2d61bbb3SSatish Balay         new_j   = (int *) (new_a + bs2*new_nz);
961*2d61bbb3SSatish Balay         new_i   = new_j + new_nz;
962*2d61bbb3SSatish Balay 
963*2d61bbb3SSatish Balay         /* copy over old data into new slots */
964*2d61bbb3SSatish Balay         for ( ii=0; ii<brow+1; ii++ ) {new_i[ii] = ai[ii];}
965*2d61bbb3SSatish Balay         for ( ii=brow+1; ii<a->mbs+1; ii++ ) {new_i[ii] = ai[ii]+CHUNKSIZE;}
966*2d61bbb3SSatish Balay         PetscMemcpy(new_j,aj,(ai[brow]+nrow)*sizeof(int));
967*2d61bbb3SSatish Balay         len = (new_nz - CHUNKSIZE - ai[brow] - nrow);
968*2d61bbb3SSatish Balay         PetscMemcpy(new_j+ai[brow]+nrow+CHUNKSIZE,aj+ai[brow]+nrow,
969*2d61bbb3SSatish Balay                                                            len*sizeof(int));
970*2d61bbb3SSatish Balay         PetscMemcpy(new_a,aa,(ai[brow]+nrow)*bs2*sizeof(Scalar));
971*2d61bbb3SSatish Balay         PetscMemzero(new_a+bs2*(ai[brow]+nrow),bs2*CHUNKSIZE*sizeof(Scalar));
972*2d61bbb3SSatish Balay         PetscMemcpy(new_a+bs2*(ai[brow]+nrow+CHUNKSIZE),
973*2d61bbb3SSatish Balay                     aa+bs2*(ai[brow]+nrow),bs2*len*sizeof(Scalar));
974*2d61bbb3SSatish Balay         /* free up old matrix storage */
975*2d61bbb3SSatish Balay         PetscFree(a->a);
976*2d61bbb3SSatish Balay         if (!a->singlemalloc) {PetscFree(a->i);PetscFree(a->j);}
977*2d61bbb3SSatish Balay         aa = a->a = new_a; ai = a->i = new_i; aj = a->j = new_j;
978*2d61bbb3SSatish Balay         a->singlemalloc = 1;
979*2d61bbb3SSatish Balay 
980*2d61bbb3SSatish Balay         rp   = aj + ai[brow]; ap = aa + bs2*ai[brow];
981*2d61bbb3SSatish Balay         rmax = imax[brow] = imax[brow] + CHUNKSIZE;
982*2d61bbb3SSatish Balay         PLogObjectMemory(A,CHUNKSIZE*(sizeof(int) + bs2*sizeof(Scalar)));
983*2d61bbb3SSatish Balay         a->maxnz += bs2*CHUNKSIZE;
984*2d61bbb3SSatish Balay         a->reallocs++;
985*2d61bbb3SSatish Balay         a->nz++;
986*2d61bbb3SSatish Balay       }
987*2d61bbb3SSatish Balay       N = nrow++ - 1;
988*2d61bbb3SSatish Balay       /* shift up all the later entries in this row */
989*2d61bbb3SSatish Balay       for ( ii=N; ii>=i; ii-- ) {
990*2d61bbb3SSatish Balay         rp[ii+1] = rp[ii];
991*2d61bbb3SSatish Balay         PetscMemcpy(ap+bs2*(ii+1),ap+bs2*(ii),bs2*sizeof(Scalar));
992*2d61bbb3SSatish Balay       }
993*2d61bbb3SSatish Balay       if (N>=i) PetscMemzero(ap+bs2*i,bs2*sizeof(Scalar));
994*2d61bbb3SSatish Balay       rp[i]                      = bcol;
995*2d61bbb3SSatish Balay       ap[bs2*i + bs*cidx + ridx] = value;
996*2d61bbb3SSatish Balay       noinsert1:;
997*2d61bbb3SSatish Balay       low = i;
998*2d61bbb3SSatish Balay     }
999*2d61bbb3SSatish Balay     ailen[brow] = nrow;
1000*2d61bbb3SSatish Balay   }
1001*2d61bbb3SSatish Balay   PetscFunctionReturn(0);
1002*2d61bbb3SSatish Balay }
1003*2d61bbb3SSatish Balay 
1004*2d61bbb3SSatish Balay extern int MatLUFactorSymbolic_SeqBAIJ(Mat,IS,IS,double,Mat*);
1005*2d61bbb3SSatish Balay extern int MatLUFactor_SeqBAIJ(Mat,IS,IS,double);
1006*2d61bbb3SSatish Balay extern int MatIncreaseOverlap_SeqBAIJ(Mat,int,IS*,int);
1007*2d61bbb3SSatish Balay extern int MatGetSubMatrix_SeqBAIJ(Mat,IS,IS,MatGetSubMatrixCall,Mat*);
1008*2d61bbb3SSatish Balay extern int MatGetSubMatrices_SeqBAIJ(Mat,int,IS*,IS*,MatGetSubMatrixCall,Mat**);
1009*2d61bbb3SSatish Balay extern int MatMultTrans_SeqBAIJ(Mat,Vec,Vec);
1010*2d61bbb3SSatish Balay extern int MatMultTransAdd_SeqBAIJ(Mat,Vec,Vec,Vec);
1011*2d61bbb3SSatish Balay extern int MatScale_SeqBAIJ(Scalar*,Mat);
1012*2d61bbb3SSatish Balay extern int MatNorm_SeqBAIJ(Mat,NormType,double *);
1013*2d61bbb3SSatish Balay extern int MatEqual_SeqBAIJ(Mat,Mat, PetscTruth*);
1014*2d61bbb3SSatish Balay extern int MatGetDiagonal_SeqBAIJ(Mat,Vec);
1015*2d61bbb3SSatish Balay extern int MatDiagonalScale_SeqBAIJ(Mat,Vec,Vec);
1016*2d61bbb3SSatish Balay extern int MatGetInfo_SeqBAIJ(Mat,MatInfoType,MatInfo *);
1017*2d61bbb3SSatish Balay extern int MatZeroEntries_SeqBAIJ(Mat);
1018*2d61bbb3SSatish Balay 
1019*2d61bbb3SSatish Balay extern int MatSolve_SeqBAIJ_N(Mat,Vec,Vec);
1020*2d61bbb3SSatish Balay extern int MatSolve_SeqBAIJ_1(Mat,Vec,Vec);
1021*2d61bbb3SSatish Balay extern int MatSolve_SeqBAIJ_2(Mat,Vec,Vec);
1022*2d61bbb3SSatish Balay extern int MatSolve_SeqBAIJ_3(Mat,Vec,Vec);
1023*2d61bbb3SSatish Balay extern int MatSolve_SeqBAIJ_4(Mat,Vec,Vec);
1024*2d61bbb3SSatish Balay extern int MatSolve_SeqBAIJ_5(Mat,Vec,Vec);
1025*2d61bbb3SSatish Balay extern int MatSolve_SeqBAIJ_7(Mat,Vec,Vec);
1026*2d61bbb3SSatish Balay 
1027*2d61bbb3SSatish Balay extern int MatLUFactorNumeric_SeqBAIJ_N(Mat,Mat*);
1028*2d61bbb3SSatish Balay extern int MatLUFactorNumeric_SeqBAIJ_1(Mat,Mat*);
1029*2d61bbb3SSatish Balay extern int MatLUFactorNumeric_SeqBAIJ_2(Mat,Mat*);
1030*2d61bbb3SSatish Balay extern int MatLUFactorNumeric_SeqBAIJ_3(Mat,Mat*);
1031*2d61bbb3SSatish Balay extern int MatLUFactorNumeric_SeqBAIJ_4(Mat,Mat*);
1032*2d61bbb3SSatish Balay extern int MatLUFactorNumeric_SeqBAIJ_5(Mat,Mat*);
1033*2d61bbb3SSatish Balay extern int MatSolve_SeqBAIJ_4_NaturalOrdering(Mat,Vec,Vec);
1034*2d61bbb3SSatish Balay 
1035*2d61bbb3SSatish Balay extern int MatMult_SeqBAIJ_1(Mat,Vec,Vec);
1036*2d61bbb3SSatish Balay extern int MatMult_SeqBAIJ_2(Mat,Vec,Vec);
1037*2d61bbb3SSatish Balay extern int MatMult_SeqBAIJ_3(Mat,Vec,Vec);
1038*2d61bbb3SSatish Balay extern int MatMult_SeqBAIJ_4(Mat,Vec,Vec);
1039*2d61bbb3SSatish Balay extern int MatMult_SeqBAIJ_5(Mat,Vec,Vec);
1040*2d61bbb3SSatish Balay extern int MatMult_SeqBAIJ_7(Mat,Vec,Vec);
1041*2d61bbb3SSatish Balay extern int MatMult_SeqBAIJ_N(Mat,Vec,Vec);
1042*2d61bbb3SSatish Balay 
1043*2d61bbb3SSatish Balay extern int MatMultAdd_SeqBAIJ_1(Mat,Vec,Vec,Vec);
1044*2d61bbb3SSatish Balay extern int MatMultAdd_SeqBAIJ_2(Mat,Vec,Vec,Vec);
1045*2d61bbb3SSatish Balay extern int MatMultAdd_SeqBAIJ_3(Mat,Vec,Vec,Vec);
1046*2d61bbb3SSatish Balay extern int MatMultAdd_SeqBAIJ_4(Mat,Vec,Vec,Vec);
1047*2d61bbb3SSatish Balay extern int MatMultAdd_SeqBAIJ_5(Mat,Vec,Vec,Vec);
1048*2d61bbb3SSatish Balay extern int MatMultAdd_SeqBAIJ_7(Mat,Vec,Vec,Vec);
1049*2d61bbb3SSatish Balay extern int MatMultAdd_SeqBAIJ_N(Mat,Vec,Vec,Vec);
1050*2d61bbb3SSatish Balay 
1051*2d61bbb3SSatish Balay /*
1052*2d61bbb3SSatish Balay      note: This can only work for identity for row and col. It would
1053*2d61bbb3SSatish Balay    be good to check this and otherwise generate an error.
1054*2d61bbb3SSatish Balay */
1055*2d61bbb3SSatish Balay #undef __FUNC__
1056*2d61bbb3SSatish Balay #define __FUNC__ "MatILUFactor_SeqBAIJ"
1057*2d61bbb3SSatish Balay int MatILUFactor_SeqBAIJ(Mat inA,IS row,IS col,double efill,int fill)
1058*2d61bbb3SSatish Balay {
1059*2d61bbb3SSatish Balay   Mat_SeqBAIJ *a = (Mat_SeqBAIJ *) inA->data;
1060*2d61bbb3SSatish Balay   Mat         outA;
1061*2d61bbb3SSatish Balay   int         ierr;
1062*2d61bbb3SSatish Balay 
1063*2d61bbb3SSatish Balay   PetscFunctionBegin;
1064*2d61bbb3SSatish Balay   if (fill != 0) SETERRQ(PETSC_ERR_SUP,0,"Only fill=0 supported");
1065*2d61bbb3SSatish Balay 
1066*2d61bbb3SSatish Balay   outA          = inA;
1067*2d61bbb3SSatish Balay   inA->factor   = FACTOR_LU;
1068*2d61bbb3SSatish Balay   a->row        = row;
1069*2d61bbb3SSatish Balay   a->col        = col;
1070*2d61bbb3SSatish Balay 
1071*2d61bbb3SSatish Balay   if (!a->solve_work) {
1072*2d61bbb3SSatish Balay     a->solve_work = (Scalar *) PetscMalloc((a->m+a->bs)*sizeof(Scalar));CHKPTRQ(a->solve_work);
1073*2d61bbb3SSatish Balay     PLogObjectMemory(inA,(a->m+a->bs)*sizeof(Scalar));
1074*2d61bbb3SSatish Balay   }
1075*2d61bbb3SSatish Balay 
1076*2d61bbb3SSatish Balay   if (!a->diag) {
1077*2d61bbb3SSatish Balay     ierr = MatMarkDiag_SeqBAIJ(inA); CHKERRQ(ierr);
1078*2d61bbb3SSatish Balay   }
1079*2d61bbb3SSatish Balay   ierr = MatLUFactorNumeric(inA,&outA); CHKERRQ(ierr);
1080*2d61bbb3SSatish Balay 
1081*2d61bbb3SSatish Balay   /*
1082*2d61bbb3SSatish Balay       Blocksize 4 has a special faster solver for ILU(0) factorization
1083*2d61bbb3SSatish Balay     with natural ordering
1084*2d61bbb3SSatish Balay   */
1085*2d61bbb3SSatish Balay   if (a->bs == 4) {
1086*2d61bbb3SSatish Balay     inA->ops.solve = MatSolve_SeqBAIJ_4_NaturalOrdering;
1087*2d61bbb3SSatish Balay   }
1088*2d61bbb3SSatish Balay 
1089*2d61bbb3SSatish Balay   PetscFunctionReturn(0);
1090*2d61bbb3SSatish Balay }
1091*2d61bbb3SSatish Balay #undef __FUNC__
1092d4bb536fSBarry Smith #define __FUNC__ "MatPrintHelp_SeqBAIJ"
1093ba4ca20aSSatish Balay int MatPrintHelp_SeqBAIJ(Mat A)
1094ba4ca20aSSatish Balay {
1095ba4ca20aSSatish Balay   static int called = 0;
1096ba4ca20aSSatish Balay   MPI_Comm   comm = A->comm;
1097ba4ca20aSSatish Balay 
10983a40ed3dSBarry Smith   PetscFunctionBegin;
10993a40ed3dSBarry Smith   if (called) {PetscFunctionReturn(0);} else called = 1;
1100ba4ca20aSSatish Balay   PetscPrintf(comm," Options for MATSEQBAIJ and MATMPIBAIJ matrix formats (the defaults):\n");
1101ba4ca20aSSatish Balay   PetscPrintf(comm,"  -mat_block_size <block_size>\n");
11023a40ed3dSBarry Smith   PetscFunctionReturn(0);
1103ba4ca20aSSatish Balay }
1104d9b7c43dSSatish Balay 
11052593348eSBarry Smith /* -------------------------------------------------------------------*/
1106cd0e1443SSatish Balay static struct _MatOps MatOps = {MatSetValues_SeqBAIJ,
11079867e207SSatish Balay        MatGetRow_SeqBAIJ,MatRestoreRow_SeqBAIJ,
1108f44d3a6dSSatish Balay        MatMult_SeqBAIJ_N,MatMultAdd_SeqBAIJ_N,
1109faf6580fSSatish Balay        MatMultTrans_SeqBAIJ,MatMultTransAdd_SeqBAIJ,
11101a6a6d98SBarry Smith        MatSolve_SeqBAIJ_N,0,
1111b6490206SBarry Smith        0,0,
1112de6a44a3SBarry Smith        MatLUFactor_SeqBAIJ,0,
1113b6490206SBarry Smith        0,
1114f2501298SSatish Balay        MatTranspose_SeqBAIJ,
111517e48fc4SSatish Balay        MatGetInfo_SeqBAIJ,MatEqual_SeqBAIJ,
11169867e207SSatish Balay        MatGetDiagonal_SeqBAIJ,MatDiagonalScale_SeqBAIJ,MatNorm_SeqBAIJ,
1117584200bdSSatish Balay        0,MatAssemblyEnd_SeqBAIJ,
1118b6490206SBarry Smith        0,
1119d9b7c43dSSatish Balay        MatSetOption_SeqBAIJ,MatZeroEntries_SeqBAIJ,MatZeroRows_SeqBAIJ,
11207fc0212eSBarry Smith        MatLUFactorSymbolic_SeqBAIJ,MatLUFactorNumeric_SeqBAIJ_N,0,0,
1121b6490206SBarry Smith        MatGetSize_SeqBAIJ,MatGetSize_SeqBAIJ,MatGetOwnershipRange_SeqBAIJ,
1122de6a44a3SBarry Smith        MatILUFactorSymbolic_SeqBAIJ,0,
1123d402145bSBarry Smith        0,0,
1124b6490206SBarry Smith        MatConvertSameType_SeqBAIJ,0,0,
1125b6490206SBarry Smith        MatILUFactor_SeqBAIJ,0,0,
1126af015674SSatish Balay        MatGetSubMatrices_SeqBAIJ,MatIncreaseOverlap_SeqBAIJ,
11277e67e3f9SSatish Balay        MatGetValues_SeqBAIJ,0,
1128ba4ca20aSSatish Balay        MatPrintHelp_SeqBAIJ,MatScale_SeqBAIJ,
11293b2fbd54SBarry Smith        0,0,0,MatGetBlockSize_SeqBAIJ,
11303b2fbd54SBarry Smith        MatGetRowIJ_SeqBAIJ,
113192c4ed94SBarry Smith        MatRestoreRowIJ_SeqBAIJ,
113292c4ed94SBarry Smith        0,0,0,0,0,0,
113392c4ed94SBarry Smith        MatSetValuesBlocked_SeqBAIJ};
11342593348eSBarry Smith 
11355615d1e5SSatish Balay #undef __FUNC__
11365615d1e5SSatish Balay #define __FUNC__ "MatCreateSeqBAIJ"
11372593348eSBarry Smith /*@C
113844cd7ae7SLois Curfman McInnes    MatCreateSeqBAIJ - Creates a sparse matrix in block AIJ (block
113944cd7ae7SLois Curfman McInnes    compressed row) format.  For good matrix assembly performance the
114044cd7ae7SLois Curfman McInnes    user should preallocate the matrix storage by setting the parameter nz
11412bd5e0b2SLois Curfman McInnes    (or the array nzz).  By setting these parameters accurately, performance
11422bd5e0b2SLois Curfman McInnes    during matrix assembly can be increased by more than a factor of 50.
11432593348eSBarry Smith 
11442593348eSBarry Smith    Input Parameters:
1145029af93fSBarry Smith .  comm - MPI communicator, set to PETSC_COMM_SELF
1146b6490206SBarry Smith .  bs - size of block
11472593348eSBarry Smith .  m - number of rows
11482593348eSBarry Smith .  n - number of columns
1149b6490206SBarry Smith .  nz - number of block nonzeros per block row (same for all rows)
11502bd5e0b2SLois Curfman McInnes .  nzz - array containing the number of block nonzeros in the various block rows
11512bd5e0b2SLois Curfman McInnes          (possibly different for each block row) or PETSC_NULL
11522593348eSBarry Smith 
11532593348eSBarry Smith    Output Parameter:
11542593348eSBarry Smith .  A - the matrix
11552593348eSBarry Smith 
11560513a670SBarry Smith    Options Database Keys:
11570513a670SBarry Smith $    -mat_no_unroll - uses code that does not unroll the loops in the
11580effe34fSLois Curfman McInnes $                     block calculations (much slower)
11590513a670SBarry Smith $    -mat_block_size - size of the blocks to use
11600513a670SBarry Smith 
11612593348eSBarry Smith    Notes:
116244cd7ae7SLois Curfman McInnes    The block AIJ format is fully compatible with standard Fortran 77
11632593348eSBarry Smith    storage.  That is, the stored row and column indices can begin at
116444cd7ae7SLois Curfman McInnes    either one (as in Fortran) or zero.  See the users' manual for details.
11652593348eSBarry Smith 
11662593348eSBarry Smith    Specify the preallocated storage with either nz or nnz (not both).
11672593348eSBarry Smith    Set nz=PETSC_DEFAULT and nnz=PETSC_NULL for PETSc to control dynamic memory
11682593348eSBarry Smith    allocation.  For additional details, see the users manual chapter on
11696da5968aSLois Curfman McInnes    matrices.
11702593348eSBarry Smith 
117144cd7ae7SLois Curfman McInnes .seealso: MatCreate(), MatCreateSeqAIJ(), MatSetValues()
11722593348eSBarry Smith @*/
1173b6490206SBarry Smith int MatCreateSeqBAIJ(MPI_Comm comm,int bs,int m,int n,int nz,int *nnz, Mat *A)
11742593348eSBarry Smith {
11752593348eSBarry Smith   Mat         B;
1176b6490206SBarry Smith   Mat_SeqBAIJ *b;
11773b2fbd54SBarry Smith   int         i,len,ierr,flg,mbs=m/bs,nbs=n/bs,bs2=bs*bs,size;
11783b2fbd54SBarry Smith 
11793a40ed3dSBarry Smith   PetscFunctionBegin;
11803b2fbd54SBarry Smith   MPI_Comm_size(comm,&size);
1181a8c6a408SBarry Smith   if (size > 1) SETERRQ(PETSC_ERR_ARG_WRONG,0,"Comm must be of size 1");
1182b6490206SBarry Smith 
11830513a670SBarry Smith   ierr = OptionsGetInt(PETSC_NULL,"-mat_block_size",&bs,&flg);CHKERRQ(ierr);
11840513a670SBarry Smith 
11853a40ed3dSBarry Smith   if (mbs*bs!=m || nbs*bs!=n) {
1186a8c6a408SBarry Smith     SETERRQ(PETSC_ERR_ARG_SIZ,0,"Number rows, cols must be divisible by blocksize");
11873a40ed3dSBarry Smith   }
11882593348eSBarry Smith 
11892593348eSBarry Smith   *A = 0;
1190d4bb536fSBarry Smith   PetscHeaderCreate(B,_p_Mat,MAT_COOKIE,MATSEQBAIJ,comm,MatDestroy,MatView);
11912593348eSBarry Smith   PLogObjectCreate(B);
1192b6490206SBarry Smith   B->data = (void *) (b = PetscNew(Mat_SeqBAIJ)); CHKPTRQ(b);
119344cd7ae7SLois Curfman McInnes   PetscMemzero(b,sizeof(Mat_SeqBAIJ));
11942593348eSBarry Smith   PetscMemcpy(&B->ops,&MatOps,sizeof(struct _MatOps));
11951a6a6d98SBarry Smith   ierr = OptionsHasName(PETSC_NULL,"-mat_no_unroll",&flg); CHKERRQ(ierr);
11961a6a6d98SBarry Smith   if (!flg) {
11977fc0212eSBarry Smith     switch (bs) {
11987fc0212eSBarry Smith     case 1:
11997fc0212eSBarry Smith       B->ops.lufactornumeric = MatLUFactorNumeric_SeqBAIJ_1;
12001a6a6d98SBarry Smith       B->ops.solve           = MatSolve_SeqBAIJ_1;
120139b95ed1SBarry Smith       B->ops.mult            = MatMult_SeqBAIJ_1;
1202f44d3a6dSSatish Balay       B->ops.multadd         = MatMultAdd_SeqBAIJ_1;
12037fc0212eSBarry Smith       break;
12044eeb42bcSBarry Smith     case 2:
12054eeb42bcSBarry Smith       B->ops.lufactornumeric = MatLUFactorNumeric_SeqBAIJ_2;
12061a6a6d98SBarry Smith       B->ops.solve           = MatSolve_SeqBAIJ_2;
120739b95ed1SBarry Smith       B->ops.mult            = MatMult_SeqBAIJ_2;
1208f44d3a6dSSatish Balay       B->ops.multadd         = MatMultAdd_SeqBAIJ_2;
12096d84be18SBarry Smith       break;
1210f327dd97SBarry Smith     case 3:
1211f327dd97SBarry Smith       B->ops.lufactornumeric = MatLUFactorNumeric_SeqBAIJ_3;
12121a6a6d98SBarry Smith       B->ops.solve           = MatSolve_SeqBAIJ_3;
121339b95ed1SBarry Smith       B->ops.mult            = MatMult_SeqBAIJ_3;
1214f44d3a6dSSatish Balay       B->ops.multadd         = MatMultAdd_SeqBAIJ_3;
12154eeb42bcSBarry Smith       break;
12166d84be18SBarry Smith     case 4:
12176d84be18SBarry Smith       B->ops.lufactornumeric = MatLUFactorNumeric_SeqBAIJ_4;
12181a6a6d98SBarry Smith       B->ops.solve           = MatSolve_SeqBAIJ_4;
121939b95ed1SBarry Smith       B->ops.mult            = MatMult_SeqBAIJ_4;
1220f44d3a6dSSatish Balay       B->ops.multadd         = MatMultAdd_SeqBAIJ_4;
12216d84be18SBarry Smith       break;
12226d84be18SBarry Smith     case 5:
12236d84be18SBarry Smith       B->ops.lufactornumeric = MatLUFactorNumeric_SeqBAIJ_5;
12241a6a6d98SBarry Smith       B->ops.solve           = MatSolve_SeqBAIJ_5;
122539b95ed1SBarry Smith       B->ops.mult            = MatMult_SeqBAIJ_5;
1226f44d3a6dSSatish Balay       B->ops.multadd         = MatMultAdd_SeqBAIJ_5;
12276d84be18SBarry Smith       break;
122848e9ddb2SSatish Balay     case 7:
122948e9ddb2SSatish Balay       B->ops.mult            = MatMult_SeqBAIJ_7;
123048e9ddb2SSatish Balay       B->ops.solve           = MatSolve_SeqBAIJ_7;
123148e9ddb2SSatish Balay       B->ops.multadd         = MatMultAdd_SeqBAIJ_7;
123248e9ddb2SSatish Balay       break;
12337fc0212eSBarry Smith     }
12341a6a6d98SBarry Smith   }
1235b6490206SBarry Smith   B->destroy          = MatDestroy_SeqBAIJ;
1236b6490206SBarry Smith   B->view             = MatView_SeqBAIJ;
12372593348eSBarry Smith   B->factor           = 0;
12382593348eSBarry Smith   B->lupivotthreshold = 1.0;
123990f02eecSBarry Smith   B->mapping          = 0;
12402593348eSBarry Smith   b->row              = 0;
12412593348eSBarry Smith   b->col              = 0;
12422593348eSBarry Smith   b->reallocs         = 0;
12432593348eSBarry Smith 
124444cd7ae7SLois Curfman McInnes   b->m       = m; B->m = m; B->M = m;
124544cd7ae7SLois Curfman McInnes   b->n       = n; B->n = n; B->N = n;
1246b6490206SBarry Smith   b->mbs     = mbs;
1247f2501298SSatish Balay   b->nbs     = nbs;
1248b6490206SBarry Smith   b->imax    = (int *) PetscMalloc( (mbs+1)*sizeof(int) ); CHKPTRQ(b->imax);
12492593348eSBarry Smith   if (nnz == PETSC_NULL) {
1250119a934aSSatish Balay     if (nz == PETSC_DEFAULT) nz = 5;
12512593348eSBarry Smith     else if (nz <= 0)        nz = 1;
1252b6490206SBarry Smith     for ( i=0; i<mbs; i++ ) b->imax[i] = nz;
1253b6490206SBarry Smith     nz = nz*mbs;
12543a40ed3dSBarry Smith   } else {
12552593348eSBarry Smith     nz = 0;
1256b6490206SBarry Smith     for ( i=0; i<mbs; i++ ) {b->imax[i] = nnz[i]; nz += nnz[i];}
12572593348eSBarry Smith   }
12582593348eSBarry Smith 
12592593348eSBarry Smith   /* allocate the matrix space */
12607e67e3f9SSatish Balay   len   = nz*sizeof(int) + nz*bs2*sizeof(Scalar) + (b->m+1)*sizeof(int);
12612593348eSBarry Smith   b->a  = (Scalar *) PetscMalloc( len ); CHKPTRQ(b->a);
12627e67e3f9SSatish Balay   PetscMemzero(b->a,nz*bs2*sizeof(Scalar));
12637e67e3f9SSatish Balay   b->j  = (int *) (b->a + nz*bs2);
12642593348eSBarry Smith   PetscMemzero(b->j,nz*sizeof(int));
12652593348eSBarry Smith   b->i  = b->j + nz;
12662593348eSBarry Smith   b->singlemalloc = 1;
12672593348eSBarry Smith 
1268de6a44a3SBarry Smith   b->i[0] = 0;
1269b6490206SBarry Smith   for (i=1; i<mbs+1; i++) {
12702593348eSBarry Smith     b->i[i] = b->i[i-1] + b->imax[i-1];
12712593348eSBarry Smith   }
12722593348eSBarry Smith 
1273b6490206SBarry Smith   /* b->ilen will count nonzeros in each block row so far. */
1274b6490206SBarry Smith   b->ilen = (int *) PetscMalloc((mbs+1)*sizeof(int));
1275f09e8eb9SSatish Balay   PLogObjectMemory(B,len+2*(mbs+1)*sizeof(int)+sizeof(struct _p_Mat)+sizeof(Mat_SeqBAIJ));
1276b6490206SBarry Smith   for ( i=0; i<mbs; i++ ) { b->ilen[i] = 0;}
12772593348eSBarry Smith 
1278b6490206SBarry Smith   b->bs               = bs;
12799df24120SSatish Balay   b->bs2              = bs2;
1280b6490206SBarry Smith   b->mbs              = mbs;
12812593348eSBarry Smith   b->nz               = 0;
128218e7b8e4SLois Curfman McInnes   b->maxnz            = nz*bs2;
12832593348eSBarry Smith   b->sorted           = 0;
12842593348eSBarry Smith   b->roworiented      = 1;
12852593348eSBarry Smith   b->nonew            = 0;
12862593348eSBarry Smith   b->diag             = 0;
12872593348eSBarry Smith   b->solve_work       = 0;
1288de6a44a3SBarry Smith   b->mult_work        = 0;
12892593348eSBarry Smith   b->spptr            = 0;
12904e220ebcSLois Curfman McInnes   B->info.nz_unneeded = (double)b->maxnz;
12914e220ebcSLois Curfman McInnes 
12922593348eSBarry Smith   *A = B;
12932593348eSBarry Smith   ierr = OptionsHasName(PETSC_NULL,"-help", &flg); CHKERRQ(ierr);
12942593348eSBarry Smith   if (flg) {ierr = MatPrintHelp(B); CHKERRQ(ierr); }
12953a40ed3dSBarry Smith   PetscFunctionReturn(0);
12962593348eSBarry Smith }
12972593348eSBarry Smith 
12985615d1e5SSatish Balay #undef __FUNC__
12995615d1e5SSatish Balay #define __FUNC__ "MatConvertSameType_SeqBAIJ"
1300b6490206SBarry Smith int MatConvertSameType_SeqBAIJ(Mat A,Mat *B,int cpvalues)
13012593348eSBarry Smith {
13022593348eSBarry Smith   Mat         C;
1303b6490206SBarry Smith   Mat_SeqBAIJ *c,*a = (Mat_SeqBAIJ *) A->data;
13049df24120SSatish Balay   int         i,len, mbs = a->mbs,nz = a->nz,bs2 =a->bs2;
1305de6a44a3SBarry Smith 
13063a40ed3dSBarry Smith   PetscFunctionBegin;
1307a8c6a408SBarry Smith   if (a->i[mbs] != nz) SETERRQ(PETSC_ERR_PLIB,0,"Corrupt matrix");
13082593348eSBarry Smith 
13092593348eSBarry Smith   *B = 0;
1310d4bb536fSBarry Smith   PetscHeaderCreate(C,_p_Mat,MAT_COOKIE,MATSEQBAIJ,A->comm,MatDestroy,MatView);
13112593348eSBarry Smith   PLogObjectCreate(C);
1312b6490206SBarry Smith   C->data       = (void *) (c = PetscNew(Mat_SeqBAIJ)); CHKPTRQ(c);
13132593348eSBarry Smith   PetscMemcpy(&C->ops,&A->ops,sizeof(struct _MatOps));
1314b6490206SBarry Smith   C->destroy    = MatDestroy_SeqBAIJ;
1315b6490206SBarry Smith   C->view       = MatView_SeqBAIJ;
13162593348eSBarry Smith   C->factor     = A->factor;
13172593348eSBarry Smith   c->row        = 0;
13182593348eSBarry Smith   c->col        = 0;
13192593348eSBarry Smith   C->assembled  = PETSC_TRUE;
13202593348eSBarry Smith 
132144cd7ae7SLois Curfman McInnes   c->m = C->m   = a->m;
132244cd7ae7SLois Curfman McInnes   c->n = C->n   = a->n;
132344cd7ae7SLois Curfman McInnes   C->M          = a->m;
132444cd7ae7SLois Curfman McInnes   C->N          = a->n;
132544cd7ae7SLois Curfman McInnes 
1326b6490206SBarry Smith   c->bs         = a->bs;
13279df24120SSatish Balay   c->bs2        = a->bs2;
1328b6490206SBarry Smith   c->mbs        = a->mbs;
1329b6490206SBarry Smith   c->nbs        = a->nbs;
13302593348eSBarry Smith 
1331b6490206SBarry Smith   c->imax       = (int *) PetscMalloc((mbs+1)*sizeof(int)); CHKPTRQ(c->imax);
1332b6490206SBarry Smith   c->ilen       = (int *) PetscMalloc((mbs+1)*sizeof(int)); CHKPTRQ(c->ilen);
1333b6490206SBarry Smith   for ( i=0; i<mbs; i++ ) {
13342593348eSBarry Smith     c->imax[i] = a->imax[i];
13352593348eSBarry Smith     c->ilen[i] = a->ilen[i];
13362593348eSBarry Smith   }
13372593348eSBarry Smith 
13382593348eSBarry Smith   /* allocate the matrix space */
13392593348eSBarry Smith   c->singlemalloc = 1;
13407e67e3f9SSatish Balay   len   = (mbs+1)*sizeof(int) + nz*(bs2*sizeof(Scalar) + sizeof(int));
13412593348eSBarry Smith   c->a  = (Scalar *) PetscMalloc( len ); CHKPTRQ(c->a);
13427e67e3f9SSatish Balay   c->j  = (int *) (c->a + nz*bs2);
1343de6a44a3SBarry Smith   c->i  = c->j + nz;
1344b6490206SBarry Smith   PetscMemcpy(c->i,a->i,(mbs+1)*sizeof(int));
1345b6490206SBarry Smith   if (mbs > 0) {
1346de6a44a3SBarry Smith     PetscMemcpy(c->j,a->j,nz*sizeof(int));
13472593348eSBarry Smith     if (cpvalues == COPY_VALUES) {
13487e67e3f9SSatish Balay       PetscMemcpy(c->a,a->a,bs2*nz*sizeof(Scalar));
13492593348eSBarry Smith     }
13502593348eSBarry Smith   }
13512593348eSBarry Smith 
1352f09e8eb9SSatish Balay   PLogObjectMemory(C,len+2*(mbs+1)*sizeof(int)+sizeof(struct _p_Mat)+sizeof(Mat_SeqBAIJ));
13532593348eSBarry Smith   c->sorted      = a->sorted;
13542593348eSBarry Smith   c->roworiented = a->roworiented;
13552593348eSBarry Smith   c->nonew       = a->nonew;
13562593348eSBarry Smith 
13572593348eSBarry Smith   if (a->diag) {
1358b6490206SBarry Smith     c->diag = (int *) PetscMalloc( (mbs+1)*sizeof(int) ); CHKPTRQ(c->diag);
1359b6490206SBarry Smith     PLogObjectMemory(C,(mbs+1)*sizeof(int));
1360b6490206SBarry Smith     for ( i=0; i<mbs; i++ ) {
13612593348eSBarry Smith       c->diag[i] = a->diag[i];
13622593348eSBarry Smith     }
13632593348eSBarry Smith   }
13642593348eSBarry Smith   else c->diag          = 0;
13652593348eSBarry Smith   c->nz                 = a->nz;
13662593348eSBarry Smith   c->maxnz              = a->maxnz;
13672593348eSBarry Smith   c->solve_work         = 0;
13682593348eSBarry Smith   c->spptr              = 0;      /* Dangerous -I'm throwing away a->spptr */
13697fc0212eSBarry Smith   c->mult_work          = 0;
13702593348eSBarry Smith   *B = C;
13713a40ed3dSBarry Smith   PetscFunctionReturn(0);
13722593348eSBarry Smith }
13732593348eSBarry Smith 
13745615d1e5SSatish Balay #undef __FUNC__
13755615d1e5SSatish Balay #define __FUNC__ "MatLoad_SeqBAIJ"
137619bcc07fSBarry Smith int MatLoad_SeqBAIJ(Viewer viewer,MatType type,Mat *A)
13772593348eSBarry Smith {
1378b6490206SBarry Smith   Mat_SeqBAIJ  *a;
13792593348eSBarry Smith   Mat          B;
1380de6a44a3SBarry Smith   int          i,nz,ierr,fd,header[4],size,*rowlengths=0,M,N,bs=1,flg;
1381b6490206SBarry Smith   int          *mask,mbs,*jj,j,rowcount,nzcount,k,*browlengths,maskcount;
138235aab85fSBarry Smith   int          kmax,jcount,block,idx,point,nzcountb,extra_rows;
1383a7c10996SSatish Balay   int          *masked, nmask,tmp,bs2,ishift;
1384b6490206SBarry Smith   Scalar       *aa;
138519bcc07fSBarry Smith   MPI_Comm     comm = ((PetscObject) viewer)->comm;
13862593348eSBarry Smith 
13873a40ed3dSBarry Smith   PetscFunctionBegin;
13881a6a6d98SBarry Smith   ierr = OptionsGetInt(PETSC_NULL,"-matload_block_size",&bs,&flg);CHKERRQ(ierr);
1389de6a44a3SBarry Smith   bs2  = bs*bs;
1390b6490206SBarry Smith 
13912593348eSBarry Smith   MPI_Comm_size(comm,&size);
1392cc0fae11SBarry Smith   if (size > 1) SETERRQ(PETSC_ERR_ARG_WRONG,0,"view must have one processor");
139390ace30eSBarry Smith   ierr = ViewerBinaryGetDescriptor(viewer,&fd); CHKERRQ(ierr);
13940752156aSBarry Smith   ierr = PetscBinaryRead(fd,header,4,PETSC_INT); CHKERRQ(ierr);
1395a8c6a408SBarry Smith   if (header[0] != MAT_COOKIE) SETERRQ(PETSC_ERR_FILE_UNEXPECTED,0,"not Mat object");
13962593348eSBarry Smith   M = header[1]; N = header[2]; nz = header[3];
13972593348eSBarry Smith 
1398d64ed03dSBarry Smith   if (header[3] < 0) {
1399a8c6a408SBarry Smith     SETERRQ(PETSC_ERR_FILE_UNEXPECTED,1,"Matrix stored in special format, cannot load as SeqBAIJ");
1400d64ed03dSBarry Smith   }
1401d64ed03dSBarry Smith 
1402a8c6a408SBarry Smith   if (M != N) SETERRQ(PETSC_ERR_SUP,0,"Can only do square matrices");
140335aab85fSBarry Smith 
140435aab85fSBarry Smith   /*
140535aab85fSBarry Smith      This code adds extra rows to make sure the number of rows is
140635aab85fSBarry Smith     divisible by the blocksize
140735aab85fSBarry Smith   */
1408b6490206SBarry Smith   mbs        = M/bs;
140935aab85fSBarry Smith   extra_rows = bs - M + bs*(mbs);
141035aab85fSBarry Smith   if (extra_rows == bs) extra_rows = 0;
141135aab85fSBarry Smith   else                  mbs++;
141235aab85fSBarry Smith   if (extra_rows) {
1413537820f0SBarry Smith     PLogInfo(0,"MatLoad_SeqBAIJ:Padding loaded matrix to match blocksize\n");
141435aab85fSBarry Smith   }
1415b6490206SBarry Smith 
14162593348eSBarry Smith   /* read in row lengths */
141735aab85fSBarry Smith   rowlengths = (int*) PetscMalloc((M+extra_rows)*sizeof(int));CHKPTRQ(rowlengths);
14180752156aSBarry Smith   ierr = PetscBinaryRead(fd,rowlengths,M,PETSC_INT); CHKERRQ(ierr);
141935aab85fSBarry Smith   for ( i=0; i<extra_rows; i++ ) rowlengths[M+i] = 1;
14202593348eSBarry Smith 
1421b6490206SBarry Smith   /* read in column indices */
142235aab85fSBarry Smith   jj = (int*) PetscMalloc( (nz+extra_rows)*sizeof(int) ); CHKPTRQ(jj);
14230752156aSBarry Smith   ierr = PetscBinaryRead(fd,jj,nz,PETSC_INT); CHKERRQ(ierr);
142435aab85fSBarry Smith   for ( i=0; i<extra_rows; i++ ) jj[nz+i] = M+i;
1425b6490206SBarry Smith 
1426b6490206SBarry Smith   /* loop over row lengths determining block row lengths */
1427b6490206SBarry Smith   browlengths = (int *) PetscMalloc(mbs*sizeof(int));CHKPTRQ(browlengths);
1428b6490206SBarry Smith   PetscMemzero(browlengths,mbs*sizeof(int));
142935aab85fSBarry Smith   mask   = (int *) PetscMalloc( 2*mbs*sizeof(int) ); CHKPTRQ(mask);
143035aab85fSBarry Smith   PetscMemzero(mask,mbs*sizeof(int));
143135aab85fSBarry Smith   masked = mask + mbs;
1432b6490206SBarry Smith   rowcount = 0; nzcount = 0;
1433b6490206SBarry Smith   for ( i=0; i<mbs; i++ ) {
143435aab85fSBarry Smith     nmask = 0;
1435b6490206SBarry Smith     for ( j=0; j<bs; j++ ) {
1436b6490206SBarry Smith       kmax = rowlengths[rowcount];
1437b6490206SBarry Smith       for ( k=0; k<kmax; k++ ) {
143835aab85fSBarry Smith         tmp = jj[nzcount++]/bs;
143935aab85fSBarry Smith         if (!mask[tmp]) {masked[nmask++] = tmp; mask[tmp] = 1;}
1440b6490206SBarry Smith       }
1441b6490206SBarry Smith       rowcount++;
1442b6490206SBarry Smith     }
144335aab85fSBarry Smith     browlengths[i] += nmask;
144435aab85fSBarry Smith     /* zero out the mask elements we set */
144535aab85fSBarry Smith     for ( j=0; j<nmask; j++ ) mask[masked[j]] = 0;
1446b6490206SBarry Smith   }
1447b6490206SBarry Smith 
14482593348eSBarry Smith   /* create our matrix */
14493eee16b0SBarry Smith   ierr = MatCreateSeqBAIJ(comm,bs,M+extra_rows,N+extra_rows,0,browlengths,A);CHKERRQ(ierr);
14502593348eSBarry Smith   B = *A;
1451b6490206SBarry Smith   a = (Mat_SeqBAIJ *) B->data;
14522593348eSBarry Smith 
14532593348eSBarry Smith   /* set matrix "i" values */
1454de6a44a3SBarry Smith   a->i[0] = 0;
1455b6490206SBarry Smith   for ( i=1; i<= mbs; i++ ) {
1456b6490206SBarry Smith     a->i[i]      = a->i[i-1] + browlengths[i-1];
1457b6490206SBarry Smith     a->ilen[i-1] = browlengths[i-1];
14582593348eSBarry Smith   }
1459b6490206SBarry Smith   a->nz         = 0;
1460b6490206SBarry Smith   for ( i=0; i<mbs; i++ ) a->nz += browlengths[i];
14612593348eSBarry Smith 
1462b6490206SBarry Smith   /* read in nonzero values */
146335aab85fSBarry Smith   aa = (Scalar *) PetscMalloc((nz+extra_rows)*sizeof(Scalar));CHKPTRQ(aa);
14640752156aSBarry Smith   ierr = PetscBinaryRead(fd,aa,nz,PETSC_SCALAR); CHKERRQ(ierr);
146535aab85fSBarry Smith   for ( i=0; i<extra_rows; i++ ) aa[nz+i] = 1.0;
1466b6490206SBarry Smith 
1467b6490206SBarry Smith   /* set "a" and "j" values into matrix */
1468b6490206SBarry Smith   nzcount = 0; jcount = 0;
1469b6490206SBarry Smith   for ( i=0; i<mbs; i++ ) {
1470b6490206SBarry Smith     nzcountb = nzcount;
147135aab85fSBarry Smith     nmask    = 0;
1472b6490206SBarry Smith     for ( j=0; j<bs; j++ ) {
1473b6490206SBarry Smith       kmax = rowlengths[i*bs+j];
1474b6490206SBarry Smith       for ( k=0; k<kmax; k++ ) {
147535aab85fSBarry Smith         tmp = jj[nzcount++]/bs;
147635aab85fSBarry Smith 	if (!mask[tmp]) { masked[nmask++] = tmp; mask[tmp] = 1;}
1477b6490206SBarry Smith       }
1478b6490206SBarry Smith       rowcount++;
1479b6490206SBarry Smith     }
1480de6a44a3SBarry Smith     /* sort the masked values */
148177c4ece6SBarry Smith     PetscSortInt(nmask,masked);
1482de6a44a3SBarry Smith 
1483b6490206SBarry Smith     /* set "j" values into matrix */
1484b6490206SBarry Smith     maskcount = 1;
148535aab85fSBarry Smith     for ( j=0; j<nmask; j++ ) {
148635aab85fSBarry Smith       a->j[jcount++]  = masked[j];
1487de6a44a3SBarry Smith       mask[masked[j]] = maskcount++;
1488b6490206SBarry Smith     }
1489b6490206SBarry Smith     /* set "a" values into matrix */
1490de6a44a3SBarry Smith     ishift = bs2*a->i[i];
1491b6490206SBarry Smith     for ( j=0; j<bs; j++ ) {
1492b6490206SBarry Smith       kmax = rowlengths[i*bs+j];
1493b6490206SBarry Smith       for ( k=0; k<kmax; k++ ) {
1494de6a44a3SBarry Smith         tmp    = jj[nzcountb]/bs ;
1495de6a44a3SBarry Smith         block  = mask[tmp] - 1;
1496de6a44a3SBarry Smith         point  = jj[nzcountb] - bs*tmp;
1497de6a44a3SBarry Smith         idx    = ishift + bs2*block + j + bs*point;
1498b6490206SBarry Smith         a->a[idx] = aa[nzcountb++];
1499b6490206SBarry Smith       }
1500b6490206SBarry Smith     }
150135aab85fSBarry Smith     /* zero out the mask elements we set */
150235aab85fSBarry Smith     for ( j=0; j<nmask; j++ ) mask[masked[j]] = 0;
1503b6490206SBarry Smith   }
1504a8c6a408SBarry Smith   if (jcount != a->nz) SETERRQ(PETSC_ERR_FILE_UNEXPECTED,0,"Bad binary matrix");
1505b6490206SBarry Smith 
1506b6490206SBarry Smith   PetscFree(rowlengths);
1507b6490206SBarry Smith   PetscFree(browlengths);
1508b6490206SBarry Smith   PetscFree(aa);
1509b6490206SBarry Smith   PetscFree(jj);
1510b6490206SBarry Smith   PetscFree(mask);
1511b6490206SBarry Smith 
1512b6490206SBarry Smith   B->assembled = PETSC_TRUE;
1513de6a44a3SBarry Smith 
15149c01be13SBarry Smith   ierr = MatView_Private(B); CHKERRQ(ierr);
15153a40ed3dSBarry Smith   PetscFunctionReturn(0);
15162593348eSBarry Smith }
15172593348eSBarry Smith 
15182593348eSBarry Smith 
15192593348eSBarry Smith 
1520