xref: /petsc/src/mat/impls/aij/seq/aij.c (revision f1e2ffcdf65679ed52caf95ee2fbac3db31d26d8)
1*f1e2ffcdSBarry Smith /*$Id: aij.c,v 1.333 1999/11/10 03:19:11 bsmith Exp bsmith $*/
2d5d45c9bSBarry Smith /*
33369ce9aSBarry Smith     Defines the basic matrix operations for the AIJ (compressed row)
4d5d45c9bSBarry Smith   matrix storage format.
5d5d45c9bSBarry Smith */
63369ce9aSBarry Smith 
73369ce9aSBarry Smith #include "sys.h"
870f55243SBarry Smith #include "src/mat/impls/aij/seq/aij.h"
9f5eb4b81SSatish Balay #include "src/vec/vecimpl.h"
10f5eb4b81SSatish Balay #include "src/inline/spops.h"
118d195f9aSBarry Smith #include "src/inline/dot.h"
12eeb667a2SSatish Balay #include "bitarray.h"
1317ab2063SBarry Smith 
14a2ce50c7SBarry Smith /*
15a2ce50c7SBarry Smith     Basic AIJ format ILU based on drop tolerance
16a2ce50c7SBarry Smith */
175615d1e5SSatish Balay #undef __FUNC__
185615d1e5SSatish Balay #define __FUNC__ "MatILUDTFactor_SeqAIJ"
19a2ce50c7SBarry Smith int MatILUDTFactor_SeqAIJ(Mat A,double dt,int maxnz,IS row,IS col,Mat *fact)
20a2ce50c7SBarry Smith {
21a2ce50c7SBarry Smith   /* Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data; */
22a2ce50c7SBarry Smith 
233a40ed3dSBarry Smith   PetscFunctionBegin;
243f1db9ecSBarry Smith   SETERRQ(1,0,"Not implemented");
25aa482453SBarry Smith #if !defined(PETSC_USE_DEBUG)
26d64ed03dSBarry Smith   PetscFunctionReturn(0);
27d64ed03dSBarry Smith #endif
28a2ce50c7SBarry Smith }
29a2ce50c7SBarry Smith 
30bcd2baecSBarry Smith extern int MatToSymmetricIJ_SeqAIJ(int,int*,int*,int,int,int**,int**);
3117ab2063SBarry Smith 
325615d1e5SSatish Balay #undef __FUNC__
335615d1e5SSatish Balay #define __FUNC__ "MatGetRowIJ_SeqAIJ"
348f6be9afSLois Curfman McInnes int MatGetRowIJ_SeqAIJ(Mat A,int oshift,PetscTruth symmetric,int *m,int **ia,int **ja,
356945ee14SBarry Smith                            PetscTruth *done)
3617ab2063SBarry Smith {
37416022c9SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data;
386945ee14SBarry Smith   int        ierr,i,ishift;
3917ab2063SBarry Smith 
403a40ed3dSBarry Smith   PetscFunctionBegin;
4131625ec5SSatish Balay   *m     = A->m;
423a40ed3dSBarry Smith   if (!ia) PetscFunctionReturn(0);
436945ee14SBarry Smith   ishift = a->indexshift;
446945ee14SBarry Smith   if (symmetric) {
4531625ec5SSatish Balay     ierr = MatToSymmetricIJ_SeqAIJ(a->m,a->i,a->j,ishift,oshift,ia,ja);CHKERRQ(ierr);
466945ee14SBarry Smith   } else if (oshift == 0 && ishift == -1) {
4731625ec5SSatish Balay     int nz = a->i[a->m];
483b2fbd54SBarry Smith     /* malloc space and  subtract 1 from i and j indices */
4931625ec5SSatish Balay     *ia = (int *) PetscMalloc( (a->m+1)*sizeof(int) );CHKPTRQ(*ia);
503b2fbd54SBarry Smith     *ja = (int *) PetscMalloc( (nz+1)*sizeof(int) );CHKPTRQ(*ja);
513b2fbd54SBarry Smith     for ( i=0; i<nz; i++ ) (*ja)[i] = a->j[i] - 1;
5231625ec5SSatish Balay     for ( i=0; i<a->m+1; i++ ) (*ia)[i] = a->i[i] - 1;
536945ee14SBarry Smith   } else if (oshift == 1 && ishift == 0) {
5431625ec5SSatish Balay     int nz = a->i[a->m] + 1;
553b2fbd54SBarry Smith     /* malloc space and  add 1 to i and j indices */
5631625ec5SSatish Balay     *ia = (int *) PetscMalloc( (a->m+1)*sizeof(int) );CHKPTRQ(*ia);
573b2fbd54SBarry Smith     *ja = (int *) PetscMalloc( (nz+1)*sizeof(int) );CHKPTRQ(*ja);
583b2fbd54SBarry Smith     for ( i=0; i<nz; i++ ) (*ja)[i] = a->j[i] + 1;
5931625ec5SSatish Balay     for ( i=0; i<a->m+1; i++ ) (*ia)[i] = a->i[i] + 1;
606945ee14SBarry Smith   } else {
616945ee14SBarry Smith     *ia = a->i; *ja = a->j;
62a2ce50c7SBarry Smith   }
63a2ce50c7SBarry Smith 
643a40ed3dSBarry Smith   PetscFunctionReturn(0);
65a2744918SBarry Smith }
66a2744918SBarry Smith 
675615d1e5SSatish Balay #undef __FUNC__
685615d1e5SSatish Balay #define __FUNC__ "MatRestoreRowIJ_SeqAIJ"
698f6be9afSLois Curfman McInnes int MatRestoreRowIJ_SeqAIJ(Mat A,int oshift,PetscTruth symmetric,int *n,int **ia,int **ja,
706945ee14SBarry Smith                                PetscTruth *done)
716945ee14SBarry Smith {
726945ee14SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data;
73606d414cSSatish Balay   int        ishift = a->indexshift,ierr;
746945ee14SBarry Smith 
753a40ed3dSBarry Smith   PetscFunctionBegin;
763a40ed3dSBarry Smith   if (!ia) PetscFunctionReturn(0);
773b2fbd54SBarry Smith   if (symmetric || (oshift == 0 && ishift == -1) || (oshift == 1 && ishift == 0)) {
78606d414cSSatish Balay     ierr = PetscFree(*ia);CHKERRQ(ierr);
79606d414cSSatish Balay     ierr = PetscFree(*ja);CHKERRQ(ierr);
80bcd2baecSBarry Smith   }
813a40ed3dSBarry Smith   PetscFunctionReturn(0);
8217ab2063SBarry Smith }
8317ab2063SBarry Smith 
845615d1e5SSatish Balay #undef __FUNC__
855615d1e5SSatish Balay #define __FUNC__ "MatGetColumnIJ_SeqAIJ"
8643a90d84SBarry Smith int MatGetColumnIJ_SeqAIJ(Mat A,int oshift,PetscTruth symmetric,int *nn,int **ia,int **ja,
873b2fbd54SBarry Smith                            PetscTruth *done)
883b2fbd54SBarry Smith {
893b2fbd54SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data;
90a93ec695SBarry Smith   int        ierr,i,ishift = a->indexshift,*collengths,*cia,*cja,n = A->n,m = A->m;
91a93ec695SBarry Smith   int        nz = a->i[m]+ishift,row,*jj,mr,col;
923b2fbd54SBarry Smith 
933a40ed3dSBarry Smith   PetscFunctionBegin;
943b2fbd54SBarry Smith   *nn     = A->n;
953a40ed3dSBarry Smith   if (!ia) PetscFunctionReturn(0);
963b2fbd54SBarry Smith   if (symmetric) {
97179192dfSSatish Balay     ierr = MatToSymmetricIJ_SeqAIJ(a->m,a->i,a->j,ishift,oshift,ia,ja);CHKERRQ(ierr);
983b2fbd54SBarry Smith   } else {
9961d2ded1SBarry Smith     collengths = (int *) PetscMalloc( (n+1)*sizeof(int) );CHKPTRQ(collengths);
100549d3d68SSatish Balay     ierr       = PetscMemzero(collengths,n*sizeof(int));CHKERRQ(ierr);
1013b2fbd54SBarry Smith     cia        = (int *) PetscMalloc( (n+1)*sizeof(int) );CHKPTRQ(cia);
102a93ec695SBarry Smith     cja        = (int *) PetscMalloc( (nz+1)*sizeof(int) );CHKPTRQ(cja);
1033b2fbd54SBarry Smith     jj = a->j;
1043b2fbd54SBarry Smith     for ( i=0; i<nz; i++ ) {
1053b2fbd54SBarry Smith       collengths[jj[i] + ishift]++;
1063b2fbd54SBarry Smith     }
1073b2fbd54SBarry Smith     cia[0] = oshift;
1083b2fbd54SBarry Smith     for ( i=0; i<n; i++) {
1093b2fbd54SBarry Smith       cia[i+1] = cia[i] + collengths[i];
1103b2fbd54SBarry Smith     }
111549d3d68SSatish Balay     ierr = PetscMemzero(collengths,n*sizeof(int));CHKERRQ(ierr);
1123b2fbd54SBarry Smith     jj   = a->j;
113a93ec695SBarry Smith     for ( row=0; row<m; row++ ) {
114a93ec695SBarry Smith       mr = a->i[row+1] - a->i[row];
115a93ec695SBarry Smith       for ( i=0; i<mr; i++ ) {
1163b2fbd54SBarry Smith         col = *jj++ + ishift;
1173b2fbd54SBarry Smith         cja[cia[col] + collengths[col]++ - oshift] = row + oshift;
1183b2fbd54SBarry Smith       }
1193b2fbd54SBarry Smith     }
120606d414cSSatish Balay     ierr = PetscFree(collengths);CHKERRQ(ierr);
1213b2fbd54SBarry Smith     *ia = cia; *ja = cja;
1223b2fbd54SBarry Smith   }
1233b2fbd54SBarry Smith 
1243a40ed3dSBarry Smith   PetscFunctionReturn(0);
1253b2fbd54SBarry Smith }
1263b2fbd54SBarry Smith 
1275615d1e5SSatish Balay #undef __FUNC__
1285615d1e5SSatish Balay #define __FUNC__ "MatRestoreColumnIJ_SeqAIJ"
12943a90d84SBarry Smith int MatRestoreColumnIJ_SeqAIJ(Mat A,int oshift,PetscTruth symmetric,int *n,int **ia,
1303b2fbd54SBarry Smith                                      int **ja,PetscTruth *done)
1313b2fbd54SBarry Smith {
132606d414cSSatish Balay   int ierr;
133606d414cSSatish Balay 
1343a40ed3dSBarry Smith   PetscFunctionBegin;
1353a40ed3dSBarry Smith   if (!ia) PetscFunctionReturn(0);
1363b2fbd54SBarry Smith 
137606d414cSSatish Balay   ierr = PetscFree(*ia);CHKERRQ(ierr);
138606d414cSSatish Balay   ierr = PetscFree(*ja);CHKERRQ(ierr);
1393b2fbd54SBarry Smith 
1403a40ed3dSBarry Smith   PetscFunctionReturn(0);
1413b2fbd54SBarry Smith }
1423b2fbd54SBarry Smith 
143227d817aSBarry Smith #define CHUNKSIZE   15
14417ab2063SBarry Smith 
1455615d1e5SSatish Balay #undef __FUNC__
1465615d1e5SSatish Balay #define __FUNC__ "MatSetValues_SeqAIJ"
14761d2ded1SBarry Smith int MatSetValues_SeqAIJ(Mat A,int m,int *im,int n,int *in,Scalar *v,InsertMode is)
14817ab2063SBarry Smith {
149416022c9SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data;
150416022c9SBarry Smith   int        *rp,k,low,high,t,ii,row,nrow,i,col,l,rmax, N, sorted = a->sorted;
1514b0e389bSBarry Smith   int        *imax = a->imax, *ai = a->i, *ailen = a->ilen,roworiented = a->roworiented;
152549d3d68SSatish Balay   int        *aj = a->j, nonew = a->nonew,shift = a->indexshift,ierr;
153416022c9SBarry Smith   Scalar     *ap,value, *aa = a->a;
15417ab2063SBarry Smith 
1553a40ed3dSBarry Smith   PetscFunctionBegin;
15617ab2063SBarry Smith   for ( k=0; k<m; k++ ) { /* loop over added rows */
157416022c9SBarry Smith     row  = im[k];
1585ef9f2a5SBarry Smith     if (row < 0) continue;
159aa482453SBarry Smith #if defined(PETSC_USE_BOPT_g)
16032e87ba3SBarry Smith     if (row >= a->m) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,0,"Row too large: row %d max %d",row,a->m);
1613b2fbd54SBarry Smith #endif
16217ab2063SBarry Smith     rp   = aj + ai[row] + shift; ap = aa + ai[row] + shift;
16317ab2063SBarry Smith     rmax = imax[row]; nrow = ailen[row];
164416022c9SBarry Smith     low = 0;
16517ab2063SBarry Smith     for ( l=0; l<n; l++ ) { /* loop over added columns */
1665ef9f2a5SBarry Smith       if (in[l] < 0) continue;
167aa482453SBarry Smith #if defined(PETSC_USE_BOPT_g)
16832e87ba3SBarry Smith       if (in[l] >= a->n) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,0,"Column too large: col %d max %d",in[l],a->n);
1693b2fbd54SBarry Smith #endif
1704b0e389bSBarry Smith       col = in[l] - shift;
1714b0e389bSBarry Smith       if (roworiented) {
1725ef9f2a5SBarry Smith         value = v[l + k*n];
173bef8e0ddSBarry Smith       } else {
1744b0e389bSBarry Smith         value = v[k + l*m];
1754b0e389bSBarry Smith       }
176416022c9SBarry Smith       if (!sorted) low = 0; high = nrow;
177416022c9SBarry Smith       while (high-low > 5) {
178416022c9SBarry Smith         t = (low+high)/2;
179416022c9SBarry Smith         if (rp[t] > col) high = t;
180416022c9SBarry Smith         else             low  = t;
18117ab2063SBarry Smith       }
182416022c9SBarry Smith       for ( i=low; i<high; i++ ) {
18317ab2063SBarry Smith         if (rp[i] > col) break;
18417ab2063SBarry Smith         if (rp[i] == col) {
185416022c9SBarry Smith           if (is == ADD_VALUES) ap[i] += value;
18617ab2063SBarry Smith           else                  ap[i] = value;
18717ab2063SBarry Smith           goto noinsert;
18817ab2063SBarry Smith         }
18917ab2063SBarry Smith       }
190c2653b3dSLois Curfman McInnes       if (nonew == 1) goto noinsert;
191a8c6a408SBarry Smith       else if (nonew == -1) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Inserting a new nonzero in the matrix");
19217ab2063SBarry Smith       if (nrow >= rmax) {
19317ab2063SBarry Smith         /* there is no extra room in row, therefore enlarge */
194416022c9SBarry Smith         int    new_nz = ai[a->m] + CHUNKSIZE,len,*new_i,*new_j;
19517ab2063SBarry Smith         Scalar *new_a;
19617ab2063SBarry Smith 
197a8c6a408SBarry Smith         if (nonew == -2) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Inserting a new nonzero in the matrix");
19896854ed6SLois Curfman McInnes 
19917ab2063SBarry Smith         /* malloc new storage space */
200416022c9SBarry Smith         len     = new_nz*(sizeof(int)+sizeof(Scalar))+(a->m+1)*sizeof(int);
2010452661fSBarry Smith         new_a   = (Scalar *) PetscMalloc( len );CHKPTRQ(new_a);
20217ab2063SBarry Smith         new_j   = (int *) (new_a + new_nz);
20317ab2063SBarry Smith         new_i   = new_j + new_nz;
20417ab2063SBarry Smith 
20517ab2063SBarry Smith         /* copy over old data into new slots */
20617ab2063SBarry Smith         for ( ii=0; ii<row+1; ii++ ) {new_i[ii] = ai[ii];}
207416022c9SBarry Smith         for ( ii=row+1; ii<a->m+1; ii++ ) {new_i[ii] = ai[ii]+CHUNKSIZE;}
208549d3d68SSatish Balay         ierr = PetscMemcpy(new_j,aj,(ai[row]+nrow+shift)*sizeof(int));CHKERRQ(ierr);
209416022c9SBarry Smith         len  = (new_nz - CHUNKSIZE - ai[row] - nrow - shift);
210549d3d68SSatish Balay         ierr = PetscMemcpy(new_j+ai[row]+shift+nrow+CHUNKSIZE,aj+ai[row]+shift+nrow,len*sizeof(int));CHKERRQ(ierr);
211549d3d68SSatish Balay         ierr = PetscMemcpy(new_a,aa,(ai[row]+nrow+shift)*sizeof(Scalar));CHKERRQ(ierr);
212549d3d68SSatish Balay         ierr = PetscMemcpy(new_a+ai[row]+shift+nrow+CHUNKSIZE,aa+ai[row]+shift+nrow,len*sizeof(Scalar));CHKERRQ(ierr);
21317ab2063SBarry Smith         /* free up old matrix storage */
214606d414cSSatish Balay         ierr = PetscFree(a->a);CHKERRQ(ierr);
215606d414cSSatish Balay         if (!a->singlemalloc) {
216606d414cSSatish Balay           ierr = PetscFree(a->i);CHKERRQ(ierr);
217606d414cSSatish Balay           ierr = PetscFree(a->j);CHKERRQ(ierr);
218606d414cSSatish Balay         }
219416022c9SBarry Smith         aa = a->a = new_a; ai = a->i = new_i; aj = a->j = new_j;
220*f1e2ffcdSBarry Smith         a->singlemalloc = PETSC_TRUE;
22117ab2063SBarry Smith 
22217ab2063SBarry Smith         rp   = aj + ai[row] + shift; ap = aa + ai[row] + shift;
223416022c9SBarry Smith         rmax = imax[row] = imax[row] + CHUNKSIZE;
224416022c9SBarry Smith         PLogObjectMemory(A,CHUNKSIZE*(sizeof(int) + sizeof(Scalar)));
225416022c9SBarry Smith         a->maxnz += CHUNKSIZE;
226b810aeb4SBarry Smith         a->reallocs++;
22717ab2063SBarry Smith       }
228416022c9SBarry Smith       N = nrow++ - 1; a->nz++;
229416022c9SBarry Smith       /* shift up all the later entries in this row */
230416022c9SBarry Smith       for ( ii=N; ii>=i; ii-- ) {
23117ab2063SBarry Smith         rp[ii+1] = rp[ii];
23217ab2063SBarry Smith         ap[ii+1] = ap[ii];
23317ab2063SBarry Smith       }
23417ab2063SBarry Smith       rp[i] = col;
23517ab2063SBarry Smith       ap[i] = value;
23617ab2063SBarry Smith       noinsert:;
237416022c9SBarry Smith       low = i + 1;
23817ab2063SBarry Smith     }
23917ab2063SBarry Smith     ailen[row] = nrow;
24017ab2063SBarry Smith   }
2413a40ed3dSBarry Smith   PetscFunctionReturn(0);
24217ab2063SBarry Smith }
24317ab2063SBarry Smith 
2445615d1e5SSatish Balay #undef __FUNC__
2455615d1e5SSatish Balay #define __FUNC__ "MatGetValues_SeqAIJ"
2468f6be9afSLois Curfman McInnes int MatGetValues_SeqAIJ(Mat A,int m,int *im,int n,int *in,Scalar *v)
2477eb43aa7SLois Curfman McInnes {
2487eb43aa7SLois Curfman McInnes   Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data;
249b49de8d1SLois Curfman McInnes   int        *rp, k, low, high, t, row, nrow, i, col, l, *aj = a->j;
2507eb43aa7SLois Curfman McInnes   int        *ai = a->i, *ailen = a->ilen, shift = a->indexshift;
2517eb43aa7SLois Curfman McInnes   Scalar     *ap, *aa = a->a, zero = 0.0;
2527eb43aa7SLois Curfman McInnes 
2533a40ed3dSBarry Smith   PetscFunctionBegin;
2547eb43aa7SLois Curfman McInnes   for ( k=0; k<m; k++ ) { /* loop over rows */
2557eb43aa7SLois Curfman McInnes     row  = im[k];
256a8c6a408SBarry Smith     if (row < 0) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Negative row");
257a8c6a408SBarry Smith     if (row >= a->m) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Row too large");
2587eb43aa7SLois Curfman McInnes     rp   = aj + ai[row] + shift; ap = aa + ai[row] + shift;
2597eb43aa7SLois Curfman McInnes     nrow = ailen[row];
2607eb43aa7SLois Curfman McInnes     for ( l=0; l<n; l++ ) { /* loop over columns */
261a8c6a408SBarry Smith       if (in[l] < 0) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Negative column");
262a8c6a408SBarry Smith       if (in[l] >= a->n) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Column too large");
2637eb43aa7SLois Curfman McInnes       col = in[l] - shift;
2647eb43aa7SLois Curfman McInnes       high = nrow; low = 0; /* assume unsorted */
2657eb43aa7SLois Curfman McInnes       while (high-low > 5) {
2667eb43aa7SLois Curfman McInnes         t = (low+high)/2;
2677eb43aa7SLois Curfman McInnes         if (rp[t] > col) high = t;
2687eb43aa7SLois Curfman McInnes         else             low  = t;
2697eb43aa7SLois Curfman McInnes       }
2707eb43aa7SLois Curfman McInnes       for ( i=low; i<high; i++ ) {
2717eb43aa7SLois Curfman McInnes         if (rp[i] > col) break;
2727eb43aa7SLois Curfman McInnes         if (rp[i] == col) {
273b49de8d1SLois Curfman McInnes           *v++ = ap[i];
2747eb43aa7SLois Curfman McInnes           goto finished;
2757eb43aa7SLois Curfman McInnes         }
2767eb43aa7SLois Curfman McInnes       }
277b49de8d1SLois Curfman McInnes       *v++ = zero;
2787eb43aa7SLois Curfman McInnes       finished:;
2797eb43aa7SLois Curfman McInnes     }
2807eb43aa7SLois Curfman McInnes   }
2813a40ed3dSBarry Smith   PetscFunctionReturn(0);
2827eb43aa7SLois Curfman McInnes }
2837eb43aa7SLois Curfman McInnes 
28417ab2063SBarry Smith 
2855615d1e5SSatish Balay #undef __FUNC__
2865615d1e5SSatish Balay #define __FUNC__ "MatView_SeqAIJ_Binary"
287480ef9eaSBarry Smith int MatView_SeqAIJ_Binary(Mat A,Viewer viewer)
28817ab2063SBarry Smith {
289416022c9SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data;
290416022c9SBarry Smith   int        i, fd, *col_lens, ierr;
29117ab2063SBarry Smith 
2923a40ed3dSBarry Smith   PetscFunctionBegin;
29390ace30eSBarry Smith   ierr = ViewerBinaryGetDescriptor(viewer,&fd);CHKERRQ(ierr);
2940452661fSBarry Smith   col_lens = (int *) PetscMalloc( (4+a->m)*sizeof(int) );CHKPTRQ(col_lens);
295416022c9SBarry Smith   col_lens[0] = MAT_COOKIE;
296416022c9SBarry Smith   col_lens[1] = a->m;
297416022c9SBarry Smith   col_lens[2] = a->n;
298416022c9SBarry Smith   col_lens[3] = a->nz;
299416022c9SBarry Smith 
300416022c9SBarry Smith   /* store lengths of each row and write (including header) to file */
301416022c9SBarry Smith   for ( i=0; i<a->m; i++ ) {
302416022c9SBarry Smith     col_lens[4+i] = a->i[i+1] - a->i[i];
30317ab2063SBarry Smith   }
3040752156aSBarry Smith   ierr = PetscBinaryWrite(fd,col_lens,4+a->m,PETSC_INT,1);CHKERRQ(ierr);
305606d414cSSatish Balay   ierr = PetscFree(col_lens);CHKERRQ(ierr);
306416022c9SBarry Smith 
307416022c9SBarry Smith   /* store column indices (zero start index) */
308416022c9SBarry Smith   if (a->indexshift) {
309416022c9SBarry Smith     for ( i=0; i<a->nz; i++ ) a->j[i]--;
31017ab2063SBarry Smith   }
3110752156aSBarry Smith   ierr = PetscBinaryWrite(fd,a->j,a->nz,PETSC_INT,0);CHKERRQ(ierr);
312416022c9SBarry Smith   if (a->indexshift) {
313416022c9SBarry Smith     for ( i=0; i<a->nz; i++ ) a->j[i]++;
31417ab2063SBarry Smith   }
315416022c9SBarry Smith 
316416022c9SBarry Smith   /* store nonzero values */
3170752156aSBarry Smith   ierr = PetscBinaryWrite(fd,a->a,a->nz,PETSC_SCALAR,0);CHKERRQ(ierr);
3183a40ed3dSBarry Smith   PetscFunctionReturn(0);
31917ab2063SBarry Smith }
320416022c9SBarry Smith 
3215615d1e5SSatish Balay #undef __FUNC__
3225615d1e5SSatish Balay #define __FUNC__ "MatView_SeqAIJ_ASCII"
323480ef9eaSBarry Smith int MatView_SeqAIJ_ASCII(Mat A,Viewer viewer)
324416022c9SBarry Smith {
325416022c9SBarry Smith   Mat_SeqAIJ  *a = (Mat_SeqAIJ *) A->data;
3266831982aSBarry Smith   int         ierr, i,j, m = a->m, shift = a->indexshift, format;
32717ab2063SBarry Smith   char        *outputname;
32817ab2063SBarry Smith 
3293a40ed3dSBarry Smith   PetscFunctionBegin;
330fb4b0f7fSBarry Smith   ierr = ViewerGetOutputname(viewer,&outputname);CHKERRQ(ierr);
331888f2ed8SSatish Balay   ierr = ViewerGetFormat(viewer,&format);CHKERRQ(ierr);
3326831982aSBarry Smith   if (format == VIEWER_FORMAT_ASCII_INFO_LONG || format == VIEWER_FORMAT_ASCII_INFO) {
3336831982aSBarry Smith     if (a->inode.size) {
3346831982aSBarry 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);
3356831982aSBarry Smith     } else {
3366831982aSBarry Smith       ierr = ViewerASCIIPrintf(viewer,"not using I-node routines\n");CHKERRQ(ierr);
3376831982aSBarry Smith     }
3383a40ed3dSBarry Smith   } else if (format == VIEWER_FORMAT_ASCII_MATLAB) {
339d00d2cf4SBarry Smith     int nofinalvalue = 0;
340d00d2cf4SBarry Smith     if ((a->i[m] == a->i[m-1]) || (a->j[a->nz-1] != a->n-!shift)) {
341d00d2cf4SBarry Smith       nofinalvalue = 1;
342d00d2cf4SBarry Smith     }
3436831982aSBarry Smith     ierr = ViewerASCIIUseTabs(viewer,PETSC_NO);CHKERRQ(ierr);
3446831982aSBarry Smith     ierr = ViewerASCIIPrintf(viewer,"%% Size = %d %d \n",m,a->n);CHKERRQ(ierr);
3456831982aSBarry Smith     ierr = ViewerASCIIPrintf(viewer,"%% Nonzeros = %d \n",a->nz);CHKERRQ(ierr);
3466831982aSBarry Smith     ierr = ViewerASCIIPrintf(viewer,"zzz = zeros(%d,3);\n",a->nz+nofinalvalue);CHKERRQ(ierr);
3476831982aSBarry Smith     ierr = ViewerASCIIPrintf(viewer,"zzz = [\n");CHKERRQ(ierr);
34817ab2063SBarry Smith 
34917ab2063SBarry Smith     for (i=0; i<m; i++) {
350416022c9SBarry Smith       for ( j=a->i[i]+shift; j<a->i[i+1]+shift; j++ ) {
351aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
3526831982aSBarry 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);
35317ab2063SBarry Smith #else
3546831982aSBarry Smith         ierr = ViewerASCIIPrintf(viewer,"%d %d  %18.16e\n", i+1, a->j[j]+!shift, a->a[j]);CHKERRQ(ierr);
35517ab2063SBarry Smith #endif
35617ab2063SBarry Smith       }
35717ab2063SBarry Smith     }
358d00d2cf4SBarry Smith     if (nofinalvalue) {
3596831982aSBarry Smith       ierr = ViewerASCIIPrintf(viewer,"%d %d  %18.16e\n", m, a->n, 0.0);CHKERRQ(ierr);
360d00d2cf4SBarry Smith     }
3616831982aSBarry Smith     if (outputname) {ierr = ViewerASCIIPrintf(viewer,"];\n %s = spconvert(zzz);\n",outputname);CHKERRQ(ierr);}
3626831982aSBarry Smith     else            {ierr = ViewerASCIIPrintf(viewer,"];\n M = spconvert(zzz);\n");CHKERRQ(ierr);}
3636831982aSBarry Smith     ierr = ViewerASCIIUseTabs(viewer,PETSC_YES);CHKERRQ(ierr);
3643a40ed3dSBarry Smith   } else if (format == VIEWER_FORMAT_ASCII_COMMON) {
3656831982aSBarry Smith     ierr = ViewerASCIIUseTabs(viewer,PETSC_NO);CHKERRQ(ierr);
36644cd7ae7SLois Curfman McInnes     for ( i=0; i<m; i++ ) {
3676831982aSBarry Smith       ierr = ViewerASCIIPrintf(viewer,"row %d:",i);CHKERRQ(ierr);
36844cd7ae7SLois Curfman McInnes       for ( j=a->i[i]+shift; j<a->i[i+1]+shift; j++ ) {
369aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
3706831982aSBarry Smith         if (PetscImaginary(a->a[j]) > 0.0 && PetscReal(a->a[j]) != 0.0) {
3716831982aSBarry Smith           ierr = ViewerASCIIPrintf(viewer," %d %g + %g i",a->j[j]+shift,PetscReal(a->a[j]),PetscImaginary(a->a[j]));CHKERRQ(ierr);
3726831982aSBarry Smith         } else if (PetscImaginary(a->a[j]) < 0.0 && PetscReal(a->a[j]) != 0.0) {
3736831982aSBarry Smith           ierr = ViewerASCIIPrintf(viewer," %d %g - %g i",a->j[j]+shift,PetscReal(a->a[j]),-PetscImaginary(a->a[j]));CHKERRQ(ierr);
3746831982aSBarry Smith         } else if (PetscReal(a->a[j]) != 0.0) {
3756831982aSBarry Smith           ierr = ViewerASCIIPrintf(viewer," %d %g ",a->j[j]+shift,PetscReal(a->a[j]));CHKERRQ(ierr);
3766831982aSBarry Smith         }
37744cd7ae7SLois Curfman McInnes #else
3786831982aSBarry Smith         if (a->a[j] != 0.0) {ierr = ViewerASCIIPrintf(viewer," %d %g ",a->j[j]+shift,a->a[j]);CHKERRQ(ierr);}
37944cd7ae7SLois Curfman McInnes #endif
38044cd7ae7SLois Curfman McInnes       }
3816831982aSBarry Smith       ierr = ViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
38244cd7ae7SLois Curfman McInnes     }
3836831982aSBarry Smith     ierr = ViewerASCIIUseTabs(viewer,PETSC_YES);CHKERRQ(ierr);
38402594712SBarry Smith   } else if (format == VIEWER_FORMAT_ASCII_SYMMODU) {
385496be53dSLois Curfman McInnes     int nzd=0, fshift=1, *sptr;
3866831982aSBarry Smith     ierr = ViewerASCIIUseTabs(viewer,PETSC_NO);CHKERRQ(ierr);
3872e44a96cSLois Curfman McInnes     sptr = (int *) PetscMalloc( (m+1)*sizeof(int) );CHKPTRQ(sptr);
388496be53dSLois Curfman McInnes     for ( i=0; i<m; i++ ) {
389496be53dSLois Curfman McInnes       sptr[i] = nzd+1;
390496be53dSLois Curfman McInnes       for ( j=a->i[i]+shift; j<a->i[i+1]+shift; j++ ) {
391496be53dSLois Curfman McInnes         if (a->j[j] >= i) {
392aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
393e20fef11SSatish Balay           if (PetscImaginary(a->a[j]) != 0.0 || PetscReal(a->a[j]) != 0.0) nzd++;
394496be53dSLois Curfman McInnes #else
395496be53dSLois Curfman McInnes           if (a->a[j] != 0.0) nzd++;
396496be53dSLois Curfman McInnes #endif
397496be53dSLois Curfman McInnes         }
398496be53dSLois Curfman McInnes       }
399496be53dSLois Curfman McInnes     }
4002e44a96cSLois Curfman McInnes     sptr[m] = nzd+1;
4016831982aSBarry Smith     ierr = ViewerASCIIPrintf(viewer," %d %d\n\n",m,nzd);CHKERRQ(ierr);
4022e44a96cSLois Curfman McInnes     for ( i=0; i<m+1; i+=6 ) {
4036831982aSBarry 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);}
4046831982aSBarry 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);}
4056831982aSBarry 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);}
4066831982aSBarry Smith       else if (i+1<m) {ierr = ViewerASCIIPrintf(viewer," %d %d %d\n",sptr[i],sptr[i+1],sptr[i+2]);CHKERRQ(ierr);}
4076831982aSBarry Smith       else if (i<m)   {ierr = ViewerASCIIPrintf(viewer," %d %d\n",sptr[i],sptr[i+1]);CHKERRQ(ierr);}
4086831982aSBarry Smith       else            {ierr = ViewerASCIIPrintf(viewer," %d\n",sptr[i]);CHKERRQ(ierr);}
409496be53dSLois Curfman McInnes     }
4106831982aSBarry Smith     ierr = ViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
411606d414cSSatish Balay     ierr = PetscFree(sptr);CHKERRQ(ierr);
412496be53dSLois Curfman McInnes     for ( i=0; i<m; i++ ) {
413496be53dSLois Curfman McInnes       for ( j=a->i[i]+shift; j<a->i[i+1]+shift; j++ ) {
4146831982aSBarry Smith         if (a->j[j] >= i) {ierr = ViewerASCIIPrintf(viewer," %d ",a->j[j]+fshift);CHKERRQ(ierr);}
415496be53dSLois Curfman McInnes       }
4166831982aSBarry Smith       ierr = ViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
417496be53dSLois Curfman McInnes     }
4186831982aSBarry Smith     ierr = ViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
419496be53dSLois Curfman McInnes     for ( i=0; i<m; i++ ) {
420496be53dSLois Curfman McInnes       for ( j=a->i[i]+shift; j<a->i[i+1]+shift; j++ ) {
421496be53dSLois Curfman McInnes         if (a->j[j] >= i) {
422aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
4236831982aSBarry Smith           if (PetscImaginary(a->a[j]) != 0.0 || PetscReal(a->a[j]) != 0.0) {
4246831982aSBarry Smith             ierr = ViewerASCIIPrintf(viewer," %18.16e %18.16e ",PetscReal(a->a[j]),PetscImaginary(a->a[j]));CHKERRQ(ierr);
4256831982aSBarry Smith           }
426496be53dSLois Curfman McInnes #else
4276831982aSBarry Smith           if (a->a[j] != 0.0) {ierr = ViewerASCIIPrintf(viewer," %18.16e ",a->a[j]);CHKERRQ(ierr);}
428496be53dSLois Curfman McInnes #endif
429496be53dSLois Curfman McInnes         }
430496be53dSLois Curfman McInnes       }
4316831982aSBarry Smith       ierr = ViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
432496be53dSLois Curfman McInnes     }
4336831982aSBarry Smith     ierr = ViewerASCIIUseTabs(viewer,PETSC_YES);CHKERRQ(ierr);
43402594712SBarry Smith   } else if (format == VIEWER_FORMAT_ASCII_DENSE) {
43502594712SBarry Smith     int    cnt = 0,jcnt;
43602594712SBarry Smith     Scalar value;
43702594712SBarry Smith 
4386831982aSBarry Smith     ierr = ViewerASCIIUseTabs(viewer,PETSC_NO);CHKERRQ(ierr);
43902594712SBarry Smith     for ( i=0; i<m; i++ ) {
44002594712SBarry Smith       jcnt = 0;
44102594712SBarry Smith       for ( j=0; j<a->n; j++ ) {
442e24b481bSBarry Smith         if ( jcnt < a->i[i+1]-a->i[i] && j == a->j[cnt]) {
44302594712SBarry Smith           value = a->a[cnt++];
444e24b481bSBarry Smith           jcnt++;
44502594712SBarry Smith         } else {
44602594712SBarry Smith           value = 0.0;
44702594712SBarry Smith         }
448aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
4496831982aSBarry Smith         ierr = ViewerASCIIPrintf(viewer," %7.5e+%7.5e i ",PetscReal(value),PetscImaginary(value));CHKERRQ(ierr);
45002594712SBarry Smith #else
4516831982aSBarry Smith         ierr = ViewerASCIIPrintf(viewer," %7.5e ",value);CHKERRQ(ierr);
45202594712SBarry Smith #endif
45302594712SBarry Smith       }
4546831982aSBarry Smith       ierr = ViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
45502594712SBarry Smith     }
4566831982aSBarry Smith     ierr = ViewerASCIIUseTabs(viewer,PETSC_YES);CHKERRQ(ierr);
4573a40ed3dSBarry Smith   } else {
4586831982aSBarry Smith     ierr = ViewerASCIIUseTabs(viewer,PETSC_NO);CHKERRQ(ierr);
45917ab2063SBarry Smith     for ( i=0; i<m; i++ ) {
4606831982aSBarry Smith       ierr = ViewerASCIIPrintf(viewer,"row %d:",i);CHKERRQ(ierr);
461416022c9SBarry Smith       for ( j=a->i[i]+shift; j<a->i[i+1]+shift; j++ ) {
462aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
463e20fef11SSatish Balay         if (PetscImaginary(a->a[j]) > 0.0) {
4646831982aSBarry Smith           ierr = ViewerASCIIPrintf(viewer," %d %g + %g i",a->j[j]+shift,PetscReal(a->a[j]),PetscImaginary(a->a[j]));CHKERRQ(ierr);
465e20fef11SSatish Balay         } else if (PetscImaginary(a->a[j]) < 0.0) {
4666831982aSBarry Smith           ierr = ViewerASCIIPrintf(viewer," %d %g - %g i",a->j[j]+shift,PetscReal(a->a[j]),-PetscImaginary(a->a[j]));CHKERRQ(ierr);
4673a40ed3dSBarry Smith         } else {
4686831982aSBarry Smith           ierr = ViewerASCIIPrintf(viewer," %d %g ",a->j[j]+shift,PetscReal(a->a[j]));CHKERRQ(ierr);
46917ab2063SBarry Smith         }
47017ab2063SBarry Smith #else
4716831982aSBarry Smith         ierr = ViewerASCIIPrintf(viewer," %d %g ",a->j[j]+shift,a->a[j]);CHKERRQ(ierr);
47217ab2063SBarry Smith #endif
47317ab2063SBarry Smith       }
4746831982aSBarry Smith       ierr = ViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
47517ab2063SBarry Smith     }
4766831982aSBarry Smith     ierr = ViewerASCIIUseTabs(viewer,PETSC_YES);CHKERRQ(ierr);
47717ab2063SBarry Smith   }
4786831982aSBarry Smith   ierr = ViewerFlush(viewer);CHKERRQ(ierr);
4793a40ed3dSBarry Smith   PetscFunctionReturn(0);
480416022c9SBarry Smith }
481416022c9SBarry Smith 
4825615d1e5SSatish Balay #undef __FUNC__
483480ef9eaSBarry Smith #define __FUNC__ "MatView_SeqAIJ_Draw_Zoom"
484480ef9eaSBarry Smith int MatView_SeqAIJ_Draw_Zoom(Draw draw,void *Aa)
485416022c9SBarry Smith {
486480ef9eaSBarry Smith   Mat         A = (Mat) Aa;
487416022c9SBarry Smith   Mat_SeqAIJ  *a = (Mat_SeqAIJ *) A->data;
48877ed5343SBarry Smith   int         ierr, i,j, m = a->m, shift = a->indexshift,color,rank;
4890513a670SBarry Smith   int         format;
490480ef9eaSBarry Smith   double      xl,yl,xr,yr,x_l,x_r,y_l,y_r,maxv = 0.0;
491480ef9eaSBarry Smith   Viewer      viewer;
49277ed5343SBarry Smith   MPI_Comm    comm;
493cddf8d76SBarry Smith 
4943a40ed3dSBarry Smith   PetscFunctionBegin;
49577ed5343SBarry Smith   /*
49677ed5343SBarry Smith       This is nasty. If this is called from an originally parallel matrix
49777ed5343SBarry Smith    then all processes call this, but only the first has the matrix so the
49877ed5343SBarry Smith    rest should return immediately.
49977ed5343SBarry Smith   */
50077ed5343SBarry Smith   ierr = PetscObjectGetComm((PetscObject)draw,&comm);CHKERRQ(ierr);
501d132466eSBarry Smith   ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr);
50277ed5343SBarry Smith   if (rank) PetscFunctionReturn(0);
50377ed5343SBarry Smith 
504480ef9eaSBarry Smith   ierr = PetscObjectQuery((PetscObject)A,"Zoomviewer",(PetscObject*) &viewer);CHKERRQ(ierr);
5050513a670SBarry Smith   ierr = ViewerGetFormat(viewer,&format);CHKERRQ(ierr);
50619bcc07fSBarry Smith 
507480ef9eaSBarry Smith   ierr = DrawGetCoordinates(draw,&xl,&yl,&xr,&yr);CHKERRQ(ierr);
508416022c9SBarry Smith   /* loop over matrix elements drawing boxes */
5090513a670SBarry Smith 
5100513a670SBarry Smith   if (format != VIEWER_FORMAT_DRAW_CONTOUR) {
5110513a670SBarry Smith     /* Blue for negative, Cyan for zero and  Red for positive */
512cddf8d76SBarry Smith     color = DRAW_BLUE;
513416022c9SBarry Smith     for ( i=0; i<m; i++ ) {
514cddf8d76SBarry Smith       y_l = m - i - 1.0; y_r = y_l + 1.0;
515416022c9SBarry Smith       for ( j=a->i[i]+shift; j<a->i[i+1]+shift; j++ ) {
516cddf8d76SBarry Smith         x_l = a->j[j] + shift; x_r = x_l + 1.0;
517aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
518e20fef11SSatish Balay         if (PetscReal(a->a[j]) >=  0.) continue;
519cddf8d76SBarry Smith #else
520cddf8d76SBarry Smith         if (a->a[j] >=  0.) continue;
521cddf8d76SBarry Smith #endif
522480ef9eaSBarry Smith         ierr = DrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr);
523cddf8d76SBarry Smith       }
524cddf8d76SBarry Smith     }
525cddf8d76SBarry Smith     color = DRAW_CYAN;
526cddf8d76SBarry Smith     for ( i=0; i<m; i++ ) {
527cddf8d76SBarry Smith       y_l = m - i - 1.0; y_r = y_l + 1.0;
528cddf8d76SBarry Smith       for ( j=a->i[i]+shift; j<a->i[i+1]+shift; j++ ) {
529cddf8d76SBarry Smith         x_l = a->j[j] + shift; x_r = x_l + 1.0;
530cddf8d76SBarry Smith         if (a->a[j] !=  0.) continue;
531480ef9eaSBarry Smith         ierr = DrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr);
532cddf8d76SBarry Smith       }
533cddf8d76SBarry Smith     }
534cddf8d76SBarry Smith     color = DRAW_RED;
535cddf8d76SBarry Smith     for ( i=0; i<m; i++ ) {
536cddf8d76SBarry Smith       y_l = m - i - 1.0; y_r = y_l + 1.0;
537cddf8d76SBarry Smith       for ( j=a->i[i]+shift; j<a->i[i+1]+shift; j++ ) {
538cddf8d76SBarry Smith         x_l = a->j[j] + shift; x_r = x_l + 1.0;
539aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
540e20fef11SSatish Balay         if (PetscReal(a->a[j]) <=  0.) continue;
541cddf8d76SBarry Smith #else
542cddf8d76SBarry Smith         if (a->a[j] <=  0.) continue;
543cddf8d76SBarry Smith #endif
544480ef9eaSBarry Smith         ierr = DrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr);
545416022c9SBarry Smith       }
546416022c9SBarry Smith     }
5470513a670SBarry Smith   } else {
5480513a670SBarry Smith     /* use contour shading to indicate magnitude of values */
5490513a670SBarry Smith     /* first determine max of all nonzero values */
5500513a670SBarry Smith     int    nz = a->nz,count;
5510513a670SBarry Smith     Draw   popup;
552480ef9eaSBarry Smith     double scale;
5530513a670SBarry Smith 
5540513a670SBarry Smith     for ( i=0; i<nz; i++ ) {
5550513a670SBarry Smith       if (PetscAbsScalar(a->a[i]) > maxv) maxv = PetscAbsScalar(a->a[i]);
5560513a670SBarry Smith     }
557480ef9eaSBarry Smith     scale = (245.0 - DRAW_BASIC_COLORS)/maxv;
558522c5e43SBarry Smith     ierr  = DrawGetPopup(draw,&popup);CHKERRQ(ierr);
559*f1e2ffcdSBarry Smith     if (popup) {ierr  = DrawScalePopup(popup,0.0,maxv);CHKERRQ(ierr);}
5600513a670SBarry Smith     count = 0;
5610513a670SBarry Smith     for ( i=0; i<m; i++ ) {
5620513a670SBarry Smith       y_l = m - i - 1.0; y_r = y_l + 1.0;
5630513a670SBarry Smith       for ( j=a->i[i]+shift; j<a->i[i+1]+shift; j++ ) {
5640513a670SBarry Smith         x_l = a->j[j] + shift; x_r = x_l + 1.0;
5656d6b6c30SSatish Balay         color = DRAW_BASIC_COLORS + (int)(scale*PetscAbsScalar(a->a[count]));
566480ef9eaSBarry Smith         ierr  = DrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr);
5670513a670SBarry Smith         count++;
5680513a670SBarry Smith       }
5690513a670SBarry Smith     }
5700513a670SBarry Smith   }
571480ef9eaSBarry Smith   PetscFunctionReturn(0);
572480ef9eaSBarry Smith }
573cddf8d76SBarry Smith 
574480ef9eaSBarry Smith #undef __FUNC__
575480ef9eaSBarry Smith #define __FUNC__ "MatView_SeqAIJ_Draw"
576480ef9eaSBarry Smith int MatView_SeqAIJ_Draw(Mat A,Viewer viewer)
577480ef9eaSBarry Smith {
578480ef9eaSBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*) A->data;
579480ef9eaSBarry Smith   int        ierr;
580480ef9eaSBarry Smith   Draw       draw;
581480ef9eaSBarry Smith   double     xr,yr,xl,yl,h,w;
582480ef9eaSBarry Smith   PetscTruth isnull;
583480ef9eaSBarry Smith 
584480ef9eaSBarry Smith   PetscFunctionBegin;
58577ed5343SBarry Smith   ierr = ViewerDrawGetDraw(viewer,0,&draw);CHKERRQ(ierr);
586480ef9eaSBarry Smith   ierr = DrawIsNull(draw,&isnull);CHKERRQ(ierr);
587480ef9eaSBarry Smith   if (isnull) PetscFunctionReturn(0);
588480ef9eaSBarry Smith 
589480ef9eaSBarry Smith   ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",(PetscObject)viewer);CHKERRQ(ierr);
590480ef9eaSBarry Smith   xr  = a->n; yr = a->m; h = yr/10.0; w = xr/10.0;
591480ef9eaSBarry Smith   xr += w;    yr += h;  xl = -w;     yl = -h;
592cddf8d76SBarry Smith   ierr = DrawSetCoordinates(draw,xl,yl,xr,yr);CHKERRQ(ierr);
593480ef9eaSBarry Smith   ierr = DrawZoom(draw,MatView_SeqAIJ_Draw_Zoom,A);CHKERRQ(ierr);
594480ef9eaSBarry Smith   ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",PETSC_NULL);CHKERRQ(ierr);
5953a40ed3dSBarry Smith   PetscFunctionReturn(0);
596416022c9SBarry Smith }
597416022c9SBarry Smith 
5985615d1e5SSatish Balay #undef __FUNC__
599d4bb536fSBarry Smith #define __FUNC__ "MatView_SeqAIJ"
600e1311b90SBarry Smith int MatView_SeqAIJ(Mat A,Viewer viewer)
601416022c9SBarry Smith {
602416022c9SBarry Smith   Mat_SeqAIJ  *a = (Mat_SeqAIJ*) A->data;
603bcd2baecSBarry Smith   int         ierr;
6046831982aSBarry Smith   PetscTruth  issocket,isascii,isbinary,isdraw;
605416022c9SBarry Smith 
6063a40ed3dSBarry Smith   PetscFunctionBegin;
6076831982aSBarry Smith   ierr = PetscTypeCompare((PetscObject)viewer,SOCKET_VIEWER,&issocket);CHKERRQ(ierr);
6086831982aSBarry Smith   ierr = PetscTypeCompare((PetscObject)viewer,ASCII_VIEWER,&isascii);CHKERRQ(ierr);
6096831982aSBarry Smith   ierr = PetscTypeCompare((PetscObject)viewer,BINARY_VIEWER,&isbinary);CHKERRQ(ierr);
6106831982aSBarry Smith   ierr = PetscTypeCompare((PetscObject)viewer,DRAW_VIEWER,&isdraw);CHKERRQ(ierr);
6110f5bd95cSBarry Smith   if (issocket) {
6127b2a1423SBarry Smith     ierr = ViewerSocketPutSparse_Private(viewer,a->m,a->n,a->nz,a->a,a->i,a->j);CHKERRQ(ierr);
6130f5bd95cSBarry Smith   } else if (isascii) {
6143a40ed3dSBarry Smith     ierr = MatView_SeqAIJ_ASCII(A,viewer);CHKERRQ(ierr);
6150f5bd95cSBarry Smith   } else if (isbinary) {
6163a40ed3dSBarry Smith     ierr = MatView_SeqAIJ_Binary(A,viewer);CHKERRQ(ierr);
6170f5bd95cSBarry Smith   } else if (isdraw) {
6183a40ed3dSBarry Smith     ierr = MatView_SeqAIJ_Draw(A,viewer);CHKERRQ(ierr);
6195cd90555SBarry Smith   } else {
6200f5bd95cSBarry Smith     SETERRQ1(1,1,"Viewer type %s not supported by SeqAIJ matrices",((PetscObject)viewer)->type_name);
62117ab2063SBarry Smith   }
6223a40ed3dSBarry Smith   PetscFunctionReturn(0);
62317ab2063SBarry Smith }
62419bcc07fSBarry Smith 
625c456f294SBarry Smith extern int Mat_AIJ_CheckInode(Mat);
6265615d1e5SSatish Balay #undef __FUNC__
6275615d1e5SSatish Balay #define __FUNC__ "MatAssemblyEnd_SeqAIJ"
6288f6be9afSLois Curfman McInnes int MatAssemblyEnd_SeqAIJ(Mat A,MatAssemblyType mode)
62917ab2063SBarry Smith {
630416022c9SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data;
63141c01911SSatish Balay   int        fshift = 0,i,j,*ai = a->i, *aj = a->j, *imax = a->imax,ierr;
63243ee02c3SBarry Smith   int        m = a->m, *ip, N, *ailen = a->ilen,shift = a->indexshift,rmax = 0;
633416022c9SBarry Smith   Scalar     *aa = a->a, *ap;
63417ab2063SBarry Smith 
6353a40ed3dSBarry Smith   PetscFunctionBegin;
6363a40ed3dSBarry Smith   if (mode == MAT_FLUSH_ASSEMBLY) PetscFunctionReturn(0);
63717ab2063SBarry Smith 
63843ee02c3SBarry Smith   if (m) rmax = ailen[0]; /* determine row with most nonzeros */
63917ab2063SBarry Smith   for ( i=1; i<m; i++ ) {
640416022c9SBarry Smith     /* move each row back by the amount of empty slots (fshift) before it*/
64117ab2063SBarry Smith     fshift += imax[i-1] - ailen[i-1];
64294a9d846SBarry Smith     rmax   = PetscMax(rmax,ailen[i]);
64317ab2063SBarry Smith     if (fshift) {
6440f5bd95cSBarry Smith       ip = aj + ai[i] + shift;
6450f5bd95cSBarry Smith       ap = aa + ai[i] + shift;
64617ab2063SBarry Smith       N  = ailen[i];
64717ab2063SBarry Smith       for ( j=0; j<N; j++ ) {
64817ab2063SBarry Smith         ip[j-fshift] = ip[j];
64917ab2063SBarry Smith         ap[j-fshift] = ap[j];
65017ab2063SBarry Smith       }
65117ab2063SBarry Smith     }
65217ab2063SBarry Smith     ai[i] = ai[i-1] + ailen[i-1];
65317ab2063SBarry Smith   }
65417ab2063SBarry Smith   if (m) {
65517ab2063SBarry Smith     fshift += imax[m-1] - ailen[m-1];
65617ab2063SBarry Smith     ai[m]  = ai[m-1] + ailen[m-1];
65717ab2063SBarry Smith   }
65817ab2063SBarry Smith   /* reset ilen and imax for each row */
65917ab2063SBarry Smith   for ( i=0; i<m; i++ ) {
66017ab2063SBarry Smith     ailen[i] = imax[i] = ai[i+1] - ai[i];
66117ab2063SBarry Smith   }
662416022c9SBarry Smith   a->nz = ai[m] + shift;
66317ab2063SBarry Smith 
66417ab2063SBarry Smith   /* diagonals may have moved, so kill the diagonal pointers */
665416022c9SBarry Smith   if (fshift && a->diag) {
666606d414cSSatish Balay     ierr = PetscFree(a->diag);CHKERRQ(ierr);
667416022c9SBarry Smith     PLogObjectMemory(A,-(m+1)*sizeof(int));
668416022c9SBarry Smith     a->diag = 0;
66917ab2063SBarry Smith   }
670c38d4ed2SBarry Smith   PLogInfo(A,"MatAssemblyEnd_SeqAIJ:Matrix size: %d X %d; storage space: %d unneeded, %d used\n",m,a->n,fshift,a->nz);
671c38d4ed2SBarry Smith   PLogInfo(A,"MatAssemblyEnd_SeqAIJ:Number of mallocs during MatSetValues() is %d\n",a->reallocs);
67294a9d846SBarry Smith   PLogInfo(A,"MatAssemblyEnd_SeqAIJ:Most nonzeros in any row is %d\n",rmax);
673dd5f02e7SSatish Balay   a->reallocs          = 0;
6744e220ebcSLois Curfman McInnes   A->info.nz_unneeded  = (double)fshift;
6754e220ebcSLois Curfman McInnes 
67676dd722bSSatish Balay   /* check out for identical nodes. If found, use inode functions */
67741c01911SSatish Balay   ierr = Mat_AIJ_CheckInode(A);CHKERRQ(ierr);
6783a40ed3dSBarry Smith   PetscFunctionReturn(0);
67917ab2063SBarry Smith }
68017ab2063SBarry Smith 
6815615d1e5SSatish Balay #undef __FUNC__
6825615d1e5SSatish Balay #define __FUNC__ "MatZeroEntries_SeqAIJ"
6838f6be9afSLois Curfman McInnes int MatZeroEntries_SeqAIJ(Mat A)
68417ab2063SBarry Smith {
685416022c9SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data;
686549d3d68SSatish Balay   int        ierr;
6873a40ed3dSBarry Smith 
6883a40ed3dSBarry Smith   PetscFunctionBegin;
689549d3d68SSatish Balay   ierr = PetscMemzero(a->a,(a->i[a->m]+a->indexshift)*sizeof(Scalar));CHKERRQ(ierr);
6903a40ed3dSBarry Smith   PetscFunctionReturn(0);
69117ab2063SBarry Smith }
692416022c9SBarry Smith 
6935615d1e5SSatish Balay #undef __FUNC__
6945615d1e5SSatish Balay #define __FUNC__ "MatDestroy_SeqAIJ"
695e1311b90SBarry Smith int MatDestroy_SeqAIJ(Mat A)
69617ab2063SBarry Smith {
697416022c9SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data;
69882bf6240SBarry Smith   int        ierr;
699d5d45c9bSBarry Smith 
7003a40ed3dSBarry Smith   PetscFunctionBegin;
70194d884c6SBarry Smith 
70294d884c6SBarry Smith   if (A->mapping) {
70394d884c6SBarry Smith     ierr = ISLocalToGlobalMappingDestroy(A->mapping);CHKERRQ(ierr);
70494d884c6SBarry Smith   }
70594d884c6SBarry Smith   if (A->bmapping) {
70694d884c6SBarry Smith     ierr = ISLocalToGlobalMappingDestroy(A->bmapping);CHKERRQ(ierr);
70794d884c6SBarry Smith   }
70861b13de0SBarry Smith   if (A->rmap) {
70961b13de0SBarry Smith     ierr = MapDestroy(A->rmap);CHKERRQ(ierr);
71061b13de0SBarry Smith   }
71161b13de0SBarry Smith   if (A->cmap) {
71261b13de0SBarry Smith     ierr = MapDestroy(A->cmap);CHKERRQ(ierr);
71361b13de0SBarry Smith   }
714606d414cSSatish Balay   if (a->idiag) {ierr = PetscFree(a->idiag);CHKERRQ(ierr);}
715aa482453SBarry Smith #if defined(PETSC_USE_LOG)
716e1311b90SBarry Smith   PLogObjectState((PetscObject)A,"Rows=%d, Cols=%d, NZ=%d",a->m,a->n,a->nz);
71717ab2063SBarry Smith #endif
718606d414cSSatish Balay   ierr = PetscFree(a->a);CHKERRQ(ierr);
719606d414cSSatish Balay   if (!a->singlemalloc) {
720606d414cSSatish Balay     ierr = PetscFree(a->i);CHKERRQ(ierr);
721606d414cSSatish Balay     ierr = PetscFree(a->j);CHKERRQ(ierr);
722606d414cSSatish Balay   }
723c38d4ed2SBarry Smith   if (a->row) {
724c38d4ed2SBarry Smith     ierr = ISDestroy(a->row);CHKERRQ(ierr);
725c38d4ed2SBarry Smith   }
726c38d4ed2SBarry Smith   if (a->col) {
727c38d4ed2SBarry Smith     ierr = ISDestroy(a->col);CHKERRQ(ierr);
728c38d4ed2SBarry Smith   }
729606d414cSSatish Balay   if (a->diag) {ierr = PetscFree(a->diag);CHKERRQ(ierr);}
730606d414cSSatish Balay   if (a->ilen) {ierr = PetscFree(a->ilen);CHKERRQ(ierr);}
731606d414cSSatish Balay   if (a->imax) {ierr = PetscFree(a->imax);CHKERRQ(ierr);}
732606d414cSSatish Balay   if (a->solve_work) {ierr = PetscFree(a->solve_work);CHKERRQ(ierr);}
733606d414cSSatish Balay   if (a->inode.size) {ierr = PetscFree(a->inode.size);CHKERRQ(ierr);}
73482bf6240SBarry Smith   if (a->icol) {ierr = ISDestroy(a->icol);CHKERRQ(ierr);}
735606d414cSSatish Balay   if (a->saved_values) {ierr = PetscFree(a->saved_values);CHKERRQ(ierr);}
736606d414cSSatish Balay   ierr = PetscFree(a);CHKERRQ(ierr);
737eed86810SBarry Smith 
738f2655603SLois Curfman McInnes   PLogObjectDestroy(A);
739f2655603SLois Curfman McInnes   PetscHeaderDestroy(A);
7403a40ed3dSBarry Smith   PetscFunctionReturn(0);
74117ab2063SBarry Smith }
74217ab2063SBarry Smith 
7435615d1e5SSatish Balay #undef __FUNC__
7445615d1e5SSatish Balay #define __FUNC__ "MatCompress_SeqAIJ"
7458f6be9afSLois Curfman McInnes int MatCompress_SeqAIJ(Mat A)
74617ab2063SBarry Smith {
7473a40ed3dSBarry Smith   PetscFunctionBegin;
7483a40ed3dSBarry Smith   PetscFunctionReturn(0);
74917ab2063SBarry Smith }
75017ab2063SBarry Smith 
7515615d1e5SSatish Balay #undef __FUNC__
7525615d1e5SSatish Balay #define __FUNC__ "MatSetOption_SeqAIJ"
7538f6be9afSLois Curfman McInnes int MatSetOption_SeqAIJ(Mat A,MatOption op)
75417ab2063SBarry Smith {
755416022c9SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data;
7563a40ed3dSBarry Smith 
7573a40ed3dSBarry Smith   PetscFunctionBegin;
758*f1e2ffcdSBarry Smith   if      (op == MAT_ROW_ORIENTED)                 a->roworiented    = PETSC_TRUE;
759*f1e2ffcdSBarry Smith   else if (op == MAT_KEEP_ZEROED_ROWS)             a->keepzeroedrows = PETSC_TRUE;
760*f1e2ffcdSBarry Smith   else if (op == MAT_COLUMN_ORIENTED)              a->roworiented    = PETSC_FALSE;
761*f1e2ffcdSBarry Smith   else if (op == MAT_COLUMNS_SORTED)               a->sorted         = PETSC_TRUE;
762*f1e2ffcdSBarry Smith   else if (op == MAT_COLUMNS_UNSORTED)             a->sorted         = PETSC_FALSE;
7636d4a8577SBarry Smith   else if (op == MAT_NO_NEW_NONZERO_LOCATIONS)     a->nonew          = 1;
7644787f768SSatish Balay   else if (op == MAT_NEW_NONZERO_LOCATION_ERR)     a->nonew          = -1;
7654787f768SSatish Balay   else if (op == MAT_NEW_NONZERO_ALLOCATION_ERR)   a->nonew          = -2;
7666d4a8577SBarry Smith   else if (op == MAT_YES_NEW_NONZERO_LOCATIONS)    a->nonew          = 0;
7676d4a8577SBarry Smith   else if (op == MAT_ROWS_SORTED ||
768219d9a1aSLois Curfman McInnes            op == MAT_ROWS_UNSORTED ||
7696d4a8577SBarry Smith            op == MAT_SYMMETRIC ||
7706d4a8577SBarry Smith            op == MAT_STRUCTURALLY_SYMMETRIC ||
77190f02eecSBarry Smith            op == MAT_YES_NEW_DIAGONALS ||
772b51ba29fSSatish Balay            op == MAT_IGNORE_OFF_PROC_ENTRIES||
773b51ba29fSSatish Balay            op == MAT_USE_HASH_TABLE)
774981c4779SBarry Smith     PLogInfo(A,"MatSetOption_SeqAIJ:Option ignored\n");
7753a40ed3dSBarry Smith   else if (op == MAT_NO_NEW_DIAGONALS) {
7763a40ed3dSBarry Smith     SETERRQ(PETSC_ERR_SUP,0,"MAT_NO_NEW_DIAGONALS");
7773a40ed3dSBarry Smith   } else if (op == MAT_INODE_LIMIT_1)          a->inode.limit  = 1;
7786d4a8577SBarry Smith   else if (op == MAT_INODE_LIMIT_2)            a->inode.limit  = 2;
7796d4a8577SBarry Smith   else if (op == MAT_INODE_LIMIT_3)            a->inode.limit  = 3;
7806d4a8577SBarry Smith   else if (op == MAT_INODE_LIMIT_4)            a->inode.limit  = 4;
7816d4a8577SBarry Smith   else if (op == MAT_INODE_LIMIT_5)            a->inode.limit  = 5;
7823a40ed3dSBarry Smith   else SETERRQ(PETSC_ERR_SUP,0,"unknown option");
7833a40ed3dSBarry Smith   PetscFunctionReturn(0);
78417ab2063SBarry Smith }
78517ab2063SBarry Smith 
7865615d1e5SSatish Balay #undef __FUNC__
7875615d1e5SSatish Balay #define __FUNC__ "MatGetDiagonal_SeqAIJ"
7888f6be9afSLois Curfman McInnes int MatGetDiagonal_SeqAIJ(Mat A,Vec v)
78917ab2063SBarry Smith {
790416022c9SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data;
7913a40ed3dSBarry Smith   int        i,j, n,shift = a->indexshift,ierr;
79217ab2063SBarry Smith   Scalar     *x, zero = 0.0;
79317ab2063SBarry Smith 
7943a40ed3dSBarry Smith   PetscFunctionBegin;
7953a40ed3dSBarry Smith   ierr = VecSet(&zero,v);CHKERRQ(ierr);
796e1311b90SBarry Smith   ierr = VecGetArray(v,&x);;CHKERRQ(ierr);
797e1311b90SBarry Smith   ierr = VecGetLocalSize(v,&n);;CHKERRQ(ierr);
798a8c6a408SBarry Smith   if (n != a->m) SETERRQ(PETSC_ERR_ARG_SIZ,0,"Nonconforming matrix and vector");
799416022c9SBarry Smith   for ( i=0; i<a->m; i++ ) {
800416022c9SBarry Smith     for ( j=a->i[i]+shift; j<a->i[i+1]+shift; j++ ) {
801416022c9SBarry Smith       if (a->j[j]+shift == i) {
802416022c9SBarry Smith         x[i] = a->a[j];
80317ab2063SBarry Smith         break;
80417ab2063SBarry Smith       }
80517ab2063SBarry Smith     }
80617ab2063SBarry Smith   }
807e1311b90SBarry Smith   ierr = VecRestoreArray(v,&x);;CHKERRQ(ierr);
8083a40ed3dSBarry Smith   PetscFunctionReturn(0);
80917ab2063SBarry Smith }
81017ab2063SBarry Smith 
81117ab2063SBarry Smith /* -------------------------------------------------------*/
81217ab2063SBarry Smith /* Should check that shapes of vectors and matrices match */
81317ab2063SBarry Smith /* -------------------------------------------------------*/
8145615d1e5SSatish Balay #undef __FUNC__
8155615d1e5SSatish Balay #define __FUNC__ "MatMultTrans_SeqAIJ"
81644cd7ae7SLois Curfman McInnes int MatMultTrans_SeqAIJ(Mat A,Vec xx,Vec yy)
81717ab2063SBarry Smith {
818416022c9SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data;
819f1af5d2fSBarry Smith   Scalar     *x, *y, *v, alpha, zero = 0.0;
820e1311b90SBarry Smith   int        ierr,m = a->m, n, i, *idx, shift = a->indexshift;
82117ab2063SBarry Smith 
8223a40ed3dSBarry Smith   PetscFunctionBegin;
823f1af5d2fSBarry Smith   ierr = VecSet(&zero,yy);CHKERRQ(ierr);
824e1311b90SBarry Smith   ierr = VecGetArray(xx,&x);CHKERRQ(ierr);
825e1311b90SBarry Smith   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
82617ab2063SBarry Smith   y = y + shift; /* shift for Fortran start by 1 indexing */
82717ab2063SBarry Smith   for ( i=0; i<m; i++ ) {
828416022c9SBarry Smith     idx   = a->j + a->i[i] + shift;
829416022c9SBarry Smith     v     = a->a + a->i[i] + shift;
830416022c9SBarry Smith     n     = a->i[i+1] - a->i[i];
83117ab2063SBarry Smith     alpha = x[i];
83217ab2063SBarry Smith     while (n-->0) {y[*idx++] += alpha * *v++;}
83317ab2063SBarry Smith   }
834416022c9SBarry Smith   PLogFlops(2*a->nz - a->n);
835e1311b90SBarry Smith   ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr);
836e1311b90SBarry Smith   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
8373a40ed3dSBarry Smith   PetscFunctionReturn(0);
83817ab2063SBarry Smith }
839d5d45c9bSBarry Smith 
8405615d1e5SSatish Balay #undef __FUNC__
8415615d1e5SSatish Balay #define __FUNC__ "MatMultTransAdd_SeqAIJ"
84244cd7ae7SLois Curfman McInnes int MatMultTransAdd_SeqAIJ(Mat A,Vec xx,Vec zz,Vec yy)
84317ab2063SBarry Smith {
844416022c9SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data;
84517ab2063SBarry Smith   Scalar     *x, *y, *v, alpha;
846e1311b90SBarry Smith   int        ierr,m = a->m, n, i, *idx,shift = a->indexshift;
84717ab2063SBarry Smith 
8483a40ed3dSBarry Smith   PetscFunctionBegin;
8492e8a6d31SBarry Smith   if (zz != yy) {ierr = VecCopy(zz,yy);CHKERRQ(ierr);}
850e1311b90SBarry Smith   ierr = VecGetArray(xx,&x);CHKERRQ(ierr);
851e1311b90SBarry Smith   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
85217ab2063SBarry Smith   y = y + shift; /* shift for Fortran start by 1 indexing */
85317ab2063SBarry Smith   for ( i=0; i<m; i++ ) {
854416022c9SBarry Smith     idx   = a->j + a->i[i] + shift;
855416022c9SBarry Smith     v     = a->a + a->i[i] + shift;
856416022c9SBarry Smith     n     = a->i[i+1] - a->i[i];
85717ab2063SBarry Smith     alpha = x[i];
85817ab2063SBarry Smith     while (n-->0) {y[*idx++] += alpha * *v++;}
85917ab2063SBarry Smith   }
86090f02eecSBarry Smith   PLogFlops(2*a->nz);
861e1311b90SBarry Smith   ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr);
862e1311b90SBarry Smith   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
8633a40ed3dSBarry Smith   PetscFunctionReturn(0);
86417ab2063SBarry Smith }
86517ab2063SBarry Smith 
8665615d1e5SSatish Balay #undef __FUNC__
8675615d1e5SSatish Balay #define __FUNC__ "MatMult_SeqAIJ"
86844cd7ae7SLois Curfman McInnes int MatMult_SeqAIJ(Mat A,Vec xx,Vec yy)
86917ab2063SBarry Smith {
870416022c9SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data;
87117ab2063SBarry Smith   Scalar     *x, *y, *v, sum;
872e1311b90SBarry Smith   int        ierr,m = a->m, *idx, shift = a->indexshift,*ii;
873aa482453SBarry Smith #if !defined(PETSC_USE_FORTRAN_KERNEL_MULTAIJ)
874e36a17ebSSatish Balay   int        n, i, jrow,j;
875e36a17ebSSatish Balay #endif
87617ab2063SBarry Smith 
877aa482453SBarry Smith #if defined(PETSC_HAVE_PRAGMA_DISJOINT)
878fee21e36SBarry Smith #pragma disjoint(*x,*y,*v)
879fee21e36SBarry Smith #endif
880fee21e36SBarry Smith 
8813a40ed3dSBarry Smith   PetscFunctionBegin;
882e1311b90SBarry Smith   ierr = VecGetArray(xx,&x);CHKERRQ(ierr);
883e1311b90SBarry Smith   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
88417ab2063SBarry Smith   x    = x + shift;    /* shift for Fortran start by 1 indexing */
885416022c9SBarry Smith   idx  = a->j;
886d64ed03dSBarry Smith   v    = a->a;
887416022c9SBarry Smith   ii   = a->i;
888aa482453SBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_MULTAIJ)
88929b5ca8aSSatish Balay   fortranmultaij_(&m,x,ii,idx+shift,v+shift,y);
8908d195f9aSBarry Smith #else
891d64ed03dSBarry Smith   v    += shift; /* shift for Fortran start by 1 indexing */
892d64ed03dSBarry Smith   idx  += shift;
89317ab2063SBarry Smith   for ( i=0; i<m; i++ ) {
8949ea0dfa2SSatish Balay     jrow = ii[i];
8959ea0dfa2SSatish Balay     n    = ii[i+1] - jrow;
89617ab2063SBarry Smith     sum  = 0.0;
8979ea0dfa2SSatish Balay     for ( j=0; j<n; j++) {
8989ea0dfa2SSatish Balay       sum += v[jrow]*x[idx[jrow]]; jrow++;
8999ea0dfa2SSatish Balay      }
90017ab2063SBarry Smith     y[i] = sum;
90117ab2063SBarry Smith   }
9028d195f9aSBarry Smith #endif
903416022c9SBarry Smith   PLogFlops(2*a->nz - m);
904e1311b90SBarry Smith   ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr);
905e1311b90SBarry Smith   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
9063a40ed3dSBarry Smith   PetscFunctionReturn(0);
90717ab2063SBarry Smith }
90817ab2063SBarry Smith 
9095615d1e5SSatish Balay #undef __FUNC__
9105615d1e5SSatish Balay #define __FUNC__ "MatMultAdd_SeqAIJ"
91144cd7ae7SLois Curfman McInnes int MatMultAdd_SeqAIJ(Mat A,Vec xx,Vec yy,Vec zz)
91217ab2063SBarry Smith {
913416022c9SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data;
91417ab2063SBarry Smith   Scalar     *x, *y, *z, *v, sum;
915e1311b90SBarry Smith   int        ierr,m = a->m, *idx, shift = a->indexshift,*ii;
916aa482453SBarry Smith #if !defined(PETSC_USE_FORTRAN_KERNEL_MULTADDAIJ)
917e36a17ebSSatish Balay   int        n,i,jrow,j;
918e36a17ebSSatish Balay #endif
9199ea0dfa2SSatish Balay 
9203a40ed3dSBarry Smith   PetscFunctionBegin;
921e1311b90SBarry Smith   ierr = VecGetArray(xx,&x);CHKERRQ(ierr);
922e1311b90SBarry Smith   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
9232e8a6d31SBarry Smith   if (zz != yy) {
924e1311b90SBarry Smith     ierr = VecGetArray(zz,&z);CHKERRQ(ierr);
9252e8a6d31SBarry Smith   } else {
9262e8a6d31SBarry Smith     z = y;
9272e8a6d31SBarry Smith   }
92817ab2063SBarry Smith   x    = x + shift; /* shift for Fortran start by 1 indexing */
929cddf8d76SBarry Smith   idx  = a->j;
930d64ed03dSBarry Smith   v    = a->a;
931cddf8d76SBarry Smith   ii   = a->i;
932aa482453SBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_MULTADDAIJ)
93329b5ca8aSSatish Balay   fortranmultaddaij_(&m,x,ii,idx+shift,v+shift,y,z);
93402ab625aSSatish Balay #else
935d64ed03dSBarry Smith   v   += shift; /* shift for Fortran start by 1 indexing */
936d64ed03dSBarry Smith   idx += shift;
93717ab2063SBarry Smith   for ( i=0; i<m; i++ ) {
9389ea0dfa2SSatish Balay     jrow = ii[i];
9399ea0dfa2SSatish Balay     n    = ii[i+1] - jrow;
94017ab2063SBarry Smith     sum  = y[i];
9419ea0dfa2SSatish Balay     for ( j=0; j<n; j++) {
9429ea0dfa2SSatish Balay       sum += v[jrow]*x[idx[jrow]]; jrow++;
9439ea0dfa2SSatish Balay      }
94417ab2063SBarry Smith     z[i] = sum;
94517ab2063SBarry Smith   }
94602ab625aSSatish Balay #endif
947416022c9SBarry Smith   PLogFlops(2*a->nz);
948e1311b90SBarry Smith   ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr);
949e1311b90SBarry Smith   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
9502e8a6d31SBarry Smith   if (zz != yy) {
951e1311b90SBarry Smith     ierr = VecRestoreArray(zz,&z);CHKERRQ(ierr);
9522e8a6d31SBarry Smith   }
9533a40ed3dSBarry Smith   PetscFunctionReturn(0);
95417ab2063SBarry Smith }
95517ab2063SBarry Smith 
95617ab2063SBarry Smith /*
95717ab2063SBarry Smith      Adds diagonal pointers to sparse matrix structure.
95817ab2063SBarry Smith */
9595615d1e5SSatish Balay #undef __FUNC__
960*f1e2ffcdSBarry Smith #define __FUNC__ "MatMarkDiagonal_SeqAIJ"
961*f1e2ffcdSBarry Smith int MatMarkDiagonal_SeqAIJ(Mat A)
96217ab2063SBarry Smith {
963416022c9SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data;
964416022c9SBarry Smith   int        i,j, *diag, m = a->m,shift = a->indexshift;
96517ab2063SBarry Smith 
9663a40ed3dSBarry Smith   PetscFunctionBegin;
967*f1e2ffcdSBarry Smith   if (a->diag) PetscFunctionReturn(0);
968*f1e2ffcdSBarry Smith 
9690452661fSBarry Smith   diag = (int *) PetscMalloc( (m+1)*sizeof(int));CHKPTRQ(diag);
970416022c9SBarry Smith   PLogObjectMemory(A,(m+1)*sizeof(int));
971416022c9SBarry Smith   for ( i=0; i<a->m; i++ ) {
97235b0346bSBarry Smith     diag[i] = a->i[i+1];
973416022c9SBarry Smith     for ( j=a->i[i]+shift; j<a->i[i+1]+shift; j++ ) {
974416022c9SBarry Smith       if (a->j[j]+shift == i) {
97517ab2063SBarry Smith         diag[i] = j - shift;
97617ab2063SBarry Smith         break;
97717ab2063SBarry Smith       }
97817ab2063SBarry Smith     }
97917ab2063SBarry Smith   }
980416022c9SBarry Smith   a->diag = diag;
9813a40ed3dSBarry Smith   PetscFunctionReturn(0);
98217ab2063SBarry Smith }
98317ab2063SBarry Smith 
984be5855fcSBarry Smith /*
985be5855fcSBarry Smith      Checks for missing diagonals
986be5855fcSBarry Smith */
987be5855fcSBarry Smith #undef __FUNC__
988*f1e2ffcdSBarry Smith #define __FUNC__ "MatMissingDiagonal_SeqAIJ"
989*f1e2ffcdSBarry Smith int MatMissingDiagonal_SeqAIJ(Mat A)
990be5855fcSBarry Smith {
991be5855fcSBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data;
992*f1e2ffcdSBarry Smith   int        *diag, *jj = a->j,i,shift = a->indexshift,ierr;
993be5855fcSBarry Smith 
994be5855fcSBarry Smith   PetscFunctionBegin;
995*f1e2ffcdSBarry Smith   ierr = MatMarkDiagonal_SeqAIJ(A);CHKERRQ(ierr);
996*f1e2ffcdSBarry Smith   diag = a->diag;
997be5855fcSBarry Smith   for ( i=0; i<a->m; i++ ) {
998be5855fcSBarry Smith     if (jj[diag[i]+shift] != i-shift) {
999be5855fcSBarry Smith       SETERRQ1(1,1,"Matrix is missing diagonal number %d",i);
1000be5855fcSBarry Smith     }
1001be5855fcSBarry Smith   }
1002be5855fcSBarry Smith   PetscFunctionReturn(0);
1003be5855fcSBarry Smith }
1004be5855fcSBarry Smith 
10055615d1e5SSatish Balay #undef __FUNC__
10065615d1e5SSatish Balay #define __FUNC__ "MatRelax_SeqAIJ"
1007be5855fcSBarry Smith int MatRelax_SeqAIJ(Mat A,Vec bb,double omega,MatSORType flag,double fshift,int its,Vec xx)
100817ab2063SBarry Smith {
1009416022c9SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data;
1010d6ed3216SSatish Balay   Scalar     *x, *b, *bs,  d, *xs, sum, *v = a->a,*t=0,scale,*ts, *xb,*idiag=0;
1011d5d45c9bSBarry Smith   int        ierr, *idx, *diag,n = a->n, m = a->m, i, shift = a->indexshift;
101217ab2063SBarry Smith 
10133a40ed3dSBarry Smith   PetscFunctionBegin;
1014e1311b90SBarry Smith   ierr = VecGetArray(xx,&x);CHKERRQ(ierr);
1015fb2e594dSBarry Smith   if (xx != bb) {
1016e1311b90SBarry Smith     ierr = VecGetArray(bb,&b);CHKERRQ(ierr);
1017fb2e594dSBarry Smith   } else {
1018fb2e594dSBarry Smith     b = x;
1019fb2e594dSBarry Smith   }
1020fb2e594dSBarry Smith 
1021*f1e2ffcdSBarry Smith   if (!a->diag) {ierr = MatMarkDiagonal_SeqAIJ(A);CHKERRQ(ierr);}
1022416022c9SBarry Smith   diag = a->diag;
1023416022c9SBarry Smith   xs   = x + shift; /* shifted by one for index start of a or a->j*/
102417ab2063SBarry Smith   if (flag == SOR_APPLY_UPPER) {
102517ab2063SBarry Smith    /* apply ( U + D/omega) to the vector */
102617ab2063SBarry Smith     bs = b + shift;
102717ab2063SBarry Smith     for ( i=0; i<m; i++ ) {
1028416022c9SBarry Smith         d    = fshift + a->a[diag[i] + shift];
1029416022c9SBarry Smith         n    = a->i[i+1] - diag[i] - 1;
1030488ecbafSBarry Smith 	PLogFlops(2*n-1);
1031416022c9SBarry Smith         idx  = a->j + diag[i] + (!shift);
1032416022c9SBarry Smith         v    = a->a + diag[i] + (!shift);
103317ab2063SBarry Smith         sum  = b[i]*d/omega;
103417ab2063SBarry Smith         SPARSEDENSEDOT(sum,bs,v,idx,n);
103517ab2063SBarry Smith         x[i] = sum;
103617ab2063SBarry Smith     }
1037cb5b572fSBarry Smith     ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr);
1038fb2e594dSBarry Smith     if (bb != xx) {ierr = VecRestoreArray(bb,&b);CHKERRQ(ierr);}
10393a40ed3dSBarry Smith     PetscFunctionReturn(0);
104017ab2063SBarry Smith   }
1041c783ea89SBarry Smith 
1042c783ea89SBarry Smith   /* setup workspace for Eisenstat */
1043c783ea89SBarry Smith   if (flag & SOR_EISENSTAT) {
1044c783ea89SBarry Smith     if (!a->idiag) {
1045c783ea89SBarry Smith       a->idiag = (Scalar *) PetscMalloc(2*m*sizeof(Scalar));CHKPTRQ(a->idiag);
1046c783ea89SBarry Smith       a->ssor  = a->idiag + m;
1047c783ea89SBarry Smith       v        = a->a;
1048c783ea89SBarry Smith       for ( i=0; i<m; i++ ) { a->idiag[i] = 1.0/v[diag[i]];}
1049c783ea89SBarry Smith     }
1050c783ea89SBarry Smith     t     = a->ssor;
1051c783ea89SBarry Smith     idiag = a->idiag;
1052c783ea89SBarry Smith   }
1053fc3d8934SBarry Smith     /* Let  A = L + U + D; where L is lower trianglar,
1054fc3d8934SBarry Smith     U is upper triangular, E is diagonal; This routine applies
1055fc3d8934SBarry Smith 
1056fc3d8934SBarry Smith             (L + E)^{-1} A (U + E)^{-1}
1057fc3d8934SBarry Smith 
1058fc3d8934SBarry Smith     to a vector efficiently using Eisenstat's trick. This is for
1059fc3d8934SBarry Smith     the case of SSOR preconditioner, so E is D/omega where omega
106048af12d7SBarry Smith     is the relaxation factor.
1061fc3d8934SBarry Smith     */
1062fc3d8934SBarry Smith 
106348af12d7SBarry Smith   if (flag == SOR_APPLY_LOWER) {
106448af12d7SBarry Smith     SETERRQ(PETSC_ERR_SUP,0,"SOR_APPLY_LOWER is not done");
106548af12d7SBarry Smith   } else if ((flag & SOR_EISENSTAT) && omega == 1.0 && shift == 0 && fshift == 0.0) {
106648af12d7SBarry Smith     /* special case for omega = 1.0 saves flops and some integer ops */
1067733d66baSBarry Smith     Scalar *v2;
106848af12d7SBarry Smith 
1069733d66baSBarry Smith     v2    = a->a;
1070fc3d8934SBarry Smith     /*  x = (E + U)^{-1} b */
1071fc3d8934SBarry Smith     for ( i=m-1; i>=0; i-- ) {
1072fc3d8934SBarry Smith       n    = a->i[i+1] - diag[i] - 1;
1073fc3d8934SBarry Smith       idx  = a->j + diag[i] + 1;
1074fc3d8934SBarry Smith       v    = a->a + diag[i] + 1;
1075fc3d8934SBarry Smith       sum  = b[i];
1076fc3d8934SBarry Smith       SPARSEDENSEMDOT(sum,xs,v,idx,n);
1077b4632166SBarry Smith       x[i] = sum*idiag[i];
1078fc3d8934SBarry Smith 
1079fc3d8934SBarry Smith       /*  t = b - (2*E - D)x */
1080733d66baSBarry Smith       t[i] = b[i] - (v2[diag[i]])*x[i];
1081733d66baSBarry Smith     }
1082fc3d8934SBarry Smith 
1083fc3d8934SBarry Smith     /*  t = (E + L)^{-1}t */
1084fc3d8934SBarry Smith     diag = a->diag;
1085fc3d8934SBarry Smith     for ( i=0; i<m; i++ ) {
1086fc3d8934SBarry Smith       n    = diag[i] - a->i[i];
1087fc3d8934SBarry Smith       idx  = a->j + a->i[i];
1088fc3d8934SBarry Smith       v    = a->a + a->i[i];
1089fc3d8934SBarry Smith       sum  = t[i];
1090fc3d8934SBarry Smith       SPARSEDENSEMDOT(sum,t,v,idx,n);
1091b4632166SBarry Smith       t[i]  = sum*idiag[i];
1092fc3d8934SBarry Smith 
1093fc3d8934SBarry Smith       /*  x = x + t */
1094733d66baSBarry Smith       x[i] += t[i];
1095733d66baSBarry Smith     }
1096733d66baSBarry Smith 
1097a4d9cbf6SBarry Smith     PLogFlops(3*m-1 + 2*a->nz);
1098fc3d8934SBarry Smith     ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr);
1099fc3d8934SBarry Smith     if (bb != xx) {ierr = VecRestoreArray(bb,&b);CHKERRQ(ierr);}
1100fc3d8934SBarry Smith     PetscFunctionReturn(0);
11013a40ed3dSBarry Smith   } else if (flag & SOR_EISENSTAT) {
110217ab2063SBarry Smith     /* Let  A = L + U + D; where L is lower trianglar,
110317ab2063SBarry Smith     U is upper triangular, E is diagonal; This routine applies
110417ab2063SBarry Smith 
110517ab2063SBarry Smith             (L + E)^{-1} A (U + E)^{-1}
110617ab2063SBarry Smith 
110717ab2063SBarry Smith     to a vector efficiently using Eisenstat's trick. This is for
110817ab2063SBarry Smith     the case of SSOR preconditioner, so E is D/omega where omega
110917ab2063SBarry Smith     is the relaxation factor.
111017ab2063SBarry Smith     */
111117ab2063SBarry Smith     scale = (2.0/omega) - 1.0;
111217ab2063SBarry Smith 
111317ab2063SBarry Smith     /*  x = (E + U)^{-1} b */
111417ab2063SBarry Smith     for ( i=m-1; i>=0; i-- ) {
1115416022c9SBarry Smith       d    = fshift + a->a[diag[i] + shift];
1116416022c9SBarry Smith       n    = a->i[i+1] - diag[i] - 1;
1117416022c9SBarry Smith       idx  = a->j + diag[i] + (!shift);
1118416022c9SBarry Smith       v    = a->a + diag[i] + (!shift);
111917ab2063SBarry Smith       sum  = b[i];
112017ab2063SBarry Smith       SPARSEDENSEMDOT(sum,xs,v,idx,n);
112117ab2063SBarry Smith       x[i] = omega*(sum/d);
112217ab2063SBarry Smith     }
112317ab2063SBarry Smith 
112417ab2063SBarry Smith     /*  t = b - (2*E - D)x */
1125416022c9SBarry Smith     v = a->a;
112617ab2063SBarry Smith     for ( i=0; i<m; i++ ) { t[i] = b[i] - scale*(v[*diag++ + shift])*x[i]; }
112717ab2063SBarry Smith 
112817ab2063SBarry Smith     /*  t = (E + L)^{-1}t */
1129416022c9SBarry Smith     ts = t + shift; /* shifted by one for index start of a or a->j*/
1130416022c9SBarry Smith     diag = a->diag;
113117ab2063SBarry Smith     for ( i=0; i<m; i++ ) {
1132416022c9SBarry Smith       d    = fshift + a->a[diag[i]+shift];
1133416022c9SBarry Smith       n    = diag[i] - a->i[i];
1134416022c9SBarry Smith       idx  = a->j + a->i[i] + shift;
1135416022c9SBarry Smith       v    = a->a + a->i[i] + shift;
113617ab2063SBarry Smith       sum  = t[i];
113717ab2063SBarry Smith       SPARSEDENSEMDOT(sum,ts,v,idx,n);
113817ab2063SBarry Smith       t[i] = omega*(sum/d);
1139733d66baSBarry Smith       /*  x = x + t */
1140733d66baSBarry Smith       x[i] += t[i];
114117ab2063SBarry Smith     }
114217ab2063SBarry Smith 
1143c783ea89SBarry Smith     PLogFlops(6*m-1 + 2*a->nz);
1144cb5b572fSBarry Smith     ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr);
1145fb2e594dSBarry Smith     if (bb != xx) {ierr = VecRestoreArray(bb,&b);CHKERRQ(ierr);}
11463a40ed3dSBarry Smith     PetscFunctionReturn(0);
114717ab2063SBarry Smith   }
114817ab2063SBarry Smith   if (flag & SOR_ZERO_INITIAL_GUESS) {
114917ab2063SBarry Smith     if (flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP){
115017ab2063SBarry Smith       for ( i=0; i<m; i++ ) {
1151416022c9SBarry Smith         d    = fshift + a->a[diag[i]+shift];
1152416022c9SBarry Smith         n    = diag[i] - a->i[i];
1153488ecbafSBarry Smith 	PLogFlops(2*n-1);
1154416022c9SBarry Smith         idx  = a->j + a->i[i] + shift;
1155416022c9SBarry Smith         v    = a->a + a->i[i] + shift;
115617ab2063SBarry Smith         sum  = b[i];
115717ab2063SBarry Smith         SPARSEDENSEMDOT(sum,xs,v,idx,n);
115817ab2063SBarry Smith         x[i] = omega*(sum/d);
115917ab2063SBarry Smith       }
116017ab2063SBarry Smith       xb = x;
11613a40ed3dSBarry Smith     } else xb = b;
116217ab2063SBarry Smith     if ((flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP) &&
116317ab2063SBarry Smith         (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP)) {
116417ab2063SBarry Smith       for ( i=0; i<m; i++ ) {
1165416022c9SBarry Smith         x[i] *= a->a[diag[i]+shift];
116617ab2063SBarry Smith       }
1167488ecbafSBarry Smith       PLogFlops(m);
116817ab2063SBarry Smith     }
116917ab2063SBarry Smith     if (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP){
117017ab2063SBarry Smith       for ( i=m-1; i>=0; i-- ) {
1171416022c9SBarry Smith         d    = fshift + a->a[diag[i] + shift];
1172416022c9SBarry Smith         n    = a->i[i+1] - diag[i] - 1;
1173488ecbafSBarry Smith 	PLogFlops(2*n-1);
1174416022c9SBarry Smith         idx  = a->j + diag[i] + (!shift);
1175416022c9SBarry Smith         v    = a->a + diag[i] + (!shift);
117617ab2063SBarry Smith         sum  = xb[i];
117717ab2063SBarry Smith         SPARSEDENSEMDOT(sum,xs,v,idx,n);
117817ab2063SBarry Smith         x[i] = omega*(sum/d);
117917ab2063SBarry Smith       }
118017ab2063SBarry Smith     }
118117ab2063SBarry Smith     its--;
118217ab2063SBarry Smith   }
118317ab2063SBarry Smith   while (its--) {
118417ab2063SBarry Smith     if (flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP){
118517ab2063SBarry Smith       for ( i=0; i<m; i++ ) {
1186416022c9SBarry Smith         d    = fshift + a->a[diag[i]+shift];
1187416022c9SBarry Smith         n    = a->i[i+1] - a->i[i];
1188488ecbafSBarry Smith 	PLogFlops(2*n-1);
1189416022c9SBarry Smith         idx  = a->j + a->i[i] + shift;
1190416022c9SBarry Smith         v    = a->a + a->i[i] + shift;
119117ab2063SBarry Smith         sum  = b[i];
119217ab2063SBarry Smith         SPARSEDENSEMDOT(sum,xs,v,idx,n);
11937e33a6baSBarry Smith         x[i] = (1. - omega)*x[i] + omega*(sum + a->a[diag[i]+shift]*x[i])/d;
119417ab2063SBarry Smith       }
119517ab2063SBarry Smith     }
119617ab2063SBarry Smith     if (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP){
119717ab2063SBarry Smith       for ( i=m-1; i>=0; i-- ) {
1198416022c9SBarry Smith         d    = fshift + a->a[diag[i] + shift];
1199416022c9SBarry Smith         n    = a->i[i+1] - a->i[i];
1200488ecbafSBarry Smith 	PLogFlops(2*n-1);
1201416022c9SBarry Smith         idx  = a->j + a->i[i] + shift;
1202416022c9SBarry Smith         v    = a->a + a->i[i] + shift;
120317ab2063SBarry Smith         sum  = b[i];
120417ab2063SBarry Smith         SPARSEDENSEMDOT(sum,xs,v,idx,n);
12057e33a6baSBarry Smith         x[i] = (1. - omega)*x[i] + omega*(sum + a->a[diag[i]+shift]*x[i])/d;
120617ab2063SBarry Smith       }
120717ab2063SBarry Smith     }
120817ab2063SBarry Smith   }
1209cb5b572fSBarry Smith   ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr);
1210fb2e594dSBarry Smith   if (bb != xx) {ierr = VecRestoreArray(bb,&b);CHKERRQ(ierr);}
12113a40ed3dSBarry Smith   PetscFunctionReturn(0);
121217ab2063SBarry Smith }
121317ab2063SBarry Smith 
12145615d1e5SSatish Balay #undef __FUNC__
12155615d1e5SSatish Balay #define __FUNC__ "MatGetInfo_SeqAIJ"
12168f6be9afSLois Curfman McInnes int MatGetInfo_SeqAIJ(Mat A,MatInfoType flag,MatInfo *info)
121717ab2063SBarry Smith {
1218416022c9SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data;
12194e220ebcSLois Curfman McInnes 
12203a40ed3dSBarry Smith   PetscFunctionBegin;
12214e220ebcSLois Curfman McInnes   info->rows_global    = (double)a->m;
12224e220ebcSLois Curfman McInnes   info->columns_global = (double)a->n;
12234e220ebcSLois Curfman McInnes   info->rows_local     = (double)a->m;
12244e220ebcSLois Curfman McInnes   info->columns_local  = (double)a->n;
12254e220ebcSLois Curfman McInnes   info->block_size     = 1.0;
12264e220ebcSLois Curfman McInnes   info->nz_allocated   = (double)a->maxnz;
12274e220ebcSLois Curfman McInnes   info->nz_used        = (double)a->nz;
12284e220ebcSLois Curfman McInnes   info->nz_unneeded    = (double)(a->maxnz - a->nz);
12294e220ebcSLois Curfman McInnes   info->assemblies     = (double)A->num_ass;
12304e220ebcSLois Curfman McInnes   info->mallocs        = (double)a->reallocs;
12314e220ebcSLois Curfman McInnes   info->memory         = A->mem;
12324e220ebcSLois Curfman McInnes   if (A->factor) {
12334e220ebcSLois Curfman McInnes     info->fill_ratio_given  = A->info.fill_ratio_given;
12344e220ebcSLois Curfman McInnes     info->fill_ratio_needed = A->info.fill_ratio_needed;
12354e220ebcSLois Curfman McInnes     info->factor_mallocs    = A->info.factor_mallocs;
12364e220ebcSLois Curfman McInnes   } else {
12374e220ebcSLois Curfman McInnes     info->fill_ratio_given  = 0;
12384e220ebcSLois Curfman McInnes     info->fill_ratio_needed = 0;
12394e220ebcSLois Curfman McInnes     info->factor_mallocs    = 0;
12404e220ebcSLois Curfman McInnes   }
12413a40ed3dSBarry Smith   PetscFunctionReturn(0);
124217ab2063SBarry Smith }
124317ab2063SBarry Smith 
124417ab2063SBarry Smith extern int MatLUFactorSymbolic_SeqAIJ(Mat,IS,IS,double,Mat*);
124517ab2063SBarry Smith extern int MatLUFactorNumeric_SeqAIJ(Mat,Mat*);
124617ab2063SBarry Smith extern int MatLUFactor_SeqAIJ(Mat,IS,IS,double);
124717ab2063SBarry Smith extern int MatSolve_SeqAIJ(Mat,Vec,Vec);
124817ab2063SBarry Smith extern int MatSolveAdd_SeqAIJ(Mat,Vec,Vec,Vec);
124917ab2063SBarry Smith extern int MatSolveTrans_SeqAIJ(Mat,Vec,Vec);
125017ab2063SBarry Smith extern int MatSolveTransAdd_SeqAIJ(Mat,Vec,Vec,Vec);
125117ab2063SBarry Smith 
12525615d1e5SSatish Balay #undef __FUNC__
12535615d1e5SSatish Balay #define __FUNC__ "MatZeroRows_SeqAIJ"
12548f6be9afSLois Curfman McInnes int MatZeroRows_SeqAIJ(Mat A,IS is,Scalar *diag)
125517ab2063SBarry Smith {
1256416022c9SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data;
1257416022c9SBarry Smith   int         i,ierr,N, *rows,m = a->m - 1,shift = a->indexshift;
125817ab2063SBarry Smith 
12593a40ed3dSBarry Smith   PetscFunctionBegin;
126077c4ece6SBarry Smith   ierr = ISGetSize(is,&N);CHKERRQ(ierr);
126117ab2063SBarry Smith   ierr = ISGetIndices(is,&rows);CHKERRQ(ierr);
1262*f1e2ffcdSBarry Smith   if (a->keepzeroedrows) {
1263*f1e2ffcdSBarry Smith     for ( i=0; i<N; i++ ) {
1264*f1e2ffcdSBarry Smith       if (rows[i] < 0 || rows[i] > m) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"row out of range");
1265*f1e2ffcdSBarry Smith       ierr = PetscMemzero(&a->a[a->i[rows[i]]+shift],a->ilen[rows[i]]*sizeof(Scalar));CHKERRQ(ierr);
1266*f1e2ffcdSBarry Smith     }
1267*f1e2ffcdSBarry Smith     if (diag) {
1268*f1e2ffcdSBarry Smith       ierr = MatMissingDiagonal_SeqAIJ(A);CHKERRQ(ierr);
1269*f1e2ffcdSBarry Smith       ierr = MatMarkDiagonal_SeqAIJ(A);CHKERRQ(ierr);
1270*f1e2ffcdSBarry Smith       for ( i=0; i<N; i++ ) {
1271*f1e2ffcdSBarry Smith         a->a[a->diag[rows[i]]] = *diag;
1272*f1e2ffcdSBarry Smith       }
1273*f1e2ffcdSBarry Smith     }
1274*f1e2ffcdSBarry Smith   } else {
127517ab2063SBarry Smith     if (diag) {
127617ab2063SBarry Smith       for ( i=0; i<N; i++ ) {
1277a8c6a408SBarry Smith         if (rows[i] < 0 || rows[i] > m) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"row out of range");
12787ae801bdSBarry Smith         if (a->ilen[rows[i]] > 0) {
1279416022c9SBarry Smith           a->ilen[rows[i]]          = 1;
1280416022c9SBarry Smith           a->a[a->i[rows[i]]+shift] = *diag;
1281416022c9SBarry Smith           a->j[a->i[rows[i]]+shift] = rows[i]+shift;
12827ae801bdSBarry Smith         } else { /* in case row was completely empty */
1283d64ed03dSBarry Smith           ierr = MatSetValues_SeqAIJ(A,1,&rows[i],1,&rows[i],diag,INSERT_VALUES);CHKERRQ(ierr);
128417ab2063SBarry Smith         }
128517ab2063SBarry Smith       }
12863a40ed3dSBarry Smith     } else {
128717ab2063SBarry Smith       for ( i=0; i<N; i++ ) {
1288a8c6a408SBarry Smith         if (rows[i] < 0 || rows[i] > m) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"row out of range");
1289416022c9SBarry Smith         a->ilen[rows[i]] = 0;
129017ab2063SBarry Smith       }
129117ab2063SBarry Smith     }
1292*f1e2ffcdSBarry Smith   }
12937ae801bdSBarry Smith   ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr);
129443a90d84SBarry Smith   ierr = MatAssemblyEnd_SeqAIJ(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
12953a40ed3dSBarry Smith   PetscFunctionReturn(0);
129617ab2063SBarry Smith }
129717ab2063SBarry Smith 
12985615d1e5SSatish Balay #undef __FUNC__
12995615d1e5SSatish Balay #define __FUNC__ "MatGetSize_SeqAIJ"
13008f6be9afSLois Curfman McInnes int MatGetSize_SeqAIJ(Mat A,int *m,int *n)
130117ab2063SBarry Smith {
1302416022c9SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data;
13033a40ed3dSBarry Smith 
13043a40ed3dSBarry Smith   PetscFunctionBegin;
13050752156aSBarry Smith   if (m) *m = a->m;
13060752156aSBarry Smith   if (n) *n = a->n;
13073a40ed3dSBarry Smith   PetscFunctionReturn(0);
130817ab2063SBarry Smith }
130917ab2063SBarry Smith 
13105615d1e5SSatish Balay #undef __FUNC__
13115615d1e5SSatish Balay #define __FUNC__ "MatGetOwnershipRange_SeqAIJ"
13128f6be9afSLois Curfman McInnes int MatGetOwnershipRange_SeqAIJ(Mat A,int *m,int *n)
131317ab2063SBarry Smith {
1314416022c9SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data;
13153a40ed3dSBarry Smith 
13163a40ed3dSBarry Smith   PetscFunctionBegin;
1317416022c9SBarry Smith   *m = 0; *n = a->m;
13183a40ed3dSBarry Smith   PetscFunctionReturn(0);
131917ab2063SBarry Smith }
1320026e39d0SSatish Balay 
13215615d1e5SSatish Balay #undef __FUNC__
13225615d1e5SSatish Balay #define __FUNC__ "MatGetRow_SeqAIJ"
13234e093b46SBarry Smith int MatGetRow_SeqAIJ(Mat A,int row,int *nz,int **idx,Scalar **v)
132417ab2063SBarry Smith {
1325416022c9SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data;
1326c456f294SBarry Smith   int        *itmp,i,shift = a->indexshift;
132717ab2063SBarry Smith 
13283a40ed3dSBarry Smith   PetscFunctionBegin;
1329a8c6a408SBarry Smith   if (row < 0 || row >= a->m) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Row out of range");
133017ab2063SBarry Smith 
1331416022c9SBarry Smith   *nz = a->i[row+1] - a->i[row];
1332416022c9SBarry Smith   if (v) *v = a->a + a->i[row] + shift;
133317ab2063SBarry Smith   if (idx) {
1334416022c9SBarry Smith     itmp = a->j + a->i[row] + shift;
13354e093b46SBarry Smith     if (*nz && shift) {
13360452661fSBarry Smith       *idx = (int *) PetscMalloc( (*nz)*sizeof(int) );CHKPTRQ(*idx);
133717ab2063SBarry Smith       for ( i=0; i<(*nz); i++ ) {(*idx)[i] = itmp[i] + shift;}
13384e093b46SBarry Smith     } else if (*nz) {
13394e093b46SBarry Smith       *idx = itmp;
134017ab2063SBarry Smith     }
134117ab2063SBarry Smith     else *idx = 0;
134217ab2063SBarry Smith   }
13433a40ed3dSBarry Smith   PetscFunctionReturn(0);
134417ab2063SBarry Smith }
134517ab2063SBarry Smith 
13465615d1e5SSatish Balay #undef __FUNC__
13475615d1e5SSatish Balay #define __FUNC__ "MatRestoreRow_SeqAIJ"
13484e093b46SBarry Smith int MatRestoreRow_SeqAIJ(Mat A,int row,int *nz,int **idx,Scalar **v)
134917ab2063SBarry Smith {
13504e093b46SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data;
1351606d414cSSatish Balay   int ierr;
13523a40ed3dSBarry Smith 
13533a40ed3dSBarry Smith   PetscFunctionBegin;
1354606d414cSSatish Balay   if (idx) {if (*idx && a->indexshift) {ierr = PetscFree(*idx);CHKERRQ(ierr);}}
13553a40ed3dSBarry Smith   PetscFunctionReturn(0);
135617ab2063SBarry Smith }
135717ab2063SBarry Smith 
13585615d1e5SSatish Balay #undef __FUNC__
13595615d1e5SSatish Balay #define __FUNC__ "MatNorm_SeqAIJ"
13608f6be9afSLois Curfman McInnes int MatNorm_SeqAIJ(Mat A,NormType type,double *norm)
136117ab2063SBarry Smith {
1362416022c9SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data;
1363416022c9SBarry Smith   Scalar     *v = a->a;
136417ab2063SBarry Smith   double     sum = 0.0;
1365549d3d68SSatish Balay   int        i, j,shift = a->indexshift,ierr;
136617ab2063SBarry Smith 
13673a40ed3dSBarry Smith   PetscFunctionBegin;
136817ab2063SBarry Smith   if (type == NORM_FROBENIUS) {
1369416022c9SBarry Smith     for (i=0; i<a->nz; i++ ) {
1370aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
1371e20fef11SSatish Balay       sum += PetscReal(PetscConj(*v)*(*v)); v++;
137217ab2063SBarry Smith #else
137317ab2063SBarry Smith       sum += (*v)*(*v); v++;
137417ab2063SBarry Smith #endif
137517ab2063SBarry Smith     }
137617ab2063SBarry Smith     *norm = sqrt(sum);
13773a40ed3dSBarry Smith   } else if (type == NORM_1) {
137817ab2063SBarry Smith     double *tmp;
1379416022c9SBarry Smith     int    *jj = a->j;
138066963ce1SSatish Balay     tmp = (double *) PetscMalloc( (a->n+1)*sizeof(double) );CHKPTRQ(tmp);
1381549d3d68SSatish Balay     ierr = PetscMemzero(tmp,a->n*sizeof(double));CHKERRQ(ierr);
138217ab2063SBarry Smith     *norm = 0.0;
1383416022c9SBarry Smith     for ( j=0; j<a->nz; j++ ) {
1384a2744918SBarry Smith         tmp[*jj++ + shift] += PetscAbsScalar(*v);  v++;
138517ab2063SBarry Smith     }
1386416022c9SBarry Smith     for ( j=0; j<a->n; j++ ) {
138717ab2063SBarry Smith       if (tmp[j] > *norm) *norm = tmp[j];
138817ab2063SBarry Smith     }
1389606d414cSSatish Balay     ierr = PetscFree(tmp);CHKERRQ(ierr);
13903a40ed3dSBarry Smith   } else if (type == NORM_INFINITY) {
139117ab2063SBarry Smith     *norm = 0.0;
1392416022c9SBarry Smith     for ( j=0; j<a->m; j++ ) {
1393416022c9SBarry Smith       v = a->a + a->i[j] + shift;
139417ab2063SBarry Smith       sum = 0.0;
1395416022c9SBarry Smith       for ( i=0; i<a->i[j+1]-a->i[j]; i++ ) {
1396cddf8d76SBarry Smith         sum += PetscAbsScalar(*v); v++;
139717ab2063SBarry Smith       }
139817ab2063SBarry Smith       if (sum > *norm) *norm = sum;
139917ab2063SBarry Smith     }
14003a40ed3dSBarry Smith   } else {
1401a8c6a408SBarry Smith     SETERRQ(PETSC_ERR_SUP,0,"No support for two norm");
140217ab2063SBarry Smith   }
14033a40ed3dSBarry Smith   PetscFunctionReturn(0);
140417ab2063SBarry Smith }
140517ab2063SBarry Smith 
14065615d1e5SSatish Balay #undef __FUNC__
14075615d1e5SSatish Balay #define __FUNC__ "MatTranspose_SeqAIJ"
14088f6be9afSLois Curfman McInnes int MatTranspose_SeqAIJ(Mat A,Mat *B)
140917ab2063SBarry Smith {
1410416022c9SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data;
1411416022c9SBarry Smith   Mat        C;
1412416022c9SBarry Smith   int        i, ierr, *aj = a->j, *ai = a->i, m = a->m, len, *col;
1413416022c9SBarry Smith   int        shift = a->indexshift;
1414d5d45c9bSBarry Smith   Scalar     *array = a->a;
141517ab2063SBarry Smith 
14163a40ed3dSBarry Smith   PetscFunctionBegin;
1417*f1e2ffcdSBarry Smith   if (!B && m != a->n) SETERRQ(PETSC_ERR_ARG_SIZ,0,"Square matrix only for in-place");
14180452661fSBarry Smith   col  = (int *) PetscMalloc((1+a->n)*sizeof(int));CHKPTRQ(col);
1419549d3d68SSatish Balay   ierr = PetscMemzero(col,(1+a->n)*sizeof(int));CHKERRQ(ierr);
142017ab2063SBarry Smith   if (shift) {
142117ab2063SBarry Smith     for ( i=0; i<ai[m]-1; i++ ) aj[i] -= 1;
142217ab2063SBarry Smith   }
142317ab2063SBarry Smith   for ( i=0; i<ai[m]+shift; i++ ) col[aj[i]] += 1;
1424416022c9SBarry Smith   ierr = MatCreateSeqAIJ(A->comm,a->n,m,0,col,&C);CHKERRQ(ierr);
1425606d414cSSatish Balay   ierr = PetscFree(col);CHKERRQ(ierr);
142617ab2063SBarry Smith   for ( i=0; i<m; i++ ) {
142717ab2063SBarry Smith     len = ai[i+1]-ai[i];
1428416022c9SBarry Smith     ierr = MatSetValues(C,len,aj,1,&i,array,INSERT_VALUES);CHKERRQ(ierr);
142917ab2063SBarry Smith     array += len; aj += len;
143017ab2063SBarry Smith   }
143117ab2063SBarry Smith   if (shift) {
143217ab2063SBarry Smith     for ( i=0; i<ai[m]-1; i++ ) aj[i] += 1;
143317ab2063SBarry Smith   }
143417ab2063SBarry Smith 
14356d4a8577SBarry Smith   ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
14366d4a8577SBarry Smith   ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
143717ab2063SBarry Smith 
1438*f1e2ffcdSBarry Smith   if (B) {
1439416022c9SBarry Smith     *B = C;
144017ab2063SBarry Smith   } else {
1441f830108cSBarry Smith     PetscOps *Abops;
14420a6ffc59SBarry Smith     MatOps   Aops;
1443f830108cSBarry Smith 
1444416022c9SBarry Smith     /* This isn't really an in-place transpose */
1445606d414cSSatish Balay     ierr = PetscFree(a->a);CHKERRQ(ierr);
1446606d414cSSatish Balay     if (!a->singlemalloc) {
1447606d414cSSatish Balay       ierr = PetscFree(a->i);CHKERRQ(ierr);
1448606d414cSSatish Balay       ierr = PetscFree(a->j);
1449606d414cSSatish Balay     }
1450606d414cSSatish Balay     if (a->diag) {ierr = PetscFree(a->diag);CHKERRQ(ierr);}
1451606d414cSSatish Balay     if (a->ilen) {ierr = PetscFree(a->ilen);CHKERRQ(ierr);}
1452606d414cSSatish Balay     if (a->imax) {ierr = PetscFree(a->imax);CHKERRQ(ierr);}
1453606d414cSSatish Balay     if (a->solve_work) {ierr = PetscFree(a->solve_work);CHKERRQ(ierr);}
1454606d414cSSatish Balay     if (a->inode.size) {ierr = PetscFree(a->inode.size);CHKERRQ(ierr);}
1455606d414cSSatish Balay     ierr = PetscFree(a);CHKERRQ(ierr);
1456f830108cSBarry Smith 
1457488ecbafSBarry Smith 
1458488ecbafSBarry Smith     ierr = MapDestroy(A->rmap);CHKERRQ(ierr);
1459488ecbafSBarry Smith     ierr = MapDestroy(A->cmap);CHKERRQ(ierr);
1460488ecbafSBarry Smith 
1461f830108cSBarry Smith     /*
1462f830108cSBarry Smith       This is horrible, horrible code. We need to keep the
14638f0f457cSSatish Balay       the bops and ops Structures, copy everything from C
14648f0f457cSSatish Balay       including the function pointers..
1465f830108cSBarry Smith     */
1466549d3d68SSatish Balay     ierr     = PetscMemcpy(A->ops,C->ops,sizeof(struct _MatOps));CHKERRQ(ierr);
1467549d3d68SSatish Balay     ierr     = PetscMemcpy(A->bops,C->bops,sizeof(PetscOps));CHKERRQ(ierr);
1468f830108cSBarry Smith     Abops    = A->bops;
1469f830108cSBarry Smith     Aops     = A->ops;
1470549d3d68SSatish Balay     ierr     = PetscMemcpy(A,C,sizeof(struct _p_Mat));CHKERRQ(ierr);
1471f830108cSBarry Smith     A->bops  = Abops;
1472f830108cSBarry Smith     A->ops   = Aops;
147327a8da17SBarry Smith     A->qlist = 0;
1474f830108cSBarry Smith 
14750452661fSBarry Smith     PetscHeaderDestroy(C);
147617ab2063SBarry Smith   }
14773a40ed3dSBarry Smith   PetscFunctionReturn(0);
147817ab2063SBarry Smith }
147917ab2063SBarry Smith 
14805615d1e5SSatish Balay #undef __FUNC__
14815615d1e5SSatish Balay #define __FUNC__ "MatDiagonalScale_SeqAIJ"
14828f6be9afSLois Curfman McInnes int MatDiagonalScale_SeqAIJ(Mat A,Vec ll,Vec rr)
148317ab2063SBarry Smith {
1484416022c9SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data;
148517ab2063SBarry Smith   Scalar     *l,*r,x,*v;
1486e1311b90SBarry Smith   int        ierr,i,j,m = a->m, n = a->n, M, nz = a->nz, *jj,shift = a->indexshift;
148717ab2063SBarry Smith 
14883a40ed3dSBarry Smith   PetscFunctionBegin;
148917ab2063SBarry Smith   if (ll) {
14903ea7c6a1SSatish Balay     /* The local size is used so that VecMPI can be passed to this routine
14913ea7c6a1SSatish Balay        by MatDiagonalScale_MPIAIJ */
1492e1311b90SBarry Smith     ierr = VecGetLocalSize(ll,&m);CHKERRQ(ierr);
1493a8c6a408SBarry Smith     if (m != a->m) SETERRQ(PETSC_ERR_ARG_SIZ,0,"Left scaling vector wrong length");
1494e1311b90SBarry Smith     ierr = VecGetArray(ll,&l);CHKERRQ(ierr);
1495416022c9SBarry Smith     v = a->a;
149617ab2063SBarry Smith     for ( i=0; i<m; i++ ) {
149717ab2063SBarry Smith       x = l[i];
1498416022c9SBarry Smith       M = a->i[i+1] - a->i[i];
149917ab2063SBarry Smith       for ( j=0; j<M; j++ ) { (*v++) *= x;}
150017ab2063SBarry Smith     }
1501e1311b90SBarry Smith     ierr = VecRestoreArray(ll,&l);CHKERRQ(ierr);
150244cd7ae7SLois Curfman McInnes     PLogFlops(nz);
150317ab2063SBarry Smith   }
150417ab2063SBarry Smith   if (rr) {
1505e1311b90SBarry Smith     ierr = VecGetLocalSize(rr,&n);CHKERRQ(ierr);
1506a8c6a408SBarry Smith     if (n != a->n) SETERRQ(PETSC_ERR_ARG_SIZ,0,"Right scaling vector wrong length");
1507e1311b90SBarry Smith     ierr = VecGetArray(rr,&r);CHKERRQ(ierr);
1508416022c9SBarry Smith     v = a->a; jj = a->j;
150917ab2063SBarry Smith     for ( i=0; i<nz; i++ ) {
151017ab2063SBarry Smith       (*v++) *= r[*jj++ + shift];
151117ab2063SBarry Smith     }
1512e1311b90SBarry Smith     ierr = VecRestoreArray(rr,&r);CHKERRQ(ierr);
151344cd7ae7SLois Curfman McInnes     PLogFlops(nz);
151417ab2063SBarry Smith   }
15153a40ed3dSBarry Smith   PetscFunctionReturn(0);
151617ab2063SBarry Smith }
151717ab2063SBarry Smith 
15185615d1e5SSatish Balay #undef __FUNC__
15195615d1e5SSatish Balay #define __FUNC__ "MatGetSubMatrix_SeqAIJ"
15207b2a1423SBarry Smith int MatGetSubMatrix_SeqAIJ(Mat A,IS isrow,IS iscol,int csize,MatReuse scall,Mat *B)
152117ab2063SBarry Smith {
1522db02288aSLois Curfman McInnes   Mat_SeqAIJ   *a = (Mat_SeqAIJ *) A->data,*c;
1523d5db1b72SBarry Smith   int          *smap, i, k, kstart, kend, ierr, oldcols = a->n,*lens;
152499141d43SSatish Balay   int          row,mat_i,*mat_j,tcol,first,step,*mat_ilen;
1525a2744918SBarry Smith   register int sum,lensi;
152699141d43SSatish Balay   int          *irow, *icol, nrows, ncols, shift = a->indexshift,*ssmap;
152799141d43SSatish Balay   int          *starts,*j_new,*i_new,*aj = a->j, *ai = a->i,ii,*ailen = a->ilen;
152899141d43SSatish Balay   Scalar       *a_new,*mat_a;
1529416022c9SBarry Smith   Mat          C;
1530fee21e36SBarry Smith   PetscTruth   stride;
153117ab2063SBarry Smith 
15323a40ed3dSBarry Smith   PetscFunctionBegin;
1533d64ed03dSBarry Smith   ierr = ISSorted(isrow,(PetscTruth*)&i);CHKERRQ(ierr);
1534a8c6a408SBarry Smith   if (!i) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,0,"ISrow is not sorted");
1535d64ed03dSBarry Smith   ierr = ISSorted(iscol,(PetscTruth*)&i);CHKERRQ(ierr);
1536a8c6a408SBarry Smith   if (!i) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,0,"IScol is not sorted");
153799141d43SSatish Balay 
153817ab2063SBarry Smith   ierr = ISGetIndices(isrow,&irow);CHKERRQ(ierr);
153917ab2063SBarry Smith   ierr = ISGetSize(isrow,&nrows);CHKERRQ(ierr);
154017ab2063SBarry Smith   ierr = ISGetSize(iscol,&ncols);CHKERRQ(ierr);
154117ab2063SBarry Smith 
1542fee21e36SBarry Smith   ierr = ISStrideGetInfo(iscol,&first,&step);CHKERRQ(ierr);
1543fee21e36SBarry Smith   ierr = ISStride(iscol,&stride);CHKERRQ(ierr);
1544fee21e36SBarry Smith   if (stride && step == 1) {
154502834360SBarry Smith     /* special case of contiguous rows */
154657faeb66SBarry Smith     lens   = (int *) PetscMalloc((ncols+nrows+1)*sizeof(int));CHKPTRQ(lens);
154702834360SBarry Smith     starts = lens + ncols;
154802834360SBarry Smith     /* loop over new rows determining lens and starting points */
154902834360SBarry Smith     for (i=0; i<nrows; i++) {
1550a2744918SBarry Smith       kstart  = ai[irow[i]]+shift;
1551a2744918SBarry Smith       kend    = kstart + ailen[irow[i]];
155202834360SBarry Smith       for ( k=kstart; k<kend; k++ ) {
1553d8ced48eSBarry Smith         if (aj[k]+shift >= first) {
155402834360SBarry Smith           starts[i] = k;
155502834360SBarry Smith           break;
155602834360SBarry Smith 	}
155702834360SBarry Smith       }
1558a2744918SBarry Smith       sum = 0;
155902834360SBarry Smith       while (k < kend) {
1560d8ced48eSBarry Smith         if (aj[k++]+shift >= first+ncols) break;
1561a2744918SBarry Smith         sum++;
156202834360SBarry Smith       }
1563a2744918SBarry Smith       lens[i] = sum;
156402834360SBarry Smith     }
156502834360SBarry Smith     /* create submatrix */
1566cddf8d76SBarry Smith     if (scall == MAT_REUSE_MATRIX) {
156708480c60SBarry Smith       int n_cols,n_rows;
156808480c60SBarry Smith       ierr = MatGetSize(*B,&n_rows,&n_cols);CHKERRQ(ierr);
1569a8c6a408SBarry Smith       if (n_rows != nrows || n_cols != ncols) SETERRQ(PETSC_ERR_ARG_SIZ,0,"Reused submatrix wrong size");
1570d8ced48eSBarry Smith       ierr = MatZeroEntries(*B);CHKERRQ(ierr);
157108480c60SBarry Smith       C = *B;
15723a40ed3dSBarry Smith     } else {
157302834360SBarry Smith       ierr = MatCreateSeqAIJ(A->comm,nrows,ncols,0,lens,&C);CHKERRQ(ierr);
157408480c60SBarry Smith     }
1575db02288aSLois Curfman McInnes     c = (Mat_SeqAIJ*) C->data;
1576db02288aSLois Curfman McInnes 
157702834360SBarry Smith     /* loop over rows inserting into submatrix */
1578db02288aSLois Curfman McInnes     a_new    = c->a;
1579db02288aSLois Curfman McInnes     j_new    = c->j;
1580db02288aSLois Curfman McInnes     i_new    = c->i;
1581db02288aSLois Curfman McInnes     i_new[0] = -shift;
158202834360SBarry Smith     for (i=0; i<nrows; i++) {
1583a2744918SBarry Smith       ii    = starts[i];
1584a2744918SBarry Smith       lensi = lens[i];
1585a2744918SBarry Smith       for ( k=0; k<lensi; k++ ) {
1586a2744918SBarry Smith         *j_new++ = aj[ii+k] - first;
158702834360SBarry Smith       }
1588549d3d68SSatish Balay       ierr = PetscMemcpy(a_new,a->a + starts[i],lensi*sizeof(Scalar));CHKERRQ(ierr);
1589a2744918SBarry Smith       a_new      += lensi;
1590a2744918SBarry Smith       i_new[i+1]  = i_new[i] + lensi;
1591a2744918SBarry Smith       c->ilen[i]  = lensi;
159202834360SBarry Smith     }
1593606d414cSSatish Balay     ierr = PetscFree(lens);CHKERRQ(ierr);
15943a40ed3dSBarry Smith   } else {
159502834360SBarry Smith     ierr  = ISGetIndices(iscol,&icol);CHKERRQ(ierr);
15960452661fSBarry Smith     smap  = (int *) PetscMalloc((1+oldcols)*sizeof(int));CHKPTRQ(smap);
159702834360SBarry Smith     ssmap = smap + shift;
159899141d43SSatish Balay     lens  = (int *) PetscMalloc((1+nrows)*sizeof(int));CHKPTRQ(lens);
1599549d3d68SSatish Balay     ierr  = PetscMemzero(smap,oldcols*sizeof(int));CHKERRQ(ierr);
160017ab2063SBarry Smith     for ( i=0; i<ncols; i++ ) smap[icol[i]] = i+1;
160102834360SBarry Smith     /* determine lens of each row */
160202834360SBarry Smith     for (i=0; i<nrows; i++) {
1603d8ced48eSBarry Smith       kstart  = ai[irow[i]]+shift;
160402834360SBarry Smith       kend    = kstart + a->ilen[irow[i]];
160502834360SBarry Smith       lens[i] = 0;
160602834360SBarry Smith       for ( k=kstart; k<kend; k++ ) {
1607d8ced48eSBarry Smith         if (ssmap[aj[k]]) {
160802834360SBarry Smith           lens[i]++;
160902834360SBarry Smith         }
161002834360SBarry Smith       }
161102834360SBarry Smith     }
161217ab2063SBarry Smith     /* Create and fill new matrix */
1613a2744918SBarry Smith     if (scall == MAT_REUSE_MATRIX) {
16140f5bd95cSBarry Smith       PetscTruth equal;
16150f5bd95cSBarry Smith 
161699141d43SSatish Balay       c = (Mat_SeqAIJ *)((*B)->data);
1617a8c6a408SBarry Smith       if (c->m  != nrows || c->n != ncols) SETERRQ(PETSC_ERR_ARG_SIZ,0,"Cannot reuse matrix. wrong size");
16180f5bd95cSBarry Smith       ierr = PetscMemcmp(c->ilen,lens, c->m*sizeof(int),&equal);CHKERRQ(ierr);
16190f5bd95cSBarry Smith       if (!equal) {
1620a8c6a408SBarry Smith         SETERRQ(PETSC_ERR_ARG_SIZ,0,"Cannot reuse matrix. wrong no of nonzeros");
162199141d43SSatish Balay       }
1622549d3d68SSatish Balay       ierr = PetscMemzero(c->ilen,c->m*sizeof(int));CHKERRQ(ierr);
162308480c60SBarry Smith       C = *B;
16243a40ed3dSBarry Smith     } else {
162502834360SBarry Smith       ierr = MatCreateSeqAIJ(A->comm,nrows,ncols,0,lens,&C);CHKERRQ(ierr);
162608480c60SBarry Smith     }
162799141d43SSatish Balay     c = (Mat_SeqAIJ *)(C->data);
162817ab2063SBarry Smith     for (i=0; i<nrows; i++) {
162999141d43SSatish Balay       row    = irow[i];
163099141d43SSatish Balay       kstart = ai[row]+shift;
163199141d43SSatish Balay       kend   = kstart + a->ilen[row];
163299141d43SSatish Balay       mat_i  = c->i[i]+shift;
163399141d43SSatish Balay       mat_j  = c->j + mat_i;
163499141d43SSatish Balay       mat_a  = c->a + mat_i;
163599141d43SSatish Balay       mat_ilen = c->ilen + i;
163617ab2063SBarry Smith       for ( k=kstart; k<kend; k++ ) {
163799141d43SSatish Balay         if ((tcol=ssmap[a->j[k]])) {
163899141d43SSatish Balay           *mat_j++ = tcol - (!shift);
163999141d43SSatish Balay           *mat_a++ = a->a[k];
164099141d43SSatish Balay           (*mat_ilen)++;
164199141d43SSatish Balay 
164217ab2063SBarry Smith         }
164317ab2063SBarry Smith       }
164417ab2063SBarry Smith     }
164502834360SBarry Smith     /* Free work space */
164602834360SBarry Smith     ierr = ISRestoreIndices(iscol,&icol);CHKERRQ(ierr);
1647606d414cSSatish Balay     ierr = PetscFree(smap);CHKERRQ(ierr);
1648606d414cSSatish Balay     ierr = PetscFree(lens);CHKERRQ(ierr);
164902834360SBarry Smith   }
16506d4a8577SBarry Smith   ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
16516d4a8577SBarry Smith   ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
165217ab2063SBarry Smith 
165317ab2063SBarry Smith   ierr = ISRestoreIndices(isrow,&irow);CHKERRQ(ierr);
1654416022c9SBarry Smith   *B = C;
16553a40ed3dSBarry Smith   PetscFunctionReturn(0);
165617ab2063SBarry Smith }
165717ab2063SBarry Smith 
1658a871dcd8SBarry Smith /*
1659a871dcd8SBarry Smith */
16605615d1e5SSatish Balay #undef __FUNC__
16615615d1e5SSatish Balay #define __FUNC__ "MatILUFactor_SeqAIJ"
16625ef9f2a5SBarry Smith int MatILUFactor_SeqAIJ(Mat inA,IS row,IS col,MatILUInfo *info)
1663a871dcd8SBarry Smith {
166463b91edcSBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ *) inA->data;
166508480c60SBarry Smith   int        ierr;
166663b91edcSBarry Smith   Mat        outA;
1667b8a78c4aSBarry Smith   PetscTruth row_identity, col_identity;
166863b91edcSBarry Smith 
16693a40ed3dSBarry Smith   PetscFunctionBegin;
1670b8a78c4aSBarry Smith   if (info && info->levels != 0) SETERRQ(PETSC_ERR_SUP,0,"Only levels=0 supported for in-place ilu");
1671b8a78c4aSBarry Smith   ierr = ISIdentity(row,&row_identity);CHKERRQ(ierr);
1672b8a78c4aSBarry Smith   ierr = ISIdentity(col,&col_identity);CHKERRQ(ierr);
1673b8a78c4aSBarry Smith   if (!row_identity || !col_identity) {
1674b8a78c4aSBarry Smith     SETERRQ(1,1,"Row and column permutations must be identity for in-place ILU");
1675b8a78c4aSBarry Smith   }
1676a871dcd8SBarry Smith 
167763b91edcSBarry Smith   outA          = inA;
167863b91edcSBarry Smith   inA->factor   = FACTOR_LU;
167963b91edcSBarry Smith   a->row        = row;
168063b91edcSBarry Smith   a->col        = col;
1681c38d4ed2SBarry Smith   ierr = PetscObjectReference((PetscObject)row);CHKERRQ(ierr);
1682c38d4ed2SBarry Smith   ierr = PetscObjectReference((PetscObject)col);CHKERRQ(ierr);
168363b91edcSBarry Smith 
1684f0ec6fceSSatish Balay   /* Create the invert permutation so that it can be used in MatLUFactorNumeric() */
1685c38d4ed2SBarry Smith   if (a->icol) {ierr = ISDestroy(a->icol);CHKERRQ(ierr);} /* if this came from a previous factored; need to remove old one */
1686f0ec6fceSSatish Balay   ierr = ISInvertPermutation(col,&(a->icol));CHKERRQ(ierr);
16871e4dd532SSatish Balay   PLogObjectParent(inA,a->icol);
1688f0ec6fceSSatish Balay 
168994a9d846SBarry Smith   if (!a->solve_work) { /* this matrix may have been factored before */
16900452661fSBarry Smith     a->solve_work = (Scalar *) PetscMalloc( (a->m+1)*sizeof(Scalar));CHKPTRQ(a->solve_work);
169194a9d846SBarry Smith   }
169263b91edcSBarry Smith 
169308480c60SBarry Smith   if (!a->diag) {
1694*f1e2ffcdSBarry Smith     ierr = MatMarkDiagonal_SeqAIJ(inA);CHKERRQ(ierr);
169563b91edcSBarry Smith   }
169663b91edcSBarry Smith   ierr = MatLUFactorNumeric_SeqAIJ(inA,&outA);CHKERRQ(ierr);
16973a40ed3dSBarry Smith   PetscFunctionReturn(0);
1698a871dcd8SBarry Smith }
1699a871dcd8SBarry Smith 
170074cdf0dfSBarry Smith #include "pinclude/blaslapack.h"
17015615d1e5SSatish Balay #undef __FUNC__
17025615d1e5SSatish Balay #define __FUNC__ "MatScale_SeqAIJ"
17038f6be9afSLois Curfman McInnes int MatScale_SeqAIJ(Scalar *alpha,Mat inA)
1704f0b747eeSBarry Smith {
1705f0b747eeSBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ *) inA->data;
1706f0b747eeSBarry Smith   int        one = 1;
17073a40ed3dSBarry Smith 
17083a40ed3dSBarry Smith   PetscFunctionBegin;
1709f0b747eeSBarry Smith   BLscal_( &a->nz, alpha, a->a, &one );
1710f0b747eeSBarry Smith   PLogFlops(a->nz);
17113a40ed3dSBarry Smith   PetscFunctionReturn(0);
1712f0b747eeSBarry Smith }
1713f0b747eeSBarry Smith 
17145615d1e5SSatish Balay #undef __FUNC__
17155615d1e5SSatish Balay #define __FUNC__ "MatGetSubMatrices_SeqAIJ"
17167b2a1423SBarry Smith int MatGetSubMatrices_SeqAIJ(Mat A,int n, IS *irow,IS *icol,MatReuse scall,Mat **B)
1717cddf8d76SBarry Smith {
1718cddf8d76SBarry Smith   int ierr,i;
1719cddf8d76SBarry Smith 
17203a40ed3dSBarry Smith   PetscFunctionBegin;
1721cddf8d76SBarry Smith   if (scall == MAT_INITIAL_MATRIX) {
17220452661fSBarry Smith     *B = (Mat *) PetscMalloc( (n+1)*sizeof(Mat) );CHKPTRQ(*B);
1723cddf8d76SBarry Smith   }
1724cddf8d76SBarry Smith 
1725cddf8d76SBarry Smith   for ( i=0; i<n; i++ ) {
17266a6a5d1dSBarry Smith     ierr = MatGetSubMatrix_SeqAIJ(A,irow[i],icol[i],PETSC_DECIDE,scall,&(*B)[i]);CHKERRQ(ierr);
1727cddf8d76SBarry Smith   }
17283a40ed3dSBarry Smith   PetscFunctionReturn(0);
1729cddf8d76SBarry Smith }
1730cddf8d76SBarry Smith 
17315615d1e5SSatish Balay #undef __FUNC__
17325615d1e5SSatish Balay #define __FUNC__ "MatGetBlockSize_SeqAIJ"
17338f6be9afSLois Curfman McInnes int MatGetBlockSize_SeqAIJ(Mat A, int *bs)
17345a838052SSatish Balay {
1735f830108cSBarry Smith   PetscFunctionBegin;
17365a838052SSatish Balay   *bs = 1;
17373a40ed3dSBarry Smith   PetscFunctionReturn(0);
17385a838052SSatish Balay }
17395a838052SSatish Balay 
17405615d1e5SSatish Balay #undef __FUNC__
17415615d1e5SSatish Balay #define __FUNC__ "MatIncreaseOverlap_SeqAIJ"
17428f6be9afSLois Curfman McInnes int MatIncreaseOverlap_SeqAIJ(Mat A, int is_max, IS *is, int ov)
17434dcbc457SBarry Smith {
1744e4d965acSSatish Balay   Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data;
174506763907SSatish Balay   int        shift, row, i,j,k,l,m,n, *idx,ierr, *nidx, isz, val;
17468a047759SSatish Balay   int        start, end, *ai, *aj;
1747f1af5d2fSBarry Smith   PetscBT    table;
1748bbd702dbSSatish Balay 
17493a40ed3dSBarry Smith   PetscFunctionBegin;
17508a047759SSatish Balay   shift = a->indexshift;
1751e4d965acSSatish Balay   m     = a->m;
1752e4d965acSSatish Balay   ai    = a->i;
17538a047759SSatish Balay   aj    = a->j+shift;
17548a047759SSatish Balay 
1755a8c6a408SBarry Smith   if (ov < 0)  SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"illegal overlap value used");
175606763907SSatish Balay 
175706763907SSatish Balay   nidx  = (int *) PetscMalloc((m+1)*sizeof(int));CHKPTRQ(nidx);
17586831982aSBarry Smith   ierr  = PetscBTCreate(m,table);CHKERRQ(ierr);
175906763907SSatish Balay 
1760e4d965acSSatish Balay   for ( i=0; i<is_max; i++ ) {
1761b97fc60eSLois Curfman McInnes     /* Initialize the two local arrays */
1762e4d965acSSatish Balay     isz  = 0;
17636831982aSBarry Smith     ierr = PetscBTMemzero(m,table);CHKERRQ(ierr);
1764e4d965acSSatish Balay 
1765e4d965acSSatish Balay     /* Extract the indices, assume there can be duplicate entries */
17664dcbc457SBarry Smith     ierr = ISGetIndices(is[i],&idx);CHKERRQ(ierr);
176777c4ece6SBarry Smith     ierr = ISGetSize(is[i],&n);CHKERRQ(ierr);
1768e4d965acSSatish Balay 
1769dd097bc3SLois Curfman McInnes     /* Enter these into the temp arrays. I.e., mark table[row], enter row into new index */
1770e4d965acSSatish Balay     for ( j=0; j<n ; ++j){
1771f1af5d2fSBarry Smith       if(!PetscBTLookupSet(table, idx[j])) { nidx[isz++] = idx[j];}
17724dcbc457SBarry Smith     }
177306763907SSatish Balay     ierr = ISRestoreIndices(is[i],&idx);CHKERRQ(ierr);
177406763907SSatish Balay     ierr = ISDestroy(is[i]);CHKERRQ(ierr);
1775e4d965acSSatish Balay 
177604a348a9SBarry Smith     k = 0;
177704a348a9SBarry Smith     for ( j=0; j<ov; j++){ /* for each overlap */
177804a348a9SBarry Smith       n = isz;
177906763907SSatish Balay       for ( ; k<n ; k++){ /* do only those rows in nidx[k], which are not done yet */
1780e4d965acSSatish Balay         row   = nidx[k];
1781e4d965acSSatish Balay         start = ai[row];
1782e4d965acSSatish Balay         end   = ai[row+1];
178304a348a9SBarry Smith         for ( l = start; l<end ; l++){
17848a047759SSatish Balay           val = aj[l] + shift;
1785f1af5d2fSBarry Smith           if (!PetscBTLookupSet(table,val)) {nidx[isz++] = val;}
1786e4d965acSSatish Balay         }
1787e4d965acSSatish Balay       }
1788e4d965acSSatish Balay     }
1789029af93fSBarry Smith     ierr = ISCreateGeneral(PETSC_COMM_SELF, isz, nidx, (is+i));CHKERRQ(ierr);
1790e4d965acSSatish Balay   }
17916831982aSBarry Smith   ierr = PetscBTDestroy(table);CHKERRQ(ierr);
1792606d414cSSatish Balay   ierr = PetscFree(nidx);CHKERRQ(ierr);
17933a40ed3dSBarry Smith   PetscFunctionReturn(0);
17944dcbc457SBarry Smith }
179517ab2063SBarry Smith 
17960513a670SBarry Smith /* -------------------------------------------------------------- */
17970513a670SBarry Smith #undef __FUNC__
17980513a670SBarry Smith #define __FUNC__ "MatPermute_SeqAIJ"
17990513a670SBarry Smith int MatPermute_SeqAIJ(Mat A, IS rowp, IS colp, Mat *B)
18000513a670SBarry Smith {
18010513a670SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data;
18020513a670SBarry Smith   Scalar     *vwork;
18030513a670SBarry Smith   int        i, ierr, nz, m = a->m, n = a->n, *cwork;
18040513a670SBarry Smith   int        *row,*col,*cnew,j,*lens;
180556cd22aeSBarry Smith   IS         icolp,irowp;
18060513a670SBarry Smith 
18073a40ed3dSBarry Smith   PetscFunctionBegin;
180856cd22aeSBarry Smith   ierr = ISInvertPermutation(rowp,&irowp);CHKERRQ(ierr);
180956cd22aeSBarry Smith   ierr = ISGetIndices(irowp,&row);CHKERRQ(ierr);
181056cd22aeSBarry Smith   ierr = ISInvertPermutation(colp,&icolp);CHKERRQ(ierr);
181156cd22aeSBarry Smith   ierr = ISGetIndices(icolp,&col);CHKERRQ(ierr);
18120513a670SBarry Smith 
18130513a670SBarry Smith   /* determine lengths of permuted rows */
18140513a670SBarry Smith   lens = (int *) PetscMalloc( (m+1)*sizeof(int) );CHKPTRQ(lens);
18150513a670SBarry Smith   for (i=0; i<m; i++ ) {
18160513a670SBarry Smith     lens[row[i]] = a->i[i+1] - a->i[i];
18170513a670SBarry Smith   }
18180513a670SBarry Smith   ierr = MatCreateSeqAIJ(A->comm,m,n,0,lens,B);CHKERRQ(ierr);
1819606d414cSSatish Balay   ierr = PetscFree(lens);CHKERRQ(ierr);
18200513a670SBarry Smith 
18210513a670SBarry Smith   cnew = (int *) PetscMalloc( n*sizeof(int) );CHKPTRQ(cnew);
18220513a670SBarry Smith   for (i=0; i<m; i++) {
18230513a670SBarry Smith     ierr = MatGetRow(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr);
18240513a670SBarry Smith     for (j=0; j<nz; j++ ) { cnew[j] = col[cwork[j]];}
18250513a670SBarry Smith     ierr = MatSetValues(*B,1,&row[i],nz,cnew,vwork,INSERT_VALUES);CHKERRQ(ierr);
18260513a670SBarry Smith     ierr = MatRestoreRow(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr);
18270513a670SBarry Smith   }
1828606d414cSSatish Balay   ierr = PetscFree(cnew);CHKERRQ(ierr);
18290513a670SBarry Smith   ierr = MatAssemblyBegin(*B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
18300513a670SBarry Smith   ierr = MatAssemblyEnd(*B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
183156cd22aeSBarry Smith   ierr = ISRestoreIndices(irowp,&row);CHKERRQ(ierr);
183256cd22aeSBarry Smith   ierr = ISRestoreIndices(icolp,&col);CHKERRQ(ierr);
183356cd22aeSBarry Smith   ierr = ISDestroy(irowp);CHKERRQ(ierr);
183456cd22aeSBarry Smith   ierr = ISDestroy(icolp);CHKERRQ(ierr);
18353a40ed3dSBarry Smith   PetscFunctionReturn(0);
18360513a670SBarry Smith }
18370513a670SBarry Smith 
18385615d1e5SSatish Balay #undef __FUNC__
18395615d1e5SSatish Balay #define __FUNC__ "MatPrintHelp_SeqAIJ"
1840682d7d0cSBarry Smith int MatPrintHelp_SeqAIJ(Mat A)
1841682d7d0cSBarry Smith {
1842c38d4ed2SBarry Smith   static PetscTruth called = PETSC_FALSE;
1843682d7d0cSBarry Smith   MPI_Comm          comm = A->comm;
1844d132466eSBarry Smith   int               ierr;
1845682d7d0cSBarry Smith 
18463a40ed3dSBarry Smith   PetscFunctionBegin;
1847c38d4ed2SBarry Smith   if (called) {PetscFunctionReturn(0);} else called = PETSC_TRUE;
1848d132466eSBarry Smith   ierr = (*PetscHelpPrintf)(comm," Options for MATSEQAIJ and MATMPIAIJ matrix formats (the defaults):\n");CHKERRQ(ierr);
1849d132466eSBarry Smith   ierr = (*PetscHelpPrintf)(comm,"  -mat_lu_pivotthreshold <threshold>: Set pivoting threshold\n");CHKERRQ(ierr);
1850d132466eSBarry Smith   ierr = (*PetscHelpPrintf)(comm,"  -mat_aij_oneindex: internal indices begin at 1 instead of the default 0.\n");CHKERRQ(ierr);
1851d132466eSBarry Smith   ierr = (*PetscHelpPrintf)(comm,"  -mat_aij_no_inode: Do not use inodes\n");CHKERRQ(ierr);
1852d132466eSBarry Smith   ierr = (*PetscHelpPrintf)(comm,"  -mat_aij_inode_limit <limit>: Set inode limit (max limit=5)\n");CHKERRQ(ierr);
1853aa482453SBarry Smith #if defined(PETSC_HAVE_ESSL)
1854d132466eSBarry Smith   ierr = (*PetscHelpPrintf)(comm,"  -mat_aij_essl: Use IBM sparse LU factorization and solve.\n");CHKERRQ(ierr);
1855682d7d0cSBarry Smith #endif
18563a40ed3dSBarry Smith   PetscFunctionReturn(0);
1857682d7d0cSBarry Smith }
18588f6be9afSLois Curfman McInnes extern int MatEqual_SeqAIJ(Mat A,Mat B, PetscTruth* flg);
1859a93ec695SBarry Smith extern int MatFDColoringCreate_SeqAIJ(Mat,ISColoring,MatFDColoring);
1860a93ec695SBarry Smith extern int MatColoringPatch_SeqAIJ(Mat,int,int *,ISColoring *);
1861a93ec695SBarry Smith 
1862cb5b572fSBarry Smith #undef __FUNC__
1863cb5b572fSBarry Smith #define __FUNC__ "MatCopy_SeqAIJ"
1864cb5b572fSBarry Smith int MatCopy_SeqAIJ(Mat A,Mat B,MatStructure str)
1865cb5b572fSBarry Smith {
1866be6bf707SBarry Smith   int    ierr;
1867cb5b572fSBarry Smith 
1868cb5b572fSBarry Smith   PetscFunctionBegin;
1869be6bf707SBarry Smith   if (str == SAME_NONZERO_PATTERN && B->type == MATSEQAIJ) {
1870be6bf707SBarry Smith     Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data;
1871be6bf707SBarry Smith     Mat_SeqAIJ *b = (Mat_SeqAIJ *) B->data;
1872be6bf707SBarry Smith 
1873be6bf707SBarry Smith     if (a->i[a->m]+a->indexshift != b->i[b->m]+a->indexshift) {
1874be6bf707SBarry Smith       SETERRQ(1,1,"Number of nonzeros in two matrices are different");
1875cb5b572fSBarry Smith     }
1876549d3d68SSatish Balay     ierr = PetscMemcpy(b->a,a->a,(a->i[a->m]+a->indexshift)*sizeof(Scalar));CHKERRQ(ierr);
1877cb5b572fSBarry Smith   } else {
1878cb5b572fSBarry Smith     ierr = MatCopy_Basic(A,B,str);CHKERRQ(ierr);
1879cb5b572fSBarry Smith   }
1880cb5b572fSBarry Smith   PetscFunctionReturn(0);
1881cb5b572fSBarry Smith }
1882cb5b572fSBarry Smith 
1883682d7d0cSBarry Smith /* -------------------------------------------------------------------*/
18840a6ffc59SBarry Smith static struct _MatOps MatOps_Values = {MatSetValues_SeqAIJ,
1885cb5b572fSBarry Smith        MatGetRow_SeqAIJ,
1886cb5b572fSBarry Smith        MatRestoreRow_SeqAIJ,
1887cb5b572fSBarry Smith        MatMult_SeqAIJ,
1888cb5b572fSBarry Smith        MatMultAdd_SeqAIJ,
1889cb5b572fSBarry Smith        MatMultTrans_SeqAIJ,
1890cb5b572fSBarry Smith        MatMultTransAdd_SeqAIJ,
1891cb5b572fSBarry Smith        MatSolve_SeqAIJ,
1892cb5b572fSBarry Smith        MatSolveAdd_SeqAIJ,
1893cb5b572fSBarry Smith        MatSolveTrans_SeqAIJ,
1894cb5b572fSBarry Smith        MatSolveTransAdd_SeqAIJ,
1895cb5b572fSBarry Smith        MatLUFactor_SeqAIJ,
1896cb5b572fSBarry Smith        0,
189717ab2063SBarry Smith        MatRelax_SeqAIJ,
189817ab2063SBarry Smith        MatTranspose_SeqAIJ,
1899cb5b572fSBarry Smith        MatGetInfo_SeqAIJ,
1900cb5b572fSBarry Smith        MatEqual_SeqAIJ,
1901cb5b572fSBarry Smith        MatGetDiagonal_SeqAIJ,
1902cb5b572fSBarry Smith        MatDiagonalScale_SeqAIJ,
1903cb5b572fSBarry Smith        MatNorm_SeqAIJ,
1904cb5b572fSBarry Smith        0,
1905cb5b572fSBarry Smith        MatAssemblyEnd_SeqAIJ,
190617ab2063SBarry Smith        MatCompress_SeqAIJ,
1907cb5b572fSBarry Smith        MatSetOption_SeqAIJ,
1908cb5b572fSBarry Smith        MatZeroEntries_SeqAIJ,
1909cb5b572fSBarry Smith        MatZeroRows_SeqAIJ,
1910cb5b572fSBarry Smith        MatLUFactorSymbolic_SeqAIJ,
1911cb5b572fSBarry Smith        MatLUFactorNumeric_SeqAIJ,
1912cb5b572fSBarry Smith        0,
1913cb5b572fSBarry Smith        0,
1914cb5b572fSBarry Smith        MatGetSize_SeqAIJ,
1915cb5b572fSBarry Smith        MatGetSize_SeqAIJ,
1916cb5b572fSBarry Smith        MatGetOwnershipRange_SeqAIJ,
1917cb5b572fSBarry Smith        MatILUFactorSymbolic_SeqAIJ,
1918cb5b572fSBarry Smith        0,
1919cb5b572fSBarry Smith        0,
1920cb5b572fSBarry Smith        0,
1921be6bf707SBarry Smith        MatDuplicate_SeqAIJ,
1922cb5b572fSBarry Smith        0,
1923cb5b572fSBarry Smith        0,
1924cb5b572fSBarry Smith        MatILUFactor_SeqAIJ,
1925cb5b572fSBarry Smith        0,
1926cb5b572fSBarry Smith        0,
1927cb5b572fSBarry Smith        MatGetSubMatrices_SeqAIJ,
1928cb5b572fSBarry Smith        MatIncreaseOverlap_SeqAIJ,
1929cb5b572fSBarry Smith        MatGetValues_SeqAIJ,
1930cb5b572fSBarry Smith        MatCopy_SeqAIJ,
1931f0b747eeSBarry Smith        MatPrintHelp_SeqAIJ,
1932cb5b572fSBarry Smith        MatScale_SeqAIJ,
1933cb5b572fSBarry Smith        0,
1934cb5b572fSBarry Smith        0,
19356945ee14SBarry Smith        MatILUDTFactor_SeqAIJ,
19366945ee14SBarry Smith        MatGetBlockSize_SeqAIJ,
19373b2fbd54SBarry Smith        MatGetRowIJ_SeqAIJ,
19383b2fbd54SBarry Smith        MatRestoreRowIJ_SeqAIJ,
19393b2fbd54SBarry Smith        MatGetColumnIJ_SeqAIJ,
1940a93ec695SBarry Smith        MatRestoreColumnIJ_SeqAIJ,
1941a93ec695SBarry Smith        MatFDColoringCreate_SeqAIJ,
19420513a670SBarry Smith        MatColoringPatch_SeqAIJ,
19430513a670SBarry Smith        0,
1944cda55fadSBarry Smith        MatPermute_SeqAIJ,
1945cda55fadSBarry Smith        0,
1946cda55fadSBarry Smith        0,
1947cda55fadSBarry Smith        0,
1948cda55fadSBarry Smith        0,
1949cda55fadSBarry Smith        MatGetMaps_Petsc};
195017ab2063SBarry Smith 
195117ab2063SBarry Smith extern int MatUseSuperLU_SeqAIJ(Mat);
195217ab2063SBarry Smith extern int MatUseEssl_SeqAIJ(Mat);
195317ab2063SBarry Smith extern int MatUseDXML_SeqAIJ(Mat);
195417ab2063SBarry Smith 
1955fb2e594dSBarry Smith EXTERN_C_BEGIN
19565615d1e5SSatish Balay #undef __FUNC__
1957bef8e0ddSBarry Smith #define __FUNC__ "MatSeqAIJSetColumnIndices_SeqAIJ"
195815091d37SBarry Smith 
1959bef8e0ddSBarry Smith int MatSeqAIJSetColumnIndices_SeqAIJ(Mat mat,int *indices)
1960bef8e0ddSBarry Smith {
1961bef8e0ddSBarry Smith   Mat_SeqAIJ *aij = (Mat_SeqAIJ *)mat->data;
1962bef8e0ddSBarry Smith   int        i,nz,n;
1963bef8e0ddSBarry Smith 
1964bef8e0ddSBarry Smith   PetscFunctionBegin;
1965bef8e0ddSBarry Smith   if (aij->indexshift) SETERRQ(1,1,"No support with 1 based indexing");
1966bef8e0ddSBarry Smith 
1967bef8e0ddSBarry Smith   nz = aij->maxnz;
1968bef8e0ddSBarry Smith   n  = aij->n;
1969bef8e0ddSBarry Smith   for (i=0; i<nz; i++) {
1970bef8e0ddSBarry Smith     aij->j[i] = indices[i];
1971bef8e0ddSBarry Smith   }
1972bef8e0ddSBarry Smith   aij->nz = nz;
1973bef8e0ddSBarry Smith   for ( i=0; i<n; i++ ) {
1974bef8e0ddSBarry Smith     aij->ilen[i] = aij->imax[i];
1975bef8e0ddSBarry Smith   }
1976bef8e0ddSBarry Smith 
1977bef8e0ddSBarry Smith   PetscFunctionReturn(0);
1978bef8e0ddSBarry Smith }
1979fb2e594dSBarry Smith EXTERN_C_END
1980bef8e0ddSBarry Smith 
1981bef8e0ddSBarry Smith #undef __FUNC__
1982bef8e0ddSBarry Smith #define __FUNC__ "MatSeqAIJSetColumnIndices"
1983bef8e0ddSBarry Smith /*@
1984bef8e0ddSBarry Smith     MatSeqAIJSetColumnIndices - Set the column indices for all the rows
1985bef8e0ddSBarry Smith        in the matrix.
1986bef8e0ddSBarry Smith 
1987bef8e0ddSBarry Smith   Input Parameters:
1988bef8e0ddSBarry Smith +  mat - the SeqAIJ matrix
1989bef8e0ddSBarry Smith -  indices - the column indices
1990bef8e0ddSBarry Smith 
199115091d37SBarry Smith   Level: advanced
199215091d37SBarry Smith 
1993bef8e0ddSBarry Smith   Notes:
1994bef8e0ddSBarry Smith     This can be called if you have precomputed the nonzero structure of the
1995bef8e0ddSBarry Smith   matrix and want to provide it to the matrix object to improve the performance
1996bef8e0ddSBarry Smith   of the MatSetValues() operation.
1997bef8e0ddSBarry Smith 
1998bef8e0ddSBarry Smith     You MUST have set the correct numbers of nonzeros per row in the call to
1999bef8e0ddSBarry Smith   MatCreateSeqAIJ().
2000bef8e0ddSBarry Smith 
2001bef8e0ddSBarry Smith     MUST be called before any calls to MatSetValues();
2002bef8e0ddSBarry Smith 
2003bef8e0ddSBarry Smith @*/
2004bef8e0ddSBarry Smith int MatSeqAIJSetColumnIndices(Mat mat,int *indices)
2005bef8e0ddSBarry Smith {
2006bef8e0ddSBarry Smith   int ierr,(*f)(Mat,int *);
2007bef8e0ddSBarry Smith 
2008bef8e0ddSBarry Smith   PetscFunctionBegin;
2009bef8e0ddSBarry Smith   PetscValidHeaderSpecific(mat,MAT_COOKIE);
2010549d3d68SSatish Balay   ierr = PetscObjectQueryFunction((PetscObject)mat,"MatSeqAIJSetColumnIndices_C",(void **)&f);CHKERRQ(ierr);
2011bef8e0ddSBarry Smith   if (f) {
2012bef8e0ddSBarry Smith     ierr = (*f)(mat,indices);CHKERRQ(ierr);
2013bef8e0ddSBarry Smith   } else {
2014bef8e0ddSBarry Smith     SETERRQ(1,1,"Wrong type of matrix to set column indices");
2015bef8e0ddSBarry Smith   }
2016bef8e0ddSBarry Smith   PetscFunctionReturn(0);
2017bef8e0ddSBarry Smith }
2018bef8e0ddSBarry Smith 
2019be6bf707SBarry Smith /* ----------------------------------------------------------------------------------------*/
2020be6bf707SBarry Smith 
2021fb2e594dSBarry Smith EXTERN_C_BEGIN
2022be6bf707SBarry Smith #undef __FUNC__
2023be6bf707SBarry Smith #define __FUNC__ "MatStoreValues_SeqAIJ"
2024be6bf707SBarry Smith int MatStoreValues_SeqAIJ(Mat mat)
2025be6bf707SBarry Smith {
2026be6bf707SBarry Smith   Mat_SeqAIJ *aij = (Mat_SeqAIJ *)mat->data;
2027549d3d68SSatish Balay   int        nz = aij->i[aij->m]+aij->indexshift,ierr;
2028be6bf707SBarry Smith 
2029be6bf707SBarry Smith   PetscFunctionBegin;
2030be6bf707SBarry Smith   if (aij->nonew != 1) {
2031be6bf707SBarry Smith     SETERRQ(1,1,"Must call MatSetOption(A,MAT_NO_NEW_NONZERO_LOCATIONS);first");
2032be6bf707SBarry Smith   }
2033be6bf707SBarry Smith 
2034be6bf707SBarry Smith   /* allocate space for values if not already there */
2035be6bf707SBarry Smith   if (!aij->saved_values) {
2036be6bf707SBarry Smith     aij->saved_values = (Scalar *) PetscMalloc(nz*sizeof(Scalar));CHKPTRQ(aij->saved_values);
2037be6bf707SBarry Smith   }
2038be6bf707SBarry Smith 
2039be6bf707SBarry Smith   /* copy values over */
2040549d3d68SSatish Balay   ierr = PetscMemcpy(aij->saved_values,aij->a,nz*sizeof(Scalar));CHKERRQ(ierr);
2041be6bf707SBarry Smith   PetscFunctionReturn(0);
2042be6bf707SBarry Smith }
2043fb2e594dSBarry Smith EXTERN_C_END
2044be6bf707SBarry Smith 
2045be6bf707SBarry Smith #undef __FUNC__
2046be6bf707SBarry Smith #define __FUNC__ "MatStoreValues"
2047be6bf707SBarry Smith /*@
2048be6bf707SBarry Smith     MatStoreValues - Stashes a copy of the matrix values; this allows, for
2049be6bf707SBarry Smith        example, reuse of the linear part of a Jacobian, while recomputing the
2050be6bf707SBarry Smith        nonlinear portion.
2051be6bf707SBarry Smith 
2052be6bf707SBarry Smith    Collect on Mat
2053be6bf707SBarry Smith 
2054be6bf707SBarry Smith   Input Parameters:
2055be6bf707SBarry Smith .  mat - the matrix (currently on AIJ matrices support this option)
2056be6bf707SBarry Smith 
205715091d37SBarry Smith   Level: advanced
205815091d37SBarry Smith 
2059be6bf707SBarry Smith   Common Usage, with SNESSolve():
2060be6bf707SBarry Smith $    Create Jacobian matrix
2061be6bf707SBarry Smith $    Set linear terms into matrix
2062be6bf707SBarry Smith $    Apply boundary conditions to matrix, at this time matrix must have
2063be6bf707SBarry Smith $      final nonzero structure (i.e. setting the nonlinear terms and applying
2064be6bf707SBarry Smith $      boundary conditions again will not change the nonzero structure
2065be6bf707SBarry Smith $    ierr = MatSetOption(mat,MAT_NO_NEW_NONZERO_LOCATIONS);
2066be6bf707SBarry Smith $    ierr = MatStoreValues(mat);
2067be6bf707SBarry Smith $    Call SNESSetJacobian() with matrix
2068be6bf707SBarry Smith $    In your Jacobian routine
2069be6bf707SBarry Smith $      ierr = MatRetrieveValues(mat);
2070be6bf707SBarry Smith $      Set nonlinear terms in matrix
2071be6bf707SBarry Smith 
2072be6bf707SBarry Smith   Common Usage without SNESSolve(), i.e. when you handle nonlinear solve yourself:
2073be6bf707SBarry Smith $    // build linear portion of Jacobian
2074be6bf707SBarry Smith $    ierr = MatSetOption(mat,MAT_NO_NEW_NONZERO_LOCATIONS);
2075be6bf707SBarry Smith $    ierr = MatStoreValues(mat);
2076be6bf707SBarry Smith $    loop over nonlinear iterations
2077be6bf707SBarry Smith $       ierr = MatRetrieveValues(mat);
2078be6bf707SBarry Smith $       // call MatSetValues(mat,...) to set nonliner portion of Jacobian
2079be6bf707SBarry Smith $       // call MatAssemblyBegin/End() on matrix
2080be6bf707SBarry Smith $       Solve linear system with Jacobian
2081be6bf707SBarry Smith $    endloop
2082be6bf707SBarry Smith 
2083be6bf707SBarry Smith   Notes:
2084be6bf707SBarry Smith     Matrix must already be assemblied before calling this routine
2085be6bf707SBarry Smith     Must set the matrix option MatSetOption(mat,MAT_NO_NEW_NONZERO_LOCATIONS); before
2086be6bf707SBarry Smith     calling this routine.
2087be6bf707SBarry Smith 
2088be6bf707SBarry Smith .seealso: MatRetrieveValues()
2089be6bf707SBarry Smith 
2090be6bf707SBarry Smith @*/
2091be6bf707SBarry Smith int MatStoreValues(Mat mat)
2092be6bf707SBarry Smith {
2093be6bf707SBarry Smith   int ierr,(*f)(Mat);
2094be6bf707SBarry Smith 
2095be6bf707SBarry Smith   PetscFunctionBegin;
2096be6bf707SBarry Smith   PetscValidHeaderSpecific(mat,MAT_COOKIE);
2097be6bf707SBarry Smith   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,0,"Not for unassembled matrix");
2098be6bf707SBarry Smith   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,0,"Not for factored matrix");
2099be6bf707SBarry Smith 
2100c5d6004cSBarry Smith   ierr = PetscObjectQueryFunction((PetscObject)mat,"MatStoreValues_C",(void **)&f);CHKERRQ(ierr);
2101be6bf707SBarry Smith   if (f) {
2102be6bf707SBarry Smith     ierr = (*f)(mat);CHKERRQ(ierr);
2103be6bf707SBarry Smith   } else {
2104be6bf707SBarry Smith     SETERRQ(1,1,"Wrong type of matrix to store values");
2105be6bf707SBarry Smith   }
2106be6bf707SBarry Smith   PetscFunctionReturn(0);
2107be6bf707SBarry Smith }
2108be6bf707SBarry Smith 
2109fb2e594dSBarry Smith EXTERN_C_BEGIN
2110be6bf707SBarry Smith #undef __FUNC__
2111be6bf707SBarry Smith #define __FUNC__ "MatRetrieveValues_SeqAIJ"
2112be6bf707SBarry Smith int MatRetrieveValues_SeqAIJ(Mat mat)
2113be6bf707SBarry Smith {
2114be6bf707SBarry Smith   Mat_SeqAIJ *aij = (Mat_SeqAIJ *)mat->data;
2115549d3d68SSatish Balay   int        nz = aij->i[aij->m]+aij->indexshift,ierr;
2116be6bf707SBarry Smith 
2117be6bf707SBarry Smith   PetscFunctionBegin;
2118be6bf707SBarry Smith   if (aij->nonew != 1) {
2119be6bf707SBarry Smith     SETERRQ(1,1,"Must call MatSetOption(A,MAT_NO_NEW_NONZERO_LOCATIONS);first");
2120be6bf707SBarry Smith   }
2121be6bf707SBarry Smith   if (!aij->saved_values) {
2122be6bf707SBarry Smith     SETERRQ(1,1,"Must call MatStoreValues(A);first");
2123be6bf707SBarry Smith   }
2124be6bf707SBarry Smith 
2125be6bf707SBarry Smith   /* copy values over */
2126549d3d68SSatish Balay   ierr = PetscMemcpy(aij->a, aij->saved_values,nz*sizeof(Scalar));CHKERRQ(ierr);
2127be6bf707SBarry Smith   PetscFunctionReturn(0);
2128be6bf707SBarry Smith }
2129fb2e594dSBarry Smith EXTERN_C_END
2130be6bf707SBarry Smith 
2131be6bf707SBarry Smith #undef __FUNC__
2132be6bf707SBarry Smith #define __FUNC__ "MatRetrieveValues"
2133be6bf707SBarry Smith /*@
2134be6bf707SBarry Smith     MatRetrieveValues - Retrieves the copy of the matrix values; this allows, for
2135be6bf707SBarry Smith        example, reuse of the linear part of a Jacobian, while recomputing the
2136be6bf707SBarry Smith        nonlinear portion.
2137be6bf707SBarry Smith 
2138be6bf707SBarry Smith    Collect on Mat
2139be6bf707SBarry Smith 
2140be6bf707SBarry Smith   Input Parameters:
2141be6bf707SBarry Smith .  mat - the matrix (currently on AIJ matrices support this option)
2142be6bf707SBarry Smith 
214315091d37SBarry Smith   Level: advanced
214415091d37SBarry Smith 
2145be6bf707SBarry Smith .seealso: MatStoreValues()
2146be6bf707SBarry Smith 
2147be6bf707SBarry Smith @*/
2148be6bf707SBarry Smith int MatRetrieveValues(Mat mat)
2149be6bf707SBarry Smith {
2150be6bf707SBarry Smith   int ierr,(*f)(Mat);
2151be6bf707SBarry Smith 
2152be6bf707SBarry Smith   PetscFunctionBegin;
2153be6bf707SBarry Smith   PetscValidHeaderSpecific(mat,MAT_COOKIE);
2154be6bf707SBarry Smith   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,0,"Not for unassembled matrix");
2155be6bf707SBarry Smith   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,0,"Not for factored matrix");
2156be6bf707SBarry Smith 
2157c5d6004cSBarry Smith   ierr = PetscObjectQueryFunction((PetscObject)mat,"MatRetrieveValues_C",(void **)&f);CHKERRQ(ierr);
2158be6bf707SBarry Smith   if (f) {
2159be6bf707SBarry Smith     ierr = (*f)(mat);CHKERRQ(ierr);
2160be6bf707SBarry Smith   } else {
2161be6bf707SBarry Smith     SETERRQ(1,1,"Wrong type of matrix to retrieve values");
2162be6bf707SBarry Smith   }
2163be6bf707SBarry Smith   PetscFunctionReturn(0);
2164be6bf707SBarry Smith }
2165be6bf707SBarry Smith 
2166be6bf707SBarry Smith /* --------------------------------------------------------------------------------*/
2167cb5b572fSBarry Smith 
2168bef8e0ddSBarry Smith #undef __FUNC__
21695615d1e5SSatish Balay #define __FUNC__ "MatCreateSeqAIJ"
217017ab2063SBarry Smith /*@C
2171682d7d0cSBarry Smith    MatCreateSeqAIJ - Creates a sparse matrix in AIJ (compressed row) format
21720d15e28bSLois Curfman McInnes    (the default parallel PETSc format).  For good matrix assembly performance
21736e62573dSLois Curfman McInnes    the user should preallocate the matrix storage by setting the parameter nz
217451c19458SBarry Smith    (or the array nnz).  By setting these parameters accurately, performance
21752bd5e0b2SLois Curfman McInnes    during matrix assembly can be increased by more than a factor of 50.
217617ab2063SBarry Smith 
2177db81eaa0SLois Curfman McInnes    Collective on MPI_Comm
2178db81eaa0SLois Curfman McInnes 
217917ab2063SBarry Smith    Input Parameters:
2180db81eaa0SLois Curfman McInnes +  comm - MPI communicator, set to PETSC_COMM_SELF
218117ab2063SBarry Smith .  m - number of rows
218217ab2063SBarry Smith .  n - number of columns
218317ab2063SBarry Smith .  nz - number of nonzeros per row (same for all rows)
218451c19458SBarry Smith -  nnz - array containing the number of nonzeros in the various rows
21852bd5e0b2SLois Curfman McInnes          (possibly different for each row) or PETSC_NULL
218617ab2063SBarry Smith 
218717ab2063SBarry Smith    Output Parameter:
2188416022c9SBarry Smith .  A - the matrix
218917ab2063SBarry Smith 
2190b259b22eSLois Curfman McInnes    Notes:
219117ab2063SBarry Smith    The AIJ format (also called the Yale sparse matrix format or
219217ab2063SBarry Smith    compressed row storage), is fully compatible with standard Fortran 77
21930002213bSLois Curfman McInnes    storage.  That is, the stored row and column indices can begin at
219444cd7ae7SLois Curfman McInnes    either one (as in Fortran) or zero.  See the users' manual for details.
219517ab2063SBarry Smith 
219617ab2063SBarry Smith    Specify the preallocated storage with either nz or nnz (not both).
2197a40aa06bSLois Curfman McInnes    Set nz=PETSC_DEFAULT and nnz=PETSC_NULL for PETSc to control dynamic memory
21983d323bbdSBarry Smith    allocation.  For large problems you MUST preallocate memory or you
21996da5968aSLois Curfman McInnes    will get TERRIBLE performance, see the users' manual chapter on matrices.
220017ab2063SBarry Smith 
2201682d7d0cSBarry Smith    By default, this format uses inodes (identical nodes) when possible, to
22024fca80b9SLois Curfman McInnes    improve numerical efficiency of matrix-vector products and solves. We
2203682d7d0cSBarry Smith    search for consecutive rows with the same nonzero structure, thereby
22046c7ebb05SLois Curfman McInnes    reusing matrix information to achieve increased efficiency.
22056c7ebb05SLois Curfman McInnes 
22066c7ebb05SLois Curfman McInnes    Options Database Keys:
2207db81eaa0SLois Curfman McInnes +  -mat_aij_no_inode  - Do not use inodes
2208db81eaa0SLois Curfman McInnes .  -mat_aij_inode_limit <limit> - Sets inode limit (max limit=5)
2209db81eaa0SLois Curfman McInnes -  -mat_aij_oneindex - Internally use indexing starting at 1
2210db81eaa0SLois Curfman McInnes         rather than 0.  Note that when calling MatSetValues(),
2211db81eaa0SLois Curfman McInnes         the user still MUST index entries starting at 0!
221217ab2063SBarry Smith 
2213027ccd11SLois Curfman McInnes    Level: intermediate
2214027ccd11SLois Curfman McInnes 
2215bef8e0ddSBarry Smith .seealso: MatCreate(), MatCreateMPIAIJ(), MatSetValues(), MatSeqAIJSetColumnIndices()
221617ab2063SBarry Smith @*/
2217416022c9SBarry Smith int MatCreateSeqAIJ(MPI_Comm comm,int m,int n,int nz,int *nnz, Mat *A)
221817ab2063SBarry Smith {
2219416022c9SBarry Smith   Mat        B;
2220416022c9SBarry Smith   Mat_SeqAIJ *b;
2221f1af5d2fSBarry Smith   int        i, len, ierr, size;
2222f1af5d2fSBarry Smith   PetscTruth flg;
22236945ee14SBarry Smith 
22243a40ed3dSBarry Smith   PetscFunctionBegin;
2225d132466eSBarry Smith   ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr);
2226a8c6a408SBarry Smith   if (size > 1) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Comm must be of size 1");
2227d5d45c9bSBarry Smith 
2228b73539f3SBarry Smith   if (nz < -2) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,0,"nz cannot be less than -2: value %d",nz);
2229b73539f3SBarry Smith   if (nnz) {
2230b73539f3SBarry Smith     for (i=0; i<m; i++) {
2231b73539f3SBarry 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]);
2232b73539f3SBarry Smith     }
2233b73539f3SBarry Smith   }
2234b73539f3SBarry Smith 
2235416022c9SBarry Smith   *A                  = 0;
22363f1db9ecSBarry Smith   PetscHeaderCreate(B,_p_Mat,struct _MatOps,MAT_COOKIE,MATSEQAIJ,"Mat",comm,MatDestroy,MatView);
2237416022c9SBarry Smith   PLogObjectCreate(B);
22380452661fSBarry Smith   B->data             = (void *) (b = PetscNew(Mat_SeqAIJ));CHKPTRQ(b);
2239549d3d68SSatish Balay   ierr = PetscMemzero(b,sizeof(Mat_SeqAIJ));CHKERRQ(ierr);
2240549d3d68SSatish Balay   ierr = PetscMemcpy(B->ops,&MatOps_Values,sizeof(struct _MatOps));CHKERRQ(ierr);
2241e1311b90SBarry Smith   B->ops->destroy          = MatDestroy_SeqAIJ;
2242e1311b90SBarry Smith   B->ops->view             = MatView_SeqAIJ;
2243416022c9SBarry Smith   B->factor           = 0;
2244416022c9SBarry Smith   B->lupivotthreshold = 1.0;
224590f02eecSBarry Smith   B->mapping          = 0;
2246f1af5d2fSBarry Smith   ierr = OptionsGetDouble(PETSC_NULL,"-mat_lu_pivotthreshold",&B->lupivotthreshold,PETSC_NULL);CHKERRQ(ierr);
2247f1af5d2fSBarry Smith   ierr = OptionsHasName(PETSC_NULL,"-pc_ilu_preserve_row_sums",&b->ilu_preserve_row_sums);CHKERRQ(ierr);
2248416022c9SBarry Smith   b->row              = 0;
2249416022c9SBarry Smith   b->col              = 0;
225082bf6240SBarry Smith   b->icol             = 0;
2251416022c9SBarry Smith   b->indexshift       = 0;
2252b810aeb4SBarry Smith   b->reallocs         = 0;
225369957df2SSatish Balay   ierr = OptionsHasName(PETSC_NULL,"-mat_aij_oneindex", &flg);CHKERRQ(ierr);
225469957df2SSatish Balay   if (flg) b->indexshift = -1;
225517ab2063SBarry Smith 
225644cd7ae7SLois Curfman McInnes   b->m = m; B->m = m; B->M = m;
225744cd7ae7SLois Curfman McInnes   b->n = n; B->n = n; B->N = n;
2258a5ae1ecdSBarry Smith 
22594d197716SBarry Smith   ierr = MapCreateMPI(comm,m,m,&B->rmap);CHKERRQ(ierr);
22604d197716SBarry Smith   ierr = MapCreateMPI(comm,n,n,&B->cmap);CHKERRQ(ierr);
2261a5ae1ecdSBarry Smith 
22620452661fSBarry Smith   b->imax = (int *) PetscMalloc( (m+1)*sizeof(int) );CHKPTRQ(b->imax);
2263*f1e2ffcdSBarry Smith   if (!nnz) {
22647b8455f0SLois Curfman McInnes     if (nz == PETSC_DEFAULT) nz = 10;
22657b8455f0SLois Curfman McInnes     else if (nz <= 0)        nz = 1;
2266416022c9SBarry Smith     for ( i=0; i<m; i++ ) b->imax[i] = nz;
226717ab2063SBarry Smith     nz = nz*m;
22683a40ed3dSBarry Smith   } else {
226917ab2063SBarry Smith     nz = 0;
2270416022c9SBarry Smith     for ( i=0; i<m; i++ ) {b->imax[i] = nnz[i]; nz += nnz[i];}
227117ab2063SBarry Smith   }
227217ab2063SBarry Smith 
227317ab2063SBarry Smith   /* allocate the matrix space */
2274416022c9SBarry Smith   len             = nz*(sizeof(int) + sizeof(Scalar)) + (b->m+1)*sizeof(int);
22750452661fSBarry Smith   b->a            = (Scalar *) PetscMalloc( len );CHKPTRQ(b->a);
2276416022c9SBarry Smith   b->j            = (int *) (b->a + nz);
2277549d3d68SSatish Balay   ierr            = PetscMemzero(b->j,nz*sizeof(int));CHKERRQ(ierr);
2278416022c9SBarry Smith   b->i            = b->j + nz;
2279*f1e2ffcdSBarry Smith   b->singlemalloc = PETSC_TRUE;
228017ab2063SBarry Smith 
2281416022c9SBarry Smith   b->i[0] = -b->indexshift;
228217ab2063SBarry Smith   for (i=1; i<m+1; i++) {
2283416022c9SBarry Smith     b->i[i] = b->i[i-1] + b->imax[i-1];
228417ab2063SBarry Smith   }
228517ab2063SBarry Smith 
2286416022c9SBarry Smith   /* b->ilen will count nonzeros in each row so far. */
22870452661fSBarry Smith   b->ilen = (int *) PetscMalloc((m+1)*sizeof(int));
2288f09e8eb9SSatish Balay   PLogObjectMemory(B,len+2*(m+1)*sizeof(int)+sizeof(struct _p_Mat)+sizeof(Mat_SeqAIJ));
2289416022c9SBarry Smith   for ( i=0; i<b->m; i++ ) { b->ilen[i] = 0;}
229017ab2063SBarry Smith 
2291416022c9SBarry Smith   b->nz               = 0;
2292416022c9SBarry Smith   b->maxnz            = nz;
2293*f1e2ffcdSBarry Smith   b->sorted           = PETSC_FALSE;
2294*f1e2ffcdSBarry Smith   b->roworiented      = PETSC_TRUE;
2295416022c9SBarry Smith   b->nonew            = 0;
2296416022c9SBarry Smith   b->diag             = 0;
2297416022c9SBarry Smith   b->solve_work       = 0;
229871bd300dSLois Curfman McInnes   b->spptr            = 0;
2299754ec7b1SSatish Balay   b->inode.node_count = 0;
2300754ec7b1SSatish Balay   b->inode.size       = 0;
23016c7ebb05SLois Curfman McInnes   b->inode.limit      = 5;
23026c7ebb05SLois Curfman McInnes   b->inode.max_limit  = 5;
2303be6bf707SBarry Smith   b->saved_values     = 0;
23044e220ebcSLois Curfman McInnes   B->info.nz_unneeded = (double)b->maxnz;
2305d7f994e1SBarry Smith   b->idiag            = 0;
2306d7f994e1SBarry Smith   b->ssor             = 0;
2307*f1e2ffcdSBarry Smith   b->keepzeroedrows   = PETSC_FALSE;
230817ab2063SBarry Smith 
2309416022c9SBarry Smith   *A = B;
23104e220ebcSLois Curfman McInnes 
23114b14c69eSBarry Smith   /*  SuperLU is not currently supported through PETSc */
2312aa482453SBarry Smith #if defined(PETSC_HAVE_SUPERLU)
231369957df2SSatish Balay   ierr = OptionsHasName(PETSC_NULL,"-mat_aij_superlu", &flg);CHKERRQ(ierr);
231469957df2SSatish Balay   if (flg) { ierr = MatUseSuperLU_SeqAIJ(B);CHKERRQ(ierr); }
23154b14c69eSBarry Smith #endif
231669957df2SSatish Balay   ierr = OptionsHasName(PETSC_NULL,"-mat_aij_essl", &flg);CHKERRQ(ierr);
231769957df2SSatish Balay   if (flg) { ierr = MatUseEssl_SeqAIJ(B);CHKERRQ(ierr); }
231869957df2SSatish Balay   ierr = OptionsHasName(PETSC_NULL,"-mat_aij_dxml", &flg);CHKERRQ(ierr);
231969957df2SSatish Balay   if (flg) {
2320a8c6a408SBarry Smith     if (!b->indexshift) SETERRQ( PETSC_ERR_LIB,0,"need -mat_aij_oneindex with -mat_aij_dxml");
2321416022c9SBarry Smith     ierr = MatUseDXML_SeqAIJ(B);CHKERRQ(ierr);
232217ab2063SBarry Smith   }
232369957df2SSatish Balay   ierr = OptionsHasName(PETSC_NULL,"-help", &flg);CHKERRQ(ierr);
232469957df2SSatish Balay   if (flg) {ierr = MatPrintHelp(B);CHKERRQ(ierr); }
2325bef8e0ddSBarry Smith 
2326f1af5d2fSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatSeqAIJSetColumnIndices_C",
2327bef8e0ddSBarry Smith                                      "MatSeqAIJSetColumnIndices_SeqAIJ",
2328bef8e0ddSBarry Smith                                      (void*)MatSeqAIJSetColumnIndices_SeqAIJ);CHKERRQ(ierr);
2329f1af5d2fSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatStoreValues_C",
2330be6bf707SBarry Smith                                      "MatStoreValues_SeqAIJ",
2331be6bf707SBarry Smith                                      (void*)MatStoreValues_SeqAIJ);CHKERRQ(ierr);
2332f1af5d2fSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatRetrieveValues_C",
2333be6bf707SBarry Smith                                      "MatRetrieveValues_SeqAIJ",
2334be6bf707SBarry Smith                                      (void*)MatRetrieveValues_SeqAIJ);CHKERRQ(ierr);
23353a40ed3dSBarry Smith   PetscFunctionReturn(0);
233617ab2063SBarry Smith }
233717ab2063SBarry Smith 
23385615d1e5SSatish Balay #undef __FUNC__
2339be6bf707SBarry Smith #define __FUNC__ "MatDuplicate_SeqAIJ"
2340be6bf707SBarry Smith int MatDuplicate_SeqAIJ(Mat A,MatDuplicateOption cpvalues,Mat *B)
234117ab2063SBarry Smith {
2342416022c9SBarry Smith   Mat        C;
2343416022c9SBarry Smith   Mat_SeqAIJ *c,*a = (Mat_SeqAIJ *) A->data;
2344bef8e0ddSBarry Smith   int        i,len, m = a->m,shift = a->indexshift,ierr;
234517ab2063SBarry Smith 
23463a40ed3dSBarry Smith   PetscFunctionBegin;
23474043dd9cSLois Curfman McInnes   *B = 0;
23483f1db9ecSBarry Smith   PetscHeaderCreate(C,_p_Mat,struct _MatOps,MAT_COOKIE,MATSEQAIJ,"Mat",A->comm,MatDestroy,MatView);
2349416022c9SBarry Smith   PLogObjectCreate(C);
23500452661fSBarry Smith   C->data           = (void *) (c = PetscNew(Mat_SeqAIJ));CHKPTRQ(c);
2351549d3d68SSatish Balay   ierr              = PetscMemcpy(C->ops,A->ops,sizeof(struct _MatOps));CHKERRQ(ierr);
2352e1311b90SBarry Smith   C->ops->destroy   = MatDestroy_SeqAIJ;
2353e1311b90SBarry Smith   C->ops->view      = MatView_SeqAIJ;
2354416022c9SBarry Smith   C->factor         = A->factor;
2355416022c9SBarry Smith   c->row            = 0;
2356416022c9SBarry Smith   c->col            = 0;
235782bf6240SBarry Smith   c->icol           = 0;
2358416022c9SBarry Smith   c->indexshift     = shift;
2359*f1e2ffcdSBarry Smith   c->keepzeroedrows = a->keepzeroedrows;
2360c456f294SBarry Smith   C->assembled      = PETSC_TRUE;
236117ab2063SBarry Smith 
236244cd7ae7SLois Curfman McInnes   c->m = C->m   = a->m;
236344cd7ae7SLois Curfman McInnes   c->n = C->n   = a->n;
236444cd7ae7SLois Curfman McInnes   C->M          = a->m;
236544cd7ae7SLois Curfman McInnes   C->N          = a->n;
236617ab2063SBarry Smith 
23670452661fSBarry Smith   c->imax       = (int *) PetscMalloc((m+1)*sizeof(int));CHKPTRQ(c->imax);
23680452661fSBarry Smith   c->ilen       = (int *) PetscMalloc((m+1)*sizeof(int));CHKPTRQ(c->ilen);
236917ab2063SBarry Smith   for ( i=0; i<m; i++ ) {
2370416022c9SBarry Smith     c->imax[i] = a->imax[i];
2371416022c9SBarry Smith     c->ilen[i] = a->ilen[i];
237217ab2063SBarry Smith   }
237317ab2063SBarry Smith 
237417ab2063SBarry Smith   /* allocate the matrix space */
2375*f1e2ffcdSBarry Smith   c->singlemalloc = PETSC_TRUE;
2376416022c9SBarry Smith   len     = (m+1)*sizeof(int)+(a->i[m])*(sizeof(Scalar)+sizeof(int));
23770452661fSBarry Smith   c->a  = (Scalar *) PetscMalloc( len );CHKPTRQ(c->a);
2378416022c9SBarry Smith   c->j  = (int *) (c->a + a->i[m] + shift);
2379416022c9SBarry Smith   c->i  = c->j + a->i[m] + shift;
2380549d3d68SSatish Balay   ierr = PetscMemcpy(c->i,a->i,(m+1)*sizeof(int));CHKERRQ(ierr);
238117ab2063SBarry Smith   if (m > 0) {
2382549d3d68SSatish Balay     ierr = PetscMemcpy(c->j,a->j,(a->i[m]+shift)*sizeof(int));CHKERRQ(ierr);
2383be6bf707SBarry Smith     if (cpvalues == MAT_COPY_VALUES) {
2384549d3d68SSatish Balay       ierr = PetscMemcpy(c->a,a->a,(a->i[m]+shift)*sizeof(Scalar));CHKERRQ(ierr);
2385be6bf707SBarry Smith     } else {
2386549d3d68SSatish Balay       ierr = PetscMemzero(c->a,(a->i[m]+shift)*sizeof(Scalar));CHKERRQ(ierr);
238717ab2063SBarry Smith     }
238808480c60SBarry Smith   }
238917ab2063SBarry Smith 
2390f09e8eb9SSatish Balay   PLogObjectMemory(C,len+2*(m+1)*sizeof(int)+sizeof(struct _p_Mat)+sizeof(Mat_SeqAIJ));
2391416022c9SBarry Smith   c->sorted      = a->sorted;
2392416022c9SBarry Smith   c->roworiented = a->roworiented;
2393416022c9SBarry Smith   c->nonew       = a->nonew;
23947a743949SBarry Smith   c->ilu_preserve_row_sums = a->ilu_preserve_row_sums;
2395be6bf707SBarry Smith   c->saved_values = 0;
2396d7f994e1SBarry Smith   c->idiag        = 0;
2397d7f994e1SBarry Smith   c->ssor         = 0;
239817ab2063SBarry Smith 
2399416022c9SBarry Smith   if (a->diag) {
24000452661fSBarry Smith     c->diag = (int *) PetscMalloc( (m+1)*sizeof(int) );CHKPTRQ(c->diag);
2401416022c9SBarry Smith     PLogObjectMemory(C,(m+1)*sizeof(int));
240217ab2063SBarry Smith     for ( i=0; i<m; i++ ) {
2403416022c9SBarry Smith       c->diag[i] = a->diag[i];
240417ab2063SBarry Smith     }
24053a40ed3dSBarry Smith   } else c->diag          = 0;
24066c7ebb05SLois Curfman McInnes   c->inode.limit        = a->inode.limit;
24076c7ebb05SLois Curfman McInnes   c->inode.max_limit    = a->inode.max_limit;
2408754ec7b1SSatish Balay   if (a->inode.size){
2409daed632aSSatish Balay     c->inode.size       = (int *) PetscMalloc( (m+1)*sizeof(int) );CHKPTRQ(c->inode.size);
2410754ec7b1SSatish Balay     c->inode.node_count = a->inode.node_count;
2411549d3d68SSatish Balay     ierr = PetscMemcpy( c->inode.size, a->inode.size, (m+1)*sizeof(int));CHKERRQ(ierr);
2412754ec7b1SSatish Balay   } else {
2413754ec7b1SSatish Balay     c->inode.size       = 0;
2414754ec7b1SSatish Balay     c->inode.node_count = 0;
2415754ec7b1SSatish Balay   }
2416416022c9SBarry Smith   c->nz                 = a->nz;
2417416022c9SBarry Smith   c->maxnz              = a->maxnz;
2418416022c9SBarry Smith   c->solve_work         = 0;
241976dd722bSSatish Balay   c->spptr              = 0;      /* Dangerous -I'm throwing away a->spptr */
2420754ec7b1SSatish Balay 
2421416022c9SBarry Smith   *B = C;
24227b2a1423SBarry Smith   ierr = FListDuplicate(A->qlist,&C->qlist);CHKERRQ(ierr);
24233a40ed3dSBarry Smith   PetscFunctionReturn(0);
242417ab2063SBarry Smith }
242517ab2063SBarry Smith 
24265615d1e5SSatish Balay #undef __FUNC__
24275615d1e5SSatish Balay #define __FUNC__ "MatLoad_SeqAIJ"
242819bcc07fSBarry Smith int MatLoad_SeqAIJ(Viewer viewer,MatType type,Mat *A)
242917ab2063SBarry Smith {
2430416022c9SBarry Smith   Mat_SeqAIJ   *a;
2431416022c9SBarry Smith   Mat          B;
243217699dbbSLois Curfman McInnes   int          i, nz, ierr, fd, header[4],size,*rowlengths = 0,M,N,shift;
2433bcd2baecSBarry Smith   MPI_Comm     comm;
243417ab2063SBarry Smith 
24353a40ed3dSBarry Smith   PetscFunctionBegin;
2436e864ced6SBarry Smith   ierr = PetscObjectGetComm((PetscObject) viewer,&comm);CHKERRQ(ierr);
2437d132466eSBarry Smith   ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr);
2438a8c6a408SBarry Smith   if (size > 1) SETERRQ(PETSC_ERR_ARG_SIZ,0,"view must have one processor");
243990ace30eSBarry Smith   ierr = ViewerBinaryGetDescriptor(viewer,&fd);CHKERRQ(ierr);
24400752156aSBarry Smith   ierr = PetscBinaryRead(fd,header,4,PETSC_INT);CHKERRQ(ierr);
2441a8c6a408SBarry Smith   if (header[0] != MAT_COOKIE) SETERRQ(PETSC_ERR_FILE_UNEXPECTED,0,"not matrix object in file");
244217ab2063SBarry Smith   M = header[1]; N = header[2]; nz = header[3];
244317ab2063SBarry Smith 
2444d64ed03dSBarry Smith   if (nz < 0) {
2445a8c6a408SBarry Smith     SETERRQ(PETSC_ERR_FILE_UNEXPECTED,1,"Matrix stored in special format on disk, cannot load as SeqAIJ");
2446d64ed03dSBarry Smith   }
2447d64ed03dSBarry Smith 
244817ab2063SBarry Smith   /* read in row lengths */
24490452661fSBarry Smith   rowlengths = (int*) PetscMalloc( M*sizeof(int) );CHKPTRQ(rowlengths);
24500752156aSBarry Smith   ierr = PetscBinaryRead(fd,rowlengths,M,PETSC_INT);CHKERRQ(ierr);
245117ab2063SBarry Smith 
245217ab2063SBarry Smith   /* create our matrix */
2453416022c9SBarry Smith   ierr = MatCreateSeqAIJ(comm,M,N,0,rowlengths,A);CHKERRQ(ierr);
2454416022c9SBarry Smith   B = *A;
2455416022c9SBarry Smith   a = (Mat_SeqAIJ *) B->data;
2456416022c9SBarry Smith   shift = a->indexshift;
245717ab2063SBarry Smith 
245817ab2063SBarry Smith   /* read in column indices and adjust for Fortran indexing*/
24590752156aSBarry Smith   ierr = PetscBinaryRead(fd,a->j,nz,PETSC_INT);CHKERRQ(ierr);
246017ab2063SBarry Smith   if (shift) {
246117ab2063SBarry Smith     for ( i=0; i<nz; i++ ) {
2462416022c9SBarry Smith       a->j[i] += 1;
246317ab2063SBarry Smith     }
246417ab2063SBarry Smith   }
246517ab2063SBarry Smith 
246617ab2063SBarry Smith   /* read in nonzero values */
24670752156aSBarry Smith   ierr = PetscBinaryRead(fd,a->a,nz,PETSC_SCALAR);CHKERRQ(ierr);
246817ab2063SBarry Smith 
246917ab2063SBarry Smith   /* set matrix "i" values */
2470416022c9SBarry Smith   a->i[0] = -shift;
247117ab2063SBarry Smith   for ( i=1; i<= M; i++ ) {
2472416022c9SBarry Smith     a->i[i]      = a->i[i-1] + rowlengths[i-1];
2473416022c9SBarry Smith     a->ilen[i-1] = rowlengths[i-1];
247417ab2063SBarry Smith   }
2475606d414cSSatish Balay   ierr = PetscFree(rowlengths);CHKERRQ(ierr);
247617ab2063SBarry Smith 
24776d4a8577SBarry Smith   ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
24786d4a8577SBarry Smith   ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
24793a40ed3dSBarry Smith   PetscFunctionReturn(0);
248017ab2063SBarry Smith }
248117ab2063SBarry Smith 
24825615d1e5SSatish Balay #undef __FUNC__
24835615d1e5SSatish Balay #define __FUNC__ "MatEqual_SeqAIJ"
24848f6be9afSLois Curfman McInnes int MatEqual_SeqAIJ(Mat A,Mat B, PetscTruth* flg)
24857264ac53SSatish Balay {
24867264ac53SSatish Balay   Mat_SeqAIJ *a = (Mat_SeqAIJ *)A->data, *b = (Mat_SeqAIJ *)B->data;
24870f5bd95cSBarry Smith   int        ierr;
24887264ac53SSatish Balay 
24893a40ed3dSBarry Smith   PetscFunctionBegin;
2490a8c6a408SBarry Smith   if (B->type !=MATSEQAIJ)SETERRQ(PETSC_ERR_ARG_INCOMP,0,"Matrices must be same type");
24917264ac53SSatish Balay 
24927264ac53SSatish Balay   /* If the  matrix dimensions are not equal, or no of nonzeros or shift */
24937264ac53SSatish Balay   if ((a->m != b->m ) || (a->n !=b->n) ||( a->nz != b->nz)||
2494bcd2baecSBarry Smith       (a->indexshift != b->indexshift)) {
24953a40ed3dSBarry Smith     *flg = PETSC_FALSE; PetscFunctionReturn(0);
2496bcd2baecSBarry Smith   }
24977264ac53SSatish Balay 
24987264ac53SSatish Balay   /* if the a->i are the same */
24990f5bd95cSBarry Smith   ierr = PetscMemcmp(a->i,b->i,(a->m+1)*sizeof(int),flg);CHKERRQ(ierr);
25000f5bd95cSBarry Smith   if (*flg == PETSC_FALSE) PetscFunctionReturn(0);
25017264ac53SSatish Balay 
25027264ac53SSatish Balay   /* if a->j are the same */
25030f5bd95cSBarry Smith   ierr = PetscMemcmp(a->j, b->j, (a->nz)*sizeof(int),flg);CHKERRQ(ierr);
25040f5bd95cSBarry Smith   if (*flg == PETSC_FALSE) PetscFunctionReturn(0);
2505bcd2baecSBarry Smith 
2506bcd2baecSBarry Smith   /* if a->a are the same */
25070f5bd95cSBarry Smith   ierr = PetscMemcmp(a->a, b->a, (a->nz)*sizeof(Scalar),flg);CHKERRQ(ierr);
25080f5bd95cSBarry Smith 
25093a40ed3dSBarry Smith   PetscFunctionReturn(0);
25107264ac53SSatish Balay 
25117264ac53SSatish Balay }
2512