xref: /petsc/src/mat/impls/aij/seq/aij.c (revision 62aa7f4e1389a38661b7a6aefc7736df8cf61fcf)
173f4d377SMatthew Knepley /*$Id: aij.c,v 1.385 2001/09/07 20:09:22 bsmith Exp $*/
2d5d45c9bSBarry Smith /*
33369ce9aSBarry Smith     Defines the basic matrix operations for the AIJ (compressed row)
4d5d45c9bSBarry Smith   matrix storage format.
5d5d45c9bSBarry Smith */
63369ce9aSBarry Smith 
79e070d67SMatthew Knepley #include "src/mat/impls/aij/seq/aij.h"          /*I "petscmat.h" I*/
8f5eb4b81SSatish Balay #include "src/vec/vecimpl.h"
9f5eb4b81SSatish Balay #include "src/inline/spops.h"
108d195f9aSBarry Smith #include "src/inline/dot.h"
110a835dfdSSatish Balay #include "petscbt.h"
1217ab2063SBarry Smith 
13a2ce50c7SBarry Smith 
14ca44d042SBarry Smith EXTERN int MatToSymmetricIJ_SeqAIJ(int,int*,int*,int,int,int**,int**);
1517ab2063SBarry Smith 
164a2ae208SSatish Balay #undef __FUNCT__
174a2ae208SSatish Balay #define __FUNCT__ "MatGetRowIJ_SeqAIJ"
1836db0b34SBarry Smith int MatGetRowIJ_SeqAIJ(Mat A,int oshift,PetscTruth symmetric,int *m,int **ia,int **ja,PetscTruth *done)
1917ab2063SBarry Smith {
20416022c9SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
216945ee14SBarry Smith   int        ierr,i,ishift;
2217ab2063SBarry Smith 
233a40ed3dSBarry Smith   PetscFunctionBegin;
2431625ec5SSatish Balay   *m     = A->m;
253a40ed3dSBarry Smith   if (!ia) PetscFunctionReturn(0);
266945ee14SBarry Smith   ishift = a->indexshift;
2753e63a63SBarry Smith   if (symmetric && !A->structurally_symmetric) {
28273d9f13SBarry Smith     ierr = MatToSymmetricIJ_SeqAIJ(A->m,a->i,a->j,ishift,oshift,ia,ja);CHKERRQ(ierr);
296945ee14SBarry Smith   } else if (oshift == 0 && ishift == -1) {
30435da068SBarry Smith     int nz = a->i[A->m] - 1;
313b2fbd54SBarry Smith     /* malloc space and  subtract 1 from i and j indices */
32b0a32e0cSBarry Smith     ierr = PetscMalloc((A->m+1)*sizeof(int),ia);CHKERRQ(ierr);
33b0a32e0cSBarry Smith     ierr = PetscMalloc((nz+1)*sizeof(int),ja);CHKERRQ(ierr);
343b2fbd54SBarry Smith     for (i=0; i<nz; i++) (*ja)[i] = a->j[i] - 1;
35273d9f13SBarry Smith     for (i=0; i<A->m+1; i++) (*ia)[i] = a->i[i] - 1;
366945ee14SBarry Smith   } else if (oshift == 1 && ishift == 0) {
37435da068SBarry Smith     int nz = a->i[A->m];
383b2fbd54SBarry Smith     /* malloc space and  add 1 to i and j indices */
391bc30dd5SBarry Smith     ierr = PetscMalloc((A->m+1)*sizeof(int),ia);CHKERRQ(ierr);
40b0a32e0cSBarry Smith     ierr = PetscMalloc((nz+1)*sizeof(int),ja);CHKERRQ(ierr);
413b2fbd54SBarry Smith     for (i=0; i<nz; i++) (*ja)[i] = a->j[i] + 1;
42273d9f13SBarry Smith     for (i=0; i<A->m+1; i++) (*ia)[i] = a->i[i] + 1;
436945ee14SBarry Smith   } else {
446945ee14SBarry Smith     *ia = a->i; *ja = a->j;
45a2ce50c7SBarry Smith   }
463a40ed3dSBarry Smith   PetscFunctionReturn(0);
47a2744918SBarry Smith }
48a2744918SBarry Smith 
494a2ae208SSatish Balay #undef __FUNCT__
504a2ae208SSatish Balay #define __FUNCT__ "MatRestoreRowIJ_SeqAIJ"
5136db0b34SBarry Smith int MatRestoreRowIJ_SeqAIJ(Mat A,int oshift,PetscTruth symmetric,int *n,int **ia,int **ja,PetscTruth *done)
526945ee14SBarry Smith {
536945ee14SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
54606d414cSSatish Balay   int        ishift = a->indexshift,ierr;
556945ee14SBarry Smith 
563a40ed3dSBarry Smith   PetscFunctionBegin;
573a40ed3dSBarry Smith   if (!ia) PetscFunctionReturn(0);
5853e63a63SBarry Smith   if ((symmetric && !A->structurally_symmetric) || (oshift == 0 && ishift == -1) || (oshift == 1 && ishift == 0)) {
59606d414cSSatish Balay     ierr = PetscFree(*ia);CHKERRQ(ierr);
60606d414cSSatish Balay     ierr = PetscFree(*ja);CHKERRQ(ierr);
61bcd2baecSBarry Smith   }
623a40ed3dSBarry Smith   PetscFunctionReturn(0);
6317ab2063SBarry Smith }
6417ab2063SBarry Smith 
654a2ae208SSatish Balay #undef __FUNCT__
664a2ae208SSatish Balay #define __FUNCT__ "MatGetColumnIJ_SeqAIJ"
6736db0b34SBarry Smith int MatGetColumnIJ_SeqAIJ(Mat A,int oshift,PetscTruth symmetric,int *nn,int **ia,int **ja,PetscTruth *done)
683b2fbd54SBarry Smith {
693b2fbd54SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
70a93ec695SBarry Smith   int        ierr,i,ishift = a->indexshift,*collengths,*cia,*cja,n = A->n,m = A->m;
71a93ec695SBarry Smith   int        nz = a->i[m]+ishift,row,*jj,mr,col;
723b2fbd54SBarry Smith 
733a40ed3dSBarry Smith   PetscFunctionBegin;
743b2fbd54SBarry Smith   *nn     = A->n;
753a40ed3dSBarry Smith   if (!ia) PetscFunctionReturn(0);
763b2fbd54SBarry Smith   if (symmetric) {
77273d9f13SBarry Smith     ierr = MatToSymmetricIJ_SeqAIJ(A->m,a->i,a->j,ishift,oshift,ia,ja);CHKERRQ(ierr);
783b2fbd54SBarry Smith   } else {
79b0a32e0cSBarry Smith     ierr = PetscMalloc((n+1)*sizeof(int),&collengths);CHKERRQ(ierr);
80549d3d68SSatish Balay     ierr = PetscMemzero(collengths,n*sizeof(int));CHKERRQ(ierr);
81b0a32e0cSBarry Smith     ierr = PetscMalloc((n+1)*sizeof(int),&cia);CHKERRQ(ierr);
82b0a32e0cSBarry Smith     ierr = PetscMalloc((nz+1)*sizeof(int),&cja);CHKERRQ(ierr);
833b2fbd54SBarry Smith     jj = a->j;
843b2fbd54SBarry Smith     for (i=0; i<nz; i++) {
853b2fbd54SBarry Smith       collengths[jj[i] + ishift]++;
863b2fbd54SBarry Smith     }
873b2fbd54SBarry Smith     cia[0] = oshift;
883b2fbd54SBarry Smith     for (i=0; i<n; i++) {
893b2fbd54SBarry Smith       cia[i+1] = cia[i] + collengths[i];
903b2fbd54SBarry Smith     }
91549d3d68SSatish Balay     ierr = PetscMemzero(collengths,n*sizeof(int));CHKERRQ(ierr);
923b2fbd54SBarry Smith     jj   = a->j;
93a93ec695SBarry Smith     for (row=0; row<m; row++) {
94a93ec695SBarry Smith       mr = a->i[row+1] - a->i[row];
95a93ec695SBarry Smith       for (i=0; i<mr; i++) {
963b2fbd54SBarry Smith         col = *jj++ + ishift;
973b2fbd54SBarry Smith         cja[cia[col] + collengths[col]++ - oshift] = row + oshift;
983b2fbd54SBarry Smith       }
993b2fbd54SBarry Smith     }
100606d414cSSatish Balay     ierr = PetscFree(collengths);CHKERRQ(ierr);
1013b2fbd54SBarry Smith     *ia = cia; *ja = cja;
1023b2fbd54SBarry Smith   }
1033a40ed3dSBarry Smith   PetscFunctionReturn(0);
1043b2fbd54SBarry Smith }
1053b2fbd54SBarry Smith 
1064a2ae208SSatish Balay #undef __FUNCT__
1074a2ae208SSatish Balay #define __FUNCT__ "MatRestoreColumnIJ_SeqAIJ"
10836db0b34SBarry Smith int MatRestoreColumnIJ_SeqAIJ(Mat A,int oshift,PetscTruth symmetric,int *n,int **ia,int **ja,PetscTruth *done)
1093b2fbd54SBarry Smith {
110606d414cSSatish Balay   int ierr;
111606d414cSSatish Balay 
1123a40ed3dSBarry Smith   PetscFunctionBegin;
1133a40ed3dSBarry Smith   if (!ia) PetscFunctionReturn(0);
1143b2fbd54SBarry Smith 
115606d414cSSatish Balay   ierr = PetscFree(*ia);CHKERRQ(ierr);
116606d414cSSatish Balay   ierr = PetscFree(*ja);CHKERRQ(ierr);
1173b2fbd54SBarry Smith 
1183a40ed3dSBarry Smith   PetscFunctionReturn(0);
1193b2fbd54SBarry Smith }
1203b2fbd54SBarry Smith 
121227d817aSBarry Smith #define CHUNKSIZE   15
12217ab2063SBarry Smith 
1234a2ae208SSatish Balay #undef __FUNCT__
1244a2ae208SSatish Balay #define __FUNCT__ "MatSetValues_SeqAIJ"
12587828ca2SBarry Smith int MatSetValues_SeqAIJ(Mat A,int m,int *im,int n,int *in,PetscScalar *v,InsertMode is)
12617ab2063SBarry Smith {
127416022c9SBarry Smith   Mat_SeqAIJ  *a = (Mat_SeqAIJ*)A->data;
128416022c9SBarry Smith   int         *rp,k,low,high,t,ii,row,nrow,i,col,l,rmax,N,sorted = a->sorted;
129273d9f13SBarry Smith   int         *imax = a->imax,*ai = a->i,*ailen = a->ilen;
130549d3d68SSatish Balay   int         *aj = a->j,nonew = a->nonew,shift = a->indexshift,ierr;
13187828ca2SBarry Smith   PetscScalar *ap,value,*aa = a->a;
13236db0b34SBarry Smith   PetscTruth  ignorezeroentries = ((a->ignorezeroentries && is == ADD_VALUES) ? PETSC_TRUE:PETSC_FALSE);
133273d9f13SBarry Smith   PetscTruth  roworiented = a->roworiented;
13417ab2063SBarry Smith 
1353a40ed3dSBarry Smith   PetscFunctionBegin;
13617ab2063SBarry Smith   for (k=0; k<m; k++) { /* loop over added rows */
137416022c9SBarry Smith     row  = im[k];
1385ef9f2a5SBarry Smith     if (row < 0) continue;
139aa482453SBarry Smith #if defined(PETSC_USE_BOPT_g)
140273d9f13SBarry Smith     if (row >= A->m) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"Row too large: row %d max %d",row,A->m);
1413b2fbd54SBarry Smith #endif
14217ab2063SBarry Smith     rp   = aj + ai[row] + shift; ap = aa + ai[row] + shift;
14317ab2063SBarry Smith     rmax = imax[row]; nrow = ailen[row];
144416022c9SBarry Smith     low = 0;
14517ab2063SBarry Smith     for (l=0; l<n; l++) { /* loop over added columns */
1465ef9f2a5SBarry Smith       if (in[l] < 0) continue;
147aa482453SBarry Smith #if defined(PETSC_USE_BOPT_g)
148273d9f13SBarry Smith       if (in[l] >= A->n) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"Column too large: col %d max %d",in[l],A->n);
1493b2fbd54SBarry Smith #endif
1504b0e389bSBarry Smith       col = in[l] - shift;
1514b0e389bSBarry Smith       if (roworiented) {
1525ef9f2a5SBarry Smith         value = v[l + k*n];
153bef8e0ddSBarry Smith       } else {
1544b0e389bSBarry Smith         value = v[k + l*m];
1554b0e389bSBarry Smith       }
15636db0b34SBarry Smith       if (value == 0.0 && ignorezeroentries) continue;
15736db0b34SBarry Smith 
158416022c9SBarry Smith       if (!sorted) low = 0; high = nrow;
159416022c9SBarry Smith       while (high-low > 5) {
160416022c9SBarry Smith         t = (low+high)/2;
161416022c9SBarry Smith         if (rp[t] > col) high = t;
162416022c9SBarry Smith         else             low  = t;
16317ab2063SBarry Smith       }
164416022c9SBarry Smith       for (i=low; i<high; i++) {
16517ab2063SBarry Smith         if (rp[i] > col) break;
16617ab2063SBarry Smith         if (rp[i] == col) {
167416022c9SBarry Smith           if (is == ADD_VALUES) ap[i] += value;
16817ab2063SBarry Smith           else                  ap[i] = value;
16917ab2063SBarry Smith           goto noinsert;
17017ab2063SBarry Smith         }
17117ab2063SBarry Smith       }
172c2653b3dSLois Curfman McInnes       if (nonew == 1) goto noinsert;
17329bbc08cSBarry Smith       else if (nonew == -1) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"Inserting a new nonzero at (%d,%d) in the matrix",row,col);
17417ab2063SBarry Smith       if (nrow >= rmax) {
17517ab2063SBarry Smith         /* there is no extra room in row, therefore enlarge */
176a7ed9263SMatthew Knepley         int         new_nz = ai[A->m] + CHUNKSIZE,*new_i,*new_j;
177a7ed9263SMatthew Knepley         size_t      len;
17887828ca2SBarry Smith         PetscScalar *new_a;
17917ab2063SBarry Smith 
18029bbc08cSBarry Smith         if (nonew == -2) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"Inserting a new nonzero at (%d,%d) in the matrix requiring new malloc()",row,col);
18196854ed6SLois Curfman McInnes 
18217ab2063SBarry Smith         /* malloc new storage space */
183a7ed9263SMatthew Knepley         len     = ((size_t) new_nz)*(sizeof(int)+sizeof(PetscScalar))+(A->m+1)*sizeof(int);
184b0a32e0cSBarry Smith 	ierr    = PetscMalloc(len,&new_a);CHKERRQ(ierr);
18517ab2063SBarry Smith         new_j   = (int*)(new_a + new_nz);
18617ab2063SBarry Smith         new_i   = new_j + new_nz;
18717ab2063SBarry Smith 
18817ab2063SBarry Smith         /* copy over old data into new slots */
18917ab2063SBarry Smith         for (ii=0; ii<row+1; ii++) {new_i[ii] = ai[ii];}
190273d9f13SBarry Smith         for (ii=row+1; ii<A->m+1; ii++) {new_i[ii] = ai[ii]+CHUNKSIZE;}
191549d3d68SSatish Balay         ierr = PetscMemcpy(new_j,aj,(ai[row]+nrow+shift)*sizeof(int));CHKERRQ(ierr);
192a7ed9263SMatthew Knepley         len  = (((size_t) new_nz) - CHUNKSIZE - ai[row] - nrow - shift);
193549d3d68SSatish Balay         ierr = PetscMemcpy(new_j+ai[row]+shift+nrow+CHUNKSIZE,aj+ai[row]+shift+nrow,len*sizeof(int));CHKERRQ(ierr);
194a7ed9263SMatthew Knepley         ierr = PetscMemcpy(new_a,aa,(((size_t) ai[row])+nrow+shift)*sizeof(PetscScalar));CHKERRQ(ierr);
19587828ca2SBarry Smith         ierr = PetscMemcpy(new_a+ai[row]+shift+nrow+CHUNKSIZE,aa+ai[row]+shift+nrow,len*sizeof(PetscScalar));CHKERRQ(ierr);
19617ab2063SBarry Smith         /* free up old matrix storage */
197606d414cSSatish Balay         ierr = PetscFree(a->a);CHKERRQ(ierr);
198606d414cSSatish Balay         if (!a->singlemalloc) {
199606d414cSSatish Balay           ierr = PetscFree(a->i);CHKERRQ(ierr);
200606d414cSSatish Balay           ierr = PetscFree(a->j);CHKERRQ(ierr);
201606d414cSSatish Balay         }
202416022c9SBarry Smith         aa = a->a = new_a; ai = a->i = new_i; aj = a->j = new_j;
203f1e2ffcdSBarry Smith         a->singlemalloc = PETSC_TRUE;
20417ab2063SBarry Smith 
20517ab2063SBarry Smith         rp   = aj + ai[row] + shift; ap = aa + ai[row] + shift;
206416022c9SBarry Smith         rmax = imax[row] = imax[row] + CHUNKSIZE;
20787828ca2SBarry Smith         PetscLogObjectMemory(A,CHUNKSIZE*(sizeof(int) + sizeof(PetscScalar)));
208416022c9SBarry Smith         a->maxnz += CHUNKSIZE;
209b810aeb4SBarry Smith         a->reallocs++;
21017ab2063SBarry Smith       }
211416022c9SBarry Smith       N = nrow++ - 1; a->nz++;
212416022c9SBarry Smith       /* shift up all the later entries in this row */
213416022c9SBarry Smith       for (ii=N; ii>=i; ii--) {
21417ab2063SBarry Smith         rp[ii+1] = rp[ii];
21517ab2063SBarry Smith         ap[ii+1] = ap[ii];
21617ab2063SBarry Smith       }
21717ab2063SBarry Smith       rp[i] = col;
21817ab2063SBarry Smith       ap[i] = value;
21917ab2063SBarry Smith       noinsert:;
220416022c9SBarry Smith       low = i + 1;
22117ab2063SBarry Smith     }
22217ab2063SBarry Smith     ailen[row] = nrow;
22317ab2063SBarry Smith   }
2243a40ed3dSBarry Smith   PetscFunctionReturn(0);
22517ab2063SBarry Smith }
22617ab2063SBarry Smith 
2274a2ae208SSatish Balay #undef __FUNCT__
2284a2ae208SSatish Balay #define __FUNCT__ "MatGetValues_SeqAIJ"
22987828ca2SBarry Smith int MatGetValues_SeqAIJ(Mat A,int m,int *im,int n,int *in,PetscScalar *v)
2307eb43aa7SLois Curfman McInnes {
2317eb43aa7SLois Curfman McInnes   Mat_SeqAIJ   *a = (Mat_SeqAIJ*)A->data;
232b49de8d1SLois Curfman McInnes   int          *rp,k,low,high,t,row,nrow,i,col,l,*aj = a->j;
2337eb43aa7SLois Curfman McInnes   int          *ai = a->i,*ailen = a->ilen,shift = a->indexshift;
23487828ca2SBarry Smith   PetscScalar  *ap,*aa = a->a,zero = 0.0;
2357eb43aa7SLois Curfman McInnes 
2363a40ed3dSBarry Smith   PetscFunctionBegin;
2377eb43aa7SLois Curfman McInnes   for (k=0; k<m; k++) { /* loop over rows */
2387eb43aa7SLois Curfman McInnes     row  = im[k];
23929bbc08cSBarry Smith     if (row < 0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Negative row: %d",row);
240273d9f13SBarry Smith     if (row >= A->m) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Row too large: %d",row);
2417eb43aa7SLois Curfman McInnes     rp   = aj + ai[row] + shift; ap = aa + ai[row] + shift;
2427eb43aa7SLois Curfman McInnes     nrow = ailen[row];
2437eb43aa7SLois Curfman McInnes     for (l=0; l<n; l++) { /* loop over columns */
24429bbc08cSBarry Smith       if (in[l] < 0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Negative column: %d",in[l]);
245273d9f13SBarry Smith       if (in[l] >= A->n) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Column too large: %d",in[l]);
2467eb43aa7SLois Curfman McInnes       col = in[l] - shift;
2477eb43aa7SLois Curfman McInnes       high = nrow; low = 0; /* assume unsorted */
2487eb43aa7SLois Curfman McInnes       while (high-low > 5) {
2497eb43aa7SLois Curfman McInnes         t = (low+high)/2;
2507eb43aa7SLois Curfman McInnes         if (rp[t] > col) high = t;
2517eb43aa7SLois Curfman McInnes         else             low  = t;
2527eb43aa7SLois Curfman McInnes       }
2537eb43aa7SLois Curfman McInnes       for (i=low; i<high; i++) {
2547eb43aa7SLois Curfman McInnes         if (rp[i] > col) break;
2557eb43aa7SLois Curfman McInnes         if (rp[i] == col) {
256b49de8d1SLois Curfman McInnes           *v++ = ap[i];
2577eb43aa7SLois Curfman McInnes           goto finished;
2587eb43aa7SLois Curfman McInnes         }
2597eb43aa7SLois Curfman McInnes       }
260b49de8d1SLois Curfman McInnes       *v++ = zero;
2617eb43aa7SLois Curfman McInnes       finished:;
2627eb43aa7SLois Curfman McInnes     }
2637eb43aa7SLois Curfman McInnes   }
2643a40ed3dSBarry Smith   PetscFunctionReturn(0);
2657eb43aa7SLois Curfman McInnes }
2667eb43aa7SLois Curfman McInnes 
26717ab2063SBarry Smith 
2684a2ae208SSatish Balay #undef __FUNCT__
2694a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqAIJ_Binary"
270b0a32e0cSBarry Smith int MatView_SeqAIJ_Binary(Mat A,PetscViewer viewer)
27117ab2063SBarry Smith {
272416022c9SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
273416022c9SBarry Smith   int        i,fd,*col_lens,ierr;
27417ab2063SBarry Smith 
2753a40ed3dSBarry Smith   PetscFunctionBegin;
276b0a32e0cSBarry Smith   ierr = PetscViewerBinaryGetDescriptor(viewer,&fd);CHKERRQ(ierr);
277b0a32e0cSBarry Smith   ierr = PetscMalloc((4+A->m)*sizeof(int),&col_lens);CHKERRQ(ierr);
278552e946dSBarry Smith   col_lens[0] = MAT_FILE_COOKIE;
279273d9f13SBarry Smith   col_lens[1] = A->m;
280273d9f13SBarry Smith   col_lens[2] = A->n;
281416022c9SBarry Smith   col_lens[3] = a->nz;
282416022c9SBarry Smith 
283416022c9SBarry Smith   /* store lengths of each row and write (including header) to file */
284273d9f13SBarry Smith   for (i=0; i<A->m; i++) {
285416022c9SBarry Smith     col_lens[4+i] = a->i[i+1] - a->i[i];
28617ab2063SBarry Smith   }
287273d9f13SBarry Smith   ierr = PetscBinaryWrite(fd,col_lens,4+A->m,PETSC_INT,1);CHKERRQ(ierr);
288606d414cSSatish Balay   ierr = PetscFree(col_lens);CHKERRQ(ierr);
289416022c9SBarry Smith 
290416022c9SBarry Smith   /* store column indices (zero start index) */
291416022c9SBarry Smith   if (a->indexshift) {
292416022c9SBarry Smith     for (i=0; i<a->nz; i++) a->j[i]--;
29317ab2063SBarry Smith   }
2940752156aSBarry Smith   ierr = PetscBinaryWrite(fd,a->j,a->nz,PETSC_INT,0);CHKERRQ(ierr);
295416022c9SBarry Smith   if (a->indexshift) {
296416022c9SBarry Smith     for (i=0; i<a->nz; i++) a->j[i]++;
29717ab2063SBarry Smith   }
298416022c9SBarry Smith 
299416022c9SBarry Smith   /* store nonzero values */
3000752156aSBarry Smith   ierr = PetscBinaryWrite(fd,a->a,a->nz,PETSC_SCALAR,0);CHKERRQ(ierr);
3013a40ed3dSBarry Smith   PetscFunctionReturn(0);
30217ab2063SBarry Smith }
303416022c9SBarry Smith 
3047f43a090SHong Zhang extern int MatSeqAIJFactorInfo_SuperLU(Mat,PetscViewer);
305cd155464SBarry Smith extern int MatMPIAIJFactorInfo_SuperLu(Mat,PetscViewer);
306a072f7f7SHong Zhang extern int MatFactorInfo_Spooles(Mat,PetscViewer);
307e7420845SHong Zhang extern int MatSeqAIJFactorInfo_UMFPACK(Mat,PetscViewer);
308cd155464SBarry Smith 
3094a2ae208SSatish Balay #undef __FUNCT__
3104a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqAIJ_ASCII"
311b0a32e0cSBarry Smith int MatView_SeqAIJ_ASCII(Mat A,PetscViewer viewer)
312416022c9SBarry Smith {
313416022c9SBarry Smith   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
314fb9695e5SSatish Balay   int               ierr,i,j,m = A->m,shift = a->indexshift;
315fb9695e5SSatish Balay   char              *name;
316f3ef73ceSBarry Smith   PetscViewerFormat format;
31717ab2063SBarry Smith 
3183a40ed3dSBarry Smith   PetscFunctionBegin;
319435da068SBarry Smith   ierr = PetscObjectGetName((PetscObject)A,&name);CHKERRQ(ierr);
320b0a32e0cSBarry Smith   ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr);
321456192e2SBarry Smith   if (format == PETSC_VIEWER_ASCII_INFO_DETAIL || format == PETSC_VIEWER_ASCII_INFO) {
3226831982aSBarry Smith     if (a->inode.size) {
323b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"using I-node routines: found %d nodes, limit used is %d\n",a->inode.node_count,a->inode.limit);CHKERRQ(ierr);
3246831982aSBarry Smith     } else {
325b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"not using I-node routines\n");CHKERRQ(ierr);
3266831982aSBarry Smith     }
327fb9695e5SSatish Balay   } else if (format == PETSC_VIEWER_ASCII_MATLAB) {
328d00d2cf4SBarry Smith     int nofinalvalue = 0;
329273d9f13SBarry Smith     if ((a->i[m] == a->i[m-1]) || (a->j[a->nz-1] != A->n-!shift)) {
330d00d2cf4SBarry Smith       nofinalvalue = 1;
331d00d2cf4SBarry Smith     }
332b0a32e0cSBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_NO);CHKERRQ(ierr);
333b0a32e0cSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"%% Size = %d %d \n",m,A->n);CHKERRQ(ierr);
334b0a32e0cSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"%% Nonzeros = %d \n",a->nz);CHKERRQ(ierr);
335b0a32e0cSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"zzz = zeros(%d,3);\n",a->nz+nofinalvalue);CHKERRQ(ierr);
336b0a32e0cSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"zzz = [\n");CHKERRQ(ierr);
33717ab2063SBarry Smith 
33817ab2063SBarry Smith     for (i=0; i<m; i++) {
339416022c9SBarry Smith       for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) {
340aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
341b0a32e0cSBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"%d %d  %18.16e + %18.16ei \n",i+1,a->j[j]+!shift,PetscRealPart(a->a[j]),PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
34217ab2063SBarry Smith #else
343b0a32e0cSBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"%d %d  %18.16e\n",i+1,a->j[j]+!shift,a->a[j]);CHKERRQ(ierr);
34417ab2063SBarry Smith #endif
34517ab2063SBarry Smith       }
34617ab2063SBarry Smith     }
347d00d2cf4SBarry Smith     if (nofinalvalue) {
348b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"%d %d  %18.16e\n",m,A->n,0.0);CHKERRQ(ierr);
349d00d2cf4SBarry Smith     }
350fb9695e5SSatish Balay     ierr = PetscViewerASCIIPrintf(viewer,"];\n %s = spconvert(zzz);\n",name);CHKERRQ(ierr);
351b0a32e0cSBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_YES);CHKERRQ(ierr);
352cd155464SBarry Smith   } else if (format == PETSC_VIEWER_ASCII_FACTOR_INFO) {
3537f43a090SHong Zhang #if defined(PETSC_HAVE_SUPERLU) && !defined(PETSC_USE_SINGLE) && !defined(PETSC_USE_COMPLEX)
3547f43a090SHong Zhang      ierr = MatSeqAIJFactorInfo_SuperLU(A,viewer);CHKERRQ(ierr);
3557f43a090SHong Zhang #endif
356cd155464SBarry Smith #if defined(PETSC_HAVE_SUPERLUDIST) && !defined(PETSC_USE_SINGLE) && !defined(PETSC_USE_COMPLEX)
357cd155464SBarry Smith      ierr = MatMPIAIJFactorInfo_SuperLu(A,viewer);CHKERRQ(ierr);
358cd155464SBarry Smith #endif
359174d842dSHong Zhang #if defined(PETSC_HAVE_SPOOLES) && !defined(PETSC_USE_SINGLE) && !defined(PETSC_USE_COMPLEX)
360a072f7f7SHong Zhang      ierr = MatFactorInfo_Spooles(A,viewer);CHKERRQ(ierr);
361174d842dSHong Zhang #endif
362e7420845SHong Zhang #if defined(PETSC_HAVE_UMFPACK) && !defined(PETSC_USE_SINGLE) && !defined(PETSC_USE_COMPLEX)
363e7420845SHong Zhang      ierr = MatSeqAIJFactorInfo_UMFPACK(A,viewer);CHKERRQ(ierr);
364e7420845SHong Zhang #endif
365cd155464SBarry Smith      PetscFunctionReturn(0);
366fb9695e5SSatish Balay   } else if (format == PETSC_VIEWER_ASCII_COMMON) {
367b0a32e0cSBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_NO);CHKERRQ(ierr);
36844cd7ae7SLois Curfman McInnes     for (i=0; i<m; i++) {
369b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"row %d:",i);CHKERRQ(ierr);
37044cd7ae7SLois Curfman McInnes       for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) {
371aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
37236db0b34SBarry Smith         if (PetscImaginaryPart(a->a[j]) > 0.0 && PetscRealPart(a->a[j]) != 0.0) {
37362b941d6SBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%d, %g + %g i)",a->j[j]+shift,PetscRealPart(a->a[j]),PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
37436db0b34SBarry Smith         } else if (PetscImaginaryPart(a->a[j]) < 0.0 && PetscRealPart(a->a[j]) != 0.0) {
37562b941d6SBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%d, %g - %g i)",a->j[j]+shift,PetscRealPart(a->a[j]),-PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
37636db0b34SBarry Smith         } else if (PetscRealPart(a->a[j]) != 0.0) {
37762b941d6SBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%d, %g) ",a->j[j]+shift,PetscRealPart(a->a[j]));CHKERRQ(ierr);
3786831982aSBarry Smith         }
37944cd7ae7SLois Curfman McInnes #else
38062b941d6SBarry Smith         if (a->a[j] != 0.0) {ierr = PetscViewerASCIIPrintf(viewer," (%d, %g) ",a->j[j]+shift,a->a[j]);CHKERRQ(ierr);}
38144cd7ae7SLois Curfman McInnes #endif
38244cd7ae7SLois Curfman McInnes       }
383b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
38444cd7ae7SLois Curfman McInnes     }
385b0a32e0cSBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_YES);CHKERRQ(ierr);
386fb9695e5SSatish Balay   } else if (format == PETSC_VIEWER_ASCII_SYMMODU) {
387496be53dSLois Curfman McInnes     int nzd=0,fshift=1,*sptr;
388b0a32e0cSBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_NO);CHKERRQ(ierr);
389b0a32e0cSBarry Smith     ierr = PetscMalloc((m+1)*sizeof(int),&sptr);CHKERRQ(ierr);
390496be53dSLois Curfman McInnes     for (i=0; i<m; i++) {
391496be53dSLois Curfman McInnes       sptr[i] = nzd+1;
392496be53dSLois Curfman McInnes       for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) {
393496be53dSLois Curfman McInnes         if (a->j[j] >= i) {
394aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
39536db0b34SBarry Smith           if (PetscImaginaryPart(a->a[j]) != 0.0 || PetscRealPart(a->a[j]) != 0.0) nzd++;
396496be53dSLois Curfman McInnes #else
397496be53dSLois Curfman McInnes           if (a->a[j] != 0.0) nzd++;
398496be53dSLois Curfman McInnes #endif
399496be53dSLois Curfman McInnes         }
400496be53dSLois Curfman McInnes       }
401496be53dSLois Curfman McInnes     }
4022e44a96cSLois Curfman McInnes     sptr[m] = nzd+1;
403b0a32e0cSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer," %d %d\n\n",m,nzd);CHKERRQ(ierr);
4042e44a96cSLois Curfman McInnes     for (i=0; i<m+1; i+=6) {
405b0a32e0cSBarry Smith       if (i+4<m) {ierr = PetscViewerASCIIPrintf(viewer," %d %d %d %d %d %d\n",sptr[i],sptr[i+1],sptr[i+2],sptr[i+3],sptr[i+4],sptr[i+5]);CHKERRQ(ierr);}
406b0a32e0cSBarry Smith       else if (i+3<m) {ierr = PetscViewerASCIIPrintf(viewer," %d %d %d %d %d\n",sptr[i],sptr[i+1],sptr[i+2],sptr[i+3],sptr[i+4]);CHKERRQ(ierr);}
407b0a32e0cSBarry Smith       else if (i+2<m) {ierr = PetscViewerASCIIPrintf(viewer," %d %d %d %d\n",sptr[i],sptr[i+1],sptr[i+2],sptr[i+3]);CHKERRQ(ierr);}
408b0a32e0cSBarry Smith       else if (i+1<m) {ierr = PetscViewerASCIIPrintf(viewer," %d %d %d\n",sptr[i],sptr[i+1],sptr[i+2]);CHKERRQ(ierr);}
409b0a32e0cSBarry Smith       else if (i<m)   {ierr = PetscViewerASCIIPrintf(viewer," %d %d\n",sptr[i],sptr[i+1]);CHKERRQ(ierr);}
410b0a32e0cSBarry Smith       else            {ierr = PetscViewerASCIIPrintf(viewer," %d\n",sptr[i]);CHKERRQ(ierr);}
411496be53dSLois Curfman McInnes     }
412b0a32e0cSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
413606d414cSSatish Balay     ierr = PetscFree(sptr);CHKERRQ(ierr);
414496be53dSLois Curfman McInnes     for (i=0; i<m; i++) {
415496be53dSLois Curfman McInnes       for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) {
416b0a32e0cSBarry Smith         if (a->j[j] >= i) {ierr = PetscViewerASCIIPrintf(viewer," %d ",a->j[j]+fshift);CHKERRQ(ierr);}
417496be53dSLois Curfman McInnes       }
418b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
419496be53dSLois Curfman McInnes     }
420b0a32e0cSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
421496be53dSLois Curfman McInnes     for (i=0; i<m; i++) {
422496be53dSLois Curfman McInnes       for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) {
423496be53dSLois Curfman McInnes         if (a->j[j] >= i) {
424aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
42536db0b34SBarry Smith           if (PetscImaginaryPart(a->a[j]) != 0.0 || PetscRealPart(a->a[j]) != 0.0) {
426b0a32e0cSBarry Smith             ierr = PetscViewerASCIIPrintf(viewer," %18.16e %18.16e ",PetscRealPart(a->a[j]),PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
4276831982aSBarry Smith           }
428496be53dSLois Curfman McInnes #else
429b0a32e0cSBarry Smith           if (a->a[j] != 0.0) {ierr = PetscViewerASCIIPrintf(viewer," %18.16e ",a->a[j]);CHKERRQ(ierr);}
430496be53dSLois Curfman McInnes #endif
431496be53dSLois Curfman McInnes         }
432496be53dSLois Curfman McInnes       }
433b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
434496be53dSLois Curfman McInnes     }
435b0a32e0cSBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_YES);CHKERRQ(ierr);
436fb9695e5SSatish Balay   } else if (format == PETSC_VIEWER_ASCII_DENSE) {
43702594712SBarry Smith     int         cnt = 0,jcnt;
43887828ca2SBarry Smith     PetscScalar value;
43902594712SBarry Smith 
440b0a32e0cSBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_NO);CHKERRQ(ierr);
44102594712SBarry Smith     for (i=0; i<m; i++) {
44202594712SBarry Smith       jcnt = 0;
443273d9f13SBarry Smith       for (j=0; j<A->n; j++) {
444e24b481bSBarry Smith         if (jcnt < a->i[i+1]-a->i[i] && j == a->j[cnt]) {
44502594712SBarry Smith           value = a->a[cnt++];
446e24b481bSBarry Smith           jcnt++;
44702594712SBarry Smith         } else {
44802594712SBarry Smith           value = 0.0;
44902594712SBarry Smith         }
450aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
451b0a32e0cSBarry Smith         ierr = PetscViewerASCIIPrintf(viewer," %7.5e+%7.5e i ",PetscRealPart(value),PetscImaginaryPart(value));CHKERRQ(ierr);
45202594712SBarry Smith #else
453b0a32e0cSBarry Smith         ierr = PetscViewerASCIIPrintf(viewer," %7.5e ",value);CHKERRQ(ierr);
45402594712SBarry Smith #endif
45502594712SBarry Smith       }
456b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
45702594712SBarry Smith     }
458b0a32e0cSBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_YES);CHKERRQ(ierr);
4593a40ed3dSBarry Smith   } else {
460b0a32e0cSBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_NO);CHKERRQ(ierr);
46117ab2063SBarry Smith     for (i=0; i<m; i++) {
462b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"row %d:",i);CHKERRQ(ierr);
463416022c9SBarry Smith       for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) {
464aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
46536db0b34SBarry Smith         if (PetscImaginaryPart(a->a[j]) > 0.0) {
46662b941d6SBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%d, %g + %g i)",a->j[j]+shift,PetscRealPart(a->a[j]),PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
46736db0b34SBarry Smith         } else if (PetscImaginaryPart(a->a[j]) < 0.0) {
46862b941d6SBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%d, %g - %g i)",a->j[j]+shift,PetscRealPart(a->a[j]),-PetscImaginaryPart(a->a[j]));CHKERRQ(ierr);
4693a40ed3dSBarry Smith         } else {
47062b941d6SBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%d, %g) ",a->j[j]+shift,PetscRealPart(a->a[j]));CHKERRQ(ierr);
47117ab2063SBarry Smith         }
47217ab2063SBarry Smith #else
47362b941d6SBarry Smith         ierr = PetscViewerASCIIPrintf(viewer," (%d, %g) ",a->j[j]+shift,a->a[j]);CHKERRQ(ierr);
47417ab2063SBarry Smith #endif
47517ab2063SBarry Smith       }
476b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
47717ab2063SBarry Smith     }
478b0a32e0cSBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_YES);CHKERRQ(ierr);
47917ab2063SBarry Smith   }
480b0a32e0cSBarry Smith   ierr = PetscViewerFlush(viewer);CHKERRQ(ierr);
4813a40ed3dSBarry Smith   PetscFunctionReturn(0);
482416022c9SBarry Smith }
483416022c9SBarry Smith 
4844a2ae208SSatish Balay #undef __FUNCT__
4854a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqAIJ_Draw_Zoom"
486b0a32e0cSBarry Smith int MatView_SeqAIJ_Draw_Zoom(PetscDraw draw,void *Aa)
487416022c9SBarry Smith {
488480ef9eaSBarry Smith   Mat               A = (Mat) Aa;
489416022c9SBarry Smith   Mat_SeqAIJ        *a = (Mat_SeqAIJ*)A->data;
490273d9f13SBarry Smith   int               ierr,i,j,m = A->m,shift = a->indexshift,color;
49136db0b34SBarry Smith   PetscReal         xl,yl,xr,yr,x_l,x_r,y_l,y_r,maxv = 0.0;
492b0a32e0cSBarry Smith   PetscViewer       viewer;
493f3ef73ceSBarry Smith   PetscViewerFormat format;
494cddf8d76SBarry Smith 
4953a40ed3dSBarry Smith   PetscFunctionBegin;
496480ef9eaSBarry Smith   ierr = PetscObjectQuery((PetscObject)A,"Zoomviewer",(PetscObject*)&viewer);CHKERRQ(ierr);
497b0a32e0cSBarry Smith   ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr);
49819bcc07fSBarry Smith 
499b0a32e0cSBarry Smith   ierr = PetscDrawGetCoordinates(draw,&xl,&yl,&xr,&yr);CHKERRQ(ierr);
500416022c9SBarry Smith   /* loop over matrix elements drawing boxes */
5010513a670SBarry Smith 
502fb9695e5SSatish Balay   if (format != PETSC_VIEWER_DRAW_CONTOUR) {
5030513a670SBarry Smith     /* Blue for negative, Cyan for zero and  Red for positive */
504b0a32e0cSBarry Smith     color = PETSC_DRAW_BLUE;
505416022c9SBarry Smith     for (i=0; i<m; i++) {
506cddf8d76SBarry Smith       y_l = m - i - 1.0; y_r = y_l + 1.0;
507416022c9SBarry Smith       for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) {
508cddf8d76SBarry Smith         x_l = a->j[j] + shift; x_r = x_l + 1.0;
509aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
51036db0b34SBarry Smith         if (PetscRealPart(a->a[j]) >=  0.) continue;
511cddf8d76SBarry Smith #else
512cddf8d76SBarry Smith         if (a->a[j] >=  0.) continue;
513cddf8d76SBarry Smith #endif
514b0a32e0cSBarry Smith         ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr);
515cddf8d76SBarry Smith       }
516cddf8d76SBarry Smith     }
517b0a32e0cSBarry Smith     color = PETSC_DRAW_CYAN;
518cddf8d76SBarry Smith     for (i=0; i<m; i++) {
519cddf8d76SBarry Smith       y_l = m - i - 1.0; y_r = y_l + 1.0;
520cddf8d76SBarry Smith       for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) {
521cddf8d76SBarry Smith         x_l = a->j[j] + shift; x_r = x_l + 1.0;
522cddf8d76SBarry Smith         if (a->a[j] !=  0.) continue;
523b0a32e0cSBarry Smith         ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr);
524cddf8d76SBarry Smith       }
525cddf8d76SBarry Smith     }
526b0a32e0cSBarry Smith     color = PETSC_DRAW_RED;
527cddf8d76SBarry Smith     for (i=0; i<m; i++) {
528cddf8d76SBarry Smith       y_l = m - i - 1.0; y_r = y_l + 1.0;
529cddf8d76SBarry Smith       for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) {
530cddf8d76SBarry Smith         x_l = a->j[j] + shift; x_r = x_l + 1.0;
531aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
53236db0b34SBarry Smith         if (PetscRealPart(a->a[j]) <=  0.) continue;
533cddf8d76SBarry Smith #else
534cddf8d76SBarry Smith         if (a->a[j] <=  0.) continue;
535cddf8d76SBarry Smith #endif
536b0a32e0cSBarry Smith         ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr);
537416022c9SBarry Smith       }
538416022c9SBarry Smith     }
5390513a670SBarry Smith   } else {
5400513a670SBarry Smith     /* use contour shading to indicate magnitude of values */
5410513a670SBarry Smith     /* first determine max of all nonzero values */
5420513a670SBarry Smith     int    nz = a->nz,count;
543b0a32e0cSBarry Smith     PetscDraw   popup;
54436db0b34SBarry Smith     PetscReal scale;
5450513a670SBarry Smith 
5460513a670SBarry Smith     for (i=0; i<nz; i++) {
5470513a670SBarry Smith       if (PetscAbsScalar(a->a[i]) > maxv) maxv = PetscAbsScalar(a->a[i]);
5480513a670SBarry Smith     }
549b0a32e0cSBarry Smith     scale = (245.0 - PETSC_DRAW_BASIC_COLORS)/maxv;
550b0a32e0cSBarry Smith     ierr  = PetscDrawGetPopup(draw,&popup);CHKERRQ(ierr);
551b0a32e0cSBarry Smith     if (popup) {ierr  = PetscDrawScalePopup(popup,0.0,maxv);CHKERRQ(ierr);}
5520513a670SBarry Smith     count = 0;
5530513a670SBarry Smith     for (i=0; i<m; i++) {
5540513a670SBarry Smith       y_l = m - i - 1.0; y_r = y_l + 1.0;
5550513a670SBarry Smith       for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) {
5560513a670SBarry Smith         x_l = a->j[j] + shift; x_r = x_l + 1.0;
557b0a32e0cSBarry Smith         color = PETSC_DRAW_BASIC_COLORS + (int)(scale*PetscAbsScalar(a->a[count]));
558b0a32e0cSBarry Smith         ierr  = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr);
5590513a670SBarry Smith         count++;
5600513a670SBarry Smith       }
5610513a670SBarry Smith     }
5620513a670SBarry Smith   }
563480ef9eaSBarry Smith   PetscFunctionReturn(0);
564480ef9eaSBarry Smith }
565cddf8d76SBarry Smith 
5664a2ae208SSatish Balay #undef __FUNCT__
5674a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqAIJ_Draw"
568b0a32e0cSBarry Smith int MatView_SeqAIJ_Draw(Mat A,PetscViewer viewer)
569480ef9eaSBarry Smith {
570480ef9eaSBarry Smith   int        ierr;
571b0a32e0cSBarry Smith   PetscDraw  draw;
57236db0b34SBarry Smith   PetscReal  xr,yr,xl,yl,h,w;
573480ef9eaSBarry Smith   PetscTruth isnull;
574480ef9eaSBarry Smith 
575480ef9eaSBarry Smith   PetscFunctionBegin;
576b0a32e0cSBarry Smith   ierr = PetscViewerDrawGetDraw(viewer,0,&draw);CHKERRQ(ierr);
577b0a32e0cSBarry Smith   ierr = PetscDrawIsNull(draw,&isnull);CHKERRQ(ierr);
578480ef9eaSBarry Smith   if (isnull) PetscFunctionReturn(0);
579480ef9eaSBarry Smith 
580480ef9eaSBarry Smith   ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",(PetscObject)viewer);CHKERRQ(ierr);
581273d9f13SBarry Smith   xr  = A->n; yr = A->m; h = yr/10.0; w = xr/10.0;
582480ef9eaSBarry Smith   xr += w;    yr += h;  xl = -w;     yl = -h;
583b0a32e0cSBarry Smith   ierr = PetscDrawSetCoordinates(draw,xl,yl,xr,yr);CHKERRQ(ierr);
584b0a32e0cSBarry Smith   ierr = PetscDrawZoom(draw,MatView_SeqAIJ_Draw_Zoom,A);CHKERRQ(ierr);
585480ef9eaSBarry Smith   ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",PETSC_NULL);CHKERRQ(ierr);
5863a40ed3dSBarry Smith   PetscFunctionReturn(0);
587416022c9SBarry Smith }
588416022c9SBarry Smith 
5894a2ae208SSatish Balay #undef __FUNCT__
5904a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqAIJ"
591b0a32e0cSBarry Smith int MatView_SeqAIJ(Mat A,PetscViewer viewer)
592416022c9SBarry Smith {
593416022c9SBarry Smith   Mat_SeqAIJ  *a = (Mat_SeqAIJ*)A->data;
594bcd2baecSBarry Smith   int         ierr;
5956831982aSBarry Smith   PetscTruth  issocket,isascii,isbinary,isdraw;
596416022c9SBarry Smith 
5973a40ed3dSBarry Smith   PetscFunctionBegin;
598b0a32e0cSBarry Smith   ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_SOCKET,&issocket);CHKERRQ(ierr);
599b0a32e0cSBarry Smith   ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&isascii);CHKERRQ(ierr);
600fb9695e5SSatish Balay   ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_BINARY,&isbinary);CHKERRQ(ierr);
601fb9695e5SSatish Balay   ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_DRAW,&isdraw);CHKERRQ(ierr);
6020f5bd95cSBarry Smith   if (issocket) {
60301820c62SBarry Smith     if (a->indexshift) {
60429bbc08cSBarry Smith       SETERRQ(1,"Can only socket send sparse matrix with 0 based indexing");
60501820c62SBarry Smith     }
606b0a32e0cSBarry Smith     ierr = PetscViewerSocketPutSparse_Private(viewer,A->m,A->n,a->nz,a->a,a->i,a->j);CHKERRQ(ierr);
6070f5bd95cSBarry Smith   } else if (isascii) {
6083a40ed3dSBarry Smith     ierr = MatView_SeqAIJ_ASCII(A,viewer);CHKERRQ(ierr);
6090f5bd95cSBarry Smith   } else if (isbinary) {
6103a40ed3dSBarry Smith     ierr = MatView_SeqAIJ_Binary(A,viewer);CHKERRQ(ierr);
6110f5bd95cSBarry Smith   } else if (isdraw) {
6123a40ed3dSBarry Smith     ierr = MatView_SeqAIJ_Draw(A,viewer);CHKERRQ(ierr);
6135cd90555SBarry Smith   } else {
61429bbc08cSBarry Smith     SETERRQ1(1,"Viewer type %s not supported by SeqAIJ matrices",((PetscObject)viewer)->type_name);
61517ab2063SBarry Smith   }
6163a40ed3dSBarry Smith   PetscFunctionReturn(0);
61717ab2063SBarry Smith }
61819bcc07fSBarry Smith 
6193a7fca6bSBarry Smith EXTERN int Mat_AIJ_CheckInode(Mat,PetscTruth);
6204a2ae208SSatish Balay #undef __FUNCT__
6214a2ae208SSatish Balay #define __FUNCT__ "MatAssemblyEnd_SeqAIJ"
6228f6be9afSLois Curfman McInnes int MatAssemblyEnd_SeqAIJ(Mat A,MatAssemblyType mode)
62317ab2063SBarry Smith {
624416022c9SBarry Smith   Mat_SeqAIJ   *a = (Mat_SeqAIJ*)A->data;
62541c01911SSatish Balay   int          fshift = 0,i,j,*ai = a->i,*aj = a->j,*imax = a->imax,ierr;
626273d9f13SBarry Smith   int          m = A->m,*ip,N,*ailen = a->ilen,shift = a->indexshift,rmax = 0;
62787828ca2SBarry Smith   PetscScalar  *aa = a->a,*ap;
628564e58d6SHong Zhang #if defined(PETSC_HAVE_SUPERLUDIST) || defined(PETSC_HAVE_SPOOLES) || defined(PETSC_HAVE_UMFPACK)
6299b9367d5SHong Zhang   PetscTruth   flag;
6309e070d67SMatthew Knepley #endif
63117ab2063SBarry Smith 
6323a40ed3dSBarry Smith   PetscFunctionBegin;
6333a40ed3dSBarry Smith   if (mode == MAT_FLUSH_ASSEMBLY) PetscFunctionReturn(0);
63417ab2063SBarry Smith 
63543ee02c3SBarry Smith   if (m) rmax = ailen[0]; /* determine row with most nonzeros */
63617ab2063SBarry Smith   for (i=1; i<m; i++) {
637416022c9SBarry Smith     /* move each row back by the amount of empty slots (fshift) before it*/
63817ab2063SBarry Smith     fshift += imax[i-1] - ailen[i-1];
63994a9d846SBarry Smith     rmax   = PetscMax(rmax,ailen[i]);
64017ab2063SBarry Smith     if (fshift) {
6410f5bd95cSBarry Smith       ip = aj + ai[i] + shift;
6420f5bd95cSBarry Smith       ap = aa + ai[i] + shift;
64317ab2063SBarry Smith       N  = ailen[i];
64417ab2063SBarry Smith       for (j=0; j<N; j++) {
64517ab2063SBarry Smith         ip[j-fshift] = ip[j];
64617ab2063SBarry Smith         ap[j-fshift] = ap[j];
64717ab2063SBarry Smith       }
64817ab2063SBarry Smith     }
64917ab2063SBarry Smith     ai[i] = ai[i-1] + ailen[i-1];
65017ab2063SBarry Smith   }
65117ab2063SBarry Smith   if (m) {
65217ab2063SBarry Smith     fshift += imax[m-1] - ailen[m-1];
65317ab2063SBarry Smith     ai[m]  = ai[m-1] + ailen[m-1];
65417ab2063SBarry Smith   }
65517ab2063SBarry Smith   /* reset ilen and imax for each row */
65617ab2063SBarry Smith   for (i=0; i<m; i++) {
65717ab2063SBarry Smith     ailen[i] = imax[i] = ai[i+1] - ai[i];
65817ab2063SBarry Smith   }
659416022c9SBarry Smith   a->nz = ai[m] + shift;
66017ab2063SBarry Smith 
66117ab2063SBarry Smith   /* diagonals may have moved, so kill the diagonal pointers */
662416022c9SBarry Smith   if (fshift && a->diag) {
663606d414cSSatish Balay     ierr = PetscFree(a->diag);CHKERRQ(ierr);
664b0a32e0cSBarry Smith     PetscLogObjectMemory(A,-(m+1)*sizeof(int));
665416022c9SBarry Smith     a->diag = 0;
66617ab2063SBarry Smith   }
667b0a32e0cSBarry Smith   PetscLogInfo(A,"MatAssemblyEnd_SeqAIJ:Matrix size: %d X %d; storage space: %d unneeded,%d used\n",m,A->n,fshift,a->nz);
668b0a32e0cSBarry Smith   PetscLogInfo(A,"MatAssemblyEnd_SeqAIJ:Number of mallocs during MatSetValues() is %d\n",a->reallocs);
669b0a32e0cSBarry Smith   PetscLogInfo(A,"MatAssemblyEnd_SeqAIJ:Most nonzeros in any row is %d\n",rmax);
670dd5f02e7SSatish Balay   a->reallocs          = 0;
6714e220ebcSLois Curfman McInnes   A->info.nz_unneeded  = (double)fshift;
67236db0b34SBarry Smith   a->rmax              = rmax;
6734e220ebcSLois Curfman McInnes 
67476dd722bSSatish Balay   /* check out for identical nodes. If found, use inode functions */
6753a7fca6bSBarry Smith   ierr = Mat_AIJ_CheckInode(A,(PetscTruth)(!fshift));CHKERRQ(ierr);
676cfef3cccSHong Zhang 
6779b9367d5SHong Zhang #if defined(PETSC_HAVE_SUPERLUDIST)
678e82a3eeeSBarry Smith   ierr = PetscOptionsHasName(A->prefix,"-mat_aij_superlu_dist",&flag);CHKERRQ(ierr);
6799b9367d5SHong Zhang   if (flag) { ierr = MatUseSuperLU_DIST_MPIAIJ(A);CHKERRQ(ierr); }
6809b9367d5SHong Zhang #endif
6819b9367d5SHong Zhang 
682cfef3cccSHong Zhang #if defined(PETSC_HAVE_SPOOLES)
683e82a3eeeSBarry Smith   ierr = PetscOptionsHasName(A->prefix,"-mat_aij_spooles",&flag);CHKERRQ(ierr);
684cfef3cccSHong Zhang   if (flag) { ierr = MatUseSpooles_SeqAIJ(A);CHKERRQ(ierr); }
685cfef3cccSHong Zhang #endif
686cfef3cccSHong Zhang 
687564e58d6SHong Zhang #if defined(PETSC_HAVE_UMFPACK)
688e82a3eeeSBarry Smith   ierr = PetscOptionsHasName(A->prefix,"-mat_aij_umfpack",&flag);CHKERRQ(ierr);
689564e58d6SHong Zhang   if (flag) { ierr = MatUseUMFPACK_SeqAIJ(A);CHKERRQ(ierr); }
690564e58d6SHong Zhang #endif
691564e58d6SHong Zhang 
6923a40ed3dSBarry Smith   PetscFunctionReturn(0);
69317ab2063SBarry Smith }
69417ab2063SBarry Smith 
6954a2ae208SSatish Balay #undef __FUNCT__
6964a2ae208SSatish Balay #define __FUNCT__ "MatZeroEntries_SeqAIJ"
6978f6be9afSLois Curfman McInnes int MatZeroEntries_SeqAIJ(Mat A)
69817ab2063SBarry Smith {
699416022c9SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
700549d3d68SSatish Balay   int        ierr;
7013a40ed3dSBarry Smith 
7023a40ed3dSBarry Smith   PetscFunctionBegin;
70387828ca2SBarry Smith   ierr = PetscMemzero(a->a,(a->i[A->m]+a->indexshift)*sizeof(PetscScalar));CHKERRQ(ierr);
7043a40ed3dSBarry Smith   PetscFunctionReturn(0);
70517ab2063SBarry Smith }
706416022c9SBarry Smith 
7074a2ae208SSatish Balay #undef __FUNCT__
7084a2ae208SSatish Balay #define __FUNCT__ "MatDestroy_SeqAIJ"
709e1311b90SBarry Smith int MatDestroy_SeqAIJ(Mat A)
71017ab2063SBarry Smith {
711416022c9SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
71282bf6240SBarry Smith   int        ierr;
713d5d45c9bSBarry Smith 
7143a40ed3dSBarry Smith   PetscFunctionBegin;
715aa482453SBarry Smith #if defined(PETSC_USE_LOG)
716b0a32e0cSBarry Smith   PetscLogObjectState((PetscObject)A,"Rows=%d, Cols=%d, NZ=%d",A->m,A->n,a->nz);
71717ab2063SBarry Smith #endif
71836db0b34SBarry Smith   if (a->freedata) {
719606d414cSSatish Balay     ierr = PetscFree(a->a);CHKERRQ(ierr);
720606d414cSSatish Balay     if (!a->singlemalloc) {
721606d414cSSatish Balay       ierr = PetscFree(a->i);CHKERRQ(ierr);
722606d414cSSatish Balay       ierr = PetscFree(a->j);CHKERRQ(ierr);
723606d414cSSatish Balay     }
72436db0b34SBarry Smith   }
725c38d4ed2SBarry Smith   if (a->row) {
726c38d4ed2SBarry Smith     ierr = ISDestroy(a->row);CHKERRQ(ierr);
727c38d4ed2SBarry Smith   }
728c38d4ed2SBarry Smith   if (a->col) {
729c38d4ed2SBarry Smith     ierr = ISDestroy(a->col);CHKERRQ(ierr);
730c38d4ed2SBarry Smith   }
731606d414cSSatish Balay   if (a->diag) {ierr = PetscFree(a->diag);CHKERRQ(ierr);}
732606d414cSSatish Balay   if (a->ilen) {ierr = PetscFree(a->ilen);CHKERRQ(ierr);}
733606d414cSSatish Balay   if (a->imax) {ierr = PetscFree(a->imax);CHKERRQ(ierr);}
734273d9f13SBarry Smith   if (a->idiag) {ierr = PetscFree(a->idiag);CHKERRQ(ierr);}
735606d414cSSatish Balay   if (a->solve_work) {ierr = PetscFree(a->solve_work);CHKERRQ(ierr);}
736606d414cSSatish Balay   if (a->inode.size) {ierr = PetscFree(a->inode.size);CHKERRQ(ierr);}
73782bf6240SBarry Smith   if (a->icol) {ierr = ISDestroy(a->icol);CHKERRQ(ierr);}
738606d414cSSatish Balay   if (a->saved_values) {ierr = PetscFree(a->saved_values);CHKERRQ(ierr);}
739cc8ba8e1SBarry Smith   if (a->coloring) {ierr = ISColoringDestroy(a->coloring);CHKERRQ(ierr);}
740606d414cSSatish Balay   ierr = PetscFree(a);CHKERRQ(ierr);
7413a40ed3dSBarry Smith   PetscFunctionReturn(0);
74217ab2063SBarry Smith }
74317ab2063SBarry Smith 
7444a2ae208SSatish Balay #undef __FUNCT__
7454a2ae208SSatish Balay #define __FUNCT__ "MatCompress_SeqAIJ"
7468f6be9afSLois Curfman McInnes int MatCompress_SeqAIJ(Mat A)
74717ab2063SBarry Smith {
7483a40ed3dSBarry Smith   PetscFunctionBegin;
7493a40ed3dSBarry Smith   PetscFunctionReturn(0);
75017ab2063SBarry Smith }
75117ab2063SBarry Smith 
7524a2ae208SSatish Balay #undef __FUNCT__
7534a2ae208SSatish Balay #define __FUNCT__ "MatSetOption_SeqAIJ"
7548f6be9afSLois Curfman McInnes int MatSetOption_SeqAIJ(Mat A,MatOption op)
75517ab2063SBarry Smith {
756416022c9SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
7573a40ed3dSBarry Smith 
7583a40ed3dSBarry Smith   PetscFunctionBegin;
759a65d3064SKris Buschelman   switch (op) {
760a65d3064SKris Buschelman     case MAT_ROW_ORIENTED:
761a65d3064SKris Buschelman       a->roworiented       = PETSC_TRUE;
762a65d3064SKris Buschelman       break;
763a65d3064SKris Buschelman     case MAT_KEEP_ZEROED_ROWS:
764a65d3064SKris Buschelman       a->keepzeroedrows    = PETSC_TRUE;
765a65d3064SKris Buschelman       break;
766a65d3064SKris Buschelman     case MAT_COLUMN_ORIENTED:
767a65d3064SKris Buschelman       a->roworiented       = PETSC_FALSE;
768a65d3064SKris Buschelman       break;
769a65d3064SKris Buschelman     case MAT_COLUMNS_SORTED:
770a65d3064SKris Buschelman       a->sorted            = PETSC_TRUE;
771a65d3064SKris Buschelman       break;
772a65d3064SKris Buschelman     case MAT_COLUMNS_UNSORTED:
773a65d3064SKris Buschelman       a->sorted            = PETSC_FALSE;
774a65d3064SKris Buschelman       break;
775a65d3064SKris Buschelman     case MAT_NO_NEW_NONZERO_LOCATIONS:
776a65d3064SKris Buschelman       a->nonew             = 1;
777a65d3064SKris Buschelman       break;
778a65d3064SKris Buschelman     case MAT_NEW_NONZERO_LOCATION_ERR:
779a65d3064SKris Buschelman       a->nonew             = -1;
780a65d3064SKris Buschelman       break;
781a65d3064SKris Buschelman     case MAT_NEW_NONZERO_ALLOCATION_ERR:
782a65d3064SKris Buschelman       a->nonew             = -2;
783a65d3064SKris Buschelman       break;
784a65d3064SKris Buschelman     case MAT_YES_NEW_NONZERO_LOCATIONS:
785a65d3064SKris Buschelman       a->nonew             = 0;
786a65d3064SKris Buschelman       break;
787a65d3064SKris Buschelman     case MAT_IGNORE_ZERO_ENTRIES:
788a65d3064SKris Buschelman       a->ignorezeroentries = PETSC_TRUE;
789a65d3064SKris Buschelman       break;
790a65d3064SKris Buschelman     case MAT_USE_INODES:
791a65d3064SKris Buschelman       a->inode.use         = PETSC_TRUE;
792a65d3064SKris Buschelman       break;
793a65d3064SKris Buschelman     case MAT_DO_NOT_USE_INODES:
794a65d3064SKris Buschelman       a->inode.use         = PETSC_FALSE;
795a65d3064SKris Buschelman       break;
796a65d3064SKris Buschelman     case MAT_ROWS_SORTED:
797a65d3064SKris Buschelman     case MAT_ROWS_UNSORTED:
798a65d3064SKris Buschelman     case MAT_YES_NEW_DIAGONALS:
799a65d3064SKris Buschelman     case MAT_IGNORE_OFF_PROC_ENTRIES:
800a65d3064SKris Buschelman     case MAT_USE_HASH_TABLE:
801d03495bdSKris Buschelman     case MAT_USE_SINGLE_PRECISION_SOLVES:
802b0a32e0cSBarry Smith       PetscLogInfo(A,"MatSetOption_SeqAIJ:Option ignored\n");
803a65d3064SKris Buschelman       break;
804a65d3064SKris Buschelman     case MAT_NO_NEW_DIAGONALS:
80529bbc08cSBarry Smith       SETERRQ(PETSC_ERR_SUP,"MAT_NO_NEW_DIAGONALS");
806a65d3064SKris Buschelman     case MAT_INODE_LIMIT_1:
807a65d3064SKris Buschelman       a->inode.limit  = 1;
808a65d3064SKris Buschelman       break;
809a65d3064SKris Buschelman     case MAT_INODE_LIMIT_2:
810a65d3064SKris Buschelman       a->inode.limit  = 2;
811a65d3064SKris Buschelman       break;
812a65d3064SKris Buschelman     case MAT_INODE_LIMIT_3:
813a65d3064SKris Buschelman       a->inode.limit  = 3;
814a65d3064SKris Buschelman       break;
815a65d3064SKris Buschelman     case MAT_INODE_LIMIT_4:
816a65d3064SKris Buschelman       a->inode.limit  = 4;
817a65d3064SKris Buschelman       break;
818a65d3064SKris Buschelman     case MAT_INODE_LIMIT_5:
819a65d3064SKris Buschelman       a->inode.limit  = 5;
820a65d3064SKris Buschelman       break;
821a65d3064SKris Buschelman     default:
822a65d3064SKris Buschelman       SETERRQ(PETSC_ERR_SUP,"unknown option");
823a65d3064SKris Buschelman   }
8243a40ed3dSBarry Smith   PetscFunctionReturn(0);
82517ab2063SBarry Smith }
82617ab2063SBarry Smith 
8274a2ae208SSatish Balay #undef __FUNCT__
8284a2ae208SSatish Balay #define __FUNCT__ "MatGetDiagonal_SeqAIJ"
8298f6be9afSLois Curfman McInnes int MatGetDiagonal_SeqAIJ(Mat A,Vec v)
83017ab2063SBarry Smith {
831416022c9SBarry Smith   Mat_SeqAIJ   *a = (Mat_SeqAIJ*)A->data;
8323a40ed3dSBarry Smith   int          i,j,n,shift = a->indexshift,ierr;
83387828ca2SBarry Smith   PetscScalar  *x,zero = 0.0;
83417ab2063SBarry Smith 
8353a40ed3dSBarry Smith   PetscFunctionBegin;
8363a40ed3dSBarry Smith   ierr = VecSet(&zero,v);CHKERRQ(ierr);
83736db0b34SBarry Smith   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
83836db0b34SBarry Smith   ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr);
839273d9f13SBarry Smith   if (n != A->m) SETERRQ(PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector");
840273d9f13SBarry Smith   for (i=0; i<A->m; i++) {
841416022c9SBarry Smith     for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) {
842416022c9SBarry Smith       if (a->j[j]+shift == i) {
843416022c9SBarry Smith         x[i] = a->a[j];
84417ab2063SBarry Smith         break;
84517ab2063SBarry Smith       }
84617ab2063SBarry Smith     }
84717ab2063SBarry Smith   }
84836db0b34SBarry Smith   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
8493a40ed3dSBarry Smith   PetscFunctionReturn(0);
85017ab2063SBarry Smith }
85117ab2063SBarry Smith 
852d5d45c9bSBarry Smith 
8534a2ae208SSatish Balay #undef __FUNCT__
8544a2ae208SSatish Balay #define __FUNCT__ "MatMultTransposeAdd_SeqAIJ"
8557c922b88SBarry Smith int MatMultTransposeAdd_SeqAIJ(Mat A,Vec xx,Vec zz,Vec yy)
85617ab2063SBarry Smith {
857416022c9SBarry Smith   Mat_SeqAIJ   *a = (Mat_SeqAIJ*)A->data;
8585c897100SBarry Smith   PetscScalar  *x,*y;
8595c897100SBarry Smith   int          ierr,m = A->m,shift = a->indexshift;
8605c897100SBarry Smith #if !defined(PETSC_USE_FORTRAN_KERNEL_MULTTRANSPOSEAIJ)
8615c897100SBarry Smith   PetscScalar  *v,alpha;
8625c897100SBarry Smith   int          n,i,*idx;
8635c897100SBarry Smith #endif
86417ab2063SBarry Smith 
8653a40ed3dSBarry Smith   PetscFunctionBegin;
8662e8a6d31SBarry Smith   if (zz != yy) {ierr = VecCopy(zz,yy);CHKERRQ(ierr);}
867e1311b90SBarry Smith   ierr = VecGetArray(xx,&x);CHKERRQ(ierr);
868e1311b90SBarry Smith   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
86917ab2063SBarry Smith   y = y + shift; /* shift for Fortran start by 1 indexing */
8705c897100SBarry Smith 
8715c897100SBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_MULTTRANSPOSEAIJ)
8725c897100SBarry Smith   fortranmulttransposeaddaij_(&m,x,a->i,a->j+shift,a->a+shift,y);
8735c897100SBarry Smith #else
87417ab2063SBarry Smith   for (i=0; i<m; i++) {
875416022c9SBarry Smith     idx   = a->j + a->i[i] + shift;
876416022c9SBarry Smith     v     = a->a + a->i[i] + shift;
877416022c9SBarry Smith     n     = a->i[i+1] - a->i[i];
87817ab2063SBarry Smith     alpha = x[i];
87917ab2063SBarry Smith     while (n-->0) {y[*idx++] += alpha * *v++;}
88017ab2063SBarry Smith   }
8815c897100SBarry Smith #endif
882b0a32e0cSBarry Smith   PetscLogFlops(2*a->nz);
883e1311b90SBarry Smith   ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr);
884e1311b90SBarry Smith   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
8853a40ed3dSBarry Smith   PetscFunctionReturn(0);
88617ab2063SBarry Smith }
88717ab2063SBarry Smith 
8884a2ae208SSatish Balay #undef __FUNCT__
8895c897100SBarry Smith #define __FUNCT__ "MatMultTranspose_SeqAIJ"
8905c897100SBarry Smith int MatMultTranspose_SeqAIJ(Mat A,Vec xx,Vec yy)
8915c897100SBarry Smith {
8928d5b0100SBarry Smith   PetscScalar  zero = 0.0;
8935c897100SBarry Smith   int          ierr;
8945c897100SBarry Smith 
8955c897100SBarry Smith   PetscFunctionBegin;
8965c897100SBarry Smith   ierr = VecSet(&zero,yy);CHKERRQ(ierr);
8975c897100SBarry Smith   ierr = MatMultTransposeAdd_SeqAIJ(A,xx,yy,yy);CHKERRQ(ierr);
8985c897100SBarry Smith   PetscFunctionReturn(0);
8995c897100SBarry Smith }
9005c897100SBarry Smith 
9015c897100SBarry Smith 
9025c897100SBarry Smith #undef __FUNCT__
9034a2ae208SSatish Balay #define __FUNCT__ "MatMult_SeqAIJ"
90444cd7ae7SLois Curfman McInnes int MatMult_SeqAIJ(Mat A,Vec xx,Vec yy)
90517ab2063SBarry Smith {
906416022c9SBarry Smith   Mat_SeqAIJ   *a = (Mat_SeqAIJ*)A->data;
907362ced78SSatish Balay   PetscScalar  *x,*y,*v;
908273d9f13SBarry Smith   int          ierr,m = A->m,*idx,shift = a->indexshift,*ii;
909aa482453SBarry Smith #if !defined(PETSC_USE_FORTRAN_KERNEL_MULTAIJ)
910e36a17ebSSatish Balay   int          n,i,jrow,j;
911362ced78SSatish Balay   PetscScalar  sum;
912e36a17ebSSatish Balay #endif
91317ab2063SBarry Smith 
914b6410449SSatish Balay #if defined(PETSC_HAVE_PRAGMA_DISJOINT)
915fee21e36SBarry Smith #pragma disjoint(*x,*y,*v)
916fee21e36SBarry Smith #endif
917fee21e36SBarry Smith 
9183a40ed3dSBarry Smith   PetscFunctionBegin;
919e1311b90SBarry Smith   ierr = VecGetArray(xx,&x);CHKERRQ(ierr);
920e1311b90SBarry Smith   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
92117ab2063SBarry Smith   x    = x + shift;    /* shift for Fortran start by 1 indexing */
922416022c9SBarry Smith   idx  = a->j;
923d64ed03dSBarry Smith   v    = a->a;
924416022c9SBarry Smith   ii   = a->i;
925aa482453SBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_MULTAIJ)
92629b5ca8aSSatish Balay   fortranmultaij_(&m,x,ii,idx+shift,v+shift,y);
9278d195f9aSBarry Smith #else
928d64ed03dSBarry Smith   v    += shift; /* shift for Fortran start by 1 indexing */
929d64ed03dSBarry Smith   idx  += shift;
93017ab2063SBarry Smith   for (i=0; i<m; i++) {
9319ea0dfa2SSatish Balay     jrow = ii[i];
9329ea0dfa2SSatish Balay     n    = ii[i+1] - jrow;
93317ab2063SBarry Smith     sum  = 0.0;
9349ea0dfa2SSatish Balay     for (j=0; j<n; j++) {
9359ea0dfa2SSatish Balay       sum += v[jrow]*x[idx[jrow]]; jrow++;
9369ea0dfa2SSatish Balay      }
93717ab2063SBarry Smith     y[i] = sum;
93817ab2063SBarry Smith   }
9398d195f9aSBarry Smith #endif
940b0a32e0cSBarry Smith   PetscLogFlops(2*a->nz - m);
941e1311b90SBarry Smith   ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr);
942e1311b90SBarry Smith   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
9433a40ed3dSBarry Smith   PetscFunctionReturn(0);
94417ab2063SBarry Smith }
94517ab2063SBarry Smith 
9464a2ae208SSatish Balay #undef __FUNCT__
9474a2ae208SSatish Balay #define __FUNCT__ "MatMultAdd_SeqAIJ"
94844cd7ae7SLois Curfman McInnes int MatMultAdd_SeqAIJ(Mat A,Vec xx,Vec yy,Vec zz)
94917ab2063SBarry Smith {
950416022c9SBarry Smith   Mat_SeqAIJ   *a = (Mat_SeqAIJ*)A->data;
951362ced78SSatish Balay   PetscScalar  *x,*y,*z,*v;
952273d9f13SBarry Smith   int          ierr,m = A->m,*idx,shift = a->indexshift,*ii;
953aa482453SBarry Smith #if !defined(PETSC_USE_FORTRAN_KERNEL_MULTADDAIJ)
954e36a17ebSSatish Balay   int          n,i,jrow,j;
955362ced78SSatish Balay PetscScalar    sum;
956e36a17ebSSatish Balay #endif
9579ea0dfa2SSatish Balay 
9583a40ed3dSBarry Smith   PetscFunctionBegin;
959e1311b90SBarry Smith   ierr = VecGetArray(xx,&x);CHKERRQ(ierr);
960e1311b90SBarry Smith   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
9612e8a6d31SBarry Smith   if (zz != yy) {
962e1311b90SBarry Smith     ierr = VecGetArray(zz,&z);CHKERRQ(ierr);
9632e8a6d31SBarry Smith   } else {
9642e8a6d31SBarry Smith     z = y;
9652e8a6d31SBarry Smith   }
96617ab2063SBarry Smith   x    = x + shift; /* shift for Fortran start by 1 indexing */
967cddf8d76SBarry Smith   idx  = a->j;
968d64ed03dSBarry Smith   v    = a->a;
969cddf8d76SBarry Smith   ii   = a->i;
970aa482453SBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_MULTADDAIJ)
97129b5ca8aSSatish Balay   fortranmultaddaij_(&m,x,ii,idx+shift,v+shift,y,z);
97202ab625aSSatish Balay #else
973d64ed03dSBarry Smith   v   += shift; /* shift for Fortran start by 1 indexing */
974d64ed03dSBarry Smith   idx += shift;
97517ab2063SBarry Smith   for (i=0; i<m; i++) {
9769ea0dfa2SSatish Balay     jrow = ii[i];
9779ea0dfa2SSatish Balay     n    = ii[i+1] - jrow;
97817ab2063SBarry Smith     sum  = y[i];
9799ea0dfa2SSatish Balay     for (j=0; j<n; j++) {
9809ea0dfa2SSatish Balay       sum += v[jrow]*x[idx[jrow]]; jrow++;
9819ea0dfa2SSatish Balay      }
98217ab2063SBarry Smith     z[i] = sum;
98317ab2063SBarry Smith   }
98402ab625aSSatish Balay #endif
985b0a32e0cSBarry Smith   PetscLogFlops(2*a->nz);
986e1311b90SBarry Smith   ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr);
987e1311b90SBarry Smith   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
9882e8a6d31SBarry Smith   if (zz != yy) {
989e1311b90SBarry Smith     ierr = VecRestoreArray(zz,&z);CHKERRQ(ierr);
9902e8a6d31SBarry Smith   }
9913a40ed3dSBarry Smith   PetscFunctionReturn(0);
99217ab2063SBarry Smith }
99317ab2063SBarry Smith 
99417ab2063SBarry Smith /*
99517ab2063SBarry Smith      Adds diagonal pointers to sparse matrix structure.
99617ab2063SBarry Smith */
9974a2ae208SSatish Balay #undef __FUNCT__
9984a2ae208SSatish Balay #define __FUNCT__ "MatMarkDiagonal_SeqAIJ"
999f1e2ffcdSBarry Smith int MatMarkDiagonal_SeqAIJ(Mat A)
100017ab2063SBarry Smith {
1001416022c9SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
1002b0a32e0cSBarry Smith   int        i,j,*diag,m = A->m,shift = a->indexshift,ierr;
100317ab2063SBarry Smith 
10043a40ed3dSBarry Smith   PetscFunctionBegin;
1005f1e2ffcdSBarry Smith   if (a->diag) PetscFunctionReturn(0);
1006f1e2ffcdSBarry Smith 
1007b0a32e0cSBarry Smith   ierr = PetscMalloc((m+1)*sizeof(int),&diag);CHKERRQ(ierr);
1008b0a32e0cSBarry Smith   PetscLogObjectMemory(A,(m+1)*sizeof(int));
1009273d9f13SBarry Smith   for (i=0; i<A->m; i++) {
101035b0346bSBarry Smith     diag[i] = a->i[i+1];
1011416022c9SBarry Smith     for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) {
1012416022c9SBarry Smith       if (a->j[j]+shift == i) {
101317ab2063SBarry Smith         diag[i] = j - shift;
101417ab2063SBarry Smith         break;
101517ab2063SBarry Smith       }
101617ab2063SBarry Smith     }
101717ab2063SBarry Smith   }
1018416022c9SBarry Smith   a->diag = diag;
10193a40ed3dSBarry Smith   PetscFunctionReturn(0);
102017ab2063SBarry Smith }
102117ab2063SBarry Smith 
1022be5855fcSBarry Smith /*
1023be5855fcSBarry Smith      Checks for missing diagonals
1024be5855fcSBarry Smith */
10254a2ae208SSatish Balay #undef __FUNCT__
10264a2ae208SSatish Balay #define __FUNCT__ "MatMissingDiagonal_SeqAIJ"
1027f1e2ffcdSBarry Smith int MatMissingDiagonal_SeqAIJ(Mat A)
1028be5855fcSBarry Smith {
1029be5855fcSBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
1030f1e2ffcdSBarry Smith   int        *diag,*jj = a->j,i,shift = a->indexshift,ierr;
1031be5855fcSBarry Smith 
1032be5855fcSBarry Smith   PetscFunctionBegin;
1033f1e2ffcdSBarry Smith   ierr = MatMarkDiagonal_SeqAIJ(A);CHKERRQ(ierr);
1034f1e2ffcdSBarry Smith   diag = a->diag;
1035273d9f13SBarry Smith   for (i=0; i<A->m; i++) {
1036be5855fcSBarry Smith     if (jj[diag[i]+shift] != i-shift) {
103729bbc08cSBarry Smith       SETERRQ1(1,"Matrix is missing diagonal number %d",i);
1038be5855fcSBarry Smith     }
1039be5855fcSBarry Smith   }
1040be5855fcSBarry Smith   PetscFunctionReturn(0);
1041be5855fcSBarry Smith }
1042be5855fcSBarry Smith 
10434a2ae208SSatish Balay #undef __FUNCT__
10444a2ae208SSatish Balay #define __FUNCT__ "MatRelax_SeqAIJ"
1045c14dc6b6SHong Zhang int MatRelax_SeqAIJ(Mat A,Vec bb,PetscReal omega,MatSORType flag,PetscReal fshift,int its,int lits,Vec xx)
104617ab2063SBarry Smith {
1047416022c9SBarry Smith   Mat_SeqAIJ   *a = (Mat_SeqAIJ*)A->data;
104887828ca2SBarry Smith   PetscScalar  *x,*b,*bs, d,*xs,sum,*v = a->a,*t=0,scale,*ts,*xb,*idiag=0;
1049273d9f13SBarry Smith   int          ierr,*idx,*diag,n = A->n,m = A->m,i,shift = a->indexshift;
105017ab2063SBarry Smith 
10513a40ed3dSBarry Smith   PetscFunctionBegin;
1052b965ef7fSBarry Smith   its = its*lits;
105391723122SBarry Smith   if (its <= 0) SETERRQ2(PETSC_ERR_ARG_WRONG,"Relaxation requires global its %d and local its %d both positive",its,lits);
105491723122SBarry Smith 
1055e1311b90SBarry Smith   ierr = VecGetArray(xx,&x);CHKERRQ(ierr);
1056fb2e594dSBarry Smith   if (xx != bb) {
1057e1311b90SBarry Smith     ierr = VecGetArray(bb,&b);CHKERRQ(ierr);
1058fb2e594dSBarry Smith   } else {
1059fb2e594dSBarry Smith     b = x;
1060fb2e594dSBarry Smith   }
1061fb2e594dSBarry Smith 
1062f1e2ffcdSBarry Smith   if (!a->diag) {ierr = MatMarkDiagonal_SeqAIJ(A);CHKERRQ(ierr);}
1063416022c9SBarry Smith   diag = a->diag;
1064416022c9SBarry Smith   xs   = x + shift; /* shifted by one for index start of a or a->j*/
106517ab2063SBarry Smith   if (flag == SOR_APPLY_UPPER) {
106617ab2063SBarry Smith    /* apply (U + D/omega) to the vector */
106717ab2063SBarry Smith     bs = b + shift;
106817ab2063SBarry Smith     for (i=0; i<m; i++) {
1069416022c9SBarry Smith         d    = fshift + a->a[diag[i] + shift];
1070416022c9SBarry Smith         n    = a->i[i+1] - diag[i] - 1;
1071b0a32e0cSBarry Smith 	PetscLogFlops(2*n-1);
1072416022c9SBarry Smith         idx  = a->j + diag[i] + (!shift);
1073416022c9SBarry Smith         v    = a->a + diag[i] + (!shift);
107417ab2063SBarry Smith         sum  = b[i]*d/omega;
107517ab2063SBarry Smith         SPARSEDENSEDOT(sum,bs,v,idx,n);
107617ab2063SBarry Smith         x[i] = sum;
107717ab2063SBarry Smith     }
1078cb5b572fSBarry Smith     ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr);
1079fb2e594dSBarry Smith     if (bb != xx) {ierr = VecRestoreArray(bb,&b);CHKERRQ(ierr);}
10803a40ed3dSBarry Smith     PetscFunctionReturn(0);
108117ab2063SBarry Smith   }
1082c783ea89SBarry Smith 
1083c783ea89SBarry Smith   /* setup workspace for Eisenstat */
1084c783ea89SBarry Smith   if (flag & SOR_EISENSTAT) {
1085c783ea89SBarry Smith     if (!a->idiag) {
108687828ca2SBarry Smith       ierr     = PetscMalloc(2*m*sizeof(PetscScalar),&a->idiag);CHKERRQ(ierr);
1087c783ea89SBarry Smith       a->ssor  = a->idiag + m;
1088c783ea89SBarry Smith       v        = a->a;
1089c783ea89SBarry Smith       for (i=0; i<m; i++) { a->idiag[i] = 1.0/v[diag[i]];}
1090c783ea89SBarry Smith     }
1091c783ea89SBarry Smith     t     = a->ssor;
1092c783ea89SBarry Smith     idiag = a->idiag;
1093c783ea89SBarry Smith   }
1094fc3d8934SBarry Smith     /* Let  A = L + U + D; where L is lower trianglar,
1095fc3d8934SBarry Smith     U is upper triangular, E is diagonal; This routine applies
1096fc3d8934SBarry Smith 
1097fc3d8934SBarry Smith             (L + E)^{-1} A (U + E)^{-1}
1098fc3d8934SBarry Smith 
1099fc3d8934SBarry Smith     to a vector efficiently using Eisenstat's trick. This is for
1100fc3d8934SBarry Smith     the case of SSOR preconditioner, so E is D/omega where omega
110148af12d7SBarry Smith     is the relaxation factor.
1102fc3d8934SBarry Smith     */
1103fc3d8934SBarry Smith 
110448af12d7SBarry Smith   if (flag == SOR_APPLY_LOWER) {
110529bbc08cSBarry Smith     SETERRQ(PETSC_ERR_SUP,"SOR_APPLY_LOWER is not implemented");
110648af12d7SBarry Smith   } else if ((flag & SOR_EISENSTAT) && omega == 1.0 && shift == 0 && fshift == 0.0) {
110748af12d7SBarry Smith     /* special case for omega = 1.0 saves flops and some integer ops */
110887828ca2SBarry Smith     PetscScalar *v2;
110948af12d7SBarry Smith 
1110733d66baSBarry Smith     v2    = a->a;
1111fc3d8934SBarry Smith     /*  x = (E + U)^{-1} b */
1112fc3d8934SBarry Smith     for (i=m-1; i>=0; i--) {
1113fc3d8934SBarry Smith       n    = a->i[i+1] - diag[i] - 1;
1114fc3d8934SBarry Smith       idx  = a->j + diag[i] + 1;
1115fc3d8934SBarry Smith       v    = a->a + diag[i] + 1;
1116fc3d8934SBarry Smith       sum  = b[i];
1117fc3d8934SBarry Smith       SPARSEDENSEMDOT(sum,xs,v,idx,n);
1118b4632166SBarry Smith       x[i] = sum*idiag[i];
1119fc3d8934SBarry Smith 
1120fc3d8934SBarry Smith       /*  t = b - (2*E - D)x */
1121733d66baSBarry Smith       t[i] = b[i] - (v2[diag[i]])*x[i];
1122733d66baSBarry Smith     }
1123fc3d8934SBarry Smith 
1124fc3d8934SBarry Smith     /*  t = (E + L)^{-1}t */
1125fc3d8934SBarry Smith     diag = a->diag;
1126fc3d8934SBarry Smith     for (i=0; i<m; i++) {
1127fc3d8934SBarry Smith       n    = diag[i] - a->i[i];
1128fc3d8934SBarry Smith       idx  = a->j + a->i[i];
1129fc3d8934SBarry Smith       v    = a->a + a->i[i];
1130fc3d8934SBarry Smith       sum  = t[i];
1131fc3d8934SBarry Smith       SPARSEDENSEMDOT(sum,t,v,idx,n);
1132b4632166SBarry Smith       t[i]  = sum*idiag[i];
1133fc3d8934SBarry Smith 
1134fc3d8934SBarry Smith       /*  x = x + t */
1135733d66baSBarry Smith       x[i] += t[i];
1136733d66baSBarry Smith     }
1137733d66baSBarry Smith 
1138b0a32e0cSBarry Smith     PetscLogFlops(3*m-1 + 2*a->nz);
1139fc3d8934SBarry Smith     ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr);
1140fc3d8934SBarry Smith     if (bb != xx) {ierr = VecRestoreArray(bb,&b);CHKERRQ(ierr);}
1141fc3d8934SBarry Smith     PetscFunctionReturn(0);
11423a40ed3dSBarry Smith   } else if (flag & SOR_EISENSTAT) {
114317ab2063SBarry Smith     /* Let  A = L + U + D; where L is lower trianglar,
114417ab2063SBarry Smith     U is upper triangular, E is diagonal; This routine applies
114517ab2063SBarry Smith 
114617ab2063SBarry Smith             (L + E)^{-1} A (U + E)^{-1}
114717ab2063SBarry Smith 
114817ab2063SBarry Smith     to a vector efficiently using Eisenstat's trick. This is for
114917ab2063SBarry Smith     the case of SSOR preconditioner, so E is D/omega where omega
115017ab2063SBarry Smith     is the relaxation factor.
115117ab2063SBarry Smith     */
115217ab2063SBarry Smith     scale = (2.0/omega) - 1.0;
115317ab2063SBarry Smith 
115417ab2063SBarry Smith     /*  x = (E + U)^{-1} b */
115517ab2063SBarry Smith     for (i=m-1; i>=0; i--) {
1156416022c9SBarry Smith       d    = fshift + a->a[diag[i] + shift];
1157416022c9SBarry Smith       n    = a->i[i+1] - diag[i] - 1;
1158416022c9SBarry Smith       idx  = a->j + diag[i] + (!shift);
1159416022c9SBarry Smith       v    = a->a + diag[i] + (!shift);
116017ab2063SBarry Smith       sum  = b[i];
116117ab2063SBarry Smith       SPARSEDENSEMDOT(sum,xs,v,idx,n);
116217ab2063SBarry Smith       x[i] = omega*(sum/d);
116317ab2063SBarry Smith     }
116417ab2063SBarry Smith 
116517ab2063SBarry Smith     /*  t = b - (2*E - D)x */
1166416022c9SBarry Smith     v = a->a;
116717ab2063SBarry Smith     for (i=0; i<m; i++) { t[i] = b[i] - scale*(v[*diag++ + shift])*x[i]; }
116817ab2063SBarry Smith 
116917ab2063SBarry Smith     /*  t = (E + L)^{-1}t */
1170416022c9SBarry Smith     ts = t + shift; /* shifted by one for index start of a or a->j*/
1171416022c9SBarry Smith     diag = a->diag;
117217ab2063SBarry Smith     for (i=0; i<m; i++) {
1173416022c9SBarry Smith       d    = fshift + a->a[diag[i]+shift];
1174416022c9SBarry Smith       n    = diag[i] - a->i[i];
1175416022c9SBarry Smith       idx  = a->j + a->i[i] + shift;
1176416022c9SBarry Smith       v    = a->a + a->i[i] + shift;
117717ab2063SBarry Smith       sum  = t[i];
117817ab2063SBarry Smith       SPARSEDENSEMDOT(sum,ts,v,idx,n);
117917ab2063SBarry Smith       t[i] = omega*(sum/d);
1180733d66baSBarry Smith       /*  x = x + t */
1181733d66baSBarry Smith       x[i] += t[i];
118217ab2063SBarry Smith     }
118317ab2063SBarry Smith 
1184b0a32e0cSBarry Smith     PetscLogFlops(6*m-1 + 2*a->nz);
1185cb5b572fSBarry Smith     ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr);
1186fb2e594dSBarry Smith     if (bb != xx) {ierr = VecRestoreArray(bb,&b);CHKERRQ(ierr);}
11873a40ed3dSBarry Smith     PetscFunctionReturn(0);
118817ab2063SBarry Smith   }
118917ab2063SBarry Smith   if (flag & SOR_ZERO_INITIAL_GUESS) {
119017ab2063SBarry Smith     if (flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP){
119177d8c4bbSBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_RELAXAIJ)
119277d8c4bbSBarry Smith       fortranrelaxaijforwardzero_(&m,&omega,x,a->i,a->j,diag,a->a,b);
119377d8c4bbSBarry Smith #else
119417ab2063SBarry Smith       for (i=0; i<m; i++) {
1195416022c9SBarry Smith         d    = fshift + a->a[diag[i]+shift];
1196416022c9SBarry Smith         n    = diag[i] - a->i[i];
1197b0a32e0cSBarry Smith 	PetscLogFlops(2*n-1);
1198416022c9SBarry Smith         idx  = a->j + a->i[i] + shift;
1199416022c9SBarry Smith         v    = a->a + a->i[i] + shift;
120017ab2063SBarry Smith         sum  = b[i];
120117ab2063SBarry Smith         SPARSEDENSEMDOT(sum,xs,v,idx,n);
120217ab2063SBarry Smith         x[i] = omega*(sum/d);
120317ab2063SBarry Smith       }
120477d8c4bbSBarry Smith #endif
120517ab2063SBarry Smith       xb = x;
12063a40ed3dSBarry Smith     } else xb = b;
120717ab2063SBarry Smith     if ((flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP) &&
120817ab2063SBarry Smith         (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP)) {
120917ab2063SBarry Smith       for (i=0; i<m; i++) {
1210416022c9SBarry Smith         x[i] *= a->a[diag[i]+shift];
121117ab2063SBarry Smith       }
1212b0a32e0cSBarry Smith       PetscLogFlops(m);
121317ab2063SBarry Smith     }
121417ab2063SBarry Smith     if (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP){
121577d8c4bbSBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_RELAXAIJ)
121677d8c4bbSBarry Smith       fortranrelaxaijbackwardzero_(&m,&omega,x,a->i,a->j,diag,a->a,xb);
121777d8c4bbSBarry Smith #else
121817ab2063SBarry Smith       for (i=m-1; i>=0; i--) {
1219416022c9SBarry Smith         d    = fshift + a->a[diag[i] + shift];
1220416022c9SBarry Smith         n    = a->i[i+1] - diag[i] - 1;
1221b0a32e0cSBarry Smith 	PetscLogFlops(2*n-1);
1222416022c9SBarry Smith         idx  = a->j + diag[i] + (!shift);
1223416022c9SBarry Smith         v    = a->a + diag[i] + (!shift);
122417ab2063SBarry Smith         sum  = xb[i];
122517ab2063SBarry Smith         SPARSEDENSEMDOT(sum,xs,v,idx,n);
122617ab2063SBarry Smith         x[i] = omega*(sum/d);
122717ab2063SBarry Smith       }
122877d8c4bbSBarry Smith #endif
122917ab2063SBarry Smith     }
123017ab2063SBarry Smith     its--;
123117ab2063SBarry Smith   }
123217ab2063SBarry Smith   while (its--) {
123317ab2063SBarry Smith     if (flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP){
123477d8c4bbSBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_RELAXAIJ)
123577d8c4bbSBarry Smith       fortranrelaxaijforward_(&m,&omega,x,a->i,a->j,diag,a->a,b);
123677d8c4bbSBarry Smith #else
123717ab2063SBarry Smith       for (i=0; i<m; i++) {
1238416022c9SBarry Smith         d    = fshift + a->a[diag[i]+shift];
1239416022c9SBarry Smith         n    = a->i[i+1] - a->i[i];
1240b0a32e0cSBarry Smith 	PetscLogFlops(2*n-1);
1241416022c9SBarry Smith         idx  = a->j + a->i[i] + shift;
1242416022c9SBarry Smith         v    = a->a + a->i[i] + shift;
124317ab2063SBarry Smith         sum  = b[i];
124417ab2063SBarry Smith         SPARSEDENSEMDOT(sum,xs,v,idx,n);
12457e33a6baSBarry Smith         x[i] = (1. - omega)*x[i] + omega*(sum + a->a[diag[i]+shift]*x[i])/d;
124617ab2063SBarry Smith       }
124777d8c4bbSBarry Smith #endif
124817ab2063SBarry Smith     }
124917ab2063SBarry Smith     if (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP){
125077d8c4bbSBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_RELAXAIJ)
125177d8c4bbSBarry Smith       fortranrelaxaijbackward_(&m,&omega,x,a->i,a->j,diag,a->a,b);
125277d8c4bbSBarry Smith #else
125317ab2063SBarry Smith       for (i=m-1; i>=0; i--) {
1254416022c9SBarry Smith         d    = fshift + a->a[diag[i] + shift];
1255416022c9SBarry Smith         n    = a->i[i+1] - a->i[i];
1256b0a32e0cSBarry Smith 	PetscLogFlops(2*n-1);
1257416022c9SBarry Smith         idx  = a->j + a->i[i] + shift;
1258416022c9SBarry Smith         v    = a->a + a->i[i] + shift;
125917ab2063SBarry Smith         sum  = b[i];
126017ab2063SBarry Smith         SPARSEDENSEMDOT(sum,xs,v,idx,n);
12617e33a6baSBarry Smith         x[i] = (1. - omega)*x[i] + omega*(sum + a->a[diag[i]+shift]*x[i])/d;
126217ab2063SBarry Smith       }
126377d8c4bbSBarry Smith #endif
126417ab2063SBarry Smith     }
126517ab2063SBarry Smith   }
1266cb5b572fSBarry Smith   ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr);
1267fb2e594dSBarry Smith   if (bb != xx) {ierr = VecRestoreArray(bb,&b);CHKERRQ(ierr);}
12683a40ed3dSBarry Smith   PetscFunctionReturn(0);
126917ab2063SBarry Smith }
127017ab2063SBarry Smith 
12714a2ae208SSatish Balay #undef __FUNCT__
12724a2ae208SSatish Balay #define __FUNCT__ "MatGetInfo_SeqAIJ"
12738f6be9afSLois Curfman McInnes int MatGetInfo_SeqAIJ(Mat A,MatInfoType flag,MatInfo *info)
127417ab2063SBarry Smith {
1275416022c9SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
12764e220ebcSLois Curfman McInnes 
12773a40ed3dSBarry Smith   PetscFunctionBegin;
1278273d9f13SBarry Smith   info->rows_global    = (double)A->m;
1279273d9f13SBarry Smith   info->columns_global = (double)A->n;
1280273d9f13SBarry Smith   info->rows_local     = (double)A->m;
1281273d9f13SBarry Smith   info->columns_local  = (double)A->n;
12824e220ebcSLois Curfman McInnes   info->block_size     = 1.0;
12834e220ebcSLois Curfman McInnes   info->nz_allocated   = (double)a->maxnz;
12844e220ebcSLois Curfman McInnes   info->nz_used        = (double)a->nz;
12854e220ebcSLois Curfman McInnes   info->nz_unneeded    = (double)(a->maxnz - a->nz);
12864e220ebcSLois Curfman McInnes   info->assemblies     = (double)A->num_ass;
12874e220ebcSLois Curfman McInnes   info->mallocs        = (double)a->reallocs;
12884e220ebcSLois Curfman McInnes   info->memory         = A->mem;
12894e220ebcSLois Curfman McInnes   if (A->factor) {
12904e220ebcSLois Curfman McInnes     info->fill_ratio_given  = A->info.fill_ratio_given;
12914e220ebcSLois Curfman McInnes     info->fill_ratio_needed = A->info.fill_ratio_needed;
12924e220ebcSLois Curfman McInnes     info->factor_mallocs    = A->info.factor_mallocs;
12934e220ebcSLois Curfman McInnes   } else {
12944e220ebcSLois Curfman McInnes     info->fill_ratio_given  = 0;
12954e220ebcSLois Curfman McInnes     info->fill_ratio_needed = 0;
12964e220ebcSLois Curfman McInnes     info->factor_mallocs    = 0;
12974e220ebcSLois Curfman McInnes   }
12983a40ed3dSBarry Smith   PetscFunctionReturn(0);
129917ab2063SBarry Smith }
130017ab2063SBarry Smith 
1301b9b97703SBarry Smith EXTERN int MatLUFactorSymbolic_SeqAIJ(Mat,IS,IS,MatLUInfo*,Mat*);
1302ca44d042SBarry Smith EXTERN int MatLUFactorNumeric_SeqAIJ(Mat,Mat*);
1303b9b97703SBarry Smith EXTERN int MatLUFactor_SeqAIJ(Mat,IS,IS,MatLUInfo*);
1304ca44d042SBarry Smith EXTERN int MatSolve_SeqAIJ(Mat,Vec,Vec);
1305ca44d042SBarry Smith EXTERN int MatSolveAdd_SeqAIJ(Mat,Vec,Vec,Vec);
1306ca44d042SBarry Smith EXTERN int MatSolveTranspose_SeqAIJ(Mat,Vec,Vec);
1307ca44d042SBarry Smith EXTERN int MatSolveTransposeAdd_SeqAIJ(Mat,Vec,Vec,Vec);
130817ab2063SBarry Smith 
13094a2ae208SSatish Balay #undef __FUNCT__
13104a2ae208SSatish Balay #define __FUNCT__ "MatZeroRows_SeqAIJ"
131187828ca2SBarry Smith int MatZeroRows_SeqAIJ(Mat A,IS is,PetscScalar *diag)
131217ab2063SBarry Smith {
1313416022c9SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
1314273d9f13SBarry Smith   int         i,ierr,N,*rows,m = A->m - 1,shift = a->indexshift;
131517ab2063SBarry Smith 
13163a40ed3dSBarry Smith   PetscFunctionBegin;
1317b9b97703SBarry Smith   ierr = ISGetLocalSize(is,&N);CHKERRQ(ierr);
131817ab2063SBarry Smith   ierr = ISGetIndices(is,&rows);CHKERRQ(ierr);
1319f1e2ffcdSBarry Smith   if (a->keepzeroedrows) {
1320f1e2ffcdSBarry Smith     for (i=0; i<N; i++) {
132129bbc08cSBarry Smith       if (rows[i] < 0 || rows[i] > m) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"row out of range");
132287828ca2SBarry Smith       ierr = PetscMemzero(&a->a[a->i[rows[i]]+shift],a->ilen[rows[i]]*sizeof(PetscScalar));CHKERRQ(ierr);
1323f1e2ffcdSBarry Smith     }
1324f1e2ffcdSBarry Smith     if (diag) {
1325f1e2ffcdSBarry Smith       ierr = MatMissingDiagonal_SeqAIJ(A);CHKERRQ(ierr);
1326f1e2ffcdSBarry Smith       ierr = MatMarkDiagonal_SeqAIJ(A);CHKERRQ(ierr);
1327f1e2ffcdSBarry Smith       for (i=0; i<N; i++) {
1328f1e2ffcdSBarry Smith         a->a[a->diag[rows[i]]] = *diag;
1329f1e2ffcdSBarry Smith       }
1330f1e2ffcdSBarry Smith     }
1331f1e2ffcdSBarry Smith   } else {
133217ab2063SBarry Smith     if (diag) {
133317ab2063SBarry Smith       for (i=0; i<N; i++) {
133429bbc08cSBarry Smith         if (rows[i] < 0 || rows[i] > m) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"row out of range");
13357ae801bdSBarry Smith         if (a->ilen[rows[i]] > 0) {
1336416022c9SBarry Smith           a->ilen[rows[i]]          = 1;
1337416022c9SBarry Smith           a->a[a->i[rows[i]]+shift] = *diag;
1338416022c9SBarry Smith           a->j[a->i[rows[i]]+shift] = rows[i]+shift;
13397ae801bdSBarry Smith         } else { /* in case row was completely empty */
1340d64ed03dSBarry Smith           ierr = MatSetValues_SeqAIJ(A,1,&rows[i],1,&rows[i],diag,INSERT_VALUES);CHKERRQ(ierr);
134117ab2063SBarry Smith         }
134217ab2063SBarry Smith       }
13433a40ed3dSBarry Smith     } else {
134417ab2063SBarry Smith       for (i=0; i<N; i++) {
134529bbc08cSBarry Smith         if (rows[i] < 0 || rows[i] > m) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"row out of range");
1346416022c9SBarry Smith         a->ilen[rows[i]] = 0;
134717ab2063SBarry Smith       }
134817ab2063SBarry Smith     }
1349f1e2ffcdSBarry Smith   }
13507ae801bdSBarry Smith   ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr);
135143a90d84SBarry Smith   ierr = MatAssemblyEnd_SeqAIJ(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
13523a40ed3dSBarry Smith   PetscFunctionReturn(0);
135317ab2063SBarry Smith }
135417ab2063SBarry Smith 
13554a2ae208SSatish Balay #undef __FUNCT__
13564a2ae208SSatish Balay #define __FUNCT__ "MatGetRow_SeqAIJ"
135787828ca2SBarry Smith int MatGetRow_SeqAIJ(Mat A,int row,int *nz,int **idx,PetscScalar **v)
135817ab2063SBarry Smith {
1359416022c9SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
1360b0a32e0cSBarry Smith   int        *itmp,i,shift = a->indexshift,ierr;
136117ab2063SBarry Smith 
13623a40ed3dSBarry Smith   PetscFunctionBegin;
1363273d9f13SBarry Smith   if (row < 0 || row >= A->m) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Row %d out of range",row);
136417ab2063SBarry Smith 
1365416022c9SBarry Smith   *nz = a->i[row+1] - a->i[row];
1366416022c9SBarry Smith   if (v) *v = a->a + a->i[row] + shift;
136717ab2063SBarry Smith   if (idx) {
1368416022c9SBarry Smith     itmp = a->j + a->i[row] + shift;
13694e093b46SBarry Smith     if (*nz && shift) {
1370b0a32e0cSBarry Smith       ierr = PetscMalloc((*nz)*sizeof(int),idx);CHKERRQ(ierr);
137117ab2063SBarry Smith       for (i=0; i<(*nz); i++) {(*idx)[i] = itmp[i] + shift;}
13724e093b46SBarry Smith     } else if (*nz) {
13734e093b46SBarry Smith       *idx = itmp;
137417ab2063SBarry Smith     }
137517ab2063SBarry Smith     else *idx = 0;
137617ab2063SBarry Smith   }
13773a40ed3dSBarry Smith   PetscFunctionReturn(0);
137817ab2063SBarry Smith }
137917ab2063SBarry Smith 
13804a2ae208SSatish Balay #undef __FUNCT__
13814a2ae208SSatish Balay #define __FUNCT__ "MatRestoreRow_SeqAIJ"
138287828ca2SBarry Smith int MatRestoreRow_SeqAIJ(Mat A,int row,int *nz,int **idx,PetscScalar **v)
138317ab2063SBarry Smith {
13844e093b46SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
1385606d414cSSatish Balay   int ierr;
13863a40ed3dSBarry Smith 
13873a40ed3dSBarry Smith   PetscFunctionBegin;
1388606d414cSSatish Balay   if (idx) {if (*idx && a->indexshift) {ierr = PetscFree(*idx);CHKERRQ(ierr);}}
13893a40ed3dSBarry Smith   PetscFunctionReturn(0);
139017ab2063SBarry Smith }
139117ab2063SBarry Smith 
13924a2ae208SSatish Balay #undef __FUNCT__
13934a2ae208SSatish Balay #define __FUNCT__ "MatNorm_SeqAIJ"
1394064f8208SBarry Smith int MatNorm_SeqAIJ(Mat A,NormType type,PetscReal *nrm)
139517ab2063SBarry Smith {
1396416022c9SBarry Smith   Mat_SeqAIJ   *a = (Mat_SeqAIJ*)A->data;
139787828ca2SBarry Smith   PetscScalar  *v = a->a;
139836db0b34SBarry Smith   PetscReal    sum = 0.0;
1399549d3d68SSatish Balay   int          i,j,shift = a->indexshift,ierr;
140017ab2063SBarry Smith 
14013a40ed3dSBarry Smith   PetscFunctionBegin;
140217ab2063SBarry Smith   if (type == NORM_FROBENIUS) {
1403416022c9SBarry Smith     for (i=0; i<a->nz; i++) {
1404aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
140536db0b34SBarry Smith       sum += PetscRealPart(PetscConj(*v)*(*v)); v++;
140617ab2063SBarry Smith #else
140717ab2063SBarry Smith       sum += (*v)*(*v); v++;
140817ab2063SBarry Smith #endif
140917ab2063SBarry Smith     }
1410064f8208SBarry Smith     *nrm = sqrt(sum);
14113a40ed3dSBarry Smith   } else if (type == NORM_1) {
141236db0b34SBarry Smith     PetscReal *tmp;
1413416022c9SBarry Smith     int    *jj = a->j;
1414b0a32e0cSBarry Smith     ierr = PetscMalloc((A->n+1)*sizeof(PetscReal),&tmp);CHKERRQ(ierr);
1415273d9f13SBarry Smith     ierr = PetscMemzero(tmp,A->n*sizeof(PetscReal));CHKERRQ(ierr);
1416064f8208SBarry Smith     *nrm = 0.0;
1417416022c9SBarry Smith     for (j=0; j<a->nz; j++) {
1418a2744918SBarry Smith         tmp[*jj++ + shift] += PetscAbsScalar(*v);  v++;
141917ab2063SBarry Smith     }
1420273d9f13SBarry Smith     for (j=0; j<A->n; j++) {
1421064f8208SBarry Smith       if (tmp[j] > *nrm) *nrm = tmp[j];
142217ab2063SBarry Smith     }
1423606d414cSSatish Balay     ierr = PetscFree(tmp);CHKERRQ(ierr);
14243a40ed3dSBarry Smith   } else if (type == NORM_INFINITY) {
1425064f8208SBarry Smith     *nrm = 0.0;
1426273d9f13SBarry Smith     for (j=0; j<A->m; j++) {
1427416022c9SBarry Smith       v = a->a + a->i[j] + shift;
142817ab2063SBarry Smith       sum = 0.0;
1429416022c9SBarry Smith       for (i=0; i<a->i[j+1]-a->i[j]; i++) {
1430cddf8d76SBarry Smith         sum += PetscAbsScalar(*v); v++;
143117ab2063SBarry Smith       }
1432064f8208SBarry Smith       if (sum > *nrm) *nrm = sum;
143317ab2063SBarry Smith     }
14343a40ed3dSBarry Smith   } else {
143529bbc08cSBarry Smith     SETERRQ(PETSC_ERR_SUP,"No support for two norm");
143617ab2063SBarry Smith   }
14373a40ed3dSBarry Smith   PetscFunctionReturn(0);
143817ab2063SBarry Smith }
143917ab2063SBarry Smith 
14404a2ae208SSatish Balay #undef __FUNCT__
14414a2ae208SSatish Balay #define __FUNCT__ "MatTranspose_SeqAIJ"
14428f6be9afSLois Curfman McInnes int MatTranspose_SeqAIJ(Mat A,Mat *B)
144317ab2063SBarry Smith {
1444416022c9SBarry Smith   Mat_SeqAIJ   *a = (Mat_SeqAIJ*)A->data;
1445416022c9SBarry Smith   Mat          C;
1446273d9f13SBarry Smith   int          i,ierr,*aj = a->j,*ai = a->i,m = A->m,len,*col;
1447273d9f13SBarry Smith   int          shift = a->indexshift;
144887828ca2SBarry Smith   PetscScalar  *array = a->a;
144917ab2063SBarry Smith 
14503a40ed3dSBarry Smith   PetscFunctionBegin;
1451273d9f13SBarry Smith   if (!B && m != A->n) SETERRQ(PETSC_ERR_ARG_SIZ,"Square matrix only for in-place");
1452b0a32e0cSBarry Smith   ierr = PetscMalloc((1+A->n)*sizeof(int),&col);CHKERRQ(ierr);
1453273d9f13SBarry Smith   ierr = PetscMemzero(col,(1+A->n)*sizeof(int));CHKERRQ(ierr);
145417ab2063SBarry Smith   if (shift) {
145517ab2063SBarry Smith     for (i=0; i<ai[m]-1; i++) aj[i] -= 1;
145617ab2063SBarry Smith   }
145717ab2063SBarry Smith   for (i=0; i<ai[m]+shift; i++) col[aj[i]] += 1;
1458273d9f13SBarry Smith   ierr = MatCreateSeqAIJ(A->comm,A->n,m,0,col,&C);CHKERRQ(ierr);
1459606d414cSSatish Balay   ierr = PetscFree(col);CHKERRQ(ierr);
146017ab2063SBarry Smith   for (i=0; i<m; i++) {
146117ab2063SBarry Smith     len    = ai[i+1]-ai[i];
1462416022c9SBarry Smith     ierr   = MatSetValues(C,len,aj,1,&i,array,INSERT_VALUES);CHKERRQ(ierr);
1463b9b97703SBarry Smith     array += len;
1464b9b97703SBarry Smith     aj    += len;
146517ab2063SBarry Smith   }
146617ab2063SBarry Smith   if (shift) {
146717ab2063SBarry Smith     for (i=0; i<ai[m]-1; i++) aj[i] += 1;
146817ab2063SBarry Smith   }
146917ab2063SBarry Smith 
14706d4a8577SBarry Smith   ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
14716d4a8577SBarry Smith   ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
147217ab2063SBarry Smith 
1473f1e2ffcdSBarry Smith   if (B) {
1474416022c9SBarry Smith     *B = C;
147517ab2063SBarry Smith   } else {
1476273d9f13SBarry Smith     ierr = MatHeaderCopy(A,C);CHKERRQ(ierr);
147717ab2063SBarry Smith   }
14783a40ed3dSBarry Smith   PetscFunctionReturn(0);
147917ab2063SBarry Smith }
148017ab2063SBarry Smith 
14814a2ae208SSatish Balay #undef __FUNCT__
14824a2ae208SSatish Balay #define __FUNCT__ "MatDiagonalScale_SeqAIJ"
14838f6be9afSLois Curfman McInnes int MatDiagonalScale_SeqAIJ(Mat A,Vec ll,Vec rr)
148417ab2063SBarry Smith {
1485416022c9SBarry Smith   Mat_SeqAIJ   *a = (Mat_SeqAIJ*)A->data;
148687828ca2SBarry Smith   PetscScalar  *l,*r,x,*v;
1487273d9f13SBarry Smith   int          ierr,i,j,m = A->m,n = A->n,M,nz = a->nz,*jj,shift = a->indexshift;
148817ab2063SBarry Smith 
14893a40ed3dSBarry Smith   PetscFunctionBegin;
149017ab2063SBarry Smith   if (ll) {
14913ea7c6a1SSatish Balay     /* The local size is used so that VecMPI can be passed to this routine
14923ea7c6a1SSatish Balay        by MatDiagonalScale_MPIAIJ */
1493e1311b90SBarry Smith     ierr = VecGetLocalSize(ll,&m);CHKERRQ(ierr);
1494273d9f13SBarry Smith     if (m != A->m) SETERRQ(PETSC_ERR_ARG_SIZ,"Left scaling vector wrong length");
1495e1311b90SBarry Smith     ierr = VecGetArray(ll,&l);CHKERRQ(ierr);
1496416022c9SBarry Smith     v = a->a;
149717ab2063SBarry Smith     for (i=0; i<m; i++) {
149817ab2063SBarry Smith       x = l[i];
1499416022c9SBarry Smith       M = a->i[i+1] - a->i[i];
150017ab2063SBarry Smith       for (j=0; j<M; j++) { (*v++) *= x;}
150117ab2063SBarry Smith     }
1502e1311b90SBarry Smith     ierr = VecRestoreArray(ll,&l);CHKERRQ(ierr);
1503b0a32e0cSBarry Smith     PetscLogFlops(nz);
150417ab2063SBarry Smith   }
150517ab2063SBarry Smith   if (rr) {
1506e1311b90SBarry Smith     ierr = VecGetLocalSize(rr,&n);CHKERRQ(ierr);
1507273d9f13SBarry Smith     if (n != A->n) SETERRQ(PETSC_ERR_ARG_SIZ,"Right scaling vector wrong length");
1508e1311b90SBarry Smith     ierr = VecGetArray(rr,&r);CHKERRQ(ierr);
1509416022c9SBarry Smith     v = a->a; jj = a->j;
151017ab2063SBarry Smith     for (i=0; i<nz; i++) {
151117ab2063SBarry Smith       (*v++) *= r[*jj++ + shift];
151217ab2063SBarry Smith     }
1513e1311b90SBarry Smith     ierr = VecRestoreArray(rr,&r);CHKERRQ(ierr);
1514b0a32e0cSBarry Smith     PetscLogFlops(nz);
151517ab2063SBarry Smith   }
15163a40ed3dSBarry Smith   PetscFunctionReturn(0);
151717ab2063SBarry Smith }
151817ab2063SBarry Smith 
15194a2ae208SSatish Balay #undef __FUNCT__
15204a2ae208SSatish Balay #define __FUNCT__ "MatGetSubMatrix_SeqAIJ"
15217b2a1423SBarry Smith int MatGetSubMatrix_SeqAIJ(Mat A,IS isrow,IS iscol,int csize,MatReuse scall,Mat *B)
152217ab2063SBarry Smith {
1523db02288aSLois Curfman McInnes   Mat_SeqAIJ   *a = (Mat_SeqAIJ*)A->data,*c;
1524273d9f13SBarry Smith   int          *smap,i,k,kstart,kend,ierr,oldcols = A->n,*lens;
152536db0b34SBarry Smith   int          row,mat_i,*mat_j,tcol,first,step,*mat_ilen,sum,lensi;
152699141d43SSatish Balay   int          *irow,*icol,nrows,ncols,shift = a->indexshift,*ssmap;
152799141d43SSatish Balay   int          *starts,*j_new,*i_new,*aj = a->j,*ai = a->i,ii,*ailen = a->ilen;
152887828ca2SBarry Smith   PetscScalar  *a_new,*mat_a;
1529416022c9SBarry Smith   Mat          C;
1530fee21e36SBarry Smith   PetscTruth   stride;
153117ab2063SBarry Smith 
15323a40ed3dSBarry Smith   PetscFunctionBegin;
1533d64ed03dSBarry Smith   ierr = ISSorted(isrow,(PetscTruth*)&i);CHKERRQ(ierr);
153429bbc08cSBarry Smith   if (!i) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"ISrow is not sorted");
1535d64ed03dSBarry Smith   ierr = ISSorted(iscol,(PetscTruth*)&i);CHKERRQ(ierr);
153629bbc08cSBarry Smith   if (!i) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"IScol is not sorted");
153799141d43SSatish Balay 
153817ab2063SBarry Smith   ierr = ISGetIndices(isrow,&irow);CHKERRQ(ierr);
1539b9b97703SBarry Smith   ierr = ISGetLocalSize(isrow,&nrows);CHKERRQ(ierr);
1540b9b97703SBarry Smith   ierr = ISGetLocalSize(iscol,&ncols);CHKERRQ(ierr);
154117ab2063SBarry Smith 
1542fee21e36SBarry Smith   ierr = ISStrideGetInfo(iscol,&first,&step);CHKERRQ(ierr);
1543fee21e36SBarry Smith   ierr = ISStride(iscol,&stride);CHKERRQ(ierr);
1544fee21e36SBarry Smith   if (stride && step == 1) {
154502834360SBarry Smith     /* special case of contiguous rows */
154631ebf83bSSatish Balay     ierr   = PetscMalloc((2*nrows+1)*sizeof(int),&lens);CHKERRQ(ierr);
154731ebf83bSSatish Balay     starts = lens + nrows;
154802834360SBarry Smith     /* loop over new rows determining lens and starting points */
154902834360SBarry Smith     for (i=0; i<nrows; i++) {
1550a2744918SBarry Smith       kstart  = ai[irow[i]]+shift;
1551a2744918SBarry Smith       kend    = kstart + ailen[irow[i]];
155202834360SBarry Smith       for (k=kstart; k<kend; k++) {
1553d8ced48eSBarry Smith         if (aj[k]+shift >= first) {
155402834360SBarry Smith           starts[i] = k;
155502834360SBarry Smith           break;
155602834360SBarry Smith 	}
155702834360SBarry Smith       }
1558a2744918SBarry Smith       sum = 0;
155902834360SBarry Smith       while (k < kend) {
1560d8ced48eSBarry Smith         if (aj[k++]+shift >= first+ncols) break;
1561a2744918SBarry Smith         sum++;
156202834360SBarry Smith       }
1563a2744918SBarry Smith       lens[i] = sum;
156402834360SBarry Smith     }
156502834360SBarry Smith     /* create submatrix */
1566cddf8d76SBarry Smith     if (scall == MAT_REUSE_MATRIX) {
156708480c60SBarry Smith       int n_cols,n_rows;
156808480c60SBarry Smith       ierr = MatGetSize(*B,&n_rows,&n_cols);CHKERRQ(ierr);
156929bbc08cSBarry Smith       if (n_rows != nrows || n_cols != ncols) SETERRQ(PETSC_ERR_ARG_SIZ,"Reused submatrix wrong size");
1570d8ced48eSBarry Smith       ierr = MatZeroEntries(*B);CHKERRQ(ierr);
157108480c60SBarry Smith       C = *B;
15723a40ed3dSBarry Smith     } else {
157302834360SBarry Smith       ierr = MatCreateSeqAIJ(A->comm,nrows,ncols,0,lens,&C);CHKERRQ(ierr);
157408480c60SBarry Smith     }
1575db02288aSLois Curfman McInnes     c = (Mat_SeqAIJ*)C->data;
1576db02288aSLois Curfman McInnes 
157702834360SBarry Smith     /* loop over rows inserting into submatrix */
1578db02288aSLois Curfman McInnes     a_new    = c->a;
1579db02288aSLois Curfman McInnes     j_new    = c->j;
1580db02288aSLois Curfman McInnes     i_new    = c->i;
1581db02288aSLois Curfman McInnes     i_new[0] = -shift;
158202834360SBarry Smith     for (i=0; i<nrows; i++) {
1583a2744918SBarry Smith       ii    = starts[i];
1584a2744918SBarry Smith       lensi = lens[i];
1585a2744918SBarry Smith       for (k=0; k<lensi; k++) {
1586a2744918SBarry Smith         *j_new++ = aj[ii+k] - first;
158702834360SBarry Smith       }
158887828ca2SBarry Smith       ierr = PetscMemcpy(a_new,a->a + starts[i],lensi*sizeof(PetscScalar));CHKERRQ(ierr);
1589a2744918SBarry Smith       a_new      += lensi;
1590a2744918SBarry Smith       i_new[i+1]  = i_new[i] + lensi;
1591a2744918SBarry Smith       c->ilen[i]  = lensi;
159202834360SBarry Smith     }
1593606d414cSSatish Balay     ierr = PetscFree(lens);CHKERRQ(ierr);
15943a40ed3dSBarry Smith   } else {
159502834360SBarry Smith     ierr  = ISGetIndices(iscol,&icol);CHKERRQ(ierr);
1596b0a32e0cSBarry Smith     ierr  = PetscMalloc((1+oldcols)*sizeof(int),&smap);CHKERRQ(ierr);
159702834360SBarry Smith     ssmap = smap + shift;
1598b0a32e0cSBarry Smith     ierr  = PetscMalloc((1+nrows)*sizeof(int),&lens);CHKERRQ(ierr);
1599549d3d68SSatish Balay     ierr  = PetscMemzero(smap,oldcols*sizeof(int));CHKERRQ(ierr);
160017ab2063SBarry Smith     for (i=0; i<ncols; i++) smap[icol[i]] = i+1;
160102834360SBarry Smith     /* determine lens of each row */
160202834360SBarry Smith     for (i=0; i<nrows; i++) {
1603d8ced48eSBarry Smith       kstart  = ai[irow[i]]+shift;
160402834360SBarry Smith       kend    = kstart + a->ilen[irow[i]];
160502834360SBarry Smith       lens[i] = 0;
160602834360SBarry Smith       for (k=kstart; k<kend; k++) {
1607d8ced48eSBarry Smith         if (ssmap[aj[k]]) {
160802834360SBarry Smith           lens[i]++;
160902834360SBarry Smith         }
161002834360SBarry Smith       }
161102834360SBarry Smith     }
161217ab2063SBarry Smith     /* Create and fill new matrix */
1613a2744918SBarry Smith     if (scall == MAT_REUSE_MATRIX) {
16140f5bd95cSBarry Smith       PetscTruth equal;
16150f5bd95cSBarry Smith 
161699141d43SSatish Balay       c = (Mat_SeqAIJ *)((*B)->data);
1617273d9f13SBarry Smith       if ((*B)->m  != nrows || (*B)->n != ncols) SETERRQ(PETSC_ERR_ARG_SIZ,"Cannot reuse matrix. wrong size");
1618273d9f13SBarry Smith       ierr = PetscMemcmp(c->ilen,lens,(*B)->m*sizeof(int),&equal);CHKERRQ(ierr);
16190f5bd95cSBarry Smith       if (!equal) {
162029bbc08cSBarry Smith         SETERRQ(PETSC_ERR_ARG_SIZ,"Cannot reuse matrix. wrong no of nonzeros");
162199141d43SSatish Balay       }
1622273d9f13SBarry Smith       ierr = PetscMemzero(c->ilen,(*B)->m*sizeof(int));CHKERRQ(ierr);
162308480c60SBarry Smith       C = *B;
16243a40ed3dSBarry Smith     } else {
162502834360SBarry Smith       ierr = MatCreateSeqAIJ(A->comm,nrows,ncols,0,lens,&C);CHKERRQ(ierr);
162608480c60SBarry Smith     }
162799141d43SSatish Balay     c = (Mat_SeqAIJ *)(C->data);
162817ab2063SBarry Smith     for (i=0; i<nrows; i++) {
162999141d43SSatish Balay       row    = irow[i];
163099141d43SSatish Balay       kstart = ai[row]+shift;
163199141d43SSatish Balay       kend   = kstart + a->ilen[row];
163299141d43SSatish Balay       mat_i  = c->i[i]+shift;
163399141d43SSatish Balay       mat_j  = c->j + mat_i;
163499141d43SSatish Balay       mat_a  = c->a + mat_i;
163599141d43SSatish Balay       mat_ilen = c->ilen + i;
163617ab2063SBarry Smith       for (k=kstart; k<kend; k++) {
163799141d43SSatish Balay         if ((tcol=ssmap[a->j[k]])) {
163899141d43SSatish Balay           *mat_j++ = tcol - (!shift);
163999141d43SSatish Balay           *mat_a++ = a->a[k];
164099141d43SSatish Balay           (*mat_ilen)++;
164199141d43SSatish Balay 
164217ab2063SBarry Smith         }
164317ab2063SBarry Smith       }
164417ab2063SBarry Smith     }
164502834360SBarry Smith     /* Free work space */
164602834360SBarry Smith     ierr = ISRestoreIndices(iscol,&icol);CHKERRQ(ierr);
1647606d414cSSatish Balay     ierr = PetscFree(smap);CHKERRQ(ierr);
1648606d414cSSatish Balay     ierr = PetscFree(lens);CHKERRQ(ierr);
164902834360SBarry Smith   }
16506d4a8577SBarry Smith   ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
16516d4a8577SBarry Smith   ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
165217ab2063SBarry Smith 
165317ab2063SBarry Smith   ierr = ISRestoreIndices(isrow,&irow);CHKERRQ(ierr);
1654416022c9SBarry Smith   *B = C;
16553a40ed3dSBarry Smith   PetscFunctionReturn(0);
165617ab2063SBarry Smith }
165717ab2063SBarry Smith 
1658a871dcd8SBarry Smith /*
1659a871dcd8SBarry Smith */
16604a2ae208SSatish Balay #undef __FUNCT__
16614a2ae208SSatish Balay #define __FUNCT__ "MatILUFactor_SeqAIJ"
16625ef9f2a5SBarry Smith int MatILUFactor_SeqAIJ(Mat inA,IS row,IS col,MatILUInfo *info)
1663a871dcd8SBarry Smith {
166463b91edcSBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)inA->data;
166508480c60SBarry Smith   int        ierr;
166663b91edcSBarry Smith   Mat        outA;
1667b8a78c4aSBarry Smith   PetscTruth row_identity,col_identity;
166863b91edcSBarry Smith 
16693a40ed3dSBarry Smith   PetscFunctionBegin;
1670d3d32019SBarry Smith   if (info->levels != 0) SETERRQ(PETSC_ERR_SUP,"Only levels=0 supported for in-place ilu");
1671b8a78c4aSBarry Smith   ierr = ISIdentity(row,&row_identity);CHKERRQ(ierr);
1672b8a78c4aSBarry Smith   ierr = ISIdentity(col,&col_identity);CHKERRQ(ierr);
1673b8a78c4aSBarry Smith   if (!row_identity || !col_identity) {
167429bbc08cSBarry Smith     SETERRQ(1,"Row and column permutations must be identity for in-place ILU");
1675b8a78c4aSBarry Smith   }
1676a871dcd8SBarry Smith 
167763b91edcSBarry Smith   outA          = inA;
167863b91edcSBarry Smith   inA->factor   = FACTOR_LU;
167963b91edcSBarry Smith   a->row        = row;
168063b91edcSBarry Smith   a->col        = col;
1681c38d4ed2SBarry Smith   ierr = PetscObjectReference((PetscObject)row);CHKERRQ(ierr);
1682c38d4ed2SBarry Smith   ierr = PetscObjectReference((PetscObject)col);CHKERRQ(ierr);
168363b91edcSBarry Smith 
168436db0b34SBarry Smith   /* Create the inverse permutation so that it can be used in MatLUFactorNumeric() */
1685b9b97703SBarry Smith   if (a->icol) {ierr = ISDestroy(a->icol);CHKERRQ(ierr);} /* need to remove old one */
16864c49b128SBarry Smith   ierr = ISInvertPermutation(col,PETSC_DECIDE,&a->icol);CHKERRQ(ierr);
1687b0a32e0cSBarry Smith   PetscLogObjectParent(inA,a->icol);
1688f0ec6fceSSatish Balay 
168994a9d846SBarry Smith   if (!a->solve_work) { /* this matrix may have been factored before */
169087828ca2SBarry Smith      ierr = PetscMalloc((inA->m+1)*sizeof(PetscScalar),&a->solve_work);CHKERRQ(ierr);
169194a9d846SBarry Smith   }
169263b91edcSBarry Smith 
169308480c60SBarry Smith   if (!a->diag) {
1694f1e2ffcdSBarry Smith     ierr = MatMarkDiagonal_SeqAIJ(inA);CHKERRQ(ierr);
169563b91edcSBarry Smith   }
169663b91edcSBarry Smith   ierr = MatLUFactorNumeric_SeqAIJ(inA,&outA);CHKERRQ(ierr);
16973a40ed3dSBarry Smith   PetscFunctionReturn(0);
1698a871dcd8SBarry Smith }
1699a871dcd8SBarry Smith 
1700d9eff348SSatish Balay #include "petscblaslapack.h"
17014a2ae208SSatish Balay #undef __FUNCT__
17024a2ae208SSatish Balay #define __FUNCT__ "MatScale_SeqAIJ"
170387828ca2SBarry Smith int MatScale_SeqAIJ(PetscScalar *alpha,Mat inA)
1704f0b747eeSBarry Smith {
1705f0b747eeSBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)inA->data;
1706f0b747eeSBarry Smith   int        one = 1;
17073a40ed3dSBarry Smith 
17083a40ed3dSBarry Smith   PetscFunctionBegin;
1709f0b747eeSBarry Smith   BLscal_(&a->nz,alpha,a->a,&one);
1710b0a32e0cSBarry Smith   PetscLogFlops(a->nz);
17113a40ed3dSBarry Smith   PetscFunctionReturn(0);
1712f0b747eeSBarry Smith }
1713f0b747eeSBarry Smith 
17144a2ae208SSatish Balay #undef __FUNCT__
17154a2ae208SSatish Balay #define __FUNCT__ "MatGetSubMatrices_SeqAIJ"
17167b2a1423SBarry Smith int MatGetSubMatrices_SeqAIJ(Mat A,int n,IS *irow,IS *icol,MatReuse scall,Mat **B)
1717cddf8d76SBarry Smith {
1718cddf8d76SBarry Smith   int ierr,i;
1719cddf8d76SBarry Smith 
17203a40ed3dSBarry Smith   PetscFunctionBegin;
1721cddf8d76SBarry Smith   if (scall == MAT_INITIAL_MATRIX) {
1722b0a32e0cSBarry Smith     ierr = PetscMalloc((n+1)*sizeof(Mat),B);CHKERRQ(ierr);
1723cddf8d76SBarry Smith   }
1724cddf8d76SBarry Smith 
1725cddf8d76SBarry Smith   for (i=0; i<n; i++) {
17266a6a5d1dSBarry Smith     ierr = MatGetSubMatrix_SeqAIJ(A,irow[i],icol[i],PETSC_DECIDE,scall,&(*B)[i]);CHKERRQ(ierr);
1727cddf8d76SBarry Smith   }
17283a40ed3dSBarry Smith   PetscFunctionReturn(0);
1729cddf8d76SBarry Smith }
1730cddf8d76SBarry Smith 
17314a2ae208SSatish Balay #undef __FUNCT__
17324a2ae208SSatish Balay #define __FUNCT__ "MatGetBlockSize_SeqAIJ"
17338f6be9afSLois Curfman McInnes int MatGetBlockSize_SeqAIJ(Mat A,int *bs)
17345a838052SSatish Balay {
1735f830108cSBarry Smith   PetscFunctionBegin;
17365a838052SSatish Balay   *bs = 1;
17373a40ed3dSBarry Smith   PetscFunctionReturn(0);
17385a838052SSatish Balay }
17395a838052SSatish Balay 
17404a2ae208SSatish Balay #undef __FUNCT__
17414a2ae208SSatish Balay #define __FUNCT__ "MatIncreaseOverlap_SeqAIJ"
17428f6be9afSLois Curfman McInnes int MatIncreaseOverlap_SeqAIJ(Mat A,int is_max,IS *is,int ov)
17434dcbc457SBarry Smith {
1744e4d965acSSatish Balay   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
174506763907SSatish Balay   int        shift,row,i,j,k,l,m,n,*idx,ierr,*nidx,isz,val;
17468a047759SSatish Balay   int        start,end,*ai,*aj;
1747f1af5d2fSBarry Smith   PetscBT    table;
1748bbd702dbSSatish Balay 
17493a40ed3dSBarry Smith   PetscFunctionBegin;
17508a047759SSatish Balay   shift = a->indexshift;
1751273d9f13SBarry Smith   m     = A->m;
1752e4d965acSSatish Balay   ai    = a->i;
17538a047759SSatish Balay   aj    = a->j+shift;
17548a047759SSatish Balay 
175529bbc08cSBarry Smith   if (ov < 0)  SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"illegal overlap value used");
175606763907SSatish Balay 
1757b0a32e0cSBarry Smith   ierr = PetscMalloc((m+1)*sizeof(int),&nidx);CHKERRQ(ierr);
17586831982aSBarry Smith   ierr = PetscBTCreate(m,table);CHKERRQ(ierr);
175906763907SSatish Balay 
1760e4d965acSSatish Balay   for (i=0; i<is_max; i++) {
1761b97fc60eSLois Curfman McInnes     /* Initialize the two local arrays */
1762e4d965acSSatish Balay     isz  = 0;
17636831982aSBarry Smith     ierr = PetscBTMemzero(m,table);CHKERRQ(ierr);
1764e4d965acSSatish Balay 
1765e4d965acSSatish Balay     /* Extract the indices, assume there can be duplicate entries */
17664dcbc457SBarry Smith     ierr = ISGetIndices(is[i],&idx);CHKERRQ(ierr);
1767b9b97703SBarry Smith     ierr = ISGetLocalSize(is[i],&n);CHKERRQ(ierr);
1768e4d965acSSatish Balay 
1769dd097bc3SLois Curfman McInnes     /* Enter these into the temp arrays. I.e., mark table[row], enter row into new index */
1770e4d965acSSatish Balay     for (j=0; j<n ; ++j){
1771f1af5d2fSBarry Smith       if(!PetscBTLookupSet(table,idx[j])) { nidx[isz++] = idx[j];}
17724dcbc457SBarry Smith     }
177306763907SSatish Balay     ierr = ISRestoreIndices(is[i],&idx);CHKERRQ(ierr);
177406763907SSatish Balay     ierr = ISDestroy(is[i]);CHKERRQ(ierr);
1775e4d965acSSatish Balay 
177604a348a9SBarry Smith     k = 0;
177704a348a9SBarry Smith     for (j=0; j<ov; j++){ /* for each overlap */
177804a348a9SBarry Smith       n = isz;
177906763907SSatish Balay       for (; k<n ; k++){ /* do only those rows in nidx[k], which are not done yet */
1780e4d965acSSatish Balay         row   = nidx[k];
1781e4d965acSSatish Balay         start = ai[row];
1782e4d965acSSatish Balay         end   = ai[row+1];
178304a348a9SBarry Smith         for (l = start; l<end ; l++){
17848a047759SSatish Balay           val = aj[l] + shift;
1785f1af5d2fSBarry Smith           if (!PetscBTLookupSet(table,val)) {nidx[isz++] = val;}
1786e4d965acSSatish Balay         }
1787e4d965acSSatish Balay       }
1788e4d965acSSatish Balay     }
1789029af93fSBarry Smith     ierr = ISCreateGeneral(PETSC_COMM_SELF,isz,nidx,(is+i));CHKERRQ(ierr);
1790e4d965acSSatish Balay   }
17916831982aSBarry Smith   ierr = PetscBTDestroy(table);CHKERRQ(ierr);
1792606d414cSSatish Balay   ierr = PetscFree(nidx);CHKERRQ(ierr);
17933a40ed3dSBarry Smith   PetscFunctionReturn(0);
17944dcbc457SBarry Smith }
179517ab2063SBarry Smith 
17960513a670SBarry Smith /* -------------------------------------------------------------- */
17974a2ae208SSatish Balay #undef __FUNCT__
17984a2ae208SSatish Balay #define __FUNCT__ "MatPermute_SeqAIJ"
17990513a670SBarry Smith int MatPermute_SeqAIJ(Mat A,IS rowp,IS colp,Mat *B)
18000513a670SBarry Smith {
18010513a670SBarry Smith   Mat_SeqAIJ   *a = (Mat_SeqAIJ*)A->data;
180287828ca2SBarry Smith   PetscScalar  *vwork;
1803273d9f13SBarry Smith   int          i,ierr,nz,m = A->m,n = A->n,*cwork;
18040513a670SBarry Smith   int          *row,*col,*cnew,j,*lens;
180556cd22aeSBarry Smith   IS           icolp,irowp;
18060513a670SBarry Smith 
18073a40ed3dSBarry Smith   PetscFunctionBegin;
18084c49b128SBarry Smith   ierr = ISInvertPermutation(rowp,PETSC_DECIDE,&irowp);CHKERRQ(ierr);
180956cd22aeSBarry Smith   ierr = ISGetIndices(irowp,&row);CHKERRQ(ierr);
18104c49b128SBarry Smith   ierr = ISInvertPermutation(colp,PETSC_DECIDE,&icolp);CHKERRQ(ierr);
181156cd22aeSBarry Smith   ierr = ISGetIndices(icolp,&col);CHKERRQ(ierr);
18120513a670SBarry Smith 
18130513a670SBarry Smith   /* determine lengths of permuted rows */
1814b0a32e0cSBarry Smith   ierr = PetscMalloc((m+1)*sizeof(int),&lens);CHKERRQ(ierr);
18150513a670SBarry Smith   for (i=0; i<m; i++) {
18160513a670SBarry Smith     lens[row[i]] = a->i[i+1] - a->i[i];
18170513a670SBarry Smith   }
18180513a670SBarry Smith   ierr = MatCreateSeqAIJ(A->comm,m,n,0,lens,B);CHKERRQ(ierr);
1819606d414cSSatish Balay   ierr = PetscFree(lens);CHKERRQ(ierr);
18200513a670SBarry Smith 
1821b0a32e0cSBarry Smith   ierr = PetscMalloc(n*sizeof(int),&cnew);CHKERRQ(ierr);
18220513a670SBarry Smith   for (i=0; i<m; i++) {
18230513a670SBarry Smith     ierr = MatGetRow(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr);
18240513a670SBarry Smith     for (j=0; j<nz; j++) { cnew[j] = col[cwork[j]];}
18250513a670SBarry Smith     ierr = MatSetValues(*B,1,&row[i],nz,cnew,vwork,INSERT_VALUES);CHKERRQ(ierr);
18260513a670SBarry Smith     ierr = MatRestoreRow(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr);
18270513a670SBarry Smith   }
1828606d414cSSatish Balay   ierr = PetscFree(cnew);CHKERRQ(ierr);
18290513a670SBarry Smith   ierr = MatAssemblyBegin(*B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
18300513a670SBarry Smith   ierr = MatAssemblyEnd(*B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
183156cd22aeSBarry Smith   ierr = ISRestoreIndices(irowp,&row);CHKERRQ(ierr);
183256cd22aeSBarry Smith   ierr = ISRestoreIndices(icolp,&col);CHKERRQ(ierr);
183356cd22aeSBarry Smith   ierr = ISDestroy(irowp);CHKERRQ(ierr);
183456cd22aeSBarry Smith   ierr = ISDestroy(icolp);CHKERRQ(ierr);
18353a40ed3dSBarry Smith   PetscFunctionReturn(0);
18360513a670SBarry Smith }
18370513a670SBarry Smith 
18384a2ae208SSatish Balay #undef __FUNCT__
18394a2ae208SSatish Balay #define __FUNCT__ "MatPrintHelp_SeqAIJ"
1840682d7d0cSBarry Smith int MatPrintHelp_SeqAIJ(Mat A)
1841682d7d0cSBarry Smith {
1842c38d4ed2SBarry Smith   static PetscTruth called = PETSC_FALSE;
1843682d7d0cSBarry Smith   MPI_Comm          comm = A->comm;
1844d132466eSBarry Smith   int               ierr;
1845682d7d0cSBarry Smith 
18463a40ed3dSBarry Smith   PetscFunctionBegin;
1847c38d4ed2SBarry Smith   if (called) {PetscFunctionReturn(0);} else called = PETSC_TRUE;
1848d132466eSBarry Smith   ierr = (*PetscHelpPrintf)(comm," Options for MATSEQAIJ and MATMPIAIJ matrix formats (the defaults):\n");CHKERRQ(ierr);
1849d132466eSBarry Smith   ierr = (*PetscHelpPrintf)(comm,"  -mat_lu_pivotthreshold <threshold>: Set pivoting threshold\n");CHKERRQ(ierr);
1850d132466eSBarry Smith   ierr = (*PetscHelpPrintf)(comm,"  -mat_aij_oneindex: internal indices begin at 1 instead of the default 0.\n");CHKERRQ(ierr);
1851d132466eSBarry Smith   ierr = (*PetscHelpPrintf)(comm,"  -mat_aij_no_inode: Do not use inodes\n");CHKERRQ(ierr);
1852d132466eSBarry Smith   ierr = (*PetscHelpPrintf)(comm,"  -mat_aij_inode_limit <limit>: Set inode limit (max limit=5)\n");CHKERRQ(ierr);
1853aa482453SBarry Smith #if defined(PETSC_HAVE_ESSL)
1854d132466eSBarry Smith   ierr = (*PetscHelpPrintf)(comm,"  -mat_aij_essl: Use IBM sparse LU factorization and solve.\n");CHKERRQ(ierr);
1855682d7d0cSBarry Smith #endif
1856cd5578b5SBarry Smith #if defined(PETSC_HAVE_LUSOL)
1857cd5578b5SBarry Smith   ierr = (*PetscHelpPrintf)(comm,"  -mat_aij_lusol: Use the Stanford LUSOL sparse factorization and solve.\n");CHKERRQ(ierr);
1858cd5578b5SBarry Smith #endif
185987828ca2SBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE) && !defined(PETSC_USE_COMPLEX) && !defined(PETSC_USE_SINGLE)
1860ca44d042SBarry Smith   ierr = (*PetscHelpPrintf)(comm,"  -mat_aij_matlab: Use Matlab engine sparse LU factorization and solve.\n");CHKERRQ(ierr);
1861ca44d042SBarry Smith #endif
18623a40ed3dSBarry Smith   PetscFunctionReturn(0);
1863682d7d0cSBarry Smith }
1864ca44d042SBarry Smith EXTERN int MatEqual_SeqAIJ(Mat A,Mat B,PetscTruth* flg);
1865ca44d042SBarry Smith EXTERN int MatFDColoringCreate_SeqAIJ(Mat,ISColoring,MatFDColoring);
1866ca44d042SBarry Smith EXTERN int MatILUDTFactor_SeqAIJ(Mat,MatILUInfo*,IS,IS,Mat*);
18674a2ae208SSatish Balay #undef __FUNCT__
18684a2ae208SSatish Balay #define __FUNCT__ "MatCopy_SeqAIJ"
1869cb5b572fSBarry Smith int MatCopy_SeqAIJ(Mat A,Mat B,MatStructure str)
1870cb5b572fSBarry Smith {
1871be6bf707SBarry Smith   int        ierr;
1872273d9f13SBarry Smith   PetscTruth flg;
1873cb5b572fSBarry Smith 
1874cb5b572fSBarry Smith   PetscFunctionBegin;
1875273d9f13SBarry Smith   ierr = PetscTypeCompare((PetscObject)B,MATSEQAIJ,&flg);CHKERRQ(ierr);
1876273d9f13SBarry Smith   if (str == SAME_NONZERO_PATTERN && flg) {
1877be6bf707SBarry Smith     Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
1878be6bf707SBarry Smith     Mat_SeqAIJ *b = (Mat_SeqAIJ*)B->data;
1879be6bf707SBarry Smith 
1880273d9f13SBarry Smith     if (a->i[A->m]+a->indexshift != b->i[B->m]+a->indexshift) {
188129bbc08cSBarry Smith       SETERRQ(1,"Number of nonzeros in two matrices are different");
1882cb5b572fSBarry Smith     }
188387828ca2SBarry Smith     ierr = PetscMemcpy(b->a,a->a,(a->i[A->m]+a->indexshift)*sizeof(PetscScalar));CHKERRQ(ierr);
1884cb5b572fSBarry Smith   } else {
1885cb5b572fSBarry Smith     ierr = MatCopy_Basic(A,B,str);CHKERRQ(ierr);
1886cb5b572fSBarry Smith   }
1887cb5b572fSBarry Smith   PetscFunctionReturn(0);
1888cb5b572fSBarry Smith }
1889cb5b572fSBarry Smith 
18904a2ae208SSatish Balay #undef __FUNCT__
18914a2ae208SSatish Balay #define __FUNCT__ "MatSetUpPreallocation_SeqAIJ"
1892273d9f13SBarry Smith int MatSetUpPreallocation_SeqAIJ(Mat A)
1893273d9f13SBarry Smith {
1894273d9f13SBarry Smith   int        ierr;
1895273d9f13SBarry Smith 
1896273d9f13SBarry Smith   PetscFunctionBegin;
1897273d9f13SBarry Smith   ierr =  MatSeqAIJSetPreallocation(A,PETSC_DEFAULT,0);CHKERRQ(ierr);
1898273d9f13SBarry Smith   PetscFunctionReturn(0);
1899273d9f13SBarry Smith }
1900273d9f13SBarry Smith 
19014a2ae208SSatish Balay #undef __FUNCT__
19024a2ae208SSatish Balay #define __FUNCT__ "MatGetArray_SeqAIJ"
190387828ca2SBarry Smith int MatGetArray_SeqAIJ(Mat A,PetscScalar **array)
19046c0721eeSBarry Smith {
19056c0721eeSBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
19066c0721eeSBarry Smith   PetscFunctionBegin;
19076c0721eeSBarry Smith   *array = a->a;
19086c0721eeSBarry Smith   PetscFunctionReturn(0);
19096c0721eeSBarry Smith }
19106c0721eeSBarry Smith 
19114a2ae208SSatish Balay #undef __FUNCT__
19124a2ae208SSatish Balay #define __FUNCT__ "MatRestoreArray_SeqAIJ"
191387828ca2SBarry Smith int MatRestoreArray_SeqAIJ(Mat A,PetscScalar **array)
19146c0721eeSBarry Smith {
19156c0721eeSBarry Smith   PetscFunctionBegin;
19166c0721eeSBarry Smith   PetscFunctionReturn(0);
19176c0721eeSBarry Smith }
1918273d9f13SBarry Smith 
1919ee4f033dSBarry Smith #undef __FUNCT__
1920ee4f033dSBarry Smith #define __FUNCT__ "MatFDColoringApply_SeqAIJ"
1921ee4f033dSBarry Smith int MatFDColoringApply_SeqAIJ(Mat J,MatFDColoring coloring,Vec x1,MatStructure *flag,void *sctx)
1922ee4f033dSBarry Smith {
1923ee4f033dSBarry Smith   int           (*f)(void *,Vec,Vec,void*) = (int (*)(void *,Vec,Vec,void *))coloring->f;
1924ee4f033dSBarry Smith   int           k,ierr,N,start,end,l,row,col,srow,**vscaleforrow,m1,m2;
192587828ca2SBarry Smith   PetscScalar   dx,mone = -1.0,*y,*xx,*w3_array;
192687828ca2SBarry Smith   PetscScalar   *vscale_array;
1927ee4f033dSBarry Smith   PetscReal     epsilon = coloring->error_rel,umin = coloring->umin;
1928ee4f033dSBarry Smith   Vec           w1,w2,w3;
1929ee4f033dSBarry Smith   void          *fctx = coloring->fctx;
1930ee4f033dSBarry Smith   PetscTruth    flg;
1931ee4f033dSBarry Smith 
1932ee4f033dSBarry Smith   PetscFunctionBegin;
1933ee4f033dSBarry Smith   if (!coloring->w1) {
1934ee4f033dSBarry Smith     ierr = VecDuplicate(x1,&coloring->w1);CHKERRQ(ierr);
1935ee4f033dSBarry Smith     PetscLogObjectParent(coloring,coloring->w1);
1936ee4f033dSBarry Smith     ierr = VecDuplicate(x1,&coloring->w2);CHKERRQ(ierr);
1937ee4f033dSBarry Smith     PetscLogObjectParent(coloring,coloring->w2);
1938ee4f033dSBarry Smith     ierr = VecDuplicate(x1,&coloring->w3);CHKERRQ(ierr);
1939ee4f033dSBarry Smith     PetscLogObjectParent(coloring,coloring->w3);
1940ee4f033dSBarry Smith   }
1941ee4f033dSBarry Smith   w1 = coloring->w1; w2 = coloring->w2; w3 = coloring->w3;
1942ee4f033dSBarry Smith 
1943ee4f033dSBarry Smith   ierr = MatSetUnfactored(J);CHKERRQ(ierr);
1944e82a3eeeSBarry Smith   ierr = PetscOptionsHasName(coloring->prefix,"-mat_fd_coloring_dont_rezero",&flg);CHKERRQ(ierr);
1945ee4f033dSBarry Smith   if (flg) {
1946ee4f033dSBarry Smith     PetscLogInfo(coloring,"MatFDColoringApply_SeqAIJ: Not calling MatZeroEntries()\n");
1947ee4f033dSBarry Smith   } else {
1948ee4f033dSBarry Smith     ierr = MatZeroEntries(J);CHKERRQ(ierr);
1949ee4f033dSBarry Smith   }
1950ee4f033dSBarry Smith 
1951ee4f033dSBarry Smith   ierr = VecGetOwnershipRange(x1,&start,&end);CHKERRQ(ierr);
1952ee4f033dSBarry Smith   ierr = VecGetSize(x1,&N);CHKERRQ(ierr);
1953ee4f033dSBarry Smith 
1954ee4f033dSBarry Smith   /*
1955ee4f033dSBarry Smith        This is a horrible, horrible, hack. See DMMGComputeJacobian_Multigrid() it inproperly sets
1956ee4f033dSBarry Smith      coloring->F for the coarser grids from the finest
1957ee4f033dSBarry Smith   */
1958ee4f033dSBarry Smith   if (coloring->F) {
1959ee4f033dSBarry Smith     ierr = VecGetLocalSize(coloring->F,&m1);CHKERRQ(ierr);
1960ee4f033dSBarry Smith     ierr = VecGetLocalSize(w1,&m2);CHKERRQ(ierr);
1961ee4f033dSBarry Smith     if (m1 != m2) {
1962ee4f033dSBarry Smith       coloring->F = 0;
1963ee4f033dSBarry Smith     }
1964ee4f033dSBarry Smith   }
1965ee4f033dSBarry Smith 
1966ee4f033dSBarry Smith   if (coloring->F) {
1967ee4f033dSBarry Smith     w1          = coloring->F;
1968ee4f033dSBarry Smith     coloring->F = 0;
1969ee4f033dSBarry Smith   } else {
1970ee4f033dSBarry Smith     ierr = (*f)(sctx,x1,w1,fctx);CHKERRQ(ierr);
1971ee4f033dSBarry Smith   }
1972ee4f033dSBarry Smith 
1973ee4f033dSBarry Smith   /*
1974ee4f033dSBarry Smith       Compute all the scale factors and share with other processors
1975ee4f033dSBarry Smith   */
1976ee4f033dSBarry Smith   ierr = VecGetArray(x1,&xx);CHKERRQ(ierr);xx = xx - start;
1977ee4f033dSBarry Smith   ierr = VecGetArray(coloring->vscale,&vscale_array);CHKERRQ(ierr);vscale_array = vscale_array - start;
1978ee4f033dSBarry Smith   for (k=0; k<coloring->ncolors; k++) {
1979ee4f033dSBarry Smith     /*
1980ee4f033dSBarry Smith        Loop over each column associated with color adding the
1981ee4f033dSBarry Smith        perturbation to the vector w3.
1982ee4f033dSBarry Smith     */
1983ee4f033dSBarry Smith     for (l=0; l<coloring->ncolumns[k]; l++) {
1984ee4f033dSBarry Smith       col = coloring->columns[k][l];    /* column of the matrix we are probing for */
1985ee4f033dSBarry Smith       dx  = xx[col];
1986ee4f033dSBarry Smith       if (dx == 0.0) dx = 1.0;
1987ee4f033dSBarry Smith #if !defined(PETSC_USE_COMPLEX)
1988ee4f033dSBarry Smith       if (dx < umin && dx >= 0.0)      dx = umin;
1989ee4f033dSBarry Smith       else if (dx < 0.0 && dx > -umin) dx = -umin;
1990ee4f033dSBarry Smith #else
1991ee4f033dSBarry Smith       if (PetscAbsScalar(dx) < umin && PetscRealPart(dx) >= 0.0)     dx = umin;
1992ee4f033dSBarry Smith       else if (PetscRealPart(dx) < 0.0 && PetscAbsScalar(dx) < umin) dx = -umin;
1993ee4f033dSBarry Smith #endif
1994ee4f033dSBarry Smith       dx                *= epsilon;
1995ee4f033dSBarry Smith       vscale_array[col] = 1.0/dx;
1996ee4f033dSBarry Smith     }
1997ee4f033dSBarry Smith   }
1998ee4f033dSBarry Smith   vscale_array = vscale_array + start;ierr = VecRestoreArray(coloring->vscale,&vscale_array);CHKERRQ(ierr);
1999ee4f033dSBarry Smith   ierr = VecGhostUpdateBegin(coloring->vscale,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
2000ee4f033dSBarry Smith   ierr = VecGhostUpdateEnd(coloring->vscale,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
2001ee4f033dSBarry Smith 
2002ee4f033dSBarry Smith   /*  ierr = VecView(coloring->vscale,PETSC_VIEWER_STDOUT_WORLD);
2003ee4f033dSBarry Smith       ierr = VecView(x1,PETSC_VIEWER_STDOUT_WORLD);*/
2004ee4f033dSBarry Smith 
2005ee4f033dSBarry Smith   if (coloring->vscaleforrow) vscaleforrow = coloring->vscaleforrow;
2006ee4f033dSBarry Smith   else                        vscaleforrow = coloring->columnsforrow;
2007ee4f033dSBarry Smith 
2008ee4f033dSBarry Smith   ierr = VecGetArray(coloring->vscale,&vscale_array);CHKERRQ(ierr);
2009ee4f033dSBarry Smith   /*
2010ee4f033dSBarry Smith       Loop over each color
2011ee4f033dSBarry Smith   */
2012ee4f033dSBarry Smith   for (k=0; k<coloring->ncolors; k++) {
201349b058dcSBarry Smith     coloring->currentcolor = k;
2014ee4f033dSBarry Smith     ierr = VecCopy(x1,w3);CHKERRQ(ierr);
2015ee4f033dSBarry Smith     ierr = VecGetArray(w3,&w3_array);CHKERRQ(ierr);w3_array = w3_array - start;
2016ee4f033dSBarry Smith     /*
2017ee4f033dSBarry Smith        Loop over each column associated with color adding the
2018ee4f033dSBarry Smith        perturbation to the vector w3.
2019ee4f033dSBarry Smith     */
2020ee4f033dSBarry Smith     for (l=0; l<coloring->ncolumns[k]; l++) {
2021ee4f033dSBarry Smith       col = coloring->columns[k][l];    /* column of the matrix we are probing for */
2022ee4f033dSBarry Smith       dx  = xx[col];
2023ee4f033dSBarry Smith       if (dx == 0.0) dx = 1.0;
2024ee4f033dSBarry Smith #if !defined(PETSC_USE_COMPLEX)
2025ee4f033dSBarry Smith       if (dx < umin && dx >= 0.0)      dx = umin;
2026ee4f033dSBarry Smith       else if (dx < 0.0 && dx > -umin) dx = -umin;
2027ee4f033dSBarry Smith #else
2028ee4f033dSBarry Smith       if (PetscAbsScalar(dx) < umin && PetscRealPart(dx) >= 0.0)     dx = umin;
2029ee4f033dSBarry Smith       else if (PetscRealPart(dx) < 0.0 && PetscAbsScalar(dx) < umin) dx = -umin;
2030ee4f033dSBarry Smith #endif
2031ee4f033dSBarry Smith       dx            *= epsilon;
2032ee4f033dSBarry Smith       if (!PetscAbsScalar(dx)) SETERRQ(1,"Computed 0 differencing parameter");
2033ee4f033dSBarry Smith       w3_array[col] += dx;
2034ee4f033dSBarry Smith     }
2035ee4f033dSBarry Smith     w3_array = w3_array + start; ierr = VecRestoreArray(w3,&w3_array);CHKERRQ(ierr);
2036ee4f033dSBarry Smith 
2037ee4f033dSBarry Smith     /*
2038ee4f033dSBarry Smith        Evaluate function at x1 + dx (here dx is a vector of perturbations)
2039ee4f033dSBarry Smith     */
2040ee4f033dSBarry Smith 
2041ee4f033dSBarry Smith     ierr = (*f)(sctx,w3,w2,fctx);CHKERRQ(ierr);
2042ee4f033dSBarry Smith     ierr = VecAXPY(&mone,w1,w2);CHKERRQ(ierr);
2043ee4f033dSBarry Smith 
2044ee4f033dSBarry Smith     /*
2045ee4f033dSBarry Smith        Loop over rows of vector, putting results into Jacobian matrix
2046ee4f033dSBarry Smith     */
2047ee4f033dSBarry Smith     ierr = VecGetArray(w2,&y);CHKERRQ(ierr);
2048ee4f033dSBarry Smith     for (l=0; l<coloring->nrows[k]; l++) {
2049ee4f033dSBarry Smith       row    = coloring->rows[k][l];
2050ee4f033dSBarry Smith       col    = coloring->columnsforrow[k][l];
2051ee4f033dSBarry Smith       y[row] *= vscale_array[vscaleforrow[k][l]];
2052ee4f033dSBarry Smith       srow   = row + start;
2053ee4f033dSBarry Smith       ierr   = MatSetValues_SeqAIJ(J,1,&srow,1,&col,y+row,INSERT_VALUES);CHKERRQ(ierr);
2054ee4f033dSBarry Smith     }
2055ee4f033dSBarry Smith     ierr = VecRestoreArray(w2,&y);CHKERRQ(ierr);
2056ee4f033dSBarry Smith   }
205749b058dcSBarry Smith   coloring->currentcolor = k;
2058ee4f033dSBarry Smith   ierr = VecRestoreArray(coloring->vscale,&vscale_array);CHKERRQ(ierr);
2059ee4f033dSBarry Smith   xx = xx + start; ierr  = VecRestoreArray(x1,&xx);CHKERRQ(ierr);
2060ee4f033dSBarry Smith   ierr  = MatAssemblyBegin(J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
2061ee4f033dSBarry Smith   ierr  = MatAssemblyEnd(J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
2062ee4f033dSBarry Smith   PetscFunctionReturn(0);
2063ee4f033dSBarry Smith }
2064ee4f033dSBarry Smith 
2065ac90fabeSBarry Smith #include "petscblaslapack.h"
2066ac90fabeSBarry Smith 
2067ac90fabeSBarry Smith #undef __FUNCT__
2068ac90fabeSBarry Smith #define __FUNCT__ "MatAXPY_SeqAIJ"
2069ac90fabeSBarry Smith int MatAXPY_SeqAIJ(PetscScalar *a,Mat X,Mat Y,MatStructure str)
2070ac90fabeSBarry Smith {
2071556bd4faSSatish Balay   int        ierr,one=1;
2072ac90fabeSBarry Smith   Mat_SeqAIJ *x  = (Mat_SeqAIJ *)X->data,*y = (Mat_SeqAIJ *)Y->data;
2073ac90fabeSBarry Smith 
2074ac90fabeSBarry Smith   PetscFunctionBegin;
2075ac90fabeSBarry Smith   if (str == SAME_NONZERO_PATTERN) {
2076ac90fabeSBarry Smith     BLaxpy_(&x->nz,a,x->a,&one,y->a,&one);
2077ac90fabeSBarry Smith   } else {
2078ac90fabeSBarry Smith     ierr = MatAXPY_Basic(a,X,Y,str);CHKERRQ(ierr);
2079ac90fabeSBarry Smith   }
2080ac90fabeSBarry Smith   PetscFunctionReturn(0);
2081ac90fabeSBarry Smith }
2082ac90fabeSBarry Smith 
2083ac90fabeSBarry Smith 
2084682d7d0cSBarry Smith /* -------------------------------------------------------------------*/
20850a6ffc59SBarry Smith static struct _MatOps MatOps_Values = {MatSetValues_SeqAIJ,
2086cb5b572fSBarry Smith        MatGetRow_SeqAIJ,
2087cb5b572fSBarry Smith        MatRestoreRow_SeqAIJ,
2088cb5b572fSBarry Smith        MatMult_SeqAIJ,
2089cb5b572fSBarry Smith        MatMultAdd_SeqAIJ,
20907c922b88SBarry Smith        MatMultTranspose_SeqAIJ,
20917c922b88SBarry Smith        MatMultTransposeAdd_SeqAIJ,
2092cb5b572fSBarry Smith        MatSolve_SeqAIJ,
2093cb5b572fSBarry Smith        MatSolveAdd_SeqAIJ,
20947c922b88SBarry Smith        MatSolveTranspose_SeqAIJ,
20957c922b88SBarry Smith        MatSolveTransposeAdd_SeqAIJ,
2096cb5b572fSBarry Smith        MatLUFactor_SeqAIJ,
2097cb5b572fSBarry Smith        0,
209817ab2063SBarry Smith        MatRelax_SeqAIJ,
209917ab2063SBarry Smith        MatTranspose_SeqAIJ,
2100cb5b572fSBarry Smith        MatGetInfo_SeqAIJ,
2101cb5b572fSBarry Smith        MatEqual_SeqAIJ,
2102cb5b572fSBarry Smith        MatGetDiagonal_SeqAIJ,
2103cb5b572fSBarry Smith        MatDiagonalScale_SeqAIJ,
2104cb5b572fSBarry Smith        MatNorm_SeqAIJ,
2105cb5b572fSBarry Smith        0,
2106cb5b572fSBarry Smith        MatAssemblyEnd_SeqAIJ,
210717ab2063SBarry Smith        MatCompress_SeqAIJ,
2108cb5b572fSBarry Smith        MatSetOption_SeqAIJ,
2109cb5b572fSBarry Smith        MatZeroEntries_SeqAIJ,
2110cb5b572fSBarry Smith        MatZeroRows_SeqAIJ,
2111cb5b572fSBarry Smith        MatLUFactorSymbolic_SeqAIJ,
2112cb5b572fSBarry Smith        MatLUFactorNumeric_SeqAIJ,
2113cb5b572fSBarry Smith        0,
2114cb5b572fSBarry Smith        0,
2115273d9f13SBarry Smith        MatSetUpPreallocation_SeqAIJ,
2116cb5b572fSBarry Smith        MatILUFactorSymbolic_SeqAIJ,
2117cb5b572fSBarry Smith        0,
21186c0721eeSBarry Smith        MatGetArray_SeqAIJ,
21196c0721eeSBarry Smith        MatRestoreArray_SeqAIJ,
2120be6bf707SBarry Smith        MatDuplicate_SeqAIJ,
2121cb5b572fSBarry Smith        0,
2122cb5b572fSBarry Smith        0,
2123cb5b572fSBarry Smith        MatILUFactor_SeqAIJ,
2124cb5b572fSBarry Smith        0,
2125ac90fabeSBarry Smith        MatAXPY_SeqAIJ,
2126cb5b572fSBarry Smith        MatGetSubMatrices_SeqAIJ,
2127cb5b572fSBarry Smith        MatIncreaseOverlap_SeqAIJ,
2128cb5b572fSBarry Smith        MatGetValues_SeqAIJ,
2129cb5b572fSBarry Smith        MatCopy_SeqAIJ,
2130f0b747eeSBarry Smith        MatPrintHelp_SeqAIJ,
2131cb5b572fSBarry Smith        MatScale_SeqAIJ,
2132cb5b572fSBarry Smith        0,
2133cb5b572fSBarry Smith        0,
21346945ee14SBarry Smith        MatILUDTFactor_SeqAIJ,
21356945ee14SBarry Smith        MatGetBlockSize_SeqAIJ,
21363b2fbd54SBarry Smith        MatGetRowIJ_SeqAIJ,
21373b2fbd54SBarry Smith        MatRestoreRowIJ_SeqAIJ,
21383b2fbd54SBarry Smith        MatGetColumnIJ_SeqAIJ,
2139a93ec695SBarry Smith        MatRestoreColumnIJ_SeqAIJ,
2140a93ec695SBarry Smith        MatFDColoringCreate_SeqAIJ,
2141b9617806SBarry Smith        0,
21420513a670SBarry Smith        0,
2143cda55fadSBarry Smith        MatPermute_SeqAIJ,
2144cda55fadSBarry Smith        0,
2145cda55fadSBarry Smith        0,
2146b9b97703SBarry Smith        MatDestroy_SeqAIJ,
2147b9b97703SBarry Smith        MatView_SeqAIJ,
21488a124369SBarry Smith        MatGetPetscMaps_Petsc,
2149ee4f033dSBarry Smith        0,
2150ee4f033dSBarry Smith        0,
2151ee4f033dSBarry Smith        0,
2152ee4f033dSBarry Smith        0,
2153ee4f033dSBarry Smith        0,
2154ee4f033dSBarry Smith        0,
2155ee4f033dSBarry Smith        0,
2156ee4f033dSBarry Smith        0,
2157ee4f033dSBarry Smith        MatSetColoring_SeqAIJ,
2158ee4f033dSBarry Smith        MatSetValuesAdic_SeqAIJ,
2159ee4f033dSBarry Smith        MatSetValuesAdifor_SeqAIJ,
2160ee4f033dSBarry Smith        MatFDColoringApply_SeqAIJ};
216117ab2063SBarry Smith 
2162fb2e594dSBarry Smith EXTERN_C_BEGIN
21634a2ae208SSatish Balay #undef __FUNCT__
21644a2ae208SSatish Balay #define __FUNCT__ "MatSeqAIJSetColumnIndices_SeqAIJ"
216515091d37SBarry Smith 
2166bef8e0ddSBarry Smith int MatSeqAIJSetColumnIndices_SeqAIJ(Mat mat,int *indices)
2167bef8e0ddSBarry Smith {
2168bef8e0ddSBarry Smith   Mat_SeqAIJ *aij = (Mat_SeqAIJ *)mat->data;
2169bef8e0ddSBarry Smith   int        i,nz,n;
2170bef8e0ddSBarry Smith 
2171bef8e0ddSBarry Smith   PetscFunctionBegin;
2172bef8e0ddSBarry Smith 
2173bef8e0ddSBarry Smith   nz = aij->maxnz;
2174273d9f13SBarry Smith   n  = mat->n;
2175bef8e0ddSBarry Smith   for (i=0; i<nz; i++) {
2176bef8e0ddSBarry Smith     aij->j[i] = indices[i];
2177bef8e0ddSBarry Smith   }
2178bef8e0ddSBarry Smith   aij->nz = nz;
2179bef8e0ddSBarry Smith   for (i=0; i<n; i++) {
2180bef8e0ddSBarry Smith     aij->ilen[i] = aij->imax[i];
2181bef8e0ddSBarry Smith   }
2182bef8e0ddSBarry Smith 
2183bef8e0ddSBarry Smith   PetscFunctionReturn(0);
2184bef8e0ddSBarry Smith }
2185fb2e594dSBarry Smith EXTERN_C_END
2186bef8e0ddSBarry Smith 
21874a2ae208SSatish Balay #undef __FUNCT__
21884a2ae208SSatish Balay #define __FUNCT__ "MatSeqAIJSetColumnIndices"
2189bef8e0ddSBarry Smith /*@
2190bef8e0ddSBarry Smith     MatSeqAIJSetColumnIndices - Set the column indices for all the rows
2191bef8e0ddSBarry Smith        in the matrix.
2192bef8e0ddSBarry Smith 
2193bef8e0ddSBarry Smith   Input Parameters:
2194bef8e0ddSBarry Smith +  mat - the SeqAIJ matrix
2195bef8e0ddSBarry Smith -  indices - the column indices
2196bef8e0ddSBarry Smith 
219715091d37SBarry Smith   Level: advanced
219815091d37SBarry Smith 
2199bef8e0ddSBarry Smith   Notes:
2200bef8e0ddSBarry Smith     This can be called if you have precomputed the nonzero structure of the
2201bef8e0ddSBarry Smith   matrix and want to provide it to the matrix object to improve the performance
2202bef8e0ddSBarry Smith   of the MatSetValues() operation.
2203bef8e0ddSBarry Smith 
2204bef8e0ddSBarry Smith     You MUST have set the correct numbers of nonzeros per row in the call to
2205bef8e0ddSBarry Smith   MatCreateSeqAIJ().
2206bef8e0ddSBarry Smith 
2207bef8e0ddSBarry Smith     MUST be called before any calls to MatSetValues();
2208bef8e0ddSBarry Smith 
2209b9617806SBarry Smith     The indices should start with zero, not one.
2210b9617806SBarry Smith 
2211bef8e0ddSBarry Smith @*/
2212bef8e0ddSBarry Smith int MatSeqAIJSetColumnIndices(Mat mat,int *indices)
2213bef8e0ddSBarry Smith {
2214bef8e0ddSBarry Smith   int ierr,(*f)(Mat,int *);
2215bef8e0ddSBarry Smith 
2216bef8e0ddSBarry Smith   PetscFunctionBegin;
2217bef8e0ddSBarry Smith   PetscValidHeaderSpecific(mat,MAT_COOKIE);
2218c134de8dSSatish Balay   ierr = PetscObjectQueryFunction((PetscObject)mat,"MatSeqAIJSetColumnIndices_C",(void (**)(void))&f);CHKERRQ(ierr);
2219bef8e0ddSBarry Smith   if (f) {
2220bef8e0ddSBarry Smith     ierr = (*f)(mat,indices);CHKERRQ(ierr);
2221bef8e0ddSBarry Smith   } else {
222229bbc08cSBarry Smith     SETERRQ(1,"Wrong type of matrix to set column indices");
2223bef8e0ddSBarry Smith   }
2224bef8e0ddSBarry Smith   PetscFunctionReturn(0);
2225bef8e0ddSBarry Smith }
2226bef8e0ddSBarry Smith 
2227be6bf707SBarry Smith /* ----------------------------------------------------------------------------------------*/
2228be6bf707SBarry Smith 
2229fb2e594dSBarry Smith EXTERN_C_BEGIN
22304a2ae208SSatish Balay #undef __FUNCT__
22314a2ae208SSatish Balay #define __FUNCT__ "MatStoreValues_SeqAIJ"
2232be6bf707SBarry Smith int MatStoreValues_SeqAIJ(Mat mat)
2233be6bf707SBarry Smith {
2234be6bf707SBarry Smith   Mat_SeqAIJ *aij = (Mat_SeqAIJ *)mat->data;
2235a7ed9263SMatthew Knepley   size_t       nz = aij->i[mat->m]+aij->indexshift,ierr;
2236be6bf707SBarry Smith 
2237be6bf707SBarry Smith   PetscFunctionBegin;
2238be6bf707SBarry Smith   if (aij->nonew != 1) {
223929bbc08cSBarry Smith     SETERRQ(1,"Must call MatSetOption(A,MAT_NO_NEW_NONZERO_LOCATIONS);first");
2240be6bf707SBarry Smith   }
2241be6bf707SBarry Smith 
2242be6bf707SBarry Smith   /* allocate space for values if not already there */
2243be6bf707SBarry Smith   if (!aij->saved_values) {
224487828ca2SBarry Smith     ierr = PetscMalloc((nz+1)*sizeof(PetscScalar),&aij->saved_values);CHKERRQ(ierr);
2245be6bf707SBarry Smith   }
2246be6bf707SBarry Smith 
2247be6bf707SBarry Smith   /* copy values over */
224887828ca2SBarry Smith   ierr = PetscMemcpy(aij->saved_values,aij->a,nz*sizeof(PetscScalar));CHKERRQ(ierr);
2249be6bf707SBarry Smith   PetscFunctionReturn(0);
2250be6bf707SBarry Smith }
2251fb2e594dSBarry Smith EXTERN_C_END
2252be6bf707SBarry Smith 
22534a2ae208SSatish Balay #undef __FUNCT__
2254b9617806SBarry Smith #define __FUNCT__ "MatStoreValues"
2255be6bf707SBarry Smith /*@
2256be6bf707SBarry Smith     MatStoreValues - Stashes a copy of the matrix values; this allows, for
2257be6bf707SBarry Smith        example, reuse of the linear part of a Jacobian, while recomputing the
2258be6bf707SBarry Smith        nonlinear portion.
2259be6bf707SBarry Smith 
2260be6bf707SBarry Smith    Collect on Mat
2261be6bf707SBarry Smith 
2262be6bf707SBarry Smith   Input Parameters:
2263be6bf707SBarry Smith .  mat - the matrix (currently on AIJ matrices support this option)
2264be6bf707SBarry Smith 
226515091d37SBarry Smith   Level: advanced
226615091d37SBarry Smith 
2267be6bf707SBarry Smith   Common Usage, with SNESSolve():
2268be6bf707SBarry Smith $    Create Jacobian matrix
2269be6bf707SBarry Smith $    Set linear terms into matrix
2270be6bf707SBarry Smith $    Apply boundary conditions to matrix, at this time matrix must have
2271be6bf707SBarry Smith $      final nonzero structure (i.e. setting the nonlinear terms and applying
2272be6bf707SBarry Smith $      boundary conditions again will not change the nonzero structure
2273be6bf707SBarry Smith $    ierr = MatSetOption(mat,MAT_NO_NEW_NONZERO_LOCATIONS);
2274be6bf707SBarry Smith $    ierr = MatStoreValues(mat);
2275be6bf707SBarry Smith $    Call SNESSetJacobian() with matrix
2276be6bf707SBarry Smith $    In your Jacobian routine
2277be6bf707SBarry Smith $      ierr = MatRetrieveValues(mat);
2278be6bf707SBarry Smith $      Set nonlinear terms in matrix
2279be6bf707SBarry Smith 
2280be6bf707SBarry Smith   Common Usage without SNESSolve(), i.e. when you handle nonlinear solve yourself:
2281be6bf707SBarry Smith $    // build linear portion of Jacobian
2282be6bf707SBarry Smith $    ierr = MatSetOption(mat,MAT_NO_NEW_NONZERO_LOCATIONS);
2283be6bf707SBarry Smith $    ierr = MatStoreValues(mat);
2284be6bf707SBarry Smith $    loop over nonlinear iterations
2285be6bf707SBarry Smith $       ierr = MatRetrieveValues(mat);
2286be6bf707SBarry Smith $       // call MatSetValues(mat,...) to set nonliner portion of Jacobian
2287be6bf707SBarry Smith $       // call MatAssemblyBegin/End() on matrix
2288be6bf707SBarry Smith $       Solve linear system with Jacobian
2289be6bf707SBarry Smith $    endloop
2290be6bf707SBarry Smith 
2291be6bf707SBarry Smith   Notes:
2292be6bf707SBarry Smith     Matrix must already be assemblied before calling this routine
2293be6bf707SBarry Smith     Must set the matrix option MatSetOption(mat,MAT_NO_NEW_NONZERO_LOCATIONS); before
2294be6bf707SBarry Smith     calling this routine.
2295be6bf707SBarry Smith 
2296be6bf707SBarry Smith .seealso: MatRetrieveValues()
2297be6bf707SBarry Smith 
2298be6bf707SBarry Smith @*/
2299be6bf707SBarry Smith int MatStoreValues(Mat mat)
2300be6bf707SBarry Smith {
2301be6bf707SBarry Smith   int ierr,(*f)(Mat);
2302be6bf707SBarry Smith 
2303be6bf707SBarry Smith   PetscFunctionBegin;
2304be6bf707SBarry Smith   PetscValidHeaderSpecific(mat,MAT_COOKIE);
230529bbc08cSBarry Smith   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
230629bbc08cSBarry Smith   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2307be6bf707SBarry Smith 
2308c134de8dSSatish Balay   ierr = PetscObjectQueryFunction((PetscObject)mat,"MatStoreValues_C",(void (**)(void))&f);CHKERRQ(ierr);
2309be6bf707SBarry Smith   if (f) {
2310be6bf707SBarry Smith     ierr = (*f)(mat);CHKERRQ(ierr);
2311be6bf707SBarry Smith   } else {
231229bbc08cSBarry Smith     SETERRQ(1,"Wrong type of matrix to store values");
2313be6bf707SBarry Smith   }
2314be6bf707SBarry Smith   PetscFunctionReturn(0);
2315be6bf707SBarry Smith }
2316be6bf707SBarry Smith 
2317fb2e594dSBarry Smith EXTERN_C_BEGIN
23184a2ae208SSatish Balay #undef __FUNCT__
23194a2ae208SSatish Balay #define __FUNCT__ "MatRetrieveValues_SeqAIJ"
2320be6bf707SBarry Smith int MatRetrieveValues_SeqAIJ(Mat mat)
2321be6bf707SBarry Smith {
2322be6bf707SBarry Smith   Mat_SeqAIJ *aij = (Mat_SeqAIJ *)mat->data;
2323273d9f13SBarry Smith   int        nz = aij->i[mat->m]+aij->indexshift,ierr;
2324be6bf707SBarry Smith 
2325be6bf707SBarry Smith   PetscFunctionBegin;
2326be6bf707SBarry Smith   if (aij->nonew != 1) {
232729bbc08cSBarry Smith     SETERRQ(1,"Must call MatSetOption(A,MAT_NO_NEW_NONZERO_LOCATIONS);first");
2328be6bf707SBarry Smith   }
2329be6bf707SBarry Smith   if (!aij->saved_values) {
233029bbc08cSBarry Smith     SETERRQ(1,"Must call MatStoreValues(A);first");
2331be6bf707SBarry Smith   }
2332be6bf707SBarry Smith 
2333be6bf707SBarry Smith   /* copy values over */
233487828ca2SBarry Smith   ierr = PetscMemcpy(aij->a,aij->saved_values,nz*sizeof(PetscScalar));CHKERRQ(ierr);
2335be6bf707SBarry Smith   PetscFunctionReturn(0);
2336be6bf707SBarry Smith }
2337fb2e594dSBarry Smith EXTERN_C_END
2338be6bf707SBarry Smith 
23394a2ae208SSatish Balay #undef __FUNCT__
23404a2ae208SSatish Balay #define __FUNCT__ "MatRetrieveValues"
2341be6bf707SBarry Smith /*@
2342be6bf707SBarry Smith     MatRetrieveValues - Retrieves the copy of the matrix values; this allows, for
2343be6bf707SBarry Smith        example, reuse of the linear part of a Jacobian, while recomputing the
2344be6bf707SBarry Smith        nonlinear portion.
2345be6bf707SBarry Smith 
2346be6bf707SBarry Smith    Collect on Mat
2347be6bf707SBarry Smith 
2348be6bf707SBarry Smith   Input Parameters:
2349be6bf707SBarry Smith .  mat - the matrix (currently on AIJ matrices support this option)
2350be6bf707SBarry Smith 
235115091d37SBarry Smith   Level: advanced
235215091d37SBarry Smith 
2353be6bf707SBarry Smith .seealso: MatStoreValues()
2354be6bf707SBarry Smith 
2355be6bf707SBarry Smith @*/
2356be6bf707SBarry Smith int MatRetrieveValues(Mat mat)
2357be6bf707SBarry Smith {
2358be6bf707SBarry Smith   int ierr,(*f)(Mat);
2359be6bf707SBarry Smith 
2360be6bf707SBarry Smith   PetscFunctionBegin;
2361be6bf707SBarry Smith   PetscValidHeaderSpecific(mat,MAT_COOKIE);
236229bbc08cSBarry Smith   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
236329bbc08cSBarry Smith   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2364be6bf707SBarry Smith 
2365c134de8dSSatish Balay   ierr = PetscObjectQueryFunction((PetscObject)mat,"MatRetrieveValues_C",(void (**)(void))&f);CHKERRQ(ierr);
2366be6bf707SBarry Smith   if (f) {
2367be6bf707SBarry Smith     ierr = (*f)(mat);CHKERRQ(ierr);
2368be6bf707SBarry Smith   } else {
236929bbc08cSBarry Smith     SETERRQ(1,"Wrong type of matrix to retrieve values");
2370be6bf707SBarry Smith   }
2371be6bf707SBarry Smith   PetscFunctionReturn(0);
2372be6bf707SBarry Smith }
2373be6bf707SBarry Smith 
2374f83d6046SBarry Smith /*
2375f83d6046SBarry Smith    This allows SeqAIJ matrices to be passed to the matlab engine
2376f83d6046SBarry Smith */
237787828ca2SBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE) && !defined(PETSC_USE_COMPLEX) && !defined(PETSC_USE_SINGLE)
2378f83d6046SBarry Smith #include "engine.h"   /* Matlab include file */
2379f83d6046SBarry Smith #include "mex.h"      /* Matlab include file */
2380f83d6046SBarry Smith EXTERN_C_BEGIN
23814a2ae208SSatish Balay #undef __FUNCT__
23824a2ae208SSatish Balay #define __FUNCT__ "MatMatlabEnginePut_SeqAIJ"
2383*62aa7f4eSBarry Smith int MatMatlabEnginePut_SeqAIJ(PetscObject obj,void *mengine)
2384f83d6046SBarry Smith {
23854a4478b9SSatish Balay   int         ierr,i,*ai,*aj;
2386f83d6046SBarry Smith   Mat         B = (Mat)obj;
2387f83d6046SBarry Smith   mxArray     *mat;
2388d79a51d8SBarry Smith   Mat_SeqAIJ  *aij = (Mat_SeqAIJ*)B->data;
2389d79a51d8SBarry Smith 
2390f83d6046SBarry Smith   PetscFunctionBegin;
239101820c62SBarry Smith   mat  = mxCreateSparse(B->n,B->m,aij->nz,mxREAL);
239287828ca2SBarry Smith   ierr = PetscMemcpy(mxGetPr(mat),aij->a,aij->nz*sizeof(PetscScalar));CHKERRQ(ierr);
2393d79a51d8SBarry Smith   /* Matlab stores by column, not row so we pass in the transpose of the matrix */
239466826eb6SBarry Smith   ierr = PetscMemcpy(mxGetIr(mat),aij->j,aij->nz*sizeof(int));CHKERRQ(ierr);
239566826eb6SBarry Smith   ierr = PetscMemcpy(mxGetJc(mat),aij->i,(B->m+1)*sizeof(int));CHKERRQ(ierr);
2396f83d6046SBarry Smith 
239701820c62SBarry Smith   /* Matlab indices start at 0 for sparse (what a surprise) */
239801820c62SBarry Smith   if (aij->indexshift) {
2399a1c0a87aSBarry Smith     ai = mxGetJc(mat);
240001820c62SBarry Smith     for (i=0; i<B->m+1; i++) {
240101820c62SBarry Smith       ai[i]--;
2402d79a51d8SBarry Smith     }
2403a1c0a87aSBarry Smith     aj = mxGetIr(mat);
2404d79a51d8SBarry Smith     for (i=0; i<aij->nz; i++) {
240501820c62SBarry Smith       aj[i]--;
2406d79a51d8SBarry Smith     }
2407d79a51d8SBarry Smith   }
2408ca44d042SBarry Smith   ierr = PetscObjectName(obj);CHKERRQ(ierr);
2409f83d6046SBarry Smith   mxSetName(mat,obj->name);
2410*62aa7f4eSBarry Smith   engPutArray((Engine *)mengine,mat);
2411f83d6046SBarry Smith   PetscFunctionReturn(0);
2412f83d6046SBarry Smith }
2413f83d6046SBarry Smith EXTERN_C_END
241466826eb6SBarry Smith 
241566826eb6SBarry Smith EXTERN_C_BEGIN
24164a2ae208SSatish Balay #undef __FUNCT__
24174a2ae208SSatish Balay #define __FUNCT__ "MatMatlabEngineGet_SeqAIJ"
2418*62aa7f4eSBarry Smith int MatMatlabEngineGet_SeqAIJ(PetscObject obj,void *mengine)
241966826eb6SBarry Smith {
242066826eb6SBarry Smith   int        ierr,ii;
242166826eb6SBarry Smith   Mat        mat = (Mat)obj;
242266826eb6SBarry Smith   Mat_SeqAIJ *aij = (Mat_SeqAIJ*)mat->data;
242366826eb6SBarry Smith   mxArray    *mmat;
242466826eb6SBarry Smith 
24256c0721eeSBarry Smith   PetscFunctionBegin;
242666826eb6SBarry Smith   ierr = PetscFree(aij->a);CHKERRQ(ierr);
242766826eb6SBarry Smith   aij->indexshift = 0;
242866826eb6SBarry Smith 
2429*62aa7f4eSBarry Smith   mmat = engGetArray((Engine *)mengine,obj->name);
243066826eb6SBarry Smith 
2431a65776f3SBarry Smith   aij->nz           = (mxGetJc(mmat))[mat->m];
2432a7ed9263SMatthew Knepley   ierr              = PetscMalloc(((size_t) aij->nz)*(sizeof(int)+sizeof(PetscScalar))+(mat->m+1)*sizeof(int),&aij->a);CHKERRQ(ierr);
243366826eb6SBarry Smith   aij->j            = (int*)(aij->a + aij->nz);
243466826eb6SBarry Smith   aij->i            = aij->j + aij->nz;
243566826eb6SBarry Smith   aij->singlemalloc = PETSC_TRUE;
243666826eb6SBarry Smith   aij->freedata     = PETSC_TRUE;
243766826eb6SBarry Smith 
243887828ca2SBarry Smith   ierr = PetscMemcpy(aij->a,mxGetPr(mmat),aij->nz*sizeof(PetscScalar));CHKERRQ(ierr);
243966826eb6SBarry Smith   /* Matlab stores by column, not row so we pass in the transpose of the matrix */
244066826eb6SBarry Smith   ierr = PetscMemcpy(aij->j,mxGetIr(mmat),aij->nz*sizeof(int));CHKERRQ(ierr);
244166826eb6SBarry Smith   ierr = PetscMemcpy(aij->i,mxGetJc(mmat),(mat->m+1)*sizeof(int));CHKERRQ(ierr);
244266826eb6SBarry Smith 
244366826eb6SBarry Smith   for (ii=0; ii<mat->m; ii++) {
244466826eb6SBarry Smith     aij->ilen[ii] = aij->imax[ii] = aij->i[ii+1] - aij->i[ii];
244566826eb6SBarry Smith   }
244666826eb6SBarry Smith 
244766826eb6SBarry Smith   ierr = MatAssemblyBegin(mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
244866826eb6SBarry Smith   ierr = MatAssemblyEnd(mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
244966826eb6SBarry Smith 
245066826eb6SBarry Smith   PetscFunctionReturn(0);
245166826eb6SBarry Smith }
245266826eb6SBarry Smith EXTERN_C_END
2453f83d6046SBarry Smith #endif
2454f83d6046SBarry Smith 
2455be6bf707SBarry Smith /* --------------------------------------------------------------------------------*/
24564a2ae208SSatish Balay #undef __FUNCT__
24574a2ae208SSatish Balay #define __FUNCT__ "MatCreateSeqAIJ"
245817ab2063SBarry Smith /*@C
2459682d7d0cSBarry Smith    MatCreateSeqAIJ - Creates a sparse matrix in AIJ (compressed row) format
24600d15e28bSLois Curfman McInnes    (the default parallel PETSc format).  For good matrix assembly performance
24616e62573dSLois Curfman McInnes    the user should preallocate the matrix storage by setting the parameter nz
246251c19458SBarry Smith    (or the array nnz).  By setting these parameters accurately, performance
24632bd5e0b2SLois Curfman McInnes    during matrix assembly can be increased by more than a factor of 50.
246417ab2063SBarry Smith 
2465db81eaa0SLois Curfman McInnes    Collective on MPI_Comm
2466db81eaa0SLois Curfman McInnes 
246717ab2063SBarry Smith    Input Parameters:
2468db81eaa0SLois Curfman McInnes +  comm - MPI communicator, set to PETSC_COMM_SELF
246917ab2063SBarry Smith .  m - number of rows
247017ab2063SBarry Smith .  n - number of columns
247117ab2063SBarry Smith .  nz - number of nonzeros per row (same for all rows)
247251c19458SBarry Smith -  nnz - array containing the number of nonzeros in the various rows
24732bd5e0b2SLois Curfman McInnes          (possibly different for each row) or PETSC_NULL
247417ab2063SBarry Smith 
247517ab2063SBarry Smith    Output Parameter:
2476416022c9SBarry Smith .  A - the matrix
247717ab2063SBarry Smith 
2478b259b22eSLois Curfman McInnes    Notes:
247917ab2063SBarry Smith    The AIJ format (also called the Yale sparse matrix format or
248017ab2063SBarry Smith    compressed row storage), is fully compatible with standard Fortran 77
24810002213bSLois Curfman McInnes    storage.  That is, the stored row and column indices can begin at
248244cd7ae7SLois Curfman McInnes    either one (as in Fortran) or zero.  See the users' manual for details.
248317ab2063SBarry Smith 
248417ab2063SBarry Smith    Specify the preallocated storage with either nz or nnz (not both).
2485a40aa06bSLois Curfman McInnes    Set nz=PETSC_DEFAULT and nnz=PETSC_NULL for PETSc to control dynamic memory
24863d323bbdSBarry Smith    allocation.  For large problems you MUST preallocate memory or you
24876da5968aSLois Curfman McInnes    will get TERRIBLE performance, see the users' manual chapter on matrices.
248817ab2063SBarry Smith 
2489682d7d0cSBarry Smith    By default, this format uses inodes (identical nodes) when possible, to
24904fca80b9SLois Curfman McInnes    improve numerical efficiency of matrix-vector products and solves. We
2491682d7d0cSBarry Smith    search for consecutive rows with the same nonzero structure, thereby
24926c7ebb05SLois Curfman McInnes    reusing matrix information to achieve increased efficiency.
24936c7ebb05SLois Curfman McInnes 
24946c7ebb05SLois Curfman McInnes    Options Database Keys:
2495db81eaa0SLois Curfman McInnes +  -mat_aij_no_inode  - Do not use inodes
2496db81eaa0SLois Curfman McInnes .  -mat_aij_inode_limit <limit> - Sets inode limit (max limit=5)
2497db81eaa0SLois Curfman McInnes -  -mat_aij_oneindex - Internally use indexing starting at 1
2498db81eaa0SLois Curfman McInnes         rather than 0.  Note that when calling MatSetValues(),
2499db81eaa0SLois Curfman McInnes         the user still MUST index entries starting at 0!
250017ab2063SBarry Smith 
2501027ccd11SLois Curfman McInnes    Level: intermediate
2502027ccd11SLois Curfman McInnes 
250336db0b34SBarry Smith .seealso: MatCreate(), MatCreateMPIAIJ(), MatSetValues(), MatSeqAIJSetColumnIndices(), MatCreateSeqAIJWithArrays()
250436db0b34SBarry Smith 
250517ab2063SBarry Smith @*/
2506416022c9SBarry Smith int MatCreateSeqAIJ(MPI_Comm comm,int m,int n,int nz,int *nnz,Mat *A)
250717ab2063SBarry Smith {
2508273d9f13SBarry Smith   int ierr;
25096945ee14SBarry Smith 
25103a40ed3dSBarry Smith   PetscFunctionBegin;
2511273d9f13SBarry Smith   ierr = MatCreate(comm,m,n,m,n,A);CHKERRQ(ierr);
2512273d9f13SBarry Smith   ierr = MatSetType(*A,MATSEQAIJ);CHKERRQ(ierr);
2513273d9f13SBarry Smith   ierr = MatSeqAIJSetPreallocation(*A,nz,nnz);CHKERRQ(ierr);
2514273d9f13SBarry Smith   PetscFunctionReturn(0);
2515273d9f13SBarry Smith }
2516273d9f13SBarry Smith 
25175da197adSKris Buschelman #define SKIP_ALLOCATION -4
25185da197adSKris Buschelman 
25194a2ae208SSatish Balay #undef __FUNCT__
25204a2ae208SSatish Balay #define __FUNCT__ "MatSeqAIJSetPreallocation"
2521273d9f13SBarry Smith /*@C
2522273d9f13SBarry Smith    MatSeqAIJSetPreallocation - For good matrix assembly performance
2523273d9f13SBarry Smith    the user should preallocate the matrix storage by setting the parameter nz
2524273d9f13SBarry Smith    (or the array nnz).  By setting these parameters accurately, performance
2525273d9f13SBarry Smith    during matrix assembly can be increased by more than a factor of 50.
2526273d9f13SBarry Smith 
2527273d9f13SBarry Smith    Collective on MPI_Comm
2528273d9f13SBarry Smith 
2529273d9f13SBarry Smith    Input Parameters:
2530273d9f13SBarry Smith +  comm - MPI communicator, set to PETSC_COMM_SELF
2531273d9f13SBarry Smith .  m - number of rows
2532273d9f13SBarry Smith .  n - number of columns
2533273d9f13SBarry Smith .  nz - number of nonzeros per row (same for all rows)
2534273d9f13SBarry Smith -  nnz - array containing the number of nonzeros in the various rows
2535273d9f13SBarry Smith          (possibly different for each row) or PETSC_NULL
2536273d9f13SBarry Smith 
2537273d9f13SBarry Smith    Output Parameter:
2538273d9f13SBarry Smith .  A - the matrix
2539273d9f13SBarry Smith 
2540273d9f13SBarry Smith    Notes:
2541273d9f13SBarry Smith    The AIJ format (also called the Yale sparse matrix format or
2542273d9f13SBarry Smith    compressed row storage), is fully compatible with standard Fortran 77
2543273d9f13SBarry Smith    storage.  That is, the stored row and column indices can begin at
2544273d9f13SBarry Smith    either one (as in Fortran) or zero.  See the users' manual for details.
2545273d9f13SBarry Smith 
2546273d9f13SBarry Smith    Specify the preallocated storage with either nz or nnz (not both).
2547273d9f13SBarry Smith    Set nz=PETSC_DEFAULT and nnz=PETSC_NULL for PETSc to control dynamic memory
2548273d9f13SBarry Smith    allocation.  For large problems you MUST preallocate memory or you
2549273d9f13SBarry Smith    will get TERRIBLE performance, see the users' manual chapter on matrices.
2550273d9f13SBarry Smith 
2551273d9f13SBarry Smith    By default, this format uses inodes (identical nodes) when possible, to
2552273d9f13SBarry Smith    improve numerical efficiency of matrix-vector products and solves. We
2553273d9f13SBarry Smith    search for consecutive rows with the same nonzero structure, thereby
2554273d9f13SBarry Smith    reusing matrix information to achieve increased efficiency.
2555273d9f13SBarry Smith 
2556273d9f13SBarry Smith    Options Database Keys:
2557273d9f13SBarry Smith +  -mat_aij_no_inode  - Do not use inodes
2558273d9f13SBarry Smith .  -mat_aij_inode_limit <limit> - Sets inode limit (max limit=5)
2559273d9f13SBarry Smith -  -mat_aij_oneindex - Internally use indexing starting at 1
2560273d9f13SBarry Smith         rather than 0.  Note that when calling MatSetValues(),
2561273d9f13SBarry Smith         the user still MUST index entries starting at 0!
2562273d9f13SBarry Smith 
2563273d9f13SBarry Smith    Level: intermediate
2564273d9f13SBarry Smith 
2565273d9f13SBarry Smith .seealso: MatCreate(), MatCreateMPIAIJ(), MatSetValues(), MatSeqAIJSetColumnIndices(), MatCreateSeqAIJWithArrays()
2566273d9f13SBarry Smith 
2567273d9f13SBarry Smith @*/
2568273d9f13SBarry Smith int MatSeqAIJSetPreallocation(Mat B,int nz,int *nnz)
2569273d9f13SBarry Smith {
2570273d9f13SBarry Smith   Mat_SeqAIJ *b;
2571a7ed9263SMatthew Knepley   size_t     len = 0;
2572c461c341SBarry Smith   PetscTruth flg2,skipallocation = PETSC_FALSE;
2573a7ed9263SMatthew Knepley   int        i,ierr;
2574273d9f13SBarry Smith 
2575273d9f13SBarry Smith   PetscFunctionBegin;
2576273d9f13SBarry Smith   ierr = PetscTypeCompare((PetscObject)B,MATSEQAIJ,&flg2);CHKERRQ(ierr);
2577273d9f13SBarry Smith   if (!flg2) PetscFunctionReturn(0);
2578d5d45c9bSBarry Smith 
2579c461c341SBarry Smith   if (nz == SKIP_ALLOCATION) {
2580c461c341SBarry Smith     skipallocation = PETSC_TRUE;
2581c461c341SBarry Smith     nz             = 0;
2582c461c341SBarry Smith   }
2583c461c341SBarry Smith 
2584435da068SBarry Smith   if (nz == PETSC_DEFAULT || nz == PETSC_DECIDE) nz = 5;
2585435da068SBarry Smith   if (nz < 0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"nz cannot be less than 0: value %d",nz);
2586b73539f3SBarry Smith   if (nnz) {
2587273d9f13SBarry Smith     for (i=0; i<B->m; i++) {
258829bbc08cSBarry Smith       if (nnz[i] < 0) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"nnz cannot be less than 0: local row %d value %d",i,nnz[i]);
25893a7fca6bSBarry Smith       if (nnz[i] > B->n) SETERRQ3(PETSC_ERR_ARG_OUTOFRANGE,"nnz cannot be greater than row length: local row %d value %d rowlength %d",i,nnz[i],B->n);
2590b73539f3SBarry Smith     }
2591b73539f3SBarry Smith   }
2592b73539f3SBarry Smith 
2593273d9f13SBarry Smith   B->preallocated = PETSC_TRUE;
2594273d9f13SBarry Smith   b = (Mat_SeqAIJ*)B->data;
2595273d9f13SBarry Smith 
2596b0a32e0cSBarry Smith   ierr = PetscMalloc((B->m+1)*sizeof(int),&b->imax);CHKERRQ(ierr);
2597273d9f13SBarry Smith   if (!nnz) {
2598435da068SBarry Smith     if (nz == PETSC_DEFAULT || nz == PETSC_DECIDE) nz = 10;
2599273d9f13SBarry Smith     else if (nz <= 0)        nz = 1;
2600273d9f13SBarry Smith     for (i=0; i<B->m; i++) b->imax[i] = nz;
2601273d9f13SBarry Smith     nz = nz*B->m;
2602273d9f13SBarry Smith   } else {
2603273d9f13SBarry Smith     nz = 0;
2604273d9f13SBarry Smith     for (i=0; i<B->m; i++) {b->imax[i] = nnz[i]; nz += nnz[i];}
2605273d9f13SBarry Smith   }
2606273d9f13SBarry Smith 
2607c461c341SBarry Smith   if (!skipallocation) {
2608273d9f13SBarry Smith     /* allocate the matrix space */
2609a7ed9263SMatthew Knepley     len             = ((size_t) nz)*(sizeof(int) + sizeof(PetscScalar)) + (B->m+1)*sizeof(int);
2610b0a32e0cSBarry Smith     ierr            = PetscMalloc(len,&b->a);CHKERRQ(ierr);
2611273d9f13SBarry Smith     b->j            = (int*)(b->a + nz);
2612273d9f13SBarry Smith     ierr            = PetscMemzero(b->j,nz*sizeof(int));CHKERRQ(ierr);
2613273d9f13SBarry Smith     b->i            = b->j + nz;
26145da197adSKris Buschelman     b->i[0] = -b->indexshift;
26155da197adSKris Buschelman     for (i=1; i<B->m+1; i++) {
26165da197adSKris Buschelman       b->i[i] = b->i[i-1] + b->imax[i-1];
26175da197adSKris Buschelman     }
2618273d9f13SBarry Smith     b->singlemalloc = PETSC_TRUE;
2619273d9f13SBarry Smith     b->freedata     = PETSC_TRUE;
2620c461c341SBarry Smith   } else {
2621c461c341SBarry Smith     b->freedata     = PETSC_FALSE;
2622c461c341SBarry Smith   }
2623273d9f13SBarry Smith 
2624273d9f13SBarry Smith   /* b->ilen will count nonzeros in each row so far. */
2625b0a32e0cSBarry Smith   ierr = PetscMalloc((B->m+1)*sizeof(int),&b->ilen);CHKERRQ(ierr);
2626b0a32e0cSBarry Smith   PetscLogObjectMemory(B,len+2*(B->m+1)*sizeof(int)+sizeof(struct _p_Mat)+sizeof(Mat_SeqAIJ));
2627273d9f13SBarry Smith   for (i=0; i<B->m; i++) { b->ilen[i] = 0;}
2628273d9f13SBarry Smith 
2629273d9f13SBarry Smith   b->nz                = 0;
2630273d9f13SBarry Smith   b->maxnz             = nz;
2631273d9f13SBarry Smith   B->info.nz_unneeded  = (double)b->maxnz;
2632273d9f13SBarry Smith   PetscFunctionReturn(0);
2633273d9f13SBarry Smith }
2634273d9f13SBarry Smith 
2635eb9c0419SKris Buschelman EXTERN int RegisterApplyPtAPRoutines_Private(Mat);
2636eb9c0419SKris Buschelman 
2637273d9f13SBarry Smith EXTERN_C_BEGIN
26384a2ae208SSatish Balay #undef __FUNCT__
26394a2ae208SSatish Balay #define __FUNCT__ "MatCreate_SeqAIJ"
2640273d9f13SBarry Smith int MatCreate_SeqAIJ(Mat B)
2641273d9f13SBarry Smith {
2642273d9f13SBarry Smith   Mat_SeqAIJ *b;
2643273d9f13SBarry Smith   int        ierr,size;
2644273d9f13SBarry Smith   PetscTruth flg;
2645273d9f13SBarry Smith 
2646273d9f13SBarry Smith   PetscFunctionBegin;
2647273d9f13SBarry Smith   ierr = MPI_Comm_size(B->comm,&size);CHKERRQ(ierr);
2648273d9f13SBarry Smith   if (size > 1) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Comm must be of size 1");
2649273d9f13SBarry Smith 
2650273d9f13SBarry Smith   B->m = B->M = PetscMax(B->m,B->M);
2651273d9f13SBarry Smith   B->n = B->N = PetscMax(B->n,B->N);
2652273d9f13SBarry Smith 
2653b0a32e0cSBarry Smith   ierr = PetscNew(Mat_SeqAIJ,&b);CHKERRQ(ierr);
2654b0a32e0cSBarry Smith   B->data             = (void*)b;
2655549d3d68SSatish Balay   ierr = PetscMemzero(b,sizeof(Mat_SeqAIJ));CHKERRQ(ierr);
2656549d3d68SSatish Balay   ierr = PetscMemcpy(B->ops,&MatOps_Values,sizeof(struct _MatOps));CHKERRQ(ierr);
2657416022c9SBarry Smith   B->factor           = 0;
2658416022c9SBarry Smith   B->lupivotthreshold = 1.0;
265990f02eecSBarry Smith   B->mapping          = 0;
2660e82a3eeeSBarry Smith   ierr = PetscOptionsGetReal(B->prefix,"-mat_lu_pivotthreshold",&B->lupivotthreshold,PETSC_NULL);CHKERRQ(ierr);
2661e82a3eeeSBarry Smith   ierr = PetscOptionsHasName(B->prefix,"-pc_ilu_preserve_row_sums",&b->ilu_preserve_row_sums);CHKERRQ(ierr);
2662416022c9SBarry Smith   b->row              = 0;
2663416022c9SBarry Smith   b->col              = 0;
266482bf6240SBarry Smith   b->icol             = 0;
2665416022c9SBarry Smith   b->indexshift       = 0;
2666b810aeb4SBarry Smith   b->reallocs         = 0;
2667e82a3eeeSBarry Smith   ierr = PetscOptionsHasName(B->prefix,"-mat_aij_oneindex",&flg);CHKERRQ(ierr);
266869957df2SSatish Balay   if (flg) b->indexshift = -1;
266917ab2063SBarry Smith 
26708a124369SBarry Smith   ierr = PetscMapCreateMPI(B->comm,B->m,B->m,&B->rmap);CHKERRQ(ierr);
26718a124369SBarry Smith   ierr = PetscMapCreateMPI(B->comm,B->n,B->n,&B->cmap);CHKERRQ(ierr);
2672a5ae1ecdSBarry Smith 
2673f1e2ffcdSBarry Smith   b->sorted            = PETSC_FALSE;
267436db0b34SBarry Smith   b->ignorezeroentries = PETSC_FALSE;
2675f1e2ffcdSBarry Smith   b->roworiented       = PETSC_TRUE;
2676416022c9SBarry Smith   b->nonew             = 0;
2677416022c9SBarry Smith   b->diag              = 0;
2678416022c9SBarry Smith   b->solve_work        = 0;
26792a1b7f2aSHong Zhang   B->spptr             = 0;
2680b65db4caSBarry Smith   b->inode.use         = PETSC_TRUE;
2681754ec7b1SSatish Balay   b->inode.node_count  = 0;
2682754ec7b1SSatish Balay   b->inode.size        = 0;
26836c7ebb05SLois Curfman McInnes   b->inode.limit       = 5;
26846c7ebb05SLois Curfman McInnes   b->inode.max_limit   = 5;
2685be6bf707SBarry Smith   b->saved_values      = 0;
2686d7f994e1SBarry Smith   b->idiag             = 0;
2687d7f994e1SBarry Smith   b->ssor              = 0;
2688f1e2ffcdSBarry Smith   b->keepzeroedrows    = PETSC_FALSE;
268917ab2063SBarry Smith 
269035d8aa7fSBarry Smith   ierr = PetscObjectChangeTypeName((PetscObject)B,MATSEQAIJ);CHKERRQ(ierr);
269135d8aa7fSBarry Smith 
2692aa482453SBarry Smith #if defined(PETSC_HAVE_SUPERLU)
2693e82a3eeeSBarry Smith   ierr = PetscOptionsHasName(B->prefix,"-mat_aij_superlu",&flg);CHKERRQ(ierr);
269469957df2SSatish Balay   if (flg) { ierr = MatUseSuperLU_SeqAIJ(B);CHKERRQ(ierr); }
26954b14c69eSBarry Smith #endif
2696564e58d6SHong Zhang 
2697e82a3eeeSBarry Smith   ierr = PetscOptionsHasName(B->prefix,"-mat_aij_essl",&flg);CHKERRQ(ierr);
269869957df2SSatish Balay   if (flg) { ierr = MatUseEssl_SeqAIJ(B);CHKERRQ(ierr); }
2699e82a3eeeSBarry Smith   ierr = PetscOptionsHasName(B->prefix,"-mat_aij_lusol",&flg);CHKERRQ(ierr);
2700cd5578b5SBarry Smith   if (flg) { ierr = MatUseLUSOL_SeqAIJ(B);CHKERRQ(ierr); }
2701e82a3eeeSBarry Smith   ierr = PetscOptionsHasName(B->prefix,"-mat_aij_matlab",&flg);CHKERRQ(ierr);
2702ca44d042SBarry Smith   if (flg) {ierr = MatUseMatlab_SeqAIJ(B);CHKERRQ(ierr);}
2703e82a3eeeSBarry Smith   ierr = PetscOptionsHasName(B->prefix,"-mat_aij_dxml",&flg);CHKERRQ(ierr);
270469957df2SSatish Balay   if (flg) {
270529bbc08cSBarry Smith     if (!b->indexshift) SETERRQ(PETSC_ERR_LIB,"need -mat_aij_oneindex with -mat_aij_dxml");
2706416022c9SBarry Smith     ierr = MatUseDXML_SeqAIJ(B);CHKERRQ(ierr);
270717ab2063SBarry Smith   }
2708f1af5d2fSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatSeqAIJSetColumnIndices_C",
2709bef8e0ddSBarry Smith                                      "MatSeqAIJSetColumnIndices_SeqAIJ",
2710bc4b532fSSatish Balay                                      MatSeqAIJSetColumnIndices_SeqAIJ);CHKERRQ(ierr);
2711f1af5d2fSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatStoreValues_C",
2712be6bf707SBarry Smith                                      "MatStoreValues_SeqAIJ",
2713bc4b532fSSatish Balay                                      MatStoreValues_SeqAIJ);CHKERRQ(ierr);
2714f1af5d2fSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatRetrieveValues_C",
2715be6bf707SBarry Smith                                      "MatRetrieveValues_SeqAIJ",
2716bc4b532fSSatish Balay                                      MatRetrieveValues_SeqAIJ);CHKERRQ(ierr);
271787828ca2SBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE) && !defined(PETSC_USE_COMPLEX) && !defined(PETSC_USE_SINGLE)
2718f83d6046SBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"PetscMatlabEnginePut_C","MatMatlabEnginePut_SeqAIJ",MatMatlabEnginePut_SeqAIJ);CHKERRQ(ierr);
271966826eb6SBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"PetscMatlabEngineGet_C","MatMatlabEngineGet_SeqAIJ",MatMatlabEngineGet_SeqAIJ);CHKERRQ(ierr);
2720f83d6046SBarry Smith #endif
2721eb9c0419SKris Buschelman   ierr = RegisterApplyPtAPRoutines_Private(B);CHKERRQ(ierr);
27223a40ed3dSBarry Smith   PetscFunctionReturn(0);
272317ab2063SBarry Smith }
2724273d9f13SBarry Smith EXTERN_C_END
272517ab2063SBarry Smith 
27264a2ae208SSatish Balay #undef __FUNCT__
27274a2ae208SSatish Balay #define __FUNCT__ "MatDuplicate_SeqAIJ"
2728be6bf707SBarry Smith int MatDuplicate_SeqAIJ(Mat A,MatDuplicateOption cpvalues,Mat *B)
272917ab2063SBarry Smith {
2730416022c9SBarry Smith   Mat        C;
2731416022c9SBarry Smith   Mat_SeqAIJ *c,*a = (Mat_SeqAIJ*)A->data;
2732a7ed9263SMatthew Knepley   int        i,m = A->m,shift = a->indexshift,ierr;
2733a7ed9263SMatthew Knepley   size_t     len;
273417ab2063SBarry Smith 
27353a40ed3dSBarry Smith   PetscFunctionBegin;
27364043dd9cSLois Curfman McInnes   *B = 0;
2737273d9f13SBarry Smith   ierr = MatCreate(A->comm,A->m,A->n,A->m,A->n,&C);CHKERRQ(ierr);
2738273d9f13SBarry Smith   ierr = MatSetType(C,MATSEQAIJ);CHKERRQ(ierr);
2739273d9f13SBarry Smith   c    = (Mat_SeqAIJ*)C->data;
2740273d9f13SBarry Smith 
2741416022c9SBarry Smith   C->factor         = A->factor;
2742416022c9SBarry Smith   c->row            = 0;
2743416022c9SBarry Smith   c->col            = 0;
274482bf6240SBarry Smith   c->icol           = 0;
2745416022c9SBarry Smith   c->indexshift     = shift;
2746f1e2ffcdSBarry Smith   c->keepzeroedrows = a->keepzeroedrows;
2747c456f294SBarry Smith   C->assembled      = PETSC_TRUE;
274817ab2063SBarry Smith 
2749273d9f13SBarry Smith   C->M          = A->m;
2750273d9f13SBarry Smith   C->N          = A->n;
275117ab2063SBarry Smith 
2752b0a32e0cSBarry Smith   ierr = PetscMalloc((m+1)*sizeof(int),&c->imax);CHKERRQ(ierr);
2753b0a32e0cSBarry Smith   ierr = PetscMalloc((m+1)*sizeof(int),&c->ilen);CHKERRQ(ierr);
275417ab2063SBarry Smith   for (i=0; i<m; i++) {
2755416022c9SBarry Smith     c->imax[i] = a->imax[i];
2756416022c9SBarry Smith     c->ilen[i] = a->ilen[i];
275717ab2063SBarry Smith   }
275817ab2063SBarry Smith 
275917ab2063SBarry Smith   /* allocate the matrix space */
2760f1e2ffcdSBarry Smith   c->singlemalloc = PETSC_TRUE;
2761a7ed9263SMatthew Knepley   len   = ((size_t) (m+1))*sizeof(int)+(a->i[m])*(sizeof(PetscScalar)+sizeof(int));
2762b0a32e0cSBarry Smith   ierr  = PetscMalloc(len,&c->a);CHKERRQ(ierr);
2763416022c9SBarry Smith   c->j  = (int*)(c->a + a->i[m] + shift);
2764416022c9SBarry Smith   c->i  = c->j + a->i[m] + shift;
2765549d3d68SSatish Balay   ierr = PetscMemcpy(c->i,a->i,(m+1)*sizeof(int));CHKERRQ(ierr);
276617ab2063SBarry Smith   if (m > 0) {
2767549d3d68SSatish Balay     ierr = PetscMemcpy(c->j,a->j,(a->i[m]+shift)*sizeof(int));CHKERRQ(ierr);
2768be6bf707SBarry Smith     if (cpvalues == MAT_COPY_VALUES) {
276987828ca2SBarry Smith       ierr = PetscMemcpy(c->a,a->a,(a->i[m]+shift)*sizeof(PetscScalar));CHKERRQ(ierr);
2770be6bf707SBarry Smith     } else {
277187828ca2SBarry Smith       ierr = PetscMemzero(c->a,(a->i[m]+shift)*sizeof(PetscScalar));CHKERRQ(ierr);
277217ab2063SBarry Smith     }
277308480c60SBarry Smith   }
277417ab2063SBarry Smith 
2775b0a32e0cSBarry Smith   PetscLogObjectMemory(C,len+2*(m+1)*sizeof(int)+sizeof(struct _p_Mat)+sizeof(Mat_SeqAIJ));
2776416022c9SBarry Smith   c->sorted      = a->sorted;
2777416022c9SBarry Smith   c->roworiented = a->roworiented;
2778416022c9SBarry Smith   c->nonew       = a->nonew;
27797a743949SBarry Smith   c->ilu_preserve_row_sums = a->ilu_preserve_row_sums;
2780be6bf707SBarry Smith   c->saved_values = 0;
2781d7f994e1SBarry Smith   c->idiag        = 0;
2782d7f994e1SBarry Smith   c->ssor         = 0;
278336db0b34SBarry Smith   c->ignorezeroentries = a->ignorezeroentries;
278436db0b34SBarry Smith   c->freedata     = PETSC_TRUE;
278517ab2063SBarry Smith 
2786416022c9SBarry Smith   if (a->diag) {
2787b0a32e0cSBarry Smith     ierr = PetscMalloc((m+1)*sizeof(int),&c->diag);CHKERRQ(ierr);
2788b0a32e0cSBarry Smith     PetscLogObjectMemory(C,(m+1)*sizeof(int));
278917ab2063SBarry Smith     for (i=0; i<m; i++) {
2790416022c9SBarry Smith       c->diag[i] = a->diag[i];
279117ab2063SBarry Smith     }
27923a40ed3dSBarry Smith   } else c->diag        = 0;
2793b65db4caSBarry Smith   c->inode.use          = a->inode.use;
27946c7ebb05SLois Curfman McInnes   c->inode.limit        = a->inode.limit;
27956c7ebb05SLois Curfman McInnes   c->inode.max_limit    = a->inode.max_limit;
2796754ec7b1SSatish Balay   if (a->inode.size){
2797b0a32e0cSBarry Smith     ierr                = PetscMalloc((m+1)*sizeof(int),&c->inode.size);CHKERRQ(ierr);
2798754ec7b1SSatish Balay     c->inode.node_count = a->inode.node_count;
2799549d3d68SSatish Balay     ierr                = PetscMemcpy(c->inode.size,a->inode.size,(m+1)*sizeof(int));CHKERRQ(ierr);
2800754ec7b1SSatish Balay   } else {
2801754ec7b1SSatish Balay     c->inode.size       = 0;
2802754ec7b1SSatish Balay     c->inode.node_count = 0;
2803754ec7b1SSatish Balay   }
2804416022c9SBarry Smith   c->nz                 = a->nz;
2805416022c9SBarry Smith   c->maxnz              = a->maxnz;
2806416022c9SBarry Smith   c->solve_work         = 0;
28072a1b7f2aSHong Zhang   C->spptr              = 0;      /* Dangerous -I'm throwing away a->spptr */
2808273d9f13SBarry Smith   C->preallocated       = PETSC_TRUE;
2809754ec7b1SSatish Balay 
2810416022c9SBarry Smith   *B = C;
2811b0a32e0cSBarry Smith   ierr = PetscFListDuplicate(A->qlist,&C->qlist);CHKERRQ(ierr);
28123a40ed3dSBarry Smith   PetscFunctionReturn(0);
281317ab2063SBarry Smith }
281417ab2063SBarry Smith 
2815273d9f13SBarry Smith EXTERN_C_BEGIN
28164a2ae208SSatish Balay #undef __FUNCT__
28174a2ae208SSatish Balay #define __FUNCT__ "MatLoad_SeqAIJ"
2818b0a32e0cSBarry Smith int MatLoad_SeqAIJ(PetscViewer viewer,MatType type,Mat *A)
281917ab2063SBarry Smith {
2820416022c9SBarry Smith   Mat_SeqAIJ   *a;
2821416022c9SBarry Smith   Mat          B;
282217699dbbSLois Curfman McInnes   int          i,nz,ierr,fd,header[4],size,*rowlengths = 0,M,N,shift;
2823bcd2baecSBarry Smith   MPI_Comm     comm;
282417ab2063SBarry Smith 
28253a40ed3dSBarry Smith   PetscFunctionBegin;
2826e864ced6SBarry Smith   ierr = PetscObjectGetComm((PetscObject)viewer,&comm);CHKERRQ(ierr);
2827d132466eSBarry Smith   ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr);
282829bbc08cSBarry Smith   if (size > 1) SETERRQ(PETSC_ERR_ARG_SIZ,"view must have one processor");
2829b0a32e0cSBarry Smith   ierr = PetscViewerBinaryGetDescriptor(viewer,&fd);CHKERRQ(ierr);
28300752156aSBarry Smith   ierr = PetscBinaryRead(fd,header,4,PETSC_INT);CHKERRQ(ierr);
2831552e946dSBarry Smith   if (header[0] != MAT_FILE_COOKIE) SETERRQ(PETSC_ERR_FILE_UNEXPECTED,"not matrix object in file");
283217ab2063SBarry Smith   M = header[1]; N = header[2]; nz = header[3];
283317ab2063SBarry Smith 
2834d64ed03dSBarry Smith   if (nz < 0) {
283529bbc08cSBarry Smith     SETERRQ(PETSC_ERR_FILE_UNEXPECTED,"Matrix stored in special format on disk,cannot load as SeqAIJ");
2836d64ed03dSBarry Smith   }
2837d64ed03dSBarry Smith 
283817ab2063SBarry Smith   /* read in row lengths */
2839b0a32e0cSBarry Smith   ierr = PetscMalloc(M*sizeof(int),&rowlengths);CHKERRQ(ierr);
28400752156aSBarry Smith   ierr = PetscBinaryRead(fd,rowlengths,M,PETSC_INT);CHKERRQ(ierr);
284117ab2063SBarry Smith 
284217ab2063SBarry Smith   /* create our matrix */
2843416022c9SBarry Smith   ierr = MatCreateSeqAIJ(comm,M,N,0,rowlengths,A);CHKERRQ(ierr);
2844416022c9SBarry Smith   B = *A;
2845416022c9SBarry Smith   a = (Mat_SeqAIJ*)B->data;
2846416022c9SBarry Smith   shift = a->indexshift;
284717ab2063SBarry Smith 
284817ab2063SBarry Smith   /* read in column indices and adjust for Fortran indexing*/
28490752156aSBarry Smith   ierr = PetscBinaryRead(fd,a->j,nz,PETSC_INT);CHKERRQ(ierr);
285017ab2063SBarry Smith   if (shift) {
285117ab2063SBarry Smith     for (i=0; i<nz; i++) {
2852416022c9SBarry Smith       a->j[i] += 1;
285317ab2063SBarry Smith     }
285417ab2063SBarry Smith   }
285517ab2063SBarry Smith 
285617ab2063SBarry Smith   /* read in nonzero values */
28570752156aSBarry Smith   ierr = PetscBinaryRead(fd,a->a,nz,PETSC_SCALAR);CHKERRQ(ierr);
285817ab2063SBarry Smith 
285917ab2063SBarry Smith   /* set matrix "i" values */
2860416022c9SBarry Smith   a->i[0] = -shift;
286117ab2063SBarry Smith   for (i=1; i<= M; i++) {
2862416022c9SBarry Smith     a->i[i]      = a->i[i-1] + rowlengths[i-1];
2863416022c9SBarry Smith     a->ilen[i-1] = rowlengths[i-1];
286417ab2063SBarry Smith   }
2865606d414cSSatish Balay   ierr = PetscFree(rowlengths);CHKERRQ(ierr);
286617ab2063SBarry Smith 
28676d4a8577SBarry Smith   ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
28686d4a8577SBarry Smith   ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
28693a40ed3dSBarry Smith   PetscFunctionReturn(0);
287017ab2063SBarry Smith }
2871273d9f13SBarry Smith EXTERN_C_END
287217ab2063SBarry Smith 
28734a2ae208SSatish Balay #undef __FUNCT__
2874b9617806SBarry Smith #define __FUNCT__ "MatEqual_SeqAIJ"
28758f6be9afSLois Curfman McInnes int MatEqual_SeqAIJ(Mat A,Mat B,PetscTruth* flg)
28767264ac53SSatish Balay {
28777264ac53SSatish Balay   Mat_SeqAIJ *a = (Mat_SeqAIJ *)A->data,*b = (Mat_SeqAIJ *)B->data;
28780f5bd95cSBarry Smith   int        ierr;
2879273d9f13SBarry Smith   PetscTruth flag;
28807264ac53SSatish Balay 
28813a40ed3dSBarry Smith   PetscFunctionBegin;
2882273d9f13SBarry Smith   ierr = PetscTypeCompare((PetscObject)B,MATSEQAIJ,&flag);CHKERRQ(ierr);
2883273d9f13SBarry Smith   if (!flag) SETERRQ(PETSC_ERR_ARG_INCOMP,"Matrices must be same type");
28847264ac53SSatish Balay 
28857264ac53SSatish Balay   /* If the  matrix dimensions are not equal,or no of nonzeros or shift */
2886273d9f13SBarry Smith   if ((A->m != B->m) || (A->n != B->n) ||(a->nz != b->nz)|| (a->indexshift != b->indexshift)) {
2887ca44d042SBarry Smith     *flg = PETSC_FALSE;
2888ca44d042SBarry Smith     PetscFunctionReturn(0);
2889bcd2baecSBarry Smith   }
28907264ac53SSatish Balay 
28917264ac53SSatish Balay   /* if the a->i are the same */
2892273d9f13SBarry Smith   ierr = PetscMemcmp(a->i,b->i,(A->m+1)*sizeof(int),flg);CHKERRQ(ierr);
28930f5bd95cSBarry Smith   if (*flg == PETSC_FALSE) PetscFunctionReturn(0);
28947264ac53SSatish Balay 
28957264ac53SSatish Balay   /* if a->j are the same */
28960f5bd95cSBarry Smith   ierr = PetscMemcmp(a->j,b->j,(a->nz)*sizeof(int),flg);CHKERRQ(ierr);
28970f5bd95cSBarry Smith   if (*flg == PETSC_FALSE) PetscFunctionReturn(0);
2898bcd2baecSBarry Smith 
2899bcd2baecSBarry Smith   /* if a->a are the same */
290087828ca2SBarry Smith   ierr = PetscMemcmp(a->a,b->a,(a->nz)*sizeof(PetscScalar),flg);CHKERRQ(ierr);
29010f5bd95cSBarry Smith 
29023a40ed3dSBarry Smith   PetscFunctionReturn(0);
29037264ac53SSatish Balay 
29047264ac53SSatish Balay }
290536db0b34SBarry Smith 
29064a2ae208SSatish Balay #undef __FUNCT__
29074a2ae208SSatish Balay #define __FUNCT__ "MatCreateSeqAIJWithArrays"
290836db0b34SBarry Smith /*@C
290936db0b34SBarry Smith      MatCreateSeqAIJWithArrays - Creates an sequential AIJ matrix using matrix elements (in CSR format)
291036db0b34SBarry Smith               provided by the user.
291136db0b34SBarry Smith 
291236db0b34SBarry Smith       Coolective on MPI_Comm
291336db0b34SBarry Smith 
291436db0b34SBarry Smith    Input Parameters:
291536db0b34SBarry Smith +   comm - must be an MPI communicator of size 1
291636db0b34SBarry Smith .   m - number of rows
291736db0b34SBarry Smith .   n - number of columns
291836db0b34SBarry Smith .   i - row indices
291936db0b34SBarry Smith .   j - column indices
292036db0b34SBarry Smith -   a - matrix values
292136db0b34SBarry Smith 
292236db0b34SBarry Smith    Output Parameter:
292336db0b34SBarry Smith .   mat - the matrix
292436db0b34SBarry Smith 
292536db0b34SBarry Smith    Level: intermediate
292636db0b34SBarry Smith 
292736db0b34SBarry Smith    Notes:
29280551d7c0SBarry Smith        The i, j, and a arrays are not copied by this routine, the user must free these arrays
292936db0b34SBarry Smith     once the matrix is destroyed
293036db0b34SBarry Smith 
293136db0b34SBarry Smith        You cannot set new nonzero locations into this matrix, that will generate an error.
293236db0b34SBarry Smith 
293336db0b34SBarry Smith        The i and j indices can be either 0- or 1 based
293436db0b34SBarry Smith 
293536db0b34SBarry Smith .seealso: MatCreate(), MatCreateMPIAIJ(), MatCreateSeqAIJ()
293636db0b34SBarry Smith 
293736db0b34SBarry Smith @*/
293887828ca2SBarry Smith int MatCreateSeqAIJWithArrays(MPI_Comm comm,int m,int n,int* i,int*j,PetscScalar *a,Mat *mat)
293936db0b34SBarry Smith {
294036db0b34SBarry Smith   int        ierr,ii;
294136db0b34SBarry Smith   Mat_SeqAIJ *aij;
294236db0b34SBarry Smith 
294336db0b34SBarry Smith   PetscFunctionBegin;
2944c461c341SBarry Smith   ierr = MatCreateSeqAIJ(comm,m,n,SKIP_ALLOCATION,0,mat);CHKERRQ(ierr);
294536db0b34SBarry Smith   aij  = (Mat_SeqAIJ*)(*mat)->data;
294636db0b34SBarry Smith 
294736db0b34SBarry Smith   if (i[0] == 1) {
294836db0b34SBarry Smith     aij->indexshift = -1;
294936db0b34SBarry Smith   } else if (i[0]) {
295029bbc08cSBarry Smith     SETERRQ(1,"i (row indices) do not start with 0 or 1");
295136db0b34SBarry Smith   }
295236db0b34SBarry Smith   aij->i = i;
295336db0b34SBarry Smith   aij->j = j;
295436db0b34SBarry Smith   aij->a = a;
295536db0b34SBarry Smith   aij->singlemalloc = PETSC_FALSE;
295636db0b34SBarry Smith   aij->nonew        = -1;             /*this indicates that inserting a new value in the matrix that generates a new nonzero is an error*/
295736db0b34SBarry Smith   aij->freedata     = PETSC_FALSE;
295836db0b34SBarry Smith 
295936db0b34SBarry Smith   for (ii=0; ii<m; ii++) {
296036db0b34SBarry Smith     aij->ilen[ii] = aij->imax[ii] = i[ii+1] - i[ii];
29619860f2b2SBarry Smith #if defined(PETSC_USE_BOPT_g)
296229bbc08cSBarry Smith     if (i[ii+1] - i[ii] < 0) SETERRQ2(1,"Negative row length in i (row indices) row = %d length = %d",ii,i[ii+1] - i[ii]);
296336db0b34SBarry Smith #endif
296436db0b34SBarry Smith   }
29659860f2b2SBarry Smith #if defined(PETSC_USE_BOPT_g)
296636db0b34SBarry Smith   for (ii=0; ii<aij->i[m]; ii++) {
296729bbc08cSBarry Smith     if (j[ii] < -aij->indexshift) SETERRQ2(1,"Negative column index at location = %d index = %d",ii,j[ii]);
296829bbc08cSBarry Smith     if (j[ii] > n - 1 -aij->indexshift) SETERRQ2(1,"Column index to large at location = %d index = %d",ii,j[ii]);
296936db0b34SBarry Smith   }
297036db0b34SBarry Smith #endif
297136db0b34SBarry Smith 
2972b65db4caSBarry Smith   /* changes indices to start at 0 */
2973b65db4caSBarry Smith   if (i[0]) {
2974b65db4caSBarry Smith     aij->indexshift = 0;
2975b65db4caSBarry Smith     for (ii=0; ii<m; ii++) {
2976b65db4caSBarry Smith       i[ii]--;
2977b65db4caSBarry Smith     }
2978b65db4caSBarry Smith     for (ii=0; ii<i[m]; ii++) {
2979b65db4caSBarry Smith       j[ii]--;
2980b65db4caSBarry Smith     }
2981b65db4caSBarry Smith   }
2982b65db4caSBarry Smith 
2983b65db4caSBarry Smith   ierr = MatAssemblyBegin(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
2984b65db4caSBarry Smith   ierr = MatAssemblyEnd(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
298536db0b34SBarry Smith   PetscFunctionReturn(0);
298636db0b34SBarry Smith }
298736db0b34SBarry Smith 
2988cc8ba8e1SBarry Smith #undef __FUNCT__
2989ee4f033dSBarry Smith #define __FUNCT__ "MatSetColoring_SeqAIJ"
2990ee4f033dSBarry Smith int MatSetColoring_SeqAIJ(Mat A,ISColoring coloring)
2991cc8ba8e1SBarry Smith {
2992cc8ba8e1SBarry Smith   int        ierr;
2993cc8ba8e1SBarry Smith   Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data;
299436db0b34SBarry Smith 
2995cc8ba8e1SBarry Smith   PetscFunctionBegin;
299612c595b3SBarry Smith   if (coloring->ctype == IS_COLORING_LOCAL) {
2997cc8ba8e1SBarry Smith     ierr        = ISColoringReference(coloring);CHKERRQ(ierr);
2998cc8ba8e1SBarry Smith     a->coloring = coloring;
299912c595b3SBarry Smith   } else if (coloring->ctype == IS_COLORING_GHOSTED) {
300012c595b3SBarry Smith     int        *colors,i,*larray;
300112c595b3SBarry Smith     ISColoring ocoloring;
300212c595b3SBarry Smith 
300312c595b3SBarry Smith     /* set coloring for diagonal portion */
300412c595b3SBarry Smith     ierr = PetscMalloc((A->n+1)*sizeof(int),&larray);CHKERRQ(ierr);
300512c595b3SBarry Smith     for (i=0; i<A->n; i++) {
300612c595b3SBarry Smith       larray[i] = i;
300712c595b3SBarry Smith     }
300812c595b3SBarry Smith     ierr = ISGlobalToLocalMappingApply(A->mapping,IS_GTOLM_MASK,A->n,larray,PETSC_NULL,larray);CHKERRQ(ierr);
300912c595b3SBarry Smith     ierr = PetscMalloc((A->n+1)*sizeof(int),&colors);CHKERRQ(ierr);
301012c595b3SBarry Smith     for (i=0; i<A->n; i++) {
301112c595b3SBarry Smith       colors[i] = coloring->colors[larray[i]];
301212c595b3SBarry Smith     }
301312c595b3SBarry Smith     ierr = PetscFree(larray);CHKERRQ(ierr);
301412c595b3SBarry Smith     ierr = ISColoringCreate(PETSC_COMM_SELF,A->n,colors,&ocoloring);CHKERRQ(ierr);
301512c595b3SBarry Smith     a->coloring = ocoloring;
301612c595b3SBarry Smith   }
3017cc8ba8e1SBarry Smith   PetscFunctionReturn(0);
3018cc8ba8e1SBarry Smith }
3019cc8ba8e1SBarry Smith 
302087828ca2SBarry Smith #if defined(PETSC_HAVE_ADIC) && !defined(PETSC_USE_COMPLEX) && !defined(PETSC_USE_SINGLE)
3021ee4f033dSBarry Smith EXTERN_C_BEGIN
302229c1e371SBarry Smith #include "adic/ad_utils.h"
3023ee4f033dSBarry Smith EXTERN_C_END
3024cc8ba8e1SBarry Smith 
3025cc8ba8e1SBarry Smith #undef __FUNCT__
3026ee4f033dSBarry Smith #define __FUNCT__ "MatSetValuesAdic_SeqAIJ"
3027ee4f033dSBarry Smith int MatSetValuesAdic_SeqAIJ(Mat A,void *advalues)
3028cc8ba8e1SBarry Smith {
3029cc8ba8e1SBarry Smith   Mat_SeqAIJ  *a = (Mat_SeqAIJ*)A->data;
3030ee4f033dSBarry Smith   int         m = A->m,*ii = a->i,*jj = a->j,nz,i,*color,j,nlen;
303187828ca2SBarry Smith   PetscScalar *v = a->a,*values;
3032ee4f033dSBarry Smith   char        *cadvalues = (char *)advalues;
3033cc8ba8e1SBarry Smith 
3034cc8ba8e1SBarry Smith   PetscFunctionBegin;
3035cc8ba8e1SBarry Smith   if (!a->coloring) SETERRQ(1,"Coloring not set for matrix");
303629c1e371SBarry Smith   nlen  = PetscADGetDerivTypeSize();
3037cc8ba8e1SBarry Smith   color = a->coloring->colors;
3038cc8ba8e1SBarry Smith   /* loop over rows */
3039cc8ba8e1SBarry Smith   for (i=0; i<m; i++) {
3040cc8ba8e1SBarry Smith     nz = ii[i+1] - ii[i];
3041cc8ba8e1SBarry Smith     /* loop over columns putting computed value into matrix */
304229c1e371SBarry Smith     values = PetscADGetGradArray(cadvalues);
3043cc8ba8e1SBarry Smith     for (j=0; j<nz; j++) {
3044cc8ba8e1SBarry Smith       *v++ = values[color[*jj++]];
3045cc8ba8e1SBarry Smith     }
3046ee4f033dSBarry Smith     cadvalues += nlen; /* jump to next row of derivatives */
3047ee4f033dSBarry Smith   }
3048ee4f033dSBarry Smith   PetscFunctionReturn(0);
3049ee4f033dSBarry Smith }
3050ee4f033dSBarry Smith 
3051ee4f033dSBarry Smith #else
3052ee4f033dSBarry Smith 
3053ee4f033dSBarry Smith #undef __FUNCT__
3054ee4f033dSBarry Smith #define __FUNCT__ "MatSetValuesAdic_SeqAIJ"
3055ee4f033dSBarry Smith int MatSetValuesAdic_SeqAIJ(Mat A,void *advalues)
3056ee4f033dSBarry Smith {
3057ee4f033dSBarry Smith   PetscFunctionBegin;
3058ee4f033dSBarry Smith   SETERRQ(1,"PETSc installed without ADIC");
3059ee4f033dSBarry Smith }
3060ee4f033dSBarry Smith 
3061ee4f033dSBarry Smith #endif
3062ee4f033dSBarry Smith 
3063ee4f033dSBarry Smith #undef __FUNCT__
3064ee4f033dSBarry Smith #define __FUNCT__ "MatSetValuesAdifor_SeqAIJ"
3065ee4f033dSBarry Smith int MatSetValuesAdifor_SeqAIJ(Mat A,int nl,void *advalues)
3066ee4f033dSBarry Smith {
3067ee4f033dSBarry Smith   Mat_SeqAIJ   *a = (Mat_SeqAIJ*)A->data;
3068ee4f033dSBarry Smith   int          m = A->m,*ii = a->i,*jj = a->j,nz,i,*color,j;
306987828ca2SBarry Smith   PetscScalar  *v = a->a,*values = (PetscScalar *)advalues;
3070ee4f033dSBarry Smith 
3071ee4f033dSBarry Smith   PetscFunctionBegin;
3072ee4f033dSBarry Smith   if (!a->coloring) SETERRQ(1,"Coloring not set for matrix");
3073ee4f033dSBarry Smith   color = a->coloring->colors;
3074ee4f033dSBarry Smith   /* loop over rows */
3075ee4f033dSBarry Smith   for (i=0; i<m; i++) {
3076ee4f033dSBarry Smith     nz = ii[i+1] - ii[i];
3077ee4f033dSBarry Smith     /* loop over columns putting computed value into matrix */
3078ee4f033dSBarry Smith     for (j=0; j<nz; j++) {
3079ee4f033dSBarry Smith       *v++ = values[color[*jj++]];
3080ee4f033dSBarry Smith     }
3081ee4f033dSBarry Smith     values += nl; /* jump to next row of derivatives */
3082cc8ba8e1SBarry Smith   }
3083cc8ba8e1SBarry Smith   PetscFunctionReturn(0);
3084cc8ba8e1SBarry Smith }
308536db0b34SBarry Smith 
3086