xref: /petsc/src/mat/impls/aij/seq/aij.c (revision 6831982abb6453c2f3e25efecb5d0951d333371e)
1a5eb4965SSatish Balay #ifdef PETSC_RCS_HEADER
2*6831982aSBarry Smith static char vcid[] = "$Id: aij.c,v 1.329 1999/10/13 20:37:19 bsmith Exp bsmith $";
317ab2063SBarry Smith #endif
417ab2063SBarry Smith 
5d5d45c9bSBarry Smith /*
63369ce9aSBarry Smith     Defines the basic matrix operations for the AIJ (compressed row)
7d5d45c9bSBarry Smith   matrix storage format.
8d5d45c9bSBarry Smith */
93369ce9aSBarry Smith 
103369ce9aSBarry Smith #include "sys.h"
1170f55243SBarry Smith #include "src/mat/impls/aij/seq/aij.h"
12f5eb4b81SSatish Balay #include "src/vec/vecimpl.h"
13f5eb4b81SSatish Balay #include "src/inline/spops.h"
148d195f9aSBarry Smith #include "src/inline/dot.h"
15eeb667a2SSatish Balay #include "bitarray.h"
1617ab2063SBarry Smith 
17a2ce50c7SBarry Smith /*
18a2ce50c7SBarry Smith     Basic AIJ format ILU based on drop tolerance
19a2ce50c7SBarry Smith */
205615d1e5SSatish Balay #undef __FUNC__
215615d1e5SSatish Balay #define __FUNC__ "MatILUDTFactor_SeqAIJ"
22a2ce50c7SBarry Smith int MatILUDTFactor_SeqAIJ(Mat A,double dt,int maxnz,IS row,IS col,Mat *fact)
23a2ce50c7SBarry Smith {
24a2ce50c7SBarry Smith   /* Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data; */
25a2ce50c7SBarry Smith 
263a40ed3dSBarry Smith   PetscFunctionBegin;
273f1db9ecSBarry Smith   SETERRQ(1,0,"Not implemented");
28aa482453SBarry Smith #if !defined(PETSC_USE_DEBUG)
29d64ed03dSBarry Smith   PetscFunctionReturn(0);
30d64ed03dSBarry Smith #endif
31a2ce50c7SBarry Smith }
32a2ce50c7SBarry Smith 
33bcd2baecSBarry Smith extern int MatToSymmetricIJ_SeqAIJ(int,int*,int*,int,int,int**,int**);
3417ab2063SBarry Smith 
355615d1e5SSatish Balay #undef __FUNC__
365615d1e5SSatish Balay #define __FUNC__ "MatGetRowIJ_SeqAIJ"
378f6be9afSLois Curfman McInnes int MatGetRowIJ_SeqAIJ(Mat A,int oshift,PetscTruth symmetric,int *m,int **ia,int **ja,
386945ee14SBarry Smith                            PetscTruth *done)
3917ab2063SBarry Smith {
40416022c9SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data;
416945ee14SBarry Smith   int        ierr,i,ishift;
4217ab2063SBarry Smith 
433a40ed3dSBarry Smith   PetscFunctionBegin;
4431625ec5SSatish Balay   *m     = A->m;
453a40ed3dSBarry Smith   if (!ia) PetscFunctionReturn(0);
466945ee14SBarry Smith   ishift = a->indexshift;
476945ee14SBarry Smith   if (symmetric) {
4831625ec5SSatish Balay     ierr = MatToSymmetricIJ_SeqAIJ(a->m,a->i,a->j,ishift,oshift,ia,ja);CHKERRQ(ierr);
496945ee14SBarry Smith   } else if (oshift == 0 && ishift == -1) {
5031625ec5SSatish Balay     int nz = a->i[a->m];
513b2fbd54SBarry Smith     /* malloc space and  subtract 1 from i and j indices */
5231625ec5SSatish Balay     *ia = (int *) PetscMalloc( (a->m+1)*sizeof(int) );CHKPTRQ(*ia);
533b2fbd54SBarry Smith     *ja = (int *) PetscMalloc( (nz+1)*sizeof(int) );CHKPTRQ(*ja);
543b2fbd54SBarry Smith     for ( i=0; i<nz; i++ ) (*ja)[i] = a->j[i] - 1;
5531625ec5SSatish Balay     for ( i=0; i<a->m+1; i++ ) (*ia)[i] = a->i[i] - 1;
566945ee14SBarry Smith   } else if (oshift == 1 && ishift == 0) {
5731625ec5SSatish Balay     int nz = a->i[a->m] + 1;
583b2fbd54SBarry Smith     /* malloc space and  add 1 to i and j indices */
5931625ec5SSatish Balay     *ia = (int *) PetscMalloc( (a->m+1)*sizeof(int) );CHKPTRQ(*ia);
603b2fbd54SBarry Smith     *ja = (int *) PetscMalloc( (nz+1)*sizeof(int) );CHKPTRQ(*ja);
613b2fbd54SBarry Smith     for ( i=0; i<nz; i++ ) (*ja)[i] = a->j[i] + 1;
6231625ec5SSatish Balay     for ( i=0; i<a->m+1; i++ ) (*ia)[i] = a->i[i] + 1;
636945ee14SBarry Smith   } else {
646945ee14SBarry Smith     *ia = a->i; *ja = a->j;
65a2ce50c7SBarry Smith   }
66a2ce50c7SBarry Smith 
673a40ed3dSBarry Smith   PetscFunctionReturn(0);
68a2744918SBarry Smith }
69a2744918SBarry Smith 
705615d1e5SSatish Balay #undef __FUNC__
715615d1e5SSatish Balay #define __FUNC__ "MatRestoreRowIJ_SeqAIJ"
728f6be9afSLois Curfman McInnes int MatRestoreRowIJ_SeqAIJ(Mat A,int oshift,PetscTruth symmetric,int *n,int **ia,int **ja,
736945ee14SBarry Smith                                PetscTruth *done)
746945ee14SBarry Smith {
756945ee14SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data;
76606d414cSSatish Balay   int        ishift = a->indexshift,ierr;
776945ee14SBarry Smith 
783a40ed3dSBarry Smith   PetscFunctionBegin;
793a40ed3dSBarry Smith   if (!ia) PetscFunctionReturn(0);
803b2fbd54SBarry Smith   if (symmetric || (oshift == 0 && ishift == -1) || (oshift == 1 && ishift == 0)) {
81606d414cSSatish Balay     ierr = PetscFree(*ia);CHKERRQ(ierr);
82606d414cSSatish Balay     ierr = PetscFree(*ja);CHKERRQ(ierr);
83bcd2baecSBarry Smith   }
843a40ed3dSBarry Smith   PetscFunctionReturn(0);
8517ab2063SBarry Smith }
8617ab2063SBarry Smith 
875615d1e5SSatish Balay #undef __FUNC__
885615d1e5SSatish Balay #define __FUNC__ "MatGetColumnIJ_SeqAIJ"
8943a90d84SBarry Smith int MatGetColumnIJ_SeqAIJ(Mat A,int oshift,PetscTruth symmetric,int *nn,int **ia,int **ja,
903b2fbd54SBarry Smith                            PetscTruth *done)
913b2fbd54SBarry Smith {
923b2fbd54SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data;
93a93ec695SBarry Smith   int        ierr,i,ishift = a->indexshift,*collengths,*cia,*cja,n = A->n,m = A->m;
94a93ec695SBarry Smith   int        nz = a->i[m]+ishift,row,*jj,mr,col;
953b2fbd54SBarry Smith 
963a40ed3dSBarry Smith   PetscFunctionBegin;
973b2fbd54SBarry Smith   *nn     = A->n;
983a40ed3dSBarry Smith   if (!ia) PetscFunctionReturn(0);
993b2fbd54SBarry Smith   if (symmetric) {
100179192dfSSatish Balay     ierr = MatToSymmetricIJ_SeqAIJ(a->m,a->i,a->j,ishift,oshift,ia,ja);CHKERRQ(ierr);
1013b2fbd54SBarry Smith   } else {
10261d2ded1SBarry Smith     collengths = (int *) PetscMalloc( (n+1)*sizeof(int) );CHKPTRQ(collengths);
103549d3d68SSatish Balay     ierr       = PetscMemzero(collengths,n*sizeof(int));CHKERRQ(ierr);
1043b2fbd54SBarry Smith     cia        = (int *) PetscMalloc( (n+1)*sizeof(int) );CHKPTRQ(cia);
105a93ec695SBarry Smith     cja        = (int *) PetscMalloc( (nz+1)*sizeof(int) );CHKPTRQ(cja);
1063b2fbd54SBarry Smith     jj = a->j;
1073b2fbd54SBarry Smith     for ( i=0; i<nz; i++ ) {
1083b2fbd54SBarry Smith       collengths[jj[i] + ishift]++;
1093b2fbd54SBarry Smith     }
1103b2fbd54SBarry Smith     cia[0] = oshift;
1113b2fbd54SBarry Smith     for ( i=0; i<n; i++) {
1123b2fbd54SBarry Smith       cia[i+1] = cia[i] + collengths[i];
1133b2fbd54SBarry Smith     }
114549d3d68SSatish Balay     ierr = PetscMemzero(collengths,n*sizeof(int));CHKERRQ(ierr);
1153b2fbd54SBarry Smith     jj   = a->j;
116a93ec695SBarry Smith     for ( row=0; row<m; row++ ) {
117a93ec695SBarry Smith       mr = a->i[row+1] - a->i[row];
118a93ec695SBarry Smith       for ( i=0; i<mr; i++ ) {
1193b2fbd54SBarry Smith         col = *jj++ + ishift;
1203b2fbd54SBarry Smith         cja[cia[col] + collengths[col]++ - oshift] = row + oshift;
1213b2fbd54SBarry Smith       }
1223b2fbd54SBarry Smith     }
123606d414cSSatish Balay     ierr = PetscFree(collengths);CHKERRQ(ierr);
1243b2fbd54SBarry Smith     *ia = cia; *ja = cja;
1253b2fbd54SBarry Smith   }
1263b2fbd54SBarry Smith 
1273a40ed3dSBarry Smith   PetscFunctionReturn(0);
1283b2fbd54SBarry Smith }
1293b2fbd54SBarry Smith 
1305615d1e5SSatish Balay #undef __FUNC__
1315615d1e5SSatish Balay #define __FUNC__ "MatRestoreColumnIJ_SeqAIJ"
13243a90d84SBarry Smith int MatRestoreColumnIJ_SeqAIJ(Mat A,int oshift,PetscTruth symmetric,int *n,int **ia,
1333b2fbd54SBarry Smith                                      int **ja,PetscTruth *done)
1343b2fbd54SBarry Smith {
135606d414cSSatish Balay   int ierr;
136606d414cSSatish Balay 
1373a40ed3dSBarry Smith   PetscFunctionBegin;
1383a40ed3dSBarry Smith   if (!ia) PetscFunctionReturn(0);
1393b2fbd54SBarry Smith 
140606d414cSSatish Balay   ierr = PetscFree(*ia);CHKERRQ(ierr);
141606d414cSSatish Balay   ierr = PetscFree(*ja);CHKERRQ(ierr);
1423b2fbd54SBarry Smith 
1433a40ed3dSBarry Smith   PetscFunctionReturn(0);
1443b2fbd54SBarry Smith }
1453b2fbd54SBarry Smith 
146227d817aSBarry Smith #define CHUNKSIZE   15
14717ab2063SBarry Smith 
1485615d1e5SSatish Balay #undef __FUNC__
1495615d1e5SSatish Balay #define __FUNC__ "MatSetValues_SeqAIJ"
15061d2ded1SBarry Smith int MatSetValues_SeqAIJ(Mat A,int m,int *im,int n,int *in,Scalar *v,InsertMode is)
15117ab2063SBarry Smith {
152416022c9SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data;
153416022c9SBarry Smith   int        *rp,k,low,high,t,ii,row,nrow,i,col,l,rmax, N, sorted = a->sorted;
1544b0e389bSBarry Smith   int        *imax = a->imax, *ai = a->i, *ailen = a->ilen,roworiented = a->roworiented;
155549d3d68SSatish Balay   int        *aj = a->j, nonew = a->nonew,shift = a->indexshift,ierr;
156416022c9SBarry Smith   Scalar     *ap,value, *aa = a->a;
15717ab2063SBarry Smith 
1583a40ed3dSBarry Smith   PetscFunctionBegin;
15917ab2063SBarry Smith   for ( k=0; k<m; k++ ) { /* loop over added rows */
160416022c9SBarry Smith     row  = im[k];
1615ef9f2a5SBarry Smith     if (row < 0) continue;
162aa482453SBarry Smith #if defined(PETSC_USE_BOPT_g)
16332e87ba3SBarry Smith     if (row >= a->m) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,0,"Row too large: row %d max %d",row,a->m);
1643b2fbd54SBarry Smith #endif
16517ab2063SBarry Smith     rp   = aj + ai[row] + shift; ap = aa + ai[row] + shift;
16617ab2063SBarry Smith     rmax = imax[row]; nrow = ailen[row];
167416022c9SBarry Smith     low = 0;
16817ab2063SBarry Smith     for ( l=0; l<n; l++ ) { /* loop over added columns */
1695ef9f2a5SBarry Smith       if (in[l] < 0) continue;
170aa482453SBarry Smith #if defined(PETSC_USE_BOPT_g)
17132e87ba3SBarry Smith       if (in[l] >= a->n) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,0,"Column too large: col %d max %d",in[l],a->n);
1723b2fbd54SBarry Smith #endif
1734b0e389bSBarry Smith       col = in[l] - shift;
1744b0e389bSBarry Smith       if (roworiented) {
1755ef9f2a5SBarry Smith         value = v[l + k*n];
176bef8e0ddSBarry Smith       } else {
1774b0e389bSBarry Smith         value = v[k + l*m];
1784b0e389bSBarry Smith       }
179416022c9SBarry Smith       if (!sorted) low = 0; high = nrow;
180416022c9SBarry Smith       while (high-low > 5) {
181416022c9SBarry Smith         t = (low+high)/2;
182416022c9SBarry Smith         if (rp[t] > col) high = t;
183416022c9SBarry Smith         else             low  = t;
18417ab2063SBarry Smith       }
185416022c9SBarry Smith       for ( i=low; i<high; i++ ) {
18617ab2063SBarry Smith         if (rp[i] > col) break;
18717ab2063SBarry Smith         if (rp[i] == col) {
188416022c9SBarry Smith           if (is == ADD_VALUES) ap[i] += value;
18917ab2063SBarry Smith           else                  ap[i] = value;
19017ab2063SBarry Smith           goto noinsert;
19117ab2063SBarry Smith         }
19217ab2063SBarry Smith       }
193c2653b3dSLois Curfman McInnes       if (nonew == 1) goto noinsert;
194a8c6a408SBarry Smith       else if (nonew == -1) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Inserting a new nonzero in the matrix");
19517ab2063SBarry Smith       if (nrow >= rmax) {
19617ab2063SBarry Smith         /* there is no extra room in row, therefore enlarge */
197416022c9SBarry Smith         int    new_nz = ai[a->m] + CHUNKSIZE,len,*new_i,*new_j;
19817ab2063SBarry Smith         Scalar *new_a;
19917ab2063SBarry Smith 
200a8c6a408SBarry Smith         if (nonew == -2) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Inserting a new nonzero in the matrix");
20196854ed6SLois Curfman McInnes 
20217ab2063SBarry Smith         /* malloc new storage space */
203416022c9SBarry Smith         len     = new_nz*(sizeof(int)+sizeof(Scalar))+(a->m+1)*sizeof(int);
2040452661fSBarry Smith         new_a   = (Scalar *) PetscMalloc( len );CHKPTRQ(new_a);
20517ab2063SBarry Smith         new_j   = (int *) (new_a + new_nz);
20617ab2063SBarry Smith         new_i   = new_j + new_nz;
20717ab2063SBarry Smith 
20817ab2063SBarry Smith         /* copy over old data into new slots */
20917ab2063SBarry Smith         for ( ii=0; ii<row+1; ii++ ) {new_i[ii] = ai[ii];}
210416022c9SBarry Smith         for ( ii=row+1; ii<a->m+1; ii++ ) {new_i[ii] = ai[ii]+CHUNKSIZE;}
211549d3d68SSatish Balay         ierr = PetscMemcpy(new_j,aj,(ai[row]+nrow+shift)*sizeof(int));CHKERRQ(ierr);
212416022c9SBarry Smith         len  = (new_nz - CHUNKSIZE - ai[row] - nrow - shift);
213549d3d68SSatish Balay         ierr = PetscMemcpy(new_j+ai[row]+shift+nrow+CHUNKSIZE,aj+ai[row]+shift+nrow,len*sizeof(int));CHKERRQ(ierr);
214549d3d68SSatish Balay         ierr = PetscMemcpy(new_a,aa,(ai[row]+nrow+shift)*sizeof(Scalar));CHKERRQ(ierr);
215549d3d68SSatish Balay         ierr = PetscMemcpy(new_a+ai[row]+shift+nrow+CHUNKSIZE,aa+ai[row]+shift+nrow,len*sizeof(Scalar));CHKERRQ(ierr);
21617ab2063SBarry Smith         /* free up old matrix storage */
217606d414cSSatish Balay         ierr = PetscFree(a->a);CHKERRQ(ierr);
218606d414cSSatish Balay         if (!a->singlemalloc) {
219606d414cSSatish Balay           ierr = PetscFree(a->i);CHKERRQ(ierr);
220606d414cSSatish Balay           ierr = PetscFree(a->j);CHKERRQ(ierr);
221606d414cSSatish Balay         }
222416022c9SBarry Smith         aa = a->a = new_a; ai = a->i = new_i; aj = a->j = new_j;
223416022c9SBarry Smith         a->singlemalloc = 1;
22417ab2063SBarry Smith 
22517ab2063SBarry Smith         rp   = aj + ai[row] + shift; ap = aa + ai[row] + shift;
226416022c9SBarry Smith         rmax = imax[row] = imax[row] + CHUNKSIZE;
227416022c9SBarry Smith         PLogObjectMemory(A,CHUNKSIZE*(sizeof(int) + sizeof(Scalar)));
228416022c9SBarry Smith         a->maxnz += CHUNKSIZE;
229b810aeb4SBarry Smith         a->reallocs++;
23017ab2063SBarry Smith       }
231416022c9SBarry Smith       N = nrow++ - 1; a->nz++;
232416022c9SBarry Smith       /* shift up all the later entries in this row */
233416022c9SBarry Smith       for ( ii=N; ii>=i; ii-- ) {
23417ab2063SBarry Smith         rp[ii+1] = rp[ii];
23517ab2063SBarry Smith         ap[ii+1] = ap[ii];
23617ab2063SBarry Smith       }
23717ab2063SBarry Smith       rp[i] = col;
23817ab2063SBarry Smith       ap[i] = value;
23917ab2063SBarry Smith       noinsert:;
240416022c9SBarry Smith       low = i + 1;
24117ab2063SBarry Smith     }
24217ab2063SBarry Smith     ailen[row] = nrow;
24317ab2063SBarry Smith   }
2443a40ed3dSBarry Smith   PetscFunctionReturn(0);
24517ab2063SBarry Smith }
24617ab2063SBarry Smith 
2475615d1e5SSatish Balay #undef __FUNC__
2485615d1e5SSatish Balay #define __FUNC__ "MatGetValues_SeqAIJ"
2498f6be9afSLois Curfman McInnes int MatGetValues_SeqAIJ(Mat A,int m,int *im,int n,int *in,Scalar *v)
2507eb43aa7SLois Curfman McInnes {
2517eb43aa7SLois Curfman McInnes   Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data;
252b49de8d1SLois Curfman McInnes   int        *rp, k, low, high, t, row, nrow, i, col, l, *aj = a->j;
2537eb43aa7SLois Curfman McInnes   int        *ai = a->i, *ailen = a->ilen, shift = a->indexshift;
2547eb43aa7SLois Curfman McInnes   Scalar     *ap, *aa = a->a, zero = 0.0;
2557eb43aa7SLois Curfman McInnes 
2563a40ed3dSBarry Smith   PetscFunctionBegin;
2577eb43aa7SLois Curfman McInnes   for ( k=0; k<m; k++ ) { /* loop over rows */
2587eb43aa7SLois Curfman McInnes     row  = im[k];
259a8c6a408SBarry Smith     if (row < 0) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Negative row");
260a8c6a408SBarry Smith     if (row >= a->m) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Row too large");
2617eb43aa7SLois Curfman McInnes     rp   = aj + ai[row] + shift; ap = aa + ai[row] + shift;
2627eb43aa7SLois Curfman McInnes     nrow = ailen[row];
2637eb43aa7SLois Curfman McInnes     for ( l=0; l<n; l++ ) { /* loop over columns */
264a8c6a408SBarry Smith       if (in[l] < 0) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Negative column");
265a8c6a408SBarry Smith       if (in[l] >= a->n) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Column too large");
2667eb43aa7SLois Curfman McInnes       col = in[l] - shift;
2677eb43aa7SLois Curfman McInnes       high = nrow; low = 0; /* assume unsorted */
2687eb43aa7SLois Curfman McInnes       while (high-low > 5) {
2697eb43aa7SLois Curfman McInnes         t = (low+high)/2;
2707eb43aa7SLois Curfman McInnes         if (rp[t] > col) high = t;
2717eb43aa7SLois Curfman McInnes         else             low  = t;
2727eb43aa7SLois Curfman McInnes       }
2737eb43aa7SLois Curfman McInnes       for ( i=low; i<high; i++ ) {
2747eb43aa7SLois Curfman McInnes         if (rp[i] > col) break;
2757eb43aa7SLois Curfman McInnes         if (rp[i] == col) {
276b49de8d1SLois Curfman McInnes           *v++ = ap[i];
2777eb43aa7SLois Curfman McInnes           goto finished;
2787eb43aa7SLois Curfman McInnes         }
2797eb43aa7SLois Curfman McInnes       }
280b49de8d1SLois Curfman McInnes       *v++ = zero;
2817eb43aa7SLois Curfman McInnes       finished:;
2827eb43aa7SLois Curfman McInnes     }
2837eb43aa7SLois Curfman McInnes   }
2843a40ed3dSBarry Smith   PetscFunctionReturn(0);
2857eb43aa7SLois Curfman McInnes }
2867eb43aa7SLois Curfman McInnes 
28717ab2063SBarry Smith 
2885615d1e5SSatish Balay #undef __FUNC__
2895615d1e5SSatish Balay #define __FUNC__ "MatView_SeqAIJ_Binary"
290480ef9eaSBarry Smith int MatView_SeqAIJ_Binary(Mat A,Viewer viewer)
29117ab2063SBarry Smith {
292416022c9SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data;
293416022c9SBarry Smith   int        i, fd, *col_lens, ierr;
29417ab2063SBarry Smith 
2953a40ed3dSBarry Smith   PetscFunctionBegin;
29690ace30eSBarry Smith   ierr = ViewerBinaryGetDescriptor(viewer,&fd);CHKERRQ(ierr);
2970452661fSBarry Smith   col_lens = (int *) PetscMalloc( (4+a->m)*sizeof(int) );CHKPTRQ(col_lens);
298416022c9SBarry Smith   col_lens[0] = MAT_COOKIE;
299416022c9SBarry Smith   col_lens[1] = a->m;
300416022c9SBarry Smith   col_lens[2] = a->n;
301416022c9SBarry Smith   col_lens[3] = a->nz;
302416022c9SBarry Smith 
303416022c9SBarry Smith   /* store lengths of each row and write (including header) to file */
304416022c9SBarry Smith   for ( i=0; i<a->m; i++ ) {
305416022c9SBarry Smith     col_lens[4+i] = a->i[i+1] - a->i[i];
30617ab2063SBarry Smith   }
3070752156aSBarry Smith   ierr = PetscBinaryWrite(fd,col_lens,4+a->m,PETSC_INT,1);CHKERRQ(ierr);
308606d414cSSatish Balay   ierr = PetscFree(col_lens);CHKERRQ(ierr);
309416022c9SBarry Smith 
310416022c9SBarry Smith   /* store column indices (zero start index) */
311416022c9SBarry Smith   if (a->indexshift) {
312416022c9SBarry Smith     for ( i=0; i<a->nz; i++ ) a->j[i]--;
31317ab2063SBarry Smith   }
3140752156aSBarry Smith   ierr = PetscBinaryWrite(fd,a->j,a->nz,PETSC_INT,0);CHKERRQ(ierr);
315416022c9SBarry Smith   if (a->indexshift) {
316416022c9SBarry Smith     for ( i=0; i<a->nz; i++ ) a->j[i]++;
31717ab2063SBarry Smith   }
318416022c9SBarry Smith 
319416022c9SBarry Smith   /* store nonzero values */
3200752156aSBarry Smith   ierr = PetscBinaryWrite(fd,a->a,a->nz,PETSC_SCALAR,0);CHKERRQ(ierr);
3213a40ed3dSBarry Smith   PetscFunctionReturn(0);
32217ab2063SBarry Smith }
323416022c9SBarry Smith 
3245615d1e5SSatish Balay #undef __FUNC__
3255615d1e5SSatish Balay #define __FUNC__ "MatView_SeqAIJ_ASCII"
326480ef9eaSBarry Smith int MatView_SeqAIJ_ASCII(Mat A,Viewer viewer)
327416022c9SBarry Smith {
328416022c9SBarry Smith   Mat_SeqAIJ  *a = (Mat_SeqAIJ *) A->data;
329*6831982aSBarry Smith   int         ierr, i,j, m = a->m, shift = a->indexshift, format;
33017ab2063SBarry Smith   char        *outputname;
33117ab2063SBarry Smith 
3323a40ed3dSBarry Smith   PetscFunctionBegin;
333fb4b0f7fSBarry Smith   ierr = ViewerGetOutputname(viewer,&outputname);CHKERRQ(ierr);
334888f2ed8SSatish Balay   ierr = ViewerGetFormat(viewer,&format);CHKERRQ(ierr);
335*6831982aSBarry Smith   if (format == VIEWER_FORMAT_ASCII_INFO_LONG || format == VIEWER_FORMAT_ASCII_INFO) {
336*6831982aSBarry Smith     if (a->inode.size) {
337*6831982aSBarry Smith       ierr = ViewerASCIIPrintf(viewer,"using I-node routines: found %d nodes, limit used is %d\n",a->inode.node_count,a->inode.limit);CHKERRQ(ierr);
338*6831982aSBarry Smith     } else {
339*6831982aSBarry Smith       ierr = ViewerASCIIPrintf(viewer,"not using I-node routines\n");CHKERRQ(ierr);
340*6831982aSBarry Smith     }
3413a40ed3dSBarry Smith   } else if (format == VIEWER_FORMAT_ASCII_MATLAB) {
342d00d2cf4SBarry Smith     int nofinalvalue = 0;
343d00d2cf4SBarry Smith     if ((a->i[m] == a->i[m-1]) || (a->j[a->nz-1] != a->n-!shift)) {
344d00d2cf4SBarry Smith       nofinalvalue = 1;
345d00d2cf4SBarry Smith     }
346*6831982aSBarry Smith     ierr = ViewerASCIIUseTabs(viewer,PETSC_NO);CHKERRQ(ierr);
347*6831982aSBarry Smith     ierr = ViewerASCIIPrintf(viewer,"%% Size = %d %d \n",m,a->n);CHKERRQ(ierr);
348*6831982aSBarry Smith     ierr = ViewerASCIIPrintf(viewer,"%% Nonzeros = %d \n",a->nz);CHKERRQ(ierr);
349*6831982aSBarry Smith     ierr = ViewerASCIIPrintf(viewer,"zzz = zeros(%d,3);\n",a->nz+nofinalvalue);CHKERRQ(ierr);
350*6831982aSBarry Smith     ierr = ViewerASCIIPrintf(viewer,"zzz = [\n");CHKERRQ(ierr);
35117ab2063SBarry Smith 
35217ab2063SBarry Smith     for (i=0; i<m; i++) {
353416022c9SBarry Smith       for ( j=a->i[i]+shift; j<a->i[i+1]+shift; j++ ) {
354aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
355*6831982aSBarry Smith         ierr = ViewerASCIIPrintf(viewer,"%d %d  %18.16e + %18.16e i \n",i+1,a->j[j]+!shift,PetscReal(a->a[j]),PetscImaginary(a->a[j]));CHKERRQ(ierr);
35617ab2063SBarry Smith #else
357*6831982aSBarry Smith         ierr = ViewerASCIIPrintf(viewer,"%d %d  %18.16e\n", i+1, a->j[j]+!shift, a->a[j]);CHKERRQ(ierr);
35817ab2063SBarry Smith #endif
35917ab2063SBarry Smith       }
36017ab2063SBarry Smith     }
361d00d2cf4SBarry Smith     if (nofinalvalue) {
362*6831982aSBarry Smith       ierr = ViewerASCIIPrintf(viewer,"%d %d  %18.16e\n", m, a->n, 0.0);CHKERRQ(ierr);
363d00d2cf4SBarry Smith     }
364*6831982aSBarry Smith     if (outputname) {ierr = ViewerASCIIPrintf(viewer,"];\n %s = spconvert(zzz);\n",outputname);CHKERRQ(ierr);}
365*6831982aSBarry Smith     else            {ierr = ViewerASCIIPrintf(viewer,"];\n M = spconvert(zzz);\n");CHKERRQ(ierr);}
366*6831982aSBarry Smith     ierr = ViewerASCIIUseTabs(viewer,PETSC_YES);CHKERRQ(ierr);
3673a40ed3dSBarry Smith   } else if (format == VIEWER_FORMAT_ASCII_COMMON) {
368*6831982aSBarry Smith     ierr = ViewerASCIIUseTabs(viewer,PETSC_NO);CHKERRQ(ierr);
36944cd7ae7SLois Curfman McInnes     for ( i=0; i<m; i++ ) {
370*6831982aSBarry Smith       ierr = ViewerASCIIPrintf(viewer,"row %d:",i);CHKERRQ(ierr);
37144cd7ae7SLois Curfman McInnes       for ( j=a->i[i]+shift; j<a->i[i+1]+shift; j++ ) {
372aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
373*6831982aSBarry Smith         if (PetscImaginary(a->a[j]) > 0.0 && PetscReal(a->a[j]) != 0.0) {
374*6831982aSBarry Smith           ierr = ViewerASCIIPrintf(viewer," %d %g + %g i",a->j[j]+shift,PetscReal(a->a[j]),PetscImaginary(a->a[j]));CHKERRQ(ierr);
375*6831982aSBarry Smith         } else if (PetscImaginary(a->a[j]) < 0.0 && PetscReal(a->a[j]) != 0.0) {
376*6831982aSBarry Smith           ierr = ViewerASCIIPrintf(viewer," %d %g - %g i",a->j[j]+shift,PetscReal(a->a[j]),-PetscImaginary(a->a[j]));CHKERRQ(ierr);
377*6831982aSBarry Smith         } else if (PetscReal(a->a[j]) != 0.0) {
378*6831982aSBarry Smith           ierr = ViewerASCIIPrintf(viewer," %d %g ",a->j[j]+shift,PetscReal(a->a[j]));CHKERRQ(ierr);
379*6831982aSBarry Smith         }
38044cd7ae7SLois Curfman McInnes #else
381*6831982aSBarry Smith         if (a->a[j] != 0.0) {ierr = ViewerASCIIPrintf(viewer," %d %g ",a->j[j]+shift,a->a[j]);CHKERRQ(ierr);}
38244cd7ae7SLois Curfman McInnes #endif
38344cd7ae7SLois Curfman McInnes       }
384*6831982aSBarry Smith       ierr = ViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
38544cd7ae7SLois Curfman McInnes     }
386*6831982aSBarry Smith     ierr = ViewerASCIIUseTabs(viewer,PETSC_YES);CHKERRQ(ierr);
38702594712SBarry Smith   } else if (format == VIEWER_FORMAT_ASCII_SYMMODU) {
388496be53dSLois Curfman McInnes     int nzd=0, fshift=1, *sptr;
389*6831982aSBarry Smith     ierr = ViewerASCIIUseTabs(viewer,PETSC_NO);CHKERRQ(ierr);
3902e44a96cSLois Curfman McInnes     sptr = (int *) PetscMalloc( (m+1)*sizeof(int) );CHKPTRQ(sptr);
391496be53dSLois Curfman McInnes     for ( i=0; i<m; i++ ) {
392496be53dSLois Curfman McInnes       sptr[i] = nzd+1;
393496be53dSLois Curfman McInnes       for ( j=a->i[i]+shift; j<a->i[i+1]+shift; j++ ) {
394496be53dSLois Curfman McInnes         if (a->j[j] >= i) {
395aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
396e20fef11SSatish Balay           if (PetscImaginary(a->a[j]) != 0.0 || PetscReal(a->a[j]) != 0.0) nzd++;
397496be53dSLois Curfman McInnes #else
398496be53dSLois Curfman McInnes           if (a->a[j] != 0.0) nzd++;
399496be53dSLois Curfman McInnes #endif
400496be53dSLois Curfman McInnes         }
401496be53dSLois Curfman McInnes       }
402496be53dSLois Curfman McInnes     }
4032e44a96cSLois Curfman McInnes     sptr[m] = nzd+1;
404*6831982aSBarry Smith     ierr = ViewerASCIIPrintf(viewer," %d %d\n\n",m,nzd);CHKERRQ(ierr);
4052e44a96cSLois Curfman McInnes     for ( i=0; i<m+1; i+=6 ) {
406*6831982aSBarry Smith       if (i+4<m) {ierr = ViewerASCIIPrintf(viewer," %d %d %d %d %d %d\n",sptr[i],sptr[i+1],sptr[i+2],sptr[i+3],sptr[i+4],sptr[i+5]);CHKERRQ(ierr);}
407*6831982aSBarry Smith       else if (i+3<m) {ierr = ViewerASCIIPrintf(viewer," %d %d %d %d %d\n",sptr[i],sptr[i+1],sptr[i+2],sptr[i+3],sptr[i+4]);CHKERRQ(ierr);}
408*6831982aSBarry Smith       else if (i+2<m) {ierr = ViewerASCIIPrintf(viewer," %d %d %d %d\n",sptr[i],sptr[i+1],sptr[i+2],sptr[i+3]);CHKERRQ(ierr);}
409*6831982aSBarry Smith       else if (i+1<m) {ierr = ViewerASCIIPrintf(viewer," %d %d %d\n",sptr[i],sptr[i+1],sptr[i+2]);CHKERRQ(ierr);}
410*6831982aSBarry Smith       else if (i<m)   {ierr = ViewerASCIIPrintf(viewer," %d %d\n",sptr[i],sptr[i+1]);CHKERRQ(ierr);}
411*6831982aSBarry Smith       else            {ierr = ViewerASCIIPrintf(viewer," %d\n",sptr[i]);CHKERRQ(ierr);}
412496be53dSLois Curfman McInnes     }
413*6831982aSBarry Smith     ierr = ViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
414606d414cSSatish Balay     ierr = PetscFree(sptr);CHKERRQ(ierr);
415496be53dSLois Curfman McInnes     for ( i=0; i<m; i++ ) {
416496be53dSLois Curfman McInnes       for ( j=a->i[i]+shift; j<a->i[i+1]+shift; j++ ) {
417*6831982aSBarry Smith         if (a->j[j] >= i) {ierr = ViewerASCIIPrintf(viewer," %d ",a->j[j]+fshift);CHKERRQ(ierr);}
418496be53dSLois Curfman McInnes       }
419*6831982aSBarry Smith       ierr = ViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
420496be53dSLois Curfman McInnes     }
421*6831982aSBarry Smith     ierr = ViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
422496be53dSLois Curfman McInnes     for ( i=0; i<m; i++ ) {
423496be53dSLois Curfman McInnes       for ( j=a->i[i]+shift; j<a->i[i+1]+shift; j++ ) {
424496be53dSLois Curfman McInnes         if (a->j[j] >= i) {
425aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
426*6831982aSBarry Smith           if (PetscImaginary(a->a[j]) != 0.0 || PetscReal(a->a[j]) != 0.0) {
427*6831982aSBarry Smith             ierr = ViewerASCIIPrintf(viewer," %18.16e %18.16e ",PetscReal(a->a[j]),PetscImaginary(a->a[j]));CHKERRQ(ierr);
428*6831982aSBarry Smith           }
429496be53dSLois Curfman McInnes #else
430*6831982aSBarry Smith           if (a->a[j] != 0.0) {ierr = ViewerASCIIPrintf(viewer," %18.16e ",a->a[j]);CHKERRQ(ierr);}
431496be53dSLois Curfman McInnes #endif
432496be53dSLois Curfman McInnes         }
433496be53dSLois Curfman McInnes       }
434*6831982aSBarry Smith       ierr = ViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
435496be53dSLois Curfman McInnes     }
436*6831982aSBarry Smith     ierr = ViewerASCIIUseTabs(viewer,PETSC_YES);CHKERRQ(ierr);
43702594712SBarry Smith   } else if (format == VIEWER_FORMAT_ASCII_DENSE) {
43802594712SBarry Smith     int    cnt = 0,jcnt;
43902594712SBarry Smith     Scalar value;
44002594712SBarry Smith 
441*6831982aSBarry Smith     ierr = ViewerASCIIUseTabs(viewer,PETSC_NO);CHKERRQ(ierr);
44202594712SBarry Smith     for ( i=0; i<m; i++ ) {
44302594712SBarry Smith       jcnt = 0;
44402594712SBarry Smith       for ( j=0; j<a->n; j++ ) {
445e24b481bSBarry Smith         if ( jcnt < a->i[i+1]-a->i[i] && j == a->j[cnt]) {
44602594712SBarry Smith           value = a->a[cnt++];
447e24b481bSBarry Smith           jcnt++;
44802594712SBarry Smith         } else {
44902594712SBarry Smith           value = 0.0;
45002594712SBarry Smith         }
451aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
452*6831982aSBarry Smith         ierr = ViewerASCIIPrintf(viewer," %7.5e+%7.5e i ",PetscReal(value),PetscImaginary(value));CHKERRQ(ierr);
45302594712SBarry Smith #else
454*6831982aSBarry Smith         ierr = ViewerASCIIPrintf(viewer," %7.5e ",value);CHKERRQ(ierr);
45502594712SBarry Smith #endif
45602594712SBarry Smith       }
457*6831982aSBarry Smith       ierr = ViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
45802594712SBarry Smith     }
459*6831982aSBarry Smith     ierr = ViewerASCIIUseTabs(viewer,PETSC_YES);CHKERRQ(ierr);
4603a40ed3dSBarry Smith   } else {
461*6831982aSBarry Smith     ierr = ViewerASCIIUseTabs(viewer,PETSC_NO);CHKERRQ(ierr);
46217ab2063SBarry Smith     for ( i=0; i<m; i++ ) {
463*6831982aSBarry Smith       ierr = ViewerASCIIPrintf(viewer,"row %d:",i);CHKERRQ(ierr);
464416022c9SBarry Smith       for ( j=a->i[i]+shift; j<a->i[i+1]+shift; j++ ) {
465aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
466e20fef11SSatish Balay         if (PetscImaginary(a->a[j]) > 0.0) {
467*6831982aSBarry Smith           ierr = ViewerASCIIPrintf(viewer," %d %g + %g i",a->j[j]+shift,PetscReal(a->a[j]),PetscImaginary(a->a[j]));CHKERRQ(ierr);
468e20fef11SSatish Balay         } else if (PetscImaginary(a->a[j]) < 0.0) {
469*6831982aSBarry Smith           ierr = ViewerASCIIPrintf(viewer," %d %g - %g i",a->j[j]+shift,PetscReal(a->a[j]),-PetscImaginary(a->a[j]));CHKERRQ(ierr);
4703a40ed3dSBarry Smith         } else {
471*6831982aSBarry Smith           ierr = ViewerASCIIPrintf(viewer," %d %g ",a->j[j]+shift,PetscReal(a->a[j]));CHKERRQ(ierr);
47217ab2063SBarry Smith         }
47317ab2063SBarry Smith #else
474*6831982aSBarry Smith         ierr = ViewerASCIIPrintf(viewer," %d %g ",a->j[j]+shift,a->a[j]);CHKERRQ(ierr);
47517ab2063SBarry Smith #endif
47617ab2063SBarry Smith       }
477*6831982aSBarry Smith       ierr = ViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
47817ab2063SBarry Smith     }
479*6831982aSBarry Smith     ierr = ViewerASCIIUseTabs(viewer,PETSC_YES);CHKERRQ(ierr);
48017ab2063SBarry Smith   }
481*6831982aSBarry Smith   ierr = ViewerFlush(viewer);CHKERRQ(ierr);
4823a40ed3dSBarry Smith   PetscFunctionReturn(0);
483416022c9SBarry Smith }
484416022c9SBarry Smith 
4855615d1e5SSatish Balay #undef __FUNC__
486480ef9eaSBarry Smith #define __FUNC__ "MatView_SeqAIJ_Draw_Zoom"
487480ef9eaSBarry Smith int MatView_SeqAIJ_Draw_Zoom(Draw draw,void *Aa)
488416022c9SBarry Smith {
489480ef9eaSBarry Smith   Mat         A = (Mat) Aa;
490416022c9SBarry Smith   Mat_SeqAIJ  *a = (Mat_SeqAIJ *) A->data;
49177ed5343SBarry Smith   int         ierr, i,j, m = a->m, shift = a->indexshift,color,rank;
4920513a670SBarry Smith   int         format;
493480ef9eaSBarry Smith   double      xl,yl,xr,yr,x_l,x_r,y_l,y_r,maxv = 0.0;
494480ef9eaSBarry Smith   Viewer      viewer;
49577ed5343SBarry Smith   MPI_Comm    comm;
496cddf8d76SBarry Smith 
4973a40ed3dSBarry Smith   PetscFunctionBegin;
49877ed5343SBarry Smith   /*
49977ed5343SBarry Smith       This is nasty. If this is called from an originally parallel matrix
50077ed5343SBarry Smith    then all processes call this, but only the first has the matrix so the
50177ed5343SBarry Smith    rest should return immediately.
50277ed5343SBarry Smith   */
50377ed5343SBarry Smith   ierr = PetscObjectGetComm((PetscObject)draw,&comm);CHKERRQ(ierr);
504d132466eSBarry Smith   ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr);
50577ed5343SBarry Smith   if (rank) PetscFunctionReturn(0);
50677ed5343SBarry Smith 
507480ef9eaSBarry Smith   ierr = PetscObjectQuery((PetscObject)A,"Zoomviewer",(PetscObject*) &viewer);CHKERRQ(ierr);
5080513a670SBarry Smith   ierr = ViewerGetFormat(viewer,&format);CHKERRQ(ierr);
50919bcc07fSBarry Smith 
510480ef9eaSBarry Smith   ierr = DrawGetCoordinates(draw,&xl,&yl,&xr,&yr);CHKERRQ(ierr);
511416022c9SBarry Smith   /* loop over matrix elements drawing boxes */
5120513a670SBarry Smith 
5130513a670SBarry Smith   if (format != VIEWER_FORMAT_DRAW_CONTOUR) {
5140513a670SBarry Smith     /* Blue for negative, Cyan for zero and  Red for positive */
515cddf8d76SBarry Smith     color = DRAW_BLUE;
516416022c9SBarry Smith     for ( i=0; i<m; i++ ) {
517cddf8d76SBarry Smith       y_l = m - i - 1.0; y_r = y_l + 1.0;
518416022c9SBarry Smith       for ( j=a->i[i]+shift; j<a->i[i+1]+shift; j++ ) {
519cddf8d76SBarry Smith         x_l = a->j[j] + shift; x_r = x_l + 1.0;
520aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
521e20fef11SSatish Balay         if (PetscReal(a->a[j]) >=  0.) continue;
522cddf8d76SBarry Smith #else
523cddf8d76SBarry Smith         if (a->a[j] >=  0.) continue;
524cddf8d76SBarry Smith #endif
525480ef9eaSBarry Smith         ierr = DrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr);
526cddf8d76SBarry Smith       }
527cddf8d76SBarry Smith     }
528cddf8d76SBarry Smith     color = DRAW_CYAN;
529cddf8d76SBarry Smith     for ( i=0; i<m; i++ ) {
530cddf8d76SBarry Smith       y_l = m - i - 1.0; y_r = y_l + 1.0;
531cddf8d76SBarry Smith       for ( j=a->i[i]+shift; j<a->i[i+1]+shift; j++ ) {
532cddf8d76SBarry Smith         x_l = a->j[j] + shift; x_r = x_l + 1.0;
533cddf8d76SBarry Smith         if (a->a[j] !=  0.) continue;
534480ef9eaSBarry Smith         ierr = DrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr);
535cddf8d76SBarry Smith       }
536cddf8d76SBarry Smith     }
537cddf8d76SBarry Smith     color = DRAW_RED;
538cddf8d76SBarry Smith     for ( i=0; i<m; i++ ) {
539cddf8d76SBarry Smith       y_l = m - i - 1.0; y_r = y_l + 1.0;
540cddf8d76SBarry Smith       for ( j=a->i[i]+shift; j<a->i[i+1]+shift; j++ ) {
541cddf8d76SBarry Smith         x_l = a->j[j] + shift; x_r = x_l + 1.0;
542aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
543e20fef11SSatish Balay         if (PetscReal(a->a[j]) <=  0.) continue;
544cddf8d76SBarry Smith #else
545cddf8d76SBarry Smith         if (a->a[j] <=  0.) continue;
546cddf8d76SBarry Smith #endif
547480ef9eaSBarry Smith         ierr = DrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr);
548416022c9SBarry Smith       }
549416022c9SBarry Smith     }
5500513a670SBarry Smith   } else {
5510513a670SBarry Smith     /* use contour shading to indicate magnitude of values */
5520513a670SBarry Smith     /* first determine max of all nonzero values */
5530513a670SBarry Smith     int    nz = a->nz,count;
5540513a670SBarry Smith     Draw   popup;
555480ef9eaSBarry Smith     double scale;
5560513a670SBarry Smith 
5570513a670SBarry Smith     for ( i=0; i<nz; i++ ) {
5580513a670SBarry Smith       if (PetscAbsScalar(a->a[i]) > maxv) maxv = PetscAbsScalar(a->a[i]);
5590513a670SBarry Smith     }
560480ef9eaSBarry Smith     scale = (245.0 - DRAW_BASIC_COLORS)/maxv;
561522c5e43SBarry Smith     ierr  = DrawGetPopup(draw,&popup);CHKERRQ(ierr);
5620513a670SBarry Smith     ierr  = DrawScalePopup(popup,0.0,maxv);CHKERRQ(ierr);
5630513a670SBarry Smith     count = 0;
5640513a670SBarry Smith     for ( i=0; i<m; i++ ) {
5650513a670SBarry Smith       y_l = m - i - 1.0; y_r = y_l + 1.0;
5660513a670SBarry Smith       for ( j=a->i[i]+shift; j<a->i[i+1]+shift; j++ ) {
5670513a670SBarry Smith         x_l = a->j[j] + shift; x_r = x_l + 1.0;
5686d6b6c30SSatish Balay         color = DRAW_BASIC_COLORS + (int)(scale*PetscAbsScalar(a->a[count]));
569480ef9eaSBarry Smith         ierr  = DrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr);
5700513a670SBarry Smith         count++;
5710513a670SBarry Smith       }
5720513a670SBarry Smith     }
5730513a670SBarry Smith   }
574480ef9eaSBarry Smith   PetscFunctionReturn(0);
575480ef9eaSBarry Smith }
576cddf8d76SBarry Smith 
577480ef9eaSBarry Smith #undef __FUNC__
578480ef9eaSBarry Smith #define __FUNC__ "MatView_SeqAIJ_Draw"
579480ef9eaSBarry Smith int MatView_SeqAIJ_Draw(Mat A,Viewer viewer)
580480ef9eaSBarry Smith {
581480ef9eaSBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*) A->data;
582480ef9eaSBarry Smith   int        ierr;
583480ef9eaSBarry Smith   Draw       draw;
584480ef9eaSBarry Smith   double     xr,yr,xl,yl,h,w;
585480ef9eaSBarry Smith   PetscTruth isnull;
586480ef9eaSBarry Smith 
587480ef9eaSBarry Smith   PetscFunctionBegin;
58877ed5343SBarry Smith   ierr = ViewerDrawGetDraw(viewer,0,&draw);CHKERRQ(ierr);
589480ef9eaSBarry Smith   ierr = DrawIsNull(draw,&isnull);CHKERRQ(ierr);
590480ef9eaSBarry Smith   if (isnull) PetscFunctionReturn(0);
591480ef9eaSBarry Smith 
592480ef9eaSBarry Smith   ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",(PetscObject)viewer);CHKERRQ(ierr);
593480ef9eaSBarry Smith   xr  = a->n; yr = a->m; h = yr/10.0; w = xr/10.0;
594480ef9eaSBarry Smith   xr += w;    yr += h;  xl = -w;     yl = -h;
595cddf8d76SBarry Smith   ierr = DrawSetCoordinates(draw,xl,yl,xr,yr);CHKERRQ(ierr);
596480ef9eaSBarry Smith   ierr = DrawZoom(draw,MatView_SeqAIJ_Draw_Zoom,A);CHKERRQ(ierr);
597480ef9eaSBarry Smith   ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",PETSC_NULL);CHKERRQ(ierr);
5983a40ed3dSBarry Smith   PetscFunctionReturn(0);
599416022c9SBarry Smith }
600416022c9SBarry Smith 
6015615d1e5SSatish Balay #undef __FUNC__
602d4bb536fSBarry Smith #define __FUNC__ "MatView_SeqAIJ"
603e1311b90SBarry Smith int MatView_SeqAIJ(Mat A,Viewer viewer)
604416022c9SBarry Smith {
605416022c9SBarry Smith   Mat_SeqAIJ  *a = (Mat_SeqAIJ*) A->data;
606bcd2baecSBarry Smith   int         ierr;
607*6831982aSBarry Smith   PetscTruth  issocket,isascii,isbinary,isdraw;
608416022c9SBarry Smith 
6093a40ed3dSBarry Smith   PetscFunctionBegin;
610*6831982aSBarry Smith   ierr = PetscTypeCompare((PetscObject)viewer,SOCKET_VIEWER,&issocket);CHKERRQ(ierr);
611*6831982aSBarry Smith   ierr = PetscTypeCompare((PetscObject)viewer,ASCII_VIEWER,&isascii);CHKERRQ(ierr);
612*6831982aSBarry Smith   ierr = PetscTypeCompare((PetscObject)viewer,BINARY_VIEWER,&isbinary);CHKERRQ(ierr);
613*6831982aSBarry Smith   ierr = PetscTypeCompare((PetscObject)viewer,DRAW_VIEWER,&isdraw);CHKERRQ(ierr);
6140f5bd95cSBarry Smith   if (issocket) {
6157b2a1423SBarry Smith     ierr = ViewerSocketPutSparse_Private(viewer,a->m,a->n,a->nz,a->a,a->i,a->j);CHKERRQ(ierr);
6160f5bd95cSBarry Smith   } else if (isascii) {
6173a40ed3dSBarry Smith     ierr = MatView_SeqAIJ_ASCII(A,viewer);CHKERRQ(ierr);
6180f5bd95cSBarry Smith   } else if (isbinary) {
6193a40ed3dSBarry Smith     ierr = MatView_SeqAIJ_Binary(A,viewer);CHKERRQ(ierr);
6200f5bd95cSBarry Smith   } else if (isdraw) {
6213a40ed3dSBarry Smith     ierr = MatView_SeqAIJ_Draw(A,viewer);CHKERRQ(ierr);
6225cd90555SBarry Smith   } else {
6230f5bd95cSBarry Smith     SETERRQ1(1,1,"Viewer type %s not supported by SeqAIJ matrices",((PetscObject)viewer)->type_name);
62417ab2063SBarry Smith   }
6253a40ed3dSBarry Smith   PetscFunctionReturn(0);
62617ab2063SBarry Smith }
62719bcc07fSBarry Smith 
628c456f294SBarry Smith extern int Mat_AIJ_CheckInode(Mat);
6295615d1e5SSatish Balay #undef __FUNC__
6305615d1e5SSatish Balay #define __FUNC__ "MatAssemblyEnd_SeqAIJ"
6318f6be9afSLois Curfman McInnes int MatAssemblyEnd_SeqAIJ(Mat A,MatAssemblyType mode)
63217ab2063SBarry Smith {
633416022c9SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data;
63441c01911SSatish Balay   int        fshift = 0,i,j,*ai = a->i, *aj = a->j, *imax = a->imax,ierr;
63543ee02c3SBarry Smith   int        m = a->m, *ip, N, *ailen = a->ilen,shift = a->indexshift,rmax = 0;
636416022c9SBarry Smith   Scalar     *aa = a->a, *ap;
63717ab2063SBarry Smith 
6383a40ed3dSBarry Smith   PetscFunctionBegin;
6393a40ed3dSBarry Smith   if (mode == MAT_FLUSH_ASSEMBLY) PetscFunctionReturn(0);
64017ab2063SBarry Smith 
64143ee02c3SBarry Smith   if (m) rmax = ailen[0]; /* determine row with most nonzeros */
64217ab2063SBarry Smith   for ( i=1; i<m; i++ ) {
643416022c9SBarry Smith     /* move each row back by the amount of empty slots (fshift) before it*/
64417ab2063SBarry Smith     fshift += imax[i-1] - ailen[i-1];
64594a9d846SBarry Smith     rmax   = PetscMax(rmax,ailen[i]);
64617ab2063SBarry Smith     if (fshift) {
6470f5bd95cSBarry Smith       ip = aj + ai[i] + shift;
6480f5bd95cSBarry Smith       ap = aa + ai[i] + shift;
64917ab2063SBarry Smith       N  = ailen[i];
65017ab2063SBarry Smith       for ( j=0; j<N; j++ ) {
65117ab2063SBarry Smith         ip[j-fshift] = ip[j];
65217ab2063SBarry Smith         ap[j-fshift] = ap[j];
65317ab2063SBarry Smith       }
65417ab2063SBarry Smith     }
65517ab2063SBarry Smith     ai[i] = ai[i-1] + ailen[i-1];
65617ab2063SBarry Smith   }
65717ab2063SBarry Smith   if (m) {
65817ab2063SBarry Smith     fshift += imax[m-1] - ailen[m-1];
65917ab2063SBarry Smith     ai[m]  = ai[m-1] + ailen[m-1];
66017ab2063SBarry Smith   }
66117ab2063SBarry Smith   /* reset ilen and imax for each row */
66217ab2063SBarry Smith   for ( i=0; i<m; i++ ) {
66317ab2063SBarry Smith     ailen[i] = imax[i] = ai[i+1] - ai[i];
66417ab2063SBarry Smith   }
665416022c9SBarry Smith   a->nz = ai[m] + shift;
66617ab2063SBarry Smith 
66717ab2063SBarry Smith   /* diagonals may have moved, so kill the diagonal pointers */
668416022c9SBarry Smith   if (fshift && a->diag) {
669606d414cSSatish Balay     ierr = PetscFree(a->diag);CHKERRQ(ierr);
670416022c9SBarry Smith     PLogObjectMemory(A,-(m+1)*sizeof(int));
671416022c9SBarry Smith     a->diag = 0;
67217ab2063SBarry Smith   }
6734e220ebcSLois Curfman McInnes   PLogInfo(A,"MatAssemblyEnd_SeqAIJ:Matrix size: %d X %d; storage space: %d unneeded, %d used\n",
6744e220ebcSLois Curfman McInnes            m,a->n,fshift,a->nz);
67514bcb312SBarry Smith   PLogInfo(A,"MatAssemblyEnd_SeqAIJ:Number of mallocs during MatSetValues() is %d\n",
676b810aeb4SBarry Smith            a->reallocs);
67794a9d846SBarry Smith   PLogInfo(A,"MatAssemblyEnd_SeqAIJ:Most nonzeros in any row is %d\n",rmax);
678dd5f02e7SSatish Balay   a->reallocs          = 0;
6794e220ebcSLois Curfman McInnes   A->info.nz_unneeded  = (double)fshift;
6804e220ebcSLois Curfman McInnes 
68176dd722bSSatish Balay   /* check out for identical nodes. If found, use inode functions */
68241c01911SSatish Balay   ierr = Mat_AIJ_CheckInode(A);CHKERRQ(ierr);
6833a40ed3dSBarry Smith   PetscFunctionReturn(0);
68417ab2063SBarry Smith }
68517ab2063SBarry Smith 
6865615d1e5SSatish Balay #undef __FUNC__
6875615d1e5SSatish Balay #define __FUNC__ "MatZeroEntries_SeqAIJ"
6888f6be9afSLois Curfman McInnes int MatZeroEntries_SeqAIJ(Mat A)
68917ab2063SBarry Smith {
690416022c9SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data;
691549d3d68SSatish Balay   int        ierr;
6923a40ed3dSBarry Smith 
6933a40ed3dSBarry Smith   PetscFunctionBegin;
694549d3d68SSatish Balay   ierr = PetscMemzero(a->a,(a->i[a->m]+a->indexshift)*sizeof(Scalar));CHKERRQ(ierr);
6953a40ed3dSBarry Smith   PetscFunctionReturn(0);
69617ab2063SBarry Smith }
697416022c9SBarry Smith 
6985615d1e5SSatish Balay #undef __FUNC__
6995615d1e5SSatish Balay #define __FUNC__ "MatDestroy_SeqAIJ"
700e1311b90SBarry Smith int MatDestroy_SeqAIJ(Mat A)
70117ab2063SBarry Smith {
702416022c9SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data;
70382bf6240SBarry Smith   int        ierr;
704d5d45c9bSBarry Smith 
7053a40ed3dSBarry Smith   PetscFunctionBegin;
70694d884c6SBarry Smith 
70794d884c6SBarry Smith   if (A->mapping) {
70894d884c6SBarry Smith     ierr = ISLocalToGlobalMappingDestroy(A->mapping);CHKERRQ(ierr);
70994d884c6SBarry Smith   }
71094d884c6SBarry Smith   if (A->bmapping) {
71194d884c6SBarry Smith     ierr = ISLocalToGlobalMappingDestroy(A->bmapping);CHKERRQ(ierr);
71294d884c6SBarry Smith   }
71361b13de0SBarry Smith   if (A->rmap) {
71461b13de0SBarry Smith     ierr = MapDestroy(A->rmap);CHKERRQ(ierr);
71561b13de0SBarry Smith   }
71661b13de0SBarry Smith   if (A->cmap) {
71761b13de0SBarry Smith     ierr = MapDestroy(A->cmap);CHKERRQ(ierr);
71861b13de0SBarry Smith   }
719606d414cSSatish Balay   if (a->idiag) {ierr = PetscFree(a->idiag);CHKERRQ(ierr);}
720aa482453SBarry Smith #if defined(PETSC_USE_LOG)
721e1311b90SBarry Smith   PLogObjectState((PetscObject)A,"Rows=%d, Cols=%d, NZ=%d",a->m,a->n,a->nz);
72217ab2063SBarry Smith #endif
723606d414cSSatish Balay   ierr = PetscFree(a->a);CHKERRQ(ierr);
724606d414cSSatish Balay   if (!a->singlemalloc) {
725606d414cSSatish Balay     ierr = PetscFree(a->i);CHKERRQ(ierr);
726606d414cSSatish Balay     ierr = PetscFree(a->j);CHKERRQ(ierr);
727606d414cSSatish Balay   }
728606d414cSSatish Balay   if (a->diag) {ierr = PetscFree(a->diag);CHKERRQ(ierr);}
729606d414cSSatish Balay   if (a->ilen) {ierr = PetscFree(a->ilen);CHKERRQ(ierr);}
730606d414cSSatish Balay   if (a->imax) {ierr = PetscFree(a->imax);CHKERRQ(ierr);}
731606d414cSSatish Balay   if (a->solve_work) {ierr = PetscFree(a->solve_work);CHKERRQ(ierr);}
732606d414cSSatish Balay   if (a->inode.size) {ierr = PetscFree(a->inode.size);CHKERRQ(ierr);}
73382bf6240SBarry Smith   if (a->icol) {ierr = ISDestroy(a->icol);CHKERRQ(ierr);}
734606d414cSSatish Balay   if (a->saved_values) {ierr = PetscFree(a->saved_values);CHKERRQ(ierr);}
735606d414cSSatish Balay   ierr = PetscFree(a);CHKERRQ(ierr);
736eed86810SBarry Smith 
737f2655603SLois Curfman McInnes   PLogObjectDestroy(A);
738f2655603SLois Curfman McInnes   PetscHeaderDestroy(A);
7393a40ed3dSBarry Smith   PetscFunctionReturn(0);
74017ab2063SBarry Smith }
74117ab2063SBarry Smith 
7425615d1e5SSatish Balay #undef __FUNC__
7435615d1e5SSatish Balay #define __FUNC__ "MatCompress_SeqAIJ"
7448f6be9afSLois Curfman McInnes int MatCompress_SeqAIJ(Mat A)
74517ab2063SBarry Smith {
7463a40ed3dSBarry Smith   PetscFunctionBegin;
7473a40ed3dSBarry Smith   PetscFunctionReturn(0);
74817ab2063SBarry Smith }
74917ab2063SBarry Smith 
7505615d1e5SSatish Balay #undef __FUNC__
7515615d1e5SSatish Balay #define __FUNC__ "MatSetOption_SeqAIJ"
7528f6be9afSLois Curfman McInnes int MatSetOption_SeqAIJ(Mat A,MatOption op)
75317ab2063SBarry Smith {
754416022c9SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data;
7553a40ed3dSBarry Smith 
7563a40ed3dSBarry Smith   PetscFunctionBegin;
7576d4a8577SBarry Smith   if      (op == MAT_ROW_ORIENTED)                 a->roworiented = 1;
7586d4a8577SBarry Smith   else if (op == MAT_COLUMN_ORIENTED)              a->roworiented = 0;
7596d4a8577SBarry Smith   else if (op == MAT_COLUMNS_SORTED)               a->sorted      = 1;
760219d9a1aSLois Curfman McInnes   else if (op == MAT_COLUMNS_UNSORTED)             a->sorted      = 0;
7616d4a8577SBarry Smith   else if (op == MAT_NO_NEW_NONZERO_LOCATIONS)     a->nonew       = 1;
7624787f768SSatish Balay   else if (op == MAT_NEW_NONZERO_LOCATION_ERR)     a->nonew       = -1;
7634787f768SSatish Balay   else if (op == MAT_NEW_NONZERO_ALLOCATION_ERR)   a->nonew       = -2;
7646d4a8577SBarry Smith   else if (op == MAT_YES_NEW_NONZERO_LOCATIONS)    a->nonew       = 0;
7656d4a8577SBarry Smith   else if (op == MAT_ROWS_SORTED ||
766219d9a1aSLois Curfman McInnes            op == MAT_ROWS_UNSORTED ||
7676d4a8577SBarry Smith            op == MAT_SYMMETRIC ||
7686d4a8577SBarry Smith            op == MAT_STRUCTURALLY_SYMMETRIC ||
76990f02eecSBarry Smith            op == MAT_YES_NEW_DIAGONALS ||
770b51ba29fSSatish Balay            op == MAT_IGNORE_OFF_PROC_ENTRIES||
771b51ba29fSSatish Balay            op == MAT_USE_HASH_TABLE)
772981c4779SBarry Smith     PLogInfo(A,"MatSetOption_SeqAIJ:Option ignored\n");
7733a40ed3dSBarry Smith   else if (op == MAT_NO_NEW_DIAGONALS) {
7743a40ed3dSBarry Smith     SETERRQ(PETSC_ERR_SUP,0,"MAT_NO_NEW_DIAGONALS");
7753a40ed3dSBarry Smith   } else if (op == MAT_INODE_LIMIT_1)            a->inode.limit  = 1;
7766d4a8577SBarry Smith   else if (op == MAT_INODE_LIMIT_2)            a->inode.limit  = 2;
7776d4a8577SBarry Smith   else if (op == MAT_INODE_LIMIT_3)            a->inode.limit  = 3;
7786d4a8577SBarry Smith   else if (op == MAT_INODE_LIMIT_4)            a->inode.limit  = 4;
7796d4a8577SBarry Smith   else if (op == MAT_INODE_LIMIT_5)            a->inode.limit  = 5;
7803a40ed3dSBarry Smith   else SETERRQ(PETSC_ERR_SUP,0,"unknown option");
7813a40ed3dSBarry Smith   PetscFunctionReturn(0);
78217ab2063SBarry Smith }
78317ab2063SBarry Smith 
7845615d1e5SSatish Balay #undef __FUNC__
7855615d1e5SSatish Balay #define __FUNC__ "MatGetDiagonal_SeqAIJ"
7868f6be9afSLois Curfman McInnes int MatGetDiagonal_SeqAIJ(Mat A,Vec v)
78717ab2063SBarry Smith {
788416022c9SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data;
7893a40ed3dSBarry Smith   int        i,j, n,shift = a->indexshift,ierr;
79017ab2063SBarry Smith   Scalar     *x, zero = 0.0;
79117ab2063SBarry Smith 
7923a40ed3dSBarry Smith   PetscFunctionBegin;
7933a40ed3dSBarry Smith   ierr = VecSet(&zero,v);CHKERRQ(ierr);
794e1311b90SBarry Smith   ierr = VecGetArray(v,&x);;CHKERRQ(ierr);
795e1311b90SBarry Smith   ierr = VecGetLocalSize(v,&n);;CHKERRQ(ierr);
796a8c6a408SBarry Smith   if (n != a->m) SETERRQ(PETSC_ERR_ARG_SIZ,0,"Nonconforming matrix and vector");
797416022c9SBarry Smith   for ( i=0; i<a->m; i++ ) {
798416022c9SBarry Smith     for ( j=a->i[i]+shift; j<a->i[i+1]+shift; j++ ) {
799416022c9SBarry Smith       if (a->j[j]+shift == i) {
800416022c9SBarry Smith         x[i] = a->a[j];
80117ab2063SBarry Smith         break;
80217ab2063SBarry Smith       }
80317ab2063SBarry Smith     }
80417ab2063SBarry Smith   }
805e1311b90SBarry Smith   ierr = VecRestoreArray(v,&x);;CHKERRQ(ierr);
8063a40ed3dSBarry Smith   PetscFunctionReturn(0);
80717ab2063SBarry Smith }
80817ab2063SBarry Smith 
80917ab2063SBarry Smith /* -------------------------------------------------------*/
81017ab2063SBarry Smith /* Should check that shapes of vectors and matrices match */
81117ab2063SBarry Smith /* -------------------------------------------------------*/
8125615d1e5SSatish Balay #undef __FUNC__
8135615d1e5SSatish Balay #define __FUNC__ "MatMultTrans_SeqAIJ"
81444cd7ae7SLois Curfman McInnes int MatMultTrans_SeqAIJ(Mat A,Vec xx,Vec yy)
81517ab2063SBarry Smith {
816416022c9SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data;
81717ab2063SBarry Smith   Scalar     *x, *y, *v, alpha;
818e1311b90SBarry Smith   int        ierr,m = a->m, n, i, *idx, shift = a->indexshift;
81917ab2063SBarry Smith 
8203a40ed3dSBarry Smith   PetscFunctionBegin;
821e1311b90SBarry Smith   ierr = VecGetArray(xx,&x);CHKERRQ(ierr);
822e1311b90SBarry Smith   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
823549d3d68SSatish Balay   ierr = PetscMemzero(y,a->n*sizeof(Scalar));CHKERRQ(ierr);
82417ab2063SBarry Smith   y = y + shift; /* shift for Fortran start by 1 indexing */
82517ab2063SBarry Smith   for ( i=0; i<m; i++ ) {
826416022c9SBarry Smith     idx   = a->j + a->i[i] + shift;
827416022c9SBarry Smith     v     = a->a + a->i[i] + shift;
828416022c9SBarry Smith     n     = a->i[i+1] - a->i[i];
82917ab2063SBarry Smith     alpha = x[i];
83017ab2063SBarry Smith     while (n-->0) {y[*idx++] += alpha * *v++;}
83117ab2063SBarry Smith   }
832416022c9SBarry Smith   PLogFlops(2*a->nz - a->n);
833e1311b90SBarry Smith   ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr);
834e1311b90SBarry Smith   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
8353a40ed3dSBarry Smith   PetscFunctionReturn(0);
83617ab2063SBarry Smith }
837d5d45c9bSBarry Smith 
8385615d1e5SSatish Balay #undef __FUNC__
8395615d1e5SSatish Balay #define __FUNC__ "MatMultTransAdd_SeqAIJ"
84044cd7ae7SLois Curfman McInnes int MatMultTransAdd_SeqAIJ(Mat A,Vec xx,Vec zz,Vec yy)
84117ab2063SBarry Smith {
842416022c9SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data;
84317ab2063SBarry Smith   Scalar     *x, *y, *v, alpha;
844e1311b90SBarry Smith   int        ierr,m = a->m, n, i, *idx,shift = a->indexshift;
84517ab2063SBarry Smith 
8463a40ed3dSBarry Smith   PetscFunctionBegin;
8472e8a6d31SBarry Smith   if (zz != yy) {ierr = VecCopy(zz,yy);CHKERRQ(ierr);}
848e1311b90SBarry Smith   ierr = VecGetArray(xx,&x);CHKERRQ(ierr);
849e1311b90SBarry Smith   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
85017ab2063SBarry Smith   y = y + shift; /* shift for Fortran start by 1 indexing */
85117ab2063SBarry Smith   for ( i=0; i<m; i++ ) {
852416022c9SBarry Smith     idx   = a->j + a->i[i] + shift;
853416022c9SBarry Smith     v     = a->a + a->i[i] + shift;
854416022c9SBarry Smith     n     = a->i[i+1] - a->i[i];
85517ab2063SBarry Smith     alpha = x[i];
85617ab2063SBarry Smith     while (n-->0) {y[*idx++] += alpha * *v++;}
85717ab2063SBarry Smith   }
85890f02eecSBarry Smith   PLogFlops(2*a->nz);
859e1311b90SBarry Smith   ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr);
860e1311b90SBarry Smith   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
8613a40ed3dSBarry Smith   PetscFunctionReturn(0);
86217ab2063SBarry Smith }
86317ab2063SBarry Smith 
8645615d1e5SSatish Balay #undef __FUNC__
8655615d1e5SSatish Balay #define __FUNC__ "MatMult_SeqAIJ"
86644cd7ae7SLois Curfman McInnes int MatMult_SeqAIJ(Mat A,Vec xx,Vec yy)
86717ab2063SBarry Smith {
868416022c9SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data;
86917ab2063SBarry Smith   Scalar     *x, *y, *v, sum;
870e1311b90SBarry Smith   int        ierr,m = a->m, *idx, shift = a->indexshift,*ii;
871aa482453SBarry Smith #if !defined(PETSC_USE_FORTRAN_KERNEL_MULTAIJ)
872e36a17ebSSatish Balay   int        n, i, jrow,j;
873e36a17ebSSatish Balay #endif
87417ab2063SBarry Smith 
875aa482453SBarry Smith #if defined(PETSC_HAVE_PRAGMA_DISJOINT)
876fee21e36SBarry Smith #pragma disjoint(*x,*y,*v)
877fee21e36SBarry Smith #endif
878fee21e36SBarry Smith 
8793a40ed3dSBarry Smith   PetscFunctionBegin;
880e1311b90SBarry Smith   ierr = VecGetArray(xx,&x);CHKERRQ(ierr);
881e1311b90SBarry Smith   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
88217ab2063SBarry Smith   x    = x + shift;    /* shift for Fortran start by 1 indexing */
883416022c9SBarry Smith   idx  = a->j;
884d64ed03dSBarry Smith   v    = a->a;
885416022c9SBarry Smith   ii   = a->i;
886aa482453SBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_MULTAIJ)
88729b5ca8aSSatish Balay   fortranmultaij_(&m,x,ii,idx+shift,v+shift,y);
8888d195f9aSBarry Smith #else
889d64ed03dSBarry Smith   v    += shift; /* shift for Fortran start by 1 indexing */
890d64ed03dSBarry Smith   idx  += shift;
89117ab2063SBarry Smith   for ( i=0; i<m; i++ ) {
8929ea0dfa2SSatish Balay     jrow = ii[i];
8939ea0dfa2SSatish Balay     n    = ii[i+1] - jrow;
89417ab2063SBarry Smith     sum  = 0.0;
8959ea0dfa2SSatish Balay     for ( j=0; j<n; j++) {
8969ea0dfa2SSatish Balay       sum += v[jrow]*x[idx[jrow]]; jrow++;
8979ea0dfa2SSatish Balay      }
89817ab2063SBarry Smith     y[i] = sum;
89917ab2063SBarry Smith   }
9008d195f9aSBarry Smith #endif
901416022c9SBarry Smith   PLogFlops(2*a->nz - m);
902e1311b90SBarry Smith   ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr);
903e1311b90SBarry Smith   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
9043a40ed3dSBarry Smith   PetscFunctionReturn(0);
90517ab2063SBarry Smith }
90617ab2063SBarry Smith 
9075615d1e5SSatish Balay #undef __FUNC__
9085615d1e5SSatish Balay #define __FUNC__ "MatMultAdd_SeqAIJ"
90944cd7ae7SLois Curfman McInnes int MatMultAdd_SeqAIJ(Mat A,Vec xx,Vec yy,Vec zz)
91017ab2063SBarry Smith {
911416022c9SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data;
91217ab2063SBarry Smith   Scalar     *x, *y, *z, *v, sum;
913e1311b90SBarry Smith   int        ierr,m = a->m, *idx, shift = a->indexshift,*ii;
914aa482453SBarry Smith #if !defined(PETSC_USE_FORTRAN_KERNEL_MULTADDAIJ)
915e36a17ebSSatish Balay   int        n,i,jrow,j;
916e36a17ebSSatish Balay #endif
9179ea0dfa2SSatish Balay 
9183a40ed3dSBarry Smith   PetscFunctionBegin;
919e1311b90SBarry Smith   ierr = VecGetArray(xx,&x);CHKERRQ(ierr);
920e1311b90SBarry Smith   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
9212e8a6d31SBarry Smith   if (zz != yy) {
922e1311b90SBarry Smith     ierr = VecGetArray(zz,&z);CHKERRQ(ierr);
9232e8a6d31SBarry Smith   } else {
9242e8a6d31SBarry Smith     z = y;
9252e8a6d31SBarry Smith   }
92617ab2063SBarry Smith   x    = x + shift; /* shift for Fortran start by 1 indexing */
927cddf8d76SBarry Smith   idx  = a->j;
928d64ed03dSBarry Smith   v    = a->a;
929cddf8d76SBarry Smith   ii   = a->i;
930aa482453SBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_MULTADDAIJ)
93129b5ca8aSSatish Balay   fortranmultaddaij_(&m,x,ii,idx+shift,v+shift,y,z);
93202ab625aSSatish Balay #else
933d64ed03dSBarry Smith   v   += shift; /* shift for Fortran start by 1 indexing */
934d64ed03dSBarry Smith   idx += shift;
93517ab2063SBarry Smith   for ( i=0; i<m; i++ ) {
9369ea0dfa2SSatish Balay     jrow = ii[i];
9379ea0dfa2SSatish Balay     n    = ii[i+1] - jrow;
93817ab2063SBarry Smith     sum  = y[i];
9399ea0dfa2SSatish Balay     for ( j=0; j<n; j++) {
9409ea0dfa2SSatish Balay       sum += v[jrow]*x[idx[jrow]]; jrow++;
9419ea0dfa2SSatish Balay      }
94217ab2063SBarry Smith     z[i] = sum;
94317ab2063SBarry Smith   }
94402ab625aSSatish Balay #endif
945416022c9SBarry Smith   PLogFlops(2*a->nz);
946e1311b90SBarry Smith   ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr);
947e1311b90SBarry Smith   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
9482e8a6d31SBarry Smith   if (zz != yy) {
949e1311b90SBarry Smith     ierr = VecRestoreArray(zz,&z);CHKERRQ(ierr);
9502e8a6d31SBarry Smith   }
9513a40ed3dSBarry Smith   PetscFunctionReturn(0);
95217ab2063SBarry Smith }
95317ab2063SBarry Smith 
95417ab2063SBarry Smith /*
95517ab2063SBarry Smith      Adds diagonal pointers to sparse matrix structure.
95617ab2063SBarry Smith */
9575615d1e5SSatish Balay #undef __FUNC__
9585615d1e5SSatish Balay #define __FUNC__ "MatMarkDiag_SeqAIJ"
959416022c9SBarry Smith int MatMarkDiag_SeqAIJ(Mat A)
96017ab2063SBarry Smith {
961416022c9SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data;
962416022c9SBarry Smith   int        i,j, *diag, m = a->m,shift = a->indexshift;
96317ab2063SBarry Smith 
9643a40ed3dSBarry Smith   PetscFunctionBegin;
9650452661fSBarry Smith   diag = (int *) PetscMalloc( (m+1)*sizeof(int));CHKPTRQ(diag);
966416022c9SBarry Smith   PLogObjectMemory(A,(m+1)*sizeof(int));
967416022c9SBarry Smith   for ( i=0; i<a->m; i++ ) {
96835b0346bSBarry Smith     diag[i] = a->i[i+1];
969416022c9SBarry Smith     for ( j=a->i[i]+shift; j<a->i[i+1]+shift; j++ ) {
970416022c9SBarry Smith       if (a->j[j]+shift == i) {
97117ab2063SBarry Smith         diag[i] = j - shift;
97217ab2063SBarry Smith         break;
97317ab2063SBarry Smith       }
97417ab2063SBarry Smith     }
97517ab2063SBarry Smith   }
976416022c9SBarry Smith   a->diag = diag;
9773a40ed3dSBarry Smith   PetscFunctionReturn(0);
97817ab2063SBarry Smith }
97917ab2063SBarry Smith 
980be5855fcSBarry Smith /*
981be5855fcSBarry Smith      Checks for missing diagonals
982be5855fcSBarry Smith */
983be5855fcSBarry Smith #undef __FUNC__
984be5855fcSBarry Smith #define __FUNC__ "MatMissingDiag_SeqAIJ"
985be5855fcSBarry Smith int MatMissingDiag_SeqAIJ(Mat A)
986be5855fcSBarry Smith {
987be5855fcSBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data;
988be5855fcSBarry Smith   int        *diag = a->diag, *jj = a->j,i,shift = a->indexshift;
989be5855fcSBarry Smith 
990be5855fcSBarry Smith   PetscFunctionBegin;
991be5855fcSBarry Smith   for ( i=0; i<a->m; i++ ) {
992be5855fcSBarry Smith     if (jj[diag[i]+shift] != i-shift) {
993be5855fcSBarry Smith       SETERRQ1(1,1,"Matrix is missing diagonal number %d",i);
994be5855fcSBarry Smith     }
995be5855fcSBarry Smith   }
996be5855fcSBarry Smith   PetscFunctionReturn(0);
997be5855fcSBarry Smith }
998be5855fcSBarry Smith 
9995615d1e5SSatish Balay #undef __FUNC__
10005615d1e5SSatish Balay #define __FUNC__ "MatRelax_SeqAIJ"
1001be5855fcSBarry Smith int MatRelax_SeqAIJ(Mat A,Vec bb,double omega,MatSORType flag,double fshift,int its,Vec xx)
100217ab2063SBarry Smith {
1003416022c9SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data;
1004d6ed3216SSatish Balay   Scalar     *x, *b, *bs,  d, *xs, sum, *v = a->a,*t=0,scale,*ts, *xb,*idiag=0;
1005d5d45c9bSBarry Smith   int        ierr, *idx, *diag,n = a->n, m = a->m, i, shift = a->indexshift;
100617ab2063SBarry Smith 
10073a40ed3dSBarry Smith   PetscFunctionBegin;
1008e1311b90SBarry Smith   ierr = VecGetArray(xx,&x);CHKERRQ(ierr);
1009fb2e594dSBarry Smith   if (xx != bb) {
1010e1311b90SBarry Smith     ierr = VecGetArray(bb,&b);CHKERRQ(ierr);
1011fb2e594dSBarry Smith   } else {
1012fb2e594dSBarry Smith     b = x;
1013fb2e594dSBarry Smith   }
1014fb2e594dSBarry Smith 
1015d00d2cf4SBarry Smith   if (!a->diag) {ierr = MatMarkDiag_SeqAIJ(A);CHKERRQ(ierr);}
1016416022c9SBarry Smith   diag = a->diag;
1017416022c9SBarry Smith   xs   = x + shift; /* shifted by one for index start of a or a->j*/
101817ab2063SBarry Smith   if (flag == SOR_APPLY_UPPER) {
101917ab2063SBarry Smith    /* apply ( U + D/omega) to the vector */
102017ab2063SBarry Smith     bs = b + shift;
102117ab2063SBarry Smith     for ( i=0; i<m; i++ ) {
1022416022c9SBarry Smith         d    = fshift + a->a[diag[i] + shift];
1023416022c9SBarry Smith         n    = a->i[i+1] - diag[i] - 1;
1024488ecbafSBarry Smith 	PLogFlops(2*n-1);
1025416022c9SBarry Smith         idx  = a->j + diag[i] + (!shift);
1026416022c9SBarry Smith         v    = a->a + diag[i] + (!shift);
102717ab2063SBarry Smith         sum  = b[i]*d/omega;
102817ab2063SBarry Smith         SPARSEDENSEDOT(sum,bs,v,idx,n);
102917ab2063SBarry Smith         x[i] = sum;
103017ab2063SBarry Smith     }
1031cb5b572fSBarry Smith     ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr);
1032fb2e594dSBarry Smith     if (bb != xx) {ierr = VecRestoreArray(bb,&b);CHKERRQ(ierr);}
10333a40ed3dSBarry Smith     PetscFunctionReturn(0);
103417ab2063SBarry Smith   }
1035c783ea89SBarry Smith 
1036c783ea89SBarry Smith   /* setup workspace for Eisenstat */
1037c783ea89SBarry Smith   if (flag & SOR_EISENSTAT) {
1038c783ea89SBarry Smith     if (!a->idiag) {
1039c783ea89SBarry Smith       a->idiag = (Scalar *) PetscMalloc(2*m*sizeof(Scalar));CHKPTRQ(a->idiag);
1040c783ea89SBarry Smith       a->ssor  = a->idiag + m;
1041c783ea89SBarry Smith       v        = a->a;
1042c783ea89SBarry Smith       for ( i=0; i<m; i++ ) { a->idiag[i] = 1.0/v[diag[i]];}
1043c783ea89SBarry Smith     }
1044c783ea89SBarry Smith     t     = a->ssor;
1045c783ea89SBarry Smith     idiag = a->idiag;
1046c783ea89SBarry Smith   }
1047fc3d8934SBarry Smith     /* Let  A = L + U + D; where L is lower trianglar,
1048fc3d8934SBarry Smith     U is upper triangular, E is diagonal; This routine applies
1049fc3d8934SBarry Smith 
1050fc3d8934SBarry Smith             (L + E)^{-1} A (U + E)^{-1}
1051fc3d8934SBarry Smith 
1052fc3d8934SBarry Smith     to a vector efficiently using Eisenstat's trick. This is for
1053fc3d8934SBarry Smith     the case of SSOR preconditioner, so E is D/omega where omega
105448af12d7SBarry Smith     is the relaxation factor.
1055fc3d8934SBarry Smith     */
1056fc3d8934SBarry Smith 
105748af12d7SBarry Smith   if (flag == SOR_APPLY_LOWER) {
105848af12d7SBarry Smith     SETERRQ(PETSC_ERR_SUP,0,"SOR_APPLY_LOWER is not done");
105948af12d7SBarry Smith   } else if ((flag & SOR_EISENSTAT) && omega == 1.0 && shift == 0 && fshift == 0.0) {
106048af12d7SBarry Smith     /* special case for omega = 1.0 saves flops and some integer ops */
1061733d66baSBarry Smith     Scalar *v2;
106248af12d7SBarry Smith 
1063733d66baSBarry Smith     v2    = a->a;
1064fc3d8934SBarry Smith     /*  x = (E + U)^{-1} b */
1065fc3d8934SBarry Smith     for ( i=m-1; i>=0; i-- ) {
1066fc3d8934SBarry Smith       n    = a->i[i+1] - diag[i] - 1;
1067fc3d8934SBarry Smith       idx  = a->j + diag[i] + 1;
1068fc3d8934SBarry Smith       v    = a->a + diag[i] + 1;
1069fc3d8934SBarry Smith       sum  = b[i];
1070fc3d8934SBarry Smith       SPARSEDENSEMDOT(sum,xs,v,idx,n);
1071b4632166SBarry Smith       x[i] = sum*idiag[i];
1072fc3d8934SBarry Smith 
1073fc3d8934SBarry Smith       /*  t = b - (2*E - D)x */
1074733d66baSBarry Smith       t[i] = b[i] - (v2[diag[i]])*x[i];
1075733d66baSBarry Smith     }
1076fc3d8934SBarry Smith 
1077fc3d8934SBarry Smith     /*  t = (E + L)^{-1}t */
1078fc3d8934SBarry Smith     diag = a->diag;
1079fc3d8934SBarry Smith     for ( i=0; i<m; i++ ) {
1080fc3d8934SBarry Smith       n    = diag[i] - a->i[i];
1081fc3d8934SBarry Smith       idx  = a->j + a->i[i];
1082fc3d8934SBarry Smith       v    = a->a + a->i[i];
1083fc3d8934SBarry Smith       sum  = t[i];
1084fc3d8934SBarry Smith       SPARSEDENSEMDOT(sum,t,v,idx,n);
1085b4632166SBarry Smith       t[i]  = sum*idiag[i];
1086fc3d8934SBarry Smith 
1087fc3d8934SBarry Smith       /*  x = x + t */
1088733d66baSBarry Smith       x[i] += t[i];
1089733d66baSBarry Smith     }
1090733d66baSBarry Smith 
1091a4d9cbf6SBarry Smith     PLogFlops(3*m-1 + 2*a->nz);
1092fc3d8934SBarry Smith     ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr);
1093fc3d8934SBarry Smith     if (bb != xx) {ierr = VecRestoreArray(bb,&b);CHKERRQ(ierr);}
1094fc3d8934SBarry Smith     PetscFunctionReturn(0);
10953a40ed3dSBarry Smith   } else if (flag & SOR_EISENSTAT) {
109617ab2063SBarry Smith     /* Let  A = L + U + D; where L is lower trianglar,
109717ab2063SBarry Smith     U is upper triangular, E is diagonal; This routine applies
109817ab2063SBarry Smith 
109917ab2063SBarry Smith             (L + E)^{-1} A (U + E)^{-1}
110017ab2063SBarry Smith 
110117ab2063SBarry Smith     to a vector efficiently using Eisenstat's trick. This is for
110217ab2063SBarry Smith     the case of SSOR preconditioner, so E is D/omega where omega
110317ab2063SBarry Smith     is the relaxation factor.
110417ab2063SBarry Smith     */
110517ab2063SBarry Smith     scale = (2.0/omega) - 1.0;
110617ab2063SBarry Smith 
110717ab2063SBarry Smith     /*  x = (E + U)^{-1} b */
110817ab2063SBarry Smith     for ( i=m-1; i>=0; i-- ) {
1109416022c9SBarry Smith       d    = fshift + a->a[diag[i] + shift];
1110416022c9SBarry Smith       n    = a->i[i+1] - diag[i] - 1;
1111416022c9SBarry Smith       idx  = a->j + diag[i] + (!shift);
1112416022c9SBarry Smith       v    = a->a + diag[i] + (!shift);
111317ab2063SBarry Smith       sum  = b[i];
111417ab2063SBarry Smith       SPARSEDENSEMDOT(sum,xs,v,idx,n);
111517ab2063SBarry Smith       x[i] = omega*(sum/d);
111617ab2063SBarry Smith     }
111717ab2063SBarry Smith 
111817ab2063SBarry Smith     /*  t = b - (2*E - D)x */
1119416022c9SBarry Smith     v = a->a;
112017ab2063SBarry Smith     for ( i=0; i<m; i++ ) { t[i] = b[i] - scale*(v[*diag++ + shift])*x[i]; }
112117ab2063SBarry Smith 
112217ab2063SBarry Smith     /*  t = (E + L)^{-1}t */
1123416022c9SBarry Smith     ts = t + shift; /* shifted by one for index start of a or a->j*/
1124416022c9SBarry Smith     diag = a->diag;
112517ab2063SBarry Smith     for ( i=0; i<m; i++ ) {
1126416022c9SBarry Smith       d    = fshift + a->a[diag[i]+shift];
1127416022c9SBarry Smith       n    = diag[i] - a->i[i];
1128416022c9SBarry Smith       idx  = a->j + a->i[i] + shift;
1129416022c9SBarry Smith       v    = a->a + a->i[i] + shift;
113017ab2063SBarry Smith       sum  = t[i];
113117ab2063SBarry Smith       SPARSEDENSEMDOT(sum,ts,v,idx,n);
113217ab2063SBarry Smith       t[i] = omega*(sum/d);
1133733d66baSBarry Smith       /*  x = x + t */
1134733d66baSBarry Smith       x[i] += t[i];
113517ab2063SBarry Smith     }
113617ab2063SBarry Smith 
1137c783ea89SBarry Smith     PLogFlops(6*m-1 + 2*a->nz);
1138cb5b572fSBarry Smith     ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr);
1139fb2e594dSBarry Smith     if (bb != xx) {ierr = VecRestoreArray(bb,&b);CHKERRQ(ierr);}
11403a40ed3dSBarry Smith     PetscFunctionReturn(0);
114117ab2063SBarry Smith   }
114217ab2063SBarry Smith   if (flag & SOR_ZERO_INITIAL_GUESS) {
114317ab2063SBarry Smith     if (flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP){
114417ab2063SBarry Smith       for ( i=0; i<m; i++ ) {
1145416022c9SBarry Smith         d    = fshift + a->a[diag[i]+shift];
1146416022c9SBarry Smith         n    = diag[i] - a->i[i];
1147488ecbafSBarry Smith 	PLogFlops(2*n-1);
1148416022c9SBarry Smith         idx  = a->j + a->i[i] + shift;
1149416022c9SBarry Smith         v    = a->a + a->i[i] + shift;
115017ab2063SBarry Smith         sum  = b[i];
115117ab2063SBarry Smith         SPARSEDENSEMDOT(sum,xs,v,idx,n);
115217ab2063SBarry Smith         x[i] = omega*(sum/d);
115317ab2063SBarry Smith       }
115417ab2063SBarry Smith       xb = x;
11553a40ed3dSBarry Smith     } else xb = b;
115617ab2063SBarry Smith     if ((flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP) &&
115717ab2063SBarry Smith         (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP)) {
115817ab2063SBarry Smith       for ( i=0; i<m; i++ ) {
1159416022c9SBarry Smith         x[i] *= a->a[diag[i]+shift];
116017ab2063SBarry Smith       }
1161488ecbafSBarry Smith       PLogFlops(m);
116217ab2063SBarry Smith     }
116317ab2063SBarry Smith     if (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP){
116417ab2063SBarry Smith       for ( i=m-1; i>=0; i-- ) {
1165416022c9SBarry Smith         d    = fshift + a->a[diag[i] + shift];
1166416022c9SBarry Smith         n    = a->i[i+1] - diag[i] - 1;
1167488ecbafSBarry Smith 	PLogFlops(2*n-1);
1168416022c9SBarry Smith         idx  = a->j + diag[i] + (!shift);
1169416022c9SBarry Smith         v    = a->a + diag[i] + (!shift);
117017ab2063SBarry Smith         sum  = xb[i];
117117ab2063SBarry Smith         SPARSEDENSEMDOT(sum,xs,v,idx,n);
117217ab2063SBarry Smith         x[i] = omega*(sum/d);
117317ab2063SBarry Smith       }
117417ab2063SBarry Smith     }
117517ab2063SBarry Smith     its--;
117617ab2063SBarry Smith   }
117717ab2063SBarry Smith   while (its--) {
117817ab2063SBarry Smith     if (flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP){
117917ab2063SBarry Smith       for ( i=0; i<m; i++ ) {
1180416022c9SBarry Smith         d    = fshift + a->a[diag[i]+shift];
1181416022c9SBarry Smith         n    = a->i[i+1] - a->i[i];
1182488ecbafSBarry Smith 	PLogFlops(2*n-1);
1183416022c9SBarry Smith         idx  = a->j + a->i[i] + shift;
1184416022c9SBarry Smith         v    = a->a + a->i[i] + shift;
118517ab2063SBarry Smith         sum  = b[i];
118617ab2063SBarry Smith         SPARSEDENSEMDOT(sum,xs,v,idx,n);
11877e33a6baSBarry Smith         x[i] = (1. - omega)*x[i] + omega*(sum + a->a[diag[i]+shift]*x[i])/d;
118817ab2063SBarry Smith       }
118917ab2063SBarry Smith     }
119017ab2063SBarry Smith     if (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP){
119117ab2063SBarry Smith       for ( i=m-1; i>=0; i-- ) {
1192416022c9SBarry Smith         d    = fshift + a->a[diag[i] + shift];
1193416022c9SBarry Smith         n    = a->i[i+1] - a->i[i];
1194488ecbafSBarry Smith 	PLogFlops(2*n-1);
1195416022c9SBarry Smith         idx  = a->j + a->i[i] + shift;
1196416022c9SBarry Smith         v    = a->a + a->i[i] + shift;
119717ab2063SBarry Smith         sum  = b[i];
119817ab2063SBarry Smith         SPARSEDENSEMDOT(sum,xs,v,idx,n);
11997e33a6baSBarry Smith         x[i] = (1. - omega)*x[i] + omega*(sum + a->a[diag[i]+shift]*x[i])/d;
120017ab2063SBarry Smith       }
120117ab2063SBarry Smith     }
120217ab2063SBarry Smith   }
1203cb5b572fSBarry Smith   ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr);
1204fb2e594dSBarry Smith   if (bb != xx) {ierr = VecRestoreArray(bb,&b);CHKERRQ(ierr);}
12053a40ed3dSBarry Smith   PetscFunctionReturn(0);
120617ab2063SBarry Smith }
120717ab2063SBarry Smith 
12085615d1e5SSatish Balay #undef __FUNC__
12095615d1e5SSatish Balay #define __FUNC__ "MatGetInfo_SeqAIJ"
12108f6be9afSLois Curfman McInnes int MatGetInfo_SeqAIJ(Mat A,MatInfoType flag,MatInfo *info)
121117ab2063SBarry Smith {
1212416022c9SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data;
12134e220ebcSLois Curfman McInnes 
12143a40ed3dSBarry Smith   PetscFunctionBegin;
12154e220ebcSLois Curfman McInnes   info->rows_global    = (double)a->m;
12164e220ebcSLois Curfman McInnes   info->columns_global = (double)a->n;
12174e220ebcSLois Curfman McInnes   info->rows_local     = (double)a->m;
12184e220ebcSLois Curfman McInnes   info->columns_local  = (double)a->n;
12194e220ebcSLois Curfman McInnes   info->block_size     = 1.0;
12204e220ebcSLois Curfman McInnes   info->nz_allocated   = (double)a->maxnz;
12214e220ebcSLois Curfman McInnes   info->nz_used        = (double)a->nz;
12224e220ebcSLois Curfman McInnes   info->nz_unneeded    = (double)(a->maxnz - a->nz);
12234e220ebcSLois Curfman McInnes   info->assemblies     = (double)A->num_ass;
12244e220ebcSLois Curfman McInnes   info->mallocs        = (double)a->reallocs;
12254e220ebcSLois Curfman McInnes   info->memory         = A->mem;
12264e220ebcSLois Curfman McInnes   if (A->factor) {
12274e220ebcSLois Curfman McInnes     info->fill_ratio_given  = A->info.fill_ratio_given;
12284e220ebcSLois Curfman McInnes     info->fill_ratio_needed = A->info.fill_ratio_needed;
12294e220ebcSLois Curfman McInnes     info->factor_mallocs    = A->info.factor_mallocs;
12304e220ebcSLois Curfman McInnes   } else {
12314e220ebcSLois Curfman McInnes     info->fill_ratio_given  = 0;
12324e220ebcSLois Curfman McInnes     info->fill_ratio_needed = 0;
12334e220ebcSLois Curfman McInnes     info->factor_mallocs    = 0;
12344e220ebcSLois Curfman McInnes   }
12353a40ed3dSBarry Smith   PetscFunctionReturn(0);
123617ab2063SBarry Smith }
123717ab2063SBarry Smith 
123817ab2063SBarry Smith extern int MatLUFactorSymbolic_SeqAIJ(Mat,IS,IS,double,Mat*);
123917ab2063SBarry Smith extern int MatLUFactorNumeric_SeqAIJ(Mat,Mat*);
124017ab2063SBarry Smith extern int MatLUFactor_SeqAIJ(Mat,IS,IS,double);
124117ab2063SBarry Smith extern int MatSolve_SeqAIJ(Mat,Vec,Vec);
124217ab2063SBarry Smith extern int MatSolveAdd_SeqAIJ(Mat,Vec,Vec,Vec);
124317ab2063SBarry Smith extern int MatSolveTrans_SeqAIJ(Mat,Vec,Vec);
124417ab2063SBarry Smith extern int MatSolveTransAdd_SeqAIJ(Mat,Vec,Vec,Vec);
124517ab2063SBarry Smith 
12465615d1e5SSatish Balay #undef __FUNC__
12475615d1e5SSatish Balay #define __FUNC__ "MatZeroRows_SeqAIJ"
12488f6be9afSLois Curfman McInnes int MatZeroRows_SeqAIJ(Mat A,IS is,Scalar *diag)
124917ab2063SBarry Smith {
1250416022c9SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data;
1251416022c9SBarry Smith   int         i,ierr,N, *rows,m = a->m - 1,shift = a->indexshift;
125217ab2063SBarry Smith 
12533a40ed3dSBarry Smith   PetscFunctionBegin;
125477c4ece6SBarry Smith   ierr = ISGetSize(is,&N);CHKERRQ(ierr);
125517ab2063SBarry Smith   ierr = ISGetIndices(is,&rows);CHKERRQ(ierr);
125617ab2063SBarry Smith   if (diag) {
125717ab2063SBarry Smith     for ( i=0; i<N; i++ ) {
1258a8c6a408SBarry Smith       if (rows[i] < 0 || rows[i] > m) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"row out of range");
12597ae801bdSBarry Smith       if (a->ilen[rows[i]] > 0) {
1260416022c9SBarry Smith         a->ilen[rows[i]]          = 1;
1261416022c9SBarry Smith         a->a[a->i[rows[i]]+shift] = *diag;
1262416022c9SBarry Smith         a->j[a->i[rows[i]]+shift] = rows[i]+shift;
12637ae801bdSBarry Smith       } else { /* in case row was completely empty */
1264d64ed03dSBarry Smith         ierr = MatSetValues_SeqAIJ(A,1,&rows[i],1,&rows[i],diag,INSERT_VALUES);CHKERRQ(ierr);
126517ab2063SBarry Smith       }
126617ab2063SBarry Smith     }
12673a40ed3dSBarry Smith   } else {
126817ab2063SBarry Smith     for ( i=0; i<N; i++ ) {
1269a8c6a408SBarry Smith       if (rows[i] < 0 || rows[i] > m) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"row out of range");
1270416022c9SBarry Smith       a->ilen[rows[i]] = 0;
127117ab2063SBarry Smith     }
127217ab2063SBarry Smith   }
12737ae801bdSBarry Smith   ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr);
127443a90d84SBarry Smith   ierr = MatAssemblyEnd_SeqAIJ(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
12753a40ed3dSBarry Smith   PetscFunctionReturn(0);
127617ab2063SBarry Smith }
127717ab2063SBarry Smith 
12785615d1e5SSatish Balay #undef __FUNC__
12795615d1e5SSatish Balay #define __FUNC__ "MatGetSize_SeqAIJ"
12808f6be9afSLois Curfman McInnes int MatGetSize_SeqAIJ(Mat A,int *m,int *n)
128117ab2063SBarry Smith {
1282416022c9SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data;
12833a40ed3dSBarry Smith 
12843a40ed3dSBarry Smith   PetscFunctionBegin;
12850752156aSBarry Smith   if (m) *m = a->m;
12860752156aSBarry Smith   if (n) *n = a->n;
12873a40ed3dSBarry Smith   PetscFunctionReturn(0);
128817ab2063SBarry Smith }
128917ab2063SBarry Smith 
12905615d1e5SSatish Balay #undef __FUNC__
12915615d1e5SSatish Balay #define __FUNC__ "MatGetOwnershipRange_SeqAIJ"
12928f6be9afSLois Curfman McInnes int MatGetOwnershipRange_SeqAIJ(Mat A,int *m,int *n)
129317ab2063SBarry Smith {
1294416022c9SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data;
12953a40ed3dSBarry Smith 
12963a40ed3dSBarry Smith   PetscFunctionBegin;
1297416022c9SBarry Smith   *m = 0; *n = a->m;
12983a40ed3dSBarry Smith   PetscFunctionReturn(0);
129917ab2063SBarry Smith }
1300026e39d0SSatish Balay 
13015615d1e5SSatish Balay #undef __FUNC__
13025615d1e5SSatish Balay #define __FUNC__ "MatGetRow_SeqAIJ"
13034e093b46SBarry Smith int MatGetRow_SeqAIJ(Mat A,int row,int *nz,int **idx,Scalar **v)
130417ab2063SBarry Smith {
1305416022c9SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data;
1306c456f294SBarry Smith   int        *itmp,i,shift = a->indexshift;
130717ab2063SBarry Smith 
13083a40ed3dSBarry Smith   PetscFunctionBegin;
1309a8c6a408SBarry Smith   if (row < 0 || row >= a->m) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Row out of range");
131017ab2063SBarry Smith 
1311416022c9SBarry Smith   *nz = a->i[row+1] - a->i[row];
1312416022c9SBarry Smith   if (v) *v = a->a + a->i[row] + shift;
131317ab2063SBarry Smith   if (idx) {
1314416022c9SBarry Smith     itmp = a->j + a->i[row] + shift;
13154e093b46SBarry Smith     if (*nz && shift) {
13160452661fSBarry Smith       *idx = (int *) PetscMalloc( (*nz)*sizeof(int) );CHKPTRQ(*idx);
131717ab2063SBarry Smith       for ( i=0; i<(*nz); i++ ) {(*idx)[i] = itmp[i] + shift;}
13184e093b46SBarry Smith     } else if (*nz) {
13194e093b46SBarry Smith       *idx = itmp;
132017ab2063SBarry Smith     }
132117ab2063SBarry Smith     else *idx = 0;
132217ab2063SBarry Smith   }
13233a40ed3dSBarry Smith   PetscFunctionReturn(0);
132417ab2063SBarry Smith }
132517ab2063SBarry Smith 
13265615d1e5SSatish Balay #undef __FUNC__
13275615d1e5SSatish Balay #define __FUNC__ "MatRestoreRow_SeqAIJ"
13284e093b46SBarry Smith int MatRestoreRow_SeqAIJ(Mat A,int row,int *nz,int **idx,Scalar **v)
132917ab2063SBarry Smith {
13304e093b46SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data;
1331606d414cSSatish Balay   int ierr;
13323a40ed3dSBarry Smith 
13333a40ed3dSBarry Smith   PetscFunctionBegin;
1334606d414cSSatish Balay   if (idx) {if (*idx && a->indexshift) {ierr = PetscFree(*idx);CHKERRQ(ierr);}}
13353a40ed3dSBarry Smith   PetscFunctionReturn(0);
133617ab2063SBarry Smith }
133717ab2063SBarry Smith 
13385615d1e5SSatish Balay #undef __FUNC__
13395615d1e5SSatish Balay #define __FUNC__ "MatNorm_SeqAIJ"
13408f6be9afSLois Curfman McInnes int MatNorm_SeqAIJ(Mat A,NormType type,double *norm)
134117ab2063SBarry Smith {
1342416022c9SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data;
1343416022c9SBarry Smith   Scalar     *v = a->a;
134417ab2063SBarry Smith   double     sum = 0.0;
1345549d3d68SSatish Balay   int        i, j,shift = a->indexshift,ierr;
134617ab2063SBarry Smith 
13473a40ed3dSBarry Smith   PetscFunctionBegin;
134817ab2063SBarry Smith   if (type == NORM_FROBENIUS) {
1349416022c9SBarry Smith     for (i=0; i<a->nz; i++ ) {
1350aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
1351e20fef11SSatish Balay       sum += PetscReal(PetscConj(*v)*(*v)); v++;
135217ab2063SBarry Smith #else
135317ab2063SBarry Smith       sum += (*v)*(*v); v++;
135417ab2063SBarry Smith #endif
135517ab2063SBarry Smith     }
135617ab2063SBarry Smith     *norm = sqrt(sum);
13573a40ed3dSBarry Smith   } else if (type == NORM_1) {
135817ab2063SBarry Smith     double *tmp;
1359416022c9SBarry Smith     int    *jj = a->j;
136066963ce1SSatish Balay     tmp = (double *) PetscMalloc( (a->n+1)*sizeof(double) );CHKPTRQ(tmp);
1361549d3d68SSatish Balay     ierr = PetscMemzero(tmp,a->n*sizeof(double));CHKERRQ(ierr);
136217ab2063SBarry Smith     *norm = 0.0;
1363416022c9SBarry Smith     for ( j=0; j<a->nz; j++ ) {
1364a2744918SBarry Smith         tmp[*jj++ + shift] += PetscAbsScalar(*v);  v++;
136517ab2063SBarry Smith     }
1366416022c9SBarry Smith     for ( j=0; j<a->n; j++ ) {
136717ab2063SBarry Smith       if (tmp[j] > *norm) *norm = tmp[j];
136817ab2063SBarry Smith     }
1369606d414cSSatish Balay     ierr = PetscFree(tmp);CHKERRQ(ierr);
13703a40ed3dSBarry Smith   } else if (type == NORM_INFINITY) {
137117ab2063SBarry Smith     *norm = 0.0;
1372416022c9SBarry Smith     for ( j=0; j<a->m; j++ ) {
1373416022c9SBarry Smith       v = a->a + a->i[j] + shift;
137417ab2063SBarry Smith       sum = 0.0;
1375416022c9SBarry Smith       for ( i=0; i<a->i[j+1]-a->i[j]; i++ ) {
1376cddf8d76SBarry Smith         sum += PetscAbsScalar(*v); v++;
137717ab2063SBarry Smith       }
137817ab2063SBarry Smith       if (sum > *norm) *norm = sum;
137917ab2063SBarry Smith     }
13803a40ed3dSBarry Smith   } else {
1381a8c6a408SBarry Smith     SETERRQ(PETSC_ERR_SUP,0,"No support for two norm");
138217ab2063SBarry Smith   }
13833a40ed3dSBarry Smith   PetscFunctionReturn(0);
138417ab2063SBarry Smith }
138517ab2063SBarry Smith 
13865615d1e5SSatish Balay #undef __FUNC__
13875615d1e5SSatish Balay #define __FUNC__ "MatTranspose_SeqAIJ"
13888f6be9afSLois Curfman McInnes int MatTranspose_SeqAIJ(Mat A,Mat *B)
138917ab2063SBarry Smith {
1390416022c9SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data;
1391416022c9SBarry Smith   Mat        C;
1392416022c9SBarry Smith   int        i, ierr, *aj = a->j, *ai = a->i, m = a->m, len, *col;
1393416022c9SBarry Smith   int        shift = a->indexshift;
1394d5d45c9bSBarry Smith   Scalar     *array = a->a;
139517ab2063SBarry Smith 
13963a40ed3dSBarry Smith   PetscFunctionBegin;
1397a8c6a408SBarry Smith   if (B == PETSC_NULL && m != a->n) SETERRQ(PETSC_ERR_ARG_SIZ,0,"Square matrix only for in-place");
13980452661fSBarry Smith   col  = (int *) PetscMalloc((1+a->n)*sizeof(int));CHKPTRQ(col);
1399549d3d68SSatish Balay   ierr = PetscMemzero(col,(1+a->n)*sizeof(int));CHKERRQ(ierr);
140017ab2063SBarry Smith   if (shift) {
140117ab2063SBarry Smith     for ( i=0; i<ai[m]-1; i++ ) aj[i] -= 1;
140217ab2063SBarry Smith   }
140317ab2063SBarry Smith   for ( i=0; i<ai[m]+shift; i++ ) col[aj[i]] += 1;
1404416022c9SBarry Smith   ierr = MatCreateSeqAIJ(A->comm,a->n,m,0,col,&C);CHKERRQ(ierr);
1405606d414cSSatish Balay   ierr = PetscFree(col);CHKERRQ(ierr);
140617ab2063SBarry Smith   for ( i=0; i<m; i++ ) {
140717ab2063SBarry Smith     len = ai[i+1]-ai[i];
1408416022c9SBarry Smith     ierr = MatSetValues(C,len,aj,1,&i,array,INSERT_VALUES);CHKERRQ(ierr);
140917ab2063SBarry Smith     array += len; aj += len;
141017ab2063SBarry Smith   }
141117ab2063SBarry Smith   if (shift) {
141217ab2063SBarry Smith     for ( i=0; i<ai[m]-1; i++ ) aj[i] += 1;
141317ab2063SBarry Smith   }
141417ab2063SBarry Smith 
14156d4a8577SBarry Smith   ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
14166d4a8577SBarry Smith   ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
141717ab2063SBarry Smith 
14183638b69dSLois Curfman McInnes   if (B != PETSC_NULL) {
1419416022c9SBarry Smith     *B = C;
142017ab2063SBarry Smith   } else {
1421f830108cSBarry Smith     PetscOps *Abops;
14220a6ffc59SBarry Smith     MatOps   Aops;
1423f830108cSBarry Smith 
1424416022c9SBarry Smith     /* This isn't really an in-place transpose */
1425606d414cSSatish Balay     ierr = PetscFree(a->a);CHKERRQ(ierr);
1426606d414cSSatish Balay     if (!a->singlemalloc) {
1427606d414cSSatish Balay       ierr = PetscFree(a->i);CHKERRQ(ierr);
1428606d414cSSatish Balay       ierr = PetscFree(a->j);
1429606d414cSSatish Balay     }
1430606d414cSSatish Balay     if (a->diag) {ierr = PetscFree(a->diag);CHKERRQ(ierr);}
1431606d414cSSatish Balay     if (a->ilen) {ierr = PetscFree(a->ilen);CHKERRQ(ierr);}
1432606d414cSSatish Balay     if (a->imax) {ierr = PetscFree(a->imax);CHKERRQ(ierr);}
1433606d414cSSatish Balay     if (a->solve_work) {ierr = PetscFree(a->solve_work);CHKERRQ(ierr);}
1434606d414cSSatish Balay     if (a->inode.size) {ierr = PetscFree(a->inode.size);CHKERRQ(ierr);}
1435606d414cSSatish Balay     ierr = PetscFree(a);CHKERRQ(ierr);
1436f830108cSBarry Smith 
1437488ecbafSBarry Smith 
1438488ecbafSBarry Smith     ierr = MapDestroy(A->rmap);CHKERRQ(ierr);
1439488ecbafSBarry Smith     ierr = MapDestroy(A->cmap);CHKERRQ(ierr);
1440488ecbafSBarry Smith 
1441f830108cSBarry Smith     /*
1442f830108cSBarry Smith       This is horrible, horrible code. We need to keep the
14438f0f457cSSatish Balay       the bops and ops Structures, copy everything from C
14448f0f457cSSatish Balay       including the function pointers..
1445f830108cSBarry Smith     */
1446549d3d68SSatish Balay     ierr     = PetscMemcpy(A->ops,C->ops,sizeof(struct _MatOps));CHKERRQ(ierr);
1447549d3d68SSatish Balay     ierr     = PetscMemcpy(A->bops,C->bops,sizeof(PetscOps));CHKERRQ(ierr);
1448f830108cSBarry Smith     Abops    = A->bops;
1449f830108cSBarry Smith     Aops     = A->ops;
1450549d3d68SSatish Balay     ierr     = PetscMemcpy(A,C,sizeof(struct _p_Mat));CHKERRQ(ierr);
1451f830108cSBarry Smith     A->bops  = Abops;
1452f830108cSBarry Smith     A->ops   = Aops;
145327a8da17SBarry Smith     A->qlist = 0;
1454f830108cSBarry Smith 
14550452661fSBarry Smith     PetscHeaderDestroy(C);
145617ab2063SBarry Smith   }
14573a40ed3dSBarry Smith   PetscFunctionReturn(0);
145817ab2063SBarry Smith }
145917ab2063SBarry Smith 
14605615d1e5SSatish Balay #undef __FUNC__
14615615d1e5SSatish Balay #define __FUNC__ "MatDiagonalScale_SeqAIJ"
14628f6be9afSLois Curfman McInnes int MatDiagonalScale_SeqAIJ(Mat A,Vec ll,Vec rr)
146317ab2063SBarry Smith {
1464416022c9SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data;
146517ab2063SBarry Smith   Scalar     *l,*r,x,*v;
1466e1311b90SBarry Smith   int        ierr,i,j,m = a->m, n = a->n, M, nz = a->nz, *jj,shift = a->indexshift;
146717ab2063SBarry Smith 
14683a40ed3dSBarry Smith   PetscFunctionBegin;
146917ab2063SBarry Smith   if (ll) {
14703ea7c6a1SSatish Balay     /* The local size is used so that VecMPI can be passed to this routine
14713ea7c6a1SSatish Balay        by MatDiagonalScale_MPIAIJ */
1472e1311b90SBarry Smith     ierr = VecGetLocalSize(ll,&m);CHKERRQ(ierr);
1473a8c6a408SBarry Smith     if (m != a->m) SETERRQ(PETSC_ERR_ARG_SIZ,0,"Left scaling vector wrong length");
1474e1311b90SBarry Smith     ierr = VecGetArray(ll,&l);CHKERRQ(ierr);
1475416022c9SBarry Smith     v = a->a;
147617ab2063SBarry Smith     for ( i=0; i<m; i++ ) {
147717ab2063SBarry Smith       x = l[i];
1478416022c9SBarry Smith       M = a->i[i+1] - a->i[i];
147917ab2063SBarry Smith       for ( j=0; j<M; j++ ) { (*v++) *= x;}
148017ab2063SBarry Smith     }
1481e1311b90SBarry Smith     ierr = VecRestoreArray(ll,&l);CHKERRQ(ierr);
148244cd7ae7SLois Curfman McInnes     PLogFlops(nz);
148317ab2063SBarry Smith   }
148417ab2063SBarry Smith   if (rr) {
1485e1311b90SBarry Smith     ierr = VecGetLocalSize(rr,&n);CHKERRQ(ierr);
1486a8c6a408SBarry Smith     if (n != a->n) SETERRQ(PETSC_ERR_ARG_SIZ,0,"Right scaling vector wrong length");
1487e1311b90SBarry Smith     ierr = VecGetArray(rr,&r);CHKERRQ(ierr);
1488416022c9SBarry Smith     v = a->a; jj = a->j;
148917ab2063SBarry Smith     for ( i=0; i<nz; i++ ) {
149017ab2063SBarry Smith       (*v++) *= r[*jj++ + shift];
149117ab2063SBarry Smith     }
1492e1311b90SBarry Smith     ierr = VecRestoreArray(rr,&r);CHKERRQ(ierr);
149344cd7ae7SLois Curfman McInnes     PLogFlops(nz);
149417ab2063SBarry Smith   }
14953a40ed3dSBarry Smith   PetscFunctionReturn(0);
149617ab2063SBarry Smith }
149717ab2063SBarry Smith 
14985615d1e5SSatish Balay #undef __FUNC__
14995615d1e5SSatish Balay #define __FUNC__ "MatGetSubMatrix_SeqAIJ"
15007b2a1423SBarry Smith int MatGetSubMatrix_SeqAIJ(Mat A,IS isrow,IS iscol,int csize,MatReuse scall,Mat *B)
150117ab2063SBarry Smith {
1502db02288aSLois Curfman McInnes   Mat_SeqAIJ   *a = (Mat_SeqAIJ *) A->data,*c;
1503d5db1b72SBarry Smith   int          *smap, i, k, kstart, kend, ierr, oldcols = a->n,*lens;
150499141d43SSatish Balay   int          row,mat_i,*mat_j,tcol,first,step,*mat_ilen;
1505a2744918SBarry Smith   register int sum,lensi;
150699141d43SSatish Balay   int          *irow, *icol, nrows, ncols, shift = a->indexshift,*ssmap;
150799141d43SSatish Balay   int          *starts,*j_new,*i_new,*aj = a->j, *ai = a->i,ii,*ailen = a->ilen;
150899141d43SSatish Balay   Scalar       *a_new,*mat_a;
1509416022c9SBarry Smith   Mat          C;
1510fee21e36SBarry Smith   PetscTruth   stride;
151117ab2063SBarry Smith 
15123a40ed3dSBarry Smith   PetscFunctionBegin;
1513d64ed03dSBarry Smith   ierr = ISSorted(isrow,(PetscTruth*)&i);CHKERRQ(ierr);
1514a8c6a408SBarry Smith   if (!i) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,0,"ISrow is not sorted");
1515d64ed03dSBarry Smith   ierr = ISSorted(iscol,(PetscTruth*)&i);CHKERRQ(ierr);
1516a8c6a408SBarry Smith   if (!i) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,0,"IScol is not sorted");
151799141d43SSatish Balay 
151817ab2063SBarry Smith   ierr = ISGetIndices(isrow,&irow);CHKERRQ(ierr);
151917ab2063SBarry Smith   ierr = ISGetSize(isrow,&nrows);CHKERRQ(ierr);
152017ab2063SBarry Smith   ierr = ISGetSize(iscol,&ncols);CHKERRQ(ierr);
152117ab2063SBarry Smith 
1522fee21e36SBarry Smith   ierr = ISStrideGetInfo(iscol,&first,&step);CHKERRQ(ierr);
1523fee21e36SBarry Smith   ierr = ISStride(iscol,&stride);CHKERRQ(ierr);
1524fee21e36SBarry Smith   if (stride && step == 1) {
152502834360SBarry Smith     /* special case of contiguous rows */
152657faeb66SBarry Smith     lens   = (int *) PetscMalloc((ncols+nrows+1)*sizeof(int));CHKPTRQ(lens);
152702834360SBarry Smith     starts = lens + ncols;
152802834360SBarry Smith     /* loop over new rows determining lens and starting points */
152902834360SBarry Smith     for (i=0; i<nrows; i++) {
1530a2744918SBarry Smith       kstart  = ai[irow[i]]+shift;
1531a2744918SBarry Smith       kend    = kstart + ailen[irow[i]];
153202834360SBarry Smith       for ( k=kstart; k<kend; k++ ) {
1533d8ced48eSBarry Smith         if (aj[k]+shift >= first) {
153402834360SBarry Smith           starts[i] = k;
153502834360SBarry Smith           break;
153602834360SBarry Smith 	}
153702834360SBarry Smith       }
1538a2744918SBarry Smith       sum = 0;
153902834360SBarry Smith       while (k < kend) {
1540d8ced48eSBarry Smith         if (aj[k++]+shift >= first+ncols) break;
1541a2744918SBarry Smith         sum++;
154202834360SBarry Smith       }
1543a2744918SBarry Smith       lens[i] = sum;
154402834360SBarry Smith     }
154502834360SBarry Smith     /* create submatrix */
1546cddf8d76SBarry Smith     if (scall == MAT_REUSE_MATRIX) {
154708480c60SBarry Smith       int n_cols,n_rows;
154808480c60SBarry Smith       ierr = MatGetSize(*B,&n_rows,&n_cols);CHKERRQ(ierr);
1549a8c6a408SBarry Smith       if (n_rows != nrows || n_cols != ncols) SETERRQ(PETSC_ERR_ARG_SIZ,0,"Reused submatrix wrong size");
1550d8ced48eSBarry Smith       ierr = MatZeroEntries(*B);CHKERRQ(ierr);
155108480c60SBarry Smith       C = *B;
15523a40ed3dSBarry Smith     } else {
155302834360SBarry Smith       ierr = MatCreateSeqAIJ(A->comm,nrows,ncols,0,lens,&C);CHKERRQ(ierr);
155408480c60SBarry Smith     }
1555db02288aSLois Curfman McInnes     c = (Mat_SeqAIJ*) C->data;
1556db02288aSLois Curfman McInnes 
155702834360SBarry Smith     /* loop over rows inserting into submatrix */
1558db02288aSLois Curfman McInnes     a_new    = c->a;
1559db02288aSLois Curfman McInnes     j_new    = c->j;
1560db02288aSLois Curfman McInnes     i_new    = c->i;
1561db02288aSLois Curfman McInnes     i_new[0] = -shift;
156202834360SBarry Smith     for (i=0; i<nrows; i++) {
1563a2744918SBarry Smith       ii    = starts[i];
1564a2744918SBarry Smith       lensi = lens[i];
1565a2744918SBarry Smith       for ( k=0; k<lensi; k++ ) {
1566a2744918SBarry Smith         *j_new++ = aj[ii+k] - first;
156702834360SBarry Smith       }
1568549d3d68SSatish Balay       ierr = PetscMemcpy(a_new,a->a + starts[i],lensi*sizeof(Scalar));CHKERRQ(ierr);
1569a2744918SBarry Smith       a_new      += lensi;
1570a2744918SBarry Smith       i_new[i+1]  = i_new[i] + lensi;
1571a2744918SBarry Smith       c->ilen[i]  = lensi;
157202834360SBarry Smith     }
1573606d414cSSatish Balay     ierr = PetscFree(lens);CHKERRQ(ierr);
15743a40ed3dSBarry Smith   } else {
157502834360SBarry Smith     ierr  = ISGetIndices(iscol,&icol);CHKERRQ(ierr);
15760452661fSBarry Smith     smap  = (int *) PetscMalloc((1+oldcols)*sizeof(int));CHKPTRQ(smap);
157702834360SBarry Smith     ssmap = smap + shift;
157899141d43SSatish Balay     lens  = (int *) PetscMalloc((1+nrows)*sizeof(int));CHKPTRQ(lens);
1579549d3d68SSatish Balay     ierr  = PetscMemzero(smap,oldcols*sizeof(int));CHKERRQ(ierr);
158017ab2063SBarry Smith     for ( i=0; i<ncols; i++ ) smap[icol[i]] = i+1;
158102834360SBarry Smith     /* determine lens of each row */
158202834360SBarry Smith     for (i=0; i<nrows; i++) {
1583d8ced48eSBarry Smith       kstart  = ai[irow[i]]+shift;
158402834360SBarry Smith       kend    = kstart + a->ilen[irow[i]];
158502834360SBarry Smith       lens[i] = 0;
158602834360SBarry Smith       for ( k=kstart; k<kend; k++ ) {
1587d8ced48eSBarry Smith         if (ssmap[aj[k]]) {
158802834360SBarry Smith           lens[i]++;
158902834360SBarry Smith         }
159002834360SBarry Smith       }
159102834360SBarry Smith     }
159217ab2063SBarry Smith     /* Create and fill new matrix */
1593a2744918SBarry Smith     if (scall == MAT_REUSE_MATRIX) {
15940f5bd95cSBarry Smith       PetscTruth equal;
15950f5bd95cSBarry Smith 
159699141d43SSatish Balay       c = (Mat_SeqAIJ *)((*B)->data);
1597a8c6a408SBarry Smith       if (c->m  != nrows || c->n != ncols) SETERRQ(PETSC_ERR_ARG_SIZ,0,"Cannot reuse matrix. wrong size");
15980f5bd95cSBarry Smith       ierr = PetscMemcmp(c->ilen,lens, c->m*sizeof(int),&equal);CHKERRQ(ierr);
15990f5bd95cSBarry Smith       if (!equal) {
1600a8c6a408SBarry Smith         SETERRQ(PETSC_ERR_ARG_SIZ,0,"Cannot reuse matrix. wrong no of nonzeros");
160199141d43SSatish Balay       }
1602549d3d68SSatish Balay       ierr = PetscMemzero(c->ilen,c->m*sizeof(int));CHKERRQ(ierr);
160308480c60SBarry Smith       C = *B;
16043a40ed3dSBarry Smith     } else {
160502834360SBarry Smith       ierr = MatCreateSeqAIJ(A->comm,nrows,ncols,0,lens,&C);CHKERRQ(ierr);
160608480c60SBarry Smith     }
160799141d43SSatish Balay     c = (Mat_SeqAIJ *)(C->data);
160817ab2063SBarry Smith     for (i=0; i<nrows; i++) {
160999141d43SSatish Balay       row    = irow[i];
161099141d43SSatish Balay       kstart = ai[row]+shift;
161199141d43SSatish Balay       kend   = kstart + a->ilen[row];
161299141d43SSatish Balay       mat_i  = c->i[i]+shift;
161399141d43SSatish Balay       mat_j  = c->j + mat_i;
161499141d43SSatish Balay       mat_a  = c->a + mat_i;
161599141d43SSatish Balay       mat_ilen = c->ilen + i;
161617ab2063SBarry Smith       for ( k=kstart; k<kend; k++ ) {
161799141d43SSatish Balay         if ((tcol=ssmap[a->j[k]])) {
161899141d43SSatish Balay           *mat_j++ = tcol - (!shift);
161999141d43SSatish Balay           *mat_a++ = a->a[k];
162099141d43SSatish Balay           (*mat_ilen)++;
162199141d43SSatish Balay 
162217ab2063SBarry Smith         }
162317ab2063SBarry Smith       }
162417ab2063SBarry Smith     }
162502834360SBarry Smith     /* Free work space */
162602834360SBarry Smith     ierr = ISRestoreIndices(iscol,&icol);CHKERRQ(ierr);
1627606d414cSSatish Balay     ierr = PetscFree(smap);CHKERRQ(ierr);
1628606d414cSSatish Balay     ierr = PetscFree(lens);CHKERRQ(ierr);
162902834360SBarry Smith   }
16306d4a8577SBarry Smith   ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
16316d4a8577SBarry Smith   ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
163217ab2063SBarry Smith 
163317ab2063SBarry Smith   ierr = ISRestoreIndices(isrow,&irow);CHKERRQ(ierr);
1634416022c9SBarry Smith   *B = C;
16353a40ed3dSBarry Smith   PetscFunctionReturn(0);
163617ab2063SBarry Smith }
163717ab2063SBarry Smith 
1638a871dcd8SBarry Smith /*
1639a871dcd8SBarry Smith */
16405615d1e5SSatish Balay #undef __FUNC__
16415615d1e5SSatish Balay #define __FUNC__ "MatILUFactor_SeqAIJ"
16425ef9f2a5SBarry Smith int MatILUFactor_SeqAIJ(Mat inA,IS row,IS col,MatILUInfo *info)
1643a871dcd8SBarry Smith {
164463b91edcSBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ *) inA->data;
164508480c60SBarry Smith   int        ierr;
164663b91edcSBarry Smith   Mat        outA;
1647b8a78c4aSBarry Smith   PetscTruth row_identity, col_identity;
164863b91edcSBarry Smith 
16493a40ed3dSBarry Smith   PetscFunctionBegin;
1650b8a78c4aSBarry Smith   if (info && info->levels != 0) SETERRQ(PETSC_ERR_SUP,0,"Only levels=0 supported for in-place ilu");
1651b8a78c4aSBarry Smith   ierr = ISIdentity(row,&row_identity);CHKERRQ(ierr);
1652b8a78c4aSBarry Smith   ierr = ISIdentity(col,&col_identity);CHKERRQ(ierr);
1653b8a78c4aSBarry Smith   if (!row_identity || !col_identity) {
1654b8a78c4aSBarry Smith     SETERRQ(1,1,"Row and column permutations must be identity for in-place ILU");
1655b8a78c4aSBarry Smith   }
1656a871dcd8SBarry Smith 
165763b91edcSBarry Smith   outA          = inA;
165863b91edcSBarry Smith   inA->factor   = FACTOR_LU;
165963b91edcSBarry Smith   a->row        = row;
166063b91edcSBarry Smith   a->col        = col;
166163b91edcSBarry Smith 
1662f0ec6fceSSatish Balay   /* Create the invert permutation so that it can be used in MatLUFactorNumeric() */
1663f0ec6fceSSatish Balay   ierr = ISInvertPermutation(col,&(a->icol));CHKERRQ(ierr);
16641e4dd532SSatish Balay   PLogObjectParent(inA,a->icol);
1665f0ec6fceSSatish Balay 
166694a9d846SBarry Smith   if (!a->solve_work) { /* this matrix may have been factored before */
16670452661fSBarry Smith     a->solve_work = (Scalar *) PetscMalloc( (a->m+1)*sizeof(Scalar));CHKPTRQ(a->solve_work);
166894a9d846SBarry Smith   }
166963b91edcSBarry Smith 
167008480c60SBarry Smith   if (!a->diag) {
167108480c60SBarry Smith     ierr = MatMarkDiag_SeqAIJ(inA);CHKERRQ(ierr);
167263b91edcSBarry Smith   }
167363b91edcSBarry Smith   ierr = MatLUFactorNumeric_SeqAIJ(inA,&outA);CHKERRQ(ierr);
16743a40ed3dSBarry Smith   PetscFunctionReturn(0);
1675a871dcd8SBarry Smith }
1676a871dcd8SBarry Smith 
167774cdf0dfSBarry Smith #include "pinclude/blaslapack.h"
16785615d1e5SSatish Balay #undef __FUNC__
16795615d1e5SSatish Balay #define __FUNC__ "MatScale_SeqAIJ"
16808f6be9afSLois Curfman McInnes int MatScale_SeqAIJ(Scalar *alpha,Mat inA)
1681f0b747eeSBarry Smith {
1682f0b747eeSBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ *) inA->data;
1683f0b747eeSBarry Smith   int        one = 1;
16843a40ed3dSBarry Smith 
16853a40ed3dSBarry Smith   PetscFunctionBegin;
1686f0b747eeSBarry Smith   BLscal_( &a->nz, alpha, a->a, &one );
1687f0b747eeSBarry Smith   PLogFlops(a->nz);
16883a40ed3dSBarry Smith   PetscFunctionReturn(0);
1689f0b747eeSBarry Smith }
1690f0b747eeSBarry Smith 
16915615d1e5SSatish Balay #undef __FUNC__
16925615d1e5SSatish Balay #define __FUNC__ "MatGetSubMatrices_SeqAIJ"
16937b2a1423SBarry Smith int MatGetSubMatrices_SeqAIJ(Mat A,int n, IS *irow,IS *icol,MatReuse scall,Mat **B)
1694cddf8d76SBarry Smith {
1695cddf8d76SBarry Smith   int ierr,i;
1696cddf8d76SBarry Smith 
16973a40ed3dSBarry Smith   PetscFunctionBegin;
1698cddf8d76SBarry Smith   if (scall == MAT_INITIAL_MATRIX) {
16990452661fSBarry Smith     *B = (Mat *) PetscMalloc( (n+1)*sizeof(Mat) );CHKPTRQ(*B);
1700cddf8d76SBarry Smith   }
1701cddf8d76SBarry Smith 
1702cddf8d76SBarry Smith   for ( i=0; i<n; i++ ) {
17036a6a5d1dSBarry Smith     ierr = MatGetSubMatrix_SeqAIJ(A,irow[i],icol[i],PETSC_DECIDE,scall,&(*B)[i]);CHKERRQ(ierr);
1704cddf8d76SBarry Smith   }
17053a40ed3dSBarry Smith   PetscFunctionReturn(0);
1706cddf8d76SBarry Smith }
1707cddf8d76SBarry Smith 
17085615d1e5SSatish Balay #undef __FUNC__
17095615d1e5SSatish Balay #define __FUNC__ "MatGetBlockSize_SeqAIJ"
17108f6be9afSLois Curfman McInnes int MatGetBlockSize_SeqAIJ(Mat A, int *bs)
17115a838052SSatish Balay {
1712f830108cSBarry Smith   PetscFunctionBegin;
17135a838052SSatish Balay   *bs = 1;
17143a40ed3dSBarry Smith   PetscFunctionReturn(0);
17155a838052SSatish Balay }
17165a838052SSatish Balay 
17175615d1e5SSatish Balay #undef __FUNC__
17185615d1e5SSatish Balay #define __FUNC__ "MatIncreaseOverlap_SeqAIJ"
17198f6be9afSLois Curfman McInnes int MatIncreaseOverlap_SeqAIJ(Mat A, int is_max, IS *is, int ov)
17204dcbc457SBarry Smith {
1721e4d965acSSatish Balay   Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data;
172206763907SSatish Balay   int        shift, row, i,j,k,l,m,n, *idx,ierr, *nidx, isz, val;
17238a047759SSatish Balay   int        start, end, *ai, *aj;
1724*6831982aSBarry Smith   BTPetsc    table;
1725bbd702dbSSatish Balay 
17263a40ed3dSBarry Smith   PetscFunctionBegin;
17278a047759SSatish Balay   shift = a->indexshift;
1728e4d965acSSatish Balay   m     = a->m;
1729e4d965acSSatish Balay   ai    = a->i;
17308a047759SSatish Balay   aj    = a->j+shift;
17318a047759SSatish Balay 
1732a8c6a408SBarry Smith   if (ov < 0)  SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"illegal overlap value used");
173306763907SSatish Balay 
173406763907SSatish Balay   nidx  = (int *) PetscMalloc((m+1)*sizeof(int));CHKPTRQ(nidx);
1735*6831982aSBarry Smith   ierr  = PetscBTCreate(m,table);CHKERRQ(ierr);
173606763907SSatish Balay 
1737e4d965acSSatish Balay   for ( i=0; i<is_max; i++ ) {
1738b97fc60eSLois Curfman McInnes     /* Initialize the two local arrays */
1739e4d965acSSatish Balay     isz  = 0;
1740*6831982aSBarry Smith     ierr = PetscBTMemzero(m,table);CHKERRQ(ierr);
1741e4d965acSSatish Balay 
1742e4d965acSSatish Balay     /* Extract the indices, assume there can be duplicate entries */
17434dcbc457SBarry Smith     ierr = ISGetIndices(is[i],&idx);CHKERRQ(ierr);
174477c4ece6SBarry Smith     ierr = ISGetSize(is[i],&n);CHKERRQ(ierr);
1745e4d965acSSatish Balay 
1746dd097bc3SLois Curfman McInnes     /* Enter these into the temp arrays. I.e., mark table[row], enter row into new index */
1747e4d965acSSatish Balay     for ( j=0; j<n ; ++j){
1748*6831982aSBarry Smith       if(!PetscBTLoopupSet(table, idx[j])) { nidx[isz++] = idx[j];}
17494dcbc457SBarry Smith     }
175006763907SSatish Balay     ierr = ISRestoreIndices(is[i],&idx);CHKERRQ(ierr);
175106763907SSatish Balay     ierr = ISDestroy(is[i]);CHKERRQ(ierr);
1752e4d965acSSatish Balay 
175304a348a9SBarry Smith     k = 0;
175404a348a9SBarry Smith     for ( j=0; j<ov; j++){ /* for each overlap */
175504a348a9SBarry Smith       n = isz;
175606763907SSatish Balay       for ( ; k<n ; k++){ /* do only those rows in nidx[k], which are not done yet */
1757e4d965acSSatish Balay         row   = nidx[k];
1758e4d965acSSatish Balay         start = ai[row];
1759e4d965acSSatish Balay         end   = ai[row+1];
176004a348a9SBarry Smith         for ( l = start; l<end ; l++){
17618a047759SSatish Balay           val = aj[l] + shift;
1762*6831982aSBarry Smith           if (!PetscBTLoopupSet(table,val)) {nidx[isz++] = val;}
1763e4d965acSSatish Balay         }
1764e4d965acSSatish Balay       }
1765e4d965acSSatish Balay     }
1766029af93fSBarry Smith     ierr = ISCreateGeneral(PETSC_COMM_SELF, isz, nidx, (is+i));CHKERRQ(ierr);
1767e4d965acSSatish Balay   }
1768*6831982aSBarry Smith   ierr = PetscBTDestroy(table);CHKERRQ(ierr);
1769606d414cSSatish Balay   ierr = PetscFree(nidx);CHKERRQ(ierr);
17703a40ed3dSBarry Smith   PetscFunctionReturn(0);
17714dcbc457SBarry Smith }
177217ab2063SBarry Smith 
17730513a670SBarry Smith /* -------------------------------------------------------------- */
17740513a670SBarry Smith #undef __FUNC__
17750513a670SBarry Smith #define __FUNC__ "MatPermute_SeqAIJ"
17760513a670SBarry Smith int MatPermute_SeqAIJ(Mat A, IS rowp, IS colp, Mat *B)
17770513a670SBarry Smith {
17780513a670SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data;
17790513a670SBarry Smith   Scalar     *vwork;
17800513a670SBarry Smith   int        i, ierr, nz, m = a->m, n = a->n, *cwork;
17810513a670SBarry Smith   int        *row,*col,*cnew,j,*lens;
178256cd22aeSBarry Smith   IS         icolp,irowp;
17830513a670SBarry Smith 
17843a40ed3dSBarry Smith   PetscFunctionBegin;
178556cd22aeSBarry Smith   ierr = ISInvertPermutation(rowp,&irowp);CHKERRQ(ierr);
178656cd22aeSBarry Smith   ierr = ISGetIndices(irowp,&row);CHKERRQ(ierr);
178756cd22aeSBarry Smith   ierr = ISInvertPermutation(colp,&icolp);CHKERRQ(ierr);
178856cd22aeSBarry Smith   ierr = ISGetIndices(icolp,&col);CHKERRQ(ierr);
17890513a670SBarry Smith 
17900513a670SBarry Smith   /* determine lengths of permuted rows */
17910513a670SBarry Smith   lens = (int *) PetscMalloc( (m+1)*sizeof(int) );CHKPTRQ(lens);
17920513a670SBarry Smith   for (i=0; i<m; i++ ) {
17930513a670SBarry Smith     lens[row[i]] = a->i[i+1] - a->i[i];
17940513a670SBarry Smith   }
17950513a670SBarry Smith   ierr = MatCreateSeqAIJ(A->comm,m,n,0,lens,B);CHKERRQ(ierr);
1796606d414cSSatish Balay   ierr = PetscFree(lens);CHKERRQ(ierr);
17970513a670SBarry Smith 
17980513a670SBarry Smith   cnew = (int *) PetscMalloc( n*sizeof(int) );CHKPTRQ(cnew);
17990513a670SBarry Smith   for (i=0; i<m; i++) {
18000513a670SBarry Smith     ierr = MatGetRow(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr);
18010513a670SBarry Smith     for (j=0; j<nz; j++ ) { cnew[j] = col[cwork[j]];}
18020513a670SBarry Smith     ierr = MatSetValues(*B,1,&row[i],nz,cnew,vwork,INSERT_VALUES);CHKERRQ(ierr);
18030513a670SBarry Smith     ierr = MatRestoreRow(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr);
18040513a670SBarry Smith   }
1805606d414cSSatish Balay   ierr = PetscFree(cnew);CHKERRQ(ierr);
18060513a670SBarry Smith   ierr = MatAssemblyBegin(*B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
18070513a670SBarry Smith   ierr = MatAssemblyEnd(*B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
180856cd22aeSBarry Smith   ierr = ISRestoreIndices(irowp,&row);CHKERRQ(ierr);
180956cd22aeSBarry Smith   ierr = ISRestoreIndices(icolp,&col);CHKERRQ(ierr);
181056cd22aeSBarry Smith   ierr = ISDestroy(irowp);CHKERRQ(ierr);
181156cd22aeSBarry Smith   ierr = ISDestroy(icolp);CHKERRQ(ierr);
18123a40ed3dSBarry Smith   PetscFunctionReturn(0);
18130513a670SBarry Smith }
18140513a670SBarry Smith 
18155615d1e5SSatish Balay #undef __FUNC__
18165615d1e5SSatish Balay #define __FUNC__ "MatPrintHelp_SeqAIJ"
1817682d7d0cSBarry Smith int MatPrintHelp_SeqAIJ(Mat A)
1818682d7d0cSBarry Smith {
1819682d7d0cSBarry Smith   static int called = 0;
1820682d7d0cSBarry Smith   MPI_Comm   comm = A->comm;
1821d132466eSBarry Smith   int        ierr;
1822682d7d0cSBarry Smith 
18233a40ed3dSBarry Smith   PetscFunctionBegin;
18243a40ed3dSBarry Smith   if (called) {PetscFunctionReturn(0);} else called = 1;
1825d132466eSBarry Smith   ierr = (*PetscHelpPrintf)(comm," Options for MATSEQAIJ and MATMPIAIJ matrix formats (the defaults):\n");CHKERRQ(ierr);
1826d132466eSBarry Smith   ierr = (*PetscHelpPrintf)(comm,"  -mat_lu_pivotthreshold <threshold>: Set pivoting threshold\n");CHKERRQ(ierr);
1827d132466eSBarry Smith   ierr = (*PetscHelpPrintf)(comm,"  -mat_aij_oneindex: internal indices begin at 1 instead of the default 0.\n");CHKERRQ(ierr);
1828d132466eSBarry Smith   ierr = (*PetscHelpPrintf)(comm,"  -mat_aij_no_inode: Do not use inodes\n");CHKERRQ(ierr);
1829d132466eSBarry Smith   ierr = (*PetscHelpPrintf)(comm,"  -mat_aij_inode_limit <limit>: Set inode limit (max limit=5)\n");CHKERRQ(ierr);
1830aa482453SBarry Smith #if defined(PETSC_HAVE_ESSL)
1831d132466eSBarry Smith   ierr = (*PetscHelpPrintf)(comm,"  -mat_aij_essl: Use IBM sparse LU factorization and solve.\n");CHKERRQ(ierr);
1832682d7d0cSBarry Smith #endif
18333a40ed3dSBarry Smith   PetscFunctionReturn(0);
1834682d7d0cSBarry Smith }
18358f6be9afSLois Curfman McInnes extern int MatEqual_SeqAIJ(Mat A,Mat B, PetscTruth* flg);
1836a93ec695SBarry Smith extern int MatFDColoringCreate_SeqAIJ(Mat,ISColoring,MatFDColoring);
1837a93ec695SBarry Smith extern int MatColoringPatch_SeqAIJ(Mat,int,int *,ISColoring *);
1838a93ec695SBarry Smith 
1839cb5b572fSBarry Smith #undef __FUNC__
1840cb5b572fSBarry Smith #define __FUNC__ "MatCopy_SeqAIJ"
1841cb5b572fSBarry Smith int MatCopy_SeqAIJ(Mat A,Mat B,MatStructure str)
1842cb5b572fSBarry Smith {
1843be6bf707SBarry Smith   int    ierr;
1844cb5b572fSBarry Smith 
1845cb5b572fSBarry Smith   PetscFunctionBegin;
1846be6bf707SBarry Smith   if (str == SAME_NONZERO_PATTERN && B->type == MATSEQAIJ) {
1847be6bf707SBarry Smith     Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data;
1848be6bf707SBarry Smith     Mat_SeqAIJ *b = (Mat_SeqAIJ *) B->data;
1849be6bf707SBarry Smith 
1850be6bf707SBarry Smith     if (a->i[a->m]+a->indexshift != b->i[b->m]+a->indexshift) {
1851be6bf707SBarry Smith       SETERRQ(1,1,"Number of nonzeros in two matrices are different");
1852cb5b572fSBarry Smith     }
1853549d3d68SSatish Balay     ierr = PetscMemcpy(b->a,a->a,(a->i[a->m]+a->indexshift)*sizeof(Scalar));CHKERRQ(ierr);
1854cb5b572fSBarry Smith   } else {
1855cb5b572fSBarry Smith     ierr = MatCopy_Basic(A,B,str);CHKERRQ(ierr);
1856cb5b572fSBarry Smith   }
1857cb5b572fSBarry Smith   PetscFunctionReturn(0);
1858cb5b572fSBarry Smith }
1859cb5b572fSBarry Smith 
1860682d7d0cSBarry Smith /* -------------------------------------------------------------------*/
18610a6ffc59SBarry Smith static struct _MatOps MatOps_Values = {MatSetValues_SeqAIJ,
1862cb5b572fSBarry Smith        MatGetRow_SeqAIJ,
1863cb5b572fSBarry Smith        MatRestoreRow_SeqAIJ,
1864cb5b572fSBarry Smith        MatMult_SeqAIJ,
1865cb5b572fSBarry Smith        MatMultAdd_SeqAIJ,
1866cb5b572fSBarry Smith        MatMultTrans_SeqAIJ,
1867cb5b572fSBarry Smith        MatMultTransAdd_SeqAIJ,
1868cb5b572fSBarry Smith        MatSolve_SeqAIJ,
1869cb5b572fSBarry Smith        MatSolveAdd_SeqAIJ,
1870cb5b572fSBarry Smith        MatSolveTrans_SeqAIJ,
1871cb5b572fSBarry Smith        MatSolveTransAdd_SeqAIJ,
1872cb5b572fSBarry Smith        MatLUFactor_SeqAIJ,
1873cb5b572fSBarry Smith        0,
187417ab2063SBarry Smith        MatRelax_SeqAIJ,
187517ab2063SBarry Smith        MatTranspose_SeqAIJ,
1876cb5b572fSBarry Smith        MatGetInfo_SeqAIJ,
1877cb5b572fSBarry Smith        MatEqual_SeqAIJ,
1878cb5b572fSBarry Smith        MatGetDiagonal_SeqAIJ,
1879cb5b572fSBarry Smith        MatDiagonalScale_SeqAIJ,
1880cb5b572fSBarry Smith        MatNorm_SeqAIJ,
1881cb5b572fSBarry Smith        0,
1882cb5b572fSBarry Smith        MatAssemblyEnd_SeqAIJ,
188317ab2063SBarry Smith        MatCompress_SeqAIJ,
1884cb5b572fSBarry Smith        MatSetOption_SeqAIJ,
1885cb5b572fSBarry Smith        MatZeroEntries_SeqAIJ,
1886cb5b572fSBarry Smith        MatZeroRows_SeqAIJ,
1887cb5b572fSBarry Smith        MatLUFactorSymbolic_SeqAIJ,
1888cb5b572fSBarry Smith        MatLUFactorNumeric_SeqAIJ,
1889cb5b572fSBarry Smith        0,
1890cb5b572fSBarry Smith        0,
1891cb5b572fSBarry Smith        MatGetSize_SeqAIJ,
1892cb5b572fSBarry Smith        MatGetSize_SeqAIJ,
1893cb5b572fSBarry Smith        MatGetOwnershipRange_SeqAIJ,
1894cb5b572fSBarry Smith        MatILUFactorSymbolic_SeqAIJ,
1895cb5b572fSBarry Smith        0,
1896cb5b572fSBarry Smith        0,
1897cb5b572fSBarry Smith        0,
1898be6bf707SBarry Smith        MatDuplicate_SeqAIJ,
1899cb5b572fSBarry Smith        0,
1900cb5b572fSBarry Smith        0,
1901cb5b572fSBarry Smith        MatILUFactor_SeqAIJ,
1902cb5b572fSBarry Smith        0,
1903cb5b572fSBarry Smith        0,
1904cb5b572fSBarry Smith        MatGetSubMatrices_SeqAIJ,
1905cb5b572fSBarry Smith        MatIncreaseOverlap_SeqAIJ,
1906cb5b572fSBarry Smith        MatGetValues_SeqAIJ,
1907cb5b572fSBarry Smith        MatCopy_SeqAIJ,
1908f0b747eeSBarry Smith        MatPrintHelp_SeqAIJ,
1909cb5b572fSBarry Smith        MatScale_SeqAIJ,
1910cb5b572fSBarry Smith        0,
1911cb5b572fSBarry Smith        0,
19126945ee14SBarry Smith        MatILUDTFactor_SeqAIJ,
19136945ee14SBarry Smith        MatGetBlockSize_SeqAIJ,
19143b2fbd54SBarry Smith        MatGetRowIJ_SeqAIJ,
19153b2fbd54SBarry Smith        MatRestoreRowIJ_SeqAIJ,
19163b2fbd54SBarry Smith        MatGetColumnIJ_SeqAIJ,
1917a93ec695SBarry Smith        MatRestoreColumnIJ_SeqAIJ,
1918a93ec695SBarry Smith        MatFDColoringCreate_SeqAIJ,
19190513a670SBarry Smith        MatColoringPatch_SeqAIJ,
19200513a670SBarry Smith        0,
1921cda55fadSBarry Smith        MatPermute_SeqAIJ,
1922cda55fadSBarry Smith        0,
1923cda55fadSBarry Smith        0,
1924cda55fadSBarry Smith        0,
1925cda55fadSBarry Smith        0,
1926cda55fadSBarry Smith        MatGetMaps_Petsc};
192717ab2063SBarry Smith 
192817ab2063SBarry Smith extern int MatUseSuperLU_SeqAIJ(Mat);
192917ab2063SBarry Smith extern int MatUseEssl_SeqAIJ(Mat);
193017ab2063SBarry Smith extern int MatUseDXML_SeqAIJ(Mat);
193117ab2063SBarry Smith 
1932fb2e594dSBarry Smith EXTERN_C_BEGIN
19335615d1e5SSatish Balay #undef __FUNC__
1934bef8e0ddSBarry Smith #define __FUNC__ "MatSeqAIJSetColumnIndices_SeqAIJ"
193515091d37SBarry Smith 
1936bef8e0ddSBarry Smith int MatSeqAIJSetColumnIndices_SeqAIJ(Mat mat,int *indices)
1937bef8e0ddSBarry Smith {
1938bef8e0ddSBarry Smith   Mat_SeqAIJ *aij = (Mat_SeqAIJ *)mat->data;
1939bef8e0ddSBarry Smith   int        i,nz,n;
1940bef8e0ddSBarry Smith 
1941bef8e0ddSBarry Smith   PetscFunctionBegin;
1942bef8e0ddSBarry Smith   if (aij->indexshift) SETERRQ(1,1,"No support with 1 based indexing");
1943bef8e0ddSBarry Smith 
1944bef8e0ddSBarry Smith   nz = aij->maxnz;
1945bef8e0ddSBarry Smith   n  = aij->n;
1946bef8e0ddSBarry Smith   for (i=0; i<nz; i++) {
1947bef8e0ddSBarry Smith     aij->j[i] = indices[i];
1948bef8e0ddSBarry Smith   }
1949bef8e0ddSBarry Smith   aij->nz = nz;
1950bef8e0ddSBarry Smith   for ( i=0; i<n; i++ ) {
1951bef8e0ddSBarry Smith     aij->ilen[i] = aij->imax[i];
1952bef8e0ddSBarry Smith   }
1953bef8e0ddSBarry Smith 
1954bef8e0ddSBarry Smith   PetscFunctionReturn(0);
1955bef8e0ddSBarry Smith }
1956fb2e594dSBarry Smith EXTERN_C_END
1957bef8e0ddSBarry Smith 
1958bef8e0ddSBarry Smith #undef __FUNC__
1959bef8e0ddSBarry Smith #define __FUNC__ "MatSeqAIJSetColumnIndices"
1960bef8e0ddSBarry Smith /*@
1961bef8e0ddSBarry Smith     MatSeqAIJSetColumnIndices - Set the column indices for all the rows
1962bef8e0ddSBarry Smith        in the matrix.
1963bef8e0ddSBarry Smith 
1964bef8e0ddSBarry Smith   Input Parameters:
1965bef8e0ddSBarry Smith +  mat - the SeqAIJ matrix
1966bef8e0ddSBarry Smith -  indices - the column indices
1967bef8e0ddSBarry Smith 
196815091d37SBarry Smith   Level: advanced
196915091d37SBarry Smith 
1970bef8e0ddSBarry Smith   Notes:
1971bef8e0ddSBarry Smith     This can be called if you have precomputed the nonzero structure of the
1972bef8e0ddSBarry Smith   matrix and want to provide it to the matrix object to improve the performance
1973bef8e0ddSBarry Smith   of the MatSetValues() operation.
1974bef8e0ddSBarry Smith 
1975bef8e0ddSBarry Smith     You MUST have set the correct numbers of nonzeros per row in the call to
1976bef8e0ddSBarry Smith   MatCreateSeqAIJ().
1977bef8e0ddSBarry Smith 
1978bef8e0ddSBarry Smith     MUST be called before any calls to MatSetValues();
1979bef8e0ddSBarry Smith 
1980bef8e0ddSBarry Smith @*/
1981bef8e0ddSBarry Smith int MatSeqAIJSetColumnIndices(Mat mat,int *indices)
1982bef8e0ddSBarry Smith {
1983bef8e0ddSBarry Smith   int ierr,(*f)(Mat,int *);
1984bef8e0ddSBarry Smith 
1985bef8e0ddSBarry Smith   PetscFunctionBegin;
1986bef8e0ddSBarry Smith   PetscValidHeaderSpecific(mat,MAT_COOKIE);
1987549d3d68SSatish Balay   ierr = PetscObjectQueryFunction((PetscObject)mat,"MatSeqAIJSetColumnIndices_C",(void **)&f);CHKERRQ(ierr);
1988bef8e0ddSBarry Smith   if (f) {
1989bef8e0ddSBarry Smith     ierr = (*f)(mat,indices);CHKERRQ(ierr);
1990bef8e0ddSBarry Smith   } else {
1991bef8e0ddSBarry Smith     SETERRQ(1,1,"Wrong type of matrix to set column indices");
1992bef8e0ddSBarry Smith   }
1993bef8e0ddSBarry Smith   PetscFunctionReturn(0);
1994bef8e0ddSBarry Smith }
1995bef8e0ddSBarry Smith 
1996be6bf707SBarry Smith /* ----------------------------------------------------------------------------------------*/
1997be6bf707SBarry Smith 
1998fb2e594dSBarry Smith EXTERN_C_BEGIN
1999be6bf707SBarry Smith #undef __FUNC__
2000be6bf707SBarry Smith #define __FUNC__ "MatStoreValues_SeqAIJ"
2001be6bf707SBarry Smith int MatStoreValues_SeqAIJ(Mat mat)
2002be6bf707SBarry Smith {
2003be6bf707SBarry Smith   Mat_SeqAIJ *aij = (Mat_SeqAIJ *)mat->data;
2004549d3d68SSatish Balay   int        nz = aij->i[aij->m]+aij->indexshift,ierr;
2005be6bf707SBarry Smith 
2006be6bf707SBarry Smith   PetscFunctionBegin;
2007be6bf707SBarry Smith   if (aij->nonew != 1) {
2008be6bf707SBarry Smith     SETERRQ(1,1,"Must call MatSetOption(A,MAT_NO_NEW_NONZERO_LOCATIONS);first");
2009be6bf707SBarry Smith   }
2010be6bf707SBarry Smith 
2011be6bf707SBarry Smith   /* allocate space for values if not already there */
2012be6bf707SBarry Smith   if (!aij->saved_values) {
2013be6bf707SBarry Smith     aij->saved_values = (Scalar *) PetscMalloc(nz*sizeof(Scalar));CHKPTRQ(aij->saved_values);
2014be6bf707SBarry Smith   }
2015be6bf707SBarry Smith 
2016be6bf707SBarry Smith   /* copy values over */
2017549d3d68SSatish Balay   ierr = PetscMemcpy(aij->saved_values,aij->a,nz*sizeof(Scalar));CHKERRQ(ierr);
2018be6bf707SBarry Smith   PetscFunctionReturn(0);
2019be6bf707SBarry Smith }
2020fb2e594dSBarry Smith EXTERN_C_END
2021be6bf707SBarry Smith 
2022be6bf707SBarry Smith #undef __FUNC__
2023be6bf707SBarry Smith #define __FUNC__ "MatStoreValues"
2024be6bf707SBarry Smith /*@
2025be6bf707SBarry Smith     MatStoreValues - Stashes a copy of the matrix values; this allows, for
2026be6bf707SBarry Smith        example, reuse of the linear part of a Jacobian, while recomputing the
2027be6bf707SBarry Smith        nonlinear portion.
2028be6bf707SBarry Smith 
2029be6bf707SBarry Smith    Collect on Mat
2030be6bf707SBarry Smith 
2031be6bf707SBarry Smith   Input Parameters:
2032be6bf707SBarry Smith .  mat - the matrix (currently on AIJ matrices support this option)
2033be6bf707SBarry Smith 
203415091d37SBarry Smith   Level: advanced
203515091d37SBarry Smith 
2036be6bf707SBarry Smith   Common Usage, with SNESSolve():
2037be6bf707SBarry Smith $    Create Jacobian matrix
2038be6bf707SBarry Smith $    Set linear terms into matrix
2039be6bf707SBarry Smith $    Apply boundary conditions to matrix, at this time matrix must have
2040be6bf707SBarry Smith $      final nonzero structure (i.e. setting the nonlinear terms and applying
2041be6bf707SBarry Smith $      boundary conditions again will not change the nonzero structure
2042be6bf707SBarry Smith $    ierr = MatSetOption(mat,MAT_NO_NEW_NONZERO_LOCATIONS);
2043be6bf707SBarry Smith $    ierr = MatStoreValues(mat);
2044be6bf707SBarry Smith $    Call SNESSetJacobian() with matrix
2045be6bf707SBarry Smith $    In your Jacobian routine
2046be6bf707SBarry Smith $      ierr = MatRetrieveValues(mat);
2047be6bf707SBarry Smith $      Set nonlinear terms in matrix
2048be6bf707SBarry Smith 
2049be6bf707SBarry Smith   Common Usage without SNESSolve(), i.e. when you handle nonlinear solve yourself:
2050be6bf707SBarry Smith $    // build linear portion of Jacobian
2051be6bf707SBarry Smith $    ierr = MatSetOption(mat,MAT_NO_NEW_NONZERO_LOCATIONS);
2052be6bf707SBarry Smith $    ierr = MatStoreValues(mat);
2053be6bf707SBarry Smith $    loop over nonlinear iterations
2054be6bf707SBarry Smith $       ierr = MatRetrieveValues(mat);
2055be6bf707SBarry Smith $       // call MatSetValues(mat,...) to set nonliner portion of Jacobian
2056be6bf707SBarry Smith $       // call MatAssemblyBegin/End() on matrix
2057be6bf707SBarry Smith $       Solve linear system with Jacobian
2058be6bf707SBarry Smith $    endloop
2059be6bf707SBarry Smith 
2060be6bf707SBarry Smith   Notes:
2061be6bf707SBarry Smith     Matrix must already be assemblied before calling this routine
2062be6bf707SBarry Smith     Must set the matrix option MatSetOption(mat,MAT_NO_NEW_NONZERO_LOCATIONS); before
2063be6bf707SBarry Smith     calling this routine.
2064be6bf707SBarry Smith 
2065be6bf707SBarry Smith .seealso: MatRetrieveValues()
2066be6bf707SBarry Smith 
2067be6bf707SBarry Smith @*/
2068be6bf707SBarry Smith int MatStoreValues(Mat mat)
2069be6bf707SBarry Smith {
2070be6bf707SBarry Smith   int ierr,(*f)(Mat);
2071be6bf707SBarry Smith 
2072be6bf707SBarry Smith   PetscFunctionBegin;
2073be6bf707SBarry Smith   PetscValidHeaderSpecific(mat,MAT_COOKIE);
2074be6bf707SBarry Smith   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,0,"Not for unassembled matrix");
2075be6bf707SBarry Smith   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,0,"Not for factored matrix");
2076be6bf707SBarry Smith 
2077c5d6004cSBarry Smith   ierr = PetscObjectQueryFunction((PetscObject)mat,"MatStoreValues_C",(void **)&f);CHKERRQ(ierr);
2078be6bf707SBarry Smith   if (f) {
2079be6bf707SBarry Smith     ierr = (*f)(mat);CHKERRQ(ierr);
2080be6bf707SBarry Smith   } else {
2081be6bf707SBarry Smith     SETERRQ(1,1,"Wrong type of matrix to store values");
2082be6bf707SBarry Smith   }
2083be6bf707SBarry Smith   PetscFunctionReturn(0);
2084be6bf707SBarry Smith }
2085be6bf707SBarry Smith 
2086fb2e594dSBarry Smith EXTERN_C_BEGIN
2087be6bf707SBarry Smith #undef __FUNC__
2088be6bf707SBarry Smith #define __FUNC__ "MatRetrieveValues_SeqAIJ"
2089be6bf707SBarry Smith int MatRetrieveValues_SeqAIJ(Mat mat)
2090be6bf707SBarry Smith {
2091be6bf707SBarry Smith   Mat_SeqAIJ *aij = (Mat_SeqAIJ *)mat->data;
2092549d3d68SSatish Balay   int        nz = aij->i[aij->m]+aij->indexshift,ierr;
2093be6bf707SBarry Smith 
2094be6bf707SBarry Smith   PetscFunctionBegin;
2095be6bf707SBarry Smith   if (aij->nonew != 1) {
2096be6bf707SBarry Smith     SETERRQ(1,1,"Must call MatSetOption(A,MAT_NO_NEW_NONZERO_LOCATIONS);first");
2097be6bf707SBarry Smith   }
2098be6bf707SBarry Smith   if (!aij->saved_values) {
2099be6bf707SBarry Smith     SETERRQ(1,1,"Must call MatStoreValues(A);first");
2100be6bf707SBarry Smith   }
2101be6bf707SBarry Smith 
2102be6bf707SBarry Smith   /* copy values over */
2103549d3d68SSatish Balay   ierr = PetscMemcpy(aij->a, aij->saved_values,nz*sizeof(Scalar));CHKERRQ(ierr);
2104be6bf707SBarry Smith   PetscFunctionReturn(0);
2105be6bf707SBarry Smith }
2106fb2e594dSBarry Smith EXTERN_C_END
2107be6bf707SBarry Smith 
2108be6bf707SBarry Smith #undef __FUNC__
2109be6bf707SBarry Smith #define __FUNC__ "MatRetrieveValues"
2110be6bf707SBarry Smith /*@
2111be6bf707SBarry Smith     MatRetrieveValues - Retrieves the copy of the matrix values; this allows, for
2112be6bf707SBarry Smith        example, reuse of the linear part of a Jacobian, while recomputing the
2113be6bf707SBarry Smith        nonlinear portion.
2114be6bf707SBarry Smith 
2115be6bf707SBarry Smith    Collect on Mat
2116be6bf707SBarry Smith 
2117be6bf707SBarry Smith   Input Parameters:
2118be6bf707SBarry Smith .  mat - the matrix (currently on AIJ matrices support this option)
2119be6bf707SBarry Smith 
212015091d37SBarry Smith   Level: advanced
212115091d37SBarry Smith 
2122be6bf707SBarry Smith .seealso: MatStoreValues()
2123be6bf707SBarry Smith 
2124be6bf707SBarry Smith @*/
2125be6bf707SBarry Smith int MatRetrieveValues(Mat mat)
2126be6bf707SBarry Smith {
2127be6bf707SBarry Smith   int ierr,(*f)(Mat);
2128be6bf707SBarry Smith 
2129be6bf707SBarry Smith   PetscFunctionBegin;
2130be6bf707SBarry Smith   PetscValidHeaderSpecific(mat,MAT_COOKIE);
2131be6bf707SBarry Smith   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,0,"Not for unassembled matrix");
2132be6bf707SBarry Smith   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,0,"Not for factored matrix");
2133be6bf707SBarry Smith 
2134c5d6004cSBarry Smith   ierr = PetscObjectQueryFunction((PetscObject)mat,"MatRetrieveValues_C",(void **)&f);CHKERRQ(ierr);
2135be6bf707SBarry Smith   if (f) {
2136be6bf707SBarry Smith     ierr = (*f)(mat);CHKERRQ(ierr);
2137be6bf707SBarry Smith   } else {
2138be6bf707SBarry Smith     SETERRQ(1,1,"Wrong type of matrix to retrieve values");
2139be6bf707SBarry Smith   }
2140be6bf707SBarry Smith   PetscFunctionReturn(0);
2141be6bf707SBarry Smith }
2142be6bf707SBarry Smith 
2143be6bf707SBarry Smith /* --------------------------------------------------------------------------------*/
2144cb5b572fSBarry Smith 
2145bef8e0ddSBarry Smith #undef __FUNC__
21465615d1e5SSatish Balay #define __FUNC__ "MatCreateSeqAIJ"
214717ab2063SBarry Smith /*@C
2148682d7d0cSBarry Smith    MatCreateSeqAIJ - Creates a sparse matrix in AIJ (compressed row) format
21490d15e28bSLois Curfman McInnes    (the default parallel PETSc format).  For good matrix assembly performance
21506e62573dSLois Curfman McInnes    the user should preallocate the matrix storage by setting the parameter nz
215151c19458SBarry Smith    (or the array nnz).  By setting these parameters accurately, performance
21522bd5e0b2SLois Curfman McInnes    during matrix assembly can be increased by more than a factor of 50.
215317ab2063SBarry Smith 
2154db81eaa0SLois Curfman McInnes    Collective on MPI_Comm
2155db81eaa0SLois Curfman McInnes 
215617ab2063SBarry Smith    Input Parameters:
2157db81eaa0SLois Curfman McInnes +  comm - MPI communicator, set to PETSC_COMM_SELF
215817ab2063SBarry Smith .  m - number of rows
215917ab2063SBarry Smith .  n - number of columns
216017ab2063SBarry Smith .  nz - number of nonzeros per row (same for all rows)
216151c19458SBarry Smith -  nnz - array containing the number of nonzeros in the various rows
21622bd5e0b2SLois Curfman McInnes          (possibly different for each row) or PETSC_NULL
216317ab2063SBarry Smith 
216417ab2063SBarry Smith    Output Parameter:
2165416022c9SBarry Smith .  A - the matrix
216617ab2063SBarry Smith 
2167b259b22eSLois Curfman McInnes    Notes:
216817ab2063SBarry Smith    The AIJ format (also called the Yale sparse matrix format or
216917ab2063SBarry Smith    compressed row storage), is fully compatible with standard Fortran 77
21700002213bSLois Curfman McInnes    storage.  That is, the stored row and column indices can begin at
217144cd7ae7SLois Curfman McInnes    either one (as in Fortran) or zero.  See the users' manual for details.
217217ab2063SBarry Smith 
217317ab2063SBarry Smith    Specify the preallocated storage with either nz or nnz (not both).
2174a40aa06bSLois Curfman McInnes    Set nz=PETSC_DEFAULT and nnz=PETSC_NULL for PETSc to control dynamic memory
21753d323bbdSBarry Smith    allocation.  For large problems you MUST preallocate memory or you
21766da5968aSLois Curfman McInnes    will get TERRIBLE performance, see the users' manual chapter on matrices.
217717ab2063SBarry Smith 
2178682d7d0cSBarry Smith    By default, this format uses inodes (identical nodes) when possible, to
21794fca80b9SLois Curfman McInnes    improve numerical efficiency of matrix-vector products and solves. We
2180682d7d0cSBarry Smith    search for consecutive rows with the same nonzero structure, thereby
21816c7ebb05SLois Curfman McInnes    reusing matrix information to achieve increased efficiency.
21826c7ebb05SLois Curfman McInnes 
21836c7ebb05SLois Curfman McInnes    Options Database Keys:
2184db81eaa0SLois Curfman McInnes +  -mat_aij_no_inode  - Do not use inodes
2185db81eaa0SLois Curfman McInnes .  -mat_aij_inode_limit <limit> - Sets inode limit (max limit=5)
2186db81eaa0SLois Curfman McInnes -  -mat_aij_oneindex - Internally use indexing starting at 1
2187db81eaa0SLois Curfman McInnes         rather than 0.  Note that when calling MatSetValues(),
2188db81eaa0SLois Curfman McInnes         the user still MUST index entries starting at 0!
218917ab2063SBarry Smith 
2190027ccd11SLois Curfman McInnes    Level: intermediate
2191027ccd11SLois Curfman McInnes 
2192bef8e0ddSBarry Smith .seealso: MatCreate(), MatCreateMPIAIJ(), MatSetValues(), MatSeqAIJSetColumnIndices()
219317ab2063SBarry Smith @*/
2194416022c9SBarry Smith int MatCreateSeqAIJ(MPI_Comm comm,int m,int n,int nz,int *nnz, Mat *A)
219517ab2063SBarry Smith {
2196416022c9SBarry Smith   Mat        B;
2197416022c9SBarry Smith   Mat_SeqAIJ *b;
21986945ee14SBarry Smith   int        i, len, ierr, flg,size;
21996945ee14SBarry Smith 
22003a40ed3dSBarry Smith   PetscFunctionBegin;
2201d132466eSBarry Smith   ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr);
2202a8c6a408SBarry Smith   if (size > 1) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Comm must be of size 1");
2203d5d45c9bSBarry Smith 
2204b73539f3SBarry Smith   if (nz < -2) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,0,"nz cannot be less than -2: value %d",nz);
2205b73539f3SBarry Smith   if (nnz) {
2206b73539f3SBarry Smith     for (i=0; i<m; i++) {
2207b73539f3SBarry Smith       if (nnz[i] < 0) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,0,"nnz cannot be less than 0: local row %d value %d",i,nnz[i]);
2208b73539f3SBarry Smith     }
2209b73539f3SBarry Smith   }
2210b73539f3SBarry Smith 
2211416022c9SBarry Smith   *A                  = 0;
22123f1db9ecSBarry Smith   PetscHeaderCreate(B,_p_Mat,struct _MatOps,MAT_COOKIE,MATSEQAIJ,"Mat",comm,MatDestroy,MatView);
2213416022c9SBarry Smith   PLogObjectCreate(B);
22140452661fSBarry Smith   B->data             = (void *) (b = PetscNew(Mat_SeqAIJ));CHKPTRQ(b);
2215549d3d68SSatish Balay   ierr = PetscMemzero(b,sizeof(Mat_SeqAIJ));CHKERRQ(ierr);
2216549d3d68SSatish Balay   ierr = PetscMemcpy(B->ops,&MatOps_Values,sizeof(struct _MatOps));CHKERRQ(ierr);
2217e1311b90SBarry Smith   B->ops->destroy          = MatDestroy_SeqAIJ;
2218e1311b90SBarry Smith   B->ops->view             = MatView_SeqAIJ;
2219416022c9SBarry Smith   B->factor           = 0;
2220416022c9SBarry Smith   B->lupivotthreshold = 1.0;
222190f02eecSBarry Smith   B->mapping          = 0;
2222e1311b90SBarry Smith   ierr = OptionsGetDouble(PETSC_NULL,"-mat_lu_pivotthreshold",&B->lupivotthreshold,&flg);CHKERRQ(ierr);
22237a743949SBarry Smith   b->ilu_preserve_row_sums = PETSC_FALSE;
2224e1311b90SBarry Smith   ierr = OptionsHasName(PETSC_NULL,"-pc_ilu_preserve_row_sums",(int*)&b->ilu_preserve_row_sums);CHKERRQ(ierr);
2225416022c9SBarry Smith   b->row              = 0;
2226416022c9SBarry Smith   b->col              = 0;
222782bf6240SBarry Smith   b->icol             = 0;
2228416022c9SBarry Smith   b->indexshift       = 0;
2229b810aeb4SBarry Smith   b->reallocs         = 0;
223069957df2SSatish Balay   ierr = OptionsHasName(PETSC_NULL,"-mat_aij_oneindex", &flg);CHKERRQ(ierr);
223169957df2SSatish Balay   if (flg) b->indexshift = -1;
223217ab2063SBarry Smith 
223344cd7ae7SLois Curfman McInnes   b->m = m; B->m = m; B->M = m;
223444cd7ae7SLois Curfman McInnes   b->n = n; B->n = n; B->N = n;
2235a5ae1ecdSBarry Smith 
22364d197716SBarry Smith   ierr = MapCreateMPI(comm,m,m,&B->rmap);CHKERRQ(ierr);
22374d197716SBarry Smith   ierr = MapCreateMPI(comm,n,n,&B->cmap);CHKERRQ(ierr);
2238a5ae1ecdSBarry Smith 
22390452661fSBarry Smith   b->imax = (int *) PetscMalloc( (m+1)*sizeof(int) );CHKPTRQ(b->imax);
2240b4fd4287SBarry Smith   if (nnz == PETSC_NULL) {
22417b8455f0SLois Curfman McInnes     if (nz == PETSC_DEFAULT) nz = 10;
22427b8455f0SLois Curfman McInnes     else if (nz <= 0)        nz = 1;
2243416022c9SBarry Smith     for ( i=0; i<m; i++ ) b->imax[i] = nz;
224417ab2063SBarry Smith     nz = nz*m;
22453a40ed3dSBarry Smith   } else {
224617ab2063SBarry Smith     nz = 0;
2247416022c9SBarry Smith     for ( i=0; i<m; i++ ) {b->imax[i] = nnz[i]; nz += nnz[i];}
224817ab2063SBarry Smith   }
224917ab2063SBarry Smith 
225017ab2063SBarry Smith   /* allocate the matrix space */
2251416022c9SBarry Smith   len             = nz*(sizeof(int) + sizeof(Scalar)) + (b->m+1)*sizeof(int);
22520452661fSBarry Smith   b->a            = (Scalar *) PetscMalloc( len );CHKPTRQ(b->a);
2253416022c9SBarry Smith   b->j            = (int *) (b->a + nz);
2254549d3d68SSatish Balay   ierr            = PetscMemzero(b->j,nz*sizeof(int));CHKERRQ(ierr);
2255416022c9SBarry Smith   b->i            = b->j + nz;
2256416022c9SBarry Smith   b->singlemalloc = 1;
225717ab2063SBarry Smith 
2258416022c9SBarry Smith   b->i[0] = -b->indexshift;
225917ab2063SBarry Smith   for (i=1; i<m+1; i++) {
2260416022c9SBarry Smith     b->i[i] = b->i[i-1] + b->imax[i-1];
226117ab2063SBarry Smith   }
226217ab2063SBarry Smith 
2263416022c9SBarry Smith   /* b->ilen will count nonzeros in each row so far. */
22640452661fSBarry Smith   b->ilen = (int *) PetscMalloc((m+1)*sizeof(int));
2265f09e8eb9SSatish Balay   PLogObjectMemory(B,len+2*(m+1)*sizeof(int)+sizeof(struct _p_Mat)+sizeof(Mat_SeqAIJ));
2266416022c9SBarry Smith   for ( i=0; i<b->m; i++ ) { b->ilen[i] = 0;}
226717ab2063SBarry Smith 
2268416022c9SBarry Smith   b->nz               = 0;
2269416022c9SBarry Smith   b->maxnz            = nz;
2270416022c9SBarry Smith   b->sorted           = 0;
2271416022c9SBarry Smith   b->roworiented      = 1;
2272416022c9SBarry Smith   b->nonew            = 0;
2273416022c9SBarry Smith   b->diag             = 0;
2274416022c9SBarry Smith   b->solve_work       = 0;
227571bd300dSLois Curfman McInnes   b->spptr            = 0;
2276754ec7b1SSatish Balay   b->inode.node_count = 0;
2277754ec7b1SSatish Balay   b->inode.size       = 0;
22786c7ebb05SLois Curfman McInnes   b->inode.limit      = 5;
22796c7ebb05SLois Curfman McInnes   b->inode.max_limit  = 5;
2280be6bf707SBarry Smith   b->saved_values     = 0;
22814e220ebcSLois Curfman McInnes   B->info.nz_unneeded = (double)b->maxnz;
2282d7f994e1SBarry Smith   b->idiag            = 0;
2283d7f994e1SBarry Smith   b->ssor             = 0;
228417ab2063SBarry Smith 
2285416022c9SBarry Smith   *A = B;
22864e220ebcSLois Curfman McInnes 
22874b14c69eSBarry Smith   /*  SuperLU is not currently supported through PETSc */
2288aa482453SBarry Smith #if defined(PETSC_HAVE_SUPERLU)
228969957df2SSatish Balay   ierr = OptionsHasName(PETSC_NULL,"-mat_aij_superlu", &flg);CHKERRQ(ierr);
229069957df2SSatish Balay   if (flg) { ierr = MatUseSuperLU_SeqAIJ(B);CHKERRQ(ierr); }
22914b14c69eSBarry Smith #endif
229269957df2SSatish Balay   ierr = OptionsHasName(PETSC_NULL,"-mat_aij_essl", &flg);CHKERRQ(ierr);
229369957df2SSatish Balay   if (flg) { ierr = MatUseEssl_SeqAIJ(B);CHKERRQ(ierr); }
229469957df2SSatish Balay   ierr = OptionsHasName(PETSC_NULL,"-mat_aij_dxml", &flg);CHKERRQ(ierr);
229569957df2SSatish Balay   if (flg) {
2296a8c6a408SBarry Smith     if (!b->indexshift) SETERRQ( PETSC_ERR_LIB,0,"need -mat_aij_oneindex with -mat_aij_dxml");
2297416022c9SBarry Smith     ierr = MatUseDXML_SeqAIJ(B);CHKERRQ(ierr);
229817ab2063SBarry Smith   }
229969957df2SSatish Balay   ierr = OptionsHasName(PETSC_NULL,"-help", &flg);CHKERRQ(ierr);
230069957df2SSatish Balay   if (flg) {ierr = MatPrintHelp(B);CHKERRQ(ierr); }
2301bef8e0ddSBarry Smith 
2302bef8e0ddSBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatSeqAIJSetColumnIndices_C",
2303bef8e0ddSBarry Smith                                      "MatSeqAIJSetColumnIndices_SeqAIJ",
2304bef8e0ddSBarry Smith                                      (void*)MatSeqAIJSetColumnIndices_SeqAIJ);CHKERRQ(ierr);
2305be6bf707SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatStoreValues_C",
2306be6bf707SBarry Smith                                      "MatStoreValues_SeqAIJ",
2307be6bf707SBarry Smith                                      (void*)MatStoreValues_SeqAIJ);CHKERRQ(ierr);
2308be6bf707SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatRetrieveValues_C",
2309be6bf707SBarry Smith                                      "MatRetrieveValues_SeqAIJ",
2310be6bf707SBarry Smith                                      (void*)MatRetrieveValues_SeqAIJ);CHKERRQ(ierr);
23113a40ed3dSBarry Smith   PetscFunctionReturn(0);
231217ab2063SBarry Smith }
231317ab2063SBarry Smith 
23145615d1e5SSatish Balay #undef __FUNC__
2315be6bf707SBarry Smith #define __FUNC__ "MatDuplicate_SeqAIJ"
2316be6bf707SBarry Smith int MatDuplicate_SeqAIJ(Mat A,MatDuplicateOption cpvalues,Mat *B)
231717ab2063SBarry Smith {
2318416022c9SBarry Smith   Mat        C;
2319416022c9SBarry Smith   Mat_SeqAIJ *c,*a = (Mat_SeqAIJ *) A->data;
2320bef8e0ddSBarry Smith   int        i,len, m = a->m,shift = a->indexshift,ierr;
232117ab2063SBarry Smith 
23223a40ed3dSBarry Smith   PetscFunctionBegin;
23234043dd9cSLois Curfman McInnes   *B = 0;
23243f1db9ecSBarry Smith   PetscHeaderCreate(C,_p_Mat,struct _MatOps,MAT_COOKIE,MATSEQAIJ,"Mat",A->comm,MatDestroy,MatView);
2325416022c9SBarry Smith   PLogObjectCreate(C);
23260452661fSBarry Smith   C->data         = (void *) (c = PetscNew(Mat_SeqAIJ));CHKPTRQ(c);
2327549d3d68SSatish Balay   ierr            = PetscMemcpy(C->ops,A->ops,sizeof(struct _MatOps));CHKERRQ(ierr);
2328e1311b90SBarry Smith   C->ops->destroy = MatDestroy_SeqAIJ;
2329e1311b90SBarry Smith   C->ops->view    = MatView_SeqAIJ;
2330416022c9SBarry Smith   C->factor       = A->factor;
2331416022c9SBarry Smith   c->row          = 0;
2332416022c9SBarry Smith   c->col          = 0;
233382bf6240SBarry Smith   c->icol         = 0;
2334416022c9SBarry Smith   c->indexshift   = shift;
2335c456f294SBarry Smith   C->assembled    = PETSC_TRUE;
233617ab2063SBarry Smith 
233744cd7ae7SLois Curfman McInnes   c->m = C->m   = a->m;
233844cd7ae7SLois Curfman McInnes   c->n = C->n   = a->n;
233944cd7ae7SLois Curfman McInnes   C->M          = a->m;
234044cd7ae7SLois Curfman McInnes   C->N          = a->n;
234117ab2063SBarry Smith 
23420452661fSBarry Smith   c->imax       = (int *) PetscMalloc((m+1)*sizeof(int));CHKPTRQ(c->imax);
23430452661fSBarry Smith   c->ilen       = (int *) PetscMalloc((m+1)*sizeof(int));CHKPTRQ(c->ilen);
234417ab2063SBarry Smith   for ( i=0; i<m; i++ ) {
2345416022c9SBarry Smith     c->imax[i] = a->imax[i];
2346416022c9SBarry Smith     c->ilen[i] = a->ilen[i];
234717ab2063SBarry Smith   }
234817ab2063SBarry Smith 
234917ab2063SBarry Smith   /* allocate the matrix space */
2350416022c9SBarry Smith   c->singlemalloc = 1;
2351416022c9SBarry Smith   len     = (m+1)*sizeof(int)+(a->i[m])*(sizeof(Scalar)+sizeof(int));
23520452661fSBarry Smith   c->a  = (Scalar *) PetscMalloc( len );CHKPTRQ(c->a);
2353416022c9SBarry Smith   c->j  = (int *) (c->a + a->i[m] + shift);
2354416022c9SBarry Smith   c->i  = c->j + a->i[m] + shift;
2355549d3d68SSatish Balay   ierr = PetscMemcpy(c->i,a->i,(m+1)*sizeof(int));CHKERRQ(ierr);
235617ab2063SBarry Smith   if (m > 0) {
2357549d3d68SSatish Balay     ierr = PetscMemcpy(c->j,a->j,(a->i[m]+shift)*sizeof(int));CHKERRQ(ierr);
2358be6bf707SBarry Smith     if (cpvalues == MAT_COPY_VALUES) {
2359549d3d68SSatish Balay       ierr = PetscMemcpy(c->a,a->a,(a->i[m]+shift)*sizeof(Scalar));CHKERRQ(ierr);
2360be6bf707SBarry Smith     } else {
2361549d3d68SSatish Balay       ierr = PetscMemzero(c->a,(a->i[m]+shift)*sizeof(Scalar));CHKERRQ(ierr);
236217ab2063SBarry Smith     }
236308480c60SBarry Smith   }
236417ab2063SBarry Smith 
2365f09e8eb9SSatish Balay   PLogObjectMemory(C,len+2*(m+1)*sizeof(int)+sizeof(struct _p_Mat)+sizeof(Mat_SeqAIJ));
2366416022c9SBarry Smith   c->sorted      = a->sorted;
2367416022c9SBarry Smith   c->roworiented = a->roworiented;
2368416022c9SBarry Smith   c->nonew       = a->nonew;
23697a743949SBarry Smith   c->ilu_preserve_row_sums = a->ilu_preserve_row_sums;
2370be6bf707SBarry Smith   c->saved_values = 0;
2371d7f994e1SBarry Smith   c->idiag        = 0;
2372d7f994e1SBarry Smith   c->ssor         = 0;
237317ab2063SBarry Smith 
2374416022c9SBarry Smith   if (a->diag) {
23750452661fSBarry Smith     c->diag = (int *) PetscMalloc( (m+1)*sizeof(int) );CHKPTRQ(c->diag);
2376416022c9SBarry Smith     PLogObjectMemory(C,(m+1)*sizeof(int));
237717ab2063SBarry Smith     for ( i=0; i<m; i++ ) {
2378416022c9SBarry Smith       c->diag[i] = a->diag[i];
237917ab2063SBarry Smith     }
23803a40ed3dSBarry Smith   } else c->diag          = 0;
23816c7ebb05SLois Curfman McInnes   c->inode.limit        = a->inode.limit;
23826c7ebb05SLois Curfman McInnes   c->inode.max_limit    = a->inode.max_limit;
2383754ec7b1SSatish Balay   if (a->inode.size){
2384daed632aSSatish Balay     c->inode.size       = (int *) PetscMalloc( (m+1)*sizeof(int) );CHKPTRQ(c->inode.size);
2385754ec7b1SSatish Balay     c->inode.node_count = a->inode.node_count;
2386549d3d68SSatish Balay     ierr = PetscMemcpy( c->inode.size, a->inode.size, (m+1)*sizeof(int));CHKERRQ(ierr);
2387754ec7b1SSatish Balay   } else {
2388754ec7b1SSatish Balay     c->inode.size       = 0;
2389754ec7b1SSatish Balay     c->inode.node_count = 0;
2390754ec7b1SSatish Balay   }
2391416022c9SBarry Smith   c->nz                 = a->nz;
2392416022c9SBarry Smith   c->maxnz              = a->maxnz;
2393416022c9SBarry Smith   c->solve_work         = 0;
239476dd722bSSatish Balay   c->spptr              = 0;      /* Dangerous -I'm throwing away a->spptr */
2395754ec7b1SSatish Balay 
2396416022c9SBarry Smith   *B = C;
23977b2a1423SBarry Smith   ierr = FListDuplicate(A->qlist,&C->qlist);CHKERRQ(ierr);
23983a40ed3dSBarry Smith   PetscFunctionReturn(0);
239917ab2063SBarry Smith }
240017ab2063SBarry Smith 
24015615d1e5SSatish Balay #undef __FUNC__
24025615d1e5SSatish Balay #define __FUNC__ "MatLoad_SeqAIJ"
240319bcc07fSBarry Smith int MatLoad_SeqAIJ(Viewer viewer,MatType type,Mat *A)
240417ab2063SBarry Smith {
2405416022c9SBarry Smith   Mat_SeqAIJ   *a;
2406416022c9SBarry Smith   Mat          B;
240717699dbbSLois Curfman McInnes   int          i, nz, ierr, fd, header[4],size,*rowlengths = 0,M,N,shift;
2408bcd2baecSBarry Smith   MPI_Comm     comm;
240917ab2063SBarry Smith 
24103a40ed3dSBarry Smith   PetscFunctionBegin;
2411e864ced6SBarry Smith   ierr = PetscObjectGetComm((PetscObject) viewer,&comm);CHKERRQ(ierr);
2412d132466eSBarry Smith   ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr);
2413a8c6a408SBarry Smith   if (size > 1) SETERRQ(PETSC_ERR_ARG_SIZ,0,"view must have one processor");
241490ace30eSBarry Smith   ierr = ViewerBinaryGetDescriptor(viewer,&fd);CHKERRQ(ierr);
24150752156aSBarry Smith   ierr = PetscBinaryRead(fd,header,4,PETSC_INT);CHKERRQ(ierr);
2416a8c6a408SBarry Smith   if (header[0] != MAT_COOKIE) SETERRQ(PETSC_ERR_FILE_UNEXPECTED,0,"not matrix object in file");
241717ab2063SBarry Smith   M = header[1]; N = header[2]; nz = header[3];
241817ab2063SBarry Smith 
2419d64ed03dSBarry Smith   if (nz < 0) {
2420a8c6a408SBarry Smith     SETERRQ(PETSC_ERR_FILE_UNEXPECTED,1,"Matrix stored in special format on disk, cannot load as SeqAIJ");
2421d64ed03dSBarry Smith   }
2422d64ed03dSBarry Smith 
242317ab2063SBarry Smith   /* read in row lengths */
24240452661fSBarry Smith   rowlengths = (int*) PetscMalloc( M*sizeof(int) );CHKPTRQ(rowlengths);
24250752156aSBarry Smith   ierr = PetscBinaryRead(fd,rowlengths,M,PETSC_INT);CHKERRQ(ierr);
242617ab2063SBarry Smith 
242717ab2063SBarry Smith   /* create our matrix */
2428416022c9SBarry Smith   ierr = MatCreateSeqAIJ(comm,M,N,0,rowlengths,A);CHKERRQ(ierr);
2429416022c9SBarry Smith   B = *A;
2430416022c9SBarry Smith   a = (Mat_SeqAIJ *) B->data;
2431416022c9SBarry Smith   shift = a->indexshift;
243217ab2063SBarry Smith 
243317ab2063SBarry Smith   /* read in column indices and adjust for Fortran indexing*/
24340752156aSBarry Smith   ierr = PetscBinaryRead(fd,a->j,nz,PETSC_INT);CHKERRQ(ierr);
243517ab2063SBarry Smith   if (shift) {
243617ab2063SBarry Smith     for ( i=0; i<nz; i++ ) {
2437416022c9SBarry Smith       a->j[i] += 1;
243817ab2063SBarry Smith     }
243917ab2063SBarry Smith   }
244017ab2063SBarry Smith 
244117ab2063SBarry Smith   /* read in nonzero values */
24420752156aSBarry Smith   ierr = PetscBinaryRead(fd,a->a,nz,PETSC_SCALAR);CHKERRQ(ierr);
244317ab2063SBarry Smith 
244417ab2063SBarry Smith   /* set matrix "i" values */
2445416022c9SBarry Smith   a->i[0] = -shift;
244617ab2063SBarry Smith   for ( i=1; i<= M; i++ ) {
2447416022c9SBarry Smith     a->i[i]      = a->i[i-1] + rowlengths[i-1];
2448416022c9SBarry Smith     a->ilen[i-1] = rowlengths[i-1];
244917ab2063SBarry Smith   }
2450606d414cSSatish Balay   ierr = PetscFree(rowlengths);CHKERRQ(ierr);
245117ab2063SBarry Smith 
24526d4a8577SBarry Smith   ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
24536d4a8577SBarry Smith   ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
24543a40ed3dSBarry Smith   PetscFunctionReturn(0);
245517ab2063SBarry Smith }
245617ab2063SBarry Smith 
24575615d1e5SSatish Balay #undef __FUNC__
24585615d1e5SSatish Balay #define __FUNC__ "MatEqual_SeqAIJ"
24598f6be9afSLois Curfman McInnes int MatEqual_SeqAIJ(Mat A,Mat B, PetscTruth* flg)
24607264ac53SSatish Balay {
24617264ac53SSatish Balay   Mat_SeqAIJ *a = (Mat_SeqAIJ *)A->data, *b = (Mat_SeqAIJ *)B->data;
24620f5bd95cSBarry Smith   int        ierr;
24637264ac53SSatish Balay 
24643a40ed3dSBarry Smith   PetscFunctionBegin;
2465a8c6a408SBarry Smith   if (B->type !=MATSEQAIJ)SETERRQ(PETSC_ERR_ARG_INCOMP,0,"Matrices must be same type");
24667264ac53SSatish Balay 
24677264ac53SSatish Balay   /* If the  matrix dimensions are not equal, or no of nonzeros or shift */
24687264ac53SSatish Balay   if ((a->m != b->m ) || (a->n !=b->n) ||( a->nz != b->nz)||
2469bcd2baecSBarry Smith       (a->indexshift != b->indexshift)) {
24703a40ed3dSBarry Smith     *flg = PETSC_FALSE; PetscFunctionReturn(0);
2471bcd2baecSBarry Smith   }
24727264ac53SSatish Balay 
24737264ac53SSatish Balay   /* if the a->i are the same */
24740f5bd95cSBarry Smith   ierr = PetscMemcmp(a->i,b->i,(a->m+1)*sizeof(int),flg);CHKERRQ(ierr);
24750f5bd95cSBarry Smith   if (*flg == PETSC_FALSE) PetscFunctionReturn(0);
24767264ac53SSatish Balay 
24777264ac53SSatish Balay   /* if a->j are the same */
24780f5bd95cSBarry Smith   ierr = PetscMemcmp(a->j, b->j, (a->nz)*sizeof(int),flg);CHKERRQ(ierr);
24790f5bd95cSBarry Smith   if (*flg == PETSC_FALSE) PetscFunctionReturn(0);
2480bcd2baecSBarry Smith 
2481bcd2baecSBarry Smith   /* if a->a are the same */
24820f5bd95cSBarry Smith   ierr = PetscMemcmp(a->a, b->a, (a->nz)*sizeof(Scalar),flg);CHKERRQ(ierr);
24830f5bd95cSBarry Smith 
24843a40ed3dSBarry Smith   PetscFunctionReturn(0);
24857264ac53SSatish Balay 
24867264ac53SSatish Balay }
2487