xref: /petsc/src/mat/impls/baij/seq/baij.c (revision b1d4fb267e72f6b087ed013bbfbbee1418c3f503)
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/inline/spops.h"
9325e03aeSBarry Smith #include "petscsys.h"                     /*I "petscmat.h" I*/
103b547af2SSatish Balay 
11af674e45SBarry Smith /*
12af674e45SBarry Smith     Special version for Fun3d sequential benchmark
13af674e45SBarry Smith */
14af674e45SBarry Smith #if defined(PETSC_HAVE_FORTRAN_CAPS)
15af674e45SBarry Smith #define matsetvaluesblocked4_ MATSETVALUESBLOCKED4
16af674e45SBarry Smith #elif !defined(PETSC_HAVE_FORTRAN_UNDERSCORE)
17af674e45SBarry Smith #define matsetvaluesblocked4_ matsetvaluesblocked4
18af674e45SBarry Smith #endif
19af674e45SBarry Smith 
209c8c1041SBarry Smith EXTERN_C_BEGIN
21af674e45SBarry Smith #undef __FUNCT__
22af674e45SBarry Smith #define __FUNCT__ "matsetvaluesblocked4_"
23f15d580aSBarry Smith void matsetvaluesblocked4_(Mat *AA,int *mm,const int im[],int *nn,const int in[],const PetscScalar v[])
24af674e45SBarry Smith {
25af674e45SBarry Smith   Mat               A = *AA;
26af674e45SBarry Smith   Mat_SeqBAIJ       *a = (Mat_SeqBAIJ*)A->data;
27a037b02bSBarry Smith   int               *rp,k,low,high,t,ii,jj,row,nrow,i,col,l,N,m = *mm,n = *nn;
2838fde467SHong Zhang   int               *ai=a->i,*ailen=a->ilen;
29a037b02bSBarry Smith   int               *aj=a->j,stepval;
30f15d580aSBarry Smith   const PetscScalar *value = v;
314bb09213Spetsc   MatScalar         *ap,*aa = a->a,*bap;
32af674e45SBarry Smith 
33af674e45SBarry Smith   PetscFunctionBegin;
34af674e45SBarry Smith   stepval = (n-1)*4;
35af674e45SBarry Smith   for (k=0; k<m; k++) { /* loop over added rows */
36af674e45SBarry Smith     row  = im[k];
37af674e45SBarry Smith     rp   = aj + ai[row];
38af674e45SBarry Smith     ap   = aa + 16*ai[row];
39af674e45SBarry Smith     nrow = ailen[row];
40af674e45SBarry Smith     low  = 0;
41af674e45SBarry Smith     for (l=0; l<n; l++) { /* loop over added columns */
42af674e45SBarry Smith       col = in[l];
43af674e45SBarry Smith       value = v + k*(stepval+4)*4 + l*4;
44af674e45SBarry Smith       low = 0; high = nrow;
45af674e45SBarry Smith       while (high-low > 7) {
46af674e45SBarry Smith         t = (low+high)/2;
47af674e45SBarry Smith         if (rp[t] > col) high = t;
48af674e45SBarry Smith         else             low  = t;
49af674e45SBarry Smith       }
50af674e45SBarry Smith       for (i=low; i<high; i++) {
51af674e45SBarry Smith         if (rp[i] > col) break;
52af674e45SBarry Smith         if (rp[i] == col) {
53af674e45SBarry Smith           bap  = ap +  16*i;
54af674e45SBarry Smith           for (ii=0; ii<4; ii++,value+=stepval) {
55af674e45SBarry Smith             for (jj=ii; jj<16; jj+=4) {
56af674e45SBarry Smith               bap[jj] += *value++;
57af674e45SBarry Smith             }
58af674e45SBarry Smith           }
59af674e45SBarry Smith           goto noinsert2;
60af674e45SBarry Smith         }
61af674e45SBarry Smith       }
62af674e45SBarry Smith       N = nrow++ - 1;
63af674e45SBarry Smith       /* shift up all the later entries in this row */
64af674e45SBarry Smith       for (ii=N; ii>=i; ii--) {
65af674e45SBarry Smith         rp[ii+1] = rp[ii];
66a037b02bSBarry Smith         PetscMemcpy(ap+16*(ii+1),ap+16*(ii),16*sizeof(MatScalar));
67af674e45SBarry Smith       }
68af674e45SBarry Smith       if (N >= i) {
69a037b02bSBarry Smith         PetscMemzero(ap+16*i,16*sizeof(MatScalar));
70af674e45SBarry Smith       }
71af674e45SBarry Smith       rp[i] = col;
72af674e45SBarry Smith       bap   = ap +  16*i;
73af674e45SBarry Smith       for (ii=0; ii<4; ii++,value+=stepval) {
74af674e45SBarry Smith         for (jj=ii; jj<16; jj+=4) {
75af674e45SBarry Smith           bap[jj] = *value++;
76af674e45SBarry Smith         }
77af674e45SBarry Smith       }
78af674e45SBarry Smith       noinsert2:;
79af674e45SBarry Smith       low = i;
80af674e45SBarry Smith     }
81af674e45SBarry Smith     ailen[row] = nrow;
82af674e45SBarry Smith   }
83af674e45SBarry Smith }
849c8c1041SBarry Smith EXTERN_C_END
85af674e45SBarry Smith 
86af674e45SBarry Smith #if defined(PETSC_HAVE_FORTRAN_CAPS)
87af674e45SBarry Smith #define matsetvalues4_ MATSETVALUES4
88af674e45SBarry Smith #elif !defined(PETSC_HAVE_FORTRAN_UNDERSCORE)
89af674e45SBarry Smith #define matsetvalues4_ matsetvalues4
90af674e45SBarry Smith #endif
91af674e45SBarry Smith 
929c8c1041SBarry Smith EXTERN_C_BEGIN
93af674e45SBarry Smith #undef __FUNCT__
94af674e45SBarry Smith #define __FUNCT__ "MatSetValues4_"
954bb09213Spetsc void matsetvalues4_(Mat *AA,int *mm,int *im,int *nn,int *in,PetscScalar *v)
96af674e45SBarry Smith {
97af674e45SBarry Smith   Mat         A = *AA;
98af674e45SBarry Smith   Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)A->data;
99a037b02bSBarry Smith   int         *rp,k,low,high,t,ii,row,nrow,i,col,l,N,n = *nn,m = *mm;
10038fde467SHong Zhang   int         *ai=a->i,*ailen=a->ilen;
101af674e45SBarry Smith   int         *aj=a->j,brow,bcol;
10238fde467SHong Zhang   int         ridx,cidx;
103af674e45SBarry Smith   MatScalar   *ap,value,*aa=a->a,*bap;
104af674e45SBarry Smith 
105af674e45SBarry Smith   PetscFunctionBegin;
106af674e45SBarry Smith   for (k=0; k<m; k++) { /* loop over added rows */
107af674e45SBarry Smith     row  = im[k]; brow = row/4;
108af674e45SBarry Smith     rp   = aj + ai[brow];
109af674e45SBarry Smith     ap   = aa + 16*ai[brow];
110af674e45SBarry Smith     nrow = ailen[brow];
111af674e45SBarry Smith     low  = 0;
112af674e45SBarry Smith     for (l=0; l<n; l++) { /* loop over added columns */
113af674e45SBarry Smith       col = in[l]; bcol = col/4;
114af674e45SBarry Smith       ridx = row % 4; cidx = col % 4;
115af674e45SBarry Smith       value = v[l + k*n];
116af674e45SBarry Smith       low = 0; high = nrow;
117af674e45SBarry Smith       while (high-low > 7) {
118af674e45SBarry Smith         t = (low+high)/2;
119af674e45SBarry Smith         if (rp[t] > bcol) high = t;
120af674e45SBarry Smith         else              low  = t;
121af674e45SBarry Smith       }
122af674e45SBarry Smith       for (i=low; i<high; i++) {
123af674e45SBarry Smith         if (rp[i] > bcol) break;
124af674e45SBarry Smith         if (rp[i] == bcol) {
125af674e45SBarry Smith           bap  = ap +  16*i + 4*cidx + ridx;
126af674e45SBarry Smith           *bap += value;
127af674e45SBarry Smith           goto noinsert1;
128af674e45SBarry Smith         }
129af674e45SBarry Smith       }
130af674e45SBarry Smith       N = nrow++ - 1;
131af674e45SBarry Smith       /* shift up all the later entries in this row */
132af674e45SBarry Smith       for (ii=N; ii>=i; ii--) {
133af674e45SBarry Smith         rp[ii+1] = rp[ii];
134a037b02bSBarry Smith         PetscMemcpy(ap+16*(ii+1),ap+16*(ii),16*sizeof(MatScalar));
135af674e45SBarry Smith       }
136af674e45SBarry Smith       if (N>=i) {
137a037b02bSBarry Smith         PetscMemzero(ap+16*i,16*sizeof(MatScalar));
138af674e45SBarry Smith       }
139af674e45SBarry Smith       rp[i]                    = bcol;
140af674e45SBarry Smith       ap[16*i + 4*cidx + ridx] = value;
141af674e45SBarry Smith       noinsert1:;
142af674e45SBarry Smith       low = i;
143af674e45SBarry Smith     }
144af674e45SBarry Smith     ailen[brow] = nrow;
145af674e45SBarry Smith   }
146af674e45SBarry Smith }
1479c8c1041SBarry Smith EXTERN_C_END
148af674e45SBarry Smith 
14995d5f7c2SBarry Smith /*  UGLY, ugly, ugly
15087828ca2SBarry Smith    When MatScalar == PetscScalar the function MatSetValuesBlocked_SeqBAIJ_MatScalar() does
1513477af42SKris Buschelman    not exist. Otherwise ..._MatScalar() takes matrix dlements in single precision and
15295d5f7c2SBarry Smith    inserts them into the single precision data structure. The function MatSetValuesBlocked_SeqBAIJ()
15395d5f7c2SBarry Smith    converts the entries into single precision and then calls ..._MatScalar() to put them
15495d5f7c2SBarry Smith    into the single precision data structures.
15595d5f7c2SBarry Smith */
15695d5f7c2SBarry Smith #if defined(PETSC_USE_MAT_SINGLE)
157f15d580aSBarry Smith EXTERN int MatSetValuesBlocked_SeqBAIJ_MatScalar(Mat,int,const int[],int,const int[],const MatScalar[],InsertMode);
15895d5f7c2SBarry Smith #else
15995d5f7c2SBarry Smith #define MatSetValuesBlocked_SeqBAIJ_MatScalar MatSetValuesBlocked_SeqBAIJ
16095d5f7c2SBarry Smith #endif
16195d5f7c2SBarry Smith 
1622d61bbb3SSatish Balay #define CHUNKSIZE  10
163de6a44a3SBarry Smith 
164be5855fcSBarry Smith /*
165be5855fcSBarry Smith      Checks for missing diagonals
166be5855fcSBarry Smith */
1674a2ae208SSatish Balay #undef __FUNCT__
1684a2ae208SSatish Balay #define __FUNCT__ "MatMissingDiagonal_SeqBAIJ"
169c4992f7dSBarry Smith int MatMissingDiagonal_SeqBAIJ(Mat A)
170be5855fcSBarry Smith {
171be5855fcSBarry Smith   Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)A->data;
172883fce79SBarry Smith   int         *diag,*jj = a->j,i,ierr;
173be5855fcSBarry Smith 
174be5855fcSBarry Smith   PetscFunctionBegin;
175c4992f7dSBarry Smith   ierr = MatMarkDiagonal_SeqBAIJ(A);CHKERRQ(ierr);
176883fce79SBarry Smith   diag = a->diag;
1770e8e8aceSBarry Smith   for (i=0; i<a->mbs; i++) {
178be5855fcSBarry Smith     if (jj[diag[i]] != i) {
17929bbc08cSBarry Smith       SETERRQ1(1,"Matrix is missing diagonal number %d",i);
180be5855fcSBarry Smith     }
181be5855fcSBarry Smith   }
182be5855fcSBarry Smith   PetscFunctionReturn(0);
183be5855fcSBarry Smith }
184be5855fcSBarry Smith 
1854a2ae208SSatish Balay #undef __FUNCT__
1864a2ae208SSatish Balay #define __FUNCT__ "MatMarkDiagonal_SeqBAIJ"
187c4992f7dSBarry Smith int MatMarkDiagonal_SeqBAIJ(Mat A)
188de6a44a3SBarry Smith {
189de6a44a3SBarry Smith   Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)A->data;
19082502324SSatish Balay   int         i,j,*diag,m = a->mbs,ierr;
191de6a44a3SBarry Smith 
1923a40ed3dSBarry Smith   PetscFunctionBegin;
193883fce79SBarry Smith   if (a->diag) PetscFunctionReturn(0);
194883fce79SBarry Smith 
195b0a32e0cSBarry Smith   ierr = PetscMalloc((m+1)*sizeof(int),&diag);CHKERRQ(ierr);
196b0a32e0cSBarry Smith   PetscLogObjectMemory(A,(m+1)*sizeof(int));
1977fc0212eSBarry Smith   for (i=0; i<m; i++) {
198ecc615b2SBarry Smith     diag[i] = a->i[i+1];
199de6a44a3SBarry Smith     for (j=a->i[i]; j<a->i[i+1]; j++) {
200de6a44a3SBarry Smith       if (a->j[j] == i) {
201de6a44a3SBarry Smith         diag[i] = j;
202de6a44a3SBarry Smith         break;
203de6a44a3SBarry Smith       }
204de6a44a3SBarry Smith     }
205de6a44a3SBarry Smith   }
206de6a44a3SBarry Smith   a->diag = diag;
2073a40ed3dSBarry Smith   PetscFunctionReturn(0);
208de6a44a3SBarry Smith }
2092593348eSBarry Smith 
2102593348eSBarry Smith 
211ca44d042SBarry Smith EXTERN int MatToSymmetricIJ_SeqAIJ(int,int*,int*,int,int,int**,int**);
2123b2fbd54SBarry Smith 
2134a2ae208SSatish Balay #undef __FUNCT__
2144a2ae208SSatish Balay #define __FUNCT__ "MatGetRowIJ_SeqBAIJ"
2154e7234bfSBarry Smith static int MatGetRowIJ_SeqBAIJ(Mat A,int oshift,PetscTruth symmetric,int *nn,int *ia[],int *ja[],PetscTruth *done)
2163b2fbd54SBarry Smith {
2173b2fbd54SBarry Smith   Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)A->data;
2183b2fbd54SBarry Smith   int         ierr,n = a->mbs,i;
2193b2fbd54SBarry Smith 
2203a40ed3dSBarry Smith   PetscFunctionBegin;
2213b2fbd54SBarry Smith   *nn = n;
2223a40ed3dSBarry Smith   if (!ia) PetscFunctionReturn(0);
2233b2fbd54SBarry Smith   if (symmetric) {
2243b2fbd54SBarry Smith     ierr = MatToSymmetricIJ_SeqAIJ(n,a->i,a->j,0,oshift,ia,ja);CHKERRQ(ierr);
2253b2fbd54SBarry Smith   } else if (oshift == 1) {
2263b2fbd54SBarry Smith     /* temporarily add 1 to i and j indices */
227435da068SBarry Smith     int nz = a->i[n];
2283b2fbd54SBarry Smith     for (i=0; i<nz; i++) a->j[i]++;
2293b2fbd54SBarry Smith     for (i=0; i<n+1; i++) a->i[i]++;
2303b2fbd54SBarry Smith     *ia = a->i; *ja = a->j;
2313b2fbd54SBarry Smith   } else {
2323b2fbd54SBarry Smith     *ia = a->i; *ja = a->j;
2333b2fbd54SBarry Smith   }
2343b2fbd54SBarry Smith 
2353a40ed3dSBarry Smith   PetscFunctionReturn(0);
2363b2fbd54SBarry Smith }
2373b2fbd54SBarry Smith 
2384a2ae208SSatish Balay #undef __FUNCT__
2394a2ae208SSatish Balay #define __FUNCT__ "MatRestoreRowIJ_SeqBAIJ"
2404e7234bfSBarry Smith static int MatRestoreRowIJ_SeqBAIJ(Mat A,int oshift,PetscTruth symmetric,int *nn,int *ia[],int *ja[],PetscTruth *done)
2413b2fbd54SBarry Smith {
2423b2fbd54SBarry Smith   Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)A->data;
243606d414cSSatish Balay   int         i,n = a->mbs,ierr;
2443b2fbd54SBarry Smith 
2453a40ed3dSBarry Smith   PetscFunctionBegin;
2463a40ed3dSBarry Smith   if (!ia) PetscFunctionReturn(0);
2473b2fbd54SBarry Smith   if (symmetric) {
248606d414cSSatish Balay     ierr = PetscFree(*ia);CHKERRQ(ierr);
249606d414cSSatish Balay     ierr = PetscFree(*ja);CHKERRQ(ierr);
250af5da2bfSBarry Smith   } else if (oshift == 1) {
251435da068SBarry Smith     int nz = a->i[n]-1;
2523b2fbd54SBarry Smith     for (i=0; i<nz; i++) a->j[i]--;
2533b2fbd54SBarry Smith     for (i=0; i<n+1; i++) a->i[i]--;
2543b2fbd54SBarry Smith   }
2553a40ed3dSBarry Smith   PetscFunctionReturn(0);
2563b2fbd54SBarry Smith }
2573b2fbd54SBarry Smith 
2584a2ae208SSatish Balay #undef __FUNCT__
2594a2ae208SSatish Balay #define __FUNCT__ "MatGetBlockSize_SeqBAIJ"
2602d61bbb3SSatish Balay int MatGetBlockSize_SeqBAIJ(Mat mat,int *bs)
2612d61bbb3SSatish Balay {
2622d61bbb3SSatish Balay   Mat_SeqBAIJ *baij = (Mat_SeqBAIJ*)mat->data;
2632d61bbb3SSatish Balay 
2642d61bbb3SSatish Balay   PetscFunctionBegin;
2652d61bbb3SSatish Balay   *bs = baij->bs;
2662d61bbb3SSatish Balay   PetscFunctionReturn(0);
2672d61bbb3SSatish Balay }
2682d61bbb3SSatish Balay 
2692d61bbb3SSatish Balay 
2704a2ae208SSatish Balay #undef __FUNCT__
2714a2ae208SSatish Balay #define __FUNCT__ "MatDestroy_SeqBAIJ"
272e1311b90SBarry Smith int MatDestroy_SeqBAIJ(Mat A)
2732d61bbb3SSatish Balay {
2742d61bbb3SSatish Balay   Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)A->data;
275e51c0b9cSSatish Balay   int         ierr;
2762d61bbb3SSatish Balay 
277433994e6SBarry Smith   PetscFunctionBegin;
278aa482453SBarry Smith #if defined(PETSC_USE_LOG)
279b0a32e0cSBarry Smith   PetscLogObjectState((PetscObject)A,"Rows=%d, Cols=%d, NZ=%d",A->m,A->n,a->nz);
2802d61bbb3SSatish Balay #endif
281606d414cSSatish Balay   ierr = PetscFree(a->a);CHKERRQ(ierr);
282606d414cSSatish Balay   if (!a->singlemalloc) {
283606d414cSSatish Balay     ierr = PetscFree(a->i);CHKERRQ(ierr);
284606d414cSSatish Balay     ierr = PetscFree(a->j);CHKERRQ(ierr);
285606d414cSSatish Balay   }
286c38d4ed2SBarry Smith   if (a->row) {
287c38d4ed2SBarry Smith     ierr = ISDestroy(a->row);CHKERRQ(ierr);
288c38d4ed2SBarry Smith   }
289c38d4ed2SBarry Smith   if (a->col) {
290c38d4ed2SBarry Smith     ierr = ISDestroy(a->col);CHKERRQ(ierr);
291c38d4ed2SBarry Smith   }
292606d414cSSatish Balay   if (a->diag) {ierr = PetscFree(a->diag);CHKERRQ(ierr);}
293606d414cSSatish Balay   if (a->ilen) {ierr = PetscFree(a->ilen);CHKERRQ(ierr);}
294606d414cSSatish Balay   if (a->imax) {ierr = PetscFree(a->imax);CHKERRQ(ierr);}
295606d414cSSatish Balay   if (a->solve_work) {ierr = PetscFree(a->solve_work);CHKERRQ(ierr);}
296606d414cSSatish Balay   if (a->mult_work) {ierr = PetscFree(a->mult_work);CHKERRQ(ierr);}
297e51c0b9cSSatish Balay   if (a->icol) {ierr = ISDestroy(a->icol);CHKERRQ(ierr);}
298606d414cSSatish Balay   if (a->saved_values) {ierr = PetscFree(a->saved_values);CHKERRQ(ierr);}
299563b5814SBarry Smith #if defined(PETSC_USE_MAT_SINGLE)
300563b5814SBarry Smith   if (a->setvaluescopy) {ierr = PetscFree(a->setvaluescopy);CHKERRQ(ierr);}
301563b5814SBarry Smith #endif
302c4319e64SHong Zhang   if (a->xtoy) {ierr = PetscFree(a->xtoy);CHKERRQ(ierr);}
303c4319e64SHong Zhang 
304606d414cSSatish Balay   ierr = PetscFree(a);CHKERRQ(ierr);
3052d61bbb3SSatish Balay   PetscFunctionReturn(0);
3062d61bbb3SSatish Balay }
3072d61bbb3SSatish Balay 
3084a2ae208SSatish Balay #undef __FUNCT__
3094a2ae208SSatish Balay #define __FUNCT__ "MatSetOption_SeqBAIJ"
3102d61bbb3SSatish Balay int MatSetOption_SeqBAIJ(Mat A,MatOption op)
3112d61bbb3SSatish Balay {
3122d61bbb3SSatish Balay   Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)A->data;
3132d61bbb3SSatish Balay 
3142d61bbb3SSatish Balay   PetscFunctionBegin;
315aa275fccSKris Buschelman   switch (op) {
316aa275fccSKris Buschelman   case MAT_ROW_ORIENTED:
317aa275fccSKris Buschelman     a->roworiented    = PETSC_TRUE;
318aa275fccSKris Buschelman     break;
319aa275fccSKris Buschelman   case MAT_COLUMN_ORIENTED:
320aa275fccSKris Buschelman     a->roworiented    = PETSC_FALSE;
321aa275fccSKris Buschelman     break;
322aa275fccSKris Buschelman   case MAT_COLUMNS_SORTED:
323aa275fccSKris Buschelman     a->sorted         = PETSC_TRUE;
324aa275fccSKris Buschelman     break;
325aa275fccSKris Buschelman   case MAT_COLUMNS_UNSORTED:
326aa275fccSKris Buschelman     a->sorted         = PETSC_FALSE;
327aa275fccSKris Buschelman     break;
328aa275fccSKris Buschelman   case MAT_KEEP_ZEROED_ROWS:
329aa275fccSKris Buschelman     a->keepzeroedrows = PETSC_TRUE;
330aa275fccSKris Buschelman     break;
331aa275fccSKris Buschelman   case MAT_NO_NEW_NONZERO_LOCATIONS:
332aa275fccSKris Buschelman     a->nonew          = 1;
333aa275fccSKris Buschelman     break;
334aa275fccSKris Buschelman   case MAT_NEW_NONZERO_LOCATION_ERR:
335aa275fccSKris Buschelman     a->nonew          = -1;
336aa275fccSKris Buschelman     break;
337aa275fccSKris Buschelman   case MAT_NEW_NONZERO_ALLOCATION_ERR:
338aa275fccSKris Buschelman     a->nonew          = -2;
339aa275fccSKris Buschelman     break;
340aa275fccSKris Buschelman   case MAT_YES_NEW_NONZERO_LOCATIONS:
341aa275fccSKris Buschelman     a->nonew          = 0;
342aa275fccSKris Buschelman     break;
343aa275fccSKris Buschelman   case MAT_ROWS_SORTED:
344aa275fccSKris Buschelman   case MAT_ROWS_UNSORTED:
345aa275fccSKris Buschelman   case MAT_YES_NEW_DIAGONALS:
346aa275fccSKris Buschelman   case MAT_IGNORE_OFF_PROC_ENTRIES:
347aa275fccSKris Buschelman   case MAT_USE_HASH_TABLE:
348b0a32e0cSBarry Smith     PetscLogInfo(A,"MatSetOption_SeqBAIJ:Option ignored\n");
349aa275fccSKris Buschelman     break;
350aa275fccSKris Buschelman   case MAT_NO_NEW_DIAGONALS:
35129bbc08cSBarry Smith     SETERRQ(PETSC_ERR_SUP,"MAT_NO_NEW_DIAGONALS");
35277e54ba9SKris Buschelman   case MAT_SYMMETRIC:
35377e54ba9SKris Buschelman   case MAT_STRUCTURALLY_SYMMETRIC:
3549a4540c5SBarry Smith   case MAT_NOT_SYMMETRIC:
3559a4540c5SBarry Smith   case MAT_NOT_STRUCTURALLY_SYMMETRIC:
3569a4540c5SBarry Smith   case MAT_HERMITIAN:
3579a4540c5SBarry Smith   case MAT_NOT_HERMITIAN:
3589a4540c5SBarry Smith   case MAT_SYMMETRY_ETERNAL:
3599a4540c5SBarry Smith   case MAT_NOT_SYMMETRY_ETERNAL:
36077e54ba9SKris Buschelman     break;
361aa275fccSKris Buschelman   default:
36229bbc08cSBarry Smith     SETERRQ(PETSC_ERR_SUP,"unknown option");
3632d61bbb3SSatish Balay   }
3642d61bbb3SSatish Balay   PetscFunctionReturn(0);
3652d61bbb3SSatish Balay }
3662d61bbb3SSatish Balay 
3674a2ae208SSatish Balay #undef __FUNCT__
3684a2ae208SSatish Balay #define __FUNCT__ "MatGetRow_SeqBAIJ"
36987828ca2SBarry Smith int MatGetRow_SeqBAIJ(Mat A,int row,int *nz,int **idx,PetscScalar **v)
3702d61bbb3SSatish Balay {
3712d61bbb3SSatish Balay   Mat_SeqBAIJ  *a = (Mat_SeqBAIJ*)A->data;
37282502324SSatish Balay   int          itmp,i,j,k,M,*ai,*aj,bs,bn,bp,*idx_i,bs2,ierr;
3733f1db9ecSBarry Smith   MatScalar    *aa,*aa_i;
37487828ca2SBarry Smith   PetscScalar  *v_i;
3752d61bbb3SSatish Balay 
3762d61bbb3SSatish Balay   PetscFunctionBegin;
3772d61bbb3SSatish Balay   bs  = a->bs;
3782d61bbb3SSatish Balay   ai  = a->i;
3792d61bbb3SSatish Balay   aj  = a->j;
3802d61bbb3SSatish Balay   aa  = a->a;
3812d61bbb3SSatish Balay   bs2 = a->bs2;
3822d61bbb3SSatish Balay 
383a45adfd6SMatthew Knepley   if (row < 0 || row >= A->m) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Row %d out of range", row);
3842d61bbb3SSatish Balay 
3852d61bbb3SSatish Balay   bn  = row/bs;   /* Block number */
3862d61bbb3SSatish Balay   bp  = row % bs; /* Block Position */
3872d61bbb3SSatish Balay   M   = ai[bn+1] - ai[bn];
3882d61bbb3SSatish Balay   *nz = bs*M;
3892d61bbb3SSatish Balay 
3902d61bbb3SSatish Balay   if (v) {
3912d61bbb3SSatish Balay     *v = 0;
3922d61bbb3SSatish Balay     if (*nz) {
39387828ca2SBarry Smith       ierr = PetscMalloc((*nz)*sizeof(PetscScalar),v);CHKERRQ(ierr);
3942d61bbb3SSatish Balay       for (i=0; i<M; i++) { /* for each block in the block row */
3952d61bbb3SSatish Balay         v_i  = *v + i*bs;
3962d61bbb3SSatish Balay         aa_i = aa + bs2*(ai[bn] + i);
3972d61bbb3SSatish Balay         for (j=bp,k=0; j<bs2; j+=bs,k++) {v_i[k] = aa_i[j];}
3982d61bbb3SSatish Balay       }
3992d61bbb3SSatish Balay     }
4002d61bbb3SSatish Balay   }
4012d61bbb3SSatish Balay 
4022d61bbb3SSatish Balay   if (idx) {
4032d61bbb3SSatish Balay     *idx = 0;
4042d61bbb3SSatish Balay     if (*nz) {
405b0a32e0cSBarry Smith       ierr = PetscMalloc((*nz)*sizeof(int),idx);CHKERRQ(ierr);
4062d61bbb3SSatish Balay       for (i=0; i<M; i++) { /* for each block in the block row */
4072d61bbb3SSatish Balay         idx_i = *idx + i*bs;
4082d61bbb3SSatish Balay         itmp  = bs*aj[ai[bn] + i];
4092d61bbb3SSatish Balay         for (j=0; j<bs; j++) {idx_i[j] = itmp++;}
4102d61bbb3SSatish Balay       }
4112d61bbb3SSatish Balay     }
4122d61bbb3SSatish Balay   }
4132d61bbb3SSatish Balay   PetscFunctionReturn(0);
4142d61bbb3SSatish Balay }
4152d61bbb3SSatish Balay 
4164a2ae208SSatish Balay #undef __FUNCT__
4174a2ae208SSatish Balay #define __FUNCT__ "MatRestoreRow_SeqBAIJ"
41887828ca2SBarry Smith int MatRestoreRow_SeqBAIJ(Mat A,int row,int *nz,int **idx,PetscScalar **v)
4192d61bbb3SSatish Balay {
420606d414cSSatish Balay   int ierr;
421606d414cSSatish Balay 
4222d61bbb3SSatish Balay   PetscFunctionBegin;
423606d414cSSatish Balay   if (idx) {if (*idx) {ierr = PetscFree(*idx);CHKERRQ(ierr);}}
424606d414cSSatish Balay   if (v)   {if (*v)   {ierr = PetscFree(*v);CHKERRQ(ierr);}}
4252d61bbb3SSatish Balay   PetscFunctionReturn(0);
4262d61bbb3SSatish Balay }
4272d61bbb3SSatish Balay 
4284a2ae208SSatish Balay #undef __FUNCT__
4294a2ae208SSatish Balay #define __FUNCT__ "MatTranspose_SeqBAIJ"
4302d61bbb3SSatish Balay int MatTranspose_SeqBAIJ(Mat A,Mat *B)
4312d61bbb3SSatish Balay {
4322d61bbb3SSatish Balay   Mat_SeqBAIJ *a=(Mat_SeqBAIJ *)A->data;
4332d61bbb3SSatish Balay   Mat         C;
4342d61bbb3SSatish Balay   int         i,j,k,ierr,*aj=a->j,*ai=a->i,bs=a->bs,mbs=a->mbs,nbs=a->nbs,len,*col;
435273d9f13SBarry Smith   int         *rows,*cols,bs2=a->bs2;
43687828ca2SBarry Smith   PetscScalar *array;
4372d61bbb3SSatish Balay 
4382d61bbb3SSatish Balay   PetscFunctionBegin;
43929bbc08cSBarry Smith   if (!B && mbs!=nbs) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Square matrix only for in-place");
440b0a32e0cSBarry Smith   ierr = PetscMalloc((1+nbs)*sizeof(int),&col);CHKERRQ(ierr);
441549d3d68SSatish Balay   ierr = PetscMemzero(col,(1+nbs)*sizeof(int));CHKERRQ(ierr);
4422d61bbb3SSatish Balay 
443375fe846SBarry Smith #if defined(PETSC_USE_MAT_SINGLE)
44487828ca2SBarry Smith   ierr = PetscMalloc(a->bs2*a->nz*sizeof(PetscScalar),&array);CHKERRQ(ierr);
44587828ca2SBarry Smith   for (i=0; i<a->bs2*a->nz; i++) array[i] = (PetscScalar)a->a[i];
446375fe846SBarry Smith #else
4473eda8832SBarry Smith   array = a->a;
448375fe846SBarry Smith #endif
449375fe846SBarry Smith 
4502d61bbb3SSatish Balay   for (i=0; i<ai[mbs]; i++) col[aj[i]] += 1;
451273d9f13SBarry Smith   ierr = MatCreateSeqBAIJ(A->comm,bs,A->n,A->m,PETSC_NULL,col,&C);CHKERRQ(ierr);
452606d414cSSatish Balay   ierr = PetscFree(col);CHKERRQ(ierr);
453b0a32e0cSBarry Smith   ierr = PetscMalloc(2*bs*sizeof(int),&rows);CHKERRQ(ierr);
4542d61bbb3SSatish Balay   cols = rows + bs;
4552d61bbb3SSatish Balay   for (i=0; i<mbs; i++) {
4562d61bbb3SSatish Balay     cols[0] = i*bs;
4572d61bbb3SSatish Balay     for (k=1; k<bs; k++) cols[k] = cols[k-1] + 1;
4582d61bbb3SSatish Balay     len = ai[i+1] - ai[i];
4592d61bbb3SSatish Balay     for (j=0; j<len; j++) {
4602d61bbb3SSatish Balay       rows[0] = (*aj++)*bs;
4612d61bbb3SSatish Balay       for (k=1; k<bs; k++) rows[k] = rows[k-1] + 1;
4622d61bbb3SSatish Balay       ierr = MatSetValues(C,bs,rows,bs,cols,array,INSERT_VALUES);CHKERRQ(ierr);
4632d61bbb3SSatish Balay       array += bs2;
4642d61bbb3SSatish Balay     }
4652d61bbb3SSatish Balay   }
466606d414cSSatish Balay   ierr = PetscFree(rows);CHKERRQ(ierr);
467375fe846SBarry Smith #if defined(PETSC_USE_MAT_SINGLE)
468375fe846SBarry Smith   ierr = PetscFree(array);
469375fe846SBarry Smith #endif
4702d61bbb3SSatish Balay 
4712d61bbb3SSatish Balay   ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
4722d61bbb3SSatish Balay   ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
4732d61bbb3SSatish Balay 
474c4992f7dSBarry Smith   if (B) {
4752d61bbb3SSatish Balay     *B = C;
4762d61bbb3SSatish Balay   } else {
477273d9f13SBarry Smith     ierr = MatHeaderCopy(A,C);CHKERRQ(ierr);
4782d61bbb3SSatish Balay   }
4792d61bbb3SSatish Balay   PetscFunctionReturn(0);
4802d61bbb3SSatish Balay }
4812d61bbb3SSatish Balay 
4824a2ae208SSatish Balay #undef __FUNCT__
4834a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqBAIJ_Binary"
484b0a32e0cSBarry Smith static int MatView_SeqBAIJ_Binary(Mat A,PetscViewer viewer)
4852593348eSBarry Smith {
486b6490206SBarry Smith   Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)A->data;
4879df24120SSatish Balay   int         i,fd,*col_lens,ierr,bs = a->bs,count,*jj,j,k,l,bs2=a->bs2;
48887828ca2SBarry Smith   PetscScalar *aa;
489ce6f0cecSBarry Smith   FILE        *file;
4902593348eSBarry Smith 
4913a40ed3dSBarry Smith   PetscFunctionBegin;
492b0a32e0cSBarry Smith   ierr        = PetscViewerBinaryGetDescriptor(viewer,&fd);CHKERRQ(ierr);
493b0a32e0cSBarry Smith   ierr        = PetscMalloc((4+A->m)*sizeof(int),&col_lens);CHKERRQ(ierr);
494552e946dSBarry Smith   col_lens[0] = MAT_FILE_COOKIE;
4953b2fbd54SBarry Smith 
496273d9f13SBarry Smith   col_lens[1] = A->m;
497273d9f13SBarry Smith   col_lens[2] = A->n;
4987e67e3f9SSatish Balay   col_lens[3] = a->nz*bs2;
4992593348eSBarry Smith 
5002593348eSBarry Smith   /* store lengths of each row and write (including header) to file */
501b6490206SBarry Smith   count = 0;
502b6490206SBarry Smith   for (i=0; i<a->mbs; i++) {
503b6490206SBarry Smith     for (j=0; j<bs; j++) {
504b6490206SBarry Smith       col_lens[4+count++] = bs*(a->i[i+1] - a->i[i]);
505b6490206SBarry Smith     }
5062593348eSBarry Smith   }
507273d9f13SBarry Smith   ierr = PetscBinaryWrite(fd,col_lens,4+A->m,PETSC_INT,1);CHKERRQ(ierr);
508606d414cSSatish Balay   ierr = PetscFree(col_lens);CHKERRQ(ierr);
5092593348eSBarry Smith 
5102593348eSBarry Smith   /* store column indices (zero start index) */
511b0a32e0cSBarry Smith   ierr  = PetscMalloc((a->nz+1)*bs2*sizeof(int),&jj);CHKERRQ(ierr);
512b6490206SBarry Smith   count = 0;
513b6490206SBarry Smith   for (i=0; i<a->mbs; i++) {
514b6490206SBarry Smith     for (j=0; j<bs; j++) {
515b6490206SBarry Smith       for (k=a->i[i]; k<a->i[i+1]; k++) {
516b6490206SBarry Smith         for (l=0; l<bs; l++) {
517b6490206SBarry Smith           jj[count++] = bs*a->j[k] + l;
5182593348eSBarry Smith         }
5192593348eSBarry Smith       }
520b6490206SBarry Smith     }
521b6490206SBarry Smith   }
5220752156aSBarry Smith   ierr = PetscBinaryWrite(fd,jj,bs2*a->nz,PETSC_INT,0);CHKERRQ(ierr);
523606d414cSSatish Balay   ierr = PetscFree(jj);CHKERRQ(ierr);
5242593348eSBarry Smith 
5252593348eSBarry Smith   /* store nonzero values */
52687828ca2SBarry Smith   ierr  = PetscMalloc((a->nz+1)*bs2*sizeof(PetscScalar),&aa);CHKERRQ(ierr);
527b6490206SBarry Smith   count = 0;
528b6490206SBarry Smith   for (i=0; i<a->mbs; i++) {
529b6490206SBarry Smith     for (j=0; j<bs; j++) {
530b6490206SBarry Smith       for (k=a->i[i]; k<a->i[i+1]; k++) {
531b6490206SBarry Smith         for (l=0; l<bs; l++) {
5327e67e3f9SSatish Balay           aa[count++] = a->a[bs2*k + l*bs + j];
533b6490206SBarry Smith         }
534b6490206SBarry Smith       }
535b6490206SBarry Smith     }
536b6490206SBarry Smith   }
5370752156aSBarry Smith   ierr = PetscBinaryWrite(fd,aa,bs2*a->nz,PETSC_SCALAR,0);CHKERRQ(ierr);
538606d414cSSatish Balay   ierr = PetscFree(aa);CHKERRQ(ierr);
539ce6f0cecSBarry Smith 
540b0a32e0cSBarry Smith   ierr = PetscViewerBinaryGetInfoPointer(viewer,&file);CHKERRQ(ierr);
541ce6f0cecSBarry Smith   if (file) {
542ce6f0cecSBarry Smith     fprintf(file,"-matload_block_size %d\n",a->bs);
543ce6f0cecSBarry Smith   }
5443a40ed3dSBarry Smith   PetscFunctionReturn(0);
5452593348eSBarry Smith }
5462593348eSBarry Smith 
5474a2ae208SSatish Balay #undef __FUNCT__
5484a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqBAIJ_ASCII"
549b0a32e0cSBarry Smith static int MatView_SeqBAIJ_ASCII(Mat A,PetscViewer viewer)
5502593348eSBarry Smith {
551b6490206SBarry Smith   Mat_SeqBAIJ       *a = (Mat_SeqBAIJ*)A->data;
552fb9695e5SSatish Balay   int               ierr,i,j,bs = a->bs,k,l,bs2=a->bs2;
553f3ef73ceSBarry Smith   PetscViewerFormat format;
5542593348eSBarry Smith 
5553a40ed3dSBarry Smith   PetscFunctionBegin;
556b0a32e0cSBarry Smith   ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr);
557456192e2SBarry Smith   if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) {
558b0a32e0cSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  block size is %d\n",bs);CHKERRQ(ierr);
559fb9695e5SSatish Balay   } else if (format == PETSC_VIEWER_ASCII_MATLAB) {
560bcd9e38bSBarry Smith     Mat aij;
561bcd9e38bSBarry Smith     ierr = MatConvert(A,MATSEQAIJ,&aij);CHKERRQ(ierr);
562bcd9e38bSBarry Smith     ierr = MatView(aij,viewer);CHKERRQ(ierr);
563bcd9e38bSBarry Smith     ierr = MatDestroy(aij);CHKERRQ(ierr);
56404929863SHong Zhang   } else if (format == PETSC_VIEWER_ASCII_FACTOR_INFO) {
56504929863SHong Zhang      PetscFunctionReturn(0);
566fb9695e5SSatish Balay   } else if (format == PETSC_VIEWER_ASCII_COMMON) {
567b0a32e0cSBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_NO);CHKERRQ(ierr);
56844cd7ae7SLois Curfman McInnes     for (i=0; i<a->mbs; i++) {
56944cd7ae7SLois Curfman McInnes       for (j=0; j<bs; j++) {
570b0a32e0cSBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"row %d:",i*bs+j);CHKERRQ(ierr);
57144cd7ae7SLois Curfman McInnes         for (k=a->i[i]; k<a->i[i+1]; k++) {
57244cd7ae7SLois Curfman McInnes           for (l=0; l<bs; l++) {
573aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
5740e6d2581SBarry Smith             if (PetscImaginaryPart(a->a[bs2*k + l*bs + j]) > 0.0 && PetscRealPart(a->a[bs2*k + l*bs + j]) != 0.0) {
57562b941d6SBarry Smith               ierr = PetscViewerASCIIPrintf(viewer," (%d, %g + %gi) ",bs*a->j[k]+l,
5760e6d2581SBarry Smith                       PetscRealPart(a->a[bs2*k + l*bs + j]),PetscImaginaryPart(a->a[bs2*k + l*bs + j]));CHKERRQ(ierr);
5770e6d2581SBarry Smith             } else if (PetscImaginaryPart(a->a[bs2*k + l*bs + j]) < 0.0 && PetscRealPart(a->a[bs2*k + l*bs + j]) != 0.0) {
57862b941d6SBarry Smith               ierr = PetscViewerASCIIPrintf(viewer," (%d, %g - %gi) ",bs*a->j[k]+l,
5790e6d2581SBarry Smith                       PetscRealPart(a->a[bs2*k + l*bs + j]),-PetscImaginaryPart(a->a[bs2*k + l*bs + j]));CHKERRQ(ierr);
5800e6d2581SBarry Smith             } else if (PetscRealPart(a->a[bs2*k + l*bs + j]) != 0.0) {
58162b941d6SBarry Smith               ierr = PetscViewerASCIIPrintf(viewer," (%d, %g) ",bs*a->j[k]+l,PetscRealPart(a->a[bs2*k + l*bs + j]));CHKERRQ(ierr);
5820ef38995SBarry Smith             }
58344cd7ae7SLois Curfman McInnes #else
5840ef38995SBarry Smith             if (a->a[bs2*k + l*bs + j] != 0.0) {
58562b941d6SBarry Smith               ierr = PetscViewerASCIIPrintf(viewer," (%d, %g) ",bs*a->j[k]+l,a->a[bs2*k + l*bs + j]);CHKERRQ(ierr);
5860ef38995SBarry Smith             }
58744cd7ae7SLois Curfman McInnes #endif
58844cd7ae7SLois Curfman McInnes           }
58944cd7ae7SLois Curfman McInnes         }
590b0a32e0cSBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
59144cd7ae7SLois Curfman McInnes       }
59244cd7ae7SLois Curfman McInnes     }
593b0a32e0cSBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_YES);CHKERRQ(ierr);
5940ef38995SBarry Smith   } else {
595b0a32e0cSBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_NO);CHKERRQ(ierr);
596b6490206SBarry Smith     for (i=0; i<a->mbs; i++) {
597b6490206SBarry Smith       for (j=0; j<bs; j++) {
598b0a32e0cSBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"row %d:",i*bs+j);CHKERRQ(ierr);
599b6490206SBarry Smith         for (k=a->i[i]; k<a->i[i+1]; k++) {
600b6490206SBarry Smith           for (l=0; l<bs; l++) {
601aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
6020e6d2581SBarry Smith             if (PetscImaginaryPart(a->a[bs2*k + l*bs + j]) > 0.0) {
60362b941d6SBarry Smith               ierr = PetscViewerASCIIPrintf(viewer," (%d, %g + %g i) ",bs*a->j[k]+l,
6040e6d2581SBarry Smith                 PetscRealPart(a->a[bs2*k + l*bs + j]),PetscImaginaryPart(a->a[bs2*k + l*bs + j]));CHKERRQ(ierr);
6050e6d2581SBarry Smith             } else if (PetscImaginaryPart(a->a[bs2*k + l*bs + j]) < 0.0) {
60662b941d6SBarry Smith               ierr = PetscViewerASCIIPrintf(viewer," (%d, %g - %g i) ",bs*a->j[k]+l,
6070e6d2581SBarry Smith                 PetscRealPart(a->a[bs2*k + l*bs + j]),-PetscImaginaryPart(a->a[bs2*k + l*bs + j]));CHKERRQ(ierr);
6080ef38995SBarry Smith             } else {
60962b941d6SBarry Smith               ierr = PetscViewerASCIIPrintf(viewer," (%d, %g) ",bs*a->j[k]+l,PetscRealPart(a->a[bs2*k + l*bs + j]));CHKERRQ(ierr);
61088685aaeSLois Curfman McInnes             }
61188685aaeSLois Curfman McInnes #else
61262b941d6SBarry Smith             ierr = PetscViewerASCIIPrintf(viewer," (%d, %g) ",bs*a->j[k]+l,a->a[bs2*k + l*bs + j]);CHKERRQ(ierr);
61388685aaeSLois Curfman McInnes #endif
6142593348eSBarry Smith           }
6152593348eSBarry Smith         }
616b0a32e0cSBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
6172593348eSBarry Smith       }
6182593348eSBarry Smith     }
619b0a32e0cSBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_YES);CHKERRQ(ierr);
620b6490206SBarry Smith   }
621b0a32e0cSBarry Smith   ierr = PetscViewerFlush(viewer);CHKERRQ(ierr);
6223a40ed3dSBarry Smith   PetscFunctionReturn(0);
6232593348eSBarry Smith }
6242593348eSBarry Smith 
6254a2ae208SSatish Balay #undef __FUNCT__
6264a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqBAIJ_Draw_Zoom"
627b0a32e0cSBarry Smith static int MatView_SeqBAIJ_Draw_Zoom(PetscDraw draw,void *Aa)
6283270192aSSatish Balay {
62977ed5343SBarry Smith   Mat          A = (Mat) Aa;
6303270192aSSatish Balay   Mat_SeqBAIJ  *a=(Mat_SeqBAIJ*)A->data;
631b65db4caSBarry Smith   int          row,ierr,i,j,k,l,mbs=a->mbs,color,bs=a->bs,bs2=a->bs2;
6320e6d2581SBarry Smith   PetscReal    xl,yl,xr,yr,x_l,x_r,y_l,y_r;
6333f1db9ecSBarry Smith   MatScalar    *aa;
634b0a32e0cSBarry Smith   PetscViewer  viewer;
6353270192aSSatish Balay 
6363a40ed3dSBarry Smith   PetscFunctionBegin;
6373270192aSSatish Balay 
638b65db4caSBarry Smith   /* still need to add support for contour plot of nonzeros; see MatView_SeqAIJ_Draw_Zoom()*/
63977ed5343SBarry Smith   ierr = PetscObjectQuery((PetscObject)A,"Zoomviewer",(PetscObject*)&viewer);CHKERRQ(ierr);
64077ed5343SBarry Smith 
641b0a32e0cSBarry Smith   ierr = PetscDrawGetCoordinates(draw,&xl,&yl,&xr,&yr);CHKERRQ(ierr);
64277ed5343SBarry Smith 
6433270192aSSatish Balay   /* loop over matrix elements drawing boxes */
644b0a32e0cSBarry Smith   color = PETSC_DRAW_BLUE;
6453270192aSSatish Balay   for (i=0,row=0; i<mbs; i++,row+=bs) {
6463270192aSSatish Balay     for (j=a->i[i]; j<a->i[i+1]; j++) {
647273d9f13SBarry Smith       y_l = A->m - row - 1.0; y_r = y_l + 1.0;
6483270192aSSatish Balay       x_l = a->j[j]*bs; x_r = x_l + 1.0;
6493270192aSSatish Balay       aa = a->a + j*bs2;
6503270192aSSatish Balay       for (k=0; k<bs; k++) {
6513270192aSSatish Balay         for (l=0; l<bs; l++) {
6520e6d2581SBarry Smith           if (PetscRealPart(*aa++) >=  0.) continue;
653b0a32e0cSBarry Smith           ierr = PetscDrawRectangle(draw,x_l+k,y_l-l,x_r+k,y_r-l,color,color,color,color);CHKERRQ(ierr);
6543270192aSSatish Balay         }
6553270192aSSatish Balay       }
6563270192aSSatish Balay     }
6573270192aSSatish Balay   }
658b0a32e0cSBarry Smith   color = PETSC_DRAW_CYAN;
6593270192aSSatish Balay   for (i=0,row=0; i<mbs; i++,row+=bs) {
6603270192aSSatish Balay     for (j=a->i[i]; j<a->i[i+1]; j++) {
661273d9f13SBarry Smith       y_l = A->m - row - 1.0; y_r = y_l + 1.0;
6623270192aSSatish Balay       x_l = a->j[j]*bs; x_r = x_l + 1.0;
6633270192aSSatish Balay       aa = a->a + j*bs2;
6643270192aSSatish Balay       for (k=0; k<bs; k++) {
6653270192aSSatish Balay         for (l=0; l<bs; l++) {
6660e6d2581SBarry Smith           if (PetscRealPart(*aa++) != 0.) continue;
667b0a32e0cSBarry Smith           ierr = PetscDrawRectangle(draw,x_l+k,y_l-l,x_r+k,y_r-l,color,color,color,color);CHKERRQ(ierr);
6683270192aSSatish Balay         }
6693270192aSSatish Balay       }
6703270192aSSatish Balay     }
6713270192aSSatish Balay   }
6723270192aSSatish Balay 
673b0a32e0cSBarry Smith   color = PETSC_DRAW_RED;
6743270192aSSatish Balay   for (i=0,row=0; i<mbs; i++,row+=bs) {
6753270192aSSatish Balay     for (j=a->i[i]; j<a->i[i+1]; j++) {
676273d9f13SBarry Smith       y_l = A->m - row - 1.0; y_r = y_l + 1.0;
6773270192aSSatish Balay       x_l = a->j[j]*bs; x_r = x_l + 1.0;
6783270192aSSatish Balay       aa = a->a + j*bs2;
6793270192aSSatish Balay       for (k=0; k<bs; k++) {
6803270192aSSatish Balay         for (l=0; l<bs; l++) {
6810e6d2581SBarry Smith           if (PetscRealPart(*aa++) <= 0.) continue;
682b0a32e0cSBarry Smith           ierr = PetscDrawRectangle(draw,x_l+k,y_l-l,x_r+k,y_r-l,color,color,color,color);CHKERRQ(ierr);
6833270192aSSatish Balay         }
6843270192aSSatish Balay       }
6853270192aSSatish Balay     }
6863270192aSSatish Balay   }
68777ed5343SBarry Smith   PetscFunctionReturn(0);
68877ed5343SBarry Smith }
6893270192aSSatish Balay 
6904a2ae208SSatish Balay #undef __FUNCT__
6914a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqBAIJ_Draw"
692b0a32e0cSBarry Smith static int MatView_SeqBAIJ_Draw(Mat A,PetscViewer viewer)
69377ed5343SBarry Smith {
6947dce120fSSatish Balay   int          ierr;
6950e6d2581SBarry Smith   PetscReal    xl,yl,xr,yr,w,h;
696b0a32e0cSBarry Smith   PetscDraw    draw;
69777ed5343SBarry Smith   PetscTruth   isnull;
6983270192aSSatish Balay 
69977ed5343SBarry Smith   PetscFunctionBegin;
70077ed5343SBarry Smith 
701b0a32e0cSBarry Smith   ierr = PetscViewerDrawGetDraw(viewer,0,&draw);CHKERRQ(ierr);
702b0a32e0cSBarry Smith   ierr = PetscDrawIsNull(draw,&isnull);CHKERRQ(ierr); if (isnull) PetscFunctionReturn(0);
70377ed5343SBarry Smith 
70477ed5343SBarry Smith   ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",(PetscObject)viewer);CHKERRQ(ierr);
705273d9f13SBarry Smith   xr  = A->n; yr = A->m; h = yr/10.0; w = xr/10.0;
70677ed5343SBarry Smith   xr += w;    yr += h;  xl = -w;     yl = -h;
707b0a32e0cSBarry Smith   ierr = PetscDrawSetCoordinates(draw,xl,yl,xr,yr);CHKERRQ(ierr);
708b0a32e0cSBarry Smith   ierr = PetscDrawZoom(draw,MatView_SeqBAIJ_Draw_Zoom,A);CHKERRQ(ierr);
70977ed5343SBarry Smith   ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",PETSC_NULL);CHKERRQ(ierr);
7103a40ed3dSBarry Smith   PetscFunctionReturn(0);
7113270192aSSatish Balay }
7123270192aSSatish Balay 
7134a2ae208SSatish Balay #undef __FUNCT__
7144a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqBAIJ"
715b0a32e0cSBarry Smith int MatView_SeqBAIJ(Mat A,PetscViewer viewer)
7162593348eSBarry Smith {
71719bcc07fSBarry Smith   int        ierr;
718a5e6ed63SBarry Smith   PetscTruth isascii,isbinary,isdraw;
7192593348eSBarry Smith 
7203a40ed3dSBarry Smith   PetscFunctionBegin;
721b0a32e0cSBarry Smith   ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&isascii);CHKERRQ(ierr);
722fb9695e5SSatish Balay   ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_BINARY,&isbinary);CHKERRQ(ierr);
723fb9695e5SSatish Balay   ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_DRAW,&isdraw);CHKERRQ(ierr);
724a5e6ed63SBarry Smith   if (isascii){
7253a40ed3dSBarry Smith     ierr = MatView_SeqBAIJ_ASCII(A,viewer);CHKERRQ(ierr);
7260f5bd95cSBarry Smith   } else if (isbinary) {
7273a40ed3dSBarry Smith     ierr = MatView_SeqBAIJ_Binary(A,viewer);CHKERRQ(ierr);
7280f5bd95cSBarry Smith   } else if (isdraw) {
7293a40ed3dSBarry Smith     ierr = MatView_SeqBAIJ_Draw(A,viewer);CHKERRQ(ierr);
7305cd90555SBarry Smith   } else {
731a5e6ed63SBarry Smith     Mat B;
732a5e6ed63SBarry Smith     ierr = MatConvert(A,MATSEQAIJ,&B);CHKERRQ(ierr);
733a5e6ed63SBarry Smith     ierr = MatView(B,viewer);CHKERRQ(ierr);
734a5e6ed63SBarry Smith     ierr = MatDestroy(B);CHKERRQ(ierr);
7352593348eSBarry Smith   }
7363a40ed3dSBarry Smith   PetscFunctionReturn(0);
7372593348eSBarry Smith }
738b6490206SBarry Smith 
739cd0e1443SSatish Balay 
7404a2ae208SSatish Balay #undef __FUNCT__
7414a2ae208SSatish Balay #define __FUNCT__ "MatGetValues_SeqBAIJ"
742f15d580aSBarry Smith int MatGetValues_SeqBAIJ(Mat A,int m,const int im[],int n,const int in[],PetscScalar v[])
743cd0e1443SSatish Balay {
744cd0e1443SSatish Balay   Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)A->data;
7452d61bbb3SSatish Balay   int        *rp,k,low,high,t,row,nrow,i,col,l,*aj = a->j;
7462d61bbb3SSatish Balay   int        *ai = a->i,*ailen = a->ilen;
7472d61bbb3SSatish Balay   int        brow,bcol,ridx,cidx,bs=a->bs,bs2=a->bs2;
7483f1db9ecSBarry Smith   MatScalar  *ap,*aa = a->a,zero = 0.0;
749cd0e1443SSatish Balay 
7503a40ed3dSBarry Smith   PetscFunctionBegin;
7512d61bbb3SSatish Balay   for (k=0; k<m; k++) { /* loop over rows */
752cd0e1443SSatish Balay     row  = im[k]; brow = row/bs;
75329bbc08cSBarry Smith     if (row < 0) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Negative row");
754a45adfd6SMatthew Knepley     if (row >= A->m) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Row %d too large", row);
7552d61bbb3SSatish Balay     rp   = aj + ai[brow] ; ap = aa + bs2*ai[brow] ;
7562c3acbe9SBarry Smith     nrow = ailen[brow];
7572d61bbb3SSatish Balay     for (l=0; l<n; l++) { /* loop over columns */
75829bbc08cSBarry Smith       if (in[l] < 0) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Negative column");
759a45adfd6SMatthew Knepley       if (in[l] >= A->n) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Column %d too large", in[l]);
7602d61bbb3SSatish Balay       col  = in[l] ;
7612d61bbb3SSatish Balay       bcol = col/bs;
7622d61bbb3SSatish Balay       cidx = col%bs;
7632d61bbb3SSatish Balay       ridx = row%bs;
7642d61bbb3SSatish Balay       high = nrow;
7652d61bbb3SSatish Balay       low  = 0; /* assume unsorted */
7662d61bbb3SSatish Balay       while (high-low > 5) {
767cd0e1443SSatish Balay         t = (low+high)/2;
768cd0e1443SSatish Balay         if (rp[t] > bcol) high = t;
769cd0e1443SSatish Balay         else             low  = t;
770cd0e1443SSatish Balay       }
771cd0e1443SSatish Balay       for (i=low; i<high; i++) {
772cd0e1443SSatish Balay         if (rp[i] > bcol) break;
773cd0e1443SSatish Balay         if (rp[i] == bcol) {
7742d61bbb3SSatish Balay           *v++ = ap[bs2*i+bs*cidx+ridx];
7752d61bbb3SSatish Balay           goto finished;
776cd0e1443SSatish Balay         }
777cd0e1443SSatish Balay       }
7782d61bbb3SSatish Balay       *v++ = zero;
7792d61bbb3SSatish Balay       finished:;
780cd0e1443SSatish Balay     }
781cd0e1443SSatish Balay   }
7823a40ed3dSBarry Smith   PetscFunctionReturn(0);
783cd0e1443SSatish Balay }
784cd0e1443SSatish Balay 
78595d5f7c2SBarry Smith #if defined(PETSC_USE_MAT_SINGLE)
7864a2ae208SSatish Balay #undef __FUNCT__
7874a2ae208SSatish Balay #define __FUNCT__ "MatSetValuesBlocked_SeqBAIJ"
788f15d580aSBarry Smith int MatSetValuesBlocked_SeqBAIJ(Mat mat,int m,const int im[],int n,const int in[],const PetscScalar v[],InsertMode addv)
78995d5f7c2SBarry Smith {
790563b5814SBarry Smith   Mat_SeqBAIJ *b = (Mat_SeqBAIJ*)mat->data;
791563b5814SBarry Smith   int         ierr,i,N = m*n*b->bs2;
792563b5814SBarry Smith   MatScalar   *vsingle;
79395d5f7c2SBarry Smith 
79495d5f7c2SBarry Smith   PetscFunctionBegin;
795563b5814SBarry Smith   if (N > b->setvalueslen) {
796563b5814SBarry Smith     if (b->setvaluescopy) {ierr = PetscFree(b->setvaluescopy);CHKERRQ(ierr);}
797b0a32e0cSBarry Smith     ierr = PetscMalloc(N*sizeof(MatScalar),&b->setvaluescopy);CHKERRQ(ierr);
798563b5814SBarry Smith     b->setvalueslen  = N;
799563b5814SBarry Smith   }
800563b5814SBarry Smith   vsingle = b->setvaluescopy;
80195d5f7c2SBarry Smith   for (i=0; i<N; i++) {
80295d5f7c2SBarry Smith     vsingle[i] = v[i];
80395d5f7c2SBarry Smith   }
80495d5f7c2SBarry Smith   ierr = MatSetValuesBlocked_SeqBAIJ_MatScalar(mat,m,im,n,in,vsingle,addv);CHKERRQ(ierr);
80595d5f7c2SBarry Smith   PetscFunctionReturn(0);
80695d5f7c2SBarry Smith }
80795d5f7c2SBarry Smith #endif
80895d5f7c2SBarry Smith 
8092d61bbb3SSatish Balay 
8104a2ae208SSatish Balay #undef __FUNCT__
8114a2ae208SSatish Balay #define __FUNCT__ "MatSetValuesBlocked_SeqBAIJ"
812f15d580aSBarry Smith int MatSetValuesBlocked_SeqBAIJ_MatScalar(Mat A,int m,const int im[],int n,const int in[],const MatScalar v[],InsertMode is)
81392c4ed94SBarry Smith {
81492c4ed94SBarry Smith   Mat_SeqBAIJ       *a = (Mat_SeqBAIJ*)A->data;
8158a84c255SSatish Balay   int               *rp,k,low,high,t,ii,jj,row,nrow,i,col,l,rmax,N,sorted=a->sorted;
816273d9f13SBarry Smith   int               *imax=a->imax,*ai=a->i,*ailen=a->ilen;
817549d3d68SSatish Balay   int               *aj=a->j,nonew=a->nonew,bs2=a->bs2,bs=a->bs,stepval,ierr;
818273d9f13SBarry Smith   PetscTruth        roworiented=a->roworiented;
819f15d580aSBarry Smith   const MatScalar   *value = v;
820f15d580aSBarry Smith   MatScalar         *ap,*aa = a->a,*bap;
82192c4ed94SBarry Smith 
8223a40ed3dSBarry Smith   PetscFunctionBegin;
8230e324ae4SSatish Balay   if (roworiented) {
8240e324ae4SSatish Balay     stepval = (n-1)*bs;
8250e324ae4SSatish Balay   } else {
8260e324ae4SSatish Balay     stepval = (m-1)*bs;
8270e324ae4SSatish Balay   }
82892c4ed94SBarry Smith   for (k=0; k<m; k++) { /* loop over added rows */
82992c4ed94SBarry Smith     row  = im[k];
8305ef9f2a5SBarry Smith     if (row < 0) continue;
831aa482453SBarry Smith #if defined(PETSC_USE_BOPT_g)
832590ac198SBarry Smith     if (row >= a->mbs) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"Row too large: row %d max %d",row,a->mbs-1);
83392c4ed94SBarry Smith #endif
83492c4ed94SBarry Smith     rp   = aj + ai[row];
83592c4ed94SBarry Smith     ap   = aa + bs2*ai[row];
83692c4ed94SBarry Smith     rmax = imax[row];
83792c4ed94SBarry Smith     nrow = ailen[row];
83892c4ed94SBarry Smith     low  = 0;
83992c4ed94SBarry Smith     for (l=0; l<n; l++) { /* loop over added columns */
8405ef9f2a5SBarry Smith       if (in[l] < 0) continue;
841aa482453SBarry Smith #if defined(PETSC_USE_BOPT_g)
842590ac198SBarry Smith       if (in[l] >= a->nbs) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"Column too large: col %d max %d",in[l],a->nbs-1);
84392c4ed94SBarry Smith #endif
84492c4ed94SBarry Smith       col = in[l];
84592c4ed94SBarry Smith       if (roworiented) {
8460e324ae4SSatish Balay         value = v + k*(stepval+bs)*bs + l*bs;
8470e324ae4SSatish Balay       } else {
8480e324ae4SSatish Balay         value = v + l*(stepval+bs)*bs + k*bs;
84992c4ed94SBarry Smith       }
85092c4ed94SBarry Smith       if (!sorted) low = 0; high = nrow;
85192c4ed94SBarry Smith       while (high-low > 7) {
85292c4ed94SBarry Smith         t = (low+high)/2;
85392c4ed94SBarry Smith         if (rp[t] > col) high = t;
85492c4ed94SBarry Smith         else             low  = t;
85592c4ed94SBarry Smith       }
85692c4ed94SBarry Smith       for (i=low; i<high; i++) {
85792c4ed94SBarry Smith         if (rp[i] > col) break;
85892c4ed94SBarry Smith         if (rp[i] == col) {
8598a84c255SSatish Balay           bap  = ap +  bs2*i;
8600e324ae4SSatish Balay           if (roworiented) {
8618a84c255SSatish Balay             if (is == ADD_VALUES) {
862dd9472c6SBarry Smith               for (ii=0; ii<bs; ii++,value+=stepval) {
863dd9472c6SBarry Smith                 for (jj=ii; jj<bs2; jj+=bs) {
8648a84c255SSatish Balay                   bap[jj] += *value++;
865dd9472c6SBarry Smith                 }
866dd9472c6SBarry Smith               }
8670e324ae4SSatish Balay             } else {
868dd9472c6SBarry Smith               for (ii=0; ii<bs; ii++,value+=stepval) {
869dd9472c6SBarry Smith                 for (jj=ii; jj<bs2; jj+=bs) {
8700e324ae4SSatish Balay                   bap[jj] = *value++;
8718a84c255SSatish Balay                 }
872dd9472c6SBarry Smith               }
873dd9472c6SBarry Smith             }
8740e324ae4SSatish Balay           } else {
8750e324ae4SSatish Balay             if (is == ADD_VALUES) {
876dd9472c6SBarry Smith               for (ii=0; ii<bs; ii++,value+=stepval) {
877dd9472c6SBarry Smith                 for (jj=0; jj<bs; jj++) {
8780e324ae4SSatish Balay                   *bap++ += *value++;
879dd9472c6SBarry Smith                 }
880dd9472c6SBarry Smith               }
8810e324ae4SSatish Balay             } else {
882dd9472c6SBarry Smith               for (ii=0; ii<bs; ii++,value+=stepval) {
883dd9472c6SBarry Smith                 for (jj=0; jj<bs; jj++) {
8840e324ae4SSatish Balay                   *bap++  = *value++;
8850e324ae4SSatish Balay                 }
8868a84c255SSatish Balay               }
887dd9472c6SBarry Smith             }
888dd9472c6SBarry Smith           }
889f1241b54SBarry Smith           goto noinsert2;
89092c4ed94SBarry Smith         }
89192c4ed94SBarry Smith       }
89289280ab3SLois Curfman McInnes       if (nonew == 1) goto noinsert2;
893a45adfd6SMatthew Knepley       else if (nonew == -1) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"Inserting a new nonzero (%d, %d) in the matrix", row, col);
89492c4ed94SBarry Smith       if (nrow >= rmax) {
89592c4ed94SBarry Smith         /* there is no extra room in row, therefore enlarge */
89692c4ed94SBarry Smith         int       new_nz = ai[a->mbs] + CHUNKSIZE,len,*new_i,*new_j;
8973f1db9ecSBarry Smith         MatScalar *new_a;
89892c4ed94SBarry Smith 
899a45adfd6SMatthew Knepley         if (nonew == -2) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"Inserting a new nonzero (%d, %d) in the matrix", row, col);
90089280ab3SLois Curfman McInnes 
90192c4ed94SBarry Smith         /* malloc new storage space */
9023f1db9ecSBarry Smith         len     = new_nz*(sizeof(int)+bs2*sizeof(MatScalar))+(a->mbs+1)*sizeof(int);
903b0a32e0cSBarry Smith 	ierr    = PetscMalloc(len,&new_a);CHKERRQ(ierr);
90492c4ed94SBarry Smith         new_j   = (int*)(new_a + bs2*new_nz);
90592c4ed94SBarry Smith         new_i   = new_j + new_nz;
90692c4ed94SBarry Smith 
90792c4ed94SBarry Smith         /* copy over old data into new slots */
90892c4ed94SBarry Smith         for (ii=0; ii<row+1; ii++) {new_i[ii] = ai[ii];}
90992c4ed94SBarry Smith         for (ii=row+1; ii<a->mbs+1; ii++) {new_i[ii] = ai[ii]+CHUNKSIZE;}
910549d3d68SSatish Balay         ierr = PetscMemcpy(new_j,aj,(ai[row]+nrow)*sizeof(int));CHKERRQ(ierr);
91192c4ed94SBarry Smith         len  = (new_nz - CHUNKSIZE - ai[row] - nrow);
912549d3d68SSatish Balay         ierr = PetscMemcpy(new_j+ai[row]+nrow+CHUNKSIZE,aj+ai[row]+nrow,len*sizeof(int));CHKERRQ(ierr);
913549d3d68SSatish Balay         ierr = PetscMemcpy(new_a,aa,(ai[row]+nrow)*bs2*sizeof(MatScalar));CHKERRQ(ierr);
914549d3d68SSatish Balay         ierr = PetscMemzero(new_a+bs2*(ai[row]+nrow),bs2*CHUNKSIZE*sizeof(MatScalar));CHKERRQ(ierr);
915549d3d68SSatish Balay         ierr = PetscMemcpy(new_a+bs2*(ai[row]+nrow+CHUNKSIZE),aa+bs2*(ai[row]+nrow),bs2*len*sizeof(MatScalar));CHKERRQ(ierr);
91692c4ed94SBarry Smith         /* free up old matrix storage */
917606d414cSSatish Balay         ierr = PetscFree(a->a);CHKERRQ(ierr);
918606d414cSSatish Balay         if (!a->singlemalloc) {
919606d414cSSatish Balay           ierr = PetscFree(a->i);CHKERRQ(ierr);
920606d414cSSatish Balay           ierr = PetscFree(a->j);CHKERRQ(ierr);
921606d414cSSatish Balay         }
92292c4ed94SBarry Smith         aa = a->a = new_a; ai = a->i = new_i; aj = a->j = new_j;
923c4992f7dSBarry Smith         a->singlemalloc = PETSC_TRUE;
92492c4ed94SBarry Smith 
92592c4ed94SBarry Smith         rp   = aj + ai[row]; ap = aa + bs2*ai[row];
92692c4ed94SBarry Smith         rmax = imax[row] = imax[row] + CHUNKSIZE;
927b0a32e0cSBarry Smith         PetscLogObjectMemory(A,CHUNKSIZE*(sizeof(int) + bs2*sizeof(MatScalar)));
92892c4ed94SBarry Smith         a->maxnz += bs2*CHUNKSIZE;
92992c4ed94SBarry Smith         a->reallocs++;
93092c4ed94SBarry Smith         a->nz++;
93192c4ed94SBarry Smith       }
93292c4ed94SBarry Smith       N = nrow++ - 1;
93392c4ed94SBarry Smith       /* shift up all the later entries in this row */
93492c4ed94SBarry Smith       for (ii=N; ii>=i; ii--) {
93592c4ed94SBarry Smith         rp[ii+1] = rp[ii];
936549d3d68SSatish Balay         ierr = PetscMemcpy(ap+bs2*(ii+1),ap+bs2*(ii),bs2*sizeof(MatScalar));CHKERRQ(ierr);
93792c4ed94SBarry Smith       }
938549d3d68SSatish Balay       if (N >= i) {
939549d3d68SSatish Balay         ierr = PetscMemzero(ap+bs2*i,bs2*sizeof(MatScalar));CHKERRQ(ierr);
940549d3d68SSatish Balay       }
94192c4ed94SBarry Smith       rp[i] = col;
9428a84c255SSatish Balay       bap   = ap +  bs2*i;
9430e324ae4SSatish Balay       if (roworiented) {
944dd9472c6SBarry Smith         for (ii=0; ii<bs; ii++,value+=stepval) {
945dd9472c6SBarry Smith           for (jj=ii; jj<bs2; jj+=bs) {
9460e324ae4SSatish Balay             bap[jj] = *value++;
947dd9472c6SBarry Smith           }
948dd9472c6SBarry Smith         }
9490e324ae4SSatish Balay       } else {
950dd9472c6SBarry Smith         for (ii=0; ii<bs; ii++,value+=stepval) {
951dd9472c6SBarry Smith           for (jj=0; jj<bs; jj++) {
9520e324ae4SSatish Balay             *bap++  = *value++;
9530e324ae4SSatish Balay           }
954dd9472c6SBarry Smith         }
955dd9472c6SBarry Smith       }
956f1241b54SBarry Smith       noinsert2:;
95792c4ed94SBarry Smith       low = i;
95892c4ed94SBarry Smith     }
95992c4ed94SBarry Smith     ailen[row] = nrow;
96092c4ed94SBarry Smith   }
9613a40ed3dSBarry Smith   PetscFunctionReturn(0);
96292c4ed94SBarry Smith }
96392c4ed94SBarry Smith 
9644a2ae208SSatish Balay #undef __FUNCT__
9654a2ae208SSatish Balay #define __FUNCT__ "MatAssemblyEnd_SeqBAIJ"
9668f6be9afSLois Curfman McInnes int MatAssemblyEnd_SeqBAIJ(Mat A,MatAssemblyType mode)
967584200bdSSatish Balay {
968584200bdSSatish Balay   Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)A->data;
969584200bdSSatish Balay   int        fshift = 0,i,j,*ai = a->i,*aj = a->j,*imax = a->imax;
970273d9f13SBarry Smith   int        m = A->m,*ip,N,*ailen = a->ilen;
971549d3d68SSatish Balay   int        mbs = a->mbs,bs2 = a->bs2,rmax = 0,ierr;
9723f1db9ecSBarry Smith   MatScalar  *aa = a->a,*ap;
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 
10143a40ed3dSBarry Smith   PetscFunctionReturn(0);
1015584200bdSSatish Balay }
1016584200bdSSatish Balay 
10175a838052SSatish Balay 
1018bea157c4SSatish Balay 
1019bea157c4SSatish Balay /*
1020bea157c4SSatish Balay    This function returns an array of flags which indicate the locations of contiguous
1021bea157c4SSatish Balay    blocks that should be zeroed. for eg: if bs = 3  and is = [0,1,2,3,5,6,7,8,9]
1022bea157c4SSatish Balay    then the resulting sizes = [3,1,1,3,1] correspondig to sets [(0,1,2),(3),(5),(6,7,8),(9)]
1023bea157c4SSatish Balay    Assume: sizes should be long enough to hold all the values.
1024bea157c4SSatish Balay */
10254a2ae208SSatish Balay #undef __FUNCT__
10264a2ae208SSatish Balay #define __FUNCT__ "MatZeroRows_SeqBAIJ_Check_Blocks"
1027bea157c4SSatish Balay static int MatZeroRows_SeqBAIJ_Check_Blocks(int idx[],int n,int bs,int sizes[], int *bs_max)
1028d9b7c43dSSatish Balay {
1029bea157c4SSatish Balay   int        i,j,k,row;
1030bea157c4SSatish Balay   PetscTruth flg;
10313a40ed3dSBarry Smith 
1032433994e6SBarry Smith   PetscFunctionBegin;
1033bea157c4SSatish Balay   for (i=0,j=0; i<n; j++) {
1034bea157c4SSatish Balay     row = idx[i];
1035bea157c4SSatish Balay     if (row%bs!=0) { /* Not the begining of a block */
1036bea157c4SSatish Balay       sizes[j] = 1;
1037bea157c4SSatish Balay       i++;
1038e4fda26cSSatish Balay     } else if (i+bs > n) { /* complete block doesn't exist (at idx end) */
1039bea157c4SSatish Balay       sizes[j] = 1;         /* Also makes sure atleast 'bs' values exist for next else */
1040bea157c4SSatish Balay       i++;
1041bea157c4SSatish Balay     } else { /* Begining of the block, so check if the complete block exists */
1042bea157c4SSatish Balay       flg = PETSC_TRUE;
1043bea157c4SSatish Balay       for (k=1; k<bs; k++) {
1044bea157c4SSatish Balay         if (row+k != idx[i+k]) { /* break in the block */
1045bea157c4SSatish Balay           flg = PETSC_FALSE;
1046bea157c4SSatish Balay           break;
1047d9b7c43dSSatish Balay         }
1048bea157c4SSatish Balay       }
1049bea157c4SSatish Balay       if (flg == PETSC_TRUE) { /* No break in the bs */
1050bea157c4SSatish Balay         sizes[j] = bs;
1051bea157c4SSatish Balay         i+= bs;
1052bea157c4SSatish Balay       } else {
1053bea157c4SSatish Balay         sizes[j] = 1;
1054bea157c4SSatish Balay         i++;
1055bea157c4SSatish Balay       }
1056bea157c4SSatish Balay     }
1057bea157c4SSatish Balay   }
1058bea157c4SSatish Balay   *bs_max = j;
10593a40ed3dSBarry Smith   PetscFunctionReturn(0);
1060d9b7c43dSSatish Balay }
1061d9b7c43dSSatish Balay 
10624a2ae208SSatish Balay #undef __FUNCT__
10634a2ae208SSatish Balay #define __FUNCT__ "MatZeroRows_SeqBAIJ"
1064268466fbSBarry Smith int MatZeroRows_SeqBAIJ(Mat A,IS is,const PetscScalar *diag)
1065d9b7c43dSSatish Balay {
1066d9b7c43dSSatish Balay   Mat_SeqBAIJ *baij=(Mat_SeqBAIJ*)A->data;
1067b6815fffSBarry Smith   int         ierr,i,j,k,count,is_n,*is_idx,*rows;
1068bea157c4SSatish Balay   int         bs=baij->bs,bs2=baij->bs2,*sizes,row,bs_max;
106987828ca2SBarry Smith   PetscScalar zero = 0.0;
10703f1db9ecSBarry Smith   MatScalar   *aa;
1071d9b7c43dSSatish Balay 
10723a40ed3dSBarry Smith   PetscFunctionBegin;
1073d9b7c43dSSatish Balay   /* Make a copy of the IS and  sort it */
1074b9b97703SBarry Smith   ierr = ISGetLocalSize(is,&is_n);CHKERRQ(ierr);
1075d9b7c43dSSatish Balay   ierr = ISGetIndices(is,&is_idx);CHKERRQ(ierr);
1076d9b7c43dSSatish Balay 
1077bea157c4SSatish Balay   /* allocate memory for rows,sizes */
1078b0a32e0cSBarry Smith   ierr  = PetscMalloc((3*is_n+1)*sizeof(int),&rows);CHKERRQ(ierr);
1079bea157c4SSatish Balay   sizes = rows + is_n;
1080bea157c4SSatish Balay 
1081563b5814SBarry Smith   /* copy IS values to rows, and sort them */
1082bea157c4SSatish Balay   for (i=0; i<is_n; i++) { rows[i] = is_idx[i]; }
1083bea157c4SSatish Balay   ierr = PetscSortInt(is_n,rows);CHKERRQ(ierr);
1084dffd3267SBarry Smith   if (baij->keepzeroedrows) {
1085dffd3267SBarry Smith     for (i=0; i<is_n; i++) { sizes[i] = 1; }
1086dffd3267SBarry Smith     bs_max = is_n;
1087dffd3267SBarry Smith   } else {
1088bea157c4SSatish Balay     ierr = MatZeroRows_SeqBAIJ_Check_Blocks(rows,is_n,bs,sizes,&bs_max);CHKERRQ(ierr);
1089dffd3267SBarry Smith   }
1090b97a56abSSatish Balay   ierr = ISRestoreIndices(is,&is_idx);CHKERRQ(ierr);
1091bea157c4SSatish Balay 
1092bea157c4SSatish Balay   for (i=0,j=0; i<bs_max; j+=sizes[i],i++) {
1093bea157c4SSatish Balay     row   = rows[j];
1094273d9f13SBarry Smith     if (row < 0 || row > A->m) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"row %d out of range",row);
1095bea157c4SSatish Balay     count = (baij->i[row/bs +1] - baij->i[row/bs])*bs;
1096bea157c4SSatish Balay     aa    = baij->a + baij->i[row/bs]*bs2 + (row%bs);
1097dffd3267SBarry Smith     if (sizes[i] == bs && !baij->keepzeroedrows) {
1098bea157c4SSatish Balay       if (diag) {
1099bea157c4SSatish Balay         if (baij->ilen[row/bs] > 0) {
1100bea157c4SSatish Balay           baij->ilen[row/bs]       = 1;
1101bea157c4SSatish Balay           baij->j[baij->i[row/bs]] = row/bs;
1102bea157c4SSatish Balay           ierr = PetscMemzero(aa,count*bs*sizeof(MatScalar));CHKERRQ(ierr);
1103a07cd24cSSatish Balay         }
1104563b5814SBarry Smith         /* Now insert all the diagonal values for this bs */
1105bea157c4SSatish Balay         for (k=0; k<bs; k++) {
1106bea157c4SSatish Balay           ierr = (*A->ops->setvalues)(A,1,rows+j+k,1,rows+j+k,diag,INSERT_VALUES);CHKERRQ(ierr);
1107bea157c4SSatish Balay         }
1108bea157c4SSatish Balay       } else { /* (!diag) */
1109bea157c4SSatish Balay         baij->ilen[row/bs] = 0;
1110bea157c4SSatish Balay       } /* end (!diag) */
1111bea157c4SSatish Balay     } else { /* (sizes[i] != bs) */
1112aa482453SBarry Smith #if defined (PETSC_USE_DEBUG)
111329bbc08cSBarry Smith       if (sizes[i] != 1) SETERRQ(1,"Internal Error. Value should be 1");
1114bea157c4SSatish Balay #endif
1115bea157c4SSatish Balay       for (k=0; k<count; k++) {
1116d9b7c43dSSatish Balay         aa[0] =  zero;
1117d9b7c43dSSatish Balay         aa    += bs;
1118d9b7c43dSSatish Balay       }
1119d9b7c43dSSatish Balay       if (diag) {
1120f830108cSBarry Smith         ierr = (*A->ops->setvalues)(A,1,rows+j,1,rows+j,diag,INSERT_VALUES);CHKERRQ(ierr);
1121d9b7c43dSSatish Balay       }
1122d9b7c43dSSatish Balay     }
1123bea157c4SSatish Balay   }
1124bea157c4SSatish Balay 
1125606d414cSSatish Balay   ierr = PetscFree(rows);CHKERRQ(ierr);
11269a8dea36SBarry Smith   ierr = MatAssemblyEnd_SeqBAIJ(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
11273a40ed3dSBarry Smith   PetscFunctionReturn(0);
1128d9b7c43dSSatish Balay }
11291c351548SSatish Balay 
11304a2ae208SSatish Balay #undef __FUNCT__
11314a2ae208SSatish Balay #define __FUNCT__ "MatSetValues_SeqBAIJ"
1132f15d580aSBarry Smith int MatSetValues_SeqBAIJ(Mat A,int m,const int im[],int n,const int in[],const PetscScalar v[],InsertMode is)
11332d61bbb3SSatish Balay {
11342d61bbb3SSatish Balay   Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)A->data;
11352d61bbb3SSatish Balay   int         *rp,k,low,high,t,ii,row,nrow,i,col,l,rmax,N,sorted=a->sorted;
1136273d9f13SBarry Smith   int         *imax=a->imax,*ai=a->i,*ailen=a->ilen;
11372d61bbb3SSatish Balay   int         *aj=a->j,nonew=a->nonew,bs=a->bs,brow,bcol;
1138549d3d68SSatish Balay   int         ridx,cidx,bs2=a->bs2,ierr;
1139273d9f13SBarry Smith   PetscTruth  roworiented=a->roworiented;
11403f1db9ecSBarry Smith   MatScalar   *ap,value,*aa=a->a,*bap;
11412d61bbb3SSatish Balay 
11422d61bbb3SSatish Balay   PetscFunctionBegin;
11432d61bbb3SSatish Balay   for (k=0; k<m; k++) { /* loop over added rows */
11442d61bbb3SSatish Balay     row  = im[k]; brow = row/bs;
11455ef9f2a5SBarry Smith     if (row < 0) continue;
1146aa482453SBarry Smith #if defined(PETSC_USE_BOPT_g)
1147590ac198SBarry Smith     if (row >= A->m) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"Row too large: row %d max %d",row,A->m-1);
11482d61bbb3SSatish Balay #endif
11492d61bbb3SSatish Balay     rp   = aj + ai[brow];
11502d61bbb3SSatish Balay     ap   = aa + bs2*ai[brow];
11512d61bbb3SSatish Balay     rmax = imax[brow];
11522d61bbb3SSatish Balay     nrow = ailen[brow];
11532d61bbb3SSatish Balay     low  = 0;
11542d61bbb3SSatish Balay     for (l=0; l<n; l++) { /* loop over added columns */
11555ef9f2a5SBarry Smith       if (in[l] < 0) continue;
1156aa482453SBarry Smith #if defined(PETSC_USE_BOPT_g)
1157590ac198SBarry Smith       if (in[l] >= A->n) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"Column too large: col %d max %d",in[l],A->n-1);
11582d61bbb3SSatish Balay #endif
11592d61bbb3SSatish Balay       col = in[l]; bcol = col/bs;
11602d61bbb3SSatish Balay       ridx = row % bs; cidx = col % bs;
11612d61bbb3SSatish Balay       if (roworiented) {
11625ef9f2a5SBarry Smith         value = v[l + k*n];
11632d61bbb3SSatish Balay       } else {
11642d61bbb3SSatish Balay         value = v[k + l*m];
11652d61bbb3SSatish Balay       }
11662d61bbb3SSatish Balay       if (!sorted) low = 0; high = nrow;
11672d61bbb3SSatish Balay       while (high-low > 7) {
11682d61bbb3SSatish Balay         t = (low+high)/2;
11692d61bbb3SSatish Balay         if (rp[t] > bcol) high = t;
11702d61bbb3SSatish Balay         else              low  = t;
11712d61bbb3SSatish Balay       }
11722d61bbb3SSatish Balay       for (i=low; i<high; i++) {
11732d61bbb3SSatish Balay         if (rp[i] > bcol) break;
11742d61bbb3SSatish Balay         if (rp[i] == bcol) {
11752d61bbb3SSatish Balay           bap  = ap +  bs2*i + bs*cidx + ridx;
11762d61bbb3SSatish Balay           if (is == ADD_VALUES) *bap += value;
11772d61bbb3SSatish Balay           else                  *bap  = value;
11782d61bbb3SSatish Balay           goto noinsert1;
11792d61bbb3SSatish Balay         }
11802d61bbb3SSatish Balay       }
11812d61bbb3SSatish Balay       if (nonew == 1) goto noinsert1;
1182a45adfd6SMatthew Knepley       else if (nonew == -1) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"Inserting a new nonzero (%d, %d) in the matrix", row, col);
11832d61bbb3SSatish Balay       if (nrow >= rmax) {
11842d61bbb3SSatish Balay         /* there is no extra room in row, therefore enlarge */
11852d61bbb3SSatish Balay         int       new_nz = ai[a->mbs] + CHUNKSIZE,len,*new_i,*new_j;
11863f1db9ecSBarry Smith         MatScalar *new_a;
11872d61bbb3SSatish Balay 
1188a45adfd6SMatthew Knepley         if (nonew == -2) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"Inserting a new nonzero (%d, %d) in the matrix", row, col);
11892d61bbb3SSatish Balay 
11902d61bbb3SSatish Balay         /* Malloc new storage space */
11913f1db9ecSBarry Smith         len     = new_nz*(sizeof(int)+bs2*sizeof(MatScalar))+(a->mbs+1)*sizeof(int);
1192b0a32e0cSBarry Smith 	ierr    = PetscMalloc(len,&new_a);CHKERRQ(ierr);
11932d61bbb3SSatish Balay         new_j   = (int*)(new_a + bs2*new_nz);
11942d61bbb3SSatish Balay         new_i   = new_j + new_nz;
11952d61bbb3SSatish Balay 
11962d61bbb3SSatish Balay         /* copy over old data into new slots */
11972d61bbb3SSatish Balay         for (ii=0; ii<brow+1; ii++) {new_i[ii] = ai[ii];}
11982d61bbb3SSatish Balay         for (ii=brow+1; ii<a->mbs+1; ii++) {new_i[ii] = ai[ii]+CHUNKSIZE;}
1199549d3d68SSatish Balay         ierr = PetscMemcpy(new_j,aj,(ai[brow]+nrow)*sizeof(int));CHKERRQ(ierr);
12002d61bbb3SSatish Balay         len  = (new_nz - CHUNKSIZE - ai[brow] - nrow);
1201549d3d68SSatish Balay         ierr = PetscMemcpy(new_j+ai[brow]+nrow+CHUNKSIZE,aj+ai[brow]+nrow,len*sizeof(int));CHKERRQ(ierr);
1202549d3d68SSatish Balay         ierr = PetscMemcpy(new_a,aa,(ai[brow]+nrow)*bs2*sizeof(MatScalar));CHKERRQ(ierr);
1203549d3d68SSatish Balay         ierr = PetscMemzero(new_a+bs2*(ai[brow]+nrow),bs2*CHUNKSIZE*sizeof(MatScalar));CHKERRQ(ierr);
1204549d3d68SSatish Balay         ierr = PetscMemcpy(new_a+bs2*(ai[brow]+nrow+CHUNKSIZE),aa+bs2*(ai[brow]+nrow),bs2*len*sizeof(MatScalar));CHKERRQ(ierr);
12052d61bbb3SSatish Balay         /* free up old matrix storage */
1206606d414cSSatish Balay         ierr = PetscFree(a->a);CHKERRQ(ierr);
1207606d414cSSatish Balay         if (!a->singlemalloc) {
1208606d414cSSatish Balay           ierr = PetscFree(a->i);CHKERRQ(ierr);
1209606d414cSSatish Balay           ierr = PetscFree(a->j);CHKERRQ(ierr);
1210606d414cSSatish Balay         }
12112d61bbb3SSatish Balay         aa = a->a = new_a; ai = a->i = new_i; aj = a->j = new_j;
1212c4992f7dSBarry Smith         a->singlemalloc = PETSC_TRUE;
12132d61bbb3SSatish Balay 
12142d61bbb3SSatish Balay         rp   = aj + ai[brow]; ap = aa + bs2*ai[brow];
12152d61bbb3SSatish Balay         rmax = imax[brow] = imax[brow] + CHUNKSIZE;
1216b0a32e0cSBarry Smith         PetscLogObjectMemory(A,CHUNKSIZE*(sizeof(int) + bs2*sizeof(MatScalar)));
12172d61bbb3SSatish Balay         a->maxnz += bs2*CHUNKSIZE;
12182d61bbb3SSatish Balay         a->reallocs++;
12192d61bbb3SSatish Balay         a->nz++;
12202d61bbb3SSatish Balay       }
12212d61bbb3SSatish Balay       N = nrow++ - 1;
12222d61bbb3SSatish Balay       /* shift up all the later entries in this row */
12232d61bbb3SSatish Balay       for (ii=N; ii>=i; ii--) {
12242d61bbb3SSatish Balay         rp[ii+1] = rp[ii];
1225549d3d68SSatish Balay         ierr     = PetscMemcpy(ap+bs2*(ii+1),ap+bs2*(ii),bs2*sizeof(MatScalar));CHKERRQ(ierr);
12262d61bbb3SSatish Balay       }
1227549d3d68SSatish Balay       if (N>=i) {
1228549d3d68SSatish Balay         ierr = PetscMemzero(ap+bs2*i,bs2*sizeof(MatScalar));CHKERRQ(ierr);
1229549d3d68SSatish Balay       }
12302d61bbb3SSatish Balay       rp[i]                      = bcol;
12312d61bbb3SSatish Balay       ap[bs2*i + bs*cidx + ridx] = value;
12322d61bbb3SSatish Balay       noinsert1:;
12332d61bbb3SSatish Balay       low = i;
12342d61bbb3SSatish Balay     }
12352d61bbb3SSatish Balay     ailen[brow] = nrow;
12362d61bbb3SSatish Balay   }
12372d61bbb3SSatish Balay   PetscFunctionReturn(0);
12382d61bbb3SSatish Balay }
12392d61bbb3SSatish Balay 
12402d61bbb3SSatish Balay 
12414a2ae208SSatish Balay #undef __FUNCT__
12424a2ae208SSatish Balay #define __FUNCT__ "MatILUFactor_SeqBAIJ"
1243b380c88cSHong Zhang int MatILUFactor_SeqBAIJ(Mat inA,IS row,IS col,MatFactorInfo *info)
12442d61bbb3SSatish Balay {
12452d61bbb3SSatish Balay   Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)inA->data;
12462d61bbb3SSatish Balay   Mat         outA;
12472d61bbb3SSatish Balay   int         ierr;
1248667159a5SBarry Smith   PetscTruth  row_identity,col_identity;
12492d61bbb3SSatish Balay 
12502d61bbb3SSatish Balay   PetscFunctionBegin;
1251d3d32019SBarry Smith   if (info->levels != 0) SETERRQ(PETSC_ERR_SUP,"Only levels = 0 supported for in-place ILU");
1252667159a5SBarry Smith   ierr = ISIdentity(row,&row_identity);CHKERRQ(ierr);
1253667159a5SBarry Smith   ierr = ISIdentity(col,&col_identity);CHKERRQ(ierr);
1254667159a5SBarry Smith   if (!row_identity || !col_identity) {
125529bbc08cSBarry Smith     SETERRQ(1,"Row and column permutations must be identity for in-place ILU");
1256667159a5SBarry Smith   }
12572d61bbb3SSatish Balay 
12582d61bbb3SSatish Balay   outA          = inA;
12592d61bbb3SSatish Balay   inA->factor   = FACTOR_LU;
12602d61bbb3SSatish Balay 
12612d61bbb3SSatish Balay   if (!a->diag) {
1262c4992f7dSBarry Smith     ierr = MatMarkDiagonal_SeqBAIJ(inA);CHKERRQ(ierr);
12632d61bbb3SSatish Balay   }
1264cf242676SKris Buschelman 
1265c38d4ed2SBarry Smith   a->row        = row;
1266c38d4ed2SBarry Smith   a->col        = col;
1267c38d4ed2SBarry Smith   ierr          = PetscObjectReference((PetscObject)row);CHKERRQ(ierr);
1268c38d4ed2SBarry Smith   ierr          = PetscObjectReference((PetscObject)col);CHKERRQ(ierr);
1269c38d4ed2SBarry Smith 
1270c38d4ed2SBarry Smith   /* Create the invert permutation so that it can be used in MatLUFactorNumeric() */
12714c49b128SBarry Smith   ierr = ISInvertPermutation(col,PETSC_DECIDE,&a->icol);CHKERRQ(ierr);
1272b0a32e0cSBarry Smith   PetscLogObjectParent(inA,a->icol);
1273c38d4ed2SBarry Smith 
1274cf242676SKris Buschelman   /*
1275cf242676SKris Buschelman       Blocksize 2, 3, 4, 5, 6 and 7 have a special faster factorization/solver
1276cf242676SKris Buschelman       for ILU(0) factorization with natural ordering
1277cf242676SKris Buschelman   */
1278cf242676SKris Buschelman   if (a->bs < 8) {
1279cf242676SKris Buschelman     ierr = MatSeqBAIJ_UpdateFactorNumeric_NaturalOrdering(inA);CHKERRQ(ierr);
1280cf242676SKris Buschelman   } else {
1281c38d4ed2SBarry Smith     if (!a->solve_work) {
128287828ca2SBarry Smith       ierr = PetscMalloc((inA->m+a->bs)*sizeof(PetscScalar),&a->solve_work);CHKERRQ(ierr);
128387828ca2SBarry Smith       PetscLogObjectMemory(inA,(inA->m+a->bs)*sizeof(PetscScalar));
1284c38d4ed2SBarry Smith     }
12852d61bbb3SSatish Balay   }
12862d61bbb3SSatish Balay 
1287667159a5SBarry Smith   ierr = MatLUFactorNumeric(inA,&outA);CHKERRQ(ierr);
1288667159a5SBarry Smith 
12892d61bbb3SSatish Balay   PetscFunctionReturn(0);
12902d61bbb3SSatish Balay }
12914a2ae208SSatish Balay #undef __FUNCT__
12924a2ae208SSatish Balay #define __FUNCT__ "MatPrintHelp_SeqBAIJ"
1293ba4ca20aSSatish Balay int MatPrintHelp_SeqBAIJ(Mat A)
1294ba4ca20aSSatish Balay {
1295c38d4ed2SBarry Smith   static PetscTruth called = PETSC_FALSE;
1296ba4ca20aSSatish Balay   MPI_Comm          comm = A->comm;
1297d132466eSBarry Smith   int               ierr;
1298ba4ca20aSSatish Balay 
12993a40ed3dSBarry Smith   PetscFunctionBegin;
1300c38d4ed2SBarry Smith   if (called) {PetscFunctionReturn(0);} else called = PETSC_TRUE;
1301d132466eSBarry Smith   ierr = (*PetscHelpPrintf)(comm," Options for MATSEQBAIJ and MATMPIBAIJ matrix formats (the defaults):\n");CHKERRQ(ierr);
1302d132466eSBarry Smith   ierr = (*PetscHelpPrintf)(comm,"  -mat_block_size <block_size>\n");CHKERRQ(ierr);
13033a40ed3dSBarry Smith   PetscFunctionReturn(0);
1304ba4ca20aSSatish Balay }
1305d9b7c43dSSatish Balay 
1306fb2e594dSBarry Smith EXTERN_C_BEGIN
13074a2ae208SSatish Balay #undef __FUNCT__
13084a2ae208SSatish Balay #define __FUNCT__ "MatSeqBAIJSetColumnIndices_SeqBAIJ"
130927a8da17SBarry Smith int MatSeqBAIJSetColumnIndices_SeqBAIJ(Mat mat,int *indices)
131027a8da17SBarry Smith {
131127a8da17SBarry Smith   Mat_SeqBAIJ *baij = (Mat_SeqBAIJ *)mat->data;
131214db4f74SSatish Balay   int         i,nz,nbs;
131327a8da17SBarry Smith 
131427a8da17SBarry Smith   PetscFunctionBegin;
131514db4f74SSatish Balay   nz  = baij->maxnz/baij->bs2;
131614db4f74SSatish Balay   nbs = baij->nbs;
131727a8da17SBarry Smith   for (i=0; i<nz; i++) {
131827a8da17SBarry Smith     baij->j[i] = indices[i];
131927a8da17SBarry Smith   }
132027a8da17SBarry Smith   baij->nz = nz;
132114db4f74SSatish Balay   for (i=0; i<nbs; i++) {
132227a8da17SBarry Smith     baij->ilen[i] = baij->imax[i];
132327a8da17SBarry Smith   }
132427a8da17SBarry Smith 
132527a8da17SBarry Smith   PetscFunctionReturn(0);
132627a8da17SBarry Smith }
1327fb2e594dSBarry Smith EXTERN_C_END
132827a8da17SBarry Smith 
13294a2ae208SSatish Balay #undef __FUNCT__
13304a2ae208SSatish Balay #define __FUNCT__ "MatSeqBAIJSetColumnIndices"
133127a8da17SBarry Smith /*@
133227a8da17SBarry Smith     MatSeqBAIJSetColumnIndices - Set the column indices for all the rows
133327a8da17SBarry Smith        in the matrix.
133427a8da17SBarry Smith 
133527a8da17SBarry Smith   Input Parameters:
133627a8da17SBarry Smith +  mat - the SeqBAIJ matrix
133727a8da17SBarry Smith -  indices - the column indices
133827a8da17SBarry Smith 
133915091d37SBarry Smith   Level: advanced
134015091d37SBarry Smith 
134127a8da17SBarry Smith   Notes:
134227a8da17SBarry Smith     This can be called if you have precomputed the nonzero structure of the
134327a8da17SBarry Smith   matrix and want to provide it to the matrix object to improve the performance
134427a8da17SBarry Smith   of the MatSetValues() operation.
134527a8da17SBarry Smith 
134627a8da17SBarry Smith     You MUST have set the correct numbers of nonzeros per row in the call to
134727a8da17SBarry Smith   MatCreateSeqBAIJ().
134827a8da17SBarry Smith 
134927a8da17SBarry Smith     MUST be called before any calls to MatSetValues();
135027a8da17SBarry Smith 
135127a8da17SBarry Smith @*/
135227a8da17SBarry Smith int MatSeqBAIJSetColumnIndices(Mat mat,int *indices)
135327a8da17SBarry Smith {
135427a8da17SBarry Smith   int ierr,(*f)(Mat,int *);
135527a8da17SBarry Smith 
135627a8da17SBarry Smith   PetscFunctionBegin;
135727a8da17SBarry Smith   PetscValidHeaderSpecific(mat,MAT_COOKIE);
1358c134de8dSSatish Balay   ierr = PetscObjectQueryFunction((PetscObject)mat,"MatSeqBAIJSetColumnIndices_C",(void (**)(void))&f);CHKERRQ(ierr);
135927a8da17SBarry Smith   if (f) {
136027a8da17SBarry Smith     ierr = (*f)(mat,indices);CHKERRQ(ierr);
136127a8da17SBarry Smith   } else {
136229bbc08cSBarry Smith     SETERRQ(1,"Wrong type of matrix to set column indices");
136327a8da17SBarry Smith   }
136427a8da17SBarry Smith   PetscFunctionReturn(0);
136527a8da17SBarry Smith }
136627a8da17SBarry Smith 
13674a2ae208SSatish Balay #undef __FUNCT__
13684a2ae208SSatish Balay #define __FUNCT__ "MatGetRowMax_SeqBAIJ"
1369273d9f13SBarry Smith int MatGetRowMax_SeqBAIJ(Mat A,Vec v)
1370273d9f13SBarry Smith {
1371273d9f13SBarry Smith   Mat_SeqBAIJ  *a = (Mat_SeqBAIJ*)A->data;
1372273d9f13SBarry Smith   int          ierr,i,j,n,row,bs,*ai,*aj,mbs;
1373273d9f13SBarry Smith   PetscReal    atmp;
137487828ca2SBarry Smith   PetscScalar  *x,zero = 0.0;
1375273d9f13SBarry Smith   MatScalar    *aa;
1376273d9f13SBarry Smith   int          ncols,brow,krow,kcol;
1377273d9f13SBarry Smith 
1378273d9f13SBarry Smith   PetscFunctionBegin;
1379273d9f13SBarry Smith   if (A->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1380273d9f13SBarry Smith   bs   = a->bs;
1381273d9f13SBarry Smith   aa   = a->a;
1382273d9f13SBarry Smith   ai   = a->i;
1383273d9f13SBarry Smith   aj   = a->j;
1384273d9f13SBarry Smith   mbs = a->mbs;
1385273d9f13SBarry Smith 
1386273d9f13SBarry Smith   ierr = VecSet(&zero,v);CHKERRQ(ierr);
1387*b1d4fb26SBarry Smith   ierr = VecGetArrayFast(v,&x);CHKERRQ(ierr);
1388273d9f13SBarry Smith   ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr);
1389273d9f13SBarry Smith   if (n != A->m) SETERRQ(PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector");
1390273d9f13SBarry Smith   for (i=0; i<mbs; i++) {
1391273d9f13SBarry Smith     ncols = ai[1] - ai[0]; ai++;
1392273d9f13SBarry Smith     brow  = bs*i;
1393273d9f13SBarry Smith     for (j=0; j<ncols; j++){
1394273d9f13SBarry Smith       /* bcol = bs*(*aj); */
1395273d9f13SBarry Smith       for (kcol=0; kcol<bs; kcol++){
1396273d9f13SBarry Smith         for (krow=0; krow<bs; krow++){
1397273d9f13SBarry Smith           atmp = PetscAbsScalar(*aa); aa++;
1398273d9f13SBarry Smith           row = brow + krow;    /* row index */
1399273d9f13SBarry Smith           /* printf("val[%d,%d]: %g\n",row,bcol+kcol,atmp); */
1400273d9f13SBarry Smith           if (PetscAbsScalar(x[row]) < atmp) x[row] = atmp;
1401273d9f13SBarry Smith         }
1402273d9f13SBarry Smith       }
1403273d9f13SBarry Smith       aj++;
1404273d9f13SBarry Smith     }
1405273d9f13SBarry Smith   }
1406*b1d4fb26SBarry Smith   ierr = VecRestoreArrayFast(v,&x);CHKERRQ(ierr);
1407273d9f13SBarry Smith   PetscFunctionReturn(0);
1408273d9f13SBarry Smith }
1409273d9f13SBarry Smith 
14104a2ae208SSatish Balay #undef __FUNCT__
14114a2ae208SSatish Balay #define __FUNCT__ "MatSetUpPreallocation_SeqBAIJ"
1412273d9f13SBarry Smith int MatSetUpPreallocation_SeqBAIJ(Mat A)
1413273d9f13SBarry Smith {
1414273d9f13SBarry Smith   int        ierr;
1415273d9f13SBarry Smith 
1416273d9f13SBarry Smith   PetscFunctionBegin;
1417273d9f13SBarry Smith   ierr =  MatSeqBAIJSetPreallocation(A,1,PETSC_DEFAULT,0);CHKERRQ(ierr);
1418273d9f13SBarry Smith   PetscFunctionReturn(0);
1419273d9f13SBarry Smith }
1420273d9f13SBarry Smith 
14214a2ae208SSatish Balay #undef __FUNCT__
14224a2ae208SSatish Balay #define __FUNCT__ "MatGetArray_SeqBAIJ"
14234e7234bfSBarry Smith int MatGetArray_SeqBAIJ(Mat A,PetscScalar *array[])
1424f2a5309cSSatish Balay {
1425f2a5309cSSatish Balay   Mat_SeqBAIJ *a = (Mat_SeqBAIJ*)A->data;
1426f2a5309cSSatish Balay   PetscFunctionBegin;
1427f2a5309cSSatish Balay   *array = a->a;
1428f2a5309cSSatish Balay   PetscFunctionReturn(0);
1429f2a5309cSSatish Balay }
1430f2a5309cSSatish Balay 
14314a2ae208SSatish Balay #undef __FUNCT__
14324a2ae208SSatish Balay #define __FUNCT__ "MatRestoreArray_SeqBAIJ"
14334e7234bfSBarry Smith int MatRestoreArray_SeqBAIJ(Mat A,PetscScalar *array[])
1434f2a5309cSSatish Balay {
1435f2a5309cSSatish Balay   PetscFunctionBegin;
1436f2a5309cSSatish Balay   PetscFunctionReturn(0);
1437f2a5309cSSatish Balay }
1438f2a5309cSSatish Balay 
143942ee4b1aSHong Zhang #include "petscblaslapack.h"
144042ee4b1aSHong Zhang #undef __FUNCT__
144142ee4b1aSHong Zhang #define __FUNCT__ "MatAXPY_SeqBAIJ"
1442268466fbSBarry Smith int MatAXPY_SeqBAIJ(const PetscScalar *a,Mat X,Mat Y,MatStructure str)
144342ee4b1aSHong Zhang {
144442ee4b1aSHong Zhang   Mat_SeqBAIJ  *x  = (Mat_SeqBAIJ *)X->data,*y = (Mat_SeqBAIJ *)Y->data;
14456550863bSHong Zhang   int          ierr,one=1,i,bs=y->bs,j,bs2;
144642ee4b1aSHong Zhang 
144742ee4b1aSHong Zhang   PetscFunctionBegin;
144842ee4b1aSHong Zhang   if (str == SAME_NONZERO_PATTERN) {
1449268466fbSBarry Smith     BLaxpy_(&x->nz,(PetscScalar*)a,x->a,&one,y->a,&one);
1450c537a176SHong Zhang   } else if (str == SUBSET_NONZERO_PATTERN) { /* nonzeros of X is a subset of Y's */
1451c4319e64SHong Zhang     if (y->xtoy && y->XtoY != X) {
1452c4319e64SHong Zhang       ierr = PetscFree(y->xtoy);CHKERRQ(ierr);
1453c4319e64SHong Zhang       ierr = MatDestroy(y->XtoY);CHKERRQ(ierr);
1454c537a176SHong Zhang     }
1455c4319e64SHong Zhang     if (!y->xtoy) { /* get xtoy */
1456c4319e64SHong Zhang       ierr = MatAXPYGetxtoy_Private(x->mbs,x->i,x->j,PETSC_NULL, y->i,y->j,PETSC_NULL, &y->xtoy);CHKERRQ(ierr);
1457c4319e64SHong Zhang       y->XtoY = X;
1458c537a176SHong Zhang     }
1459c4319e64SHong Zhang     bs2 = bs*bs;
1460c537a176SHong Zhang     for (i=0; i<x->nz; i++) {
1461c4319e64SHong Zhang       j = 0;
1462c4319e64SHong Zhang       while (j < bs2){
14636550863bSHong Zhang         y->a[bs2*y->xtoy[i]+j] += (*a)*(x->a[bs2*i+j]);
1464c4319e64SHong Zhang         j++;
1465c537a176SHong Zhang       }
1466c4319e64SHong Zhang     }
1467c4319e64SHong Zhang     PetscLogInfo(0,"MatAXPY_SeqBAIJ: ratio of nnz(X)/nnz(Y): %d/%d = %g\n",bs2*x->nz,bs2*y->nz,(PetscReal)(bs2*x->nz)/(bs2*y->nz));
146842ee4b1aSHong Zhang   } else {
146942ee4b1aSHong Zhang     ierr = MatAXPY_Basic(a,X,Y,str);CHKERRQ(ierr);
147042ee4b1aSHong Zhang   }
147142ee4b1aSHong Zhang   PetscFunctionReturn(0);
147242ee4b1aSHong Zhang }
147342ee4b1aSHong Zhang 
14742593348eSBarry Smith /* -------------------------------------------------------------------*/
1475cc2dc46cSBarry Smith static struct _MatOps MatOps_Values = {MatSetValues_SeqBAIJ,
1476cc2dc46cSBarry Smith        MatGetRow_SeqBAIJ,
1477cc2dc46cSBarry Smith        MatRestoreRow_SeqBAIJ,
1478cc2dc46cSBarry Smith        MatMult_SeqBAIJ_N,
147997304618SKris Buschelman /* 4*/ MatMultAdd_SeqBAIJ_N,
14807c922b88SBarry Smith        MatMultTranspose_SeqBAIJ,
14817c922b88SBarry Smith        MatMultTransposeAdd_SeqBAIJ,
1482cc2dc46cSBarry Smith        MatSolve_SeqBAIJ_N,
1483cc2dc46cSBarry Smith        0,
1484cc2dc46cSBarry Smith        0,
148597304618SKris Buschelman /*10*/ 0,
1486cc2dc46cSBarry Smith        MatLUFactor_SeqBAIJ,
1487cc2dc46cSBarry Smith        0,
1488b6490206SBarry Smith        0,
1489f2501298SSatish Balay        MatTranspose_SeqBAIJ,
149097304618SKris Buschelman /*15*/ MatGetInfo_SeqBAIJ,
1491cc2dc46cSBarry Smith        MatEqual_SeqBAIJ,
1492cc2dc46cSBarry Smith        MatGetDiagonal_SeqBAIJ,
1493cc2dc46cSBarry Smith        MatDiagonalScale_SeqBAIJ,
1494cc2dc46cSBarry Smith        MatNorm_SeqBAIJ,
149597304618SKris Buschelman /*20*/ 0,
1496cc2dc46cSBarry Smith        MatAssemblyEnd_SeqBAIJ,
1497cc2dc46cSBarry Smith        0,
1498cc2dc46cSBarry Smith        MatSetOption_SeqBAIJ,
1499cc2dc46cSBarry Smith        MatZeroEntries_SeqBAIJ,
150097304618SKris Buschelman /*25*/ MatZeroRows_SeqBAIJ,
1501cc2dc46cSBarry Smith        MatLUFactorSymbolic_SeqBAIJ,
1502cc2dc46cSBarry Smith        MatLUFactorNumeric_SeqBAIJ_N,
1503cc2dc46cSBarry Smith        0,
1504cc2dc46cSBarry Smith        0,
150597304618SKris Buschelman /*30*/ MatSetUpPreallocation_SeqBAIJ,
1506cc2dc46cSBarry Smith        MatILUFactorSymbolic_SeqBAIJ,
1507cc2dc46cSBarry Smith        0,
1508f2a5309cSSatish Balay        MatGetArray_SeqBAIJ,
1509f2a5309cSSatish Balay        MatRestoreArray_SeqBAIJ,
151097304618SKris Buschelman /*35*/ MatDuplicate_SeqBAIJ,
1511cc2dc46cSBarry Smith        0,
1512cc2dc46cSBarry Smith        0,
1513cc2dc46cSBarry Smith        MatILUFactor_SeqBAIJ,
1514cc2dc46cSBarry Smith        0,
151597304618SKris Buschelman /*40*/ MatAXPY_SeqBAIJ,
1516cc2dc46cSBarry Smith        MatGetSubMatrices_SeqBAIJ,
1517cc2dc46cSBarry Smith        MatIncreaseOverlap_SeqBAIJ,
1518cc2dc46cSBarry Smith        MatGetValues_SeqBAIJ,
1519cc2dc46cSBarry Smith        0,
152097304618SKris Buschelman /*45*/ MatPrintHelp_SeqBAIJ,
1521cc2dc46cSBarry Smith        MatScale_SeqBAIJ,
1522cc2dc46cSBarry Smith        0,
1523cc2dc46cSBarry Smith        0,
1524cc2dc46cSBarry Smith        0,
152597304618SKris Buschelman /*50*/ MatGetBlockSize_SeqBAIJ,
15263b2fbd54SBarry Smith        MatGetRowIJ_SeqBAIJ,
152792c4ed94SBarry Smith        MatRestoreRowIJ_SeqBAIJ,
1528cc2dc46cSBarry Smith        0,
1529cc2dc46cSBarry Smith        0,
153097304618SKris Buschelman /*55*/ 0,
1531cc2dc46cSBarry Smith        0,
1532cc2dc46cSBarry Smith        0,
1533cc2dc46cSBarry Smith        0,
1534d3825aa8SBarry Smith        MatSetValuesBlocked_SeqBAIJ,
153597304618SKris Buschelman /*60*/ MatGetSubMatrix_SeqBAIJ,
1536b9b97703SBarry Smith        MatDestroy_SeqBAIJ,
1537b9b97703SBarry Smith        MatView_SeqBAIJ,
15383a64cc32SBarry Smith        MatGetPetscMaps_Petsc,
1539273d9f13SBarry Smith        0,
154097304618SKris Buschelman /*65*/ 0,
1541273d9f13SBarry Smith        0,
1542273d9f13SBarry Smith        0,
1543273d9f13SBarry Smith        0,
1544273d9f13SBarry Smith        0,
154597304618SKris Buschelman /*70*/ MatGetRowMax_SeqBAIJ,
154697304618SKris Buschelman        MatConvert_Basic,
1547273d9f13SBarry Smith        0,
154897304618SKris Buschelman        0,
154997304618SKris Buschelman        0,
155097304618SKris Buschelman /*75*/ 0,
155197304618SKris Buschelman        0,
155297304618SKris Buschelman        0,
155397304618SKris Buschelman        0,
155497304618SKris Buschelman        0,
155597304618SKris Buschelman /*80*/ 0,
155697304618SKris Buschelman        0,
155797304618SKris Buschelman        0,
155897304618SKris Buschelman        0,
155997304618SKris Buschelman /*85*/ MatLoad_SeqBAIJ
156097304618SKris Buschelman };
15612593348eSBarry Smith 
15623e90b805SBarry Smith EXTERN_C_BEGIN
15634a2ae208SSatish Balay #undef __FUNCT__
15644a2ae208SSatish Balay #define __FUNCT__ "MatStoreValues_SeqBAIJ"
15653e90b805SBarry Smith int MatStoreValues_SeqBAIJ(Mat mat)
15663e90b805SBarry Smith {
15673e90b805SBarry Smith   Mat_SeqBAIJ *aij = (Mat_SeqBAIJ *)mat->data;
1568273d9f13SBarry Smith   int         nz = aij->i[mat->m]*aij->bs*aij->bs2;
1569d132466eSBarry Smith   int         ierr;
15703e90b805SBarry Smith 
15713e90b805SBarry Smith   PetscFunctionBegin;
15723e90b805SBarry Smith   if (aij->nonew != 1) {
157329bbc08cSBarry Smith     SETERRQ(1,"Must call MatSetOption(A,MAT_NO_NEW_NONZERO_LOCATIONS);first");
15743e90b805SBarry Smith   }
15753e90b805SBarry Smith 
15763e90b805SBarry Smith   /* allocate space for values if not already there */
15773e90b805SBarry Smith   if (!aij->saved_values) {
157887828ca2SBarry Smith     ierr = PetscMalloc((nz+1)*sizeof(PetscScalar),&aij->saved_values);CHKERRQ(ierr);
15793e90b805SBarry Smith   }
15803e90b805SBarry Smith 
15813e90b805SBarry Smith   /* copy values over */
158287828ca2SBarry Smith   ierr = PetscMemcpy(aij->saved_values,aij->a,nz*sizeof(PetscScalar));CHKERRQ(ierr);
15833e90b805SBarry Smith   PetscFunctionReturn(0);
15843e90b805SBarry Smith }
15853e90b805SBarry Smith EXTERN_C_END
15863e90b805SBarry Smith 
15873e90b805SBarry Smith EXTERN_C_BEGIN
15884a2ae208SSatish Balay #undef __FUNCT__
15894a2ae208SSatish Balay #define __FUNCT__ "MatRetrieveValues_SeqBAIJ"
159032e87ba3SBarry Smith int MatRetrieveValues_SeqBAIJ(Mat mat)
15913e90b805SBarry Smith {
15923e90b805SBarry Smith   Mat_SeqBAIJ *aij = (Mat_SeqBAIJ *)mat->data;
1593273d9f13SBarry Smith   int         nz = aij->i[mat->m]*aij->bs*aij->bs2,ierr;
15943e90b805SBarry Smith 
15953e90b805SBarry Smith   PetscFunctionBegin;
15963e90b805SBarry Smith   if (aij->nonew != 1) {
159729bbc08cSBarry Smith     SETERRQ(1,"Must call MatSetOption(A,MAT_NO_NEW_NONZERO_LOCATIONS);first");
15983e90b805SBarry Smith   }
15993e90b805SBarry Smith   if (!aij->saved_values) {
160029bbc08cSBarry Smith     SETERRQ(1,"Must call MatStoreValues(A);first");
16013e90b805SBarry Smith   }
16023e90b805SBarry Smith 
16033e90b805SBarry Smith   /* copy values over */
160487828ca2SBarry Smith   ierr = PetscMemcpy(aij->a,aij->saved_values,nz*sizeof(PetscScalar));CHKERRQ(ierr);
16053e90b805SBarry Smith   PetscFunctionReturn(0);
16063e90b805SBarry Smith }
16073e90b805SBarry Smith EXTERN_C_END
16083e90b805SBarry Smith 
1609273d9f13SBarry Smith EXTERN_C_BEGIN
1610f248c16bSBarry Smith extern int MatConvert_SeqBAIJ_SeqAIJ(Mat,const MatType,Mat*);
1611a0e1a404SHong Zhang extern int MatConvert_SeqBAIJ_SeqSBAIJ(Mat,const MatType,Mat*);
1612273d9f13SBarry Smith EXTERN_C_END
1613273d9f13SBarry Smith 
1614273d9f13SBarry Smith EXTERN_C_BEGIN
16154a2ae208SSatish Balay #undef __FUNCT__
1616a23d5eceSKris Buschelman #define __FUNCT__ "MatSeqBAIJSetPreallocation_SeqBAIJ"
1617a23d5eceSKris Buschelman int MatSeqBAIJSetPreallocation_SeqBAIJ(Mat B,int bs,int nz,int *nnz)
1618a23d5eceSKris Buschelman {
1619a23d5eceSKris Buschelman   Mat_SeqBAIJ *b;
1620a23d5eceSKris Buschelman   int         i,len,ierr,mbs,nbs,bs2,newbs = bs;
1621a23d5eceSKris Buschelman   PetscTruth  flg;
1622a23d5eceSKris Buschelman 
1623a23d5eceSKris Buschelman   PetscFunctionBegin;
1624a23d5eceSKris Buschelman 
1625a23d5eceSKris Buschelman   B->preallocated = PETSC_TRUE;
1626a23d5eceSKris Buschelman   ierr = PetscOptionsGetInt(B->prefix,"-mat_block_size",&newbs,PETSC_NULL);CHKERRQ(ierr);
1627a23d5eceSKris Buschelman   if (nnz && newbs != bs) {
1628a23d5eceSKris Buschelman     SETERRQ(1,"Cannot change blocksize from command line if setting nnz");
1629a23d5eceSKris Buschelman   }
1630a23d5eceSKris Buschelman   bs   = newbs;
1631a23d5eceSKris Buschelman 
1632a23d5eceSKris Buschelman   mbs  = B->m/bs;
1633a23d5eceSKris Buschelman   nbs  = B->n/bs;
1634a23d5eceSKris Buschelman   bs2  = bs*bs;
1635a23d5eceSKris Buschelman 
1636a23d5eceSKris Buschelman   if (mbs*bs!=B->m || nbs*bs!=B->n) {
1637a23d5eceSKris Buschelman     SETERRQ3(PETSC_ERR_ARG_SIZ,"Number rows %d, cols %d must be divisible by blocksize %d",B->m,B->n,bs);
1638a23d5eceSKris Buschelman   }
1639a23d5eceSKris Buschelman 
1640a23d5eceSKris Buschelman   if (nz == PETSC_DEFAULT || nz == PETSC_DECIDE) nz = 5;
1641a23d5eceSKris Buschelman   if (nz < 0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"nz cannot be less than 0: value %d",nz);
1642a23d5eceSKris Buschelman   if (nnz) {
1643a23d5eceSKris Buschelman     for (i=0; i<mbs; i++) {
1644a23d5eceSKris Buschelman       if (nnz[i] < 0) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"nnz cannot be less than 0: local row %d value %d",i,nnz[i]);
1645a23d5eceSKris Buschelman       if (nnz[i] > nbs) SETERRQ3(PETSC_ERR_ARG_OUTOFRANGE,"nnz cannot be greater than block row length: local row %d value %d rowlength %d",i,nnz[i],nbs);
1646a23d5eceSKris Buschelman     }
1647a23d5eceSKris Buschelman   }
1648a23d5eceSKris Buschelman 
1649a23d5eceSKris Buschelman   b       = (Mat_SeqBAIJ*)B->data;
1650a23d5eceSKris Buschelman   ierr    = PetscOptionsHasName(PETSC_NULL,"-mat_no_unroll",&flg);CHKERRQ(ierr);
1651a23d5eceSKris Buschelman   B->ops->solve               = MatSolve_SeqBAIJ_Update;
1652a23d5eceSKris Buschelman   B->ops->solvetranspose      = MatSolveTranspose_SeqBAIJ_Update;
1653a23d5eceSKris Buschelman   if (!flg) {
1654a23d5eceSKris Buschelman     switch (bs) {
1655a23d5eceSKris Buschelman     case 1:
1656a23d5eceSKris Buschelman       B->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_1;
1657a23d5eceSKris Buschelman       B->ops->mult            = MatMult_SeqBAIJ_1;
1658a23d5eceSKris Buschelman       B->ops->multadd         = MatMultAdd_SeqBAIJ_1;
1659a23d5eceSKris Buschelman       break;
1660a23d5eceSKris Buschelman     case 2:
1661a23d5eceSKris Buschelman       B->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_2;
1662a23d5eceSKris Buschelman       B->ops->mult            = MatMult_SeqBAIJ_2;
1663a23d5eceSKris Buschelman       B->ops->multadd         = MatMultAdd_SeqBAIJ_2;
1664a23d5eceSKris Buschelman       break;
1665a23d5eceSKris Buschelman     case 3:
1666a23d5eceSKris Buschelman       B->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_3;
1667a23d5eceSKris Buschelman       B->ops->mult            = MatMult_SeqBAIJ_3;
1668a23d5eceSKris Buschelman       B->ops->multadd         = MatMultAdd_SeqBAIJ_3;
1669a23d5eceSKris Buschelman       break;
1670a23d5eceSKris Buschelman     case 4:
1671a23d5eceSKris Buschelman       B->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_4;
1672a23d5eceSKris Buschelman       B->ops->mult            = MatMult_SeqBAIJ_4;
1673a23d5eceSKris Buschelman       B->ops->multadd         = MatMultAdd_SeqBAIJ_4;
1674a23d5eceSKris Buschelman       break;
1675a23d5eceSKris Buschelman     case 5:
1676a23d5eceSKris Buschelman       B->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_5;
1677a23d5eceSKris Buschelman       B->ops->mult            = MatMult_SeqBAIJ_5;
1678a23d5eceSKris Buschelman       B->ops->multadd         = MatMultAdd_SeqBAIJ_5;
1679a23d5eceSKris Buschelman       break;
1680a23d5eceSKris Buschelman     case 6:
1681a23d5eceSKris Buschelman       B->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_6;
1682a23d5eceSKris Buschelman       B->ops->mult            = MatMult_SeqBAIJ_6;
1683a23d5eceSKris Buschelman       B->ops->multadd         = MatMultAdd_SeqBAIJ_6;
1684a23d5eceSKris Buschelman       break;
1685a23d5eceSKris Buschelman     case 7:
1686a23d5eceSKris Buschelman       B->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_7;
1687a23d5eceSKris Buschelman       B->ops->mult            = MatMult_SeqBAIJ_7;
1688a23d5eceSKris Buschelman       B->ops->multadd         = MatMultAdd_SeqBAIJ_7;
1689a23d5eceSKris Buschelman       break;
1690a23d5eceSKris Buschelman     default:
1691a23d5eceSKris Buschelman       B->ops->lufactornumeric = MatLUFactorNumeric_SeqBAIJ_N;
1692a23d5eceSKris Buschelman       B->ops->mult            = MatMult_SeqBAIJ_N;
1693a23d5eceSKris Buschelman       B->ops->multadd         = MatMultAdd_SeqBAIJ_N;
1694a23d5eceSKris Buschelman       break;
1695a23d5eceSKris Buschelman     }
1696a23d5eceSKris Buschelman   }
1697a23d5eceSKris Buschelman   b->bs      = bs;
1698a23d5eceSKris Buschelman   b->mbs     = mbs;
1699a23d5eceSKris Buschelman   b->nbs     = nbs;
1700a23d5eceSKris Buschelman   ierr = PetscMalloc((mbs+1)*sizeof(int),&b->imax);CHKERRQ(ierr);
1701a23d5eceSKris Buschelman   if (!nnz) {
1702a23d5eceSKris Buschelman     if (nz == PETSC_DEFAULT || nz == PETSC_DECIDE) nz = 5;
1703a23d5eceSKris Buschelman     else if (nz <= 0)        nz = 1;
1704a23d5eceSKris Buschelman     for (i=0; i<mbs; i++) b->imax[i] = nz;
1705a23d5eceSKris Buschelman     nz = nz*mbs;
1706a23d5eceSKris Buschelman   } else {
1707a23d5eceSKris Buschelman     nz = 0;
1708a23d5eceSKris Buschelman     for (i=0; i<mbs; i++) {b->imax[i] = nnz[i]; nz += nnz[i];}
1709a23d5eceSKris Buschelman   }
1710a23d5eceSKris Buschelman 
1711a23d5eceSKris Buschelman   /* allocate the matrix space */
1712a23d5eceSKris Buschelman   len   = nz*sizeof(int) + nz*bs2*sizeof(MatScalar) + (B->m+1)*sizeof(int);
1713a23d5eceSKris Buschelman   ierr  = PetscMalloc(len,&b->a);CHKERRQ(ierr);
1714a23d5eceSKris Buschelman   ierr  = PetscMemzero(b->a,nz*bs2*sizeof(MatScalar));CHKERRQ(ierr);
1715a23d5eceSKris Buschelman   b->j  = (int*)(b->a + nz*bs2);
1716a23d5eceSKris Buschelman   ierr = PetscMemzero(b->j,nz*sizeof(int));CHKERRQ(ierr);
1717a23d5eceSKris Buschelman   b->i  = b->j + nz;
1718a23d5eceSKris Buschelman   b->singlemalloc = PETSC_TRUE;
1719a23d5eceSKris Buschelman 
1720a23d5eceSKris Buschelman   b->i[0] = 0;
1721a23d5eceSKris Buschelman   for (i=1; i<mbs+1; i++) {
1722a23d5eceSKris Buschelman     b->i[i] = b->i[i-1] + b->imax[i-1];
1723a23d5eceSKris Buschelman   }
1724a23d5eceSKris Buschelman 
1725a23d5eceSKris Buschelman   /* b->ilen will count nonzeros in each block row so far. */
1726a23d5eceSKris Buschelman   ierr = PetscMalloc((mbs+1)*sizeof(int),&b->ilen);CHKERRQ(ierr);
1727a23d5eceSKris Buschelman   PetscLogObjectMemory(B,len+2*(mbs+1)*sizeof(int)+sizeof(struct _p_Mat)+sizeof(Mat_SeqBAIJ));
1728a23d5eceSKris Buschelman   for (i=0; i<mbs; i++) { b->ilen[i] = 0;}
1729a23d5eceSKris Buschelman 
1730a23d5eceSKris Buschelman   b->bs               = bs;
1731a23d5eceSKris Buschelman   b->bs2              = bs2;
1732a23d5eceSKris Buschelman   b->mbs              = mbs;
1733a23d5eceSKris Buschelman   b->nz               = 0;
1734a23d5eceSKris Buschelman   b->maxnz            = nz*bs2;
1735a23d5eceSKris Buschelman   B->info.nz_unneeded = (PetscReal)b->maxnz;
1736a23d5eceSKris Buschelman   PetscFunctionReturn(0);
1737a23d5eceSKris Buschelman }
1738a23d5eceSKris Buschelman EXTERN_C_END
1739a23d5eceSKris Buschelman 
17400bad9183SKris Buschelman /*MC
1741fafad747SKris Buschelman    MATSEQBAIJ - MATSEQBAIJ = "seqbaij" - A matrix type to be used for sequential block sparse matrices, based on
17420bad9183SKris Buschelman    block sparse compressed row format.
17430bad9183SKris Buschelman 
17440bad9183SKris Buschelman    Options Database Keys:
17450bad9183SKris Buschelman . -mat_type seqbaij - sets the matrix type to "seqbaij" during a call to MatSetFromOptions()
17460bad9183SKris Buschelman 
17470bad9183SKris Buschelman   Level: beginner
17480bad9183SKris Buschelman 
17490bad9183SKris Buschelman .seealso: MatCreateSeqBAIJ
17500bad9183SKris Buschelman M*/
17510bad9183SKris Buschelman 
1752a23d5eceSKris Buschelman EXTERN_C_BEGIN
1753a23d5eceSKris Buschelman #undef __FUNCT__
17544a2ae208SSatish Balay #define __FUNCT__ "MatCreate_SeqBAIJ"
1755273d9f13SBarry Smith int MatCreate_SeqBAIJ(Mat B)
17562593348eSBarry Smith {
1757273d9f13SBarry Smith   int         ierr,size;
1758b6490206SBarry Smith   Mat_SeqBAIJ *b;
17593b2fbd54SBarry Smith 
17603a40ed3dSBarry Smith   PetscFunctionBegin;
1761273d9f13SBarry Smith   ierr = MPI_Comm_size(B->comm,&size);CHKERRQ(ierr);
176229bbc08cSBarry Smith   if (size > 1) SETERRQ(PETSC_ERR_ARG_WRONG,"Comm must be of size 1");
1763b6490206SBarry Smith 
1764273d9f13SBarry Smith   B->m = B->M = PetscMax(B->m,B->M);
1765273d9f13SBarry Smith   B->n = B->N = PetscMax(B->n,B->N);
1766b0a32e0cSBarry Smith   ierr    = PetscNew(Mat_SeqBAIJ,&b);CHKERRQ(ierr);
1767b0a32e0cSBarry Smith   B->data = (void*)b;
1768549d3d68SSatish Balay   ierr    = PetscMemzero(b,sizeof(Mat_SeqBAIJ));CHKERRQ(ierr);
1769549d3d68SSatish Balay   ierr    = PetscMemcpy(B->ops,&MatOps_Values,sizeof(struct _MatOps));CHKERRQ(ierr);
17702593348eSBarry Smith   B->factor           = 0;
17712593348eSBarry Smith   B->lupivotthreshold = 1.0;
177290f02eecSBarry Smith   B->mapping          = 0;
17732593348eSBarry Smith   b->row              = 0;
17742593348eSBarry Smith   b->col              = 0;
1775e51c0b9cSSatish Balay   b->icol             = 0;
17762593348eSBarry Smith   b->reallocs         = 0;
17773e90b805SBarry Smith   b->saved_values     = 0;
1778cfce73b9SSatish Balay #if defined(PETSC_USE_MAT_SINGLE)
1779563b5814SBarry Smith   b->setvalueslen     = 0;
1780563b5814SBarry Smith   b->setvaluescopy    = PETSC_NULL;
1781563b5814SBarry Smith #endif
17822593348eSBarry Smith 
17833a64cc32SBarry Smith   ierr = PetscMapCreateMPI(B->comm,B->m,B->m,&B->rmap);CHKERRQ(ierr);
17843a64cc32SBarry Smith   ierr = PetscMapCreateMPI(B->comm,B->n,B->n,&B->cmap);CHKERRQ(ierr);
1785a5ae1ecdSBarry Smith 
1786c4992f7dSBarry Smith   b->sorted           = PETSC_FALSE;
1787c4992f7dSBarry Smith   b->roworiented      = PETSC_TRUE;
17882593348eSBarry Smith   b->nonew            = 0;
17892593348eSBarry Smith   b->diag             = 0;
17902593348eSBarry Smith   b->solve_work       = 0;
1791de6a44a3SBarry Smith   b->mult_work        = 0;
17922a1b7f2aSHong Zhang   B->spptr            = 0;
17930e6d2581SBarry Smith   B->info.nz_unneeded = (PetscReal)b->maxnz;
1794883fce79SBarry Smith   b->keepzeroedrows   = PETSC_FALSE;
1795c4319e64SHong Zhang   b->xtoy              = 0;
1796c4319e64SHong Zhang   b->XtoY              = 0;
17974e220ebcSLois Curfman McInnes 
1798f1af5d2fSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatStoreValues_C",
17993e90b805SBarry Smith                                      "MatStoreValues_SeqBAIJ",
1800bc4b532fSSatish Balay                                       MatStoreValues_SeqBAIJ);CHKERRQ(ierr);
1801f1af5d2fSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatRetrieveValues_C",
18023e90b805SBarry Smith                                      "MatRetrieveValues_SeqBAIJ",
1803bc4b532fSSatish Balay                                       MatRetrieveValues_SeqBAIJ);CHKERRQ(ierr);
1804f1af5d2fSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatSeqBAIJSetColumnIndices_C",
180527a8da17SBarry Smith                                      "MatSeqBAIJSetColumnIndices_SeqBAIJ",
1806bc4b532fSSatish Balay                                       MatSeqBAIJSetColumnIndices_SeqBAIJ);CHKERRQ(ierr);
1807a6175056SHong Zhang   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatConvert_seqbaij_seqaij_C",
1808273d9f13SBarry Smith                                      "MatConvert_SeqBAIJ_SeqAIJ",
1809273d9f13SBarry Smith                                       MatConvert_SeqBAIJ_SeqAIJ);CHKERRQ(ierr);
1810a0e1a404SHong Zhang ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatConvert_seqbaij_seqsbaij_C",
1811a0e1a404SHong Zhang                                      "MatConvert_SeqBAIJ_SeqSBAIJ",
1812a0e1a404SHong Zhang                                       MatConvert_SeqBAIJ_SeqSBAIJ);CHKERRQ(ierr);
1813a23d5eceSKris Buschelman   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatSeqBAIJSetPreallocation_C",
1814a23d5eceSKris Buschelman                                      "MatSeqBAIJSetPreallocation_SeqBAIJ",
1815a23d5eceSKris Buschelman                                       MatSeqBAIJSetPreallocation_SeqBAIJ);CHKERRQ(ierr);
18163a40ed3dSBarry Smith   PetscFunctionReturn(0);
18172593348eSBarry Smith }
1818273d9f13SBarry Smith EXTERN_C_END
18192593348eSBarry Smith 
18204a2ae208SSatish Balay #undef __FUNCT__
18214a2ae208SSatish Balay #define __FUNCT__ "MatDuplicate_SeqBAIJ"
18222e8a6d31SBarry Smith int MatDuplicate_SeqBAIJ(Mat A,MatDuplicateOption cpvalues,Mat *B)
18232593348eSBarry Smith {
18242593348eSBarry Smith   Mat         C;
1825b6490206SBarry Smith   Mat_SeqBAIJ *c,*a = (Mat_SeqBAIJ*)A->data;
182627a8da17SBarry Smith   int         i,len,mbs = a->mbs,nz = a->nz,bs2 =a->bs2,ierr;
1827de6a44a3SBarry Smith 
18283a40ed3dSBarry Smith   PetscFunctionBegin;
182929bbc08cSBarry Smith   if (a->i[mbs] != nz) SETERRQ(PETSC_ERR_PLIB,"Corrupt matrix");
18302593348eSBarry Smith 
18312593348eSBarry Smith   *B = 0;
1832273d9f13SBarry Smith   ierr = MatCreate(A->comm,A->m,A->n,A->m,A->n,&C);CHKERRQ(ierr);
1833273d9f13SBarry Smith   ierr = MatSetType(C,MATSEQBAIJ);CHKERRQ(ierr);
1834273d9f13SBarry Smith   c    = (Mat_SeqBAIJ*)C->data;
183544cd7ae7SLois Curfman McInnes 
1836b6490206SBarry Smith   c->bs         = a->bs;
18379df24120SSatish Balay   c->bs2        = a->bs2;
1838b6490206SBarry Smith   c->mbs        = a->mbs;
1839b6490206SBarry Smith   c->nbs        = a->nbs;
184035d8aa7fSBarry Smith   ierr = PetscMemcpy(C->ops,A->ops,sizeof(struct _MatOps));CHKERRQ(ierr);
18412593348eSBarry Smith 
1842b0a32e0cSBarry Smith   ierr = PetscMalloc((mbs+1)*sizeof(int),&c->imax);CHKERRQ(ierr);
1843b0a32e0cSBarry Smith   ierr = PetscMalloc((mbs+1)*sizeof(int),&c->ilen);CHKERRQ(ierr);
1844b6490206SBarry Smith   for (i=0; i<mbs; i++) {
18452593348eSBarry Smith     c->imax[i] = a->imax[i];
18462593348eSBarry Smith     c->ilen[i] = a->ilen[i];
18472593348eSBarry Smith   }
18482593348eSBarry Smith 
18492593348eSBarry Smith   /* allocate the matrix space */
1850c4992f7dSBarry Smith   c->singlemalloc = PETSC_TRUE;
18513f1db9ecSBarry Smith   len  = (mbs+1)*sizeof(int) + nz*(bs2*sizeof(MatScalar) + sizeof(int));
1852b0a32e0cSBarry Smith   ierr = PetscMalloc(len,&c->a);CHKERRQ(ierr);
18537e67e3f9SSatish Balay   c->j = (int*)(c->a + nz*bs2);
1854de6a44a3SBarry Smith   c->i = c->j + nz;
1855549d3d68SSatish Balay   ierr = PetscMemcpy(c->i,a->i,(mbs+1)*sizeof(int));CHKERRQ(ierr);
1856b6490206SBarry Smith   if (mbs > 0) {
1857549d3d68SSatish Balay     ierr = PetscMemcpy(c->j,a->j,nz*sizeof(int));CHKERRQ(ierr);
18582e8a6d31SBarry Smith     if (cpvalues == MAT_COPY_VALUES) {
1859549d3d68SSatish Balay       ierr = PetscMemcpy(c->a,a->a,bs2*nz*sizeof(MatScalar));CHKERRQ(ierr);
18602e8a6d31SBarry Smith     } else {
1861549d3d68SSatish Balay       ierr = PetscMemzero(c->a,bs2*nz*sizeof(MatScalar));CHKERRQ(ierr);
18622593348eSBarry Smith     }
18632593348eSBarry Smith   }
18642593348eSBarry Smith 
1865b0a32e0cSBarry Smith   PetscLogObjectMemory(C,len+2*(mbs+1)*sizeof(int)+sizeof(struct _p_Mat)+sizeof(Mat_SeqBAIJ));
18662593348eSBarry Smith   c->sorted      = a->sorted;
18672593348eSBarry Smith   c->roworiented = a->roworiented;
18682593348eSBarry Smith   c->nonew       = a->nonew;
18692593348eSBarry Smith 
18702593348eSBarry Smith   if (a->diag) {
1871b0a32e0cSBarry Smith     ierr = PetscMalloc((mbs+1)*sizeof(int),&c->diag);CHKERRQ(ierr);
1872b0a32e0cSBarry Smith     PetscLogObjectMemory(C,(mbs+1)*sizeof(int));
1873b6490206SBarry Smith     for (i=0; i<mbs; i++) {
18742593348eSBarry Smith       c->diag[i] = a->diag[i];
18752593348eSBarry Smith     }
187698305bb5SBarry Smith   } else c->diag        = 0;
18772593348eSBarry Smith   c->nz                 = a->nz;
18782593348eSBarry Smith   c->maxnz              = a->maxnz;
18792593348eSBarry Smith   c->solve_work         = 0;
18802a1b7f2aSHong Zhang   C->spptr              = 0;     /* Dangerous -I'm throwing away a->spptr */
18817fc0212eSBarry Smith   c->mult_work          = 0;
1882273d9f13SBarry Smith   C->preallocated       = PETSC_TRUE;
1883273d9f13SBarry Smith   C->assembled          = PETSC_TRUE;
18842593348eSBarry Smith   *B = C;
1885b0a32e0cSBarry Smith   ierr = PetscFListDuplicate(A->qlist,&C->qlist);CHKERRQ(ierr);
18863a40ed3dSBarry Smith   PetscFunctionReturn(0);
18872593348eSBarry Smith }
18882593348eSBarry Smith 
18894a2ae208SSatish Balay #undef __FUNCT__
18904a2ae208SSatish Balay #define __FUNCT__ "MatLoad_SeqBAIJ"
18918e9aea5cSBarry Smith int MatLoad_SeqBAIJ(PetscViewer viewer,const MatType type,Mat *A)
18922593348eSBarry Smith {
1893b6490206SBarry Smith   Mat_SeqBAIJ  *a;
18942593348eSBarry Smith   Mat          B;
1895f1af5d2fSBarry Smith   int          i,nz,ierr,fd,header[4],size,*rowlengths=0,M,N,bs=1;
1896b6490206SBarry Smith   int          *mask,mbs,*jj,j,rowcount,nzcount,k,*browlengths,maskcount;
189735aab85fSBarry Smith   int          kmax,jcount,block,idx,point,nzcountb,extra_rows;
1898a7c10996SSatish Balay   int          *masked,nmask,tmp,bs2,ishift;
189987828ca2SBarry Smith   PetscScalar  *aa;
190019bcc07fSBarry Smith   MPI_Comm     comm = ((PetscObject)viewer)->comm;
19012593348eSBarry Smith 
19023a40ed3dSBarry Smith   PetscFunctionBegin;
1903b0a32e0cSBarry Smith   ierr = PetscOptionsGetInt(PETSC_NULL,"-matload_block_size",&bs,PETSC_NULL);CHKERRQ(ierr);
1904de6a44a3SBarry Smith   bs2  = bs*bs;
1905b6490206SBarry Smith 
1906d132466eSBarry Smith   ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr);
190729bbc08cSBarry Smith   if (size > 1) SETERRQ(PETSC_ERR_ARG_WRONG,"view must have one processor");
1908b0a32e0cSBarry Smith   ierr = PetscViewerBinaryGetDescriptor(viewer,&fd);CHKERRQ(ierr);
19090752156aSBarry Smith   ierr = PetscBinaryRead(fd,header,4,PETSC_INT);CHKERRQ(ierr);
1910552e946dSBarry Smith   if (header[0] != MAT_FILE_COOKIE) SETERRQ(PETSC_ERR_FILE_UNEXPECTED,"not Mat object");
19112593348eSBarry Smith   M = header[1]; N = header[2]; nz = header[3];
19122593348eSBarry Smith 
1913d64ed03dSBarry Smith   if (header[3] < 0) {
191429bbc08cSBarry Smith     SETERRQ(PETSC_ERR_FILE_UNEXPECTED,"Matrix stored in special format, cannot load as SeqBAIJ");
1915d64ed03dSBarry Smith   }
1916d64ed03dSBarry Smith 
191729bbc08cSBarry Smith   if (M != N) SETERRQ(PETSC_ERR_SUP,"Can only do square matrices");
191835aab85fSBarry Smith 
191935aab85fSBarry Smith   /*
192035aab85fSBarry Smith      This code adds extra rows to make sure the number of rows is
192135aab85fSBarry Smith     divisible by the blocksize
192235aab85fSBarry Smith   */
1923b6490206SBarry Smith   mbs        = M/bs;
192435aab85fSBarry Smith   extra_rows = bs - M + bs*(mbs);
192535aab85fSBarry Smith   if (extra_rows == bs) extra_rows = 0;
192635aab85fSBarry Smith   else                  mbs++;
192735aab85fSBarry Smith   if (extra_rows) {
1928b0a32e0cSBarry Smith     PetscLogInfo(0,"MatLoad_SeqBAIJ:Padding loaded matrix to match blocksize\n");
192935aab85fSBarry Smith   }
1930b6490206SBarry Smith 
19312593348eSBarry Smith   /* read in row lengths */
1932b0a32e0cSBarry Smith   ierr = PetscMalloc((M+extra_rows)*sizeof(int),&rowlengths);CHKERRQ(ierr);
19330752156aSBarry Smith   ierr = PetscBinaryRead(fd,rowlengths,M,PETSC_INT);CHKERRQ(ierr);
193435aab85fSBarry Smith   for (i=0; i<extra_rows; i++) rowlengths[M+i] = 1;
19352593348eSBarry Smith 
1936b6490206SBarry Smith   /* read in column indices */
1937b0a32e0cSBarry Smith   ierr = PetscMalloc((nz+extra_rows)*sizeof(int),&jj);CHKERRQ(ierr);
19380752156aSBarry Smith   ierr = PetscBinaryRead(fd,jj,nz,PETSC_INT);CHKERRQ(ierr);
193935aab85fSBarry Smith   for (i=0; i<extra_rows; i++) jj[nz+i] = M+i;
1940b6490206SBarry Smith 
1941b6490206SBarry Smith   /* loop over row lengths determining block row lengths */
1942b0a32e0cSBarry Smith   ierr     = PetscMalloc(mbs*sizeof(int),&browlengths);CHKERRQ(ierr);
1943549d3d68SSatish Balay   ierr     = PetscMemzero(browlengths,mbs*sizeof(int));CHKERRQ(ierr);
1944b0a32e0cSBarry Smith   ierr     = PetscMalloc(2*mbs*sizeof(int),&mask);CHKERRQ(ierr);
1945549d3d68SSatish Balay   ierr     = PetscMemzero(mask,mbs*sizeof(int));CHKERRQ(ierr);
194635aab85fSBarry Smith   masked   = mask + mbs;
1947b6490206SBarry Smith   rowcount = 0; nzcount = 0;
1948b6490206SBarry Smith   for (i=0; i<mbs; i++) {
194935aab85fSBarry Smith     nmask = 0;
1950b6490206SBarry Smith     for (j=0; j<bs; j++) {
1951b6490206SBarry Smith       kmax = rowlengths[rowcount];
1952b6490206SBarry Smith       for (k=0; k<kmax; k++) {
195335aab85fSBarry Smith         tmp = jj[nzcount++]/bs;
195435aab85fSBarry Smith         if (!mask[tmp]) {masked[nmask++] = tmp; mask[tmp] = 1;}
1955b6490206SBarry Smith       }
1956b6490206SBarry Smith       rowcount++;
1957b6490206SBarry Smith     }
195835aab85fSBarry Smith     browlengths[i] += nmask;
195935aab85fSBarry Smith     /* zero out the mask elements we set */
196035aab85fSBarry Smith     for (j=0; j<nmask; j++) mask[masked[j]] = 0;
1961b6490206SBarry Smith   }
1962b6490206SBarry Smith 
19632593348eSBarry Smith   /* create our matrix */
1964dd23797bSKris Buschelman   ierr = MatCreate(comm,PETSC_DECIDE,PETSC_DECIDE,M+extra_rows,N+extra_rows,&B);
196578ae41b4SKris Buschelman   ierr = MatSetType(B,type);CHKERRQ(ierr);
196678ae41b4SKris Buschelman   ierr = MatSeqBAIJSetPreallocation(B,bs,0,browlengths);CHKERRQ(ierr);
1967b6490206SBarry Smith   a = (Mat_SeqBAIJ*)B->data;
19682593348eSBarry Smith 
19692593348eSBarry Smith   /* set matrix "i" values */
1970de6a44a3SBarry Smith   a->i[0] = 0;
1971b6490206SBarry Smith   for (i=1; i<= mbs; i++) {
1972b6490206SBarry Smith     a->i[i]      = a->i[i-1] + browlengths[i-1];
1973b6490206SBarry Smith     a->ilen[i-1] = browlengths[i-1];
19742593348eSBarry Smith   }
1975b6490206SBarry Smith   a->nz         = 0;
1976b6490206SBarry Smith   for (i=0; i<mbs; i++) a->nz += browlengths[i];
19772593348eSBarry Smith 
1978b6490206SBarry Smith   /* read in nonzero values */
197987828ca2SBarry Smith   ierr = PetscMalloc((nz+extra_rows)*sizeof(PetscScalar),&aa);CHKERRQ(ierr);
19800752156aSBarry Smith   ierr = PetscBinaryRead(fd,aa,nz,PETSC_SCALAR);CHKERRQ(ierr);
198135aab85fSBarry Smith   for (i=0; i<extra_rows; i++) aa[nz+i] = 1.0;
1982b6490206SBarry Smith 
1983b6490206SBarry Smith   /* set "a" and "j" values into matrix */
1984b6490206SBarry Smith   nzcount = 0; jcount = 0;
1985b6490206SBarry Smith   for (i=0; i<mbs; i++) {
1986b6490206SBarry Smith     nzcountb = nzcount;
198735aab85fSBarry Smith     nmask    = 0;
1988b6490206SBarry Smith     for (j=0; j<bs; j++) {
1989b6490206SBarry Smith       kmax = rowlengths[i*bs+j];
1990b6490206SBarry Smith       for (k=0; k<kmax; k++) {
199135aab85fSBarry Smith         tmp = jj[nzcount++]/bs;
199235aab85fSBarry Smith 	if (!mask[tmp]) { masked[nmask++] = tmp; mask[tmp] = 1;}
1993b6490206SBarry Smith       }
1994b6490206SBarry Smith     }
1995de6a44a3SBarry Smith     /* sort the masked values */
1996433994e6SBarry Smith     ierr = PetscSortInt(nmask,masked);CHKERRQ(ierr);
1997de6a44a3SBarry Smith 
1998b6490206SBarry Smith     /* set "j" values into matrix */
1999b6490206SBarry Smith     maskcount = 1;
200035aab85fSBarry Smith     for (j=0; j<nmask; j++) {
200135aab85fSBarry Smith       a->j[jcount++]  = masked[j];
2002de6a44a3SBarry Smith       mask[masked[j]] = maskcount++;
2003b6490206SBarry Smith     }
2004b6490206SBarry Smith     /* set "a" values into matrix */
2005de6a44a3SBarry Smith     ishift = bs2*a->i[i];
2006b6490206SBarry Smith     for (j=0; j<bs; j++) {
2007b6490206SBarry Smith       kmax = rowlengths[i*bs+j];
2008b6490206SBarry Smith       for (k=0; k<kmax; k++) {
2009de6a44a3SBarry Smith         tmp       = jj[nzcountb]/bs ;
2010de6a44a3SBarry Smith         block     = mask[tmp] - 1;
2011de6a44a3SBarry Smith         point     = jj[nzcountb] - bs*tmp;
2012de6a44a3SBarry Smith         idx       = ishift + bs2*block + j + bs*point;
2013375fe846SBarry Smith         a->a[idx] = (MatScalar)aa[nzcountb++];
2014b6490206SBarry Smith       }
2015b6490206SBarry Smith     }
201635aab85fSBarry Smith     /* zero out the mask elements we set */
201735aab85fSBarry Smith     for (j=0; j<nmask; j++) mask[masked[j]] = 0;
2018b6490206SBarry Smith   }
201929bbc08cSBarry Smith   if (jcount != a->nz) SETERRQ(PETSC_ERR_FILE_UNEXPECTED,"Bad binary matrix");
2020b6490206SBarry Smith 
2021606d414cSSatish Balay   ierr = PetscFree(rowlengths);CHKERRQ(ierr);
2022606d414cSSatish Balay   ierr = PetscFree(browlengths);CHKERRQ(ierr);
2023606d414cSSatish Balay   ierr = PetscFree(aa);CHKERRQ(ierr);
2024606d414cSSatish Balay   ierr = PetscFree(jj);CHKERRQ(ierr);
2025606d414cSSatish Balay   ierr = PetscFree(mask);CHKERRQ(ierr);
2026b6490206SBarry Smith 
202778ae41b4SKris Buschelman   ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
202878ae41b4SKris Buschelman   ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
20299c01be13SBarry Smith   ierr = MatView_Private(B);CHKERRQ(ierr);
203078ae41b4SKris Buschelman 
203178ae41b4SKris Buschelman   *A = B;
20323a40ed3dSBarry Smith   PetscFunctionReturn(0);
20332593348eSBarry Smith }
20342593348eSBarry Smith 
20354a2ae208SSatish Balay #undef __FUNCT__
20364a2ae208SSatish Balay #define __FUNCT__ "MatCreateSeqBAIJ"
2037273d9f13SBarry Smith /*@C
2038273d9f13SBarry Smith    MatCreateSeqBAIJ - Creates a sparse matrix in block AIJ (block
2039273d9f13SBarry Smith    compressed row) format.  For good matrix assembly performance the
2040273d9f13SBarry Smith    user should preallocate the matrix storage by setting the parameter nz
2041273d9f13SBarry Smith    (or the array nnz).  By setting these parameters accurately, performance
2042273d9f13SBarry Smith    during matrix assembly can be increased by more than a factor of 50.
20432593348eSBarry Smith 
2044273d9f13SBarry Smith    Collective on MPI_Comm
2045273d9f13SBarry Smith 
2046273d9f13SBarry Smith    Input Parameters:
2047273d9f13SBarry Smith +  comm - MPI communicator, set to PETSC_COMM_SELF
2048273d9f13SBarry Smith .  bs - size of block
2049273d9f13SBarry Smith .  m - number of rows
2050273d9f13SBarry Smith .  n - number of columns
205135d8aa7fSBarry Smith .  nz - number of nonzero blocks  per block row (same for all rows)
205235d8aa7fSBarry Smith -  nnz - array containing the number of nonzero blocks in the various block rows
2053273d9f13SBarry Smith          (possibly different for each block row) or PETSC_NULL
2054273d9f13SBarry Smith 
2055273d9f13SBarry Smith    Output Parameter:
2056273d9f13SBarry Smith .  A - the matrix
2057273d9f13SBarry Smith 
2058273d9f13SBarry Smith    Options Database Keys:
2059273d9f13SBarry Smith .   -mat_no_unroll - uses code that does not unroll the loops in the
2060273d9f13SBarry Smith                      block calculations (much slower)
2061273d9f13SBarry Smith .    -mat_block_size - size of the blocks to use
2062273d9f13SBarry Smith 
2063273d9f13SBarry Smith    Level: intermediate
2064273d9f13SBarry Smith 
2065273d9f13SBarry Smith    Notes:
206635d8aa7fSBarry Smith    A nonzero block is any block that as 1 or more nonzeros in it
206735d8aa7fSBarry Smith 
2068273d9f13SBarry Smith    The block AIJ format is fully compatible with standard Fortran 77
2069273d9f13SBarry Smith    storage.  That is, the stored row and column indices can begin at
2070273d9f13SBarry Smith    either one (as in Fortran) or zero.  See the users' manual for details.
2071273d9f13SBarry Smith 
2072273d9f13SBarry Smith    Specify the preallocated storage with either nz or nnz (not both).
2073273d9f13SBarry Smith    Set nz=PETSC_DEFAULT and nnz=PETSC_NULL for PETSc to control dynamic memory
2074273d9f13SBarry Smith    allocation.  For additional details, see the users manual chapter on
2075273d9f13SBarry Smith    matrices.
2076273d9f13SBarry Smith 
2077273d9f13SBarry Smith .seealso: MatCreate(), MatCreateSeqAIJ(), MatSetValues(), MatCreateMPIBAIJ()
2078273d9f13SBarry Smith @*/
2079ca01db9bSBarry Smith int MatCreateSeqBAIJ(MPI_Comm comm,int bs,int m,int n,int nz,const int nnz[],Mat *A)
2080273d9f13SBarry Smith {
2081273d9f13SBarry Smith   int ierr;
2082273d9f13SBarry Smith 
2083273d9f13SBarry Smith   PetscFunctionBegin;
2084273d9f13SBarry Smith   ierr = MatCreate(comm,m,n,m,n,A);CHKERRQ(ierr);
2085273d9f13SBarry Smith   ierr = MatSetType(*A,MATSEQBAIJ);CHKERRQ(ierr);
2086273d9f13SBarry Smith   ierr = MatSeqBAIJSetPreallocation(*A,bs,nz,nnz);CHKERRQ(ierr);
2087273d9f13SBarry Smith   PetscFunctionReturn(0);
2088273d9f13SBarry Smith }
2089273d9f13SBarry Smith 
20904a2ae208SSatish Balay #undef __FUNCT__
20914a2ae208SSatish Balay #define __FUNCT__ "MatSeqBAIJSetPreallocation"
2092273d9f13SBarry Smith /*@C
2093273d9f13SBarry Smith    MatSeqBAIJSetPreallocation - Sets the block size and expected nonzeros
2094273d9f13SBarry Smith    per row in the matrix. For good matrix assembly performance the
2095273d9f13SBarry Smith    user should preallocate the matrix storage by setting the parameter nz
2096273d9f13SBarry Smith    (or the array nnz).  By setting these parameters accurately, performance
2097273d9f13SBarry Smith    during matrix assembly can be increased by more than a factor of 50.
2098273d9f13SBarry Smith 
2099273d9f13SBarry Smith    Collective on MPI_Comm
2100273d9f13SBarry Smith 
2101273d9f13SBarry Smith    Input Parameters:
2102273d9f13SBarry Smith +  A - the matrix
2103273d9f13SBarry Smith .  bs - size of block
2104273d9f13SBarry Smith .  nz - number of block nonzeros per block row (same for all rows)
2105273d9f13SBarry Smith -  nnz - array containing the number of block nonzeros in the various block rows
2106273d9f13SBarry Smith          (possibly different for each block row) or PETSC_NULL
2107273d9f13SBarry Smith 
2108273d9f13SBarry Smith    Options Database Keys:
2109273d9f13SBarry Smith .   -mat_no_unroll - uses code that does not unroll the loops in the
2110273d9f13SBarry Smith                      block calculations (much slower)
2111273d9f13SBarry Smith .    -mat_block_size - size of the blocks to use
2112273d9f13SBarry Smith 
2113273d9f13SBarry Smith    Level: intermediate
2114273d9f13SBarry Smith 
2115273d9f13SBarry Smith    Notes:
2116273d9f13SBarry Smith    The block AIJ format is fully compatible with standard Fortran 77
2117273d9f13SBarry Smith    storage.  That is, the stored row and column indices can begin at
2118273d9f13SBarry Smith    either one (as in Fortran) or zero.  See the users' manual for details.
2119273d9f13SBarry Smith 
2120273d9f13SBarry Smith    Specify the preallocated storage with either nz or nnz (not both).
2121273d9f13SBarry Smith    Set nz=PETSC_DEFAULT and nnz=PETSC_NULL for PETSc to control dynamic memory
2122273d9f13SBarry Smith    allocation.  For additional details, see the users manual chapter on
2123273d9f13SBarry Smith    matrices.
2124273d9f13SBarry Smith 
2125273d9f13SBarry Smith .seealso: MatCreate(), MatCreateSeqAIJ(), MatSetValues(), MatCreateMPIBAIJ()
2126273d9f13SBarry Smith @*/
2127ca01db9bSBarry Smith int MatSeqBAIJSetPreallocation(Mat B,int bs,int nz,const int nnz[])
2128273d9f13SBarry Smith {
2129ca01db9bSBarry Smith   int ierr,(*f)(Mat,int,int,const int[]);
2130273d9f13SBarry Smith 
2131273d9f13SBarry Smith   PetscFunctionBegin;
2132a23d5eceSKris Buschelman   ierr = PetscObjectQueryFunction((PetscObject)B,"MatSeqBAIJSetPreallocation_C",(void (**)(void))&f);CHKERRQ(ierr);
2133a23d5eceSKris Buschelman   if (f) {
2134a23d5eceSKris Buschelman     ierr = (*f)(B,bs,nz,nnz);CHKERRQ(ierr);
2135273d9f13SBarry Smith   }
2136273d9f13SBarry Smith   PetscFunctionReturn(0);
2137273d9f13SBarry Smith }
2138