xref: /petsc/src/mat/impls/aij/seq/aij.c (revision c38d4ed214221df9ea04de46f7761bef149d00ff)
1*c38d4ed2SBarry Smith /*$Id: aij.c,v 1.332 1999/11/05 14:45:18 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;
220416022c9SBarry Smith         a->singlemalloc = 1;
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);
5590513a670SBarry Smith     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   }
670*c38d4ed2SBarry Smith   PLogInfo(A,"MatAssemblyEnd_SeqAIJ:Matrix size: %d X %d; storage space: %d unneeded, %d used\n",m,a->n,fshift,a->nz);
671*c38d4ed2SBarry 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   }
723*c38d4ed2SBarry Smith   if (a->row) {
724*c38d4ed2SBarry Smith     ierr = ISDestroy(a->row);CHKERRQ(ierr);
725*c38d4ed2SBarry Smith   }
726*c38d4ed2SBarry Smith   if (a->col) {
727*c38d4ed2SBarry Smith     ierr = ISDestroy(a->col);CHKERRQ(ierr);
728*c38d4ed2SBarry 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;
7586d4a8577SBarry Smith   if      (op == MAT_ROW_ORIENTED)                 a->roworiented = 1;
7596d4a8577SBarry Smith   else if (op == MAT_COLUMN_ORIENTED)              a->roworiented = 0;
7606d4a8577SBarry Smith   else if (op == MAT_COLUMNS_SORTED)               a->sorted      = 1;
761219d9a1aSLois Curfman McInnes   else if (op == MAT_COLUMNS_UNSORTED)             a->sorted      = 0;
7626d4a8577SBarry Smith   else if (op == MAT_NO_NEW_NONZERO_LOCATIONS)     a->nonew       = 1;
7634787f768SSatish Balay   else if (op == MAT_NEW_NONZERO_LOCATION_ERR)     a->nonew       = -1;
7644787f768SSatish Balay   else if (op == MAT_NEW_NONZERO_ALLOCATION_ERR)   a->nonew       = -2;
7656d4a8577SBarry Smith   else if (op == MAT_YES_NEW_NONZERO_LOCATIONS)    a->nonew       = 0;
7666d4a8577SBarry Smith   else if (op == MAT_ROWS_SORTED ||
767219d9a1aSLois Curfman McInnes            op == MAT_ROWS_UNSORTED ||
7686d4a8577SBarry Smith            op == MAT_SYMMETRIC ||
7696d4a8577SBarry Smith            op == MAT_STRUCTURALLY_SYMMETRIC ||
77090f02eecSBarry Smith            op == MAT_YES_NEW_DIAGONALS ||
771b51ba29fSSatish Balay            op == MAT_IGNORE_OFF_PROC_ENTRIES||
772b51ba29fSSatish Balay            op == MAT_USE_HASH_TABLE)
773981c4779SBarry Smith     PLogInfo(A,"MatSetOption_SeqAIJ:Option ignored\n");
7743a40ed3dSBarry Smith   else if (op == MAT_NO_NEW_DIAGONALS) {
7753a40ed3dSBarry Smith     SETERRQ(PETSC_ERR_SUP,0,"MAT_NO_NEW_DIAGONALS");
7763a40ed3dSBarry Smith   } else if (op == MAT_INODE_LIMIT_1)            a->inode.limit  = 1;
7776d4a8577SBarry Smith   else if (op == MAT_INODE_LIMIT_2)            a->inode.limit  = 2;
7786d4a8577SBarry Smith   else if (op == MAT_INODE_LIMIT_3)            a->inode.limit  = 3;
7796d4a8577SBarry Smith   else if (op == MAT_INODE_LIMIT_4)            a->inode.limit  = 4;
7806d4a8577SBarry Smith   else if (op == MAT_INODE_LIMIT_5)            a->inode.limit  = 5;
7813a40ed3dSBarry Smith   else SETERRQ(PETSC_ERR_SUP,0,"unknown option");
7823a40ed3dSBarry Smith   PetscFunctionReturn(0);
78317ab2063SBarry Smith }
78417ab2063SBarry Smith 
7855615d1e5SSatish Balay #undef __FUNC__
7865615d1e5SSatish Balay #define __FUNC__ "MatGetDiagonal_SeqAIJ"
7878f6be9afSLois Curfman McInnes int MatGetDiagonal_SeqAIJ(Mat A,Vec v)
78817ab2063SBarry Smith {
789416022c9SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data;
7903a40ed3dSBarry Smith   int        i,j, n,shift = a->indexshift,ierr;
79117ab2063SBarry Smith   Scalar     *x, zero = 0.0;
79217ab2063SBarry Smith 
7933a40ed3dSBarry Smith   PetscFunctionBegin;
7943a40ed3dSBarry Smith   ierr = VecSet(&zero,v);CHKERRQ(ierr);
795e1311b90SBarry Smith   ierr = VecGetArray(v,&x);;CHKERRQ(ierr);
796e1311b90SBarry Smith   ierr = VecGetLocalSize(v,&n);;CHKERRQ(ierr);
797a8c6a408SBarry Smith   if (n != a->m) SETERRQ(PETSC_ERR_ARG_SIZ,0,"Nonconforming matrix and vector");
798416022c9SBarry Smith   for ( i=0; i<a->m; i++ ) {
799416022c9SBarry Smith     for ( j=a->i[i]+shift; j<a->i[i+1]+shift; j++ ) {
800416022c9SBarry Smith       if (a->j[j]+shift == i) {
801416022c9SBarry Smith         x[i] = a->a[j];
80217ab2063SBarry Smith         break;
80317ab2063SBarry Smith       }
80417ab2063SBarry Smith     }
80517ab2063SBarry Smith   }
806e1311b90SBarry Smith   ierr = VecRestoreArray(v,&x);;CHKERRQ(ierr);
8073a40ed3dSBarry Smith   PetscFunctionReturn(0);
80817ab2063SBarry Smith }
80917ab2063SBarry Smith 
81017ab2063SBarry Smith /* -------------------------------------------------------*/
81117ab2063SBarry Smith /* Should check that shapes of vectors and matrices match */
81217ab2063SBarry Smith /* -------------------------------------------------------*/
8135615d1e5SSatish Balay #undef __FUNC__
8145615d1e5SSatish Balay #define __FUNC__ "MatMultTrans_SeqAIJ"
81544cd7ae7SLois Curfman McInnes int MatMultTrans_SeqAIJ(Mat A,Vec xx,Vec yy)
81617ab2063SBarry Smith {
817416022c9SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data;
818f1af5d2fSBarry Smith   Scalar     *x, *y, *v, alpha, zero = 0.0;
819e1311b90SBarry Smith   int        ierr,m = a->m, n, i, *idx, shift = a->indexshift;
82017ab2063SBarry Smith 
8213a40ed3dSBarry Smith   PetscFunctionBegin;
822f1af5d2fSBarry Smith   ierr = VecSet(&zero,yy);CHKERRQ(ierr);
823e1311b90SBarry Smith   ierr = VecGetArray(xx,&x);CHKERRQ(ierr);
824e1311b90SBarry Smith   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
82517ab2063SBarry Smith   y = y + shift; /* shift for Fortran start by 1 indexing */
82617ab2063SBarry Smith   for ( i=0; i<m; i++ ) {
827416022c9SBarry Smith     idx   = a->j + a->i[i] + shift;
828416022c9SBarry Smith     v     = a->a + a->i[i] + shift;
829416022c9SBarry Smith     n     = a->i[i+1] - a->i[i];
83017ab2063SBarry Smith     alpha = x[i];
83117ab2063SBarry Smith     while (n-->0) {y[*idx++] += alpha * *v++;}
83217ab2063SBarry Smith   }
833416022c9SBarry Smith   PLogFlops(2*a->nz - a->n);
834e1311b90SBarry Smith   ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr);
835e1311b90SBarry Smith   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
8363a40ed3dSBarry Smith   PetscFunctionReturn(0);
83717ab2063SBarry Smith }
838d5d45c9bSBarry Smith 
8395615d1e5SSatish Balay #undef __FUNC__
8405615d1e5SSatish Balay #define __FUNC__ "MatMultTransAdd_SeqAIJ"
84144cd7ae7SLois Curfman McInnes int MatMultTransAdd_SeqAIJ(Mat A,Vec xx,Vec zz,Vec yy)
84217ab2063SBarry Smith {
843416022c9SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data;
84417ab2063SBarry Smith   Scalar     *x, *y, *v, alpha;
845e1311b90SBarry Smith   int        ierr,m = a->m, n, i, *idx,shift = a->indexshift;
84617ab2063SBarry Smith 
8473a40ed3dSBarry Smith   PetscFunctionBegin;
8482e8a6d31SBarry Smith   if (zz != yy) {ierr = VecCopy(zz,yy);CHKERRQ(ierr);}
849e1311b90SBarry Smith   ierr = VecGetArray(xx,&x);CHKERRQ(ierr);
850e1311b90SBarry Smith   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
85117ab2063SBarry Smith   y = y + shift; /* shift for Fortran start by 1 indexing */
85217ab2063SBarry Smith   for ( i=0; i<m; i++ ) {
853416022c9SBarry Smith     idx   = a->j + a->i[i] + shift;
854416022c9SBarry Smith     v     = a->a + a->i[i] + shift;
855416022c9SBarry Smith     n     = a->i[i+1] - a->i[i];
85617ab2063SBarry Smith     alpha = x[i];
85717ab2063SBarry Smith     while (n-->0) {y[*idx++] += alpha * *v++;}
85817ab2063SBarry Smith   }
85990f02eecSBarry Smith   PLogFlops(2*a->nz);
860e1311b90SBarry Smith   ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr);
861e1311b90SBarry Smith   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
8623a40ed3dSBarry Smith   PetscFunctionReturn(0);
86317ab2063SBarry Smith }
86417ab2063SBarry Smith 
8655615d1e5SSatish Balay #undef __FUNC__
8665615d1e5SSatish Balay #define __FUNC__ "MatMult_SeqAIJ"
86744cd7ae7SLois Curfman McInnes int MatMult_SeqAIJ(Mat A,Vec xx,Vec yy)
86817ab2063SBarry Smith {
869416022c9SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data;
87017ab2063SBarry Smith   Scalar     *x, *y, *v, sum;
871e1311b90SBarry Smith   int        ierr,m = a->m, *idx, shift = a->indexshift,*ii;
872aa482453SBarry Smith #if !defined(PETSC_USE_FORTRAN_KERNEL_MULTAIJ)
873e36a17ebSSatish Balay   int        n, i, jrow,j;
874e36a17ebSSatish Balay #endif
87517ab2063SBarry Smith 
876aa482453SBarry Smith #if defined(PETSC_HAVE_PRAGMA_DISJOINT)
877fee21e36SBarry Smith #pragma disjoint(*x,*y,*v)
878fee21e36SBarry Smith #endif
879fee21e36SBarry Smith 
8803a40ed3dSBarry Smith   PetscFunctionBegin;
881e1311b90SBarry Smith   ierr = VecGetArray(xx,&x);CHKERRQ(ierr);
882e1311b90SBarry Smith   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
88317ab2063SBarry Smith   x    = x + shift;    /* shift for Fortran start by 1 indexing */
884416022c9SBarry Smith   idx  = a->j;
885d64ed03dSBarry Smith   v    = a->a;
886416022c9SBarry Smith   ii   = a->i;
887aa482453SBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_MULTAIJ)
88829b5ca8aSSatish Balay   fortranmultaij_(&m,x,ii,idx+shift,v+shift,y);
8898d195f9aSBarry Smith #else
890d64ed03dSBarry Smith   v    += shift; /* shift for Fortran start by 1 indexing */
891d64ed03dSBarry Smith   idx  += shift;
89217ab2063SBarry Smith   for ( i=0; i<m; i++ ) {
8939ea0dfa2SSatish Balay     jrow = ii[i];
8949ea0dfa2SSatish Balay     n    = ii[i+1] - jrow;
89517ab2063SBarry Smith     sum  = 0.0;
8969ea0dfa2SSatish Balay     for ( j=0; j<n; j++) {
8979ea0dfa2SSatish Balay       sum += v[jrow]*x[idx[jrow]]; jrow++;
8989ea0dfa2SSatish Balay      }
89917ab2063SBarry Smith     y[i] = sum;
90017ab2063SBarry Smith   }
9018d195f9aSBarry Smith #endif
902416022c9SBarry Smith   PLogFlops(2*a->nz - m);
903e1311b90SBarry Smith   ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr);
904e1311b90SBarry Smith   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
9053a40ed3dSBarry Smith   PetscFunctionReturn(0);
90617ab2063SBarry Smith }
90717ab2063SBarry Smith 
9085615d1e5SSatish Balay #undef __FUNC__
9095615d1e5SSatish Balay #define __FUNC__ "MatMultAdd_SeqAIJ"
91044cd7ae7SLois Curfman McInnes int MatMultAdd_SeqAIJ(Mat A,Vec xx,Vec yy,Vec zz)
91117ab2063SBarry Smith {
912416022c9SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data;
91317ab2063SBarry Smith   Scalar     *x, *y, *z, *v, sum;
914e1311b90SBarry Smith   int        ierr,m = a->m, *idx, shift = a->indexshift,*ii;
915aa482453SBarry Smith #if !defined(PETSC_USE_FORTRAN_KERNEL_MULTADDAIJ)
916e36a17ebSSatish Balay   int        n,i,jrow,j;
917e36a17ebSSatish Balay #endif
9189ea0dfa2SSatish Balay 
9193a40ed3dSBarry Smith   PetscFunctionBegin;
920e1311b90SBarry Smith   ierr = VecGetArray(xx,&x);CHKERRQ(ierr);
921e1311b90SBarry Smith   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
9222e8a6d31SBarry Smith   if (zz != yy) {
923e1311b90SBarry Smith     ierr = VecGetArray(zz,&z);CHKERRQ(ierr);
9242e8a6d31SBarry Smith   } else {
9252e8a6d31SBarry Smith     z = y;
9262e8a6d31SBarry Smith   }
92717ab2063SBarry Smith   x    = x + shift; /* shift for Fortran start by 1 indexing */
928cddf8d76SBarry Smith   idx  = a->j;
929d64ed03dSBarry Smith   v    = a->a;
930cddf8d76SBarry Smith   ii   = a->i;
931aa482453SBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_MULTADDAIJ)
93229b5ca8aSSatish Balay   fortranmultaddaij_(&m,x,ii,idx+shift,v+shift,y,z);
93302ab625aSSatish Balay #else
934d64ed03dSBarry Smith   v   += shift; /* shift for Fortran start by 1 indexing */
935d64ed03dSBarry Smith   idx += shift;
93617ab2063SBarry Smith   for ( i=0; i<m; i++ ) {
9379ea0dfa2SSatish Balay     jrow = ii[i];
9389ea0dfa2SSatish Balay     n    = ii[i+1] - jrow;
93917ab2063SBarry Smith     sum  = y[i];
9409ea0dfa2SSatish Balay     for ( j=0; j<n; j++) {
9419ea0dfa2SSatish Balay       sum += v[jrow]*x[idx[jrow]]; jrow++;
9429ea0dfa2SSatish Balay      }
94317ab2063SBarry Smith     z[i] = sum;
94417ab2063SBarry Smith   }
94502ab625aSSatish Balay #endif
946416022c9SBarry Smith   PLogFlops(2*a->nz);
947e1311b90SBarry Smith   ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr);
948e1311b90SBarry Smith   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
9492e8a6d31SBarry Smith   if (zz != yy) {
950e1311b90SBarry Smith     ierr = VecRestoreArray(zz,&z);CHKERRQ(ierr);
9512e8a6d31SBarry Smith   }
9523a40ed3dSBarry Smith   PetscFunctionReturn(0);
95317ab2063SBarry Smith }
95417ab2063SBarry Smith 
95517ab2063SBarry Smith /*
95617ab2063SBarry Smith      Adds diagonal pointers to sparse matrix structure.
95717ab2063SBarry Smith */
9585615d1e5SSatish Balay #undef __FUNC__
9595615d1e5SSatish Balay #define __FUNC__ "MatMarkDiag_SeqAIJ"
960416022c9SBarry Smith int MatMarkDiag_SeqAIJ(Mat A)
96117ab2063SBarry Smith {
962416022c9SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data;
963416022c9SBarry Smith   int        i,j, *diag, m = a->m,shift = a->indexshift;
96417ab2063SBarry Smith 
9653a40ed3dSBarry Smith   PetscFunctionBegin;
9660452661fSBarry Smith   diag = (int *) PetscMalloc( (m+1)*sizeof(int));CHKPTRQ(diag);
967416022c9SBarry Smith   PLogObjectMemory(A,(m+1)*sizeof(int));
968416022c9SBarry Smith   for ( i=0; i<a->m; i++ ) {
96935b0346bSBarry Smith     diag[i] = a->i[i+1];
970416022c9SBarry Smith     for ( j=a->i[i]+shift; j<a->i[i+1]+shift; j++ ) {
971416022c9SBarry Smith       if (a->j[j]+shift == i) {
97217ab2063SBarry Smith         diag[i] = j - shift;
97317ab2063SBarry Smith         break;
97417ab2063SBarry Smith       }
97517ab2063SBarry Smith     }
97617ab2063SBarry Smith   }
977416022c9SBarry Smith   a->diag = diag;
9783a40ed3dSBarry Smith   PetscFunctionReturn(0);
97917ab2063SBarry Smith }
98017ab2063SBarry Smith 
981be5855fcSBarry Smith /*
982be5855fcSBarry Smith      Checks for missing diagonals
983be5855fcSBarry Smith */
984be5855fcSBarry Smith #undef __FUNC__
985be5855fcSBarry Smith #define __FUNC__ "MatMissingDiag_SeqAIJ"
986be5855fcSBarry Smith int MatMissingDiag_SeqAIJ(Mat A)
987be5855fcSBarry Smith {
988be5855fcSBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data;
989be5855fcSBarry Smith   int        *diag = a->diag, *jj = a->j,i,shift = a->indexshift;
990be5855fcSBarry Smith 
991be5855fcSBarry Smith   PetscFunctionBegin;
992be5855fcSBarry Smith   for ( i=0; i<a->m; i++ ) {
993be5855fcSBarry Smith     if (jj[diag[i]+shift] != i-shift) {
994be5855fcSBarry Smith       SETERRQ1(1,1,"Matrix is missing diagonal number %d",i);
995be5855fcSBarry Smith     }
996be5855fcSBarry Smith   }
997be5855fcSBarry Smith   PetscFunctionReturn(0);
998be5855fcSBarry Smith }
999be5855fcSBarry Smith 
10005615d1e5SSatish Balay #undef __FUNC__
10015615d1e5SSatish Balay #define __FUNC__ "MatRelax_SeqAIJ"
1002be5855fcSBarry Smith int MatRelax_SeqAIJ(Mat A,Vec bb,double omega,MatSORType flag,double fshift,int its,Vec xx)
100317ab2063SBarry Smith {
1004416022c9SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data;
1005d6ed3216SSatish Balay   Scalar     *x, *b, *bs,  d, *xs, sum, *v = a->a,*t=0,scale,*ts, *xb,*idiag=0;
1006d5d45c9bSBarry Smith   int        ierr, *idx, *diag,n = a->n, m = a->m, i, shift = a->indexshift;
100717ab2063SBarry Smith 
10083a40ed3dSBarry Smith   PetscFunctionBegin;
1009e1311b90SBarry Smith   ierr = VecGetArray(xx,&x);CHKERRQ(ierr);
1010fb2e594dSBarry Smith   if (xx != bb) {
1011e1311b90SBarry Smith     ierr = VecGetArray(bb,&b);CHKERRQ(ierr);
1012fb2e594dSBarry Smith   } else {
1013fb2e594dSBarry Smith     b = x;
1014fb2e594dSBarry Smith   }
1015fb2e594dSBarry Smith 
1016d00d2cf4SBarry Smith   if (!a->diag) {ierr = MatMarkDiag_SeqAIJ(A);CHKERRQ(ierr);}
1017416022c9SBarry Smith   diag = a->diag;
1018416022c9SBarry Smith   xs   = x + shift; /* shifted by one for index start of a or a->j*/
101917ab2063SBarry Smith   if (flag == SOR_APPLY_UPPER) {
102017ab2063SBarry Smith    /* apply ( U + D/omega) to the vector */
102117ab2063SBarry Smith     bs = b + shift;
102217ab2063SBarry Smith     for ( i=0; i<m; i++ ) {
1023416022c9SBarry Smith         d    = fshift + a->a[diag[i] + shift];
1024416022c9SBarry Smith         n    = a->i[i+1] - diag[i] - 1;
1025488ecbafSBarry Smith 	PLogFlops(2*n-1);
1026416022c9SBarry Smith         idx  = a->j + diag[i] + (!shift);
1027416022c9SBarry Smith         v    = a->a + diag[i] + (!shift);
102817ab2063SBarry Smith         sum  = b[i]*d/omega;
102917ab2063SBarry Smith         SPARSEDENSEDOT(sum,bs,v,idx,n);
103017ab2063SBarry Smith         x[i] = sum;
103117ab2063SBarry Smith     }
1032cb5b572fSBarry Smith     ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr);
1033fb2e594dSBarry Smith     if (bb != xx) {ierr = VecRestoreArray(bb,&b);CHKERRQ(ierr);}
10343a40ed3dSBarry Smith     PetscFunctionReturn(0);
103517ab2063SBarry Smith   }
1036c783ea89SBarry Smith 
1037c783ea89SBarry Smith   /* setup workspace for Eisenstat */
1038c783ea89SBarry Smith   if (flag & SOR_EISENSTAT) {
1039c783ea89SBarry Smith     if (!a->idiag) {
1040c783ea89SBarry Smith       a->idiag = (Scalar *) PetscMalloc(2*m*sizeof(Scalar));CHKPTRQ(a->idiag);
1041c783ea89SBarry Smith       a->ssor  = a->idiag + m;
1042c783ea89SBarry Smith       v        = a->a;
1043c783ea89SBarry Smith       for ( i=0; i<m; i++ ) { a->idiag[i] = 1.0/v[diag[i]];}
1044c783ea89SBarry Smith     }
1045c783ea89SBarry Smith     t     = a->ssor;
1046c783ea89SBarry Smith     idiag = a->idiag;
1047c783ea89SBarry Smith   }
1048fc3d8934SBarry Smith     /* Let  A = L + U + D; where L is lower trianglar,
1049fc3d8934SBarry Smith     U is upper triangular, E is diagonal; This routine applies
1050fc3d8934SBarry Smith 
1051fc3d8934SBarry Smith             (L + E)^{-1} A (U + E)^{-1}
1052fc3d8934SBarry Smith 
1053fc3d8934SBarry Smith     to a vector efficiently using Eisenstat's trick. This is for
1054fc3d8934SBarry Smith     the case of SSOR preconditioner, so E is D/omega where omega
105548af12d7SBarry Smith     is the relaxation factor.
1056fc3d8934SBarry Smith     */
1057fc3d8934SBarry Smith 
105848af12d7SBarry Smith   if (flag == SOR_APPLY_LOWER) {
105948af12d7SBarry Smith     SETERRQ(PETSC_ERR_SUP,0,"SOR_APPLY_LOWER is not done");
106048af12d7SBarry Smith   } else if ((flag & SOR_EISENSTAT) && omega == 1.0 && shift == 0 && fshift == 0.0) {
106148af12d7SBarry Smith     /* special case for omega = 1.0 saves flops and some integer ops */
1062733d66baSBarry Smith     Scalar *v2;
106348af12d7SBarry Smith 
1064733d66baSBarry Smith     v2    = a->a;
1065fc3d8934SBarry Smith     /*  x = (E + U)^{-1} b */
1066fc3d8934SBarry Smith     for ( i=m-1; i>=0; i-- ) {
1067fc3d8934SBarry Smith       n    = a->i[i+1] - diag[i] - 1;
1068fc3d8934SBarry Smith       idx  = a->j + diag[i] + 1;
1069fc3d8934SBarry Smith       v    = a->a + diag[i] + 1;
1070fc3d8934SBarry Smith       sum  = b[i];
1071fc3d8934SBarry Smith       SPARSEDENSEMDOT(sum,xs,v,idx,n);
1072b4632166SBarry Smith       x[i] = sum*idiag[i];
1073fc3d8934SBarry Smith 
1074fc3d8934SBarry Smith       /*  t = b - (2*E - D)x */
1075733d66baSBarry Smith       t[i] = b[i] - (v2[diag[i]])*x[i];
1076733d66baSBarry Smith     }
1077fc3d8934SBarry Smith 
1078fc3d8934SBarry Smith     /*  t = (E + L)^{-1}t */
1079fc3d8934SBarry Smith     diag = a->diag;
1080fc3d8934SBarry Smith     for ( i=0; i<m; i++ ) {
1081fc3d8934SBarry Smith       n    = diag[i] - a->i[i];
1082fc3d8934SBarry Smith       idx  = a->j + a->i[i];
1083fc3d8934SBarry Smith       v    = a->a + a->i[i];
1084fc3d8934SBarry Smith       sum  = t[i];
1085fc3d8934SBarry Smith       SPARSEDENSEMDOT(sum,t,v,idx,n);
1086b4632166SBarry Smith       t[i]  = sum*idiag[i];
1087fc3d8934SBarry Smith 
1088fc3d8934SBarry Smith       /*  x = x + t */
1089733d66baSBarry Smith       x[i] += t[i];
1090733d66baSBarry Smith     }
1091733d66baSBarry Smith 
1092a4d9cbf6SBarry Smith     PLogFlops(3*m-1 + 2*a->nz);
1093fc3d8934SBarry Smith     ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr);
1094fc3d8934SBarry Smith     if (bb != xx) {ierr = VecRestoreArray(bb,&b);CHKERRQ(ierr);}
1095fc3d8934SBarry Smith     PetscFunctionReturn(0);
10963a40ed3dSBarry Smith   } else if (flag & SOR_EISENSTAT) {
109717ab2063SBarry Smith     /* Let  A = L + U + D; where L is lower trianglar,
109817ab2063SBarry Smith     U is upper triangular, E is diagonal; This routine applies
109917ab2063SBarry Smith 
110017ab2063SBarry Smith             (L + E)^{-1} A (U + E)^{-1}
110117ab2063SBarry Smith 
110217ab2063SBarry Smith     to a vector efficiently using Eisenstat's trick. This is for
110317ab2063SBarry Smith     the case of SSOR preconditioner, so E is D/omega where omega
110417ab2063SBarry Smith     is the relaxation factor.
110517ab2063SBarry Smith     */
110617ab2063SBarry Smith     scale = (2.0/omega) - 1.0;
110717ab2063SBarry Smith 
110817ab2063SBarry Smith     /*  x = (E + U)^{-1} b */
110917ab2063SBarry Smith     for ( i=m-1; i>=0; i-- ) {
1110416022c9SBarry Smith       d    = fshift + a->a[diag[i] + shift];
1111416022c9SBarry Smith       n    = a->i[i+1] - diag[i] - 1;
1112416022c9SBarry Smith       idx  = a->j + diag[i] + (!shift);
1113416022c9SBarry Smith       v    = a->a + diag[i] + (!shift);
111417ab2063SBarry Smith       sum  = b[i];
111517ab2063SBarry Smith       SPARSEDENSEMDOT(sum,xs,v,idx,n);
111617ab2063SBarry Smith       x[i] = omega*(sum/d);
111717ab2063SBarry Smith     }
111817ab2063SBarry Smith 
111917ab2063SBarry Smith     /*  t = b - (2*E - D)x */
1120416022c9SBarry Smith     v = a->a;
112117ab2063SBarry Smith     for ( i=0; i<m; i++ ) { t[i] = b[i] - scale*(v[*diag++ + shift])*x[i]; }
112217ab2063SBarry Smith 
112317ab2063SBarry Smith     /*  t = (E + L)^{-1}t */
1124416022c9SBarry Smith     ts = t + shift; /* shifted by one for index start of a or a->j*/
1125416022c9SBarry Smith     diag = a->diag;
112617ab2063SBarry Smith     for ( i=0; i<m; i++ ) {
1127416022c9SBarry Smith       d    = fshift + a->a[diag[i]+shift];
1128416022c9SBarry Smith       n    = diag[i] - a->i[i];
1129416022c9SBarry Smith       idx  = a->j + a->i[i] + shift;
1130416022c9SBarry Smith       v    = a->a + a->i[i] + shift;
113117ab2063SBarry Smith       sum  = t[i];
113217ab2063SBarry Smith       SPARSEDENSEMDOT(sum,ts,v,idx,n);
113317ab2063SBarry Smith       t[i] = omega*(sum/d);
1134733d66baSBarry Smith       /*  x = x + t */
1135733d66baSBarry Smith       x[i] += t[i];
113617ab2063SBarry Smith     }
113717ab2063SBarry Smith 
1138c783ea89SBarry Smith     PLogFlops(6*m-1 + 2*a->nz);
1139cb5b572fSBarry Smith     ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr);
1140fb2e594dSBarry Smith     if (bb != xx) {ierr = VecRestoreArray(bb,&b);CHKERRQ(ierr);}
11413a40ed3dSBarry Smith     PetscFunctionReturn(0);
114217ab2063SBarry Smith   }
114317ab2063SBarry Smith   if (flag & SOR_ZERO_INITIAL_GUESS) {
114417ab2063SBarry Smith     if (flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP){
114517ab2063SBarry Smith       for ( i=0; i<m; i++ ) {
1146416022c9SBarry Smith         d    = fshift + a->a[diag[i]+shift];
1147416022c9SBarry Smith         n    = diag[i] - a->i[i];
1148488ecbafSBarry Smith 	PLogFlops(2*n-1);
1149416022c9SBarry Smith         idx  = a->j + a->i[i] + shift;
1150416022c9SBarry Smith         v    = a->a + a->i[i] + shift;
115117ab2063SBarry Smith         sum  = b[i];
115217ab2063SBarry Smith         SPARSEDENSEMDOT(sum,xs,v,idx,n);
115317ab2063SBarry Smith         x[i] = omega*(sum/d);
115417ab2063SBarry Smith       }
115517ab2063SBarry Smith       xb = x;
11563a40ed3dSBarry Smith     } else xb = b;
115717ab2063SBarry Smith     if ((flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP) &&
115817ab2063SBarry Smith         (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP)) {
115917ab2063SBarry Smith       for ( i=0; i<m; i++ ) {
1160416022c9SBarry Smith         x[i] *= a->a[diag[i]+shift];
116117ab2063SBarry Smith       }
1162488ecbafSBarry Smith       PLogFlops(m);
116317ab2063SBarry Smith     }
116417ab2063SBarry Smith     if (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP){
116517ab2063SBarry Smith       for ( i=m-1; i>=0; i-- ) {
1166416022c9SBarry Smith         d    = fshift + a->a[diag[i] + shift];
1167416022c9SBarry Smith         n    = a->i[i+1] - diag[i] - 1;
1168488ecbafSBarry Smith 	PLogFlops(2*n-1);
1169416022c9SBarry Smith         idx  = a->j + diag[i] + (!shift);
1170416022c9SBarry Smith         v    = a->a + diag[i] + (!shift);
117117ab2063SBarry Smith         sum  = xb[i];
117217ab2063SBarry Smith         SPARSEDENSEMDOT(sum,xs,v,idx,n);
117317ab2063SBarry Smith         x[i] = omega*(sum/d);
117417ab2063SBarry Smith       }
117517ab2063SBarry Smith     }
117617ab2063SBarry Smith     its--;
117717ab2063SBarry Smith   }
117817ab2063SBarry Smith   while (its--) {
117917ab2063SBarry Smith     if (flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP){
118017ab2063SBarry Smith       for ( i=0; i<m; i++ ) {
1181416022c9SBarry Smith         d    = fshift + a->a[diag[i]+shift];
1182416022c9SBarry Smith         n    = a->i[i+1] - a->i[i];
1183488ecbafSBarry Smith 	PLogFlops(2*n-1);
1184416022c9SBarry Smith         idx  = a->j + a->i[i] + shift;
1185416022c9SBarry Smith         v    = a->a + a->i[i] + shift;
118617ab2063SBarry Smith         sum  = b[i];
118717ab2063SBarry Smith         SPARSEDENSEMDOT(sum,xs,v,idx,n);
11887e33a6baSBarry Smith         x[i] = (1. - omega)*x[i] + omega*(sum + a->a[diag[i]+shift]*x[i])/d;
118917ab2063SBarry Smith       }
119017ab2063SBarry Smith     }
119117ab2063SBarry Smith     if (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP){
119217ab2063SBarry Smith       for ( i=m-1; i>=0; i-- ) {
1193416022c9SBarry Smith         d    = fshift + a->a[diag[i] + shift];
1194416022c9SBarry Smith         n    = a->i[i+1] - a->i[i];
1195488ecbafSBarry Smith 	PLogFlops(2*n-1);
1196416022c9SBarry Smith         idx  = a->j + a->i[i] + shift;
1197416022c9SBarry Smith         v    = a->a + a->i[i] + shift;
119817ab2063SBarry Smith         sum  = b[i];
119917ab2063SBarry Smith         SPARSEDENSEMDOT(sum,xs,v,idx,n);
12007e33a6baSBarry Smith         x[i] = (1. - omega)*x[i] + omega*(sum + a->a[diag[i]+shift]*x[i])/d;
120117ab2063SBarry Smith       }
120217ab2063SBarry Smith     }
120317ab2063SBarry Smith   }
1204cb5b572fSBarry Smith   ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr);
1205fb2e594dSBarry Smith   if (bb != xx) {ierr = VecRestoreArray(bb,&b);CHKERRQ(ierr);}
12063a40ed3dSBarry Smith   PetscFunctionReturn(0);
120717ab2063SBarry Smith }
120817ab2063SBarry Smith 
12095615d1e5SSatish Balay #undef __FUNC__
12105615d1e5SSatish Balay #define __FUNC__ "MatGetInfo_SeqAIJ"
12118f6be9afSLois Curfman McInnes int MatGetInfo_SeqAIJ(Mat A,MatInfoType flag,MatInfo *info)
121217ab2063SBarry Smith {
1213416022c9SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data;
12144e220ebcSLois Curfman McInnes 
12153a40ed3dSBarry Smith   PetscFunctionBegin;
12164e220ebcSLois Curfman McInnes   info->rows_global    = (double)a->m;
12174e220ebcSLois Curfman McInnes   info->columns_global = (double)a->n;
12184e220ebcSLois Curfman McInnes   info->rows_local     = (double)a->m;
12194e220ebcSLois Curfman McInnes   info->columns_local  = (double)a->n;
12204e220ebcSLois Curfman McInnes   info->block_size     = 1.0;
12214e220ebcSLois Curfman McInnes   info->nz_allocated   = (double)a->maxnz;
12224e220ebcSLois Curfman McInnes   info->nz_used        = (double)a->nz;
12234e220ebcSLois Curfman McInnes   info->nz_unneeded    = (double)(a->maxnz - a->nz);
12244e220ebcSLois Curfman McInnes   info->assemblies     = (double)A->num_ass;
12254e220ebcSLois Curfman McInnes   info->mallocs        = (double)a->reallocs;
12264e220ebcSLois Curfman McInnes   info->memory         = A->mem;
12274e220ebcSLois Curfman McInnes   if (A->factor) {
12284e220ebcSLois Curfman McInnes     info->fill_ratio_given  = A->info.fill_ratio_given;
12294e220ebcSLois Curfman McInnes     info->fill_ratio_needed = A->info.fill_ratio_needed;
12304e220ebcSLois Curfman McInnes     info->factor_mallocs    = A->info.factor_mallocs;
12314e220ebcSLois Curfman McInnes   } else {
12324e220ebcSLois Curfman McInnes     info->fill_ratio_given  = 0;
12334e220ebcSLois Curfman McInnes     info->fill_ratio_needed = 0;
12344e220ebcSLois Curfman McInnes     info->factor_mallocs    = 0;
12354e220ebcSLois Curfman McInnes   }
12363a40ed3dSBarry Smith   PetscFunctionReturn(0);
123717ab2063SBarry Smith }
123817ab2063SBarry Smith 
123917ab2063SBarry Smith extern int MatLUFactorSymbolic_SeqAIJ(Mat,IS,IS,double,Mat*);
124017ab2063SBarry Smith extern int MatLUFactorNumeric_SeqAIJ(Mat,Mat*);
124117ab2063SBarry Smith extern int MatLUFactor_SeqAIJ(Mat,IS,IS,double);
124217ab2063SBarry Smith extern int MatSolve_SeqAIJ(Mat,Vec,Vec);
124317ab2063SBarry Smith extern int MatSolveAdd_SeqAIJ(Mat,Vec,Vec,Vec);
124417ab2063SBarry Smith extern int MatSolveTrans_SeqAIJ(Mat,Vec,Vec);
124517ab2063SBarry Smith extern int MatSolveTransAdd_SeqAIJ(Mat,Vec,Vec,Vec);
124617ab2063SBarry Smith 
12475615d1e5SSatish Balay #undef __FUNC__
12485615d1e5SSatish Balay #define __FUNC__ "MatZeroRows_SeqAIJ"
12498f6be9afSLois Curfman McInnes int MatZeroRows_SeqAIJ(Mat A,IS is,Scalar *diag)
125017ab2063SBarry Smith {
1251416022c9SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data;
1252416022c9SBarry Smith   int         i,ierr,N, *rows,m = a->m - 1,shift = a->indexshift;
125317ab2063SBarry Smith 
12543a40ed3dSBarry Smith   PetscFunctionBegin;
125577c4ece6SBarry Smith   ierr = ISGetSize(is,&N);CHKERRQ(ierr);
125617ab2063SBarry Smith   ierr = ISGetIndices(is,&rows);CHKERRQ(ierr);
125717ab2063SBarry Smith   if (diag) {
125817ab2063SBarry Smith     for ( i=0; i<N; i++ ) {
1259a8c6a408SBarry Smith       if (rows[i] < 0 || rows[i] > m) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"row out of range");
12607ae801bdSBarry Smith       if (a->ilen[rows[i]] > 0) {
1261416022c9SBarry Smith         a->ilen[rows[i]]          = 1;
1262416022c9SBarry Smith         a->a[a->i[rows[i]]+shift] = *diag;
1263416022c9SBarry Smith         a->j[a->i[rows[i]]+shift] = rows[i]+shift;
12647ae801bdSBarry Smith       } else { /* in case row was completely empty */
1265d64ed03dSBarry Smith         ierr = MatSetValues_SeqAIJ(A,1,&rows[i],1,&rows[i],diag,INSERT_VALUES);CHKERRQ(ierr);
126617ab2063SBarry Smith       }
126717ab2063SBarry Smith     }
12683a40ed3dSBarry Smith   } else {
126917ab2063SBarry Smith     for ( i=0; i<N; i++ ) {
1270a8c6a408SBarry Smith       if (rows[i] < 0 || rows[i] > m) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"row out of range");
1271416022c9SBarry Smith       a->ilen[rows[i]] = 0;
127217ab2063SBarry Smith     }
127317ab2063SBarry Smith   }
12747ae801bdSBarry Smith   ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr);
127543a90d84SBarry Smith   ierr = MatAssemblyEnd_SeqAIJ(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
12763a40ed3dSBarry Smith   PetscFunctionReturn(0);
127717ab2063SBarry Smith }
127817ab2063SBarry Smith 
12795615d1e5SSatish Balay #undef __FUNC__
12805615d1e5SSatish Balay #define __FUNC__ "MatGetSize_SeqAIJ"
12818f6be9afSLois Curfman McInnes int MatGetSize_SeqAIJ(Mat A,int *m,int *n)
128217ab2063SBarry Smith {
1283416022c9SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data;
12843a40ed3dSBarry Smith 
12853a40ed3dSBarry Smith   PetscFunctionBegin;
12860752156aSBarry Smith   if (m) *m = a->m;
12870752156aSBarry Smith   if (n) *n = a->n;
12883a40ed3dSBarry Smith   PetscFunctionReturn(0);
128917ab2063SBarry Smith }
129017ab2063SBarry Smith 
12915615d1e5SSatish Balay #undef __FUNC__
12925615d1e5SSatish Balay #define __FUNC__ "MatGetOwnershipRange_SeqAIJ"
12938f6be9afSLois Curfman McInnes int MatGetOwnershipRange_SeqAIJ(Mat A,int *m,int *n)
129417ab2063SBarry Smith {
1295416022c9SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data;
12963a40ed3dSBarry Smith 
12973a40ed3dSBarry Smith   PetscFunctionBegin;
1298416022c9SBarry Smith   *m = 0; *n = a->m;
12993a40ed3dSBarry Smith   PetscFunctionReturn(0);
130017ab2063SBarry Smith }
1301026e39d0SSatish Balay 
13025615d1e5SSatish Balay #undef __FUNC__
13035615d1e5SSatish Balay #define __FUNC__ "MatGetRow_SeqAIJ"
13044e093b46SBarry Smith int MatGetRow_SeqAIJ(Mat A,int row,int *nz,int **idx,Scalar **v)
130517ab2063SBarry Smith {
1306416022c9SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data;
1307c456f294SBarry Smith   int        *itmp,i,shift = a->indexshift;
130817ab2063SBarry Smith 
13093a40ed3dSBarry Smith   PetscFunctionBegin;
1310a8c6a408SBarry Smith   if (row < 0 || row >= a->m) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Row out of range");
131117ab2063SBarry Smith 
1312416022c9SBarry Smith   *nz = a->i[row+1] - a->i[row];
1313416022c9SBarry Smith   if (v) *v = a->a + a->i[row] + shift;
131417ab2063SBarry Smith   if (idx) {
1315416022c9SBarry Smith     itmp = a->j + a->i[row] + shift;
13164e093b46SBarry Smith     if (*nz && shift) {
13170452661fSBarry Smith       *idx = (int *) PetscMalloc( (*nz)*sizeof(int) );CHKPTRQ(*idx);
131817ab2063SBarry Smith       for ( i=0; i<(*nz); i++ ) {(*idx)[i] = itmp[i] + shift;}
13194e093b46SBarry Smith     } else if (*nz) {
13204e093b46SBarry Smith       *idx = itmp;
132117ab2063SBarry Smith     }
132217ab2063SBarry Smith     else *idx = 0;
132317ab2063SBarry Smith   }
13243a40ed3dSBarry Smith   PetscFunctionReturn(0);
132517ab2063SBarry Smith }
132617ab2063SBarry Smith 
13275615d1e5SSatish Balay #undef __FUNC__
13285615d1e5SSatish Balay #define __FUNC__ "MatRestoreRow_SeqAIJ"
13294e093b46SBarry Smith int MatRestoreRow_SeqAIJ(Mat A,int row,int *nz,int **idx,Scalar **v)
133017ab2063SBarry Smith {
13314e093b46SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data;
1332606d414cSSatish Balay   int ierr;
13333a40ed3dSBarry Smith 
13343a40ed3dSBarry Smith   PetscFunctionBegin;
1335606d414cSSatish Balay   if (idx) {if (*idx && a->indexshift) {ierr = PetscFree(*idx);CHKERRQ(ierr);}}
13363a40ed3dSBarry Smith   PetscFunctionReturn(0);
133717ab2063SBarry Smith }
133817ab2063SBarry Smith 
13395615d1e5SSatish Balay #undef __FUNC__
13405615d1e5SSatish Balay #define __FUNC__ "MatNorm_SeqAIJ"
13418f6be9afSLois Curfman McInnes int MatNorm_SeqAIJ(Mat A,NormType type,double *norm)
134217ab2063SBarry Smith {
1343416022c9SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data;
1344416022c9SBarry Smith   Scalar     *v = a->a;
134517ab2063SBarry Smith   double     sum = 0.0;
1346549d3d68SSatish Balay   int        i, j,shift = a->indexshift,ierr;
134717ab2063SBarry Smith 
13483a40ed3dSBarry Smith   PetscFunctionBegin;
134917ab2063SBarry Smith   if (type == NORM_FROBENIUS) {
1350416022c9SBarry Smith     for (i=0; i<a->nz; i++ ) {
1351aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
1352e20fef11SSatish Balay       sum += PetscReal(PetscConj(*v)*(*v)); v++;
135317ab2063SBarry Smith #else
135417ab2063SBarry Smith       sum += (*v)*(*v); v++;
135517ab2063SBarry Smith #endif
135617ab2063SBarry Smith     }
135717ab2063SBarry Smith     *norm = sqrt(sum);
13583a40ed3dSBarry Smith   } else if (type == NORM_1) {
135917ab2063SBarry Smith     double *tmp;
1360416022c9SBarry Smith     int    *jj = a->j;
136166963ce1SSatish Balay     tmp = (double *) PetscMalloc( (a->n+1)*sizeof(double) );CHKPTRQ(tmp);
1362549d3d68SSatish Balay     ierr = PetscMemzero(tmp,a->n*sizeof(double));CHKERRQ(ierr);
136317ab2063SBarry Smith     *norm = 0.0;
1364416022c9SBarry Smith     for ( j=0; j<a->nz; j++ ) {
1365a2744918SBarry Smith         tmp[*jj++ + shift] += PetscAbsScalar(*v);  v++;
136617ab2063SBarry Smith     }
1367416022c9SBarry Smith     for ( j=0; j<a->n; j++ ) {
136817ab2063SBarry Smith       if (tmp[j] > *norm) *norm = tmp[j];
136917ab2063SBarry Smith     }
1370606d414cSSatish Balay     ierr = PetscFree(tmp);CHKERRQ(ierr);
13713a40ed3dSBarry Smith   } else if (type == NORM_INFINITY) {
137217ab2063SBarry Smith     *norm = 0.0;
1373416022c9SBarry Smith     for ( j=0; j<a->m; j++ ) {
1374416022c9SBarry Smith       v = a->a + a->i[j] + shift;
137517ab2063SBarry Smith       sum = 0.0;
1376416022c9SBarry Smith       for ( i=0; i<a->i[j+1]-a->i[j]; i++ ) {
1377cddf8d76SBarry Smith         sum += PetscAbsScalar(*v); v++;
137817ab2063SBarry Smith       }
137917ab2063SBarry Smith       if (sum > *norm) *norm = sum;
138017ab2063SBarry Smith     }
13813a40ed3dSBarry Smith   } else {
1382a8c6a408SBarry Smith     SETERRQ(PETSC_ERR_SUP,0,"No support for two norm");
138317ab2063SBarry Smith   }
13843a40ed3dSBarry Smith   PetscFunctionReturn(0);
138517ab2063SBarry Smith }
138617ab2063SBarry Smith 
13875615d1e5SSatish Balay #undef __FUNC__
13885615d1e5SSatish Balay #define __FUNC__ "MatTranspose_SeqAIJ"
13898f6be9afSLois Curfman McInnes int MatTranspose_SeqAIJ(Mat A,Mat *B)
139017ab2063SBarry Smith {
1391416022c9SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data;
1392416022c9SBarry Smith   Mat        C;
1393416022c9SBarry Smith   int        i, ierr, *aj = a->j, *ai = a->i, m = a->m, len, *col;
1394416022c9SBarry Smith   int        shift = a->indexshift;
1395d5d45c9bSBarry Smith   Scalar     *array = a->a;
139617ab2063SBarry Smith 
13973a40ed3dSBarry Smith   PetscFunctionBegin;
1398a8c6a408SBarry Smith   if (B == PETSC_NULL && m != a->n) SETERRQ(PETSC_ERR_ARG_SIZ,0,"Square matrix only for in-place");
13990452661fSBarry Smith   col  = (int *) PetscMalloc((1+a->n)*sizeof(int));CHKPTRQ(col);
1400549d3d68SSatish Balay   ierr = PetscMemzero(col,(1+a->n)*sizeof(int));CHKERRQ(ierr);
140117ab2063SBarry Smith   if (shift) {
140217ab2063SBarry Smith     for ( i=0; i<ai[m]-1; i++ ) aj[i] -= 1;
140317ab2063SBarry Smith   }
140417ab2063SBarry Smith   for ( i=0; i<ai[m]+shift; i++ ) col[aj[i]] += 1;
1405416022c9SBarry Smith   ierr = MatCreateSeqAIJ(A->comm,a->n,m,0,col,&C);CHKERRQ(ierr);
1406606d414cSSatish Balay   ierr = PetscFree(col);CHKERRQ(ierr);
140717ab2063SBarry Smith   for ( i=0; i<m; i++ ) {
140817ab2063SBarry Smith     len = ai[i+1]-ai[i];
1409416022c9SBarry Smith     ierr = MatSetValues(C,len,aj,1,&i,array,INSERT_VALUES);CHKERRQ(ierr);
141017ab2063SBarry Smith     array += len; aj += len;
141117ab2063SBarry Smith   }
141217ab2063SBarry Smith   if (shift) {
141317ab2063SBarry Smith     for ( i=0; i<ai[m]-1; i++ ) aj[i] += 1;
141417ab2063SBarry Smith   }
141517ab2063SBarry Smith 
14166d4a8577SBarry Smith   ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
14176d4a8577SBarry Smith   ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
141817ab2063SBarry Smith 
14193638b69dSLois Curfman McInnes   if (B != PETSC_NULL) {
1420416022c9SBarry Smith     *B = C;
142117ab2063SBarry Smith   } else {
1422f830108cSBarry Smith     PetscOps *Abops;
14230a6ffc59SBarry Smith     MatOps   Aops;
1424f830108cSBarry Smith 
1425416022c9SBarry Smith     /* This isn't really an in-place transpose */
1426606d414cSSatish Balay     ierr = PetscFree(a->a);CHKERRQ(ierr);
1427606d414cSSatish Balay     if (!a->singlemalloc) {
1428606d414cSSatish Balay       ierr = PetscFree(a->i);CHKERRQ(ierr);
1429606d414cSSatish Balay       ierr = PetscFree(a->j);
1430606d414cSSatish Balay     }
1431606d414cSSatish Balay     if (a->diag) {ierr = PetscFree(a->diag);CHKERRQ(ierr);}
1432606d414cSSatish Balay     if (a->ilen) {ierr = PetscFree(a->ilen);CHKERRQ(ierr);}
1433606d414cSSatish Balay     if (a->imax) {ierr = PetscFree(a->imax);CHKERRQ(ierr);}
1434606d414cSSatish Balay     if (a->solve_work) {ierr = PetscFree(a->solve_work);CHKERRQ(ierr);}
1435606d414cSSatish Balay     if (a->inode.size) {ierr = PetscFree(a->inode.size);CHKERRQ(ierr);}
1436606d414cSSatish Balay     ierr = PetscFree(a);CHKERRQ(ierr);
1437f830108cSBarry Smith 
1438488ecbafSBarry Smith 
1439488ecbafSBarry Smith     ierr = MapDestroy(A->rmap);CHKERRQ(ierr);
1440488ecbafSBarry Smith     ierr = MapDestroy(A->cmap);CHKERRQ(ierr);
1441488ecbafSBarry Smith 
1442f830108cSBarry Smith     /*
1443f830108cSBarry Smith       This is horrible, horrible code. We need to keep the
14448f0f457cSSatish Balay       the bops and ops Structures, copy everything from C
14458f0f457cSSatish Balay       including the function pointers..
1446f830108cSBarry Smith     */
1447549d3d68SSatish Balay     ierr     = PetscMemcpy(A->ops,C->ops,sizeof(struct _MatOps));CHKERRQ(ierr);
1448549d3d68SSatish Balay     ierr     = PetscMemcpy(A->bops,C->bops,sizeof(PetscOps));CHKERRQ(ierr);
1449f830108cSBarry Smith     Abops    = A->bops;
1450f830108cSBarry Smith     Aops     = A->ops;
1451549d3d68SSatish Balay     ierr     = PetscMemcpy(A,C,sizeof(struct _p_Mat));CHKERRQ(ierr);
1452f830108cSBarry Smith     A->bops  = Abops;
1453f830108cSBarry Smith     A->ops   = Aops;
145427a8da17SBarry Smith     A->qlist = 0;
1455f830108cSBarry Smith 
14560452661fSBarry Smith     PetscHeaderDestroy(C);
145717ab2063SBarry Smith   }
14583a40ed3dSBarry Smith   PetscFunctionReturn(0);
145917ab2063SBarry Smith }
146017ab2063SBarry Smith 
14615615d1e5SSatish Balay #undef __FUNC__
14625615d1e5SSatish Balay #define __FUNC__ "MatDiagonalScale_SeqAIJ"
14638f6be9afSLois Curfman McInnes int MatDiagonalScale_SeqAIJ(Mat A,Vec ll,Vec rr)
146417ab2063SBarry Smith {
1465416022c9SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data;
146617ab2063SBarry Smith   Scalar     *l,*r,x,*v;
1467e1311b90SBarry Smith   int        ierr,i,j,m = a->m, n = a->n, M, nz = a->nz, *jj,shift = a->indexshift;
146817ab2063SBarry Smith 
14693a40ed3dSBarry Smith   PetscFunctionBegin;
147017ab2063SBarry Smith   if (ll) {
14713ea7c6a1SSatish Balay     /* The local size is used so that VecMPI can be passed to this routine
14723ea7c6a1SSatish Balay        by MatDiagonalScale_MPIAIJ */
1473e1311b90SBarry Smith     ierr = VecGetLocalSize(ll,&m);CHKERRQ(ierr);
1474a8c6a408SBarry Smith     if (m != a->m) SETERRQ(PETSC_ERR_ARG_SIZ,0,"Left scaling vector wrong length");
1475e1311b90SBarry Smith     ierr = VecGetArray(ll,&l);CHKERRQ(ierr);
1476416022c9SBarry Smith     v = a->a;
147717ab2063SBarry Smith     for ( i=0; i<m; i++ ) {
147817ab2063SBarry Smith       x = l[i];
1479416022c9SBarry Smith       M = a->i[i+1] - a->i[i];
148017ab2063SBarry Smith       for ( j=0; j<M; j++ ) { (*v++) *= x;}
148117ab2063SBarry Smith     }
1482e1311b90SBarry Smith     ierr = VecRestoreArray(ll,&l);CHKERRQ(ierr);
148344cd7ae7SLois Curfman McInnes     PLogFlops(nz);
148417ab2063SBarry Smith   }
148517ab2063SBarry Smith   if (rr) {
1486e1311b90SBarry Smith     ierr = VecGetLocalSize(rr,&n);CHKERRQ(ierr);
1487a8c6a408SBarry Smith     if (n != a->n) SETERRQ(PETSC_ERR_ARG_SIZ,0,"Right scaling vector wrong length");
1488e1311b90SBarry Smith     ierr = VecGetArray(rr,&r);CHKERRQ(ierr);
1489416022c9SBarry Smith     v = a->a; jj = a->j;
149017ab2063SBarry Smith     for ( i=0; i<nz; i++ ) {
149117ab2063SBarry Smith       (*v++) *= r[*jj++ + shift];
149217ab2063SBarry Smith     }
1493e1311b90SBarry Smith     ierr = VecRestoreArray(rr,&r);CHKERRQ(ierr);
149444cd7ae7SLois Curfman McInnes     PLogFlops(nz);
149517ab2063SBarry Smith   }
14963a40ed3dSBarry Smith   PetscFunctionReturn(0);
149717ab2063SBarry Smith }
149817ab2063SBarry Smith 
14995615d1e5SSatish Balay #undef __FUNC__
15005615d1e5SSatish Balay #define __FUNC__ "MatGetSubMatrix_SeqAIJ"
15017b2a1423SBarry Smith int MatGetSubMatrix_SeqAIJ(Mat A,IS isrow,IS iscol,int csize,MatReuse scall,Mat *B)
150217ab2063SBarry Smith {
1503db02288aSLois Curfman McInnes   Mat_SeqAIJ   *a = (Mat_SeqAIJ *) A->data,*c;
1504d5db1b72SBarry Smith   int          *smap, i, k, kstart, kend, ierr, oldcols = a->n,*lens;
150599141d43SSatish Balay   int          row,mat_i,*mat_j,tcol,first,step,*mat_ilen;
1506a2744918SBarry Smith   register int sum,lensi;
150799141d43SSatish Balay   int          *irow, *icol, nrows, ncols, shift = a->indexshift,*ssmap;
150899141d43SSatish Balay   int          *starts,*j_new,*i_new,*aj = a->j, *ai = a->i,ii,*ailen = a->ilen;
150999141d43SSatish Balay   Scalar       *a_new,*mat_a;
1510416022c9SBarry Smith   Mat          C;
1511fee21e36SBarry Smith   PetscTruth   stride;
151217ab2063SBarry Smith 
15133a40ed3dSBarry Smith   PetscFunctionBegin;
1514d64ed03dSBarry Smith   ierr = ISSorted(isrow,(PetscTruth*)&i);CHKERRQ(ierr);
1515a8c6a408SBarry Smith   if (!i) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,0,"ISrow is not sorted");
1516d64ed03dSBarry Smith   ierr = ISSorted(iscol,(PetscTruth*)&i);CHKERRQ(ierr);
1517a8c6a408SBarry Smith   if (!i) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,0,"IScol is not sorted");
151899141d43SSatish Balay 
151917ab2063SBarry Smith   ierr = ISGetIndices(isrow,&irow);CHKERRQ(ierr);
152017ab2063SBarry Smith   ierr = ISGetSize(isrow,&nrows);CHKERRQ(ierr);
152117ab2063SBarry Smith   ierr = ISGetSize(iscol,&ncols);CHKERRQ(ierr);
152217ab2063SBarry Smith 
1523fee21e36SBarry Smith   ierr = ISStrideGetInfo(iscol,&first,&step);CHKERRQ(ierr);
1524fee21e36SBarry Smith   ierr = ISStride(iscol,&stride);CHKERRQ(ierr);
1525fee21e36SBarry Smith   if (stride && step == 1) {
152602834360SBarry Smith     /* special case of contiguous rows */
152757faeb66SBarry Smith     lens   = (int *) PetscMalloc((ncols+nrows+1)*sizeof(int));CHKPTRQ(lens);
152802834360SBarry Smith     starts = lens + ncols;
152902834360SBarry Smith     /* loop over new rows determining lens and starting points */
153002834360SBarry Smith     for (i=0; i<nrows; i++) {
1531a2744918SBarry Smith       kstart  = ai[irow[i]]+shift;
1532a2744918SBarry Smith       kend    = kstart + ailen[irow[i]];
153302834360SBarry Smith       for ( k=kstart; k<kend; k++ ) {
1534d8ced48eSBarry Smith         if (aj[k]+shift >= first) {
153502834360SBarry Smith           starts[i] = k;
153602834360SBarry Smith           break;
153702834360SBarry Smith 	}
153802834360SBarry Smith       }
1539a2744918SBarry Smith       sum = 0;
154002834360SBarry Smith       while (k < kend) {
1541d8ced48eSBarry Smith         if (aj[k++]+shift >= first+ncols) break;
1542a2744918SBarry Smith         sum++;
154302834360SBarry Smith       }
1544a2744918SBarry Smith       lens[i] = sum;
154502834360SBarry Smith     }
154602834360SBarry Smith     /* create submatrix */
1547cddf8d76SBarry Smith     if (scall == MAT_REUSE_MATRIX) {
154808480c60SBarry Smith       int n_cols,n_rows;
154908480c60SBarry Smith       ierr = MatGetSize(*B,&n_rows,&n_cols);CHKERRQ(ierr);
1550a8c6a408SBarry Smith       if (n_rows != nrows || n_cols != ncols) SETERRQ(PETSC_ERR_ARG_SIZ,0,"Reused submatrix wrong size");
1551d8ced48eSBarry Smith       ierr = MatZeroEntries(*B);CHKERRQ(ierr);
155208480c60SBarry Smith       C = *B;
15533a40ed3dSBarry Smith     } else {
155402834360SBarry Smith       ierr = MatCreateSeqAIJ(A->comm,nrows,ncols,0,lens,&C);CHKERRQ(ierr);
155508480c60SBarry Smith     }
1556db02288aSLois Curfman McInnes     c = (Mat_SeqAIJ*) C->data;
1557db02288aSLois Curfman McInnes 
155802834360SBarry Smith     /* loop over rows inserting into submatrix */
1559db02288aSLois Curfman McInnes     a_new    = c->a;
1560db02288aSLois Curfman McInnes     j_new    = c->j;
1561db02288aSLois Curfman McInnes     i_new    = c->i;
1562db02288aSLois Curfman McInnes     i_new[0] = -shift;
156302834360SBarry Smith     for (i=0; i<nrows; i++) {
1564a2744918SBarry Smith       ii    = starts[i];
1565a2744918SBarry Smith       lensi = lens[i];
1566a2744918SBarry Smith       for ( k=0; k<lensi; k++ ) {
1567a2744918SBarry Smith         *j_new++ = aj[ii+k] - first;
156802834360SBarry Smith       }
1569549d3d68SSatish Balay       ierr = PetscMemcpy(a_new,a->a + starts[i],lensi*sizeof(Scalar));CHKERRQ(ierr);
1570a2744918SBarry Smith       a_new      += lensi;
1571a2744918SBarry Smith       i_new[i+1]  = i_new[i] + lensi;
1572a2744918SBarry Smith       c->ilen[i]  = lensi;
157302834360SBarry Smith     }
1574606d414cSSatish Balay     ierr = PetscFree(lens);CHKERRQ(ierr);
15753a40ed3dSBarry Smith   } else {
157602834360SBarry Smith     ierr  = ISGetIndices(iscol,&icol);CHKERRQ(ierr);
15770452661fSBarry Smith     smap  = (int *) PetscMalloc((1+oldcols)*sizeof(int));CHKPTRQ(smap);
157802834360SBarry Smith     ssmap = smap + shift;
157999141d43SSatish Balay     lens  = (int *) PetscMalloc((1+nrows)*sizeof(int));CHKPTRQ(lens);
1580549d3d68SSatish Balay     ierr  = PetscMemzero(smap,oldcols*sizeof(int));CHKERRQ(ierr);
158117ab2063SBarry Smith     for ( i=0; i<ncols; i++ ) smap[icol[i]] = i+1;
158202834360SBarry Smith     /* determine lens of each row */
158302834360SBarry Smith     for (i=0; i<nrows; i++) {
1584d8ced48eSBarry Smith       kstart  = ai[irow[i]]+shift;
158502834360SBarry Smith       kend    = kstart + a->ilen[irow[i]];
158602834360SBarry Smith       lens[i] = 0;
158702834360SBarry Smith       for ( k=kstart; k<kend; k++ ) {
1588d8ced48eSBarry Smith         if (ssmap[aj[k]]) {
158902834360SBarry Smith           lens[i]++;
159002834360SBarry Smith         }
159102834360SBarry Smith       }
159202834360SBarry Smith     }
159317ab2063SBarry Smith     /* Create and fill new matrix */
1594a2744918SBarry Smith     if (scall == MAT_REUSE_MATRIX) {
15950f5bd95cSBarry Smith       PetscTruth equal;
15960f5bd95cSBarry Smith 
159799141d43SSatish Balay       c = (Mat_SeqAIJ *)((*B)->data);
1598a8c6a408SBarry Smith       if (c->m  != nrows || c->n != ncols) SETERRQ(PETSC_ERR_ARG_SIZ,0,"Cannot reuse matrix. wrong size");
15990f5bd95cSBarry Smith       ierr = PetscMemcmp(c->ilen,lens, c->m*sizeof(int),&equal);CHKERRQ(ierr);
16000f5bd95cSBarry Smith       if (!equal) {
1601a8c6a408SBarry Smith         SETERRQ(PETSC_ERR_ARG_SIZ,0,"Cannot reuse matrix. wrong no of nonzeros");
160299141d43SSatish Balay       }
1603549d3d68SSatish Balay       ierr = PetscMemzero(c->ilen,c->m*sizeof(int));CHKERRQ(ierr);
160408480c60SBarry Smith       C = *B;
16053a40ed3dSBarry Smith     } else {
160602834360SBarry Smith       ierr = MatCreateSeqAIJ(A->comm,nrows,ncols,0,lens,&C);CHKERRQ(ierr);
160708480c60SBarry Smith     }
160899141d43SSatish Balay     c = (Mat_SeqAIJ *)(C->data);
160917ab2063SBarry Smith     for (i=0; i<nrows; i++) {
161099141d43SSatish Balay       row    = irow[i];
161199141d43SSatish Balay       kstart = ai[row]+shift;
161299141d43SSatish Balay       kend   = kstart + a->ilen[row];
161399141d43SSatish Balay       mat_i  = c->i[i]+shift;
161499141d43SSatish Balay       mat_j  = c->j + mat_i;
161599141d43SSatish Balay       mat_a  = c->a + mat_i;
161699141d43SSatish Balay       mat_ilen = c->ilen + i;
161717ab2063SBarry Smith       for ( k=kstart; k<kend; k++ ) {
161899141d43SSatish Balay         if ((tcol=ssmap[a->j[k]])) {
161999141d43SSatish Balay           *mat_j++ = tcol - (!shift);
162099141d43SSatish Balay           *mat_a++ = a->a[k];
162199141d43SSatish Balay           (*mat_ilen)++;
162299141d43SSatish Balay 
162317ab2063SBarry Smith         }
162417ab2063SBarry Smith       }
162517ab2063SBarry Smith     }
162602834360SBarry Smith     /* Free work space */
162702834360SBarry Smith     ierr = ISRestoreIndices(iscol,&icol);CHKERRQ(ierr);
1628606d414cSSatish Balay     ierr = PetscFree(smap);CHKERRQ(ierr);
1629606d414cSSatish Balay     ierr = PetscFree(lens);CHKERRQ(ierr);
163002834360SBarry Smith   }
16316d4a8577SBarry Smith   ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
16326d4a8577SBarry Smith   ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
163317ab2063SBarry Smith 
163417ab2063SBarry Smith   ierr = ISRestoreIndices(isrow,&irow);CHKERRQ(ierr);
1635416022c9SBarry Smith   *B = C;
16363a40ed3dSBarry Smith   PetscFunctionReturn(0);
163717ab2063SBarry Smith }
163817ab2063SBarry Smith 
1639a871dcd8SBarry Smith /*
1640a871dcd8SBarry Smith */
16415615d1e5SSatish Balay #undef __FUNC__
16425615d1e5SSatish Balay #define __FUNC__ "MatILUFactor_SeqAIJ"
16435ef9f2a5SBarry Smith int MatILUFactor_SeqAIJ(Mat inA,IS row,IS col,MatILUInfo *info)
1644a871dcd8SBarry Smith {
164563b91edcSBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ *) inA->data;
164608480c60SBarry Smith   int        ierr;
164763b91edcSBarry Smith   Mat        outA;
1648b8a78c4aSBarry Smith   PetscTruth row_identity, col_identity;
164963b91edcSBarry Smith 
16503a40ed3dSBarry Smith   PetscFunctionBegin;
1651b8a78c4aSBarry Smith   if (info && info->levels != 0) SETERRQ(PETSC_ERR_SUP,0,"Only levels=0 supported for in-place ilu");
1652b8a78c4aSBarry Smith   ierr = ISIdentity(row,&row_identity);CHKERRQ(ierr);
1653b8a78c4aSBarry Smith   ierr = ISIdentity(col,&col_identity);CHKERRQ(ierr);
1654b8a78c4aSBarry Smith   if (!row_identity || !col_identity) {
1655b8a78c4aSBarry Smith     SETERRQ(1,1,"Row and column permutations must be identity for in-place ILU");
1656b8a78c4aSBarry Smith   }
1657a871dcd8SBarry Smith 
165863b91edcSBarry Smith   outA          = inA;
165963b91edcSBarry Smith   inA->factor   = FACTOR_LU;
166063b91edcSBarry Smith   a->row        = row;
166163b91edcSBarry Smith   a->col        = col;
1662*c38d4ed2SBarry Smith   ierr = PetscObjectReference((PetscObject)row);CHKERRQ(ierr);
1663*c38d4ed2SBarry Smith   ierr = PetscObjectReference((PetscObject)col);CHKERRQ(ierr);
166463b91edcSBarry Smith 
1665f0ec6fceSSatish Balay   /* Create the invert permutation so that it can be used in MatLUFactorNumeric() */
1666*c38d4ed2SBarry Smith   if (a->icol) {ierr = ISDestroy(a->icol);CHKERRQ(ierr);} /* if this came from a previous factored; need to remove old one */
1667f0ec6fceSSatish Balay   ierr = ISInvertPermutation(col,&(a->icol));CHKERRQ(ierr);
16681e4dd532SSatish Balay   PLogObjectParent(inA,a->icol);
1669f0ec6fceSSatish Balay 
167094a9d846SBarry Smith   if (!a->solve_work) { /* this matrix may have been factored before */
16710452661fSBarry Smith     a->solve_work = (Scalar *) PetscMalloc( (a->m+1)*sizeof(Scalar));CHKPTRQ(a->solve_work);
167294a9d846SBarry Smith   }
167363b91edcSBarry Smith 
167408480c60SBarry Smith   if (!a->diag) {
167508480c60SBarry Smith     ierr = MatMarkDiag_SeqAIJ(inA);CHKERRQ(ierr);
167663b91edcSBarry Smith   }
167763b91edcSBarry Smith   ierr = MatLUFactorNumeric_SeqAIJ(inA,&outA);CHKERRQ(ierr);
16783a40ed3dSBarry Smith   PetscFunctionReturn(0);
1679a871dcd8SBarry Smith }
1680a871dcd8SBarry Smith 
168174cdf0dfSBarry Smith #include "pinclude/blaslapack.h"
16825615d1e5SSatish Balay #undef __FUNC__
16835615d1e5SSatish Balay #define __FUNC__ "MatScale_SeqAIJ"
16848f6be9afSLois Curfman McInnes int MatScale_SeqAIJ(Scalar *alpha,Mat inA)
1685f0b747eeSBarry Smith {
1686f0b747eeSBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ *) inA->data;
1687f0b747eeSBarry Smith   int        one = 1;
16883a40ed3dSBarry Smith 
16893a40ed3dSBarry Smith   PetscFunctionBegin;
1690f0b747eeSBarry Smith   BLscal_( &a->nz, alpha, a->a, &one );
1691f0b747eeSBarry Smith   PLogFlops(a->nz);
16923a40ed3dSBarry Smith   PetscFunctionReturn(0);
1693f0b747eeSBarry Smith }
1694f0b747eeSBarry Smith 
16955615d1e5SSatish Balay #undef __FUNC__
16965615d1e5SSatish Balay #define __FUNC__ "MatGetSubMatrices_SeqAIJ"
16977b2a1423SBarry Smith int MatGetSubMatrices_SeqAIJ(Mat A,int n, IS *irow,IS *icol,MatReuse scall,Mat **B)
1698cddf8d76SBarry Smith {
1699cddf8d76SBarry Smith   int ierr,i;
1700cddf8d76SBarry Smith 
17013a40ed3dSBarry Smith   PetscFunctionBegin;
1702cddf8d76SBarry Smith   if (scall == MAT_INITIAL_MATRIX) {
17030452661fSBarry Smith     *B = (Mat *) PetscMalloc( (n+1)*sizeof(Mat) );CHKPTRQ(*B);
1704cddf8d76SBarry Smith   }
1705cddf8d76SBarry Smith 
1706cddf8d76SBarry Smith   for ( i=0; i<n; i++ ) {
17076a6a5d1dSBarry Smith     ierr = MatGetSubMatrix_SeqAIJ(A,irow[i],icol[i],PETSC_DECIDE,scall,&(*B)[i]);CHKERRQ(ierr);
1708cddf8d76SBarry Smith   }
17093a40ed3dSBarry Smith   PetscFunctionReturn(0);
1710cddf8d76SBarry Smith }
1711cddf8d76SBarry Smith 
17125615d1e5SSatish Balay #undef __FUNC__
17135615d1e5SSatish Balay #define __FUNC__ "MatGetBlockSize_SeqAIJ"
17148f6be9afSLois Curfman McInnes int MatGetBlockSize_SeqAIJ(Mat A, int *bs)
17155a838052SSatish Balay {
1716f830108cSBarry Smith   PetscFunctionBegin;
17175a838052SSatish Balay   *bs = 1;
17183a40ed3dSBarry Smith   PetscFunctionReturn(0);
17195a838052SSatish Balay }
17205a838052SSatish Balay 
17215615d1e5SSatish Balay #undef __FUNC__
17225615d1e5SSatish Balay #define __FUNC__ "MatIncreaseOverlap_SeqAIJ"
17238f6be9afSLois Curfman McInnes int MatIncreaseOverlap_SeqAIJ(Mat A, int is_max, IS *is, int ov)
17244dcbc457SBarry Smith {
1725e4d965acSSatish Balay   Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data;
172606763907SSatish Balay   int        shift, row, i,j,k,l,m,n, *idx,ierr, *nidx, isz, val;
17278a047759SSatish Balay   int        start, end, *ai, *aj;
1728f1af5d2fSBarry Smith   PetscBT    table;
1729bbd702dbSSatish Balay 
17303a40ed3dSBarry Smith   PetscFunctionBegin;
17318a047759SSatish Balay   shift = a->indexshift;
1732e4d965acSSatish Balay   m     = a->m;
1733e4d965acSSatish Balay   ai    = a->i;
17348a047759SSatish Balay   aj    = a->j+shift;
17358a047759SSatish Balay 
1736a8c6a408SBarry Smith   if (ov < 0)  SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"illegal overlap value used");
173706763907SSatish Balay 
173806763907SSatish Balay   nidx  = (int *) PetscMalloc((m+1)*sizeof(int));CHKPTRQ(nidx);
17396831982aSBarry Smith   ierr  = PetscBTCreate(m,table);CHKERRQ(ierr);
174006763907SSatish Balay 
1741e4d965acSSatish Balay   for ( i=0; i<is_max; i++ ) {
1742b97fc60eSLois Curfman McInnes     /* Initialize the two local arrays */
1743e4d965acSSatish Balay     isz  = 0;
17446831982aSBarry Smith     ierr = PetscBTMemzero(m,table);CHKERRQ(ierr);
1745e4d965acSSatish Balay 
1746e4d965acSSatish Balay     /* Extract the indices, assume there can be duplicate entries */
17474dcbc457SBarry Smith     ierr = ISGetIndices(is[i],&idx);CHKERRQ(ierr);
174877c4ece6SBarry Smith     ierr = ISGetSize(is[i],&n);CHKERRQ(ierr);
1749e4d965acSSatish Balay 
1750dd097bc3SLois Curfman McInnes     /* Enter these into the temp arrays. I.e., mark table[row], enter row into new index */
1751e4d965acSSatish Balay     for ( j=0; j<n ; ++j){
1752f1af5d2fSBarry Smith       if(!PetscBTLookupSet(table, idx[j])) { nidx[isz++] = idx[j];}
17534dcbc457SBarry Smith     }
175406763907SSatish Balay     ierr = ISRestoreIndices(is[i],&idx);CHKERRQ(ierr);
175506763907SSatish Balay     ierr = ISDestroy(is[i]);CHKERRQ(ierr);
1756e4d965acSSatish Balay 
175704a348a9SBarry Smith     k = 0;
175804a348a9SBarry Smith     for ( j=0; j<ov; j++){ /* for each overlap */
175904a348a9SBarry Smith       n = isz;
176006763907SSatish Balay       for ( ; k<n ; k++){ /* do only those rows in nidx[k], which are not done yet */
1761e4d965acSSatish Balay         row   = nidx[k];
1762e4d965acSSatish Balay         start = ai[row];
1763e4d965acSSatish Balay         end   = ai[row+1];
176404a348a9SBarry Smith         for ( l = start; l<end ; l++){
17658a047759SSatish Balay           val = aj[l] + shift;
1766f1af5d2fSBarry Smith           if (!PetscBTLookupSet(table,val)) {nidx[isz++] = val;}
1767e4d965acSSatish Balay         }
1768e4d965acSSatish Balay       }
1769e4d965acSSatish Balay     }
1770029af93fSBarry Smith     ierr = ISCreateGeneral(PETSC_COMM_SELF, isz, nidx, (is+i));CHKERRQ(ierr);
1771e4d965acSSatish Balay   }
17726831982aSBarry Smith   ierr = PetscBTDestroy(table);CHKERRQ(ierr);
1773606d414cSSatish Balay   ierr = PetscFree(nidx);CHKERRQ(ierr);
17743a40ed3dSBarry Smith   PetscFunctionReturn(0);
17754dcbc457SBarry Smith }
177617ab2063SBarry Smith 
17770513a670SBarry Smith /* -------------------------------------------------------------- */
17780513a670SBarry Smith #undef __FUNC__
17790513a670SBarry Smith #define __FUNC__ "MatPermute_SeqAIJ"
17800513a670SBarry Smith int MatPermute_SeqAIJ(Mat A, IS rowp, IS colp, Mat *B)
17810513a670SBarry Smith {
17820513a670SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data;
17830513a670SBarry Smith   Scalar     *vwork;
17840513a670SBarry Smith   int        i, ierr, nz, m = a->m, n = a->n, *cwork;
17850513a670SBarry Smith   int        *row,*col,*cnew,j,*lens;
178656cd22aeSBarry Smith   IS         icolp,irowp;
17870513a670SBarry Smith 
17883a40ed3dSBarry Smith   PetscFunctionBegin;
178956cd22aeSBarry Smith   ierr = ISInvertPermutation(rowp,&irowp);CHKERRQ(ierr);
179056cd22aeSBarry Smith   ierr = ISGetIndices(irowp,&row);CHKERRQ(ierr);
179156cd22aeSBarry Smith   ierr = ISInvertPermutation(colp,&icolp);CHKERRQ(ierr);
179256cd22aeSBarry Smith   ierr = ISGetIndices(icolp,&col);CHKERRQ(ierr);
17930513a670SBarry Smith 
17940513a670SBarry Smith   /* determine lengths of permuted rows */
17950513a670SBarry Smith   lens = (int *) PetscMalloc( (m+1)*sizeof(int) );CHKPTRQ(lens);
17960513a670SBarry Smith   for (i=0; i<m; i++ ) {
17970513a670SBarry Smith     lens[row[i]] = a->i[i+1] - a->i[i];
17980513a670SBarry Smith   }
17990513a670SBarry Smith   ierr = MatCreateSeqAIJ(A->comm,m,n,0,lens,B);CHKERRQ(ierr);
1800606d414cSSatish Balay   ierr = PetscFree(lens);CHKERRQ(ierr);
18010513a670SBarry Smith 
18020513a670SBarry Smith   cnew = (int *) PetscMalloc( n*sizeof(int) );CHKPTRQ(cnew);
18030513a670SBarry Smith   for (i=0; i<m; i++) {
18040513a670SBarry Smith     ierr = MatGetRow(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr);
18050513a670SBarry Smith     for (j=0; j<nz; j++ ) { cnew[j] = col[cwork[j]];}
18060513a670SBarry Smith     ierr = MatSetValues(*B,1,&row[i],nz,cnew,vwork,INSERT_VALUES);CHKERRQ(ierr);
18070513a670SBarry Smith     ierr = MatRestoreRow(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr);
18080513a670SBarry Smith   }
1809606d414cSSatish Balay   ierr = PetscFree(cnew);CHKERRQ(ierr);
18100513a670SBarry Smith   ierr = MatAssemblyBegin(*B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
18110513a670SBarry Smith   ierr = MatAssemblyEnd(*B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
181256cd22aeSBarry Smith   ierr = ISRestoreIndices(irowp,&row);CHKERRQ(ierr);
181356cd22aeSBarry Smith   ierr = ISRestoreIndices(icolp,&col);CHKERRQ(ierr);
181456cd22aeSBarry Smith   ierr = ISDestroy(irowp);CHKERRQ(ierr);
181556cd22aeSBarry Smith   ierr = ISDestroy(icolp);CHKERRQ(ierr);
18163a40ed3dSBarry Smith   PetscFunctionReturn(0);
18170513a670SBarry Smith }
18180513a670SBarry Smith 
18195615d1e5SSatish Balay #undef __FUNC__
18205615d1e5SSatish Balay #define __FUNC__ "MatPrintHelp_SeqAIJ"
1821682d7d0cSBarry Smith int MatPrintHelp_SeqAIJ(Mat A)
1822682d7d0cSBarry Smith {
1823*c38d4ed2SBarry Smith   static PetscTruth called = PETSC_FALSE;
1824682d7d0cSBarry Smith   MPI_Comm          comm = A->comm;
1825d132466eSBarry Smith   int               ierr;
1826682d7d0cSBarry Smith 
18273a40ed3dSBarry Smith   PetscFunctionBegin;
1828*c38d4ed2SBarry Smith   if (called) {PetscFunctionReturn(0);} else called = PETSC_TRUE;
1829d132466eSBarry Smith   ierr = (*PetscHelpPrintf)(comm," Options for MATSEQAIJ and MATMPIAIJ matrix formats (the defaults):\n");CHKERRQ(ierr);
1830d132466eSBarry Smith   ierr = (*PetscHelpPrintf)(comm,"  -mat_lu_pivotthreshold <threshold>: Set pivoting threshold\n");CHKERRQ(ierr);
1831d132466eSBarry Smith   ierr = (*PetscHelpPrintf)(comm,"  -mat_aij_oneindex: internal indices begin at 1 instead of the default 0.\n");CHKERRQ(ierr);
1832d132466eSBarry Smith   ierr = (*PetscHelpPrintf)(comm,"  -mat_aij_no_inode: Do not use inodes\n");CHKERRQ(ierr);
1833d132466eSBarry Smith   ierr = (*PetscHelpPrintf)(comm,"  -mat_aij_inode_limit <limit>: Set inode limit (max limit=5)\n");CHKERRQ(ierr);
1834aa482453SBarry Smith #if defined(PETSC_HAVE_ESSL)
1835d132466eSBarry Smith   ierr = (*PetscHelpPrintf)(comm,"  -mat_aij_essl: Use IBM sparse LU factorization and solve.\n");CHKERRQ(ierr);
1836682d7d0cSBarry Smith #endif
18373a40ed3dSBarry Smith   PetscFunctionReturn(0);
1838682d7d0cSBarry Smith }
18398f6be9afSLois Curfman McInnes extern int MatEqual_SeqAIJ(Mat A,Mat B, PetscTruth* flg);
1840a93ec695SBarry Smith extern int MatFDColoringCreate_SeqAIJ(Mat,ISColoring,MatFDColoring);
1841a93ec695SBarry Smith extern int MatColoringPatch_SeqAIJ(Mat,int,int *,ISColoring *);
1842a93ec695SBarry Smith 
1843cb5b572fSBarry Smith #undef __FUNC__
1844cb5b572fSBarry Smith #define __FUNC__ "MatCopy_SeqAIJ"
1845cb5b572fSBarry Smith int MatCopy_SeqAIJ(Mat A,Mat B,MatStructure str)
1846cb5b572fSBarry Smith {
1847be6bf707SBarry Smith   int    ierr;
1848cb5b572fSBarry Smith 
1849cb5b572fSBarry Smith   PetscFunctionBegin;
1850be6bf707SBarry Smith   if (str == SAME_NONZERO_PATTERN && B->type == MATSEQAIJ) {
1851be6bf707SBarry Smith     Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data;
1852be6bf707SBarry Smith     Mat_SeqAIJ *b = (Mat_SeqAIJ *) B->data;
1853be6bf707SBarry Smith 
1854be6bf707SBarry Smith     if (a->i[a->m]+a->indexshift != b->i[b->m]+a->indexshift) {
1855be6bf707SBarry Smith       SETERRQ(1,1,"Number of nonzeros in two matrices are different");
1856cb5b572fSBarry Smith     }
1857549d3d68SSatish Balay     ierr = PetscMemcpy(b->a,a->a,(a->i[a->m]+a->indexshift)*sizeof(Scalar));CHKERRQ(ierr);
1858cb5b572fSBarry Smith   } else {
1859cb5b572fSBarry Smith     ierr = MatCopy_Basic(A,B,str);CHKERRQ(ierr);
1860cb5b572fSBarry Smith   }
1861cb5b572fSBarry Smith   PetscFunctionReturn(0);
1862cb5b572fSBarry Smith }
1863cb5b572fSBarry Smith 
1864682d7d0cSBarry Smith /* -------------------------------------------------------------------*/
18650a6ffc59SBarry Smith static struct _MatOps MatOps_Values = {MatSetValues_SeqAIJ,
1866cb5b572fSBarry Smith        MatGetRow_SeqAIJ,
1867cb5b572fSBarry Smith        MatRestoreRow_SeqAIJ,
1868cb5b572fSBarry Smith        MatMult_SeqAIJ,
1869cb5b572fSBarry Smith        MatMultAdd_SeqAIJ,
1870cb5b572fSBarry Smith        MatMultTrans_SeqAIJ,
1871cb5b572fSBarry Smith        MatMultTransAdd_SeqAIJ,
1872cb5b572fSBarry Smith        MatSolve_SeqAIJ,
1873cb5b572fSBarry Smith        MatSolveAdd_SeqAIJ,
1874cb5b572fSBarry Smith        MatSolveTrans_SeqAIJ,
1875cb5b572fSBarry Smith        MatSolveTransAdd_SeqAIJ,
1876cb5b572fSBarry Smith        MatLUFactor_SeqAIJ,
1877cb5b572fSBarry Smith        0,
187817ab2063SBarry Smith        MatRelax_SeqAIJ,
187917ab2063SBarry Smith        MatTranspose_SeqAIJ,
1880cb5b572fSBarry Smith        MatGetInfo_SeqAIJ,
1881cb5b572fSBarry Smith        MatEqual_SeqAIJ,
1882cb5b572fSBarry Smith        MatGetDiagonal_SeqAIJ,
1883cb5b572fSBarry Smith        MatDiagonalScale_SeqAIJ,
1884cb5b572fSBarry Smith        MatNorm_SeqAIJ,
1885cb5b572fSBarry Smith        0,
1886cb5b572fSBarry Smith        MatAssemblyEnd_SeqAIJ,
188717ab2063SBarry Smith        MatCompress_SeqAIJ,
1888cb5b572fSBarry Smith        MatSetOption_SeqAIJ,
1889cb5b572fSBarry Smith        MatZeroEntries_SeqAIJ,
1890cb5b572fSBarry Smith        MatZeroRows_SeqAIJ,
1891cb5b572fSBarry Smith        MatLUFactorSymbolic_SeqAIJ,
1892cb5b572fSBarry Smith        MatLUFactorNumeric_SeqAIJ,
1893cb5b572fSBarry Smith        0,
1894cb5b572fSBarry Smith        0,
1895cb5b572fSBarry Smith        MatGetSize_SeqAIJ,
1896cb5b572fSBarry Smith        MatGetSize_SeqAIJ,
1897cb5b572fSBarry Smith        MatGetOwnershipRange_SeqAIJ,
1898cb5b572fSBarry Smith        MatILUFactorSymbolic_SeqAIJ,
1899cb5b572fSBarry Smith        0,
1900cb5b572fSBarry Smith        0,
1901cb5b572fSBarry Smith        0,
1902be6bf707SBarry Smith        MatDuplicate_SeqAIJ,
1903cb5b572fSBarry Smith        0,
1904cb5b572fSBarry Smith        0,
1905cb5b572fSBarry Smith        MatILUFactor_SeqAIJ,
1906cb5b572fSBarry Smith        0,
1907cb5b572fSBarry Smith        0,
1908cb5b572fSBarry Smith        MatGetSubMatrices_SeqAIJ,
1909cb5b572fSBarry Smith        MatIncreaseOverlap_SeqAIJ,
1910cb5b572fSBarry Smith        MatGetValues_SeqAIJ,
1911cb5b572fSBarry Smith        MatCopy_SeqAIJ,
1912f0b747eeSBarry Smith        MatPrintHelp_SeqAIJ,
1913cb5b572fSBarry Smith        MatScale_SeqAIJ,
1914cb5b572fSBarry Smith        0,
1915cb5b572fSBarry Smith        0,
19166945ee14SBarry Smith        MatILUDTFactor_SeqAIJ,
19176945ee14SBarry Smith        MatGetBlockSize_SeqAIJ,
19183b2fbd54SBarry Smith        MatGetRowIJ_SeqAIJ,
19193b2fbd54SBarry Smith        MatRestoreRowIJ_SeqAIJ,
19203b2fbd54SBarry Smith        MatGetColumnIJ_SeqAIJ,
1921a93ec695SBarry Smith        MatRestoreColumnIJ_SeqAIJ,
1922a93ec695SBarry Smith        MatFDColoringCreate_SeqAIJ,
19230513a670SBarry Smith        MatColoringPatch_SeqAIJ,
19240513a670SBarry Smith        0,
1925cda55fadSBarry Smith        MatPermute_SeqAIJ,
1926cda55fadSBarry Smith        0,
1927cda55fadSBarry Smith        0,
1928cda55fadSBarry Smith        0,
1929cda55fadSBarry Smith        0,
1930cda55fadSBarry Smith        MatGetMaps_Petsc};
193117ab2063SBarry Smith 
193217ab2063SBarry Smith extern int MatUseSuperLU_SeqAIJ(Mat);
193317ab2063SBarry Smith extern int MatUseEssl_SeqAIJ(Mat);
193417ab2063SBarry Smith extern int MatUseDXML_SeqAIJ(Mat);
193517ab2063SBarry Smith 
1936fb2e594dSBarry Smith EXTERN_C_BEGIN
19375615d1e5SSatish Balay #undef __FUNC__
1938bef8e0ddSBarry Smith #define __FUNC__ "MatSeqAIJSetColumnIndices_SeqAIJ"
193915091d37SBarry Smith 
1940bef8e0ddSBarry Smith int MatSeqAIJSetColumnIndices_SeqAIJ(Mat mat,int *indices)
1941bef8e0ddSBarry Smith {
1942bef8e0ddSBarry Smith   Mat_SeqAIJ *aij = (Mat_SeqAIJ *)mat->data;
1943bef8e0ddSBarry Smith   int        i,nz,n;
1944bef8e0ddSBarry Smith 
1945bef8e0ddSBarry Smith   PetscFunctionBegin;
1946bef8e0ddSBarry Smith   if (aij->indexshift) SETERRQ(1,1,"No support with 1 based indexing");
1947bef8e0ddSBarry Smith 
1948bef8e0ddSBarry Smith   nz = aij->maxnz;
1949bef8e0ddSBarry Smith   n  = aij->n;
1950bef8e0ddSBarry Smith   for (i=0; i<nz; i++) {
1951bef8e0ddSBarry Smith     aij->j[i] = indices[i];
1952bef8e0ddSBarry Smith   }
1953bef8e0ddSBarry Smith   aij->nz = nz;
1954bef8e0ddSBarry Smith   for ( i=0; i<n; i++ ) {
1955bef8e0ddSBarry Smith     aij->ilen[i] = aij->imax[i];
1956bef8e0ddSBarry Smith   }
1957bef8e0ddSBarry Smith 
1958bef8e0ddSBarry Smith   PetscFunctionReturn(0);
1959bef8e0ddSBarry Smith }
1960fb2e594dSBarry Smith EXTERN_C_END
1961bef8e0ddSBarry Smith 
1962bef8e0ddSBarry Smith #undef __FUNC__
1963bef8e0ddSBarry Smith #define __FUNC__ "MatSeqAIJSetColumnIndices"
1964bef8e0ddSBarry Smith /*@
1965bef8e0ddSBarry Smith     MatSeqAIJSetColumnIndices - Set the column indices for all the rows
1966bef8e0ddSBarry Smith        in the matrix.
1967bef8e0ddSBarry Smith 
1968bef8e0ddSBarry Smith   Input Parameters:
1969bef8e0ddSBarry Smith +  mat - the SeqAIJ matrix
1970bef8e0ddSBarry Smith -  indices - the column indices
1971bef8e0ddSBarry Smith 
197215091d37SBarry Smith   Level: advanced
197315091d37SBarry Smith 
1974bef8e0ddSBarry Smith   Notes:
1975bef8e0ddSBarry Smith     This can be called if you have precomputed the nonzero structure of the
1976bef8e0ddSBarry Smith   matrix and want to provide it to the matrix object to improve the performance
1977bef8e0ddSBarry Smith   of the MatSetValues() operation.
1978bef8e0ddSBarry Smith 
1979bef8e0ddSBarry Smith     You MUST have set the correct numbers of nonzeros per row in the call to
1980bef8e0ddSBarry Smith   MatCreateSeqAIJ().
1981bef8e0ddSBarry Smith 
1982bef8e0ddSBarry Smith     MUST be called before any calls to MatSetValues();
1983bef8e0ddSBarry Smith 
1984bef8e0ddSBarry Smith @*/
1985bef8e0ddSBarry Smith int MatSeqAIJSetColumnIndices(Mat mat,int *indices)
1986bef8e0ddSBarry Smith {
1987bef8e0ddSBarry Smith   int ierr,(*f)(Mat,int *);
1988bef8e0ddSBarry Smith 
1989bef8e0ddSBarry Smith   PetscFunctionBegin;
1990bef8e0ddSBarry Smith   PetscValidHeaderSpecific(mat,MAT_COOKIE);
1991549d3d68SSatish Balay   ierr = PetscObjectQueryFunction((PetscObject)mat,"MatSeqAIJSetColumnIndices_C",(void **)&f);CHKERRQ(ierr);
1992bef8e0ddSBarry Smith   if (f) {
1993bef8e0ddSBarry Smith     ierr = (*f)(mat,indices);CHKERRQ(ierr);
1994bef8e0ddSBarry Smith   } else {
1995bef8e0ddSBarry Smith     SETERRQ(1,1,"Wrong type of matrix to set column indices");
1996bef8e0ddSBarry Smith   }
1997bef8e0ddSBarry Smith   PetscFunctionReturn(0);
1998bef8e0ddSBarry Smith }
1999bef8e0ddSBarry Smith 
2000be6bf707SBarry Smith /* ----------------------------------------------------------------------------------------*/
2001be6bf707SBarry Smith 
2002fb2e594dSBarry Smith EXTERN_C_BEGIN
2003be6bf707SBarry Smith #undef __FUNC__
2004be6bf707SBarry Smith #define __FUNC__ "MatStoreValues_SeqAIJ"
2005be6bf707SBarry Smith int MatStoreValues_SeqAIJ(Mat mat)
2006be6bf707SBarry Smith {
2007be6bf707SBarry Smith   Mat_SeqAIJ *aij = (Mat_SeqAIJ *)mat->data;
2008549d3d68SSatish Balay   int        nz = aij->i[aij->m]+aij->indexshift,ierr;
2009be6bf707SBarry Smith 
2010be6bf707SBarry Smith   PetscFunctionBegin;
2011be6bf707SBarry Smith   if (aij->nonew != 1) {
2012be6bf707SBarry Smith     SETERRQ(1,1,"Must call MatSetOption(A,MAT_NO_NEW_NONZERO_LOCATIONS);first");
2013be6bf707SBarry Smith   }
2014be6bf707SBarry Smith 
2015be6bf707SBarry Smith   /* allocate space for values if not already there */
2016be6bf707SBarry Smith   if (!aij->saved_values) {
2017be6bf707SBarry Smith     aij->saved_values = (Scalar *) PetscMalloc(nz*sizeof(Scalar));CHKPTRQ(aij->saved_values);
2018be6bf707SBarry Smith   }
2019be6bf707SBarry Smith 
2020be6bf707SBarry Smith   /* copy values over */
2021549d3d68SSatish Balay   ierr = PetscMemcpy(aij->saved_values,aij->a,nz*sizeof(Scalar));CHKERRQ(ierr);
2022be6bf707SBarry Smith   PetscFunctionReturn(0);
2023be6bf707SBarry Smith }
2024fb2e594dSBarry Smith EXTERN_C_END
2025be6bf707SBarry Smith 
2026be6bf707SBarry Smith #undef __FUNC__
2027be6bf707SBarry Smith #define __FUNC__ "MatStoreValues"
2028be6bf707SBarry Smith /*@
2029be6bf707SBarry Smith     MatStoreValues - Stashes a copy of the matrix values; this allows, for
2030be6bf707SBarry Smith        example, reuse of the linear part of a Jacobian, while recomputing the
2031be6bf707SBarry Smith        nonlinear portion.
2032be6bf707SBarry Smith 
2033be6bf707SBarry Smith    Collect on Mat
2034be6bf707SBarry Smith 
2035be6bf707SBarry Smith   Input Parameters:
2036be6bf707SBarry Smith .  mat - the matrix (currently on AIJ matrices support this option)
2037be6bf707SBarry Smith 
203815091d37SBarry Smith   Level: advanced
203915091d37SBarry Smith 
2040be6bf707SBarry Smith   Common Usage, with SNESSolve():
2041be6bf707SBarry Smith $    Create Jacobian matrix
2042be6bf707SBarry Smith $    Set linear terms into matrix
2043be6bf707SBarry Smith $    Apply boundary conditions to matrix, at this time matrix must have
2044be6bf707SBarry Smith $      final nonzero structure (i.e. setting the nonlinear terms and applying
2045be6bf707SBarry Smith $      boundary conditions again will not change the nonzero structure
2046be6bf707SBarry Smith $    ierr = MatSetOption(mat,MAT_NO_NEW_NONZERO_LOCATIONS);
2047be6bf707SBarry Smith $    ierr = MatStoreValues(mat);
2048be6bf707SBarry Smith $    Call SNESSetJacobian() with matrix
2049be6bf707SBarry Smith $    In your Jacobian routine
2050be6bf707SBarry Smith $      ierr = MatRetrieveValues(mat);
2051be6bf707SBarry Smith $      Set nonlinear terms in matrix
2052be6bf707SBarry Smith 
2053be6bf707SBarry Smith   Common Usage without SNESSolve(), i.e. when you handle nonlinear solve yourself:
2054be6bf707SBarry Smith $    // build linear portion of Jacobian
2055be6bf707SBarry Smith $    ierr = MatSetOption(mat,MAT_NO_NEW_NONZERO_LOCATIONS);
2056be6bf707SBarry Smith $    ierr = MatStoreValues(mat);
2057be6bf707SBarry Smith $    loop over nonlinear iterations
2058be6bf707SBarry Smith $       ierr = MatRetrieveValues(mat);
2059be6bf707SBarry Smith $       // call MatSetValues(mat,...) to set nonliner portion of Jacobian
2060be6bf707SBarry Smith $       // call MatAssemblyBegin/End() on matrix
2061be6bf707SBarry Smith $       Solve linear system with Jacobian
2062be6bf707SBarry Smith $    endloop
2063be6bf707SBarry Smith 
2064be6bf707SBarry Smith   Notes:
2065be6bf707SBarry Smith     Matrix must already be assemblied before calling this routine
2066be6bf707SBarry Smith     Must set the matrix option MatSetOption(mat,MAT_NO_NEW_NONZERO_LOCATIONS); before
2067be6bf707SBarry Smith     calling this routine.
2068be6bf707SBarry Smith 
2069be6bf707SBarry Smith .seealso: MatRetrieveValues()
2070be6bf707SBarry Smith 
2071be6bf707SBarry Smith @*/
2072be6bf707SBarry Smith int MatStoreValues(Mat mat)
2073be6bf707SBarry Smith {
2074be6bf707SBarry Smith   int ierr,(*f)(Mat);
2075be6bf707SBarry Smith 
2076be6bf707SBarry Smith   PetscFunctionBegin;
2077be6bf707SBarry Smith   PetscValidHeaderSpecific(mat,MAT_COOKIE);
2078be6bf707SBarry Smith   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,0,"Not for unassembled matrix");
2079be6bf707SBarry Smith   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,0,"Not for factored matrix");
2080be6bf707SBarry Smith 
2081c5d6004cSBarry Smith   ierr = PetscObjectQueryFunction((PetscObject)mat,"MatStoreValues_C",(void **)&f);CHKERRQ(ierr);
2082be6bf707SBarry Smith   if (f) {
2083be6bf707SBarry Smith     ierr = (*f)(mat);CHKERRQ(ierr);
2084be6bf707SBarry Smith   } else {
2085be6bf707SBarry Smith     SETERRQ(1,1,"Wrong type of matrix to store values");
2086be6bf707SBarry Smith   }
2087be6bf707SBarry Smith   PetscFunctionReturn(0);
2088be6bf707SBarry Smith }
2089be6bf707SBarry Smith 
2090fb2e594dSBarry Smith EXTERN_C_BEGIN
2091be6bf707SBarry Smith #undef __FUNC__
2092be6bf707SBarry Smith #define __FUNC__ "MatRetrieveValues_SeqAIJ"
2093be6bf707SBarry Smith int MatRetrieveValues_SeqAIJ(Mat mat)
2094be6bf707SBarry Smith {
2095be6bf707SBarry Smith   Mat_SeqAIJ *aij = (Mat_SeqAIJ *)mat->data;
2096549d3d68SSatish Balay   int        nz = aij->i[aij->m]+aij->indexshift,ierr;
2097be6bf707SBarry Smith 
2098be6bf707SBarry Smith   PetscFunctionBegin;
2099be6bf707SBarry Smith   if (aij->nonew != 1) {
2100be6bf707SBarry Smith     SETERRQ(1,1,"Must call MatSetOption(A,MAT_NO_NEW_NONZERO_LOCATIONS);first");
2101be6bf707SBarry Smith   }
2102be6bf707SBarry Smith   if (!aij->saved_values) {
2103be6bf707SBarry Smith     SETERRQ(1,1,"Must call MatStoreValues(A);first");
2104be6bf707SBarry Smith   }
2105be6bf707SBarry Smith 
2106be6bf707SBarry Smith   /* copy values over */
2107549d3d68SSatish Balay   ierr = PetscMemcpy(aij->a, aij->saved_values,nz*sizeof(Scalar));CHKERRQ(ierr);
2108be6bf707SBarry Smith   PetscFunctionReturn(0);
2109be6bf707SBarry Smith }
2110fb2e594dSBarry Smith EXTERN_C_END
2111be6bf707SBarry Smith 
2112be6bf707SBarry Smith #undef __FUNC__
2113be6bf707SBarry Smith #define __FUNC__ "MatRetrieveValues"
2114be6bf707SBarry Smith /*@
2115be6bf707SBarry Smith     MatRetrieveValues - Retrieves the copy of the matrix values; this allows, for
2116be6bf707SBarry Smith        example, reuse of the linear part of a Jacobian, while recomputing the
2117be6bf707SBarry Smith        nonlinear portion.
2118be6bf707SBarry Smith 
2119be6bf707SBarry Smith    Collect on Mat
2120be6bf707SBarry Smith 
2121be6bf707SBarry Smith   Input Parameters:
2122be6bf707SBarry Smith .  mat - the matrix (currently on AIJ matrices support this option)
2123be6bf707SBarry Smith 
212415091d37SBarry Smith   Level: advanced
212515091d37SBarry Smith 
2126be6bf707SBarry Smith .seealso: MatStoreValues()
2127be6bf707SBarry Smith 
2128be6bf707SBarry Smith @*/
2129be6bf707SBarry Smith int MatRetrieveValues(Mat mat)
2130be6bf707SBarry Smith {
2131be6bf707SBarry Smith   int ierr,(*f)(Mat);
2132be6bf707SBarry Smith 
2133be6bf707SBarry Smith   PetscFunctionBegin;
2134be6bf707SBarry Smith   PetscValidHeaderSpecific(mat,MAT_COOKIE);
2135be6bf707SBarry Smith   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,0,"Not for unassembled matrix");
2136be6bf707SBarry Smith   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,0,"Not for factored matrix");
2137be6bf707SBarry Smith 
2138c5d6004cSBarry Smith   ierr = PetscObjectQueryFunction((PetscObject)mat,"MatRetrieveValues_C",(void **)&f);CHKERRQ(ierr);
2139be6bf707SBarry Smith   if (f) {
2140be6bf707SBarry Smith     ierr = (*f)(mat);CHKERRQ(ierr);
2141be6bf707SBarry Smith   } else {
2142be6bf707SBarry Smith     SETERRQ(1,1,"Wrong type of matrix to retrieve values");
2143be6bf707SBarry Smith   }
2144be6bf707SBarry Smith   PetscFunctionReturn(0);
2145be6bf707SBarry Smith }
2146be6bf707SBarry Smith 
2147be6bf707SBarry Smith /* --------------------------------------------------------------------------------*/
2148cb5b572fSBarry Smith 
2149bef8e0ddSBarry Smith #undef __FUNC__
21505615d1e5SSatish Balay #define __FUNC__ "MatCreateSeqAIJ"
215117ab2063SBarry Smith /*@C
2152682d7d0cSBarry Smith    MatCreateSeqAIJ - Creates a sparse matrix in AIJ (compressed row) format
21530d15e28bSLois Curfman McInnes    (the default parallel PETSc format).  For good matrix assembly performance
21546e62573dSLois Curfman McInnes    the user should preallocate the matrix storage by setting the parameter nz
215551c19458SBarry Smith    (or the array nnz).  By setting these parameters accurately, performance
21562bd5e0b2SLois Curfman McInnes    during matrix assembly can be increased by more than a factor of 50.
215717ab2063SBarry Smith 
2158db81eaa0SLois Curfman McInnes    Collective on MPI_Comm
2159db81eaa0SLois Curfman McInnes 
216017ab2063SBarry Smith    Input Parameters:
2161db81eaa0SLois Curfman McInnes +  comm - MPI communicator, set to PETSC_COMM_SELF
216217ab2063SBarry Smith .  m - number of rows
216317ab2063SBarry Smith .  n - number of columns
216417ab2063SBarry Smith .  nz - number of nonzeros per row (same for all rows)
216551c19458SBarry Smith -  nnz - array containing the number of nonzeros in the various rows
21662bd5e0b2SLois Curfman McInnes          (possibly different for each row) or PETSC_NULL
216717ab2063SBarry Smith 
216817ab2063SBarry Smith    Output Parameter:
2169416022c9SBarry Smith .  A - the matrix
217017ab2063SBarry Smith 
2171b259b22eSLois Curfman McInnes    Notes:
217217ab2063SBarry Smith    The AIJ format (also called the Yale sparse matrix format or
217317ab2063SBarry Smith    compressed row storage), is fully compatible with standard Fortran 77
21740002213bSLois Curfman McInnes    storage.  That is, the stored row and column indices can begin at
217544cd7ae7SLois Curfman McInnes    either one (as in Fortran) or zero.  See the users' manual for details.
217617ab2063SBarry Smith 
217717ab2063SBarry Smith    Specify the preallocated storage with either nz or nnz (not both).
2178a40aa06bSLois Curfman McInnes    Set nz=PETSC_DEFAULT and nnz=PETSC_NULL for PETSc to control dynamic memory
21793d323bbdSBarry Smith    allocation.  For large problems you MUST preallocate memory or you
21806da5968aSLois Curfman McInnes    will get TERRIBLE performance, see the users' manual chapter on matrices.
218117ab2063SBarry Smith 
2182682d7d0cSBarry Smith    By default, this format uses inodes (identical nodes) when possible, to
21834fca80b9SLois Curfman McInnes    improve numerical efficiency of matrix-vector products and solves. We
2184682d7d0cSBarry Smith    search for consecutive rows with the same nonzero structure, thereby
21856c7ebb05SLois Curfman McInnes    reusing matrix information to achieve increased efficiency.
21866c7ebb05SLois Curfman McInnes 
21876c7ebb05SLois Curfman McInnes    Options Database Keys:
2188db81eaa0SLois Curfman McInnes +  -mat_aij_no_inode  - Do not use inodes
2189db81eaa0SLois Curfman McInnes .  -mat_aij_inode_limit <limit> - Sets inode limit (max limit=5)
2190db81eaa0SLois Curfman McInnes -  -mat_aij_oneindex - Internally use indexing starting at 1
2191db81eaa0SLois Curfman McInnes         rather than 0.  Note that when calling MatSetValues(),
2192db81eaa0SLois Curfman McInnes         the user still MUST index entries starting at 0!
219317ab2063SBarry Smith 
2194027ccd11SLois Curfman McInnes    Level: intermediate
2195027ccd11SLois Curfman McInnes 
2196bef8e0ddSBarry Smith .seealso: MatCreate(), MatCreateMPIAIJ(), MatSetValues(), MatSeqAIJSetColumnIndices()
219717ab2063SBarry Smith @*/
2198416022c9SBarry Smith int MatCreateSeqAIJ(MPI_Comm comm,int m,int n,int nz,int *nnz, Mat *A)
219917ab2063SBarry Smith {
2200416022c9SBarry Smith   Mat        B;
2201416022c9SBarry Smith   Mat_SeqAIJ *b;
2202f1af5d2fSBarry Smith   int        i, len, ierr, size;
2203f1af5d2fSBarry Smith   PetscTruth flg;
22046945ee14SBarry Smith 
22053a40ed3dSBarry Smith   PetscFunctionBegin;
2206d132466eSBarry Smith   ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr);
2207a8c6a408SBarry Smith   if (size > 1) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Comm must be of size 1");
2208d5d45c9bSBarry Smith 
2209b73539f3SBarry Smith   if (nz < -2) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,0,"nz cannot be less than -2: value %d",nz);
2210b73539f3SBarry Smith   if (nnz) {
2211b73539f3SBarry Smith     for (i=0; i<m; i++) {
2212b73539f3SBarry 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]);
2213b73539f3SBarry Smith     }
2214b73539f3SBarry Smith   }
2215b73539f3SBarry Smith 
2216416022c9SBarry Smith   *A                  = 0;
22173f1db9ecSBarry Smith   PetscHeaderCreate(B,_p_Mat,struct _MatOps,MAT_COOKIE,MATSEQAIJ,"Mat",comm,MatDestroy,MatView);
2218416022c9SBarry Smith   PLogObjectCreate(B);
22190452661fSBarry Smith   B->data             = (void *) (b = PetscNew(Mat_SeqAIJ));CHKPTRQ(b);
2220549d3d68SSatish Balay   ierr = PetscMemzero(b,sizeof(Mat_SeqAIJ));CHKERRQ(ierr);
2221549d3d68SSatish Balay   ierr = PetscMemcpy(B->ops,&MatOps_Values,sizeof(struct _MatOps));CHKERRQ(ierr);
2222e1311b90SBarry Smith   B->ops->destroy          = MatDestroy_SeqAIJ;
2223e1311b90SBarry Smith   B->ops->view             = MatView_SeqAIJ;
2224416022c9SBarry Smith   B->factor           = 0;
2225416022c9SBarry Smith   B->lupivotthreshold = 1.0;
222690f02eecSBarry Smith   B->mapping          = 0;
2227f1af5d2fSBarry Smith   ierr = OptionsGetDouble(PETSC_NULL,"-mat_lu_pivotthreshold",&B->lupivotthreshold,PETSC_NULL);CHKERRQ(ierr);
2228f1af5d2fSBarry Smith   ierr = OptionsHasName(PETSC_NULL,"-pc_ilu_preserve_row_sums",&b->ilu_preserve_row_sums);CHKERRQ(ierr);
2229416022c9SBarry Smith   b->row              = 0;
2230416022c9SBarry Smith   b->col              = 0;
223182bf6240SBarry Smith   b->icol             = 0;
2232416022c9SBarry Smith   b->indexshift       = 0;
2233b810aeb4SBarry Smith   b->reallocs         = 0;
223469957df2SSatish Balay   ierr = OptionsHasName(PETSC_NULL,"-mat_aij_oneindex", &flg);CHKERRQ(ierr);
223569957df2SSatish Balay   if (flg) b->indexshift = -1;
223617ab2063SBarry Smith 
223744cd7ae7SLois Curfman McInnes   b->m = m; B->m = m; B->M = m;
223844cd7ae7SLois Curfman McInnes   b->n = n; B->n = n; B->N = n;
2239a5ae1ecdSBarry Smith 
22404d197716SBarry Smith   ierr = MapCreateMPI(comm,m,m,&B->rmap);CHKERRQ(ierr);
22414d197716SBarry Smith   ierr = MapCreateMPI(comm,n,n,&B->cmap);CHKERRQ(ierr);
2242a5ae1ecdSBarry Smith 
22430452661fSBarry Smith   b->imax = (int *) PetscMalloc( (m+1)*sizeof(int) );CHKPTRQ(b->imax);
2244b4fd4287SBarry Smith   if (nnz == PETSC_NULL) {
22457b8455f0SLois Curfman McInnes     if (nz == PETSC_DEFAULT) nz = 10;
22467b8455f0SLois Curfman McInnes     else if (nz <= 0)        nz = 1;
2247416022c9SBarry Smith     for ( i=0; i<m; i++ ) b->imax[i] = nz;
224817ab2063SBarry Smith     nz = nz*m;
22493a40ed3dSBarry Smith   } else {
225017ab2063SBarry Smith     nz = 0;
2251416022c9SBarry Smith     for ( i=0; i<m; i++ ) {b->imax[i] = nnz[i]; nz += nnz[i];}
225217ab2063SBarry Smith   }
225317ab2063SBarry Smith 
225417ab2063SBarry Smith   /* allocate the matrix space */
2255416022c9SBarry Smith   len             = nz*(sizeof(int) + sizeof(Scalar)) + (b->m+1)*sizeof(int);
22560452661fSBarry Smith   b->a            = (Scalar *) PetscMalloc( len );CHKPTRQ(b->a);
2257416022c9SBarry Smith   b->j            = (int *) (b->a + nz);
2258549d3d68SSatish Balay   ierr            = PetscMemzero(b->j,nz*sizeof(int));CHKERRQ(ierr);
2259416022c9SBarry Smith   b->i            = b->j + nz;
2260416022c9SBarry Smith   b->singlemalloc = 1;
226117ab2063SBarry Smith 
2262416022c9SBarry Smith   b->i[0] = -b->indexshift;
226317ab2063SBarry Smith   for (i=1; i<m+1; i++) {
2264416022c9SBarry Smith     b->i[i] = b->i[i-1] + b->imax[i-1];
226517ab2063SBarry Smith   }
226617ab2063SBarry Smith 
2267416022c9SBarry Smith   /* b->ilen will count nonzeros in each row so far. */
22680452661fSBarry Smith   b->ilen = (int *) PetscMalloc((m+1)*sizeof(int));
2269f09e8eb9SSatish Balay   PLogObjectMemory(B,len+2*(m+1)*sizeof(int)+sizeof(struct _p_Mat)+sizeof(Mat_SeqAIJ));
2270416022c9SBarry Smith   for ( i=0; i<b->m; i++ ) { b->ilen[i] = 0;}
227117ab2063SBarry Smith 
2272416022c9SBarry Smith   b->nz               = 0;
2273416022c9SBarry Smith   b->maxnz            = nz;
2274416022c9SBarry Smith   b->sorted           = 0;
2275416022c9SBarry Smith   b->roworiented      = 1;
2276416022c9SBarry Smith   b->nonew            = 0;
2277416022c9SBarry Smith   b->diag             = 0;
2278416022c9SBarry Smith   b->solve_work       = 0;
227971bd300dSLois Curfman McInnes   b->spptr            = 0;
2280754ec7b1SSatish Balay   b->inode.node_count = 0;
2281754ec7b1SSatish Balay   b->inode.size       = 0;
22826c7ebb05SLois Curfman McInnes   b->inode.limit      = 5;
22836c7ebb05SLois Curfman McInnes   b->inode.max_limit  = 5;
2284be6bf707SBarry Smith   b->saved_values     = 0;
22854e220ebcSLois Curfman McInnes   B->info.nz_unneeded = (double)b->maxnz;
2286d7f994e1SBarry Smith   b->idiag            = 0;
2287d7f994e1SBarry Smith   b->ssor             = 0;
228817ab2063SBarry Smith 
2289416022c9SBarry Smith   *A = B;
22904e220ebcSLois Curfman McInnes 
22914b14c69eSBarry Smith   /*  SuperLU is not currently supported through PETSc */
2292aa482453SBarry Smith #if defined(PETSC_HAVE_SUPERLU)
229369957df2SSatish Balay   ierr = OptionsHasName(PETSC_NULL,"-mat_aij_superlu", &flg);CHKERRQ(ierr);
229469957df2SSatish Balay   if (flg) { ierr = MatUseSuperLU_SeqAIJ(B);CHKERRQ(ierr); }
22954b14c69eSBarry Smith #endif
229669957df2SSatish Balay   ierr = OptionsHasName(PETSC_NULL,"-mat_aij_essl", &flg);CHKERRQ(ierr);
229769957df2SSatish Balay   if (flg) { ierr = MatUseEssl_SeqAIJ(B);CHKERRQ(ierr); }
229869957df2SSatish Balay   ierr = OptionsHasName(PETSC_NULL,"-mat_aij_dxml", &flg);CHKERRQ(ierr);
229969957df2SSatish Balay   if (flg) {
2300a8c6a408SBarry Smith     if (!b->indexshift) SETERRQ( PETSC_ERR_LIB,0,"need -mat_aij_oneindex with -mat_aij_dxml");
2301416022c9SBarry Smith     ierr = MatUseDXML_SeqAIJ(B);CHKERRQ(ierr);
230217ab2063SBarry Smith   }
230369957df2SSatish Balay   ierr = OptionsHasName(PETSC_NULL,"-help", &flg);CHKERRQ(ierr);
230469957df2SSatish Balay   if (flg) {ierr = MatPrintHelp(B);CHKERRQ(ierr); }
2305bef8e0ddSBarry Smith 
2306f1af5d2fSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatSeqAIJSetColumnIndices_C",
2307bef8e0ddSBarry Smith                                      "MatSeqAIJSetColumnIndices_SeqAIJ",
2308bef8e0ddSBarry Smith                                      (void*)MatSeqAIJSetColumnIndices_SeqAIJ);CHKERRQ(ierr);
2309f1af5d2fSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatStoreValues_C",
2310be6bf707SBarry Smith                                      "MatStoreValues_SeqAIJ",
2311be6bf707SBarry Smith                                      (void*)MatStoreValues_SeqAIJ);CHKERRQ(ierr);
2312f1af5d2fSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatRetrieveValues_C",
2313be6bf707SBarry Smith                                      "MatRetrieveValues_SeqAIJ",
2314be6bf707SBarry Smith                                      (void*)MatRetrieveValues_SeqAIJ);CHKERRQ(ierr);
23153a40ed3dSBarry Smith   PetscFunctionReturn(0);
231617ab2063SBarry Smith }
231717ab2063SBarry Smith 
23185615d1e5SSatish Balay #undef __FUNC__
2319be6bf707SBarry Smith #define __FUNC__ "MatDuplicate_SeqAIJ"
2320be6bf707SBarry Smith int MatDuplicate_SeqAIJ(Mat A,MatDuplicateOption cpvalues,Mat *B)
232117ab2063SBarry Smith {
2322416022c9SBarry Smith   Mat        C;
2323416022c9SBarry Smith   Mat_SeqAIJ *c,*a = (Mat_SeqAIJ *) A->data;
2324bef8e0ddSBarry Smith   int        i,len, m = a->m,shift = a->indexshift,ierr;
232517ab2063SBarry Smith 
23263a40ed3dSBarry Smith   PetscFunctionBegin;
23274043dd9cSLois Curfman McInnes   *B = 0;
23283f1db9ecSBarry Smith   PetscHeaderCreate(C,_p_Mat,struct _MatOps,MAT_COOKIE,MATSEQAIJ,"Mat",A->comm,MatDestroy,MatView);
2329416022c9SBarry Smith   PLogObjectCreate(C);
23300452661fSBarry Smith   C->data         = (void *) (c = PetscNew(Mat_SeqAIJ));CHKPTRQ(c);
2331549d3d68SSatish Balay   ierr            = PetscMemcpy(C->ops,A->ops,sizeof(struct _MatOps));CHKERRQ(ierr);
2332e1311b90SBarry Smith   C->ops->destroy = MatDestroy_SeqAIJ;
2333e1311b90SBarry Smith   C->ops->view    = MatView_SeqAIJ;
2334416022c9SBarry Smith   C->factor       = A->factor;
2335416022c9SBarry Smith   c->row          = 0;
2336416022c9SBarry Smith   c->col          = 0;
233782bf6240SBarry Smith   c->icol         = 0;
2338416022c9SBarry Smith   c->indexshift   = shift;
2339c456f294SBarry Smith   C->assembled    = PETSC_TRUE;
234017ab2063SBarry Smith 
234144cd7ae7SLois Curfman McInnes   c->m = C->m   = a->m;
234244cd7ae7SLois Curfman McInnes   c->n = C->n   = a->n;
234344cd7ae7SLois Curfman McInnes   C->M          = a->m;
234444cd7ae7SLois Curfman McInnes   C->N          = a->n;
234517ab2063SBarry Smith 
23460452661fSBarry Smith   c->imax       = (int *) PetscMalloc((m+1)*sizeof(int));CHKPTRQ(c->imax);
23470452661fSBarry Smith   c->ilen       = (int *) PetscMalloc((m+1)*sizeof(int));CHKPTRQ(c->ilen);
234817ab2063SBarry Smith   for ( i=0; i<m; i++ ) {
2349416022c9SBarry Smith     c->imax[i] = a->imax[i];
2350416022c9SBarry Smith     c->ilen[i] = a->ilen[i];
235117ab2063SBarry Smith   }
235217ab2063SBarry Smith 
235317ab2063SBarry Smith   /* allocate the matrix space */
2354416022c9SBarry Smith   c->singlemalloc = 1;
2355416022c9SBarry Smith   len     = (m+1)*sizeof(int)+(a->i[m])*(sizeof(Scalar)+sizeof(int));
23560452661fSBarry Smith   c->a  = (Scalar *) PetscMalloc( len );CHKPTRQ(c->a);
2357416022c9SBarry Smith   c->j  = (int *) (c->a + a->i[m] + shift);
2358416022c9SBarry Smith   c->i  = c->j + a->i[m] + shift;
2359549d3d68SSatish Balay   ierr = PetscMemcpy(c->i,a->i,(m+1)*sizeof(int));CHKERRQ(ierr);
236017ab2063SBarry Smith   if (m > 0) {
2361549d3d68SSatish Balay     ierr = PetscMemcpy(c->j,a->j,(a->i[m]+shift)*sizeof(int));CHKERRQ(ierr);
2362be6bf707SBarry Smith     if (cpvalues == MAT_COPY_VALUES) {
2363549d3d68SSatish Balay       ierr = PetscMemcpy(c->a,a->a,(a->i[m]+shift)*sizeof(Scalar));CHKERRQ(ierr);
2364be6bf707SBarry Smith     } else {
2365549d3d68SSatish Balay       ierr = PetscMemzero(c->a,(a->i[m]+shift)*sizeof(Scalar));CHKERRQ(ierr);
236617ab2063SBarry Smith     }
236708480c60SBarry Smith   }
236817ab2063SBarry Smith 
2369f09e8eb9SSatish Balay   PLogObjectMemory(C,len+2*(m+1)*sizeof(int)+sizeof(struct _p_Mat)+sizeof(Mat_SeqAIJ));
2370416022c9SBarry Smith   c->sorted      = a->sorted;
2371416022c9SBarry Smith   c->roworiented = a->roworiented;
2372416022c9SBarry Smith   c->nonew       = a->nonew;
23737a743949SBarry Smith   c->ilu_preserve_row_sums = a->ilu_preserve_row_sums;
2374be6bf707SBarry Smith   c->saved_values = 0;
2375d7f994e1SBarry Smith   c->idiag        = 0;
2376d7f994e1SBarry Smith   c->ssor         = 0;
237717ab2063SBarry Smith 
2378416022c9SBarry Smith   if (a->diag) {
23790452661fSBarry Smith     c->diag = (int *) PetscMalloc( (m+1)*sizeof(int) );CHKPTRQ(c->diag);
2380416022c9SBarry Smith     PLogObjectMemory(C,(m+1)*sizeof(int));
238117ab2063SBarry Smith     for ( i=0; i<m; i++ ) {
2382416022c9SBarry Smith       c->diag[i] = a->diag[i];
238317ab2063SBarry Smith     }
23843a40ed3dSBarry Smith   } else c->diag          = 0;
23856c7ebb05SLois Curfman McInnes   c->inode.limit        = a->inode.limit;
23866c7ebb05SLois Curfman McInnes   c->inode.max_limit    = a->inode.max_limit;
2387754ec7b1SSatish Balay   if (a->inode.size){
2388daed632aSSatish Balay     c->inode.size       = (int *) PetscMalloc( (m+1)*sizeof(int) );CHKPTRQ(c->inode.size);
2389754ec7b1SSatish Balay     c->inode.node_count = a->inode.node_count;
2390549d3d68SSatish Balay     ierr = PetscMemcpy( c->inode.size, a->inode.size, (m+1)*sizeof(int));CHKERRQ(ierr);
2391754ec7b1SSatish Balay   } else {
2392754ec7b1SSatish Balay     c->inode.size       = 0;
2393754ec7b1SSatish Balay     c->inode.node_count = 0;
2394754ec7b1SSatish Balay   }
2395416022c9SBarry Smith   c->nz                 = a->nz;
2396416022c9SBarry Smith   c->maxnz              = a->maxnz;
2397416022c9SBarry Smith   c->solve_work         = 0;
239876dd722bSSatish Balay   c->spptr              = 0;      /* Dangerous -I'm throwing away a->spptr */
2399754ec7b1SSatish Balay 
2400416022c9SBarry Smith   *B = C;
24017b2a1423SBarry Smith   ierr = FListDuplicate(A->qlist,&C->qlist);CHKERRQ(ierr);
24023a40ed3dSBarry Smith   PetscFunctionReturn(0);
240317ab2063SBarry Smith }
240417ab2063SBarry Smith 
24055615d1e5SSatish Balay #undef __FUNC__
24065615d1e5SSatish Balay #define __FUNC__ "MatLoad_SeqAIJ"
240719bcc07fSBarry Smith int MatLoad_SeqAIJ(Viewer viewer,MatType type,Mat *A)
240817ab2063SBarry Smith {
2409416022c9SBarry Smith   Mat_SeqAIJ   *a;
2410416022c9SBarry Smith   Mat          B;
241117699dbbSLois Curfman McInnes   int          i, nz, ierr, fd, header[4],size,*rowlengths = 0,M,N,shift;
2412bcd2baecSBarry Smith   MPI_Comm     comm;
241317ab2063SBarry Smith 
24143a40ed3dSBarry Smith   PetscFunctionBegin;
2415e864ced6SBarry Smith   ierr = PetscObjectGetComm((PetscObject) viewer,&comm);CHKERRQ(ierr);
2416d132466eSBarry Smith   ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr);
2417a8c6a408SBarry Smith   if (size > 1) SETERRQ(PETSC_ERR_ARG_SIZ,0,"view must have one processor");
241890ace30eSBarry Smith   ierr = ViewerBinaryGetDescriptor(viewer,&fd);CHKERRQ(ierr);
24190752156aSBarry Smith   ierr = PetscBinaryRead(fd,header,4,PETSC_INT);CHKERRQ(ierr);
2420a8c6a408SBarry Smith   if (header[0] != MAT_COOKIE) SETERRQ(PETSC_ERR_FILE_UNEXPECTED,0,"not matrix object in file");
242117ab2063SBarry Smith   M = header[1]; N = header[2]; nz = header[3];
242217ab2063SBarry Smith 
2423d64ed03dSBarry Smith   if (nz < 0) {
2424a8c6a408SBarry Smith     SETERRQ(PETSC_ERR_FILE_UNEXPECTED,1,"Matrix stored in special format on disk, cannot load as SeqAIJ");
2425d64ed03dSBarry Smith   }
2426d64ed03dSBarry Smith 
242717ab2063SBarry Smith   /* read in row lengths */
24280452661fSBarry Smith   rowlengths = (int*) PetscMalloc( M*sizeof(int) );CHKPTRQ(rowlengths);
24290752156aSBarry Smith   ierr = PetscBinaryRead(fd,rowlengths,M,PETSC_INT);CHKERRQ(ierr);
243017ab2063SBarry Smith 
243117ab2063SBarry Smith   /* create our matrix */
2432416022c9SBarry Smith   ierr = MatCreateSeqAIJ(comm,M,N,0,rowlengths,A);CHKERRQ(ierr);
2433416022c9SBarry Smith   B = *A;
2434416022c9SBarry Smith   a = (Mat_SeqAIJ *) B->data;
2435416022c9SBarry Smith   shift = a->indexshift;
243617ab2063SBarry Smith 
243717ab2063SBarry Smith   /* read in column indices and adjust for Fortran indexing*/
24380752156aSBarry Smith   ierr = PetscBinaryRead(fd,a->j,nz,PETSC_INT);CHKERRQ(ierr);
243917ab2063SBarry Smith   if (shift) {
244017ab2063SBarry Smith     for ( i=0; i<nz; i++ ) {
2441416022c9SBarry Smith       a->j[i] += 1;
244217ab2063SBarry Smith     }
244317ab2063SBarry Smith   }
244417ab2063SBarry Smith 
244517ab2063SBarry Smith   /* read in nonzero values */
24460752156aSBarry Smith   ierr = PetscBinaryRead(fd,a->a,nz,PETSC_SCALAR);CHKERRQ(ierr);
244717ab2063SBarry Smith 
244817ab2063SBarry Smith   /* set matrix "i" values */
2449416022c9SBarry Smith   a->i[0] = -shift;
245017ab2063SBarry Smith   for ( i=1; i<= M; i++ ) {
2451416022c9SBarry Smith     a->i[i]      = a->i[i-1] + rowlengths[i-1];
2452416022c9SBarry Smith     a->ilen[i-1] = rowlengths[i-1];
245317ab2063SBarry Smith   }
2454606d414cSSatish Balay   ierr = PetscFree(rowlengths);CHKERRQ(ierr);
245517ab2063SBarry Smith 
24566d4a8577SBarry Smith   ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
24576d4a8577SBarry Smith   ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
24583a40ed3dSBarry Smith   PetscFunctionReturn(0);
245917ab2063SBarry Smith }
246017ab2063SBarry Smith 
24615615d1e5SSatish Balay #undef __FUNC__
24625615d1e5SSatish Balay #define __FUNC__ "MatEqual_SeqAIJ"
24638f6be9afSLois Curfman McInnes int MatEqual_SeqAIJ(Mat A,Mat B, PetscTruth* flg)
24647264ac53SSatish Balay {
24657264ac53SSatish Balay   Mat_SeqAIJ *a = (Mat_SeqAIJ *)A->data, *b = (Mat_SeqAIJ *)B->data;
24660f5bd95cSBarry Smith   int        ierr;
24677264ac53SSatish Balay 
24683a40ed3dSBarry Smith   PetscFunctionBegin;
2469a8c6a408SBarry Smith   if (B->type !=MATSEQAIJ)SETERRQ(PETSC_ERR_ARG_INCOMP,0,"Matrices must be same type");
24707264ac53SSatish Balay 
24717264ac53SSatish Balay   /* If the  matrix dimensions are not equal, or no of nonzeros or shift */
24727264ac53SSatish Balay   if ((a->m != b->m ) || (a->n !=b->n) ||( a->nz != b->nz)||
2473bcd2baecSBarry Smith       (a->indexshift != b->indexshift)) {
24743a40ed3dSBarry Smith     *flg = PETSC_FALSE; PetscFunctionReturn(0);
2475bcd2baecSBarry Smith   }
24767264ac53SSatish Balay 
24777264ac53SSatish Balay   /* if the a->i are the same */
24780f5bd95cSBarry Smith   ierr = PetscMemcmp(a->i,b->i,(a->m+1)*sizeof(int),flg);CHKERRQ(ierr);
24790f5bd95cSBarry Smith   if (*flg == PETSC_FALSE) PetscFunctionReturn(0);
24807264ac53SSatish Balay 
24817264ac53SSatish Balay   /* if a->j are the same */
24820f5bd95cSBarry Smith   ierr = PetscMemcmp(a->j, b->j, (a->nz)*sizeof(int),flg);CHKERRQ(ierr);
24830f5bd95cSBarry Smith   if (*flg == PETSC_FALSE) PetscFunctionReturn(0);
2484bcd2baecSBarry Smith 
2485bcd2baecSBarry Smith   /* if a->a are the same */
24860f5bd95cSBarry Smith   ierr = PetscMemcmp(a->a, b->a, (a->nz)*sizeof(Scalar),flg);CHKERRQ(ierr);
24870f5bd95cSBarry Smith 
24883a40ed3dSBarry Smith   PetscFunctionReturn(0);
24897264ac53SSatish Balay 
24907264ac53SSatish Balay }
2491