xref: /petsc/src/mat/impls/aij/seq/aij.c (revision 77ed534321f0a860738694ee6d0aa216f0623125)
1a5eb4965SSatish Balay #ifdef PETSC_RCS_HEADER
2*77ed5343SBarry Smith static char vcid[] = "$Id: aij.c,v 1.288 1998/11/30 23:23:27 bsmith Exp bsmith $";
317ab2063SBarry Smith #endif
417ab2063SBarry Smith 
5d5d45c9bSBarry Smith /*
63369ce9aSBarry Smith     Defines the basic matrix operations for the AIJ (compressed row)
7d5d45c9bSBarry Smith   matrix storage format.
8d5d45c9bSBarry Smith */
93369ce9aSBarry Smith 
103369ce9aSBarry Smith #include "sys.h"
1170f55243SBarry Smith #include "src/mat/impls/aij/seq/aij.h"
12f5eb4b81SSatish Balay #include "src/vec/vecimpl.h"
13f5eb4b81SSatish Balay #include "src/inline/spops.h"
148d195f9aSBarry Smith #include "src/inline/dot.h"
15eeb667a2SSatish Balay #include "bitarray.h"
1617ab2063SBarry Smith 
17a2ce50c7SBarry Smith /*
18a2ce50c7SBarry Smith     Basic AIJ format ILU based on drop tolerance
19a2ce50c7SBarry Smith */
205615d1e5SSatish Balay #undef __FUNC__
215615d1e5SSatish Balay #define __FUNC__ "MatILUDTFactor_SeqAIJ"
22a2ce50c7SBarry Smith int MatILUDTFactor_SeqAIJ(Mat A,double dt,int maxnz,IS row,IS col,Mat *fact)
23a2ce50c7SBarry Smith {
24a2ce50c7SBarry Smith   /* Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data; */
25a2ce50c7SBarry Smith   int        ierr = 1;
26a2ce50c7SBarry Smith 
273a40ed3dSBarry Smith   PetscFunctionBegin;
28e3372554SBarry Smith   SETERRQ(ierr,0,"Not implemented");
29d64ed03dSBarry Smith #if !defined(USE_PETSC_DEBUG)
30d64ed03dSBarry Smith   PetscFunctionReturn(0);
31d64ed03dSBarry Smith #endif
32a2ce50c7SBarry Smith }
33a2ce50c7SBarry Smith 
34bcd2baecSBarry Smith extern int MatToSymmetricIJ_SeqAIJ(int,int*,int*,int,int,int**,int**);
3517ab2063SBarry Smith 
365615d1e5SSatish Balay #undef __FUNC__
375615d1e5SSatish Balay #define __FUNC__ "MatGetRowIJ_SeqAIJ"
388f6be9afSLois Curfman McInnes int MatGetRowIJ_SeqAIJ(Mat A,int oshift,PetscTruth symmetric,int *m,int **ia,int **ja,
396945ee14SBarry Smith                            PetscTruth *done)
4017ab2063SBarry Smith {
41416022c9SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data;
426945ee14SBarry Smith   int        ierr,i,ishift;
4317ab2063SBarry Smith 
443a40ed3dSBarry Smith   PetscFunctionBegin;
4531625ec5SSatish Balay   *m     = A->m;
463a40ed3dSBarry Smith   if (!ia) PetscFunctionReturn(0);
476945ee14SBarry Smith   ishift = a->indexshift;
486945ee14SBarry Smith   if (symmetric) {
4931625ec5SSatish Balay     ierr = MatToSymmetricIJ_SeqAIJ(a->m,a->i,a->j,ishift,oshift,ia,ja); CHKERRQ(ierr);
506945ee14SBarry Smith   } else if (oshift == 0 && ishift == -1) {
5131625ec5SSatish Balay     int nz = a->i[a->m];
523b2fbd54SBarry Smith     /* malloc space and  subtract 1 from i and j indices */
5331625ec5SSatish Balay     *ia = (int *) PetscMalloc( (a->m+1)*sizeof(int) ); CHKPTRQ(*ia);
543b2fbd54SBarry Smith     *ja = (int *) PetscMalloc( (nz+1)*sizeof(int) ); CHKPTRQ(*ja);
553b2fbd54SBarry Smith     for ( i=0; i<nz; i++ ) (*ja)[i] = a->j[i] - 1;
5631625ec5SSatish Balay     for ( i=0; i<a->m+1; i++ ) (*ia)[i] = a->i[i] - 1;
576945ee14SBarry Smith   } else if (oshift == 1 && ishift == 0) {
5831625ec5SSatish Balay     int nz = a->i[a->m] + 1;
593b2fbd54SBarry Smith     /* malloc space and  add 1 to i and j indices */
6031625ec5SSatish Balay     *ia = (int *) PetscMalloc( (a->m+1)*sizeof(int) ); CHKPTRQ(*ia);
613b2fbd54SBarry Smith     *ja = (int *) PetscMalloc( (nz+1)*sizeof(int) ); CHKPTRQ(*ja);
623b2fbd54SBarry Smith     for ( i=0; i<nz; i++ ) (*ja)[i] = a->j[i] + 1;
6331625ec5SSatish Balay     for ( i=0; i<a->m+1; i++ ) (*ia)[i] = a->i[i] + 1;
646945ee14SBarry Smith   } else {
656945ee14SBarry Smith     *ia = a->i; *ja = a->j;
66a2ce50c7SBarry Smith   }
67a2ce50c7SBarry Smith 
683a40ed3dSBarry Smith   PetscFunctionReturn(0);
69a2744918SBarry Smith }
70a2744918SBarry Smith 
715615d1e5SSatish Balay #undef __FUNC__
725615d1e5SSatish Balay #define __FUNC__ "MatRestoreRowIJ_SeqAIJ"
738f6be9afSLois Curfman McInnes int MatRestoreRowIJ_SeqAIJ(Mat A,int oshift,PetscTruth symmetric,int *n,int **ia,int **ja,
746945ee14SBarry Smith                                PetscTruth *done)
756945ee14SBarry Smith {
766945ee14SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data;
773b2fbd54SBarry Smith   int        ishift = a->indexshift;
786945ee14SBarry Smith 
793a40ed3dSBarry Smith   PetscFunctionBegin;
803a40ed3dSBarry Smith   if (!ia) PetscFunctionReturn(0);
813b2fbd54SBarry Smith   if (symmetric || (oshift == 0 && ishift == -1) || (oshift == 1 && ishift == 0)) {
826945ee14SBarry Smith     PetscFree(*ia);
836945ee14SBarry Smith     PetscFree(*ja);
84bcd2baecSBarry Smith   }
853a40ed3dSBarry Smith   PetscFunctionReturn(0);
8617ab2063SBarry Smith }
8717ab2063SBarry Smith 
885615d1e5SSatish Balay #undef __FUNC__
895615d1e5SSatish Balay #define __FUNC__ "MatGetColumnIJ_SeqAIJ"
9043a90d84SBarry Smith int MatGetColumnIJ_SeqAIJ(Mat A,int oshift,PetscTruth symmetric,int *nn,int **ia,int **ja,
913b2fbd54SBarry Smith                            PetscTruth *done)
923b2fbd54SBarry Smith {
933b2fbd54SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data;
94a93ec695SBarry Smith   int        ierr,i,ishift = a->indexshift,*collengths,*cia,*cja,n = A->n,m = A->m;
95a93ec695SBarry Smith   int        nz = a->i[m]+ishift,row,*jj,mr,col;
963b2fbd54SBarry Smith 
973a40ed3dSBarry Smith   PetscFunctionBegin;
983b2fbd54SBarry Smith   *nn     = A->n;
993a40ed3dSBarry Smith   if (!ia) PetscFunctionReturn(0);
1003b2fbd54SBarry Smith   if (symmetric) {
101179192dfSSatish Balay     ierr = MatToSymmetricIJ_SeqAIJ(a->m,a->i,a->j,ishift,oshift,ia,ja); CHKERRQ(ierr);
1023b2fbd54SBarry Smith   } else {
10361d2ded1SBarry Smith     collengths = (int *) PetscMalloc( (n+1)*sizeof(int) ); CHKPTRQ(collengths);
1043b2fbd54SBarry Smith     PetscMemzero(collengths,n*sizeof(int));
1053b2fbd54SBarry Smith     cia        = (int *) PetscMalloc( (n+1)*sizeof(int) ); CHKPTRQ(cia);
106a93ec695SBarry Smith     cja        = (int *) PetscMalloc( (nz+1)*sizeof(int) ); CHKPTRQ(cja);
1073b2fbd54SBarry Smith     jj = a->j;
1083b2fbd54SBarry Smith     for ( i=0; i<nz; i++ ) {
1093b2fbd54SBarry Smith       collengths[jj[i] + ishift]++;
1103b2fbd54SBarry Smith     }
1113b2fbd54SBarry Smith     cia[0] = oshift;
1123b2fbd54SBarry Smith     for ( i=0; i<n; i++) {
1133b2fbd54SBarry Smith       cia[i+1] = cia[i] + collengths[i];
1143b2fbd54SBarry Smith     }
1153b2fbd54SBarry Smith     PetscMemzero(collengths,n*sizeof(int));
1163b2fbd54SBarry Smith     jj = a->j;
117a93ec695SBarry Smith     for ( row=0; row<m; row++ ) {
118a93ec695SBarry Smith       mr = a->i[row+1] - a->i[row];
119a93ec695SBarry Smith       for ( i=0; i<mr; i++ ) {
1203b2fbd54SBarry Smith         col = *jj++ + ishift;
1213b2fbd54SBarry Smith         cja[cia[col] + collengths[col]++ - oshift] = row + oshift;
1223b2fbd54SBarry Smith       }
1233b2fbd54SBarry Smith     }
1243b2fbd54SBarry Smith     PetscFree(collengths);
1253b2fbd54SBarry Smith     *ia = cia; *ja = cja;
1263b2fbd54SBarry Smith   }
1273b2fbd54SBarry Smith 
1283a40ed3dSBarry Smith   PetscFunctionReturn(0);
1293b2fbd54SBarry Smith }
1303b2fbd54SBarry Smith 
1315615d1e5SSatish Balay #undef __FUNC__
1325615d1e5SSatish Balay #define __FUNC__ "MatRestoreColumnIJ_SeqAIJ"
13343a90d84SBarry Smith int MatRestoreColumnIJ_SeqAIJ(Mat A,int oshift,PetscTruth symmetric,int *n,int **ia,
1343b2fbd54SBarry Smith                                      int **ja,PetscTruth *done)
1353b2fbd54SBarry Smith {
1363a40ed3dSBarry Smith   PetscFunctionBegin;
1373a40ed3dSBarry Smith   if (!ia) PetscFunctionReturn(0);
1383b2fbd54SBarry Smith 
1393b2fbd54SBarry Smith   PetscFree(*ia);
1403b2fbd54SBarry Smith   PetscFree(*ja);
1413b2fbd54SBarry Smith 
1423a40ed3dSBarry Smith   PetscFunctionReturn(0);
1433b2fbd54SBarry Smith }
1443b2fbd54SBarry Smith 
145227d817aSBarry Smith #define CHUNKSIZE   15
14617ab2063SBarry Smith 
1475615d1e5SSatish Balay #undef __FUNC__
1485615d1e5SSatish Balay #define __FUNC__ "MatSetValues_SeqAIJ"
14961d2ded1SBarry Smith int MatSetValues_SeqAIJ(Mat A,int m,int *im,int n,int *in,Scalar *v,InsertMode is)
15017ab2063SBarry Smith {
151416022c9SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data;
152416022c9SBarry Smith   int        *rp,k,low,high,t,ii,row,nrow,i,col,l,rmax, N, sorted = a->sorted;
1534b0e389bSBarry Smith   int        *imax = a->imax, *ai = a->i, *ailen = a->ilen,roworiented = a->roworiented;
154d5d45c9bSBarry Smith   int        *aj = a->j, nonew = a->nonew,shift = a->indexshift;
155416022c9SBarry Smith   Scalar     *ap,value, *aa = a->a;
15617ab2063SBarry Smith 
1573a40ed3dSBarry Smith   PetscFunctionBegin;
15817ab2063SBarry Smith   for ( k=0; k<m; k++ ) { /* loop over added rows */
159416022c9SBarry Smith     row  = im[k];
1603a40ed3dSBarry Smith #if defined(USE_PETSC_BOPT_g)
161a8c6a408SBarry Smith     if (row < 0) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Negative row");
162a8c6a408SBarry Smith     if (row >= a->m) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Row too large");
1633b2fbd54SBarry Smith #endif
16417ab2063SBarry Smith     rp   = aj + ai[row] + shift; ap = aa + ai[row] + shift;
16517ab2063SBarry Smith     rmax = imax[row]; nrow = ailen[row];
166416022c9SBarry Smith     low = 0;
16717ab2063SBarry Smith     for ( l=0; l<n; l++ ) { /* loop over added columns */
1683a40ed3dSBarry Smith #if defined(USE_PETSC_BOPT_g)
169a8c6a408SBarry Smith       if (in[l] < 0) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Negative column");
170a8c6a408SBarry Smith       if (in[l] >= a->n) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Column too large");
1713b2fbd54SBarry Smith #endif
1724b0e389bSBarry Smith       col = in[l] - shift;
1734b0e389bSBarry Smith       if (roworiented) {
1744b0e389bSBarry Smith         value = *v++;
175bef8e0ddSBarry Smith       } else {
1764b0e389bSBarry Smith         value = v[k + l*m];
1774b0e389bSBarry Smith       }
178416022c9SBarry Smith       if (!sorted) low = 0; high = nrow;
179416022c9SBarry Smith       while (high-low > 5) {
180416022c9SBarry Smith         t = (low+high)/2;
181416022c9SBarry Smith         if (rp[t] > col) high = t;
182416022c9SBarry Smith         else             low  = t;
18317ab2063SBarry Smith       }
184416022c9SBarry Smith       for ( i=low; i<high; i++ ) {
18517ab2063SBarry Smith         if (rp[i] > col) break;
18617ab2063SBarry Smith         if (rp[i] == col) {
187416022c9SBarry Smith           if (is == ADD_VALUES) ap[i] += value;
18817ab2063SBarry Smith           else                  ap[i] = value;
18917ab2063SBarry Smith           goto noinsert;
19017ab2063SBarry Smith         }
19117ab2063SBarry Smith       }
192c2653b3dSLois Curfman McInnes       if (nonew == 1) goto noinsert;
193a8c6a408SBarry Smith       else if (nonew == -1) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Inserting a new nonzero in the matrix");
19417ab2063SBarry Smith       if (nrow >= rmax) {
19517ab2063SBarry Smith         /* there is no extra room in row, therefore enlarge */
196416022c9SBarry Smith         int    new_nz = ai[a->m] + CHUNKSIZE,len,*new_i,*new_j;
19717ab2063SBarry Smith         Scalar *new_a;
19817ab2063SBarry Smith 
199a8c6a408SBarry Smith         if (nonew == -2) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Inserting a new nonzero in the matrix");
20096854ed6SLois Curfman McInnes 
20117ab2063SBarry Smith         /* malloc new storage space */
202416022c9SBarry Smith         len     = new_nz*(sizeof(int)+sizeof(Scalar))+(a->m+1)*sizeof(int);
2030452661fSBarry Smith         new_a   = (Scalar *) PetscMalloc( len ); CHKPTRQ(new_a);
20417ab2063SBarry Smith         new_j   = (int *) (new_a + new_nz);
20517ab2063SBarry Smith         new_i   = new_j + new_nz;
20617ab2063SBarry Smith 
20717ab2063SBarry Smith         /* copy over old data into new slots */
20817ab2063SBarry Smith         for ( ii=0; ii<row+1; ii++ ) {new_i[ii] = ai[ii];}
209416022c9SBarry Smith         for ( ii=row+1; ii<a->m+1; ii++ ) {new_i[ii] = ai[ii]+CHUNKSIZE;}
210416022c9SBarry Smith         PetscMemcpy(new_j,aj,(ai[row]+nrow+shift)*sizeof(int));
211416022c9SBarry Smith         len = (new_nz - CHUNKSIZE - ai[row] - nrow - shift);
212416022c9SBarry Smith         PetscMemcpy(new_j+ai[row]+shift+nrow+CHUNKSIZE,aj+ai[row]+shift+nrow,
21317ab2063SBarry Smith                                                            len*sizeof(int));
214416022c9SBarry Smith         PetscMemcpy(new_a,aa,(ai[row]+nrow+shift)*sizeof(Scalar));
215416022c9SBarry Smith         PetscMemcpy(new_a+ai[row]+shift+nrow+CHUNKSIZE,aa+ai[row]+shift+nrow,
21617ab2063SBarry Smith                                                            len*sizeof(Scalar));
21717ab2063SBarry Smith         /* free up old matrix storage */
2180452661fSBarry Smith         PetscFree(a->a);
2190452661fSBarry Smith         if (!a->singlemalloc) {PetscFree(a->i);PetscFree(a->j);}
220416022c9SBarry Smith         aa = a->a = new_a; ai = a->i = new_i; aj = a->j = new_j;
221416022c9SBarry Smith         a->singlemalloc = 1;
22217ab2063SBarry Smith 
22317ab2063SBarry Smith         rp   = aj + ai[row] + shift; ap = aa + ai[row] + shift;
224416022c9SBarry Smith         rmax = imax[row] = imax[row] + CHUNKSIZE;
225416022c9SBarry Smith         PLogObjectMemory(A,CHUNKSIZE*(sizeof(int) + sizeof(Scalar)));
226416022c9SBarry Smith         a->maxnz += CHUNKSIZE;
227b810aeb4SBarry Smith         a->reallocs++;
22817ab2063SBarry Smith       }
229416022c9SBarry Smith       N = nrow++ - 1; a->nz++;
230416022c9SBarry Smith       /* shift up all the later entries in this row */
231416022c9SBarry Smith       for ( ii=N; ii>=i; ii-- ) {
23217ab2063SBarry Smith         rp[ii+1] = rp[ii];
23317ab2063SBarry Smith         ap[ii+1] = ap[ii];
23417ab2063SBarry Smith       }
23517ab2063SBarry Smith       rp[i] = col;
23617ab2063SBarry Smith       ap[i] = value;
23717ab2063SBarry Smith       noinsert:;
238416022c9SBarry Smith       low = i + 1;
23917ab2063SBarry Smith     }
24017ab2063SBarry Smith     ailen[row] = nrow;
24117ab2063SBarry Smith   }
2423a40ed3dSBarry Smith   PetscFunctionReturn(0);
24317ab2063SBarry Smith }
24417ab2063SBarry Smith 
2455615d1e5SSatish Balay #undef __FUNC__
2465615d1e5SSatish Balay #define __FUNC__ "MatGetValues_SeqAIJ"
2478f6be9afSLois Curfman McInnes int MatGetValues_SeqAIJ(Mat A,int m,int *im,int n,int *in,Scalar *v)
2487eb43aa7SLois Curfman McInnes {
2497eb43aa7SLois Curfman McInnes   Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data;
250b49de8d1SLois Curfman McInnes   int        *rp, k, low, high, t, row, nrow, i, col, l, *aj = a->j;
2517eb43aa7SLois Curfman McInnes   int        *ai = a->i, *ailen = a->ilen, shift = a->indexshift;
2527eb43aa7SLois Curfman McInnes   Scalar     *ap, *aa = a->a, zero = 0.0;
2537eb43aa7SLois Curfman McInnes 
2543a40ed3dSBarry Smith   PetscFunctionBegin;
2557eb43aa7SLois Curfman McInnes   for ( k=0; k<m; k++ ) { /* loop over rows */
2567eb43aa7SLois Curfman McInnes     row  = im[k];
257a8c6a408SBarry Smith     if (row < 0) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Negative row");
258a8c6a408SBarry Smith     if (row >= a->m) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Row too large");
2597eb43aa7SLois Curfman McInnes     rp   = aj + ai[row] + shift; ap = aa + ai[row] + shift;
2607eb43aa7SLois Curfman McInnes     nrow = ailen[row];
2617eb43aa7SLois Curfman McInnes     for ( l=0; l<n; l++ ) { /* loop over columns */
262a8c6a408SBarry Smith       if (in[l] < 0) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Negative column");
263a8c6a408SBarry Smith       if (in[l] >= a->n) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Column too large");
2647eb43aa7SLois Curfman McInnes       col = in[l] - shift;
2657eb43aa7SLois Curfman McInnes       high = nrow; low = 0; /* assume unsorted */
2667eb43aa7SLois Curfman McInnes       while (high-low > 5) {
2677eb43aa7SLois Curfman McInnes         t = (low+high)/2;
2687eb43aa7SLois Curfman McInnes         if (rp[t] > col) high = t;
2697eb43aa7SLois Curfman McInnes         else             low  = t;
2707eb43aa7SLois Curfman McInnes       }
2717eb43aa7SLois Curfman McInnes       for ( i=low; i<high; i++ ) {
2727eb43aa7SLois Curfman McInnes         if (rp[i] > col) break;
2737eb43aa7SLois Curfman McInnes         if (rp[i] == col) {
274b49de8d1SLois Curfman McInnes           *v++ = ap[i];
2757eb43aa7SLois Curfman McInnes           goto finished;
2767eb43aa7SLois Curfman McInnes         }
2777eb43aa7SLois Curfman McInnes       }
278b49de8d1SLois Curfman McInnes       *v++ = zero;
2797eb43aa7SLois Curfman McInnes       finished:;
2807eb43aa7SLois Curfman McInnes     }
2817eb43aa7SLois Curfman McInnes   }
2823a40ed3dSBarry Smith   PetscFunctionReturn(0);
2837eb43aa7SLois Curfman McInnes }
2847eb43aa7SLois Curfman McInnes 
28517ab2063SBarry Smith 
2865615d1e5SSatish Balay #undef __FUNC__
2875615d1e5SSatish Balay #define __FUNC__ "MatView_SeqAIJ_Binary"
288480ef9eaSBarry Smith int MatView_SeqAIJ_Binary(Mat A,Viewer viewer)
28917ab2063SBarry Smith {
290416022c9SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data;
291416022c9SBarry Smith   int        i, fd, *col_lens, ierr;
29217ab2063SBarry Smith 
2933a40ed3dSBarry Smith   PetscFunctionBegin;
29490ace30eSBarry Smith   ierr = ViewerBinaryGetDescriptor(viewer,&fd); CHKERRQ(ierr);
2950452661fSBarry Smith   col_lens = (int *) PetscMalloc( (4+a->m)*sizeof(int) ); CHKPTRQ(col_lens);
296416022c9SBarry Smith   col_lens[0] = MAT_COOKIE;
297416022c9SBarry Smith   col_lens[1] = a->m;
298416022c9SBarry Smith   col_lens[2] = a->n;
299416022c9SBarry Smith   col_lens[3] = a->nz;
300416022c9SBarry Smith 
301416022c9SBarry Smith   /* store lengths of each row and write (including header) to file */
302416022c9SBarry Smith   for ( i=0; i<a->m; i++ ) {
303416022c9SBarry Smith     col_lens[4+i] = a->i[i+1] - a->i[i];
30417ab2063SBarry Smith   }
3050752156aSBarry Smith   ierr = PetscBinaryWrite(fd,col_lens,4+a->m,PETSC_INT,1); CHKERRQ(ierr);
3060452661fSBarry Smith   PetscFree(col_lens);
307416022c9SBarry Smith 
308416022c9SBarry Smith   /* store column indices (zero start index) */
309416022c9SBarry Smith   if (a->indexshift) {
310416022c9SBarry Smith     for ( i=0; i<a->nz; i++ ) a->j[i]--;
31117ab2063SBarry Smith   }
3120752156aSBarry Smith   ierr = PetscBinaryWrite(fd,a->j,a->nz,PETSC_INT,0); CHKERRQ(ierr);
313416022c9SBarry Smith   if (a->indexshift) {
314416022c9SBarry Smith     for ( i=0; i<a->nz; i++ ) a->j[i]++;
31517ab2063SBarry Smith   }
316416022c9SBarry Smith 
317416022c9SBarry Smith   /* store nonzero values */
3180752156aSBarry Smith   ierr = PetscBinaryWrite(fd,a->a,a->nz,PETSC_SCALAR,0); CHKERRQ(ierr);
3193a40ed3dSBarry Smith   PetscFunctionReturn(0);
32017ab2063SBarry Smith }
321416022c9SBarry Smith 
3225615d1e5SSatish Balay #undef __FUNC__
3235615d1e5SSatish Balay #define __FUNC__ "MatView_SeqAIJ_ASCII"
324480ef9eaSBarry Smith int MatView_SeqAIJ_ASCII(Mat A,Viewer viewer)
325416022c9SBarry Smith {
326416022c9SBarry Smith   Mat_SeqAIJ  *a = (Mat_SeqAIJ *) A->data;
327496e697eSBarry Smith   int         ierr, i,j, m = a->m, shift = a->indexshift, format, flg1,flg2;
32817ab2063SBarry Smith   FILE        *fd;
32917ab2063SBarry Smith   char        *outputname;
33017ab2063SBarry Smith 
3313a40ed3dSBarry Smith   PetscFunctionBegin;
33290ace30eSBarry Smith   ierr = ViewerASCIIGetPointer(viewer,&fd); CHKERRQ(ierr);
333fb4b0f7fSBarry Smith   ierr = ViewerGetOutputname(viewer,&outputname); CHKERRQ(ierr);
33490ace30eSBarry Smith   ierr = ViewerGetFormat(viewer,&format);
335a93ec695SBarry Smith   if (format == VIEWER_FORMAT_ASCII_INFO) {
3363a40ed3dSBarry Smith     PetscFunctionReturn(0);
3373a40ed3dSBarry Smith   } else if (format == VIEWER_FORMAT_ASCII_INFO_LONG) {
338496e697eSBarry Smith     ierr = OptionsHasName(PETSC_NULL,"-mat_aij_no_inode",&flg1); CHKERRQ(ierr);
339496e697eSBarry Smith     ierr = OptionsHasName(PETSC_NULL,"-mat_no_unroll",&flg2); CHKERRQ(ierr);
340496e697eSBarry Smith     if (flg1 || flg2) fprintf(fd,"  not using I-node routines\n");
34195e01e2fSLois Curfman McInnes     else     fprintf(fd,"  using I-node routines: found %d nodes, limit used is %d\n",
34295e01e2fSLois Curfman McInnes         a->inode.node_count,a->inode.limit);
3433a40ed3dSBarry Smith   } else if (format == VIEWER_FORMAT_ASCII_MATLAB) {
344d00d2cf4SBarry Smith     int nofinalvalue = 0;
345d00d2cf4SBarry Smith     if ((a->i[m] == a->i[m-1]) || (a->j[a->nz-1] != a->n-!shift)) {
346d00d2cf4SBarry Smith       nofinalvalue = 1;
347d00d2cf4SBarry Smith     }
348416022c9SBarry Smith     fprintf(fd,"%% Size = %d %d \n",m,a->n);
3494e220ebcSLois Curfman McInnes     fprintf(fd,"%% Nonzeros = %d \n",a->nz);
350d00d2cf4SBarry Smith     fprintf(fd,"zzz = zeros(%d,3);\n",a->nz+nofinalvalue);
35117ab2063SBarry Smith     fprintf(fd,"zzz = [\n");
35217ab2063SBarry Smith 
35317ab2063SBarry Smith     for (i=0; i<m; i++) {
354416022c9SBarry Smith       for ( j=a->i[i]+shift; j<a->i[i+1]+shift; j++ ) {
3553a40ed3dSBarry Smith #if defined(USE_PETSC_COMPLEX)
356e20fef11SSatish Balay         fprintf(fd,"%d %d  %18.16e + %18.16e i \n",i+1,a->j[j]+!shift,PetscReal(a->a[j]),PetscImaginary(a->a[j]));
35717ab2063SBarry Smith #else
3587a743949SBarry Smith         fprintf(fd,"%d %d  %18.16e\n", i+1, a->j[j]+!shift, a->a[j]);
35917ab2063SBarry Smith #endif
36017ab2063SBarry Smith       }
36117ab2063SBarry Smith     }
362d00d2cf4SBarry Smith     if (nofinalvalue) {
363d00d2cf4SBarry Smith       fprintf(fd,"%d %d  %18.16e\n", m, a->n, 0.0);
364d00d2cf4SBarry Smith     }
365e24b481bSBarry Smith     if (outputname) fprintf(fd,"];\n %s = spconvert(zzz);\n",outputname);
366e24b481bSBarry Smith     else            fprintf(fd,"];\n M = spconvert(zzz);\n");
3673a40ed3dSBarry Smith   } else if (format == VIEWER_FORMAT_ASCII_COMMON) {
36844cd7ae7SLois Curfman McInnes     for ( i=0; i<m; i++ ) {
36944cd7ae7SLois Curfman McInnes       fprintf(fd,"row %d:",i);
37044cd7ae7SLois Curfman McInnes       for ( j=a->i[i]+shift; j<a->i[i+1]+shift; j++ ) {
3713a40ed3dSBarry Smith #if defined(USE_PETSC_COMPLEX)
372e20fef11SSatish Balay         if (PetscImaginary(a->a[j]) > 0.0 && PetscReal(a->a[j]) != 0.0)
373e20fef11SSatish Balay           fprintf(fd," %d %g + %g i",a->j[j]+shift,PetscReal(a->a[j]),PetscImaginary(a->a[j]));
374e20fef11SSatish Balay         else if (PetscImaginary(a->a[j]) < 0.0 && PetscReal(a->a[j]) != 0.0)
375e20fef11SSatish Balay           fprintf(fd," %d %g - %g i",a->j[j]+shift,PetscReal(a->a[j]),-PetscImaginary(a->a[j]));
376e20fef11SSatish Balay         else if (PetscReal(a->a[j]) != 0.0)
377e20fef11SSatish Balay           fprintf(fd," %d %g ",a->j[j]+shift,PetscReal(a->a[j]));
37844cd7ae7SLois Curfman McInnes #else
37944cd7ae7SLois Curfman McInnes         if (a->a[j] != 0.0) fprintf(fd," %d %g ",a->j[j]+shift,a->a[j]);
38044cd7ae7SLois Curfman McInnes #endif
38144cd7ae7SLois Curfman McInnes       }
38244cd7ae7SLois Curfman McInnes       fprintf(fd,"\n");
38344cd7ae7SLois Curfman McInnes     }
38402594712SBarry Smith   } else if (format == VIEWER_FORMAT_ASCII_SYMMODU) {
385496be53dSLois Curfman McInnes     int nzd=0, fshift=1, *sptr;
3862e44a96cSLois Curfman McInnes     sptr = (int *) PetscMalloc( (m+1)*sizeof(int) ); CHKPTRQ(sptr);
387496be53dSLois Curfman McInnes     for ( i=0; i<m; i++ ) {
388496be53dSLois Curfman McInnes       sptr[i] = nzd+1;
389496be53dSLois Curfman McInnes       for ( j=a->i[i]+shift; j<a->i[i+1]+shift; j++ ) {
390496be53dSLois Curfman McInnes         if (a->j[j] >= i) {
3913a40ed3dSBarry Smith #if defined(USE_PETSC_COMPLEX)
392e20fef11SSatish Balay           if (PetscImaginary(a->a[j]) != 0.0 || PetscReal(a->a[j]) != 0.0) nzd++;
393496be53dSLois Curfman McInnes #else
394496be53dSLois Curfman McInnes           if (a->a[j] != 0.0) nzd++;
395496be53dSLois Curfman McInnes #endif
396496be53dSLois Curfman McInnes         }
397496be53dSLois Curfman McInnes       }
398496be53dSLois Curfman McInnes     }
3992e44a96cSLois Curfman McInnes     sptr[m] = nzd+1;
400496be53dSLois Curfman McInnes     fprintf(fd," %d %d\n\n",m,nzd);
4012e44a96cSLois Curfman McInnes     for ( i=0; i<m+1; i+=6 ) {
4022e44a96cSLois Curfman McInnes       if (i+4<m) fprintf(fd," %d %d %d %d %d %d\n",sptr[i],sptr[i+1],sptr[i+2],sptr[i+3],sptr[i+4],sptr[i+5]);
4032e44a96cSLois Curfman McInnes       else if (i+3<m) fprintf(fd," %d %d %d %d %d\n",sptr[i],sptr[i+1],sptr[i+2],sptr[i+3],sptr[i+4]);
4042e44a96cSLois Curfman McInnes       else if (i+2<m) fprintf(fd," %d %d %d %d\n",sptr[i],sptr[i+1],sptr[i+2],sptr[i+3]);
4052e44a96cSLois Curfman McInnes       else if (i+1<m) fprintf(fd," %d %d %d\n",sptr[i],sptr[i+1],sptr[i+2]);
4062e44a96cSLois Curfman McInnes       else if (i<m)   fprintf(fd," %d %d\n",sptr[i],sptr[i+1]);
4077272d637SLois Curfman McInnes       else            fprintf(fd," %d\n",sptr[i]);
408496be53dSLois Curfman McInnes     }
409496be53dSLois Curfman McInnes     fprintf(fd,"\n");
410496be53dSLois Curfman McInnes     PetscFree(sptr);
411496be53dSLois Curfman McInnes     for ( i=0; i<m; i++ ) {
412496be53dSLois Curfman McInnes       for ( j=a->i[i]+shift; j<a->i[i+1]+shift; j++ ) {
413496be53dSLois Curfman McInnes         if (a->j[j] >= i) fprintf(fd," %d ",a->j[j]+fshift);
414496be53dSLois Curfman McInnes       }
415496be53dSLois Curfman McInnes       fprintf(fd,"\n");
416496be53dSLois Curfman McInnes     }
417496be53dSLois Curfman McInnes     fprintf(fd,"\n");
418496be53dSLois Curfman McInnes     for ( i=0; i<m; i++ ) {
419496be53dSLois Curfman McInnes       for ( j=a->i[i]+shift; j<a->i[i+1]+shift; j++ ) {
420496be53dSLois Curfman McInnes         if (a->j[j] >= i) {
4213a40ed3dSBarry Smith #if defined(USE_PETSC_COMPLEX)
422e20fef11SSatish Balay           if (PetscImaginary(a->a[j]) != 0.0 || PetscReal(a->a[j]) != 0.0)
423e20fef11SSatish Balay             fprintf(fd," %18.16e %18.16e ",PetscReal(a->a[j]),PetscImaginary(a->a[j]));
424496be53dSLois Curfman McInnes #else
425496be53dSLois Curfman McInnes           if (a->a[j] != 0.0) fprintf(fd," %18.16e ",a->a[j]);
426496be53dSLois Curfman McInnes #endif
427496be53dSLois Curfman McInnes         }
428496be53dSLois Curfman McInnes       }
429496be53dSLois Curfman McInnes       fprintf(fd,"\n");
430496be53dSLois Curfman McInnes     }
43102594712SBarry Smith   } else if (format == VIEWER_FORMAT_ASCII_DENSE) {
43202594712SBarry Smith     int    cnt = 0,jcnt;
43302594712SBarry Smith     Scalar value;
43402594712SBarry Smith 
43502594712SBarry Smith     for ( i=0; i<m; i++ ) {
43602594712SBarry Smith       jcnt = 0;
43702594712SBarry Smith       for ( j=0; j<a->n; j++ ) {
438e24b481bSBarry Smith         if ( jcnt < a->i[i+1]-a->i[i] && j == a->j[cnt]) {
43902594712SBarry Smith           value = a->a[cnt++];
440e24b481bSBarry Smith           jcnt++;
44102594712SBarry Smith         } else {
44202594712SBarry Smith           value = 0.0;
44302594712SBarry Smith         }
44402594712SBarry Smith #if defined(USE_PETSC_COMPLEX)
44502594712SBarry Smith         fprintf(fd," %7.5e+%7.5e i ",PetscReal(value),PetscImaginary(value));
44602594712SBarry Smith #else
44702594712SBarry Smith         fprintf(fd," %7.5e ",value);
44802594712SBarry Smith #endif
44902594712SBarry Smith       }
45002594712SBarry Smith         fprintf(fd,"\n");
45102594712SBarry Smith     }
4523a40ed3dSBarry Smith   } else {
45317ab2063SBarry Smith     for ( i=0; i<m; i++ ) {
45417ab2063SBarry Smith       fprintf(fd,"row %d:",i);
455416022c9SBarry Smith       for ( j=a->i[i]+shift; j<a->i[i+1]+shift; j++ ) {
4563a40ed3dSBarry Smith #if defined(USE_PETSC_COMPLEX)
457e20fef11SSatish Balay         if (PetscImaginary(a->a[j]) > 0.0) {
458e20fef11SSatish Balay           fprintf(fd," %d %g + %g i",a->j[j]+shift,PetscReal(a->a[j]),PetscImaginary(a->a[j]));
459e20fef11SSatish Balay         } else if (PetscImaginary(a->a[j]) < 0.0) {
460e20fef11SSatish Balay           fprintf(fd," %d %g - %g i",a->j[j]+shift,PetscReal(a->a[j]),-PetscImaginary(a->a[j]));
4613a40ed3dSBarry Smith         } else {
462e20fef11SSatish Balay           fprintf(fd," %d %g ",a->j[j]+shift,PetscReal(a->a[j]));
46317ab2063SBarry Smith         }
46417ab2063SBarry Smith #else
465416022c9SBarry Smith         fprintf(fd," %d %g ",a->j[j]+shift,a->a[j]);
46617ab2063SBarry Smith #endif
46717ab2063SBarry Smith       }
46817ab2063SBarry Smith       fprintf(fd,"\n");
46917ab2063SBarry Smith     }
47017ab2063SBarry Smith   }
47117ab2063SBarry Smith   fflush(fd);
4723a40ed3dSBarry Smith   PetscFunctionReturn(0);
473416022c9SBarry Smith }
474416022c9SBarry Smith 
4755615d1e5SSatish Balay #undef __FUNC__
476480ef9eaSBarry Smith #define __FUNC__ "MatView_SeqAIJ_Draw_Zoom"
477480ef9eaSBarry Smith int MatView_SeqAIJ_Draw_Zoom(Draw draw,void *Aa)
478416022c9SBarry Smith {
479480ef9eaSBarry Smith   Mat         A = (Mat) Aa;
480416022c9SBarry Smith   Mat_SeqAIJ  *a = (Mat_SeqAIJ *) A->data;
481*77ed5343SBarry Smith   int         ierr, i,j, m = a->m, shift = a->indexshift,color,rank;
4820513a670SBarry Smith   int         format;
483480ef9eaSBarry Smith   double      xl,yl,xr,yr,x_l,x_r,y_l,y_r,maxv = 0.0;
484480ef9eaSBarry Smith   Viewer      viewer;
485*77ed5343SBarry Smith   MPI_Comm    comm;
486cddf8d76SBarry Smith 
4873a40ed3dSBarry Smith   PetscFunctionBegin;
488*77ed5343SBarry Smith   /*
489*77ed5343SBarry Smith       This is nasty. If this is called from an originally parallel matrix
490*77ed5343SBarry Smith    then all processes call this, but only the first has the matrix so the
491*77ed5343SBarry Smith    rest should return immediately.
492*77ed5343SBarry Smith   */
493*77ed5343SBarry Smith   ierr = PetscObjectGetComm((PetscObject)draw,&comm);CHKERRQ(ierr);
494*77ed5343SBarry Smith   MPI_Comm_rank(comm,&rank);
495*77ed5343SBarry Smith   if (rank) PetscFunctionReturn(0);
496*77ed5343SBarry Smith 
497480ef9eaSBarry Smith   ierr = PetscObjectQuery((PetscObject)A,"Zoomviewer",(PetscObject*) &viewer);CHKERRQ(ierr);
4980513a670SBarry Smith   ierr = ViewerGetFormat(viewer,&format); CHKERRQ(ierr);
49919bcc07fSBarry Smith 
500480ef9eaSBarry Smith   ierr = DrawGetCoordinates(draw,&xl,&yl,&xr,&yr); CHKERRQ(ierr);
501416022c9SBarry Smith   /* loop over matrix elements drawing boxes */
5020513a670SBarry Smith 
5030513a670SBarry Smith   if (format != VIEWER_FORMAT_DRAW_CONTOUR) {
5040513a670SBarry Smith     /* Blue for negative, Cyan for zero and  Red for positive */
505cddf8d76SBarry Smith     color = DRAW_BLUE;
506416022c9SBarry Smith     for ( i=0; i<m; i++ ) {
507cddf8d76SBarry Smith       y_l = m - i - 1.0; y_r = y_l + 1.0;
508416022c9SBarry Smith       for ( j=a->i[i]+shift; j<a->i[i+1]+shift; j++ ) {
509cddf8d76SBarry Smith         x_l = a->j[j] + shift; x_r = x_l + 1.0;
5103a40ed3dSBarry Smith #if defined(USE_PETSC_COMPLEX)
511e20fef11SSatish Balay         if (PetscReal(a->a[j]) >=  0.) continue;
512cddf8d76SBarry Smith #else
513cddf8d76SBarry Smith         if (a->a[j] >=  0.) continue;
514cddf8d76SBarry Smith #endif
515480ef9eaSBarry Smith         ierr = DrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr);
516cddf8d76SBarry Smith       }
517cddf8d76SBarry Smith     }
518cddf8d76SBarry Smith     color = DRAW_CYAN;
519cddf8d76SBarry Smith     for ( i=0; i<m; i++ ) {
520cddf8d76SBarry Smith       y_l = m - i - 1.0; y_r = y_l + 1.0;
521cddf8d76SBarry Smith       for ( j=a->i[i]+shift; j<a->i[i+1]+shift; j++ ) {
522cddf8d76SBarry Smith         x_l = a->j[j] + shift; x_r = x_l + 1.0;
523cddf8d76SBarry Smith         if (a->a[j] !=  0.) continue;
524480ef9eaSBarry Smith         ierr = DrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr);
525cddf8d76SBarry Smith       }
526cddf8d76SBarry Smith     }
527cddf8d76SBarry Smith     color = DRAW_RED;
528cddf8d76SBarry Smith     for ( i=0; i<m; i++ ) {
529cddf8d76SBarry Smith       y_l = m - i - 1.0; y_r = y_l + 1.0;
530cddf8d76SBarry Smith       for ( j=a->i[i]+shift; j<a->i[i+1]+shift; j++ ) {
531cddf8d76SBarry Smith         x_l = a->j[j] + shift; x_r = x_l + 1.0;
5323a40ed3dSBarry Smith #if defined(USE_PETSC_COMPLEX)
533e20fef11SSatish Balay         if (PetscReal(a->a[j]) <=  0.) continue;
534cddf8d76SBarry Smith #else
535cddf8d76SBarry Smith         if (a->a[j] <=  0.) continue;
536cddf8d76SBarry Smith #endif
537480ef9eaSBarry Smith         ierr = DrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr);
538416022c9SBarry Smith       }
539416022c9SBarry Smith     }
5400513a670SBarry Smith   } else {
5410513a670SBarry Smith     /* use contour shading to indicate magnitude of values */
5420513a670SBarry Smith     /* first determine max of all nonzero values */
5430513a670SBarry Smith     int    nz = a->nz,count;
5440513a670SBarry Smith     Draw   popup;
545480ef9eaSBarry Smith     double scale;
5460513a670SBarry Smith 
5470513a670SBarry Smith     for ( i=0; i<nz; i++ ) {
5480513a670SBarry Smith       if (PetscAbsScalar(a->a[i]) > maxv) maxv = PetscAbsScalar(a->a[i]);
5490513a670SBarry Smith     }
550480ef9eaSBarry Smith     scale = (245.0 - DRAW_BASIC_COLORS)/maxv;
551522c5e43SBarry Smith     ierr  = DrawGetPopup(draw,&popup); CHKERRQ(ierr);
5520513a670SBarry Smith     ierr  = DrawScalePopup(popup,0.0,maxv); CHKERRQ(ierr);
5530513a670SBarry Smith     count = 0;
5540513a670SBarry Smith     for ( i=0; i<m; i++ ) {
5550513a670SBarry Smith       y_l = m - i - 1.0; y_r = y_l + 1.0;
5560513a670SBarry Smith       for ( j=a->i[i]+shift; j<a->i[i+1]+shift; j++ ) {
5570513a670SBarry Smith         x_l = a->j[j] + shift; x_r = x_l + 1.0;
5586d6b6c30SSatish Balay         color = DRAW_BASIC_COLORS + (int)(scale*PetscAbsScalar(a->a[count]));
559480ef9eaSBarry Smith         ierr  = DrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr);
5600513a670SBarry Smith         count++;
5610513a670SBarry Smith       }
5620513a670SBarry Smith     }
5630513a670SBarry Smith   }
564480ef9eaSBarry Smith   PetscFunctionReturn(0);
565480ef9eaSBarry Smith }
566cddf8d76SBarry Smith 
567480ef9eaSBarry Smith #undef __FUNC__
568480ef9eaSBarry Smith #define __FUNC__ "MatView_SeqAIJ_Draw"
569480ef9eaSBarry Smith int MatView_SeqAIJ_Draw(Mat A,Viewer viewer)
570480ef9eaSBarry Smith {
571480ef9eaSBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*) A->data;
572480ef9eaSBarry Smith   int        ierr;
573480ef9eaSBarry Smith   Draw       draw;
574480ef9eaSBarry Smith   double     xr,yr,xl,yl,h,w;
575480ef9eaSBarry Smith 
576480ef9eaSBarry Smith   PetscTruth isnull;
577480ef9eaSBarry Smith 
578480ef9eaSBarry Smith   PetscFunctionBegin;
579*77ed5343SBarry Smith   ierr = ViewerDrawGetDraw(viewer,0,&draw); CHKERRQ(ierr);
580480ef9eaSBarry Smith   ierr = DrawIsNull(draw,&isnull); CHKERRQ(ierr);
581480ef9eaSBarry Smith   if (isnull) PetscFunctionReturn(0);
582480ef9eaSBarry Smith 
583480ef9eaSBarry Smith   ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",(PetscObject)viewer);CHKERRQ(ierr);
584480ef9eaSBarry Smith   xr  = a->n; yr = a->m; h = yr/10.0; w = xr/10.0;
585480ef9eaSBarry Smith   xr += w;    yr += h;  xl = -w;     yl = -h;
586cddf8d76SBarry Smith   ierr = DrawSetCoordinates(draw,xl,yl,xr,yr); CHKERRQ(ierr);
587480ef9eaSBarry Smith   ierr = DrawZoom(draw,MatView_SeqAIJ_Draw_Zoom,A); CHKERRQ(ierr);
588480ef9eaSBarry Smith   ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",PETSC_NULL);CHKERRQ(ierr);
5893a40ed3dSBarry Smith   PetscFunctionReturn(0);
590416022c9SBarry Smith }
591416022c9SBarry Smith 
5925615d1e5SSatish Balay #undef __FUNC__
593d4bb536fSBarry Smith #define __FUNC__ "MatView_SeqAIJ"
594e1311b90SBarry Smith int MatView_SeqAIJ(Mat A,Viewer viewer)
595416022c9SBarry Smith {
596416022c9SBarry Smith   Mat_SeqAIJ  *a = (Mat_SeqAIJ*) A->data;
597bcd2baecSBarry Smith   ViewerType  vtype;
598bcd2baecSBarry Smith   int         ierr;
599416022c9SBarry Smith 
6003a40ed3dSBarry Smith   PetscFunctionBegin;
601bcd2baecSBarry Smith   ierr = ViewerGetType(viewer,&vtype); CHKERRQ(ierr);
602*77ed5343SBarry Smith   if (!PetscStrcmp(vtype,MATLAB_VIEWER)) {
6033a40ed3dSBarry Smith     ierr = ViewerMatlabPutSparse_Private(viewer,a->m,a->n,a->nz,a->a,a->i,a->j);CHKERRQ(ierr);
604*77ed5343SBarry Smith   } else if (!PetscStrcmp(vtype,ASCII_VIEWER)){
6053a40ed3dSBarry Smith     ierr = MatView_SeqAIJ_ASCII(A,viewer); CHKERRQ(ierr);
606*77ed5343SBarry Smith   } else if (!PetscStrcmp(vtype,BINARY_VIEWER)) {
6073a40ed3dSBarry Smith     ierr = MatView_SeqAIJ_Binary(A,viewer); CHKERRQ(ierr);
608*77ed5343SBarry Smith   } else if (!PetscStrcmp(vtype,DRAW_VIEWER)) {
6093a40ed3dSBarry Smith     ierr = MatView_SeqAIJ_Draw(A,viewer); CHKERRQ(ierr);
6105cd90555SBarry Smith   } else {
6115cd90555SBarry Smith     SETERRQ(1,1,"Viewer type not supported by PETSc object");
61217ab2063SBarry Smith   }
6133a40ed3dSBarry Smith   PetscFunctionReturn(0);
61417ab2063SBarry Smith }
61519bcc07fSBarry Smith 
616c456f294SBarry Smith extern int Mat_AIJ_CheckInode(Mat);
6175615d1e5SSatish Balay #undef __FUNC__
6185615d1e5SSatish Balay #define __FUNC__ "MatAssemblyEnd_SeqAIJ"
6198f6be9afSLois Curfman McInnes int MatAssemblyEnd_SeqAIJ(Mat A,MatAssemblyType mode)
62017ab2063SBarry Smith {
621416022c9SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data;
62241c01911SSatish Balay   int        fshift = 0,i,j,*ai = a->i, *aj = a->j, *imax = a->imax,ierr;
62343ee02c3SBarry Smith   int        m = a->m, *ip, N, *ailen = a->ilen,shift = a->indexshift,rmax = 0;
624416022c9SBarry Smith   Scalar     *aa = a->a, *ap;
62517ab2063SBarry Smith 
6263a40ed3dSBarry Smith   PetscFunctionBegin;
6273a40ed3dSBarry Smith   if (mode == MAT_FLUSH_ASSEMBLY) PetscFunctionReturn(0);
62817ab2063SBarry Smith 
62943ee02c3SBarry Smith   if (m) rmax = ailen[0]; /* determine row with most nonzeros */
63017ab2063SBarry Smith   for ( i=1; i<m; i++ ) {
631416022c9SBarry Smith     /* move each row back by the amount of empty slots (fshift) before it*/
63217ab2063SBarry Smith     fshift += imax[i-1] - ailen[i-1];
63394a9d846SBarry Smith     rmax   = PetscMax(rmax,ailen[i]);
63417ab2063SBarry Smith     if (fshift) {
635416022c9SBarry Smith       ip = aj + ai[i] + shift; ap = aa + ai[i] + shift;
63617ab2063SBarry Smith       N = ailen[i];
63717ab2063SBarry Smith       for ( j=0; j<N; j++ ) {
63817ab2063SBarry Smith         ip[j-fshift] = ip[j];
63917ab2063SBarry Smith         ap[j-fshift] = ap[j];
64017ab2063SBarry Smith       }
64117ab2063SBarry Smith     }
64217ab2063SBarry Smith     ai[i] = ai[i-1] + ailen[i-1];
64317ab2063SBarry Smith   }
64417ab2063SBarry Smith   if (m) {
64517ab2063SBarry Smith     fshift += imax[m-1] - ailen[m-1];
64617ab2063SBarry Smith     ai[m] = ai[m-1] + ailen[m-1];
64717ab2063SBarry Smith   }
64817ab2063SBarry Smith   /* reset ilen and imax for each row */
64917ab2063SBarry Smith   for ( i=0; i<m; i++ ) {
65017ab2063SBarry Smith     ailen[i] = imax[i] = ai[i+1] - ai[i];
65117ab2063SBarry Smith   }
652416022c9SBarry Smith   a->nz = ai[m] + shift;
65317ab2063SBarry Smith 
65417ab2063SBarry Smith   /* diagonals may have moved, so kill the diagonal pointers */
655416022c9SBarry Smith   if (fshift && a->diag) {
6560452661fSBarry Smith     PetscFree(a->diag);
657416022c9SBarry Smith     PLogObjectMemory(A,-(m+1)*sizeof(int));
658416022c9SBarry Smith     a->diag = 0;
65917ab2063SBarry Smith   }
6604e220ebcSLois Curfman McInnes   PLogInfo(A,"MatAssemblyEnd_SeqAIJ:Matrix size: %d X %d; storage space: %d unneeded, %d used\n",
6614e220ebcSLois Curfman McInnes            m,a->n,fshift,a->nz);
6624e220ebcSLois Curfman McInnes   PLogInfo(A,"MatAssemblyEnd_SeqAIJ:Number of mallocs during MatSetValues is %d\n",
663b810aeb4SBarry Smith            a->reallocs);
66494a9d846SBarry Smith   PLogInfo(A,"MatAssemblyEnd_SeqAIJ:Most nonzeros in any row is %d\n",rmax);
665dd5f02e7SSatish Balay   a->reallocs          = 0;
6664e220ebcSLois Curfman McInnes   A->info.nz_unneeded  = (double)fshift;
6674e220ebcSLois Curfman McInnes 
66876dd722bSSatish Balay   /* check out for identical nodes. If found, use inode functions */
66941c01911SSatish Balay   ierr = Mat_AIJ_CheckInode(A); CHKERRQ(ierr);
6703a40ed3dSBarry Smith   PetscFunctionReturn(0);
67117ab2063SBarry Smith }
67217ab2063SBarry Smith 
6735615d1e5SSatish Balay #undef __FUNC__
6745615d1e5SSatish Balay #define __FUNC__ "MatZeroEntries_SeqAIJ"
6758f6be9afSLois Curfman McInnes int MatZeroEntries_SeqAIJ(Mat A)
67617ab2063SBarry Smith {
677416022c9SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data;
6783a40ed3dSBarry Smith 
6793a40ed3dSBarry Smith   PetscFunctionBegin;
680cddf8d76SBarry Smith   PetscMemzero(a->a,(a->i[a->m]+a->indexshift)*sizeof(Scalar));
6813a40ed3dSBarry Smith   PetscFunctionReturn(0);
68217ab2063SBarry Smith }
683416022c9SBarry Smith 
6845615d1e5SSatish Balay #undef __FUNC__
6855615d1e5SSatish Balay #define __FUNC__ "MatDestroy_SeqAIJ"
686e1311b90SBarry Smith int MatDestroy_SeqAIJ(Mat A)
68717ab2063SBarry Smith {
688416022c9SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data;
68982bf6240SBarry Smith   int        ierr;
690d5d45c9bSBarry Smith 
6913a40ed3dSBarry Smith   PetscFunctionBegin;
69294d884c6SBarry Smith   if (--A->refct > 0) PetscFunctionReturn(0);
69394d884c6SBarry Smith 
69494d884c6SBarry Smith   if (A->mapping) {
69594d884c6SBarry Smith     ierr = ISLocalToGlobalMappingDestroy(A->mapping); CHKERRQ(ierr);
69694d884c6SBarry Smith   }
69794d884c6SBarry Smith   if (A->bmapping) {
69894d884c6SBarry Smith     ierr = ISLocalToGlobalMappingDestroy(A->bmapping); CHKERRQ(ierr);
69994d884c6SBarry Smith   }
70061b13de0SBarry Smith   if (A->rmap) {
70161b13de0SBarry Smith     ierr = MapDestroy(A->rmap);CHKERRQ(ierr);
70261b13de0SBarry Smith   }
70361b13de0SBarry Smith   if (A->cmap) {
70461b13de0SBarry Smith     ierr = MapDestroy(A->cmap);CHKERRQ(ierr);
70561b13de0SBarry Smith   }
7063a40ed3dSBarry Smith #if defined(USE_PETSC_LOG)
707e1311b90SBarry Smith   PLogObjectState((PetscObject)A,"Rows=%d, Cols=%d, NZ=%d",a->m,a->n,a->nz);
70817ab2063SBarry Smith #endif
7090452661fSBarry Smith   PetscFree(a->a);
7100452661fSBarry Smith   if (!a->singlemalloc) { PetscFree(a->i); PetscFree(a->j);}
7110452661fSBarry Smith   if (a->diag) PetscFree(a->diag);
7120452661fSBarry Smith   if (a->ilen) PetscFree(a->ilen);
7130452661fSBarry Smith   if (a->imax) PetscFree(a->imax);
7140452661fSBarry Smith   if (a->solve_work) PetscFree(a->solve_work);
71576dd722bSSatish Balay   if (a->inode.size) PetscFree(a->inode.size);
71682bf6240SBarry Smith   if (a->icol) {ierr = ISDestroy(a->icol);CHKERRQ(ierr);}
717be6bf707SBarry Smith   if (a->saved_values) PetscFree(a->saved_values);
7180452661fSBarry Smith   PetscFree(a);
719eed86810SBarry Smith 
720f2655603SLois Curfman McInnes   PLogObjectDestroy(A);
721f2655603SLois Curfman McInnes   PetscHeaderDestroy(A);
7223a40ed3dSBarry Smith   PetscFunctionReturn(0);
72317ab2063SBarry Smith }
72417ab2063SBarry Smith 
7255615d1e5SSatish Balay #undef __FUNC__
7265615d1e5SSatish Balay #define __FUNC__ "MatCompress_SeqAIJ"
7278f6be9afSLois Curfman McInnes int MatCompress_SeqAIJ(Mat A)
72817ab2063SBarry Smith {
7293a40ed3dSBarry Smith   PetscFunctionBegin;
7303a40ed3dSBarry Smith   PetscFunctionReturn(0);
73117ab2063SBarry Smith }
73217ab2063SBarry Smith 
7335615d1e5SSatish Balay #undef __FUNC__
7345615d1e5SSatish Balay #define __FUNC__ "MatSetOption_SeqAIJ"
7358f6be9afSLois Curfman McInnes int MatSetOption_SeqAIJ(Mat A,MatOption op)
73617ab2063SBarry Smith {
737416022c9SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data;
7383a40ed3dSBarry Smith 
7393a40ed3dSBarry Smith   PetscFunctionBegin;
7406d4a8577SBarry Smith   if      (op == MAT_ROW_ORIENTED)                 a->roworiented = 1;
7416d4a8577SBarry Smith   else if (op == MAT_COLUMN_ORIENTED)              a->roworiented = 0;
7426d4a8577SBarry Smith   else if (op == MAT_COLUMNS_SORTED)               a->sorted      = 1;
743219d9a1aSLois Curfman McInnes   else if (op == MAT_COLUMNS_UNSORTED)             a->sorted      = 0;
7446d4a8577SBarry Smith   else if (op == MAT_NO_NEW_NONZERO_LOCATIONS)     a->nonew       = 1;
745c2653b3dSLois Curfman McInnes   else if (op == MAT_NEW_NONZERO_LOCATION_ERROR)   a->nonew       = -1;
74696854ed6SLois Curfman McInnes   else if (op == MAT_NEW_NONZERO_ALLOCATION_ERROR) a->nonew       = -2;
7476d4a8577SBarry Smith   else if (op == MAT_YES_NEW_NONZERO_LOCATIONS)    a->nonew       = 0;
7486d4a8577SBarry Smith   else if (op == MAT_ROWS_SORTED ||
749219d9a1aSLois Curfman McInnes            op == MAT_ROWS_UNSORTED ||
7506d4a8577SBarry Smith            op == MAT_SYMMETRIC ||
7516d4a8577SBarry Smith            op == MAT_STRUCTURALLY_SYMMETRIC ||
75290f02eecSBarry Smith            op == MAT_YES_NEW_DIAGONALS ||
753b51ba29fSSatish Balay            op == MAT_IGNORE_OFF_PROC_ENTRIES||
754b51ba29fSSatish Balay            op == MAT_USE_HASH_TABLE)
755981c4779SBarry Smith     PLogInfo(A,"MatSetOption_SeqAIJ:Option ignored\n");
7563a40ed3dSBarry Smith   else if (op == MAT_NO_NEW_DIAGONALS) {
7573a40ed3dSBarry Smith     SETERRQ(PETSC_ERR_SUP,0,"MAT_NO_NEW_DIAGONALS");
7583a40ed3dSBarry Smith   } else if (op == MAT_INODE_LIMIT_1)            a->inode.limit  = 1;
7596d4a8577SBarry Smith   else if (op == MAT_INODE_LIMIT_2)            a->inode.limit  = 2;
7606d4a8577SBarry Smith   else if (op == MAT_INODE_LIMIT_3)            a->inode.limit  = 3;
7616d4a8577SBarry Smith   else if (op == MAT_INODE_LIMIT_4)            a->inode.limit  = 4;
7626d4a8577SBarry Smith   else if (op == MAT_INODE_LIMIT_5)            a->inode.limit  = 5;
7633a40ed3dSBarry Smith   else SETERRQ(PETSC_ERR_SUP,0,"unknown option");
7643a40ed3dSBarry Smith   PetscFunctionReturn(0);
76517ab2063SBarry Smith }
76617ab2063SBarry Smith 
7675615d1e5SSatish Balay #undef __FUNC__
7685615d1e5SSatish Balay #define __FUNC__ "MatGetDiagonal_SeqAIJ"
7698f6be9afSLois Curfman McInnes int MatGetDiagonal_SeqAIJ(Mat A,Vec v)
77017ab2063SBarry Smith {
771416022c9SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data;
7723a40ed3dSBarry Smith   int        i,j, n,shift = a->indexshift,ierr;
77317ab2063SBarry Smith   Scalar     *x, zero = 0.0;
77417ab2063SBarry Smith 
7753a40ed3dSBarry Smith   PetscFunctionBegin;
7763a40ed3dSBarry Smith   ierr = VecSet(&zero,v);CHKERRQ(ierr);
777e1311b90SBarry Smith   ierr = VecGetArray(v,&x);;CHKERRQ(ierr);
778e1311b90SBarry Smith   ierr = VecGetLocalSize(v,&n);;CHKERRQ(ierr);
779a8c6a408SBarry Smith   if (n != a->m) SETERRQ(PETSC_ERR_ARG_SIZ,0,"Nonconforming matrix and vector");
780416022c9SBarry Smith   for ( i=0; i<a->m; i++ ) {
781416022c9SBarry Smith     for ( j=a->i[i]+shift; j<a->i[i+1]+shift; j++ ) {
782416022c9SBarry Smith       if (a->j[j]+shift == i) {
783416022c9SBarry Smith         x[i] = a->a[j];
78417ab2063SBarry Smith         break;
78517ab2063SBarry Smith       }
78617ab2063SBarry Smith     }
78717ab2063SBarry Smith   }
788e1311b90SBarry Smith   ierr = VecRestoreArray(v,&x);;CHKERRQ(ierr);
7893a40ed3dSBarry Smith   PetscFunctionReturn(0);
79017ab2063SBarry Smith }
79117ab2063SBarry Smith 
79217ab2063SBarry Smith /* -------------------------------------------------------*/
79317ab2063SBarry Smith /* Should check that shapes of vectors and matrices match */
79417ab2063SBarry Smith /* -------------------------------------------------------*/
7955615d1e5SSatish Balay #undef __FUNC__
7965615d1e5SSatish Balay #define __FUNC__ "MatMultTrans_SeqAIJ"
79744cd7ae7SLois Curfman McInnes int MatMultTrans_SeqAIJ(Mat A,Vec xx,Vec yy)
79817ab2063SBarry Smith {
799416022c9SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data;
80017ab2063SBarry Smith   Scalar     *x, *y, *v, alpha;
801e1311b90SBarry Smith   int        ierr,m = a->m, n, i, *idx, shift = a->indexshift;
80217ab2063SBarry Smith 
8033a40ed3dSBarry Smith   PetscFunctionBegin;
804e1311b90SBarry Smith   ierr = VecGetArray(xx,&x);CHKERRQ(ierr);
805e1311b90SBarry Smith   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
806cddf8d76SBarry Smith   PetscMemzero(y,a->n*sizeof(Scalar));
80717ab2063SBarry Smith   y = y + shift; /* shift for Fortran start by 1 indexing */
80817ab2063SBarry Smith   for ( i=0; i<m; i++ ) {
809416022c9SBarry Smith     idx   = a->j + a->i[i] + shift;
810416022c9SBarry Smith     v     = a->a + a->i[i] + shift;
811416022c9SBarry Smith     n     = a->i[i+1] - a->i[i];
81217ab2063SBarry Smith     alpha = x[i];
81317ab2063SBarry Smith     while (n-->0) {y[*idx++] += alpha * *v++;}
81417ab2063SBarry Smith   }
815416022c9SBarry Smith   PLogFlops(2*a->nz - a->n);
816e1311b90SBarry Smith   ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr);
817e1311b90SBarry Smith   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
8183a40ed3dSBarry Smith   PetscFunctionReturn(0);
81917ab2063SBarry Smith }
820d5d45c9bSBarry Smith 
8215615d1e5SSatish Balay #undef __FUNC__
8225615d1e5SSatish Balay #define __FUNC__ "MatMultTransAdd_SeqAIJ"
82344cd7ae7SLois Curfman McInnes int MatMultTransAdd_SeqAIJ(Mat A,Vec xx,Vec zz,Vec yy)
82417ab2063SBarry Smith {
825416022c9SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data;
82617ab2063SBarry Smith   Scalar     *x, *y, *v, alpha;
827e1311b90SBarry Smith   int        ierr,m = a->m, n, i, *idx,shift = a->indexshift;
82817ab2063SBarry Smith 
8293a40ed3dSBarry Smith   PetscFunctionBegin;
8302e8a6d31SBarry Smith   if (zz != yy) {ierr = VecCopy(zz,yy);CHKERRQ(ierr);}
831e1311b90SBarry Smith   ierr = VecGetArray(xx,&x);CHKERRQ(ierr);
832e1311b90SBarry Smith   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
83317ab2063SBarry Smith   y = y + shift; /* shift for Fortran start by 1 indexing */
83417ab2063SBarry Smith   for ( i=0; i<m; i++ ) {
835416022c9SBarry Smith     idx   = a->j + a->i[i] + shift;
836416022c9SBarry Smith     v     = a->a + a->i[i] + shift;
837416022c9SBarry Smith     n     = a->i[i+1] - a->i[i];
83817ab2063SBarry Smith     alpha = x[i];
83917ab2063SBarry Smith     while (n-->0) {y[*idx++] += alpha * *v++;}
84017ab2063SBarry Smith   }
84190f02eecSBarry Smith   PLogFlops(2*a->nz);
842e1311b90SBarry Smith   ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr);
843e1311b90SBarry Smith   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
8443a40ed3dSBarry Smith   PetscFunctionReturn(0);
84517ab2063SBarry Smith }
84617ab2063SBarry Smith 
8475615d1e5SSatish Balay #undef __FUNC__
8485615d1e5SSatish Balay #define __FUNC__ "MatMult_SeqAIJ"
84944cd7ae7SLois Curfman McInnes int MatMult_SeqAIJ(Mat A,Vec xx,Vec yy)
85017ab2063SBarry Smith {
851416022c9SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data;
85217ab2063SBarry Smith   Scalar     *x, *y, *v, sum;
853e1311b90SBarry Smith   int        ierr,m = a->m, *idx, shift = a->indexshift,*ii;
8542e40c62eSSatish Balay #if !defined(USE_FORTRAN_KERNEL_MULTAIJ)
855e36a17ebSSatish Balay   int        n, i, jrow,j;
856e36a17ebSSatish Balay #endif
85717ab2063SBarry Smith 
858fee21e36SBarry Smith #if defined(HAVE_PRAGMA_DISJOINT)
859fee21e36SBarry Smith #pragma disjoint(*x,*y,*v)
860fee21e36SBarry Smith #endif
861fee21e36SBarry Smith 
8623a40ed3dSBarry Smith   PetscFunctionBegin;
863e1311b90SBarry Smith   ierr = VecGetArray(xx,&x); CHKERRQ(ierr);
864e1311b90SBarry Smith   ierr = VecGetArray(yy,&y); CHKERRQ(ierr);
86517ab2063SBarry Smith   x    = x + shift;    /* shift for Fortran start by 1 indexing */
866416022c9SBarry Smith   idx  = a->j;
867d64ed03dSBarry Smith   v    = a->a;
868416022c9SBarry Smith   ii   = a->i;
869acc4d009SSatish Balay #if defined(USE_FORTRAN_KERNEL_MULTAIJ)
87029b5ca8aSSatish Balay   fortranmultaij_(&m,x,ii,idx+shift,v+shift,y);
8718d195f9aSBarry Smith #else
872d64ed03dSBarry Smith   v    += shift; /* shift for Fortran start by 1 indexing */
873d64ed03dSBarry Smith   idx  += shift;
87417ab2063SBarry Smith   for ( i=0; i<m; i++ ) {
8759ea0dfa2SSatish Balay     jrow = ii[i];
8769ea0dfa2SSatish Balay     n    = ii[i+1] - jrow;
87717ab2063SBarry Smith     sum  = 0.0;
8789ea0dfa2SSatish Balay     for ( j=0; j<n; j++) {
8799ea0dfa2SSatish Balay       sum += v[jrow]*x[idx[jrow]]; jrow++;
8809ea0dfa2SSatish Balay      }
88117ab2063SBarry Smith     y[i] = sum;
88217ab2063SBarry Smith   }
8838d195f9aSBarry Smith #endif
884416022c9SBarry Smith   PLogFlops(2*a->nz - m);
885e1311b90SBarry Smith   ierr = VecRestoreArray(xx,&x); CHKERRQ(ierr);
886e1311b90SBarry Smith   ierr = VecRestoreArray(yy,&y); CHKERRQ(ierr);
8873a40ed3dSBarry Smith   PetscFunctionReturn(0);
88817ab2063SBarry Smith }
88917ab2063SBarry Smith 
8905615d1e5SSatish Balay #undef __FUNC__
8915615d1e5SSatish Balay #define __FUNC__ "MatMultAdd_SeqAIJ"
89244cd7ae7SLois Curfman McInnes int MatMultAdd_SeqAIJ(Mat A,Vec xx,Vec yy,Vec zz)
89317ab2063SBarry Smith {
894416022c9SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data;
89517ab2063SBarry Smith   Scalar     *x, *y, *z, *v, sum;
896e1311b90SBarry Smith   int        ierr,m = a->m, *idx, shift = a->indexshift,*ii;
8972e40c62eSSatish Balay #if !defined(USE_FORTRAN_KERNEL_MULTADDAIJ)
898e36a17ebSSatish Balay   int        n,i,jrow,j;
899e36a17ebSSatish Balay #endif
9009ea0dfa2SSatish Balay 
9013a40ed3dSBarry Smith   PetscFunctionBegin;
902e1311b90SBarry Smith   ierr = VecGetArray(xx,&x); CHKERRQ(ierr);
903e1311b90SBarry Smith   ierr = VecGetArray(yy,&y); CHKERRQ(ierr);
9042e8a6d31SBarry Smith   if (zz != yy) {
905e1311b90SBarry Smith     ierr = VecGetArray(zz,&z); CHKERRQ(ierr);
9062e8a6d31SBarry Smith   } else {
9072e8a6d31SBarry Smith     z = y;
9082e8a6d31SBarry Smith   }
90917ab2063SBarry Smith   x    = x + shift; /* shift for Fortran start by 1 indexing */
910cddf8d76SBarry Smith   idx  = a->j;
911d64ed03dSBarry Smith   v    = a->a;
912cddf8d76SBarry Smith   ii   = a->i;
9132e40c62eSSatish Balay #if defined(USE_FORTRAN_KERNEL_MULTADDAIJ)
91429b5ca8aSSatish Balay   fortranmultaddaij_(&m,x,ii,idx+shift,v+shift,y,z);
91502ab625aSSatish Balay #else
916d64ed03dSBarry Smith   v   += shift; /* shift for Fortran start by 1 indexing */
917d64ed03dSBarry Smith   idx += shift;
91817ab2063SBarry Smith   for ( i=0; i<m; i++ ) {
9199ea0dfa2SSatish Balay     jrow = ii[i];
9209ea0dfa2SSatish Balay     n    = ii[i+1] - jrow;
92117ab2063SBarry Smith     sum  = y[i];
9229ea0dfa2SSatish Balay     for ( j=0; j<n; j++) {
9239ea0dfa2SSatish Balay       sum += v[jrow]*x[idx[jrow]]; jrow++;
9249ea0dfa2SSatish Balay      }
92517ab2063SBarry Smith     z[i] = sum;
92617ab2063SBarry Smith   }
92702ab625aSSatish Balay #endif
928416022c9SBarry Smith   PLogFlops(2*a->nz);
929e1311b90SBarry Smith   ierr = VecRestoreArray(xx,&x); CHKERRQ(ierr);
930e1311b90SBarry Smith   ierr = VecRestoreArray(yy,&y); CHKERRQ(ierr);
9312e8a6d31SBarry Smith   if (zz != yy) {
932e1311b90SBarry Smith     ierr = VecRestoreArray(zz,&z); CHKERRQ(ierr);
9332e8a6d31SBarry Smith   }
9343a40ed3dSBarry Smith   PetscFunctionReturn(0);
93517ab2063SBarry Smith }
93617ab2063SBarry Smith 
93717ab2063SBarry Smith /*
93817ab2063SBarry Smith      Adds diagonal pointers to sparse matrix structure.
93917ab2063SBarry Smith */
94017ab2063SBarry Smith 
9415615d1e5SSatish Balay #undef __FUNC__
9425615d1e5SSatish Balay #define __FUNC__ "MatMarkDiag_SeqAIJ"
943416022c9SBarry Smith int MatMarkDiag_SeqAIJ(Mat A)
94417ab2063SBarry Smith {
945416022c9SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data;
946416022c9SBarry Smith   int        i,j, *diag, m = a->m,shift = a->indexshift;
94717ab2063SBarry Smith 
9483a40ed3dSBarry Smith   PetscFunctionBegin;
9490452661fSBarry Smith   diag = (int *) PetscMalloc( (m+1)*sizeof(int)); CHKPTRQ(diag);
950416022c9SBarry Smith   PLogObjectMemory(A,(m+1)*sizeof(int));
951416022c9SBarry Smith   for ( i=0; i<a->m; i++ ) {
95235b0346bSBarry Smith     diag[i] = a->i[i+1];
953416022c9SBarry Smith     for ( j=a->i[i]+shift; j<a->i[i+1]+shift; j++ ) {
954416022c9SBarry Smith       if (a->j[j]+shift == i) {
95517ab2063SBarry Smith         diag[i] = j - shift;
95617ab2063SBarry Smith         break;
95717ab2063SBarry Smith       }
95817ab2063SBarry Smith     }
95917ab2063SBarry Smith   }
960416022c9SBarry Smith   a->diag = diag;
9613a40ed3dSBarry Smith   PetscFunctionReturn(0);
96217ab2063SBarry Smith }
96317ab2063SBarry Smith 
9645615d1e5SSatish Balay #undef __FUNC__
9655615d1e5SSatish Balay #define __FUNC__ "MatRelax_SeqAIJ"
96644cd7ae7SLois Curfman McInnes int MatRelax_SeqAIJ(Mat A,Vec bb,double omega,MatSORType flag,
96717ab2063SBarry Smith                            double fshift,int its,Vec xx)
96817ab2063SBarry Smith {
969416022c9SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data;
970416022c9SBarry Smith   Scalar     *x, *b, *bs,  d, *xs, sum, *v = a->a,*t,scale,*ts, *xb;
971d5d45c9bSBarry Smith   int        ierr, *idx, *diag,n = a->n, m = a->m, i, shift = a->indexshift;
97217ab2063SBarry Smith 
9733a40ed3dSBarry Smith   PetscFunctionBegin;
974e1311b90SBarry Smith   ierr = VecGetArray(xx,&x); CHKERRQ(ierr);
975fb2e594dSBarry Smith   if (xx != bb) {
976e1311b90SBarry Smith     ierr = VecGetArray(bb,&b);CHKERRQ(ierr);
977fb2e594dSBarry Smith   } else {
978fb2e594dSBarry Smith     b = x;
979fb2e594dSBarry Smith   }
980fb2e594dSBarry Smith 
981d00d2cf4SBarry Smith   if (!a->diag) {ierr = MatMarkDiag_SeqAIJ(A);CHKERRQ(ierr);}
982416022c9SBarry Smith   diag = a->diag;
983416022c9SBarry Smith   xs   = x + shift; /* shifted by one for index start of a or a->j*/
98417ab2063SBarry Smith   if (flag == SOR_APPLY_UPPER) {
98517ab2063SBarry Smith    /* apply ( U + D/omega) to the vector */
98617ab2063SBarry Smith     bs = b + shift;
98717ab2063SBarry Smith     for ( i=0; i<m; i++ ) {
988416022c9SBarry Smith         d    = fshift + a->a[diag[i] + shift];
989416022c9SBarry Smith         n    = a->i[i+1] - diag[i] - 1;
990488ecbafSBarry Smith 	PLogFlops(2*n-1);
991416022c9SBarry Smith         idx  = a->j + diag[i] + (!shift);
992416022c9SBarry Smith         v    = a->a + diag[i] + (!shift);
99317ab2063SBarry Smith         sum  = b[i]*d/omega;
99417ab2063SBarry Smith         SPARSEDENSEDOT(sum,bs,v,idx,n);
99517ab2063SBarry Smith         x[i] = sum;
99617ab2063SBarry Smith     }
997cb5b572fSBarry Smith     ierr = VecRestoreArray(xx,&x); CHKERRQ(ierr);
998fb2e594dSBarry Smith     if (bb != xx) {ierr = VecRestoreArray(bb,&b);CHKERRQ(ierr);}
9993a40ed3dSBarry Smith     PetscFunctionReturn(0);
100017ab2063SBarry Smith   }
100117ab2063SBarry Smith   if (flag == SOR_APPLY_LOWER) {
1002a8c6a408SBarry Smith     SETERRQ(PETSC_ERR_SUP,0,"SOR_APPLY_LOWER is not done");
10033a40ed3dSBarry Smith   } else if (flag & SOR_EISENSTAT) {
100417ab2063SBarry Smith     /* Let  A = L + U + D; where L is lower trianglar,
100517ab2063SBarry Smith     U is upper triangular, E is diagonal; This routine applies
100617ab2063SBarry Smith 
100717ab2063SBarry Smith             (L + E)^{-1} A (U + E)^{-1}
100817ab2063SBarry Smith 
100917ab2063SBarry Smith     to a vector efficiently using Eisenstat's trick. This is for
101017ab2063SBarry Smith     the case of SSOR preconditioner, so E is D/omega where omega
101117ab2063SBarry Smith     is the relaxation factor.
101217ab2063SBarry Smith     */
10130452661fSBarry Smith     t = (Scalar *) PetscMalloc( m*sizeof(Scalar) ); CHKPTRQ(t);
101417ab2063SBarry Smith     scale = (2.0/omega) - 1.0;
101517ab2063SBarry Smith 
101617ab2063SBarry Smith     /*  x = (E + U)^{-1} b */
101717ab2063SBarry Smith     for ( i=m-1; i>=0; i-- ) {
1018416022c9SBarry Smith       d    = fshift + a->a[diag[i] + shift];
1019416022c9SBarry Smith       n    = a->i[i+1] - diag[i] - 1;
1020488ecbafSBarry Smith       PLogFlops(2*n-1);
1021416022c9SBarry Smith       idx  = a->j + diag[i] + (!shift);
1022416022c9SBarry Smith       v    = a->a + diag[i] + (!shift);
102317ab2063SBarry Smith       sum  = b[i];
102417ab2063SBarry Smith       SPARSEDENSEMDOT(sum,xs,v,idx,n);
102517ab2063SBarry Smith       x[i] = omega*(sum/d);
102617ab2063SBarry Smith     }
102717ab2063SBarry Smith 
102817ab2063SBarry Smith     /*  t = b - (2*E - D)x */
1029416022c9SBarry Smith     v = a->a;
103017ab2063SBarry Smith     for ( i=0; i<m; i++ ) { t[i] = b[i] - scale*(v[*diag++ + shift])*x[i]; }
1031488ecbafSBarry Smith     PLogFlops(2*m);
1032488ecbafSBarry Smith 
103317ab2063SBarry Smith 
103417ab2063SBarry Smith     /*  t = (E + L)^{-1}t */
1035416022c9SBarry Smith     ts = t + shift; /* shifted by one for index start of a or a->j*/
1036416022c9SBarry Smith     diag = a->diag;
103717ab2063SBarry Smith     for ( i=0; i<m; i++ ) {
1038416022c9SBarry Smith       d    = fshift + a->a[diag[i]+shift];
1039416022c9SBarry Smith       n    = diag[i] - a->i[i];
1040488ecbafSBarry Smith       PLogFlops(2*n-1);
1041416022c9SBarry Smith       idx  = a->j + a->i[i] + shift;
1042416022c9SBarry Smith       v    = a->a + a->i[i] + shift;
104317ab2063SBarry Smith       sum  = t[i];
104417ab2063SBarry Smith       SPARSEDENSEMDOT(sum,ts,v,idx,n);
104517ab2063SBarry Smith       t[i] = omega*(sum/d);
104617ab2063SBarry Smith     }
104717ab2063SBarry Smith 
104817ab2063SBarry Smith     /*  x = x + t */
104917ab2063SBarry Smith     for ( i=0; i<m; i++ ) { x[i] += t[i]; }
10500452661fSBarry Smith     PetscFree(t);
1051cb5b572fSBarry Smith     ierr = VecRestoreArray(xx,&x); CHKERRQ(ierr);
1052fb2e594dSBarry Smith     if (bb != xx) {ierr = VecRestoreArray(bb,&b);CHKERRQ(ierr);}
10533a40ed3dSBarry Smith     PetscFunctionReturn(0);
105417ab2063SBarry Smith   }
105517ab2063SBarry Smith   if (flag & SOR_ZERO_INITIAL_GUESS) {
105617ab2063SBarry Smith     if (flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP){
105717ab2063SBarry Smith       for ( i=0; i<m; i++ ) {
1058416022c9SBarry Smith         d    = fshift + a->a[diag[i]+shift];
1059416022c9SBarry Smith         n    = diag[i] - a->i[i];
1060488ecbafSBarry Smith 	PLogFlops(2*n-1);
1061416022c9SBarry Smith         idx  = a->j + a->i[i] + shift;
1062416022c9SBarry Smith         v    = a->a + a->i[i] + shift;
106317ab2063SBarry Smith         sum  = b[i];
106417ab2063SBarry Smith         SPARSEDENSEMDOT(sum,xs,v,idx,n);
106517ab2063SBarry Smith         x[i] = omega*(sum/d);
106617ab2063SBarry Smith       }
106717ab2063SBarry Smith       xb = x;
10683a40ed3dSBarry Smith     } else xb = b;
106917ab2063SBarry Smith     if ((flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP) &&
107017ab2063SBarry Smith         (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP)) {
107117ab2063SBarry Smith       for ( i=0; i<m; i++ ) {
1072416022c9SBarry Smith         x[i] *= a->a[diag[i]+shift];
107317ab2063SBarry Smith       }
1074488ecbafSBarry Smith       PLogFlops(m);
107517ab2063SBarry Smith     }
107617ab2063SBarry Smith     if (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP){
107717ab2063SBarry Smith       for ( i=m-1; i>=0; i-- ) {
1078416022c9SBarry Smith         d    = fshift + a->a[diag[i] + shift];
1079416022c9SBarry Smith         n    = a->i[i+1] - diag[i] - 1;
1080488ecbafSBarry Smith 	PLogFlops(2*n-1);
1081416022c9SBarry Smith         idx  = a->j + diag[i] + (!shift);
1082416022c9SBarry Smith         v    = a->a + diag[i] + (!shift);
108317ab2063SBarry Smith         sum  = xb[i];
108417ab2063SBarry Smith         SPARSEDENSEMDOT(sum,xs,v,idx,n);
108517ab2063SBarry Smith         x[i] = omega*(sum/d);
108617ab2063SBarry Smith       }
108717ab2063SBarry Smith     }
108817ab2063SBarry Smith     its--;
108917ab2063SBarry Smith   }
109017ab2063SBarry Smith   while (its--) {
109117ab2063SBarry Smith     if (flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP){
109217ab2063SBarry Smith       for ( i=0; i<m; i++ ) {
1093416022c9SBarry Smith         d    = fshift + a->a[diag[i]+shift];
1094416022c9SBarry Smith         n    = a->i[i+1] - a->i[i];
1095488ecbafSBarry Smith 	PLogFlops(2*n-1);
1096416022c9SBarry Smith         idx  = a->j + a->i[i] + shift;
1097416022c9SBarry Smith         v    = a->a + a->i[i] + shift;
109817ab2063SBarry Smith         sum  = b[i];
109917ab2063SBarry Smith         SPARSEDENSEMDOT(sum,xs,v,idx,n);
11007e33a6baSBarry Smith         x[i] = (1. - omega)*x[i] + omega*(sum + a->a[diag[i]+shift]*x[i])/d;
110117ab2063SBarry Smith       }
110217ab2063SBarry Smith     }
110317ab2063SBarry Smith     if (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP){
110417ab2063SBarry Smith       for ( i=m-1; i>=0; i-- ) {
1105416022c9SBarry Smith         d    = fshift + a->a[diag[i] + shift];
1106416022c9SBarry Smith         n    = a->i[i+1] - a->i[i];
1107488ecbafSBarry Smith 	PLogFlops(2*n-1);
1108416022c9SBarry Smith         idx  = a->j + a->i[i] + shift;
1109416022c9SBarry Smith         v    = a->a + a->i[i] + shift;
111017ab2063SBarry Smith         sum  = b[i];
111117ab2063SBarry Smith         SPARSEDENSEMDOT(sum,xs,v,idx,n);
11127e33a6baSBarry Smith         x[i] = (1. - omega)*x[i] + omega*(sum + a->a[diag[i]+shift]*x[i])/d;
111317ab2063SBarry Smith       }
111417ab2063SBarry Smith     }
111517ab2063SBarry Smith   }
1116cb5b572fSBarry Smith   ierr = VecRestoreArray(xx,&x); CHKERRQ(ierr);
1117fb2e594dSBarry Smith   if (bb != xx) {ierr = VecRestoreArray(bb,&b);CHKERRQ(ierr);}
11183a40ed3dSBarry Smith   PetscFunctionReturn(0);
111917ab2063SBarry Smith }
112017ab2063SBarry Smith 
11215615d1e5SSatish Balay #undef __FUNC__
11225615d1e5SSatish Balay #define __FUNC__ "MatGetInfo_SeqAIJ"
11238f6be9afSLois Curfman McInnes int MatGetInfo_SeqAIJ(Mat A,MatInfoType flag,MatInfo *info)
112417ab2063SBarry Smith {
1125416022c9SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data;
11264e220ebcSLois Curfman McInnes 
11273a40ed3dSBarry Smith   PetscFunctionBegin;
11284e220ebcSLois Curfman McInnes   info->rows_global    = (double)a->m;
11294e220ebcSLois Curfman McInnes   info->columns_global = (double)a->n;
11304e220ebcSLois Curfman McInnes   info->rows_local     = (double)a->m;
11314e220ebcSLois Curfman McInnes   info->columns_local  = (double)a->n;
11324e220ebcSLois Curfman McInnes   info->block_size     = 1.0;
11334e220ebcSLois Curfman McInnes   info->nz_allocated   = (double)a->maxnz;
11344e220ebcSLois Curfman McInnes   info->nz_used        = (double)a->nz;
11354e220ebcSLois Curfman McInnes   info->nz_unneeded    = (double)(a->maxnz - a->nz);
11364e220ebcSLois Curfman McInnes   info->assemblies     = (double)A->num_ass;
11374e220ebcSLois Curfman McInnes   info->mallocs        = (double)a->reallocs;
11384e220ebcSLois Curfman McInnes   info->memory         = A->mem;
11394e220ebcSLois Curfman McInnes   if (A->factor) {
11404e220ebcSLois Curfman McInnes     info->fill_ratio_given  = A->info.fill_ratio_given;
11414e220ebcSLois Curfman McInnes     info->fill_ratio_needed = A->info.fill_ratio_needed;
11424e220ebcSLois Curfman McInnes     info->factor_mallocs    = A->info.factor_mallocs;
11434e220ebcSLois Curfman McInnes   } else {
11444e220ebcSLois Curfman McInnes     info->fill_ratio_given  = 0;
11454e220ebcSLois Curfman McInnes     info->fill_ratio_needed = 0;
11464e220ebcSLois Curfman McInnes     info->factor_mallocs    = 0;
11474e220ebcSLois Curfman McInnes   }
11483a40ed3dSBarry Smith   PetscFunctionReturn(0);
114917ab2063SBarry Smith }
115017ab2063SBarry Smith 
115117ab2063SBarry Smith extern int MatLUFactorSymbolic_SeqAIJ(Mat,IS,IS,double,Mat*);
115217ab2063SBarry Smith extern int MatLUFactorNumeric_SeqAIJ(Mat,Mat*);
115317ab2063SBarry Smith extern int MatLUFactor_SeqAIJ(Mat,IS,IS,double);
115417ab2063SBarry Smith extern int MatSolve_SeqAIJ(Mat,Vec,Vec);
115517ab2063SBarry Smith extern int MatSolveAdd_SeqAIJ(Mat,Vec,Vec,Vec);
115617ab2063SBarry Smith extern int MatSolveTrans_SeqAIJ(Mat,Vec,Vec);
115717ab2063SBarry Smith extern int MatSolveTransAdd_SeqAIJ(Mat,Vec,Vec,Vec);
115817ab2063SBarry Smith 
11595615d1e5SSatish Balay #undef __FUNC__
11605615d1e5SSatish Balay #define __FUNC__ "MatZeroRows_SeqAIJ"
11618f6be9afSLois Curfman McInnes int MatZeroRows_SeqAIJ(Mat A,IS is,Scalar *diag)
116217ab2063SBarry Smith {
1163416022c9SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data;
1164416022c9SBarry Smith   int         i,ierr,N, *rows,m = a->m - 1,shift = a->indexshift;
116517ab2063SBarry Smith 
11663a40ed3dSBarry Smith   PetscFunctionBegin;
116777c4ece6SBarry Smith   ierr = ISGetSize(is,&N); CHKERRQ(ierr);
116817ab2063SBarry Smith   ierr = ISGetIndices(is,&rows); CHKERRQ(ierr);
116917ab2063SBarry Smith   if (diag) {
117017ab2063SBarry Smith     for ( i=0; i<N; i++ ) {
1171a8c6a408SBarry Smith       if (rows[i] < 0 || rows[i] > m) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"row out of range");
1172416022c9SBarry Smith       if (a->ilen[rows[i]] > 0) { /* in case row was completely empty */
1173416022c9SBarry Smith         a->ilen[rows[i]] = 1;
1174416022c9SBarry Smith         a->a[a->i[rows[i]]+shift] = *diag;
1175416022c9SBarry Smith         a->j[a->i[rows[i]]+shift] = rows[i]+shift;
11763a40ed3dSBarry Smith       } else {
1177d64ed03dSBarry Smith         ierr = MatSetValues_SeqAIJ(A,1,&rows[i],1,&rows[i],diag,INSERT_VALUES);CHKERRQ(ierr);
117817ab2063SBarry Smith       }
117917ab2063SBarry Smith     }
11803a40ed3dSBarry Smith   } else {
118117ab2063SBarry Smith     for ( i=0; i<N; i++ ) {
1182a8c6a408SBarry Smith       if (rows[i] < 0 || rows[i] > m) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"row out of range");
1183416022c9SBarry Smith       a->ilen[rows[i]] = 0;
118417ab2063SBarry Smith     }
118517ab2063SBarry Smith   }
118617ab2063SBarry Smith   ISRestoreIndices(is,&rows);
118743a90d84SBarry Smith   ierr = MatAssemblyEnd_SeqAIJ(A,MAT_FINAL_ASSEMBLY); CHKERRQ(ierr);
11883a40ed3dSBarry Smith   PetscFunctionReturn(0);
118917ab2063SBarry Smith }
119017ab2063SBarry Smith 
11915615d1e5SSatish Balay #undef __FUNC__
11925615d1e5SSatish Balay #define __FUNC__ "MatGetSize_SeqAIJ"
11938f6be9afSLois Curfman McInnes int MatGetSize_SeqAIJ(Mat A,int *m,int *n)
119417ab2063SBarry Smith {
1195416022c9SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data;
11963a40ed3dSBarry Smith 
11973a40ed3dSBarry Smith   PetscFunctionBegin;
11980752156aSBarry Smith   if (m) *m = a->m;
11990752156aSBarry Smith   if (n) *n = a->n;
12003a40ed3dSBarry Smith   PetscFunctionReturn(0);
120117ab2063SBarry Smith }
120217ab2063SBarry Smith 
12035615d1e5SSatish Balay #undef __FUNC__
12045615d1e5SSatish Balay #define __FUNC__ "MatGetOwnershipRange_SeqAIJ"
12058f6be9afSLois Curfman McInnes int MatGetOwnershipRange_SeqAIJ(Mat A,int *m,int *n)
120617ab2063SBarry Smith {
1207416022c9SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data;
12083a40ed3dSBarry Smith 
12093a40ed3dSBarry Smith   PetscFunctionBegin;
1210416022c9SBarry Smith   *m = 0; *n = a->m;
12113a40ed3dSBarry Smith   PetscFunctionReturn(0);
121217ab2063SBarry Smith }
1213026e39d0SSatish Balay 
12145615d1e5SSatish Balay #undef __FUNC__
12155615d1e5SSatish Balay #define __FUNC__ "MatGetRow_SeqAIJ"
12164e093b46SBarry Smith int MatGetRow_SeqAIJ(Mat A,int row,int *nz,int **idx,Scalar **v)
121717ab2063SBarry Smith {
1218416022c9SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data;
1219c456f294SBarry Smith   int        *itmp,i,shift = a->indexshift;
122017ab2063SBarry Smith 
12213a40ed3dSBarry Smith   PetscFunctionBegin;
1222a8c6a408SBarry Smith   if (row < 0 || row >= a->m) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Row out of range");
122317ab2063SBarry Smith 
1224416022c9SBarry Smith   *nz = a->i[row+1] - a->i[row];
1225416022c9SBarry Smith   if (v) *v = a->a + a->i[row] + shift;
122617ab2063SBarry Smith   if (idx) {
1227416022c9SBarry Smith     itmp = a->j + a->i[row] + shift;
12284e093b46SBarry Smith     if (*nz && shift) {
12290452661fSBarry Smith       *idx = (int *) PetscMalloc( (*nz)*sizeof(int) ); CHKPTRQ(*idx);
123017ab2063SBarry Smith       for ( i=0; i<(*nz); i++ ) {(*idx)[i] = itmp[i] + shift;}
12314e093b46SBarry Smith     } else if (*nz) {
12324e093b46SBarry Smith       *idx = itmp;
123317ab2063SBarry Smith     }
123417ab2063SBarry Smith     else *idx = 0;
123517ab2063SBarry Smith   }
12363a40ed3dSBarry Smith   PetscFunctionReturn(0);
123717ab2063SBarry Smith }
123817ab2063SBarry Smith 
12395615d1e5SSatish Balay #undef __FUNC__
12405615d1e5SSatish Balay #define __FUNC__ "MatRestoreRow_SeqAIJ"
12414e093b46SBarry Smith int MatRestoreRow_SeqAIJ(Mat A,int row,int *nz,int **idx,Scalar **v)
124217ab2063SBarry Smith {
12434e093b46SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data;
12443a40ed3dSBarry Smith 
12453a40ed3dSBarry Smith   PetscFunctionBegin;
12464e093b46SBarry Smith   if (idx) {if (*idx && a->indexshift) PetscFree(*idx);}
12473a40ed3dSBarry Smith   PetscFunctionReturn(0);
124817ab2063SBarry Smith }
124917ab2063SBarry Smith 
12505615d1e5SSatish Balay #undef __FUNC__
12515615d1e5SSatish Balay #define __FUNC__ "MatNorm_SeqAIJ"
12528f6be9afSLois Curfman McInnes int MatNorm_SeqAIJ(Mat A,NormType type,double *norm)
125317ab2063SBarry Smith {
1254416022c9SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data;
1255416022c9SBarry Smith   Scalar     *v = a->a;
125617ab2063SBarry Smith   double     sum = 0.0;
1257416022c9SBarry Smith   int        i, j,shift = a->indexshift;
125817ab2063SBarry Smith 
12593a40ed3dSBarry Smith   PetscFunctionBegin;
126017ab2063SBarry Smith   if (type == NORM_FROBENIUS) {
1261416022c9SBarry Smith     for (i=0; i<a->nz; i++ ) {
12623a40ed3dSBarry Smith #if defined(USE_PETSC_COMPLEX)
1263e20fef11SSatish Balay       sum += PetscReal(PetscConj(*v)*(*v)); v++;
126417ab2063SBarry Smith #else
126517ab2063SBarry Smith       sum += (*v)*(*v); v++;
126617ab2063SBarry Smith #endif
126717ab2063SBarry Smith     }
126817ab2063SBarry Smith     *norm = sqrt(sum);
12693a40ed3dSBarry Smith   } else if (type == NORM_1) {
127017ab2063SBarry Smith     double *tmp;
1271416022c9SBarry Smith     int    *jj = a->j;
127266963ce1SSatish Balay     tmp = (double *) PetscMalloc( (a->n+1)*sizeof(double) ); CHKPTRQ(tmp);
1273cddf8d76SBarry Smith     PetscMemzero(tmp,a->n*sizeof(double));
127417ab2063SBarry Smith     *norm = 0.0;
1275416022c9SBarry Smith     for ( j=0; j<a->nz; j++ ) {
1276a2744918SBarry Smith         tmp[*jj++ + shift] += PetscAbsScalar(*v);  v++;
127717ab2063SBarry Smith     }
1278416022c9SBarry Smith     for ( j=0; j<a->n; j++ ) {
127917ab2063SBarry Smith       if (tmp[j] > *norm) *norm = tmp[j];
128017ab2063SBarry Smith     }
12810452661fSBarry Smith     PetscFree(tmp);
12823a40ed3dSBarry Smith   } else if (type == NORM_INFINITY) {
128317ab2063SBarry Smith     *norm = 0.0;
1284416022c9SBarry Smith     for ( j=0; j<a->m; j++ ) {
1285416022c9SBarry Smith       v = a->a + a->i[j] + shift;
128617ab2063SBarry Smith       sum = 0.0;
1287416022c9SBarry Smith       for ( i=0; i<a->i[j+1]-a->i[j]; i++ ) {
1288cddf8d76SBarry Smith         sum += PetscAbsScalar(*v); v++;
128917ab2063SBarry Smith       }
129017ab2063SBarry Smith       if (sum > *norm) *norm = sum;
129117ab2063SBarry Smith     }
12923a40ed3dSBarry Smith   } else {
1293a8c6a408SBarry Smith     SETERRQ(PETSC_ERR_SUP,0,"No support for two norm");
129417ab2063SBarry Smith   }
12953a40ed3dSBarry Smith   PetscFunctionReturn(0);
129617ab2063SBarry Smith }
129717ab2063SBarry Smith 
12985615d1e5SSatish Balay #undef __FUNC__
12995615d1e5SSatish Balay #define __FUNC__ "MatTranspose_SeqAIJ"
13008f6be9afSLois Curfman McInnes int MatTranspose_SeqAIJ(Mat A,Mat *B)
130117ab2063SBarry Smith {
1302416022c9SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data;
1303416022c9SBarry Smith   Mat        C;
1304416022c9SBarry Smith   int        i, ierr, *aj = a->j, *ai = a->i, m = a->m, len, *col;
1305416022c9SBarry Smith   int        shift = a->indexshift;
1306d5d45c9bSBarry Smith   Scalar     *array = a->a;
130717ab2063SBarry Smith 
13083a40ed3dSBarry Smith   PetscFunctionBegin;
1309a8c6a408SBarry Smith   if (B == PETSC_NULL && m != a->n) SETERRQ(PETSC_ERR_ARG_SIZ,0,"Square matrix only for in-place");
13100452661fSBarry Smith   col = (int *) PetscMalloc((1+a->n)*sizeof(int)); CHKPTRQ(col);
1311cddf8d76SBarry Smith   PetscMemzero(col,(1+a->n)*sizeof(int));
131217ab2063SBarry Smith   if (shift) {
131317ab2063SBarry Smith     for ( i=0; i<ai[m]-1; i++ ) aj[i] -= 1;
131417ab2063SBarry Smith   }
131517ab2063SBarry Smith   for ( i=0; i<ai[m]+shift; i++ ) col[aj[i]] += 1;
1316416022c9SBarry Smith   ierr = MatCreateSeqAIJ(A->comm,a->n,m,0,col,&C); CHKERRQ(ierr);
13170452661fSBarry Smith   PetscFree(col);
131817ab2063SBarry Smith   for ( i=0; i<m; i++ ) {
131917ab2063SBarry Smith     len = ai[i+1]-ai[i];
1320416022c9SBarry Smith     ierr = MatSetValues(C,len,aj,1,&i,array,INSERT_VALUES); CHKERRQ(ierr);
132117ab2063SBarry Smith     array += len; aj += len;
132217ab2063SBarry Smith   }
132317ab2063SBarry Smith   if (shift) {
132417ab2063SBarry Smith     for ( i=0; i<ai[m]-1; i++ ) aj[i] += 1;
132517ab2063SBarry Smith   }
132617ab2063SBarry Smith 
13276d4a8577SBarry Smith   ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY); CHKERRQ(ierr);
13286d4a8577SBarry Smith   ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY); CHKERRQ(ierr);
132917ab2063SBarry Smith 
13303638b69dSLois Curfman McInnes   if (B != PETSC_NULL) {
1331416022c9SBarry Smith     *B = C;
133217ab2063SBarry Smith   } else {
1333f830108cSBarry Smith     PetscOps *Abops;
13340a6ffc59SBarry Smith     MatOps   Aops;
1335f830108cSBarry Smith 
1336416022c9SBarry Smith     /* This isn't really an in-place transpose */
13370452661fSBarry Smith     PetscFree(a->a);
13380452661fSBarry Smith     if (!a->singlemalloc) {PetscFree(a->i); PetscFree(a->j);}
13390452661fSBarry Smith     if (a->diag) PetscFree(a->diag);
13400452661fSBarry Smith     if (a->ilen) PetscFree(a->ilen);
13410452661fSBarry Smith     if (a->imax) PetscFree(a->imax);
13420452661fSBarry Smith     if (a->solve_work) PetscFree(a->solve_work);
13431073c447SSatish Balay     if (a->inode.size) PetscFree(a->inode.size);
13440452661fSBarry Smith     PetscFree(a);
1345f830108cSBarry Smith 
1346488ecbafSBarry Smith 
1347488ecbafSBarry Smith     ierr = MapDestroy(A->rmap);CHKERRQ(ierr);
1348488ecbafSBarry Smith     ierr = MapDestroy(A->cmap);CHKERRQ(ierr);
1349488ecbafSBarry Smith 
1350f830108cSBarry Smith     /*
1351f830108cSBarry Smith       This is horrible, horrible code. We need to keep the
13528f0f457cSSatish Balay       the bops and ops Structures, copy everything from C
13538f0f457cSSatish Balay       including the function pointers..
1354f830108cSBarry Smith     */
13558f0f457cSSatish Balay     PetscMemcpy(A->ops,C->ops,sizeof(struct _MatOps));
13568f0f457cSSatish Balay     PetscMemcpy(A->bops,C->bops,sizeof(PetscOps));
1357f830108cSBarry Smith     Abops    = A->bops;
1358f830108cSBarry Smith     Aops     = A->ops;
1359f09e8eb9SSatish Balay     PetscMemcpy(A,C,sizeof(struct _p_Mat));
1360f830108cSBarry Smith     A->bops  = Abops;
1361f830108cSBarry Smith     A->ops   = Aops;
136227a8da17SBarry Smith     A->qlist = 0;
1363f830108cSBarry Smith 
13640452661fSBarry Smith     PetscHeaderDestroy(C);
136517ab2063SBarry Smith   }
13663a40ed3dSBarry Smith   PetscFunctionReturn(0);
136717ab2063SBarry Smith }
136817ab2063SBarry Smith 
13695615d1e5SSatish Balay #undef __FUNC__
13705615d1e5SSatish Balay #define __FUNC__ "MatDiagonalScale_SeqAIJ"
13718f6be9afSLois Curfman McInnes int MatDiagonalScale_SeqAIJ(Mat A,Vec ll,Vec rr)
137217ab2063SBarry Smith {
1373416022c9SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data;
137417ab2063SBarry Smith   Scalar     *l,*r,x,*v;
1375e1311b90SBarry Smith   int        ierr,i,j,m = a->m, n = a->n, M, nz = a->nz, *jj,shift = a->indexshift;
137617ab2063SBarry Smith 
13773a40ed3dSBarry Smith   PetscFunctionBegin;
137817ab2063SBarry Smith   if (ll) {
13793ea7c6a1SSatish Balay     /* The local size is used so that VecMPI can be passed to this routine
13803ea7c6a1SSatish Balay        by MatDiagonalScale_MPIAIJ */
1381e1311b90SBarry Smith     ierr = VecGetLocalSize(ll,&m);CHKERRQ(ierr);
1382a8c6a408SBarry Smith     if (m != a->m) SETERRQ(PETSC_ERR_ARG_SIZ,0,"Left scaling vector wrong length");
1383e1311b90SBarry Smith     ierr = VecGetArray(ll,&l); CHKERRQ(ierr);
1384416022c9SBarry Smith     v = a->a;
138517ab2063SBarry Smith     for ( i=0; i<m; i++ ) {
138617ab2063SBarry Smith       x = l[i];
1387416022c9SBarry Smith       M = a->i[i+1] - a->i[i];
138817ab2063SBarry Smith       for ( j=0; j<M; j++ ) { (*v++) *= x;}
138917ab2063SBarry Smith     }
1390e1311b90SBarry Smith     ierr = VecRestoreArray(ll,&l); CHKERRQ(ierr);
139144cd7ae7SLois Curfman McInnes     PLogFlops(nz);
139217ab2063SBarry Smith   }
139317ab2063SBarry Smith   if (rr) {
1394e1311b90SBarry Smith     ierr = VecGetLocalSize(rr,&n);CHKERRQ(ierr);
1395a8c6a408SBarry Smith     if (n != a->n) SETERRQ(PETSC_ERR_ARG_SIZ,0,"Right scaling vector wrong length");
1396e1311b90SBarry Smith     ierr = VecGetArray(rr,&r);CHKERRQ(ierr);
1397416022c9SBarry Smith     v = a->a; jj = a->j;
139817ab2063SBarry Smith     for ( i=0; i<nz; i++ ) {
139917ab2063SBarry Smith       (*v++) *= r[*jj++ + shift];
140017ab2063SBarry Smith     }
1401e1311b90SBarry Smith     ierr = VecRestoreArray(rr,&r);CHKERRQ(ierr);
140244cd7ae7SLois Curfman McInnes     PLogFlops(nz);
140317ab2063SBarry Smith   }
14043a40ed3dSBarry Smith   PetscFunctionReturn(0);
140517ab2063SBarry Smith }
140617ab2063SBarry Smith 
14075615d1e5SSatish Balay #undef __FUNC__
14085615d1e5SSatish Balay #define __FUNC__ "MatGetSubMatrix_SeqAIJ"
14096a6a5d1dSBarry Smith int MatGetSubMatrix_SeqAIJ(Mat A,IS isrow,IS iscol,int csize,MatGetSubMatrixCall scall,Mat *B)
141017ab2063SBarry Smith {
1411db02288aSLois Curfman McInnes   Mat_SeqAIJ   *a = (Mat_SeqAIJ *) A->data,*c;
1412d5db1b72SBarry Smith   int          *smap, i, k, kstart, kend, ierr, oldcols = a->n,*lens;
141399141d43SSatish Balay   int          row,mat_i,*mat_j,tcol,first,step,*mat_ilen;
1414a2744918SBarry Smith   register int sum,lensi;
141599141d43SSatish Balay   int          *irow, *icol, nrows, ncols, shift = a->indexshift,*ssmap;
141699141d43SSatish Balay   int          *starts,*j_new,*i_new,*aj = a->j, *ai = a->i,ii,*ailen = a->ilen;
141799141d43SSatish Balay   Scalar       *a_new,*mat_a;
1418416022c9SBarry Smith   Mat          C;
1419fee21e36SBarry Smith   PetscTruth   stride;
142017ab2063SBarry Smith 
14213a40ed3dSBarry Smith   PetscFunctionBegin;
1422d64ed03dSBarry Smith   ierr = ISSorted(isrow,(PetscTruth*)&i);CHKERRQ(ierr);
1423a8c6a408SBarry Smith   if (!i) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,0,"ISrow is not sorted");
1424d64ed03dSBarry Smith   ierr = ISSorted(iscol,(PetscTruth*)&i);CHKERRQ(ierr);
1425a8c6a408SBarry Smith   if (!i) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,0,"IScol is not sorted");
142699141d43SSatish Balay 
142717ab2063SBarry Smith   ierr = ISGetIndices(isrow,&irow); CHKERRQ(ierr);
142817ab2063SBarry Smith   ierr = ISGetSize(isrow,&nrows); CHKERRQ(ierr);
142917ab2063SBarry Smith   ierr = ISGetSize(iscol,&ncols); CHKERRQ(ierr);
143017ab2063SBarry Smith 
1431fee21e36SBarry Smith   ierr = ISStrideGetInfo(iscol,&first,&step); CHKERRQ(ierr);
1432fee21e36SBarry Smith   ierr = ISStride(iscol,&stride); CHKERRQ(ierr);
1433fee21e36SBarry Smith   if (stride && step == 1) {
143402834360SBarry Smith     /* special case of contiguous rows */
143557faeb66SBarry Smith     lens   = (int *) PetscMalloc((ncols+nrows+1)*sizeof(int)); CHKPTRQ(lens);
143602834360SBarry Smith     starts = lens + ncols;
143702834360SBarry Smith     /* loop over new rows determining lens and starting points */
143802834360SBarry Smith     for (i=0; i<nrows; i++) {
1439a2744918SBarry Smith       kstart  = ai[irow[i]]+shift;
1440a2744918SBarry Smith       kend    = kstart + ailen[irow[i]];
144102834360SBarry Smith       for ( k=kstart; k<kend; k++ ) {
1442d8ced48eSBarry Smith         if (aj[k]+shift >= first) {
144302834360SBarry Smith           starts[i] = k;
144402834360SBarry Smith           break;
144502834360SBarry Smith 	}
144602834360SBarry Smith       }
1447a2744918SBarry Smith       sum = 0;
144802834360SBarry Smith       while (k < kend) {
1449d8ced48eSBarry Smith         if (aj[k++]+shift >= first+ncols) break;
1450a2744918SBarry Smith         sum++;
145102834360SBarry Smith       }
1452a2744918SBarry Smith       lens[i] = sum;
145302834360SBarry Smith     }
145402834360SBarry Smith     /* create submatrix */
1455cddf8d76SBarry Smith     if (scall == MAT_REUSE_MATRIX) {
145608480c60SBarry Smith       int n_cols,n_rows;
145708480c60SBarry Smith       ierr = MatGetSize(*B,&n_rows,&n_cols); CHKERRQ(ierr);
1458a8c6a408SBarry Smith       if (n_rows != nrows || n_cols != ncols) SETERRQ(PETSC_ERR_ARG_SIZ,0,"Reused submatrix wrong size");
1459d8ced48eSBarry Smith       ierr = MatZeroEntries(*B); CHKERRQ(ierr);
146008480c60SBarry Smith       C = *B;
14613a40ed3dSBarry Smith     } else {
146202834360SBarry Smith       ierr = MatCreateSeqAIJ(A->comm,nrows,ncols,0,lens,&C);CHKERRQ(ierr);
146308480c60SBarry Smith     }
1464db02288aSLois Curfman McInnes     c = (Mat_SeqAIJ*) C->data;
1465db02288aSLois Curfman McInnes 
146602834360SBarry Smith     /* loop over rows inserting into submatrix */
1467db02288aSLois Curfman McInnes     a_new    = c->a;
1468db02288aSLois Curfman McInnes     j_new    = c->j;
1469db02288aSLois Curfman McInnes     i_new    = c->i;
1470db02288aSLois Curfman McInnes     i_new[0] = -shift;
147102834360SBarry Smith     for (i=0; i<nrows; i++) {
1472a2744918SBarry Smith       ii    = starts[i];
1473a2744918SBarry Smith       lensi = lens[i];
1474a2744918SBarry Smith       for ( k=0; k<lensi; k++ ) {
1475a2744918SBarry Smith         *j_new++ = aj[ii+k] - first;
147602834360SBarry Smith       }
1477a2744918SBarry Smith       PetscMemcpy(a_new,a->a + starts[i],lensi*sizeof(Scalar));
1478a2744918SBarry Smith       a_new      += lensi;
1479a2744918SBarry Smith       i_new[i+1]  = i_new[i] + lensi;
1480a2744918SBarry Smith       c->ilen[i]  = lensi;
148102834360SBarry Smith     }
14820452661fSBarry Smith     PetscFree(lens);
14833a40ed3dSBarry Smith   } else {
148402834360SBarry Smith     ierr = ISGetIndices(iscol,&icol); CHKERRQ(ierr);
14850452661fSBarry Smith     smap  = (int *) PetscMalloc((1+oldcols)*sizeof(int)); CHKPTRQ(smap);
148602834360SBarry Smith     ssmap = smap + shift;
148799141d43SSatish Balay     lens  = (int *) PetscMalloc((1+nrows)*sizeof(int)); CHKPTRQ(lens);
1488cddf8d76SBarry Smith     PetscMemzero(smap,oldcols*sizeof(int));
148917ab2063SBarry Smith     for ( i=0; i<ncols; i++ ) smap[icol[i]] = i+1;
149002834360SBarry Smith     /* determine lens of each row */
149102834360SBarry Smith     for (i=0; i<nrows; i++) {
1492d8ced48eSBarry Smith       kstart  = ai[irow[i]]+shift;
149302834360SBarry Smith       kend    = kstart + a->ilen[irow[i]];
149402834360SBarry Smith       lens[i] = 0;
149502834360SBarry Smith       for ( k=kstart; k<kend; k++ ) {
1496d8ced48eSBarry Smith         if (ssmap[aj[k]]) {
149702834360SBarry Smith           lens[i]++;
149802834360SBarry Smith         }
149902834360SBarry Smith       }
150002834360SBarry Smith     }
150117ab2063SBarry Smith     /* Create and fill new matrix */
1502a2744918SBarry Smith     if (scall == MAT_REUSE_MATRIX) {
150399141d43SSatish Balay       c = (Mat_SeqAIJ *)((*B)->data);
1504a8c6a408SBarry Smith       if (c->m  != nrows || c->n != ncols) SETERRQ(PETSC_ERR_ARG_SIZ,0,"Cannot reuse matrix. wrong size");
150599141d43SSatish Balay       if (PetscMemcmp(c->ilen,lens, c->m *sizeof(int))) {
1506a8c6a408SBarry Smith         SETERRQ(PETSC_ERR_ARG_SIZ,0,"Cannot reuse matrix. wrong no of nonzeros");
150799141d43SSatish Balay       }
150899141d43SSatish Balay       PetscMemzero(c->ilen,c->m*sizeof(int));
150908480c60SBarry Smith       C = *B;
15103a40ed3dSBarry Smith     } else {
151102834360SBarry Smith       ierr = MatCreateSeqAIJ(A->comm,nrows,ncols,0,lens,&C);CHKERRQ(ierr);
151208480c60SBarry Smith     }
151399141d43SSatish Balay     c = (Mat_SeqAIJ *)(C->data);
151417ab2063SBarry Smith     for (i=0; i<nrows; i++) {
151599141d43SSatish Balay       row    = irow[i];
151699141d43SSatish Balay       kstart = ai[row]+shift;
151799141d43SSatish Balay       kend   = kstart + a->ilen[row];
151899141d43SSatish Balay       mat_i  = c->i[i]+shift;
151999141d43SSatish Balay       mat_j  = c->j + mat_i;
152099141d43SSatish Balay       mat_a  = c->a + mat_i;
152199141d43SSatish Balay       mat_ilen = c->ilen + i;
152217ab2063SBarry Smith       for ( k=kstart; k<kend; k++ ) {
152399141d43SSatish Balay         if ((tcol=ssmap[a->j[k]])) {
152499141d43SSatish Balay           *mat_j++ = tcol - (!shift);
152599141d43SSatish Balay           *mat_a++ = a->a[k];
152699141d43SSatish Balay           (*mat_ilen)++;
152799141d43SSatish Balay 
152817ab2063SBarry Smith         }
152917ab2063SBarry Smith       }
153017ab2063SBarry Smith     }
153102834360SBarry Smith     /* Free work space */
153202834360SBarry Smith     ierr = ISRestoreIndices(iscol,&icol); CHKERRQ(ierr);
153399141d43SSatish Balay     PetscFree(smap); PetscFree(lens);
153402834360SBarry Smith   }
15356d4a8577SBarry Smith   ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY); CHKERRQ(ierr);
15366d4a8577SBarry Smith   ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY); CHKERRQ(ierr);
153717ab2063SBarry Smith 
153817ab2063SBarry Smith   ierr = ISRestoreIndices(isrow,&irow); CHKERRQ(ierr);
1539416022c9SBarry Smith   *B = C;
15403a40ed3dSBarry Smith   PetscFunctionReturn(0);
154117ab2063SBarry Smith }
154217ab2063SBarry Smith 
1543a871dcd8SBarry Smith /*
154463b91edcSBarry Smith      note: This can only work for identity for row and col. It would
154563b91edcSBarry Smith    be good to check this and otherwise generate an error.
1546a871dcd8SBarry Smith */
15475615d1e5SSatish Balay #undef __FUNC__
15485615d1e5SSatish Balay #define __FUNC__ "MatILUFactor_SeqAIJ"
15498f6be9afSLois Curfman McInnes int MatILUFactor_SeqAIJ(Mat inA,IS row,IS col,double efill,int fill)
1550a871dcd8SBarry Smith {
155163b91edcSBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ *) inA->data;
155208480c60SBarry Smith   int        ierr;
155363b91edcSBarry Smith   Mat        outA;
155463b91edcSBarry Smith 
15553a40ed3dSBarry Smith   PetscFunctionBegin;
1556a8c6a408SBarry Smith   if (fill != 0) SETERRQ(PETSC_ERR_SUP,0,"Only fill=0 supported");
1557a871dcd8SBarry Smith 
155863b91edcSBarry Smith   outA          = inA;
155963b91edcSBarry Smith   inA->factor   = FACTOR_LU;
156063b91edcSBarry Smith   a->row        = row;
156163b91edcSBarry Smith   a->col        = col;
156263b91edcSBarry Smith 
1563f0ec6fceSSatish Balay   /* Create the invert permutation so that it can be used in MatLUFactorNumeric() */
1564f0ec6fceSSatish Balay   ierr = ISInvertPermutation(col,&(a->icol)); CHKERRQ(ierr);
15651e4dd532SSatish Balay   PLogObjectParent(inA,a->icol);
1566f0ec6fceSSatish Balay 
156794a9d846SBarry Smith   if (!a->solve_work) { /* this matrix may have been factored before */
15680452661fSBarry Smith     a->solve_work = (Scalar *) PetscMalloc( (a->m+1)*sizeof(Scalar));CHKPTRQ(a->solve_work);
156994a9d846SBarry Smith   }
157063b91edcSBarry Smith 
157108480c60SBarry Smith   if (!a->diag) {
157208480c60SBarry Smith     ierr = MatMarkDiag_SeqAIJ(inA); CHKERRQ(ierr);
157363b91edcSBarry Smith   }
157463b91edcSBarry Smith   ierr = MatLUFactorNumeric_SeqAIJ(inA,&outA); CHKERRQ(ierr);
15753a40ed3dSBarry Smith   PetscFunctionReturn(0);
1576a871dcd8SBarry Smith }
1577a871dcd8SBarry Smith 
157874cdf0dfSBarry Smith #include "pinclude/blaslapack.h"
15795615d1e5SSatish Balay #undef __FUNC__
15805615d1e5SSatish Balay #define __FUNC__ "MatScale_SeqAIJ"
15818f6be9afSLois Curfman McInnes int MatScale_SeqAIJ(Scalar *alpha,Mat inA)
1582f0b747eeSBarry Smith {
1583f0b747eeSBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ *) inA->data;
1584f0b747eeSBarry Smith   int        one = 1;
15853a40ed3dSBarry Smith 
15863a40ed3dSBarry Smith   PetscFunctionBegin;
1587f0b747eeSBarry Smith   BLscal_( &a->nz, alpha, a->a, &one );
1588f0b747eeSBarry Smith   PLogFlops(a->nz);
15893a40ed3dSBarry Smith   PetscFunctionReturn(0);
1590f0b747eeSBarry Smith }
1591f0b747eeSBarry Smith 
15925615d1e5SSatish Balay #undef __FUNC__
15935615d1e5SSatish Balay #define __FUNC__ "MatGetSubMatrices_SeqAIJ"
15946a6a5d1dSBarry Smith int MatGetSubMatrices_SeqAIJ(Mat A,int n, IS *irow,IS *icol,MatGetSubMatrixCall scall,Mat **B)
1595cddf8d76SBarry Smith {
1596cddf8d76SBarry Smith   int ierr,i;
1597cddf8d76SBarry Smith 
15983a40ed3dSBarry Smith   PetscFunctionBegin;
1599cddf8d76SBarry Smith   if (scall == MAT_INITIAL_MATRIX) {
16000452661fSBarry Smith     *B = (Mat *) PetscMalloc( (n+1)*sizeof(Mat) ); CHKPTRQ(*B);
1601cddf8d76SBarry Smith   }
1602cddf8d76SBarry Smith 
1603cddf8d76SBarry Smith   for ( i=0; i<n; i++ ) {
16046a6a5d1dSBarry Smith     ierr = MatGetSubMatrix_SeqAIJ(A,irow[i],icol[i],PETSC_DECIDE,scall,&(*B)[i]);CHKERRQ(ierr);
1605cddf8d76SBarry Smith   }
16063a40ed3dSBarry Smith   PetscFunctionReturn(0);
1607cddf8d76SBarry Smith }
1608cddf8d76SBarry Smith 
16095615d1e5SSatish Balay #undef __FUNC__
16105615d1e5SSatish Balay #define __FUNC__ "MatGetBlockSize_SeqAIJ"
16118f6be9afSLois Curfman McInnes int MatGetBlockSize_SeqAIJ(Mat A, int *bs)
16125a838052SSatish Balay {
1613f830108cSBarry Smith   PetscFunctionBegin;
16145a838052SSatish Balay   *bs = 1;
16153a40ed3dSBarry Smith   PetscFunctionReturn(0);
16165a838052SSatish Balay }
16175a838052SSatish Balay 
16185615d1e5SSatish Balay #undef __FUNC__
16195615d1e5SSatish Balay #define __FUNC__ "MatIncreaseOverlap_SeqAIJ"
16208f6be9afSLois Curfman McInnes int MatIncreaseOverlap_SeqAIJ(Mat A, int is_max, IS *is, int ov)
16214dcbc457SBarry Smith {
1622e4d965acSSatish Balay   Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data;
162306763907SSatish Balay   int        shift, row, i,j,k,l,m,n, *idx,ierr, *nidx, isz, val;
16248a047759SSatish Balay   int        start, end, *ai, *aj;
1625bbd702dbSSatish Balay   BT         table;
1626bbd702dbSSatish Balay 
16273a40ed3dSBarry Smith   PetscFunctionBegin;
16288a047759SSatish Balay   shift = a->indexshift;
1629e4d965acSSatish Balay   m     = a->m;
1630e4d965acSSatish Balay   ai    = a->i;
16318a047759SSatish Balay   aj    = a->j+shift;
16328a047759SSatish Balay 
1633a8c6a408SBarry Smith   if (ov < 0)  SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"illegal overlap value used");
163406763907SSatish Balay 
163506763907SSatish Balay   nidx  = (int *) PetscMalloc((m+1)*sizeof(int)); CHKPTRQ(nidx);
1636bbd702dbSSatish Balay   ierr  = BTCreate(m,table); CHKERRQ(ierr);
163706763907SSatish Balay 
1638e4d965acSSatish Balay   for ( i=0; i<is_max; i++ ) {
1639b97fc60eSLois Curfman McInnes     /* Initialize the two local arrays */
1640e4d965acSSatish Balay     isz  = 0;
1641bbd702dbSSatish Balay     BTMemzero(m,table);
1642e4d965acSSatish Balay 
1643e4d965acSSatish Balay     /* Extract the indices, assume there can be duplicate entries */
16444dcbc457SBarry Smith     ierr = ISGetIndices(is[i],&idx);  CHKERRQ(ierr);
164577c4ece6SBarry Smith     ierr = ISGetSize(is[i],&n);  CHKERRQ(ierr);
1646e4d965acSSatish Balay 
1647dd097bc3SLois Curfman McInnes     /* Enter these into the temp arrays. I.e., mark table[row], enter row into new index */
1648e4d965acSSatish Balay     for ( j=0; j<n ; ++j){
1649bbd702dbSSatish Balay       if(!BTLookupSet(table, idx[j])) { nidx[isz++] = idx[j];}
16504dcbc457SBarry Smith     }
165106763907SSatish Balay     ierr = ISRestoreIndices(is[i],&idx);  CHKERRQ(ierr);
165206763907SSatish Balay     ierr = ISDestroy(is[i]); CHKERRQ(ierr);
1653e4d965acSSatish Balay 
165404a348a9SBarry Smith     k = 0;
165504a348a9SBarry Smith     for ( j=0; j<ov; j++){ /* for each overlap */
165604a348a9SBarry Smith       n = isz;
165706763907SSatish Balay       for ( ; k<n ; k++){ /* do only those rows in nidx[k], which are not done yet */
1658e4d965acSSatish Balay         row   = nidx[k];
1659e4d965acSSatish Balay         start = ai[row];
1660e4d965acSSatish Balay         end   = ai[row+1];
166104a348a9SBarry Smith         for ( l = start; l<end ; l++){
16628a047759SSatish Balay           val = aj[l] + shift;
16632a8f2162SSatish Balay           if (!BTLookupSet(table,val)) {nidx[isz++] = val;}
1664e4d965acSSatish Balay         }
1665e4d965acSSatish Balay       }
1666e4d965acSSatish Balay     }
1667029af93fSBarry Smith     ierr = ISCreateGeneral(PETSC_COMM_SELF, isz, nidx, (is+i)); CHKERRQ(ierr);
1668e4d965acSSatish Balay   }
1669bbd702dbSSatish Balay   BTDestroy(table);
167006763907SSatish Balay   PetscFree(nidx);
16713a40ed3dSBarry Smith   PetscFunctionReturn(0);
16724dcbc457SBarry Smith }
167317ab2063SBarry Smith 
16740513a670SBarry Smith /* -------------------------------------------------------------- */
16750513a670SBarry Smith #undef __FUNC__
16760513a670SBarry Smith #define __FUNC__ "MatPermute_SeqAIJ"
16770513a670SBarry Smith int MatPermute_SeqAIJ(Mat A, IS rowp, IS colp, Mat *B)
16780513a670SBarry Smith {
16790513a670SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data;
16800513a670SBarry Smith   Scalar     *vwork;
16810513a670SBarry Smith   int        i, ierr, nz, m = a->m, n = a->n, *cwork;
16820513a670SBarry Smith   int        *row,*col,*cnew,j,*lens;
168356cd22aeSBarry Smith   IS         icolp,irowp;
16840513a670SBarry Smith 
16853a40ed3dSBarry Smith   PetscFunctionBegin;
168656cd22aeSBarry Smith   ierr = ISInvertPermutation(rowp,&irowp); CHKERRQ(ierr);
168756cd22aeSBarry Smith   ierr = ISGetIndices(irowp,&row); CHKERRQ(ierr);
168856cd22aeSBarry Smith   ierr = ISInvertPermutation(colp,&icolp); CHKERRQ(ierr);
168956cd22aeSBarry Smith   ierr = ISGetIndices(icolp,&col); CHKERRQ(ierr);
16900513a670SBarry Smith 
16910513a670SBarry Smith   /* determine lengths of permuted rows */
16920513a670SBarry Smith   lens = (int *) PetscMalloc( (m+1)*sizeof(int) ); CHKPTRQ(lens);
16930513a670SBarry Smith   for (i=0; i<m; i++ ) {
16940513a670SBarry Smith     lens[row[i]] = a->i[i+1] - a->i[i];
16950513a670SBarry Smith   }
16960513a670SBarry Smith   ierr = MatCreateSeqAIJ(A->comm,m,n,0,lens,B);CHKERRQ(ierr);
16970513a670SBarry Smith   PetscFree(lens);
16980513a670SBarry Smith 
16990513a670SBarry Smith   cnew = (int *) PetscMalloc( n*sizeof(int) ); CHKPTRQ(cnew);
17000513a670SBarry Smith   for (i=0; i<m; i++) {
17010513a670SBarry Smith     ierr = MatGetRow(A,i,&nz,&cwork,&vwork); CHKERRQ(ierr);
17020513a670SBarry Smith     for (j=0; j<nz; j++ ) { cnew[j] = col[cwork[j]];}
17030513a670SBarry Smith     ierr = MatSetValues(*B,1,&row[i],nz,cnew,vwork,INSERT_VALUES); CHKERRQ(ierr);
17040513a670SBarry Smith     ierr = MatRestoreRow(A,i,&nz,&cwork,&vwork); CHKERRQ(ierr);
17050513a670SBarry Smith   }
17060513a670SBarry Smith   PetscFree(cnew);
17070513a670SBarry Smith   ierr = MatAssemblyBegin(*B,MAT_FINAL_ASSEMBLY); CHKERRQ(ierr);
17080513a670SBarry Smith   ierr = MatAssemblyEnd(*B,MAT_FINAL_ASSEMBLY); CHKERRQ(ierr);
170956cd22aeSBarry Smith   ierr = ISRestoreIndices(irowp,&row); CHKERRQ(ierr);
171056cd22aeSBarry Smith   ierr = ISRestoreIndices(icolp,&col); CHKERRQ(ierr);
171156cd22aeSBarry Smith   ierr = ISDestroy(irowp); CHKERRQ(ierr);
171256cd22aeSBarry Smith   ierr = ISDestroy(icolp); CHKERRQ(ierr);
17133a40ed3dSBarry Smith   PetscFunctionReturn(0);
17140513a670SBarry Smith }
17150513a670SBarry Smith 
17165615d1e5SSatish Balay #undef __FUNC__
17175615d1e5SSatish Balay #define __FUNC__ "MatPrintHelp_SeqAIJ"
1718682d7d0cSBarry Smith int MatPrintHelp_SeqAIJ(Mat A)
1719682d7d0cSBarry Smith {
1720682d7d0cSBarry Smith   static int called = 0;
1721682d7d0cSBarry Smith   MPI_Comm   comm = A->comm;
1722682d7d0cSBarry Smith 
17233a40ed3dSBarry Smith   PetscFunctionBegin;
17243a40ed3dSBarry Smith   if (called) {PetscFunctionReturn(0);} else called = 1;
172576be9ce4SBarry Smith   (*PetscHelpPrintf)(comm," Options for MATSEQAIJ and MATMPIAIJ matrix formats (the defaults):\n");
172676be9ce4SBarry Smith   (*PetscHelpPrintf)(comm,"  -mat_lu_pivotthreshold <threshold>: Set pivoting threshold\n");
172776be9ce4SBarry Smith   (*PetscHelpPrintf)(comm,"  -mat_aij_oneindex: internal indices begin at 1 instead of the default 0.\n");
172876be9ce4SBarry Smith   (*PetscHelpPrintf)(comm,"  -mat_aij_no_inode: Do not use inodes\n");
172976be9ce4SBarry Smith   (*PetscHelpPrintf)(comm,"  -mat_aij_inode_limit <limit>: Set inode limit (max limit=5)\n");
1730682d7d0cSBarry Smith #if defined(HAVE_ESSL)
173176be9ce4SBarry Smith   (*PetscHelpPrintf)(comm,"  -mat_aij_essl: Use IBM sparse LU factorization and solve.\n");
1732682d7d0cSBarry Smith #endif
17333a40ed3dSBarry Smith   PetscFunctionReturn(0);
1734682d7d0cSBarry Smith }
17358f6be9afSLois Curfman McInnes extern int MatEqual_SeqAIJ(Mat A,Mat B, PetscTruth* flg);
1736a93ec695SBarry Smith extern int MatFDColoringCreate_SeqAIJ(Mat,ISColoring,MatFDColoring);
1737a93ec695SBarry Smith extern int MatColoringPatch_SeqAIJ(Mat,int,int *,ISColoring *);
1738a93ec695SBarry Smith 
1739cb5b572fSBarry Smith #undef __FUNC__
1740cb5b572fSBarry Smith #define __FUNC__ "MatCopy_SeqAIJ"
1741cb5b572fSBarry Smith int MatCopy_SeqAIJ(Mat A,Mat B,MatStructure str)
1742cb5b572fSBarry Smith {
1743be6bf707SBarry Smith   int    ierr;
1744cb5b572fSBarry Smith 
1745cb5b572fSBarry Smith   PetscFunctionBegin;
1746be6bf707SBarry Smith   if (str == SAME_NONZERO_PATTERN && B->type == MATSEQAIJ) {
1747be6bf707SBarry Smith     Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data;
1748be6bf707SBarry Smith     Mat_SeqAIJ *b = (Mat_SeqAIJ *) B->data;
1749be6bf707SBarry Smith 
1750be6bf707SBarry Smith     if (a->nonew != 1) SETERRQ(1,1,"Must call MatSetOption(A,MAT_NO_NEW_NONZERO_LOCATIONS);first");
1751be6bf707SBarry Smith     if (b->nonew != 1) SETERRQ(1,1,"Must call MatSetOption(B,MAT_NO_NEW_NONZERO_LOCATIONS);first");
1752be6bf707SBarry Smith     if (a->i[a->m]+a->indexshift != b->i[b->m]+a->indexshift) {
1753be6bf707SBarry Smith       SETERRQ(1,1,"Number of nonzeros in two matrices are different");
1754cb5b572fSBarry Smith     }
1755be6bf707SBarry Smith     PetscMemcpy(b->a,a->a,(a->i[a->m]+a->indexshift)*sizeof(Scalar));
1756cb5b572fSBarry Smith   } else {
1757cb5b572fSBarry Smith     ierr = MatCopy_Basic(A,B,str);CHKERRQ(ierr);
1758cb5b572fSBarry Smith   }
1759cb5b572fSBarry Smith   PetscFunctionReturn(0);
1760cb5b572fSBarry Smith }
1761cb5b572fSBarry Smith 
1762682d7d0cSBarry Smith /* -------------------------------------------------------------------*/
17630a6ffc59SBarry Smith static struct _MatOps MatOps_Values = {MatSetValues_SeqAIJ,
1764cb5b572fSBarry Smith        MatGetRow_SeqAIJ,
1765cb5b572fSBarry Smith        MatRestoreRow_SeqAIJ,
1766cb5b572fSBarry Smith        MatMult_SeqAIJ,
1767cb5b572fSBarry Smith        MatMultAdd_SeqAIJ,
1768cb5b572fSBarry Smith        MatMultTrans_SeqAIJ,
1769cb5b572fSBarry Smith        MatMultTransAdd_SeqAIJ,
1770cb5b572fSBarry Smith        MatSolve_SeqAIJ,
1771cb5b572fSBarry Smith        MatSolveAdd_SeqAIJ,
1772cb5b572fSBarry Smith        MatSolveTrans_SeqAIJ,
1773cb5b572fSBarry Smith        MatSolveTransAdd_SeqAIJ,
1774cb5b572fSBarry Smith        MatLUFactor_SeqAIJ,
1775cb5b572fSBarry Smith        0,
177617ab2063SBarry Smith        MatRelax_SeqAIJ,
177717ab2063SBarry Smith        MatTranspose_SeqAIJ,
1778cb5b572fSBarry Smith        MatGetInfo_SeqAIJ,
1779cb5b572fSBarry Smith        MatEqual_SeqAIJ,
1780cb5b572fSBarry Smith        MatGetDiagonal_SeqAIJ,
1781cb5b572fSBarry Smith        MatDiagonalScale_SeqAIJ,
1782cb5b572fSBarry Smith        MatNorm_SeqAIJ,
1783cb5b572fSBarry Smith        0,
1784cb5b572fSBarry Smith        MatAssemblyEnd_SeqAIJ,
178517ab2063SBarry Smith        MatCompress_SeqAIJ,
1786cb5b572fSBarry Smith        MatSetOption_SeqAIJ,
1787cb5b572fSBarry Smith        MatZeroEntries_SeqAIJ,
1788cb5b572fSBarry Smith        MatZeroRows_SeqAIJ,
1789cb5b572fSBarry Smith        MatLUFactorSymbolic_SeqAIJ,
1790cb5b572fSBarry Smith        MatLUFactorNumeric_SeqAIJ,
1791cb5b572fSBarry Smith        0,
1792cb5b572fSBarry Smith        0,
1793cb5b572fSBarry Smith        MatGetSize_SeqAIJ,
1794cb5b572fSBarry Smith        MatGetSize_SeqAIJ,
1795cb5b572fSBarry Smith        MatGetOwnershipRange_SeqAIJ,
1796cb5b572fSBarry Smith        MatILUFactorSymbolic_SeqAIJ,
1797cb5b572fSBarry Smith        0,
1798cb5b572fSBarry Smith        0,
1799cb5b572fSBarry Smith        0,
1800be6bf707SBarry Smith        MatDuplicate_SeqAIJ,
1801cb5b572fSBarry Smith        0,
1802cb5b572fSBarry Smith        0,
1803cb5b572fSBarry Smith        MatILUFactor_SeqAIJ,
1804cb5b572fSBarry Smith        0,
1805cb5b572fSBarry Smith        0,
1806cb5b572fSBarry Smith        MatGetSubMatrices_SeqAIJ,
1807cb5b572fSBarry Smith        MatIncreaseOverlap_SeqAIJ,
1808cb5b572fSBarry Smith        MatGetValues_SeqAIJ,
1809cb5b572fSBarry Smith        MatCopy_SeqAIJ,
1810f0b747eeSBarry Smith        MatPrintHelp_SeqAIJ,
1811cb5b572fSBarry Smith        MatScale_SeqAIJ,
1812cb5b572fSBarry Smith        0,
1813cb5b572fSBarry Smith        0,
18146945ee14SBarry Smith        MatILUDTFactor_SeqAIJ,
18156945ee14SBarry Smith        MatGetBlockSize_SeqAIJ,
18163b2fbd54SBarry Smith        MatGetRowIJ_SeqAIJ,
18173b2fbd54SBarry Smith        MatRestoreRowIJ_SeqAIJ,
18183b2fbd54SBarry Smith        MatGetColumnIJ_SeqAIJ,
1819a93ec695SBarry Smith        MatRestoreColumnIJ_SeqAIJ,
1820a93ec695SBarry Smith        MatFDColoringCreate_SeqAIJ,
18210513a670SBarry Smith        MatColoringPatch_SeqAIJ,
18220513a670SBarry Smith        0,
1823cda55fadSBarry Smith        MatPermute_SeqAIJ,
1824cda55fadSBarry Smith        0,
1825cda55fadSBarry Smith        0,
1826cda55fadSBarry Smith        0,
1827cda55fadSBarry Smith        0,
1828cda55fadSBarry Smith        MatGetMaps_Petsc};
182917ab2063SBarry Smith 
183017ab2063SBarry Smith extern int MatUseSuperLU_SeqAIJ(Mat);
183117ab2063SBarry Smith extern int MatUseEssl_SeqAIJ(Mat);
183217ab2063SBarry Smith extern int MatUseDXML_SeqAIJ(Mat);
183317ab2063SBarry Smith 
1834fb2e594dSBarry Smith EXTERN_C_BEGIN
18355615d1e5SSatish Balay #undef __FUNC__
1836bef8e0ddSBarry Smith #define __FUNC__ "MatSeqAIJSetColumnIndices_SeqAIJ"
1837bef8e0ddSBarry Smith int MatSeqAIJSetColumnIndices_SeqAIJ(Mat mat,int *indices)
1838bef8e0ddSBarry Smith {
1839bef8e0ddSBarry Smith   Mat_SeqAIJ *aij = (Mat_SeqAIJ *)mat->data;
1840bef8e0ddSBarry Smith   int        i,nz,n;
1841bef8e0ddSBarry Smith 
1842bef8e0ddSBarry Smith   PetscFunctionBegin;
1843bef8e0ddSBarry Smith   if (aij->indexshift) SETERRQ(1,1,"No support with 1 based indexing");
1844bef8e0ddSBarry Smith 
1845bef8e0ddSBarry Smith   nz = aij->maxnz;
1846bef8e0ddSBarry Smith   n  = aij->n;
1847bef8e0ddSBarry Smith   for (i=0; i<nz; i++) {
1848bef8e0ddSBarry Smith     aij->j[i] = indices[i];
1849bef8e0ddSBarry Smith   }
1850bef8e0ddSBarry Smith   aij->nz = nz;
1851bef8e0ddSBarry Smith   for ( i=0; i<n; i++ ) {
1852bef8e0ddSBarry Smith     aij->ilen[i] = aij->imax[i];
1853bef8e0ddSBarry Smith   }
1854bef8e0ddSBarry Smith 
1855bef8e0ddSBarry Smith   PetscFunctionReturn(0);
1856bef8e0ddSBarry Smith }
1857fb2e594dSBarry Smith EXTERN_C_END
1858bef8e0ddSBarry Smith 
1859bef8e0ddSBarry Smith #undef __FUNC__
1860bef8e0ddSBarry Smith #define __FUNC__ "MatSeqAIJSetColumnIndices"
1861bef8e0ddSBarry Smith /*@
1862bef8e0ddSBarry Smith     MatSeqAIJSetColumnIndices - Set the column indices for all the rows
1863bef8e0ddSBarry Smith        in the matrix.
1864bef8e0ddSBarry Smith 
1865bef8e0ddSBarry Smith   Input Parameters:
1866bef8e0ddSBarry Smith +  mat - the SeqAIJ matrix
1867bef8e0ddSBarry Smith -  indices - the column indices
1868bef8e0ddSBarry Smith 
1869bef8e0ddSBarry Smith   Notes:
1870bef8e0ddSBarry Smith     This can be called if you have precomputed the nonzero structure of the
1871bef8e0ddSBarry Smith   matrix and want to provide it to the matrix object to improve the performance
1872bef8e0ddSBarry Smith   of the MatSetValues() operation.
1873bef8e0ddSBarry Smith 
1874bef8e0ddSBarry Smith     You MUST have set the correct numbers of nonzeros per row in the call to
1875bef8e0ddSBarry Smith   MatCreateSeqAIJ().
1876bef8e0ddSBarry Smith 
1877bef8e0ddSBarry Smith     MUST be called before any calls to MatSetValues();
1878bef8e0ddSBarry Smith 
1879bef8e0ddSBarry Smith @*/
1880bef8e0ddSBarry Smith int MatSeqAIJSetColumnIndices(Mat mat,int *indices)
1881bef8e0ddSBarry Smith {
1882bef8e0ddSBarry Smith   int ierr,(*f)(Mat,int *);
1883bef8e0ddSBarry Smith 
1884bef8e0ddSBarry Smith   PetscFunctionBegin;
1885bef8e0ddSBarry Smith   PetscValidHeaderSpecific(mat,MAT_COOKIE);
1886bef8e0ddSBarry Smith   ierr = PetscObjectQueryFunction((PetscObject)mat,"MatSeqAIJSetColumnIndices_C",(void **)&f);
1887bef8e0ddSBarry Smith          CHKERRQ(ierr);
1888bef8e0ddSBarry Smith   if (f) {
1889bef8e0ddSBarry Smith     ierr = (*f)(mat,indices);CHKERRQ(ierr);
1890bef8e0ddSBarry Smith   } else {
1891bef8e0ddSBarry Smith     SETERRQ(1,1,"Wrong type of matrix to set column indices");
1892bef8e0ddSBarry Smith   }
1893bef8e0ddSBarry Smith   PetscFunctionReturn(0);
1894bef8e0ddSBarry Smith }
1895bef8e0ddSBarry Smith 
1896be6bf707SBarry Smith /* ----------------------------------------------------------------------------------------*/
1897be6bf707SBarry Smith 
1898fb2e594dSBarry Smith EXTERN_C_BEGIN
1899be6bf707SBarry Smith #undef __FUNC__
1900be6bf707SBarry Smith #define __FUNC__ "MatStoreValues_SeqAIJ"
1901be6bf707SBarry Smith int MatStoreValues_SeqAIJ(Mat mat)
1902be6bf707SBarry Smith {
1903be6bf707SBarry Smith   Mat_SeqAIJ *aij = (Mat_SeqAIJ *)mat->data;
1904be6bf707SBarry Smith   int        nz = aij->i[aij->m]+aij->indexshift;
1905be6bf707SBarry Smith 
1906be6bf707SBarry Smith   PetscFunctionBegin;
1907be6bf707SBarry Smith   if (aij->nonew != 1) {
1908be6bf707SBarry Smith     SETERRQ(1,1,"Must call MatSetOption(A,MAT_NO_NEW_NONZERO_LOCATIONS);first");
1909be6bf707SBarry Smith   }
1910be6bf707SBarry Smith 
1911be6bf707SBarry Smith   /* allocate space for values if not already there */
1912be6bf707SBarry Smith   if (!aij->saved_values) {
1913be6bf707SBarry Smith     aij->saved_values = (Scalar *) PetscMalloc(nz*sizeof(Scalar));CHKPTRQ(aij->saved_values);
1914be6bf707SBarry Smith   }
1915be6bf707SBarry Smith 
1916be6bf707SBarry Smith   /* copy values over */
1917be6bf707SBarry Smith   PetscMemcpy(aij->saved_values,aij->a,nz*sizeof(Scalar));
1918be6bf707SBarry Smith   PetscFunctionReturn(0);
1919be6bf707SBarry Smith }
1920fb2e594dSBarry Smith EXTERN_C_END
1921be6bf707SBarry Smith 
1922be6bf707SBarry Smith #undef __FUNC__
1923be6bf707SBarry Smith #define __FUNC__ "MatStoreValues"
1924be6bf707SBarry Smith /*@
1925be6bf707SBarry Smith     MatStoreValues - Stashes a copy of the matrix values; this allows, for
1926be6bf707SBarry Smith        example, reuse of the linear part of a Jacobian, while recomputing the
1927be6bf707SBarry Smith        nonlinear portion.
1928be6bf707SBarry Smith 
1929be6bf707SBarry Smith    Collect on Mat
1930be6bf707SBarry Smith 
1931be6bf707SBarry Smith   Input Parameters:
1932be6bf707SBarry Smith .  mat - the matrix (currently on AIJ matrices support this option)
1933be6bf707SBarry Smith 
1934be6bf707SBarry Smith   Common Usage, with SNESSolve():
1935be6bf707SBarry Smith $    Create Jacobian matrix
1936be6bf707SBarry Smith $    Set linear terms into matrix
1937be6bf707SBarry Smith $    Apply boundary conditions to matrix, at this time matrix must have
1938be6bf707SBarry Smith $      final nonzero structure (i.e. setting the nonlinear terms and applying
1939be6bf707SBarry Smith $      boundary conditions again will not change the nonzero structure
1940be6bf707SBarry Smith $    ierr = MatSetOption(mat,MAT_NO_NEW_NONZERO_LOCATIONS);
1941be6bf707SBarry Smith $    ierr = MatStoreValues(mat);
1942be6bf707SBarry Smith $    Call SNESSetJacobian() with matrix
1943be6bf707SBarry Smith $    In your Jacobian routine
1944be6bf707SBarry Smith $      ierr = MatRetrieveValues(mat);
1945be6bf707SBarry Smith $      Set nonlinear terms in matrix
1946be6bf707SBarry Smith 
1947be6bf707SBarry Smith   Common Usage without SNESSolve(), i.e. when you handle nonlinear solve yourself:
1948be6bf707SBarry Smith $    // build linear portion of Jacobian
1949be6bf707SBarry Smith $    ierr = MatSetOption(mat,MAT_NO_NEW_NONZERO_LOCATIONS);
1950be6bf707SBarry Smith $    ierr = MatStoreValues(mat);
1951be6bf707SBarry Smith $    loop over nonlinear iterations
1952be6bf707SBarry Smith $       ierr = MatRetrieveValues(mat);
1953be6bf707SBarry Smith $       // call MatSetValues(mat,...) to set nonliner portion of Jacobian
1954be6bf707SBarry Smith $       // call MatAssemblyBegin/End() on matrix
1955be6bf707SBarry Smith $       Solve linear system with Jacobian
1956be6bf707SBarry Smith $    endloop
1957be6bf707SBarry Smith 
1958be6bf707SBarry Smith   Notes:
1959be6bf707SBarry Smith     Matrix must already be assemblied before calling this routine
1960be6bf707SBarry Smith     Must set the matrix option MatSetOption(mat,MAT_NO_NEW_NONZERO_LOCATIONS); before
1961be6bf707SBarry Smith     calling this routine.
1962be6bf707SBarry Smith 
1963be6bf707SBarry Smith .seealso: MatRetrieveValues()
1964be6bf707SBarry Smith 
1965be6bf707SBarry Smith @*/
1966be6bf707SBarry Smith int MatStoreValues(Mat mat)
1967be6bf707SBarry Smith {
1968be6bf707SBarry Smith   int ierr,(*f)(Mat);
1969be6bf707SBarry Smith 
1970be6bf707SBarry Smith   PetscFunctionBegin;
1971be6bf707SBarry Smith   PetscValidHeaderSpecific(mat,MAT_COOKIE);
1972be6bf707SBarry Smith   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,0,"Not for unassembled matrix");
1973be6bf707SBarry Smith   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,0,"Not for factored matrix");
1974be6bf707SBarry Smith 
1975be6bf707SBarry Smith   ierr = PetscObjectQueryFunction((PetscObject)mat,"MatStoreValues_C",(void **)&f);
1976be6bf707SBarry Smith          CHKERRQ(ierr);
1977be6bf707SBarry Smith   if (f) {
1978be6bf707SBarry Smith     ierr = (*f)(mat);CHKERRQ(ierr);
1979be6bf707SBarry Smith   } else {
1980be6bf707SBarry Smith     SETERRQ(1,1,"Wrong type of matrix to store values");
1981be6bf707SBarry Smith   }
1982be6bf707SBarry Smith   PetscFunctionReturn(0);
1983be6bf707SBarry Smith }
1984be6bf707SBarry Smith 
1985fb2e594dSBarry Smith EXTERN_C_BEGIN
1986be6bf707SBarry Smith #undef __FUNC__
1987be6bf707SBarry Smith #define __FUNC__ "MatRetrieveValues_SeqAIJ"
1988be6bf707SBarry Smith int MatRetrieveValues_SeqAIJ(Mat mat)
1989be6bf707SBarry Smith {
1990be6bf707SBarry Smith   Mat_SeqAIJ *aij = (Mat_SeqAIJ *)mat->data;
1991be6bf707SBarry Smith   int        nz = aij->i[aij->m]+aij->indexshift;
1992be6bf707SBarry Smith 
1993be6bf707SBarry Smith   PetscFunctionBegin;
1994be6bf707SBarry Smith   if (aij->nonew != 1) {
1995be6bf707SBarry Smith     SETERRQ(1,1,"Must call MatSetOption(A,MAT_NO_NEW_NONZERO_LOCATIONS);first");
1996be6bf707SBarry Smith   }
1997be6bf707SBarry Smith   if (!aij->saved_values) {
1998be6bf707SBarry Smith     SETERRQ(1,1,"Must call MatStoreValues(A);first");
1999be6bf707SBarry Smith   }
2000be6bf707SBarry Smith 
2001be6bf707SBarry Smith   /* copy values over */
2002be6bf707SBarry Smith   PetscMemcpy(aij->a, aij->saved_values,nz*sizeof(Scalar));
2003be6bf707SBarry Smith   PetscFunctionReturn(0);
2004be6bf707SBarry Smith }
2005fb2e594dSBarry Smith EXTERN_C_END
2006be6bf707SBarry Smith 
2007be6bf707SBarry Smith #undef __FUNC__
2008be6bf707SBarry Smith #define __FUNC__ "MatRetrieveValues"
2009be6bf707SBarry Smith /*@
2010be6bf707SBarry Smith     MatRetrieveValues - Retrieves the copy of the matrix values; this allows, for
2011be6bf707SBarry Smith        example, reuse of the linear part of a Jacobian, while recomputing the
2012be6bf707SBarry Smith        nonlinear portion.
2013be6bf707SBarry Smith 
2014be6bf707SBarry Smith    Collect on Mat
2015be6bf707SBarry Smith 
2016be6bf707SBarry Smith   Input Parameters:
2017be6bf707SBarry Smith .  mat - the matrix (currently on AIJ matrices support this option)
2018be6bf707SBarry Smith 
2019be6bf707SBarry Smith .seealso: MatStoreValues()
2020be6bf707SBarry Smith 
2021be6bf707SBarry Smith @*/
2022be6bf707SBarry Smith int MatRetrieveValues(Mat mat)
2023be6bf707SBarry Smith {
2024be6bf707SBarry Smith   int ierr,(*f)(Mat);
2025be6bf707SBarry Smith 
2026be6bf707SBarry Smith   PetscFunctionBegin;
2027be6bf707SBarry Smith   PetscValidHeaderSpecific(mat,MAT_COOKIE);
2028be6bf707SBarry Smith   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,0,"Not for unassembled matrix");
2029be6bf707SBarry Smith   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,0,"Not for factored matrix");
2030be6bf707SBarry Smith 
2031be6bf707SBarry Smith   ierr = PetscObjectQueryFunction((PetscObject)mat,"MatRetrieveValues_C",(void **)&f);
2032be6bf707SBarry Smith          CHKERRQ(ierr);
2033be6bf707SBarry Smith   if (f) {
2034be6bf707SBarry Smith     ierr = (*f)(mat);CHKERRQ(ierr);
2035be6bf707SBarry Smith   } else {
2036be6bf707SBarry Smith     SETERRQ(1,1,"Wrong type of matrix to retrieve values");
2037be6bf707SBarry Smith   }
2038be6bf707SBarry Smith   PetscFunctionReturn(0);
2039be6bf707SBarry Smith }
2040be6bf707SBarry Smith 
2041be6bf707SBarry Smith /* --------------------------------------------------------------------------------*/
2042cb5b572fSBarry Smith 
2043bef8e0ddSBarry Smith #undef __FUNC__
20445615d1e5SSatish Balay #define __FUNC__ "MatCreateSeqAIJ"
204517ab2063SBarry Smith /*@C
2046682d7d0cSBarry Smith    MatCreateSeqAIJ - Creates a sparse matrix in AIJ (compressed row) format
20470d15e28bSLois Curfman McInnes    (the default parallel PETSc format).  For good matrix assembly performance
20486e62573dSLois Curfman McInnes    the user should preallocate the matrix storage by setting the parameter nz
20492bd5e0b2SLois Curfman McInnes    (or the array nzz).  By setting these parameters accurately, performance
20502bd5e0b2SLois Curfman McInnes    during matrix assembly can be increased by more than a factor of 50.
205117ab2063SBarry Smith 
2052db81eaa0SLois Curfman McInnes    Collective on MPI_Comm
2053db81eaa0SLois Curfman McInnes 
205417ab2063SBarry Smith    Input Parameters:
2055db81eaa0SLois Curfman McInnes +  comm - MPI communicator, set to PETSC_COMM_SELF
205617ab2063SBarry Smith .  m - number of rows
205717ab2063SBarry Smith .  n - number of columns
205817ab2063SBarry Smith .  nz - number of nonzeros per row (same for all rows)
2059db81eaa0SLois Curfman McInnes -  nzz - array containing the number of nonzeros in the various rows
20602bd5e0b2SLois Curfman McInnes          (possibly different for each row) or PETSC_NULL
206117ab2063SBarry Smith 
206217ab2063SBarry Smith    Output Parameter:
2063416022c9SBarry Smith .  A - the matrix
206417ab2063SBarry Smith 
2065b259b22eSLois Curfman McInnes    Notes:
206617ab2063SBarry Smith    The AIJ format (also called the Yale sparse matrix format or
206717ab2063SBarry Smith    compressed row storage), is fully compatible with standard Fortran 77
20680002213bSLois Curfman McInnes    storage.  That is, the stored row and column indices can begin at
206944cd7ae7SLois Curfman McInnes    either one (as in Fortran) or zero.  See the users' manual for details.
207017ab2063SBarry Smith 
207117ab2063SBarry Smith    Specify the preallocated storage with either nz or nnz (not both).
2072a40aa06bSLois Curfman McInnes    Set nz=PETSC_DEFAULT and nnz=PETSC_NULL for PETSc to control dynamic memory
20733d323bbdSBarry Smith    allocation.  For large problems you MUST preallocate memory or you
20746da5968aSLois Curfman McInnes    will get TERRIBLE performance, see the users' manual chapter on matrices.
207517ab2063SBarry Smith 
2076682d7d0cSBarry Smith    By default, this format uses inodes (identical nodes) when possible, to
20774fca80b9SLois Curfman McInnes    improve numerical efficiency of matrix-vector products and solves. We
2078682d7d0cSBarry Smith    search for consecutive rows with the same nonzero structure, thereby
20796c7ebb05SLois Curfman McInnes    reusing matrix information to achieve increased efficiency.
20806c7ebb05SLois Curfman McInnes 
20816c7ebb05SLois Curfman McInnes    Options Database Keys:
2082db81eaa0SLois Curfman McInnes +  -mat_aij_no_inode  - Do not use inodes
2083db81eaa0SLois Curfman McInnes .  -mat_aij_inode_limit <limit> - Sets inode limit (max limit=5)
2084db81eaa0SLois Curfman McInnes -  -mat_aij_oneindex - Internally use indexing starting at 1
2085db81eaa0SLois Curfman McInnes         rather than 0.  Note that when calling MatSetValues(),
2086db81eaa0SLois Curfman McInnes         the user still MUST index entries starting at 0!
208717ab2063SBarry Smith 
2088bef8e0ddSBarry Smith .seealso: MatCreate(), MatCreateMPIAIJ(), MatSetValues(), MatSeqAIJSetColumnIndices()
208917ab2063SBarry Smith @*/
2090416022c9SBarry Smith int MatCreateSeqAIJ(MPI_Comm comm,int m,int n,int nz,int *nnz, Mat *A)
209117ab2063SBarry Smith {
2092416022c9SBarry Smith   Mat        B;
2093416022c9SBarry Smith   Mat_SeqAIJ *b;
20946945ee14SBarry Smith   int        i, len, ierr, flg,size;
20956945ee14SBarry Smith 
20963a40ed3dSBarry Smith   PetscFunctionBegin;
20976945ee14SBarry Smith   MPI_Comm_size(comm,&size);
2098a8c6a408SBarry Smith   if (size > 1) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Comm must be of size 1");
2099d5d45c9bSBarry Smith 
2100416022c9SBarry Smith   *A                  = 0;
2101f830108cSBarry Smith   PetscHeaderCreate(B,_p_Mat,struct _MatOps,MAT_COOKIE,MATSEQAIJ,comm,MatDestroy,MatView);
2102416022c9SBarry Smith   PLogObjectCreate(B);
21030452661fSBarry Smith   B->data             = (void *) (b = PetscNew(Mat_SeqAIJ)); CHKPTRQ(b);
210444cd7ae7SLois Curfman McInnes   PetscMemzero(b,sizeof(Mat_SeqAIJ));
21050a6ffc59SBarry Smith   PetscMemcpy(B->ops,&MatOps_Values,sizeof(struct _MatOps));
2106e1311b90SBarry Smith   B->ops->destroy          = MatDestroy_SeqAIJ;
2107e1311b90SBarry Smith   B->ops->view             = MatView_SeqAIJ;
2108416022c9SBarry Smith   B->factor           = 0;
2109416022c9SBarry Smith   B->lupivotthreshold = 1.0;
211090f02eecSBarry Smith   B->mapping          = 0;
2111e1311b90SBarry Smith   ierr = OptionsGetDouble(PETSC_NULL,"-mat_lu_pivotthreshold",&B->lupivotthreshold,&flg);CHKERRQ(ierr);
21127a743949SBarry Smith   b->ilu_preserve_row_sums = PETSC_FALSE;
2113e1311b90SBarry Smith   ierr = OptionsHasName(PETSC_NULL,"-pc_ilu_preserve_row_sums",(int*)&b->ilu_preserve_row_sums);CHKERRQ(ierr);
2114416022c9SBarry Smith   b->row              = 0;
2115416022c9SBarry Smith   b->col              = 0;
211682bf6240SBarry Smith   b->icol             = 0;
2117416022c9SBarry Smith   b->indexshift       = 0;
2118b810aeb4SBarry Smith   b->reallocs         = 0;
211969957df2SSatish Balay   ierr = OptionsHasName(PETSC_NULL,"-mat_aij_oneindex", &flg); CHKERRQ(ierr);
212069957df2SSatish Balay   if (flg) b->indexshift = -1;
212117ab2063SBarry Smith 
212244cd7ae7SLois Curfman McInnes   b->m = m; B->m = m; B->M = m;
212344cd7ae7SLois Curfman McInnes   b->n = n; B->n = n; B->N = n;
2124a5ae1ecdSBarry Smith 
21254d197716SBarry Smith   ierr = MapCreateMPI(comm,m,m,&B->rmap);CHKERRQ(ierr);
21264d197716SBarry Smith   ierr = MapCreateMPI(comm,n,n,&B->cmap);CHKERRQ(ierr);
2127a5ae1ecdSBarry Smith 
21280452661fSBarry Smith   b->imax = (int *) PetscMalloc( (m+1)*sizeof(int) ); CHKPTRQ(b->imax);
2129b4fd4287SBarry Smith   if (nnz == PETSC_NULL) {
21307b8455f0SLois Curfman McInnes     if (nz == PETSC_DEFAULT) nz = 10;
21317b8455f0SLois Curfman McInnes     else if (nz <= 0)        nz = 1;
2132416022c9SBarry Smith     for ( i=0; i<m; i++ ) b->imax[i] = nz;
213317ab2063SBarry Smith     nz = nz*m;
21343a40ed3dSBarry Smith   } else {
213517ab2063SBarry Smith     nz = 0;
2136416022c9SBarry Smith     for ( i=0; i<m; i++ ) {b->imax[i] = nnz[i]; nz += nnz[i];}
213717ab2063SBarry Smith   }
213817ab2063SBarry Smith 
213917ab2063SBarry Smith   /* allocate the matrix space */
2140416022c9SBarry Smith   len             = nz*(sizeof(int) + sizeof(Scalar)) + (b->m+1)*sizeof(int);
21410452661fSBarry Smith   b->a            = (Scalar *) PetscMalloc( len ); CHKPTRQ(b->a);
2142416022c9SBarry Smith   b->j            = (int *) (b->a + nz);
2143cddf8d76SBarry Smith   PetscMemzero(b->j,nz*sizeof(int));
2144416022c9SBarry Smith   b->i            = b->j + nz;
2145416022c9SBarry Smith   b->singlemalloc = 1;
214617ab2063SBarry Smith 
2147416022c9SBarry Smith   b->i[0] = -b->indexshift;
214817ab2063SBarry Smith   for (i=1; i<m+1; i++) {
2149416022c9SBarry Smith     b->i[i] = b->i[i-1] + b->imax[i-1];
215017ab2063SBarry Smith   }
215117ab2063SBarry Smith 
2152416022c9SBarry Smith   /* b->ilen will count nonzeros in each row so far. */
21530452661fSBarry Smith   b->ilen = (int *) PetscMalloc((m+1)*sizeof(int));
2154f09e8eb9SSatish Balay   PLogObjectMemory(B,len+2*(m+1)*sizeof(int)+sizeof(struct _p_Mat)+sizeof(Mat_SeqAIJ));
2155416022c9SBarry Smith   for ( i=0; i<b->m; i++ ) { b->ilen[i] = 0;}
215617ab2063SBarry Smith 
2157416022c9SBarry Smith   b->nz               = 0;
2158416022c9SBarry Smith   b->maxnz            = nz;
2159416022c9SBarry Smith   b->sorted           = 0;
2160416022c9SBarry Smith   b->roworiented      = 1;
2161416022c9SBarry Smith   b->nonew            = 0;
2162416022c9SBarry Smith   b->diag             = 0;
2163416022c9SBarry Smith   b->solve_work       = 0;
216471bd300dSLois Curfman McInnes   b->spptr            = 0;
2165754ec7b1SSatish Balay   b->inode.node_count = 0;
2166754ec7b1SSatish Balay   b->inode.size       = 0;
21676c7ebb05SLois Curfman McInnes   b->inode.limit      = 5;
21686c7ebb05SLois Curfman McInnes   b->inode.max_limit  = 5;
2169be6bf707SBarry Smith   b->saved_values     = 0;
21704e220ebcSLois Curfman McInnes   B->info.nz_unneeded = (double)b->maxnz;
217117ab2063SBarry Smith 
2172416022c9SBarry Smith   *A = B;
21734e220ebcSLois Curfman McInnes 
21744b14c69eSBarry Smith   /*  SuperLU is not currently supported through PETSc */
21754b14c69eSBarry Smith #if defined(HAVE_SUPERLU)
217669957df2SSatish Balay   ierr = OptionsHasName(PETSC_NULL,"-mat_aij_superlu", &flg); CHKERRQ(ierr);
217769957df2SSatish Balay   if (flg) { ierr = MatUseSuperLU_SeqAIJ(B); CHKERRQ(ierr); }
21784b14c69eSBarry Smith #endif
217969957df2SSatish Balay   ierr = OptionsHasName(PETSC_NULL,"-mat_aij_essl", &flg); CHKERRQ(ierr);
218069957df2SSatish Balay   if (flg) { ierr = MatUseEssl_SeqAIJ(B); CHKERRQ(ierr); }
218169957df2SSatish Balay   ierr = OptionsHasName(PETSC_NULL,"-mat_aij_dxml", &flg); CHKERRQ(ierr);
218269957df2SSatish Balay   if (flg) {
2183a8c6a408SBarry Smith     if (!b->indexshift) SETERRQ( PETSC_ERR_LIB,0,"need -mat_aij_oneindex with -mat_aij_dxml");
2184416022c9SBarry Smith     ierr = MatUseDXML_SeqAIJ(B); CHKERRQ(ierr);
218517ab2063SBarry Smith   }
218669957df2SSatish Balay   ierr = OptionsHasName(PETSC_NULL,"-help", &flg); CHKERRQ(ierr);
218769957df2SSatish Balay   if (flg) {ierr = MatPrintHelp(B); CHKERRQ(ierr); }
2188bef8e0ddSBarry Smith 
2189bef8e0ddSBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatSeqAIJSetColumnIndices_C",
2190bef8e0ddSBarry Smith                                      "MatSeqAIJSetColumnIndices_SeqAIJ",
2191bef8e0ddSBarry Smith                                      (void*)MatSeqAIJSetColumnIndices_SeqAIJ);CHKERRQ(ierr);
2192be6bf707SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatStoreValues_C",
2193be6bf707SBarry Smith                                      "MatStoreValues_SeqAIJ",
2194be6bf707SBarry Smith                                      (void*)MatStoreValues_SeqAIJ);CHKERRQ(ierr);
2195be6bf707SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatRetrieveValues_C",
2196be6bf707SBarry Smith                                      "MatRetrieveValues_SeqAIJ",
2197be6bf707SBarry Smith                                      (void*)MatRetrieveValues_SeqAIJ);CHKERRQ(ierr);
21983a40ed3dSBarry Smith   PetscFunctionReturn(0);
219917ab2063SBarry Smith }
220017ab2063SBarry Smith 
22015615d1e5SSatish Balay #undef __FUNC__
2202be6bf707SBarry Smith #define __FUNC__ "MatDuplicate_SeqAIJ"
2203be6bf707SBarry Smith int MatDuplicate_SeqAIJ(Mat A,MatDuplicateOption cpvalues,Mat *B)
220417ab2063SBarry Smith {
2205416022c9SBarry Smith   Mat        C;
2206416022c9SBarry Smith   Mat_SeqAIJ *c,*a = (Mat_SeqAIJ *) A->data;
2207bef8e0ddSBarry Smith   int        i,len, m = a->m,shift = a->indexshift,ierr;
220817ab2063SBarry Smith 
22093a40ed3dSBarry Smith   PetscFunctionBegin;
22104043dd9cSLois Curfman McInnes   *B = 0;
2211f830108cSBarry Smith   PetscHeaderCreate(C,_p_Mat,struct _MatOps,MAT_COOKIE,MATSEQAIJ,A->comm,MatDestroy,MatView);
2212416022c9SBarry Smith   PLogObjectCreate(C);
22130452661fSBarry Smith   C->data       = (void *) (c = PetscNew(Mat_SeqAIJ)); CHKPTRQ(c);
2214f830108cSBarry Smith   PetscMemcpy(C->ops,A->ops,sizeof(struct _MatOps));
2215e1311b90SBarry Smith   C->ops->destroy    = MatDestroy_SeqAIJ;
2216e1311b90SBarry Smith   C->ops->view       = MatView_SeqAIJ;
2217416022c9SBarry Smith   C->factor     = A->factor;
2218416022c9SBarry Smith   c->row        = 0;
2219416022c9SBarry Smith   c->col        = 0;
222082bf6240SBarry Smith   c->icol       = 0;
2221416022c9SBarry Smith   c->indexshift = shift;
2222c456f294SBarry Smith   C->assembled  = PETSC_TRUE;
222317ab2063SBarry Smith 
222444cd7ae7SLois Curfman McInnes   c->m = C->m   = a->m;
222544cd7ae7SLois Curfman McInnes   c->n = C->n   = a->n;
222644cd7ae7SLois Curfman McInnes   C->M          = a->m;
222744cd7ae7SLois Curfman McInnes   C->N          = a->n;
222817ab2063SBarry Smith 
22290452661fSBarry Smith   c->imax       = (int *) PetscMalloc((m+1)*sizeof(int)); CHKPTRQ(c->imax);
22300452661fSBarry Smith   c->ilen       = (int *) PetscMalloc((m+1)*sizeof(int)); CHKPTRQ(c->ilen);
223117ab2063SBarry Smith   for ( i=0; i<m; i++ ) {
2232416022c9SBarry Smith     c->imax[i] = a->imax[i];
2233416022c9SBarry Smith     c->ilen[i] = a->ilen[i];
223417ab2063SBarry Smith   }
223517ab2063SBarry Smith 
223617ab2063SBarry Smith   /* allocate the matrix space */
2237416022c9SBarry Smith   c->singlemalloc = 1;
2238416022c9SBarry Smith   len     = (m+1)*sizeof(int)+(a->i[m])*(sizeof(Scalar)+sizeof(int));
22390452661fSBarry Smith   c->a  = (Scalar *) PetscMalloc( len ); CHKPTRQ(c->a);
2240416022c9SBarry Smith   c->j  = (int *) (c->a + a->i[m] + shift);
2241416022c9SBarry Smith   c->i  = c->j + a->i[m] + shift;
2242416022c9SBarry Smith   PetscMemcpy(c->i,a->i,(m+1)*sizeof(int));
224317ab2063SBarry Smith   if (m > 0) {
2244416022c9SBarry Smith     PetscMemcpy(c->j,a->j,(a->i[m]+shift)*sizeof(int));
2245be6bf707SBarry Smith     if (cpvalues == MAT_COPY_VALUES) {
2246416022c9SBarry Smith       PetscMemcpy(c->a,a->a,(a->i[m]+shift)*sizeof(Scalar));
2247be6bf707SBarry Smith     } else {
2248be6bf707SBarry Smith       PetscMemzero(c->a,(a->i[m]+shift)*sizeof(Scalar));
224917ab2063SBarry Smith     }
225008480c60SBarry Smith   }
225117ab2063SBarry Smith 
2252f09e8eb9SSatish Balay   PLogObjectMemory(C,len+2*(m+1)*sizeof(int)+sizeof(struct _p_Mat)+sizeof(Mat_SeqAIJ));
2253416022c9SBarry Smith   c->sorted      = a->sorted;
2254416022c9SBarry Smith   c->roworiented = a->roworiented;
2255416022c9SBarry Smith   c->nonew       = a->nonew;
22567a743949SBarry Smith   c->ilu_preserve_row_sums = a->ilu_preserve_row_sums;
2257be6bf707SBarry Smith   c->saved_values = 0;
225817ab2063SBarry Smith 
2259416022c9SBarry Smith   if (a->diag) {
22600452661fSBarry Smith     c->diag = (int *) PetscMalloc( (m+1)*sizeof(int) ); CHKPTRQ(c->diag);
2261416022c9SBarry Smith     PLogObjectMemory(C,(m+1)*sizeof(int));
226217ab2063SBarry Smith     for ( i=0; i<m; i++ ) {
2263416022c9SBarry Smith       c->diag[i] = a->diag[i];
226417ab2063SBarry Smith     }
22653a40ed3dSBarry Smith   } else c->diag          = 0;
22666c7ebb05SLois Curfman McInnes   c->inode.limit        = a->inode.limit;
22676c7ebb05SLois Curfman McInnes   c->inode.max_limit    = a->inode.max_limit;
2268754ec7b1SSatish Balay   if (a->inode.size){
2269daed632aSSatish Balay     c->inode.size       = (int *) PetscMalloc( (m+1)*sizeof(int) ); CHKPTRQ(c->inode.size);
2270754ec7b1SSatish Balay     c->inode.node_count = a->inode.node_count;
2271daed632aSSatish Balay     PetscMemcpy( c->inode.size, a->inode.size, (m+1)*sizeof(int));
2272754ec7b1SSatish Balay   } else {
2273754ec7b1SSatish Balay     c->inode.size       = 0;
2274754ec7b1SSatish Balay     c->inode.node_count = 0;
2275754ec7b1SSatish Balay   }
2276416022c9SBarry Smith   c->nz                 = a->nz;
2277416022c9SBarry Smith   c->maxnz              = a->maxnz;
2278416022c9SBarry Smith   c->solve_work         = 0;
227976dd722bSSatish Balay   c->spptr              = 0;      /* Dangerous -I'm throwing away a->spptr */
2280754ec7b1SSatish Balay 
2281416022c9SBarry Smith   *B = C;
2282bef8e0ddSBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)C,"MatSeqAIJSetColumnIndices_C",
2283bef8e0ddSBarry Smith                                      "MatSeqAIJSetColumnIndices_SeqAIJ",
2284bef8e0ddSBarry Smith                                      (void*)MatSeqAIJSetColumnIndices_SeqAIJ);CHKERRQ(ierr);
22853a40ed3dSBarry Smith   PetscFunctionReturn(0);
228617ab2063SBarry Smith }
228717ab2063SBarry Smith 
22885615d1e5SSatish Balay #undef __FUNC__
22895615d1e5SSatish Balay #define __FUNC__ "MatLoad_SeqAIJ"
229019bcc07fSBarry Smith int MatLoad_SeqAIJ(Viewer viewer,MatType type,Mat *A)
229117ab2063SBarry Smith {
2292416022c9SBarry Smith   Mat_SeqAIJ   *a;
2293416022c9SBarry Smith   Mat          B;
229417699dbbSLois Curfman McInnes   int          i, nz, ierr, fd, header[4],size,*rowlengths = 0,M,N,shift;
2295bcd2baecSBarry Smith   MPI_Comm     comm;
229617ab2063SBarry Smith 
22973a40ed3dSBarry Smith   PetscFunctionBegin;
229819bcc07fSBarry Smith   PetscObjectGetComm((PetscObject) viewer,&comm);
229917699dbbSLois Curfman McInnes   MPI_Comm_size(comm,&size);
2300a8c6a408SBarry Smith   if (size > 1) SETERRQ(PETSC_ERR_ARG_SIZ,0,"view must have one processor");
230190ace30eSBarry Smith   ierr = ViewerBinaryGetDescriptor(viewer,&fd); CHKERRQ(ierr);
23020752156aSBarry Smith   ierr = PetscBinaryRead(fd,header,4,PETSC_INT); CHKERRQ(ierr);
2303a8c6a408SBarry Smith   if (header[0] != MAT_COOKIE) SETERRQ(PETSC_ERR_FILE_UNEXPECTED,0,"not matrix object in file");
230417ab2063SBarry Smith   M = header[1]; N = header[2]; nz = header[3];
230517ab2063SBarry Smith 
2306d64ed03dSBarry Smith   if (nz < 0) {
2307a8c6a408SBarry Smith     SETERRQ(PETSC_ERR_FILE_UNEXPECTED,1,"Matrix stored in special format on disk, cannot load as SeqAIJ");
2308d64ed03dSBarry Smith   }
2309d64ed03dSBarry Smith 
231017ab2063SBarry Smith   /* read in row lengths */
23110452661fSBarry Smith   rowlengths = (int*) PetscMalloc( M*sizeof(int) ); CHKPTRQ(rowlengths);
23120752156aSBarry Smith   ierr = PetscBinaryRead(fd,rowlengths,M,PETSC_INT); CHKERRQ(ierr);
231317ab2063SBarry Smith 
231417ab2063SBarry Smith   /* create our matrix */
2315416022c9SBarry Smith   ierr = MatCreateSeqAIJ(comm,M,N,0,rowlengths,A); CHKERRQ(ierr);
2316416022c9SBarry Smith   B = *A;
2317416022c9SBarry Smith   a = (Mat_SeqAIJ *) B->data;
2318416022c9SBarry Smith   shift = a->indexshift;
231917ab2063SBarry Smith 
232017ab2063SBarry Smith   /* read in column indices and adjust for Fortran indexing*/
23210752156aSBarry Smith   ierr = PetscBinaryRead(fd,a->j,nz,PETSC_INT); CHKERRQ(ierr);
232217ab2063SBarry Smith   if (shift) {
232317ab2063SBarry Smith     for ( i=0; i<nz; i++ ) {
2324416022c9SBarry Smith       a->j[i] += 1;
232517ab2063SBarry Smith     }
232617ab2063SBarry Smith   }
232717ab2063SBarry Smith 
232817ab2063SBarry Smith   /* read in nonzero values */
23290752156aSBarry Smith   ierr = PetscBinaryRead(fd,a->a,nz,PETSC_SCALAR); CHKERRQ(ierr);
233017ab2063SBarry Smith 
233117ab2063SBarry Smith   /* set matrix "i" values */
2332416022c9SBarry Smith   a->i[0] = -shift;
233317ab2063SBarry Smith   for ( i=1; i<= M; i++ ) {
2334416022c9SBarry Smith     a->i[i]      = a->i[i-1] + rowlengths[i-1];
2335416022c9SBarry Smith     a->ilen[i-1] = rowlengths[i-1];
233617ab2063SBarry Smith   }
23370452661fSBarry Smith   PetscFree(rowlengths);
233817ab2063SBarry Smith 
23396d4a8577SBarry Smith   ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY); CHKERRQ(ierr);
23406d4a8577SBarry Smith   ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY); CHKERRQ(ierr);
23413a40ed3dSBarry Smith   PetscFunctionReturn(0);
234217ab2063SBarry Smith }
234317ab2063SBarry Smith 
23445615d1e5SSatish Balay #undef __FUNC__
23455615d1e5SSatish Balay #define __FUNC__ "MatEqual_SeqAIJ"
23468f6be9afSLois Curfman McInnes int MatEqual_SeqAIJ(Mat A,Mat B, PetscTruth* flg)
23477264ac53SSatish Balay {
23487264ac53SSatish Balay   Mat_SeqAIJ *a = (Mat_SeqAIJ *)A->data, *b = (Mat_SeqAIJ *)B->data;
23497264ac53SSatish Balay 
23503a40ed3dSBarry Smith   PetscFunctionBegin;
2351a8c6a408SBarry Smith   if (B->type !=MATSEQAIJ)SETERRQ(PETSC_ERR_ARG_INCOMP,0,"Matrices must be same type");
23527264ac53SSatish Balay 
23537264ac53SSatish Balay   /* If the  matrix dimensions are not equal, or no of nonzeros or shift */
23547264ac53SSatish Balay   if ((a->m != b->m ) || (a->n !=b->n) ||( a->nz != b->nz)||
2355bcd2baecSBarry Smith       (a->indexshift != b->indexshift)) {
23563a40ed3dSBarry Smith     *flg = PETSC_FALSE; PetscFunctionReturn(0);
2357bcd2baecSBarry Smith   }
23587264ac53SSatish Balay 
23597264ac53SSatish Balay   /* if the a->i are the same */
23608108c231SLois Curfman McInnes   if (PetscMemcmp(a->i,b->i,(a->m+1)*sizeof(int))) {
23613a40ed3dSBarry Smith     *flg = PETSC_FALSE; PetscFunctionReturn(0);
23627264ac53SSatish Balay   }
23637264ac53SSatish Balay 
23647264ac53SSatish Balay   /* if a->j are the same */
2365bcd2baecSBarry Smith   if (PetscMemcmp(a->j, b->j, (a->nz)*sizeof(int))) {
23663a40ed3dSBarry Smith     *flg = PETSC_FALSE; PetscFunctionReturn(0);
2367bcd2baecSBarry Smith   }
2368bcd2baecSBarry Smith 
2369bcd2baecSBarry Smith   /* if a->a are the same */
237019bcc07fSBarry Smith   if (PetscMemcmp(a->a, b->a, (a->nz)*sizeof(Scalar))) {
23713a40ed3dSBarry Smith     *flg = PETSC_FALSE; PetscFunctionReturn(0);
23727264ac53SSatish Balay   }
237377c4ece6SBarry Smith   *flg = PETSC_TRUE;
23743a40ed3dSBarry Smith   PetscFunctionReturn(0);
23757264ac53SSatish Balay 
23767264ac53SSatish Balay }
2377